NTSTATUS SetAdministratorPassword(LPCWSTR Password) { PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL; PUSER_ACCOUNT_NAME_INFORMATION AccountNameInfo = NULL; USER_SET_PASSWORD_INFORMATION PasswordInfo; LSA_OBJECT_ATTRIBUTES ObjectAttributes; LSA_HANDLE PolicyHandle = NULL; SAM_HANDLE ServerHandle = NULL; SAM_HANDLE DomainHandle = NULL; SAM_HANDLE UserHandle = NULL; NTSTATUS Status; DPRINT1("SYSSETUP: SetAdministratorPassword(%S)\n", Password); memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES)); ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES); Status = LsaOpenPolicy(NULL, &ObjectAttributes, POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN, &PolicyHandle); if (Status != STATUS_SUCCESS) { DPRINT1("LsaOpenPolicy() failed (Status: 0x%08lx)\n", Status); return Status; } Status = LsaQueryInformationPolicy(PolicyHandle, PolicyAccountDomainInformation, (PVOID *)&OrigInfo); if (!NT_SUCCESS(Status)) { DPRINT1("LsaQueryInformationPolicy() failed (Status: 0x%08lx)\n", Status); goto done; } Status = SamConnect(NULL, &ServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("SamConnect() failed (Status: 0x%08lx)\n", Status); goto done; } Status = SamOpenDomain(ServerHandle, DOMAIN_LOOKUP, OrigInfo->DomainSid, &DomainHandle); if (!NT_SUCCESS(Status)) { DPRINT1("SamOpenDomain() failed (Status: 0x%08lx)\n", Status); goto done; } Status = SamOpenUser(DomainHandle, USER_FORCE_PASSWORD_CHANGE | USER_READ_GENERAL, DOMAIN_USER_RID_ADMIN, &UserHandle); if (!NT_SUCCESS(Status)) { DPRINT1("SamOpenUser() failed (Status %08lx)\n", Status); goto done; } RtlInitUnicodeString(&PasswordInfo.Password, Password); PasswordInfo.PasswordExpired = FALSE; Status = SamSetInformationUser(UserHandle, UserSetPasswordInformation, (PVOID)&PasswordInfo); if (!NT_SUCCESS(Status)) { DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status); goto done; } Status = SamQueryInformationUser(UserHandle, UserAccountNameInformation, (PVOID*)&AccountNameInfo); if (!NT_SUCCESS(Status)) { DPRINT1("SamSetInformationUser() failed (Status %08lx)\n", Status); goto done; } AdminInfo.Name = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, AccountNameInfo->UserName.Length + sizeof(WCHAR)); if (AdminInfo.Name != NULL) RtlCopyMemory(AdminInfo.Name, AccountNameInfo->UserName.Buffer, AccountNameInfo->UserName.Length); AdminInfo.Domain = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, OrigInfo->DomainName.Length + sizeof(WCHAR)); if (AdminInfo.Domain != NULL) RtlCopyMemory(AdminInfo.Domain, OrigInfo->DomainName.Buffer, OrigInfo->DomainName.Length); AdminInfo.Password = RtlAllocateHeap(RtlGetProcessHeap(), 0, (wcslen(Password) + 1) * sizeof(WCHAR)); if (AdminInfo.Password != NULL) wcscpy(AdminInfo.Password, Password); DPRINT("Administrator Name: %S\n", AdminInfo.Name); DPRINT("Administrator Domain: %S\n", AdminInfo.Domain); DPRINT("Administrator Password: %S\n", AdminInfo.Password); done: if (AccountNameInfo != NULL) SamFreeMemory(AccountNameInfo); if (OrigInfo != NULL) LsaFreeMemory(OrigInfo); if (PolicyHandle != NULL) LsaClose(PolicyHandle); if (UserHandle != NULL) SamCloseHandle(UserHandle); if (DomainHandle != NULL) SamCloseHandle(DomainHandle); if (ServerHandle != NULL) SamCloseHandle(ServerHandle); DPRINT1("SYSSETUP: SetAdministratorPassword() done (Status %08lx)\n", Status); return Status; }
NTSTATUS SetAccountDomain(LPCWSTR DomainName, PSID DomainSid) { PPOLICY_ACCOUNT_DOMAIN_INFO OrigInfo = NULL; POLICY_ACCOUNT_DOMAIN_INFO Info; LSA_OBJECT_ATTRIBUTES ObjectAttributes; LSA_HANDLE PolicyHandle; SAM_HANDLE ServerHandle = NULL; SAM_HANDLE DomainHandle = NULL; DOMAIN_NAME_INFORMATION DomainNameInfo; NTSTATUS Status; DPRINT1("SYSSETUP: SetAccountDomain\n"); memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES)); ObjectAttributes.Length = sizeof(LSA_OBJECT_ATTRIBUTES); Status = LsaOpenPolicy(NULL, &ObjectAttributes, POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN, &PolicyHandle); if (Status != STATUS_SUCCESS) { DPRINT("LsaOpenPolicy failed (Status: 0x%08lx)\n", Status); return Status; } Status = LsaQueryInformationPolicy(PolicyHandle, PolicyAccountDomainInformation, (PVOID *)&OrigInfo); if (Status == STATUS_SUCCESS && OrigInfo != NULL) { if (DomainName == NULL) { Info.DomainName.Buffer = OrigInfo->DomainName.Buffer; Info.DomainName.Length = OrigInfo->DomainName.Length; Info.DomainName.MaximumLength = OrigInfo->DomainName.MaximumLength; } else { Info.DomainName.Buffer = (LPWSTR)DomainName; Info.DomainName.Length = wcslen(DomainName) * sizeof(WCHAR); Info.DomainName.MaximumLength = Info.DomainName.Length + sizeof(WCHAR); } if (DomainSid == NULL) Info.DomainSid = OrigInfo->DomainSid; else Info.DomainSid = DomainSid; } else { Info.DomainName.Buffer = (LPWSTR)DomainName; Info.DomainName.Length = wcslen(DomainName) * sizeof(WCHAR); Info.DomainName.MaximumLength = Info.DomainName.Length + sizeof(WCHAR); Info.DomainSid = DomainSid; } Status = LsaSetInformationPolicy(PolicyHandle, PolicyAccountDomainInformation, (PVOID)&Info); if (Status != STATUS_SUCCESS) { DPRINT("LsaSetInformationPolicy failed (Status: 0x%08lx)\n", Status); } if (OrigInfo != NULL) LsaFreeMemory(OrigInfo); LsaClose(PolicyHandle); DomainNameInfo.DomainName.Length = wcslen(DomainName) * sizeof(WCHAR); DomainNameInfo.DomainName.MaximumLength = (wcslen(DomainName) + 1) * sizeof(WCHAR); DomainNameInfo.DomainName.Buffer = (LPWSTR)DomainName; Status = SamConnect(NULL, &ServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, NULL); if (NT_SUCCESS(Status)) { Status = SamOpenDomain(ServerHandle, DOMAIN_WRITE_OTHER_PARAMETERS, Info.DomainSid, &DomainHandle); if (NT_SUCCESS(Status)) { Status = SamSetInformationDomain(DomainHandle, DomainNameInformation, (PVOID)&DomainNameInfo); if (!NT_SUCCESS(Status)) { DPRINT1("SamSetInformationDomain failed (Status: 0x%08lx)\n", Status); } SamCloseHandle(DomainHandle); } else { DPRINT1("SamOpenDomain failed (Status: 0x%08lx)\n", Status); } SamCloseHandle(ServerHandle); } return Status; }
void impersonateToGetData(PCSTR user, PCSTR domain, PCSTR password, PCSTR kdc, PSID *sid, DWORD *rid, PCSTR usingWhat) { NTSTATUS status; DWORD ret, *aRid, *usage; ANSI_STRING aUser, aKdc, aDomain, aPass, aProg; UNICODE_STRING uUser, uKdc, uDomain, uPass, uProg; SAMPR_HANDLE hServerHandle, hDomainHandle; PSID domainSid; HANDLE hToken, hNewToken; PROCESS_INFORMATION processInfos; STARTUPINFOW startupInfo; RtlZeroMemory(&startupInfo, sizeof(STARTUPINFOW)); startupInfo.cb = sizeof(STARTUPINFOW); RtlInitString(&aUser, user); RtlInitString(&aKdc, kdc); RtlInitString(&aDomain, domain); RtlInitString(&aPass, password); RtlInitString(&aProg, usingWhat ? usingWhat : "winver.exe"); if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uUser, &aUser, TRUE))) { if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uKdc, &aKdc, TRUE))) { if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uDomain, &aDomain, TRUE))) { if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uPass, &aPass, TRUE))) { if(NT_SUCCESS(RtlAnsiStringToUnicodeString(&uProg, &aProg, TRUE))) { if(CreateProcessWithLogonW(uUser.Buffer, uDomain.Buffer, uPass.Buffer, LOGON_NETCREDENTIALS_ONLY, uProg.Buffer, NULL, CREATE_SUSPENDED, NULL, NULL, &startupInfo, &processInfos)) { if(OpenProcessToken(processInfos.hProcess, TOKEN_DUPLICATE, &hToken)) { if(DuplicateTokenEx(hToken, TOKEN_QUERY | TOKEN_IMPERSONATE, NULL, SecurityDelegation, TokenImpersonation, &hNewToken)) { if(SetThreadToken(NULL, hNewToken)) { kprintf("[AUTH] Impersonation\n"); if(!(*sid && *rid)) { kprintf("[SID/RID] \'%s @ %s\' must be translated to SID/RID\n", user, domain); status = SamConnect(&uKdc, &hServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, FALSE); if(NT_SUCCESS(status)) { status = SamLookupDomainInSamServer(hServerHandle, &uDomain, &domainSid); if(NT_SUCCESS(status)) { status = SamOpenDomain(hServerHandle, DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP, domainSid, &hDomainHandle); if(NT_SUCCESS(status)) { status = SamLookupNamesInDomain(hDomainHandle, 1, &uUser, &aRid, &usage); if(NT_SUCCESS(status)) *rid = *aRid; else PRINT_ERROR("SamLookupNamesInDomain %08x\n", status); } else PRINT_ERROR("SamOpenDomain %08x\n", status); ret = GetLengthSid(domainSid); if(*sid = (PSID) LocalAlloc(LPTR, ret)) { if(!CopySid(ret, *sid, domainSid)) { *sid = (PSID) LocalFree(*sid); PRINT_ERROR_AUTO("CopySid"); } } SamFreeMemory(domainSid); } else PRINT_ERROR("SamLookupDomainInSamServer %08x\n", status); SamCloseHandle(hServerHandle); } else PRINT_ERROR("SamConnect %08x\n", status); } RevertToSelf(); } else PRINT_ERROR_AUTO("SetThreadToken"); CloseHandle(hNewToken); } else PRINT_ERROR_AUTO("DuplicateTokenEx"); CloseHandle(hToken); } else PRINT_ERROR_AUTO("OpenProcessToken"); TerminateProcess(processInfos.hProcess, 0); CloseHandle(processInfos.hProcess); CloseHandle(processInfos.hThread); } else PRINT_ERROR_AUTO("CreateProcessWithLogonW"); RtlFreeUnicodeString(&uProg); } RtlFreeUnicodeString(&uPass); } RtlFreeUnicodeString(&uDomain); } RtlFreeUnicodeString(&uKdc); } RtlFreeUnicodeString(&uUser); } }
NTSTATUS kuhl_m_net_user(int argc, wchar_t * argv[]) { NTSTATUS status, enumDomainStatus, enumUserStatus; UNICODE_STRING serverName, *groupName; SAMPR_HANDLE hServerHandle, hBuiltinHandle = NULL, hDomainHandle, hUserHandle; DWORD domainEnumerationContext, domainCountRetourned, userEnumerationContext, userCountRetourned, groupsCountRetourned, i, j, k, *usage, aliasCountRetourned, *alias; PSAMPR_RID_ENUMERATION pEnumDomainBuffer, pEnumUsersBuffer; PSID domainSid, userSid; PGROUP_MEMBERSHIP pGroupMemberShip; SID builtin = {1, 1, {0, 0, 0, 0, 0, 5}, {32}}; RtlInitUnicodeString(&serverName, argc ? argv[0] : L""); status = SamConnect(&serverName, &hServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_ENUMERATE_DOMAINS | SAM_SERVER_LOOKUP_DOMAIN, FALSE); if(NT_SUCCESS(status)) { status = SamOpenDomain(hServerHandle, DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP, &builtin, &hBuiltinHandle); if(!NT_SUCCESS(status)) PRINT_ERROR(L"SamOpenDomain Builtin (?) %08x\n", status); domainEnumerationContext = 0; do { enumDomainStatus = SamEnumerateDomainsInSamServer(hServerHandle, &domainEnumerationContext, &pEnumDomainBuffer, 1, &domainCountRetourned); if(NT_SUCCESS(enumDomainStatus) || enumDomainStatus == STATUS_MORE_ENTRIES) { for(i = 0; i < domainCountRetourned; i++) { kprintf(L"\nDomain name : %wZ", &pEnumDomainBuffer[i].Name); status = SamLookupDomainInSamServer(hServerHandle, &pEnumDomainBuffer[i].Name, &domainSid); if(NT_SUCCESS(status)) { kprintf(L"\nDomain SID : "); kull_m_string_displaySID(domainSid); status = SamOpenDomain(hServerHandle, DOMAIN_LIST_ACCOUNTS | DOMAIN_LOOKUP, domainSid, &hDomainHandle); if(NT_SUCCESS(status)) { userEnumerationContext = 0; do { enumUserStatus = SamEnumerateUsersInDomain(hDomainHandle, &userEnumerationContext, 0/*UF_NORMAL_ACCOUNT*/, &pEnumUsersBuffer, 1, &userCountRetourned); if(NT_SUCCESS(enumUserStatus) || enumUserStatus == STATUS_MORE_ENTRIES) { for(j = 0; j < userCountRetourned; j++) { kprintf(L"\n %-5u %wZ", pEnumUsersBuffer[j].RelativeId, &pEnumUsersBuffer[j].Name); status = SamOpenUser(hDomainHandle, USER_READ_GROUP_INFORMATION | USER_LIST_GROUPS | USER_READ_ACCOUNT | USER_READ_LOGON | USER_READ_PREFERENCES | USER_READ_GENERAL, pEnumUsersBuffer[j].RelativeId, &hUserHandle); if(NT_SUCCESS(status)) { status = SamGetGroupsForUser(hUserHandle, &pGroupMemberShip, &groupsCountRetourned); if(NT_SUCCESS(status)) { for(k = 0; k < groupsCountRetourned; k++) { kprintf(L"\n | %-5u ", pGroupMemberShip[k].RelativeId); status = SamLookupIdsInDomain(hDomainHandle, 1, &pGroupMemberShip[k].RelativeId, &groupName, &usage); if(NT_SUCCESS(status)) { kprintf(L"%wZ", groupName); SamFreeMemory(groupName); SamFreeMemory(usage); } else PRINT_ERROR(L"SamLookupIdsInDomain %08x", status); } SamFreeMemory(pGroupMemberShip); } else PRINT_ERROR(L"SamGetGroupsForUser %08x", status); status = SamRidToSid(hUserHandle, pEnumUsersBuffer[j].RelativeId, &userSid); if(NT_SUCCESS(status)) { status = SamGetAliasMembership(hDomainHandle, 1, &userSid, &aliasCountRetourned, &alias); if(NT_SUCCESS(status)) { for(k = 0; k < aliasCountRetourned; k++) { kprintf(L"\n |`%-5u ", alias[k]); status = SamLookupIdsInDomain(hDomainHandle, 1, &alias[k], &groupName, &usage); if(NT_SUCCESS(status)) { kprintf(L"%wZ", groupName); SamFreeMemory(groupName); SamFreeMemory(usage); } else PRINT_ERROR(L"SamLookupIdsInDomain %08x", status); } SamFreeMemory(alias); } else PRINT_ERROR(L"SamGetAliasMembership %08x", status); if(hBuiltinHandle) { status = SamGetAliasMembership(hBuiltinHandle, 1, &userSid, &aliasCountRetourned, &alias); if(NT_SUCCESS(status)) { for(k = 0; k < aliasCountRetourned; k++) { kprintf(L"\n |´%-5u ", alias[k]); status = SamLookupIdsInDomain(hBuiltinHandle, 1, &alias[k], &groupName, &usage); if(NT_SUCCESS(status)) { kprintf(L"%wZ", groupName); SamFreeMemory(groupName); SamFreeMemory(usage); } else PRINT_ERROR(L"SamLookupIdsInDomain %08x", status); } SamFreeMemory(alias); } else PRINT_ERROR(L"SamGetAliasMembership %08x", status); } SamFreeMemory(userSid); } else PRINT_ERROR(L"SamRidToSid %08x", status); } else PRINT_ERROR(L"SamOpenUser %08x", status); } SamFreeMemory(pEnumUsersBuffer); } else PRINT_ERROR(L"SamEnumerateUsersInDomain %08x", enumUserStatus); } while(enumUserStatus == STATUS_MORE_ENTRIES); SamCloseHandle(hDomainHandle); } else PRINT_ERROR(L"SamOpenDomain %08x", status); SamFreeMemory(domainSid); } else PRINT_ERROR(L"SamLookupDomainInSamServer %08x", status); } SamFreeMemory(pEnumDomainBuffer); } else PRINT_ERROR(L"SamEnumerateDomainsInSamServer %08x\n", enumDomainStatus); kprintf(L"\n"); } while(enumDomainStatus == STATUS_MORE_ENTRIES); if(hBuiltinHandle) SamCloseHandle(hBuiltinHandle); SamCloseHandle(hServerHandle); } else PRINT_ERROR(L"SamConnect %08x\n", status); return ERROR_SUCCESS; }
NET_API_STATUS WINAPI NetQueryDisplayInformation( _In_ LPCWSTR ServerName, _In_ DWORD Level, _In_ DWORD Index, _In_ DWORD EntriesRequested, _In_ DWORD PreferredMaximumLength, _Out_ LPDWORD ReturnedEntryCount, _Out_ PVOID *SortedBuffer) { UNICODE_STRING ServerNameString; SAM_HANDLE ServerHandle = NULL; SAM_HANDLE DomainHandle = NULL; DOMAIN_DISPLAY_INFORMATION DisplayInformation; DWORD LocalTotalBytesAvailable; DWORD LocalTotalBytesReturned; DWORD LocalReturnedEntryCount; PVOID LocalSortedBuffer; NET_API_STATUS ApiStatus = NERR_Success; NTSTATUS Status; TRACE("NetQueryDisplayInformation(%s, %ld, %ld, %ld, %ld, %p, %p)\n", debugstr_w(ServerName), Level, Index, EntriesRequested, PreferredMaximumLength, ReturnedEntryCount, SortedBuffer); *ReturnedEntryCount = 0; *SortedBuffer = NULL; switch (Level) { case 1: DisplayInformation = DomainDisplayUser; break; case 2: DisplayInformation = DomainDisplayMachine; break; case 3: DisplayInformation = DomainDisplayGroup; break; default: return ERROR_INVALID_LEVEL; } if (ServerName != NULL) RtlInitUnicodeString(&ServerNameString, ServerName); /* Connect to the SAM Server */ Status = SamConnect((ServerName != NULL) ? &ServerNameString : NULL, &ServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, NULL); if (!NT_SUCCESS(Status)) { ERR("SamConnect failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; } /* Open the Account Domain */ Status = OpenAccountDomain(ServerHandle, (ServerName != NULL) ? &ServerNameString : NULL, DOMAIN_LIST_ACCOUNTS, &DomainHandle); if (!NT_SUCCESS(Status)) { ERR("OpenAccountDomain failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; } /* Query the information */ Status = SamQueryDisplayInformation(DomainHandle, DisplayInformation, Index, EntriesRequested, PreferredMaximumLength, &LocalTotalBytesAvailable, &LocalTotalBytesReturned, &LocalReturnedEntryCount, &LocalSortedBuffer); if (!NT_SUCCESS(Status)) { ERR("SamQueryDisplayInformation failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; } /* FIXME */ done: if (DomainHandle != NULL) SamCloseHandle(DomainHandle); if (ServerHandle != NULL) SamCloseHandle(ServerHandle); return ApiStatus; }
NET_API_STATUS WINAPI NetGetDisplayInformationIndex( _In_ LPCWSTR ServerName, _In_ DWORD Level, _In_ LPCWSTR Prefix, _Out_ LPDWORD Index) { UNICODE_STRING ServerNameString, PrefixString; SAM_HANDLE ServerHandle = NULL; SAM_HANDLE DomainHandle = NULL; DOMAIN_DISPLAY_INFORMATION DisplayInformation; NET_API_STATUS ApiStatus = NERR_Success; NTSTATUS Status; TRACE("NetGetDisplayInformationIndex(%s %ld %s %p)\n", debugstr_w(ServerName), Level, debugstr_w(Prefix), Index); switch (Level) { case 1: DisplayInformation = DomainDisplayUser; break; case 2: DisplayInformation = DomainDisplayMachine; break; case 3: DisplayInformation = DomainDisplayGroup; break; default: return ERROR_INVALID_LEVEL; } if (ServerName != NULL) RtlInitUnicodeString(&ServerNameString, ServerName); /* Connect to the SAM Server */ Status = SamConnect((ServerName != NULL) ? &ServerNameString : NULL, &ServerHandle, SAM_SERVER_CONNECT | SAM_SERVER_LOOKUP_DOMAIN, NULL); if (!NT_SUCCESS(Status)) { ERR("SamConnect failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; } /* Open the Account Domain */ Status = OpenAccountDomain(ServerHandle, (ServerName != NULL) ? &ServerNameString : NULL, DOMAIN_LIST_ACCOUNTS, &DomainHandle); if (!NT_SUCCESS(Status)) { ERR("OpenAccountDomain failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); goto done; } RtlInitUnicodeString(&PrefixString, Prefix); /* Get the index */ Status = SamGetDisplayEnumerationIndex(DomainHandle, DisplayInformation, &PrefixString, Index); if (!NT_SUCCESS(Status)) { ERR("SamGetDisplayEnumerationIndex failed (Status %08lx)\n", Status); ApiStatus = NetpNtStatusToApiStatus(Status); } done: if (DomainHandle != NULL) SamCloseHandle(DomainHandle); if (ServerHandle != NULL) SamCloseHandle(ServerHandle); return ApiStatus; }