From: Eric Kohl Date: Mon, 24 Dec 2012 16:13:02 +0000 (+0000) Subject: [NETAPI32] X-Git-Tag: backups/ros-csrss@60644~104^2~35 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=7b6e0d965e59cbc0c25bd4fe74b1179378c21b01 [NETAPI32] - Implement NetUserGetInfo. - Implement level 10 in BuildUserInfoBuffer. - Zero-initialize the user info buffer after allocation. svn path=/trunk/; revision=57997 --- diff --git a/reactos/dll/win32/netapi32/user.c b/reactos/dll/win32/netapi32/user.c index 23e00146d6a..20482fa3a0b 100644 --- a/reactos/dll/win32/netapi32/user.c +++ b/reactos/dll/win32/netapi32/user.c @@ -126,45 +126,18 @@ static struct sam_user* NETAPI_FindUser(LPCWSTR UserName) return NULL; } -static BOOL NETAPI_IsCurrentUser(LPCWSTR username) -{ - LPWSTR curr_user = NULL; - DWORD dwSize; - BOOL ret = FALSE; - - dwSize = LM20_UNLEN+1; - curr_user = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR)); - if(!curr_user) - { - ERR("Failed to allocate memory for user name.\n"); - goto end; - } - if(!GetUserNameW(curr_user, &dwSize)) - { - ERR("Failed to get current user's user name.\n"); - goto end; - } - if (!lstrcmpW(curr_user, username)) - { - ret = TRUE; - } - -end: - HeapFree(GetProcessHeap(), 0, curr_user); - return ret; -} - static NET_API_STATUS -BuildInfoBuffer(PUSER_ACCOUNT_INFORMATION UserInfo, - DWORD level, - ULONG RelativeId, - LPVOID *Buffer) +BuildUserInfoBuffer(PUSER_ACCOUNT_INFORMATION UserInfo, + DWORD level, + ULONG RelativeId, + LPVOID *Buffer) { LPVOID LocalBuffer = NULL; PUSER_INFO_0 UserInfo0; PUSER_INFO_1 UserInfo1; + PUSER_INFO_10 UserInfo10; PUSER_INFO_20 UserInfo20; LPWSTR Ptr; ULONG Size = 0; @@ -196,7 +169,20 @@ BuildInfoBuffer(PUSER_ACCOUNT_INFORMATION UserInfo, // case 2: // case 3: // case 4: -// case 10: + + case 10: + Size = sizeof(USER_INFO_10) + + UserInfo->UserName.Length + sizeof(WCHAR); + + if (UserInfo->AdminComment.Length > 0) + Size += UserInfo->AdminComment.Length + sizeof(WCHAR); + + /* FIXME: Add user comment here */ + + if (UserInfo->FullName.Length > 0) + Size += UserInfo->FullName.Length + sizeof(WCHAR); + break; + // case 11: case 20: @@ -221,6 +207,8 @@ BuildInfoBuffer(PUSER_ACCOUNT_INFORMATION UserInfo, if (ApiStatus != NERR_Success) goto done; + ZeroMemory(LocalBuffer, Size); + switch (level) { case 0: @@ -292,54 +280,95 @@ BuildInfoBuffer(PUSER_ACCOUNT_INFORMATION UserInfo, } break; -// case 2: -// case 3: -// case 10: -// case 11: +// case 2: +// case 3: +// case 4: - case 20: - UserInfo20 = (PUSER_INFO_20)LocalBuffer; + case 10: + UserInfo10 = (PUSER_INFO_10)LocalBuffer; - Ptr = (LPWSTR)((ULONG_PTR)UserInfo20 + sizeof(USER_INFO_20)); + Ptr = (LPWSTR)((ULONG_PTR)UserInfo10 + sizeof(USER_INFO_10)); - UserInfo20->usri20_name = Ptr; + UserInfo10->usri10_name = Ptr; - memcpy(UserInfo20->usri20_name, - UserInfo->UserName.Buffer, - UserInfo->UserName.Length); - UserInfo20->usri20_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL; + memcpy(UserInfo10->usri10_name, + UserInfo->UserName.Buffer, + UserInfo->UserName.Length); + UserInfo10->usri10_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL; - Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR)); + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR)); - if (UserInfo->FullName.Length > 0) - { - UserInfo20->usri20_full_name = Ptr; + if (UserInfo->AdminComment.Length > 0) + { + UserInfo10->usri10_comment = Ptr; - memcpy(UserInfo20->usri20_full_name, - UserInfo->FullName.Buffer, - UserInfo->FullName.Length); - UserInfo20->usri20_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL; + memcpy(UserInfo10->usri10_comment, + UserInfo->AdminComment.Buffer, + UserInfo->AdminComment.Length); + UserInfo10->usri10_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; - Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR)); - } + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR)); + } - if (UserInfo->AdminComment.Length > 0) - { - UserInfo20->usri20_comment = Ptr; + /* FIXME: Add user comment here */ - memcpy(UserInfo20->usri20_comment, - UserInfo->AdminComment.Buffer, - UserInfo->AdminComment.Length); - UserInfo20->usri20_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; + if (UserInfo->FullName.Length > 0) + { + UserInfo10->usri10_full_name = Ptr; - Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR)); - } + memcpy(UserInfo10->usri10_full_name, + UserInfo->FullName.Buffer, + UserInfo->FullName.Length); + UserInfo10->usri10_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL; + } + break; - UserInfo20->usri20_flags = UserInfo->UserAccountControl; - UserInfo20->usri20_user_id = RelativeId; - break; -// case 23: +// case 11: + + case 20: + UserInfo20 = (PUSER_INFO_20)LocalBuffer; + + Ptr = (LPWSTR)((ULONG_PTR)UserInfo20 + sizeof(USER_INFO_20)); + + UserInfo20->usri20_name = Ptr; + + memcpy(UserInfo20->usri20_name, + UserInfo->UserName.Buffer, + UserInfo->UserName.Length); + UserInfo20->usri20_name[UserInfo->UserName.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->UserName.Length + sizeof(WCHAR)); + + if (UserInfo->FullName.Length > 0) + { + UserInfo20->usri20_full_name = Ptr; + + memcpy(UserInfo20->usri20_full_name, + UserInfo->FullName.Buffer, + UserInfo->FullName.Length); + UserInfo20->usri20_full_name[UserInfo->FullName.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->FullName.Length + sizeof(WCHAR)); + } + + if (UserInfo->AdminComment.Length > 0) + { + UserInfo20->usri20_comment = Ptr; + + memcpy(UserInfo20->usri20_comment, + UserInfo->AdminComment.Buffer, + UserInfo->AdminComment.Length); + UserInfo20->usri20_comment[UserInfo->AdminComment.Length / sizeof(WCHAR)] = UNICODE_NULL; + + Ptr = (LPWSTR)((ULONG_PTR)Ptr + UserInfo->AdminComment.Length + sizeof(WCHAR)); + } + + UserInfo20->usri20_flags = UserInfo->UserAccountControl; + UserInfo20->usri20_user_id = RelativeId; + break; + +// case 23: } done: @@ -729,13 +758,13 @@ NetUserEnum(LPCWSTR servername, SamCloseHandle(UserHandle); UserHandle = NULL; - ApiStatus = BuildInfoBuffer(UserInfo, - level, - CurrentUser->RelativeId, - &Buffer); + ApiStatus = BuildUserInfoBuffer(UserInfo, + level, + CurrentUser->RelativeId, + &Buffer); if (ApiStatus != NERR_Success) { - ERR("BuildInfoBuffer failed (ApiStatus %lu)\n", ApiStatus); + ERR("BuildUserInfoBuffer failed (ApiStatus %lu)\n", ApiStatus); goto done; } @@ -837,172 +866,141 @@ NetUserGetInfo(LPCWSTR servername, DWORD level, LPBYTE* bufptr) { - NET_API_STATUS status; - TRACE("(%s, %s, %d, %p)\n", debugstr_w(servername), debugstr_w(username), - level, bufptr); - status = NETAPI_ValidateServername(servername); - if (status != NERR_Success) - return status; + UNICODE_STRING ServerName; + UNICODE_STRING UserName; + SAM_HANDLE ServerHandle = NULL; + SAM_HANDLE AccountDomainHandle = NULL; + SAM_HANDLE UserHandle = NULL; + PSID DomainSid = NULL; + PULONG RelativeIds = NULL; + PSID_NAME_USE Use = NULL; + PUSER_ACCOUNT_INFORMATION UserInfo = NULL; + LPVOID Buffer = NULL; + NET_API_STATUS ApiStatus = NERR_Success; + NTSTATUS Status = STATUS_SUCCESS; + + TRACE("(%s, %s, %d, %p)\n", debugstr_w(servername), + debugstr_w(username), level, bufptr); + + if (servername != NULL) + RtlInitUnicodeString(&ServerName, servername); + + RtlInitUnicodeString(&UserName, username); - if(!NETAPI_IsLocalComputer(servername)) + /* Connect to the SAM Server */ + Status = SamConnect((servername != NULL) ? &ServerName : NULL, + &ServerHandle, + SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, + NULL); + if (!NT_SUCCESS(Status)) { - FIXME("Only implemented for local computer, but remote server" - "%s was requested.\n", debugstr_w(servername)); - return NERR_InvalidComputer; + ERR("SamConnect failed (Status %08lx)\n", Status); + ApiStatus = NetpNtStatusToApiStatus(Status); + goto done; } - if(!NETAPI_FindUser(username) && !NETAPI_IsCurrentUser(username)) + /* Get the Account Domain SID */ + Status = GetAccountDomainSid((servername != NULL) ? &ServerName : NULL, + &DomainSid); + if (!NT_SUCCESS(Status)) { - TRACE("User %s is unknown.\n", debugstr_w(username)); - return NERR_UserNotFound; + ERR("GetAccountDomainSid failed (Status %08lx)\n", Status); + ApiStatus = NetpNtStatusToApiStatus(Status); + goto done; } - switch (level) - { - case 0: + /* Open the Account Domain */ + Status = SamOpenDomain(ServerHandle, + DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP, + DomainSid, + &AccountDomainHandle); + if (!NT_SUCCESS(Status)) { - PUSER_INFO_0 ui; - int name_sz; + ERR("SamOpenDomain failed (Status %08lx)\n", Status); + ApiStatus = NetpNtStatusToApiStatus(Status); + goto done; + } - name_sz = lstrlenW(username) + 1; + /* Get the RID for the given user name */ + Status = SamLookupNamesInDomain(AccountDomainHandle, + 1, + &UserName, + &RelativeIds, + &Use); + if (!NT_SUCCESS(Status)) + { + ERR("SamOpenDomain failed (Status %08lx)\n", Status); + ApiStatus = NetpNtStatusToApiStatus(Status); + goto done; + } - /* set up buffer */ - NetApiBufferAllocate(sizeof(USER_INFO_0) + name_sz * sizeof(WCHAR), - (LPVOID *) bufptr); + /* Check if the account is a user account */ + if (Use[0] != SidTypeUser) + { + ERR("No user found!\n"); + ApiStatus = NERR_UserNotFound; + goto done; + } - ui = (PUSER_INFO_0) *bufptr; - ui->usri0_name = (LPWSTR) (*bufptr + sizeof(USER_INFO_0)); + TRACE("RID: %lu\n", RelativeIds[0]); - /* get data */ - lstrcpyW(ui->usri0_name, username); - break; + /* Open the user object */ + Status = SamOpenUser(AccountDomainHandle, + USER_READ_GENERAL | USER_READ_PREFERENCES | USER_READ_LOGON | USER_READ_ACCOUNT, + RelativeIds[0], + &UserHandle); + if (!NT_SUCCESS(Status)) + { + ERR("SamOpenUser failed (Status %08lx)\n", Status); + ApiStatus = NetpNtStatusToApiStatus(Status); + goto done; } - case 10: + Status = SamQueryInformationUser(UserHandle, + UserAccountInformation, + (PVOID *)&UserInfo); + if (!NT_SUCCESS(Status)) { - PUSER_INFO_10 ui; - PUSER_INFO_0 ui0; - NET_API_STATUS status; - /* sizes of the field buffers in WCHARS */ - int name_sz, comment_sz, usr_comment_sz, full_name_sz; - - comment_sz = 1; - usr_comment_sz = 1; - full_name_sz = 1; - - /* get data */ - status = NetUserGetInfo(servername, username, 0, (LPBYTE *) &ui0); - if (status != NERR_Success) - { - NetApiBufferFree(ui0); - return status; - } - name_sz = lstrlenW(ui0->usri0_name) + 1; - - /* set up buffer */ - NetApiBufferAllocate(sizeof(USER_INFO_10) + - (name_sz + comment_sz + usr_comment_sz + - full_name_sz) * sizeof(WCHAR), - (LPVOID *) bufptr); - ui = (PUSER_INFO_10) *bufptr; - ui->usri10_name = (LPWSTR) (*bufptr + sizeof(USER_INFO_10)); - ui->usri10_comment = (LPWSTR) ( - ((PBYTE) ui->usri10_name) + name_sz * sizeof(WCHAR)); - ui->usri10_usr_comment = (LPWSTR) ( - ((PBYTE) ui->usri10_comment) + comment_sz * sizeof(WCHAR)); - ui->usri10_full_name = (LPWSTR) ( - ((PBYTE) ui->usri10_usr_comment) + usr_comment_sz * sizeof(WCHAR)); - - /* set data */ - lstrcpyW(ui->usri10_name, ui0->usri0_name); - NetApiBufferFree(ui0); - ui->usri10_comment[0] = 0; - ui->usri10_usr_comment[0] = 0; - ui->usri10_full_name[0] = 0; - break; + ERR("SamQueryInformationUser failed (Status %08lx)\n", Status); + ApiStatus = NetpNtStatusToApiStatus(Status); + goto done; } - case 1: - { - static const WCHAR homedirW[] = {'H','O','M','E',0}; - PUSER_INFO_1 ui; - PUSER_INFO_0 ui0; - NET_API_STATUS status; - /* sizes of the field buffers in WCHARS */ - int name_sz, password_sz, home_dir_sz, comment_sz, script_path_sz; - - password_sz = 1; /* not filled out for security reasons for NetUserGetInfo*/ - comment_sz = 1; - script_path_sz = 1; - - /* get data */ - status = NetUserGetInfo(servername, username, 0, (LPBYTE *) &ui0); - if (status != NERR_Success) - { - NetApiBufferFree(ui0); - return status; - } - name_sz = lstrlenW(ui0->usri0_name) + 1; - home_dir_sz = GetEnvironmentVariableW(homedirW, NULL,0); - /* set up buffer */ - NetApiBufferAllocate(sizeof(USER_INFO_1) + - (name_sz + password_sz + home_dir_sz + - comment_sz + script_path_sz) * sizeof(WCHAR), - (LPVOID *) bufptr); - - ui = (PUSER_INFO_1) *bufptr; - ui->usri1_name = (LPWSTR) (ui + 1); - ui->usri1_password = ui->usri1_name + name_sz; - ui->usri1_home_dir = ui->usri1_password + password_sz; - ui->usri1_comment = ui->usri1_home_dir + home_dir_sz; - ui->usri1_script_path = ui->usri1_comment + comment_sz; - /* set data */ - lstrcpyW(ui->usri1_name, ui0->usri0_name); - NetApiBufferFree(ui0); - ui->usri1_password[0] = 0; - ui->usri1_password_age = 0; - ui->usri1_priv = 0; - GetEnvironmentVariableW(homedirW, ui->usri1_home_dir,home_dir_sz); - ui->usri1_comment[0] = 0; - ui->usri1_flags = 0; - ui->usri1_script_path[0] = 0; - break; - } - case 2: - case 3: - case 4: - case 11: - case 20: - case 23: - case 1003: - case 1005: - case 1006: - case 1007: - case 1008: - case 1009: - case 1010: - case 1011: - case 1012: - case 1013: - case 1014: - case 1017: - case 1018: - case 1020: - case 1023: - case 1024: - case 1025: - case 1051: - case 1052: - case 1053: + ApiStatus = BuildUserInfoBuffer(UserInfo, + level, + RelativeIds[0], + &Buffer); + if (ApiStatus != NERR_Success) { - FIXME("Level %d is not implemented\n", level); - return NERR_InternalError; - } - default: - TRACE("Invalid level %d is specified\n", level); - return ERROR_INVALID_LEVEL; + ERR("BuildUserInfoBuffer failed (ApiStatus %08lu)\n", ApiStatus); + goto done; } - return NERR_Success; + +done: + if (UserInfo != NULL) + FreeUserInfo(UserInfo); + + if (UserHandle != NULL) + SamCloseHandle(UserHandle); + + if (RelativeIds != NULL) + SamFreeMemory(RelativeIds); + + if (Use != NULL) + SamFreeMemory(Use); + + if (DomainSid != NULL) + RtlFreeHeap(RtlGetProcessHeap(), 0, DomainSid); + + if (AccountDomainHandle != NULL) + SamCloseHandle(AccountDomainHandle); + + if (ServerHandle != NULL) + SamCloseHandle(ServerHandle); + + *bufptr = (LPBYTE)Buffer; + + return ApiStatus; }