int main(void) { // GetCurrentProcess cannot fail HANDLE hProcess = GetCurrentProcess(); if (OpenProcessToken(hProcess, TOKEN_READ, &hProcess)) { LUID seCreateSymbolicLinkPrivilege; if (LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &seCreateSymbolicLinkPrivilege)) { DWORD length; printf("SeCreateSymbolicLinkPrivilege = %ld, %ld\n", seCreateSymbolicLinkPrivilege.HighPart, seCreateSymbolicLinkPrivilege.LowPart); if (!GetTokenInformation(hProcess, TokenPrivileges, NULL, 0, &length)) { if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) { TOKEN_PRIVILEGES* privileges = (TOKEN_PRIVILEGES*)malloc(length); if (GetTokenInformation(hProcess, TokenPrivileges, privileges, length, &length)) { BOOL found = FALSE; DWORD count = privileges->PrivilegeCount; printf("User has %ld privileges\n", count); if (count > 0) { LUID_AND_ATTRIBUTES* privs = privileges->Privileges; while (count-- > 0 && !luid_eq(privs->Luid, seCreateSymbolicLinkPrivilege)) privs++; found = (count > 0); } printf("User does%s have the SeCreateSymbolicLinkPrivilege\n", (found ? "" : "n't")); } else { fprintf(stderr, "Second GetTokenInformation failed\n"); } free(privileges); } else { fprintf(stderr, "First GetTokenInformation failed\n"); } } else { fprintf(stderr, "Impossible output from GetTokenInformation\n"); } } else { fprintf(stderr, "LookupPrivilegeValue failed\n"); } CloseHandle(hProcess); } else { fprintf(stderr, "OpenProcessToken failed\n"); } LSA_HANDLE hPolicy; NTSTATUS r; LSA_OBJECT_ATTRIBUTES attributes = {0, NULL, NULL, 0, NULL, NULL}; attributes.Length = sizeof(attributes); LUID seCreateSymbolicLinkPrivilege; if (LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &seCreateSymbolicLinkPrivilege)) { // POLICY_LOOKUP_NAMES: LsaLookupNames2, LsaEnumerateAccountRights, LsaLookupSids, LsaAddAccountRights // POLICY_VIEW_LOCAL_INFORMATION: LsaEnumerateAccountsWithUserRight // Elevation: LsaEnumerateAccountRights, LsaEnumerateAccountsWithUserRight, LsaRemoveAccountRights, LsaAddAccountRights if (NT_SUCCESS(r = LsaOpenPolicy(NULL, &attributes, POLICY_LOOKUP_NAMES | POLICY_VIEW_LOCAL_INFORMATION, &hPolicy))) { LSA_REFERENCED_DOMAIN_LIST* referencedDomains; LSA_TRANSLATED_SID2* sids; LSA_UNICODE_STRING name; name.Buffer = L"Users"; name.Length = wcslen(name.Buffer) * sizeof(WCHAR); name.MaximumLength = name.Length + sizeof(WCHAR); if (NT_SUCCESS(r = LsaLookupNames2(hPolicy, LSA_LOOKUP_ISOLATED_AS_LOCAL, 1, &name, &referencedDomains, &sids))) { LSA_UNICODE_STRING* rights; ULONG count; LsaFreeMemory(referencedDomains); if (NT_SUCCESS(r = LsaEnumerateAccountRights(hPolicy, sids->Sid, &rights, &count))) { LSA_UNICODE_STRING* right = rights; printf("%ld right%s found\n", count, PLURAL(count)); while (count-- > 0) { printf(" %.*S\n", right->Length / 2, right->Buffer); right++; } LsaFreeMemory(rights); LSA_ENUMERATION_INFORMATION* allSidsRaw; LSA_UNICODE_STRING lsaCreateSymbolicLinkPrivilege; lsaCreateSymbolicLinkPrivilege.Buffer = SE_CREATE_SYMBOLIC_LINK_NAME; lsaCreateSymbolicLinkPrivilege.Length = wcslen(lsaCreateSymbolicLinkPrivilege.Buffer) * sizeof(WCHAR); lsaCreateSymbolicLinkPrivilege.MaximumLength = lsaCreateSymbolicLinkPrivilege.Length + sizeof(WCHAR); if (NT_SUCCESS(r = LsaEnumerateAccountsWithUserRight(hPolicy, &lsaCreateSymbolicLinkPrivilege, (void**)&allSidsRaw, &count))) { LSA_ENUMERATION_INFORMATION* sid = allSidsRaw; PSID* allSids; PSID* p; PLSA_TRANSLATED_NAME names; ULONG i = count; printf("%ld SID%s found\n", count, PLURAL(count)); p = allSids = (PSID*)malloc(count * sizeof(PSID)); while (i-- > 0) *p++ = (sid++)->Sid; if (NT_SUCCESS(r = LsaLookupSids(hPolicy, count, allSids, &referencedDomains, &names))) { PLSA_TRANSLATED_NAME name = names; BOOL usersAssigned = FALSE; LsaFreeMemory(referencedDomains); while (count-- > 0) { LPTSTR sidString; USHORT len = name->Name.Length / 2; ConvertSidToStringSid(*allSids++, &sidString); printf(" %.*S (%S)\n", len, name->Name.Buffer, sidString); usersAssigned |= (len > 4 && !wcsncmp(L"Users", name->Name.Buffer, len)); name++; LocalFree(sidString); } printf("Users had%s got SeCreateSymbolicLinkPrivilege\n", (usersAssigned ? "" : "n't")); if (usersAssigned) { if (!NT_SUCCESS(r = LsaRemoveAccountRights(hPolicy, sids->Sid, FALSE, &lsaCreateSymbolicLinkPrivilege, 1))) { fprintf(stderr, "Lsa failed with code %x\n", r); } } else { if (!NT_SUCCESS(r = LsaAddAccountRights(hPolicy, sids->Sid, &lsaCreateSymbolicLinkPrivilege, 1))) { fprintf(stderr, "LsaAddAccountRights failed with code %x\n", r); } } LsaFreeMemory(names); } else { fprintf(stderr, "LsaLookupSids2 failed with code %x\n", r); } LsaFreeMemory(allSidsRaw); free(allSids); } else { fprintf(stderr, "LsaEnumerateAccountsWithUserRight failed with code %x\n", r); } } else { fprintf(stderr, "LsaEnumerateAccountRights failed with code %x\n", r); } LsaFreeMemory(sids); } else { fprintf(stderr, "LsaLookupNames2 failed with code %x\n", r); } LsaClose(hPolicy); } else { fprintf(stderr, "LsaOpenPolicy failed with code %x\n", r); } } else { fprintf(stderr, "LookupPrivilegeValue failed\n"); } }
BOOL valid_user(LSA_HANDLE lsa_handle, PSID* answer, LPTSTR constant) { LSA_REFERENCED_DOMAIN_LIST* domain = 0; LUID luid; NTSTATUS nt_status; LSA_TRANSLATED_SID* sid = 0; BOOL success; LSA_UNICODE_STRING user; if (!lsa_string_constant(&user, constant)) return FALSE; nt_status = LsaLookupNames(lsa_handle, 1, &user, &domain, &sid); if (nt_status != STATUS_SUCCESS) return lsa_error(nt_status, L"LsaLookupNames"); if (sid->Use != SidTypeUser) { success = print_error(L"Error: expecting <user>"); } else if (sid->DomainIndex < 0 || sid->DomainIndex > domain->Entries) { success = print_error(L"Error: LsaLookupNames domain index out of range."); } else { success = make_relative_sid(answer, domain->Domains[sid->DomainIndex].Sid, sid->RelativeId); } LsaFreeMemory(domain); LsaFreeMemory(sid); return success; }
BOOL lsa_account_from_sid(LSA_HANDLE lsa_handle, PSID sid, PLSA_ACCOUNT account) { LSA_REFERENCED_DOMAIN_LIST* domain = 0; LSA_TRANSLATED_NAME* name = 0; NTSTATUS nt_status; BOOL success; if (sid == NULL) return print_error(L"Error in lsa_account_from_sid: sid is NULL.\n"); if (account == NULL) return print_error(L"Error in lsa_account_from_sid: account is NULL.\n"); nt_status = LsaLookupSids(lsa_handle, 1, &sid, &domain, &name); if (nt_status!=STATUS_SUCCESS) return lsa_error(nt_status, L"LsaLookupSids"); account->use = name->Use; if (name->DomainIndex >= 0 && name->DomainIndex < domain->Entries) success = copy_lsa_string_to_wchar(account->domain, sizeof(account->domain), &domain->Domains[name->DomainIndex].Name); else success = copy_lsa_string_to_wchar(account->domain, sizeof(account->domain), NULL); success &= copy_lsa_string_to_wchar(account->name, sizeof(account->name), &name->Name); LsaFreeMemory(domain); LsaFreeMemory(name); return success; }
NTSTATUS SetAuditEvent( LSA_HANDLE PolicyHandle, POLICY_AUDIT_EVENT_TYPE EventType, POLICY_AUDIT_EVENT_OPTIONS EventOption ) { PPOLICY_AUDIT_EVENTS_INFO pae; NTSTATUS Status; DWORD i; // index into EventAuditingOptions // // obtain AuditEvents // Status = LsaQueryInformationPolicy( PolicyHandle, PolicyAuditEventsInformation, &pae ); if(Status != STATUS_SUCCESS) return Status; // // insure we were passed a valid EventType and EventOption // if((ULONG)EventType > pae->MaximumAuditEventCount || (!EventOption & POLICY_AUDIT_EVENT_MASK) ) { LsaFreeMemory(pae); return STATUS_INVALID_PARAMETER; } // // set all auditevents to the unchanged status... // for(i = 0 ; i < pae->MaximumAuditEventCount ; i++) { pae->EventAuditingOptions[i] = POLICY_AUDIT_EVENT_UNCHANGED; } // // ...and update only the specified EventType // pae->EventAuditingOptions[EventType] = EventOption; // // set the new AuditEvents // Status = LsaSetInformationPolicy( PolicyHandle, PolicyAuditEventsInformation, pae ); // // free allocated memory // LsaFreeMemory(pae); return Status; }
int isDomainMember(wchar_t *wszDomain) { PPOLICY_PRIMARY_DOMAIN_INFO ppdiDomainInfo=NULL; PPOLICY_DNS_DOMAIN_INFO pddiDomainInfo=NULL; LSA_HANDLE PolicyHandle; NTSTATUS status; BOOL retval = FALSE; *wszDomain = '\0'; // open the policy object for the local system status = OpenPolicy( NULL , GENERIC_READ | POLICY_VIEW_LOCAL_INFORMATION , &PolicyHandle ); // You have a handle to the policy object. Now, get the // domain information using LsaQueryInformationPolicy. if ( !status ) { /* Based on patch by Valdas Sevelis. Call PolicyDnsDomainInformation first as Win2K Advanced server is broken w/PolicyPrimaryDomainInformation */ status = LsaQueryInformationPolicy( PolicyHandle, PolicyDnsDomainInformation, (void**)&pddiDomainInfo); if(!status) { retval = pddiDomainInfo->Sid != 0; if(wszDomain && retval) { wcsncpy(wszDomain,pddiDomainInfo->Name.Buffer,pddiDomainInfo->Name.Length/sizeof(wchar_t)); wszDomain[pddiDomainInfo->Name.Length/sizeof(wchar_t)]='\0'; } LsaFreeMemory( (LPVOID)pddiDomainInfo ); } else { status = LsaQueryInformationPolicy( PolicyHandle, PolicyPrimaryDomainInformation, (void**)&ppdiDomainInfo); if(!status) { retval = ppdiDomainInfo->Sid != 0; if(wszDomain && retval) { wcsncpy(wszDomain,ppdiDomainInfo->Name.Buffer,ppdiDomainInfo->Name.Length/sizeof(wchar_t)); wszDomain[ppdiDomainInfo->Name.Length/sizeof(wchar_t)]='\0'; } LsaFreeMemory( (LPVOID)ppdiDomainInfo ); } } } // Clean up all the memory buffers created by the LSA calls LsaClose(PolicyHandle); return retval; }
BOOL lsp_list_by_privilege(LSA_HANDLE lsa_handle, LPTSTR privilegeConstant) { LSA_ACCOUNT account; LSA_ENUMERATION_INFORMATION* array; ULONG count; ULONG i; NTSTATUS nt_status; LSA_UNICODE_STRING privilege; BOOL success = TRUE; if (!valid_privilege(&privilege, privilegeConstant)) return FALSE; print_string(L"Accounts with %s:\n", privilegeConstant); nt_status = LsaEnumerateAccountsWithUserRight(lsa_handle, &privilege, (void**)&array, &count); if (nt_status != STATUS_SUCCESS) return lsa_error(nt_status, L"LsaEnumerateAccountsWithUserRight"); for(i=0; i<count; i++) { if (!lsa_account_from_sid(lsa_handle, array[i].Sid, &account)) { success = FALSE; break; } print_string(L" - "); print_account(&account); print_string(L"\n"); } LsaFreeMemory(array); return TRUE; }
static void test_LsaLookupPrivilegeName(void) { LSA_OBJECT_ATTRIBUTES attrs; LSA_UNICODE_STRING *name; LSA_HANDLE policy; NTSTATUS status; LUID luid; memset(&attrs, 0, sizeof(attrs)); attrs.Length = sizeof(attrs); status = LsaOpenPolicy(NULL, &attrs, POLICY_LOOKUP_NAMES, &policy); ok(status == STATUS_SUCCESS, "Failed to open policy, %#x.\n", status); name = (void *)0xdeadbeef; status = LsaLookupPrivilegeName(policy, NULL, &name); ok(status != STATUS_SUCCESS, "Unexpected status %#x.\n", status); ok(name == (void *)0xdeadbeef, "Unexpected name pointer.\n"); name = (void *)0xdeadbeef; luid.HighPart = 1; luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE; status = LsaLookupPrivilegeName(policy, &luid, &name); ok(status == STATUS_NO_SUCH_PRIVILEGE, "Unexpected status %#x.\n", status); ok(name == NULL, "Unexpected name pointer.\n"); luid.HighPart = 0; luid.LowPart = SE_CREATE_TOKEN_PRIVILEGE; status = LsaLookupPrivilegeName(policy, &luid, &name); ok(status == 0, "got %#x.\n", status); LsaFreeMemory(name); }
static int onterminate_no_sam(struct lm_sam_s *This){ LsaFreeMemory(This->lsa_policy_info_buffer); This->lsa_policy_info_buffer = NULL; This->domain_sid = NULL; This->state = &state_no_sid; return This->state->terminate(This); }
std::vector<std::wstring> GetPrivileges(PSID sid) { LSA_HANDLE hPolicy = OpenPolicy(POLICY_LOOKUP_NAMES); PLSA_UNICODE_STRING userRights = NULL; try { ULONG rightsCount = 0; CheckRetVal(LsaEnumerateAccountRights(hPolicy, sid, &userRights, &rightsCount), ERROR_FILE_NOT_FOUND); std::vector<std::wstring> v; for (int i = 0; i < rightsCount; i++) { std::wstring s(userRights[i].Buffer, userRights[i].Length / sizeof(WCHAR)); v.push_back(s); } LsaFreeMemory(userRights); userRights = NULL; LsaClose(hPolicy); hPolicy = NULL; return v; } catch (const std::exception&) { if (userRights) { LsaFreeMemory(userRights); } if (hPolicy) { LsaClose(hPolicy); } throw; } }
void CDialupass::GetLsaPasswords() { PLSA_UNICODE_STRING PrivateData; char Win2k[]="RasDialParams!%s#0"; char WinXP[]="L$_RasDefaultCredentials#0"; char temp[256]; wsprintf(temp,Win2k,GetLocalSid()); PrivateData=GetLsaData(temp); if(PrivateData!=NULL) { ParseLsaBuffer(PrivateData->Buffer,PrivateData->Length); LsaFreeMemory(PrivateData->Buffer); } PrivateData=GetLsaData(WinXP); if(PrivateData!=NULL) { ParseLsaBuffer(PrivateData->Buffer,PrivateData->Length); LsaFreeMemory(PrivateData->Buffer); } }
NTSTATUS SetAuditMode( LSA_HANDLE PolicyHandle, BOOL bEnable ) { PPOLICY_AUDIT_EVENTS_INFO AuditEvents; NTSTATUS Status; DWORD i; // // obtain current AuditEvents // Status = LsaQueryInformationPolicy( PolicyHandle, PolicyAuditEventsInformation, &AuditEvents ); if(Status != STATUS_SUCCESS) return Status; // // update the relevant member // AuditEvents->AuditingMode = bEnable; // // set all auditevents to the unchanged status... // for(i = 0 ; i < AuditEvents->MaximumAuditEventCount ; i++) { AuditEvents->EventAuditingOptions[i] = POLICY_AUDIT_EVENT_UNCHANGED; } // // set the new auditing mode (enabled or disabled) // Status = LsaSetInformationPolicy( PolicyHandle, PolicyAuditEventsInformation, AuditEvents ); LsaFreeMemory(AuditEvents); return Status; }
BOOL lsp_list_by_user(LSA_HANDLE lsa_handle, LPTSTR user) { LSA_ACCOUNT account; LSA_UNICODE_STRING* array; ULONG count; ULONG i; NTSTATUS nt_status; PSID sid; if (!valid_user(lsa_handle, &sid, user)) return FALSE; if (!lsa_account_from_sid(lsa_handle, sid, &account)) { FreeSid(sid); return FALSE; } print_string(L"Privileges for "); print_account(&account); print_string(L":\n"); nt_status = LsaEnumerateAccountRights(lsa_handle, sid, &array, &count); if (nt_status != STATUS_SUCCESS) { FreeSid(sid); return lsa_error(nt_status, L"LsaEnumerateAccountRights"); } for(i=0; i<count; i++) { print_string(L" - "); print_lsa_string(&array[i]); print_string(L"\n"); } LsaFreeMemory(array); FreeSid(sid); return TRUE; }
static VOID PhpAddAccountsToComboBox( _In_ HWND ComboBoxHandle ) { LSA_HANDLE policyHandle; LSA_ENUMERATION_HANDLE enumerationContext = 0; PLSA_ENUMERATION_INFORMATION buffer; ULONG count; ULONG i; PPH_STRING name; SID_NAME_USE nameUse; if (NT_SUCCESS(PhOpenLsaPolicy(&policyHandle, POLICY_VIEW_LOCAL_INFORMATION, NULL))) { while (NT_SUCCESS(LsaEnumerateAccounts( policyHandle, &enumerationContext, &buffer, 0x100, &count ))) { for (i = 0; i < count; i++) { name = PhGetSidFullName(buffer[i].Sid, TRUE, &nameUse); if (name) { if (nameUse == SidTypeUser) ComboBox_AddString(ComboBoxHandle, name->Buffer); PhDereferenceObject(name); } } LsaFreeMemory(buffer); } LsaClose(policyHandle); } }
NTSTATUS DisplayAudit( LSA_HANDLE PolicyHandle ) { PPOLICY_AUDIT_EVENTS_INFO AuditEvents; NTSTATUS Status; DWORD i; // index into EventAuditingOptions // // obtain AuditEvents // Status = LsaQueryInformationPolicy( PolicyHandle, PolicyAuditEventsInformation, &AuditEvents ); if(Status != STATUS_SUCCESS) return Status; // // successfully obtained AuditEventsInformation. Now display. // if(AuditEvents->AuditingMode) { printf("Auditing Enabled\n"); } else { printf("Auditing Disabled\n"); } for(i = 0 ; i < AuditEvents->MaximumAuditEventCount ; i++) { DisplayAuditEventOption(i, AuditEvents->EventAuditingOptions[i]); } // // free allocated memory // LsaFreeMemory(AuditEvents); return Status; }
/* Hack */ static NTSTATUS SetPrimaryDomain(LPCWSTR DomainName, PSID DomainSid) { PPOLICY_PRIMARY_DOMAIN_INFO OrigInfo = NULL; POLICY_PRIMARY_DOMAIN_INFO Info; LSA_OBJECT_ATTRIBUTES ObjectAttributes; LSA_HANDLE PolicyHandle; NTSTATUS Status; DPRINT1("SYSSETUP: SetPrimaryDomain()\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, PolicyPrimaryDomainInformation, (PVOID *)&OrigInfo); if (Status == STATUS_SUCCESS && OrigInfo != NULL) { if (DomainName == NULL) { Info.Name.Buffer = OrigInfo->Name.Buffer; Info.Name.Length = OrigInfo->Name.Length; Info.Name.MaximumLength = OrigInfo->Name.MaximumLength; } else { Info.Name.Buffer = (LPWSTR)DomainName; Info.Name.Length = wcslen(DomainName) * sizeof(WCHAR); Info.Name.MaximumLength = Info.Name.Length + sizeof(WCHAR); } if (DomainSid == NULL) Info.Sid = OrigInfo->Sid; else Info.Sid = DomainSid; } else { Info.Name.Buffer = (LPWSTR)DomainName; Info.Name.Length = wcslen(DomainName) * sizeof(WCHAR); Info.Name.MaximumLength = Info.Name.Length + sizeof(WCHAR); Info.Sid = DomainSid; } Status = LsaSetInformationPolicy(PolicyHandle, PolicyPrimaryDomainInformation, (PVOID)&Info); if (Status != STATUS_SUCCESS) { DPRINT("LsaSetInformationPolicy failed (Status: 0x%08lx)\n", Status); } if (OrigInfo != NULL) LsaFreeMemory(OrigInfo); LsaClose(PolicyHandle); return Status; }
USHORT SERVICES_grant_privilege(const TEXT* account, pfnSvcError err_handler, const WCHAR* privilege) { /*************************************************** * * S E R V I C E _ g r a n t _ l o g o n _ r i g h t * *************************************************** * * Functional description * Grants the "Log on as a service" right to account. * This is a Windows NT, 2000, XP, 2003 security thing. * To run a service under an account other than LocalSystem, the account * must have this right. To succeed granting the right, the current user * must be an Administrator. * Returns FB_SUCCESS when actually granted the right. * Returns FB_LOGON_SRVC_RIGHT_ALREADY_DEFINED if right was already granted * to the user. * Returns FB_FAILURE on any error. * * OM - AUG 2003 - Initial implementation * OM - SEP 2003 - Control flow revision, no functional change * ***************************************************/ LSA_OBJECT_ATTRIBUTES ObjectAttributes; LSA_HANDLE PolicyHandle; // Open the policy on the local machine. ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes)); NTSTATUS lsaErr = LsaOpenPolicy(NULL, &ObjectAttributes, POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES, &PolicyHandle); if (lsaErr != (NTSTATUS) 0) return (*err_handler)(LsaNtStatusToWinError(lsaErr), "LsaOpenPolicy", NULL); // Obtain the SID of the user/group. // First, dummy call to LookupAccountName to get the required buffer sizes. DWORD cbSid; DWORD cchDomain; cbSid = cchDomain = 0; SID_NAME_USE peUse; LookupAccountName(NULL, account, NULL, &cbSid, NULL, &cchDomain, &peUse); PSID pSid = (PSID) LocalAlloc(LMEM_ZEROINIT, cbSid); if (pSid == 0) { DWORD err = GetLastError(); LsaClose(PolicyHandle); return (*err_handler)(err, "LocalAlloc(Sid)", NULL); } TEXT* pDomain = (LPTSTR) LocalAlloc(LMEM_ZEROINIT, cchDomain); if (pDomain == 0) { DWORD err = GetLastError(); LsaClose(PolicyHandle); LocalFree(pSid); return (*err_handler)(err, "LocalAlloc(Domain)", NULL); } // Now, really obtain the SID of the user/group. if (LookupAccountName(NULL, account, pSid, &cbSid, pDomain, &cchDomain, &peUse) == 0) { DWORD err = GetLastError(); LsaClose(PolicyHandle); LocalFree(pSid); LocalFree(pDomain); return (*err_handler)(err, "LookupAccountName", NULL); } PLSA_UNICODE_STRING UserRights; ULONG CountOfRights = 0; NTSTATUS ntStatus = LsaEnumerateAccountRights(PolicyHandle, pSid, &UserRights, &CountOfRights); if (ntStatus == (NTSTATUS) 0xC0000034L) //STATUS_OBJECT_NAME_NOT_FOUND CountOfRights = 0; // Check if the seServiceLogonRight is already granted ULONG i; for (i = 0; i < CountOfRights; i++) { if (wcscmp(UserRights[i].Buffer, privilege) == 0) break; } LsaFreeMemory(UserRights); // Don't leak LSA_UNICODE_STRING PrivilegeString; if (CountOfRights == 0 || i == CountOfRights) { // Grant the SeServiceLogonRight to users represented by pSid. const int string_buff_size = 100; WCHAR tempStr[string_buff_size]; wcsncpy(tempStr, privilege, string_buff_size - 1); tempStr[string_buff_size - 1] = 0; PrivilegeString.Buffer = tempStr; PrivilegeString.Length = wcslen(tempStr) * sizeof(WCHAR); PrivilegeString.MaximumLength = sizeof(tempStr); if ((lsaErr = LsaAddAccountRights(PolicyHandle, pSid, &PrivilegeString, 1)) != (NTSTATUS) 0) { LsaClose(PolicyHandle); LocalFree(pSid); LocalFree(pDomain); return (*err_handler)(LsaNtStatusToWinError(lsaErr), "LsaAddAccountRights", NULL); } } else { LsaClose(PolicyHandle); LocalFree(pSid); LocalFree(pDomain); return FB_PRIVILEGE_ALREADY_GRANTED; } LsaClose(PolicyHandle); LocalFree(pSid); LocalFree(pDomain); return FB_SUCCESS; }
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; }
/************************************************************ * DsRoleGetPrimaryDomainInformation (NETAPI32.@) * * PARAMS * lpServer [I] Pointer to UNICODE string with ComputerName * InfoLevel [I] Type of data to retrieve * Buffer [O] Pointer to to the requested data * * RETURNS * * NOTES * When lpServer is NULL, use the local computer */ DWORD WINAPI DsRoleGetPrimaryDomainInformation( LPCWSTR lpServer, DSROLE_PRIMARY_DOMAIN_INFO_LEVEL InfoLevel, PBYTE* Buffer) { DWORD ret; FIXME("(%p, %d, %p) stub\n", lpServer, InfoLevel, Buffer); /* Check some input parameters */ if (!Buffer) return ERROR_INVALID_PARAMETER; if ((InfoLevel < DsRolePrimaryDomainInfoBasic) || (InfoLevel > DsRoleOperationState)) return ERROR_INVALID_PARAMETER; *Buffer = NULL; switch (InfoLevel) { case DsRolePrimaryDomainInfoBasic: { LSA_OBJECT_ATTRIBUTES ObjectAttributes; LSA_HANDLE PolicyHandle; PPOLICY_ACCOUNT_DOMAIN_INFO DomainInfo; NTSTATUS NtStatus; int logon_domain_sz; DWORD size; PDSROLE_PRIMARY_DOMAIN_INFO_BASIC basic; ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes)); NtStatus = LsaOpenPolicy(NULL, &ObjectAttributes, POLICY_VIEW_LOCAL_INFORMATION, &PolicyHandle); if (NtStatus != STATUS_SUCCESS) { TRACE("LsaOpenPolicyFailed with NT status %x\n", LsaNtStatusToWinError(NtStatus)); return ERROR_OUTOFMEMORY; } LsaQueryInformationPolicy(PolicyHandle, PolicyAccountDomainInformation, (PVOID*)&DomainInfo); logon_domain_sz = lstrlenW(DomainInfo->DomainName.Buffer) + 1; LsaClose(PolicyHandle); size = sizeof(DSROLE_PRIMARY_DOMAIN_INFO_BASIC) + logon_domain_sz * sizeof(WCHAR); basic = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size); if (basic) { basic->MachineRole = DsRole_RoleStandaloneWorkstation; basic->DomainNameFlat = (LPWSTR)((LPBYTE)basic + sizeof(DSROLE_PRIMARY_DOMAIN_INFO_BASIC)); lstrcpyW(basic->DomainNameFlat, DomainInfo->DomainName.Buffer); ret = ERROR_SUCCESS; } else ret = ERROR_OUTOFMEMORY; *Buffer = (PBYTE)basic; LsaFreeMemory(DomainInfo); } break; default: ret = ERROR_CALL_NOT_IMPLEMENTED; } return ret; }
static void test_LsaLookupNames2(void) { static const WCHAR n1[] = {'L','O','C','A','L',' ','S','E','R','V','I','C','E'}; static const WCHAR n2[] = {'N','T',' ','A','U','T','H','O','R','I','T','Y','\\','L','o','c','a','l','S','e','r','v','i','c','e'}; NTSTATUS status; LSA_HANDLE handle; LSA_OBJECT_ATTRIBUTES attrs; PLSA_REFERENCED_DOMAIN_LIST domains; PLSA_TRANSLATED_SID2 sids; LSA_UNICODE_STRING name[3]; LPSTR account, sid_dom; if ((PRIMARYLANGID(LANGIDFROMLCID(GetSystemDefaultLCID())) != LANG_ENGLISH) || (PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale())) != LANG_ENGLISH)) { skip("Non-English locale (skipping LsaLookupNames2 tests)\n"); return; } memset(&attrs, 0, sizeof(attrs)); attrs.Length = sizeof(attrs); status = LsaOpenPolicy(NULL, &attrs, POLICY_ALL_ACCESS, &handle); ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED, "LsaOpenPolicy(POLICY_ALL_ACCESS) returned 0x%08x\n", status); /* try a more restricted access mask if necessary */ if (status == STATUS_ACCESS_DENIED) { trace("LsaOpenPolicy(POLICY_ALL_ACCESS) failed, trying POLICY_VIEW_LOCAL_INFORMATION\n"); status = LsaOpenPolicy(NULL, &attrs, POLICY_LOOKUP_NAMES, &handle); ok(status == STATUS_SUCCESS, "LsaOpenPolicy(POLICY_VIEW_LOCAL_INFORMATION) returned 0x%08x\n", status); } if (status != STATUS_SUCCESS) { skip("Cannot acquire policy handle\n"); return; } name[0].Buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(n1)); name[0].Length = name[0].MaximumLength = sizeof(n1); memcpy(name[0].Buffer, n1, sizeof(n1)); name[1].Buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(n1)); name[1].Length = name[1].MaximumLength = sizeof(n1) - sizeof(WCHAR); memcpy(name[1].Buffer, n1, sizeof(n1) - sizeof(WCHAR)); name[2].Buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(n2)); name[2].Length = name[2].MaximumLength = sizeof(n2); memcpy(name[2].Buffer, n2, sizeof(n2)); /* account name only */ sids = NULL; domains = NULL; status = LsaLookupNames2(handle, 0, 1, &name[0], &domains, &sids); ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %x)\n", status); ok(sids[0].Use == SidTypeWellKnownGroup, "expected SidTypeWellKnownGroup, got %u\n", sids[0].Use); ok(sids[0].Flags == 0, "expected 0, got 0x%08x\n", sids[0].Flags); ok(domains->Entries == 1, "expected 1, got %u\n", domains->Entries); get_sid_info(sids[0].Sid, &account, &sid_dom); ok(!strcmp(account, "LOCAL SERVICE"), "expected \"LOCAL SERVICE\", got \"%s\"\n", account); ok(!strcmp(sid_dom, "NT AUTHORITY"), "expected \"NT AUTHORITY\", got \"%s\"\n", sid_dom); LsaFreeMemory(sids); LsaFreeMemory(domains); /* unknown account name */ sids = NULL; domains = NULL; status = LsaLookupNames2(handle, 0, 1, &name[1], &domains, &sids); ok(status == STATUS_NONE_MAPPED, "expected STATUS_NONE_MAPPED, got %x)\n", status); ok(sids[0].Use == SidTypeUnknown, "expected SidTypeUnknown, got %u\n", sids[0].Use); ok(sids[0].Flags == 0, "expected 0, got 0x%08x\n", sids[0].Flags); ok(domains->Entries == 0, "expected 0, got %u\n", domains->Entries); LsaFreeMemory(sids); LsaFreeMemory(domains); /* account + domain */ sids = NULL; domains = NULL; status = LsaLookupNames2(handle, 0, 1, &name[2], &domains, &sids); ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %x)\n", status); ok(sids[0].Use == SidTypeWellKnownGroup, "expected SidTypeWellKnownGroup, got %u\n", sids[0].Use); ok(sids[0].Flags == 0, "expected 0, got 0x%08x\n", sids[0].Flags); ok(domains->Entries == 1, "expected 1, got %u\n", domains->Entries); get_sid_info(sids[0].Sid, &account, &sid_dom); ok(!strcmp(account, "LOCAL SERVICE"), "expected \"LOCAL SERVICE\", got \"%s\"\n", account); ok(!strcmp(sid_dom, "NT AUTHORITY"), "expected \"NT AUTHORITY\", got \"%s\"\n", sid_dom); LsaFreeMemory(sids); LsaFreeMemory(domains); /* all three */ sids = NULL; domains = NULL; status = LsaLookupNames2(handle, 0, 3, name, &domains, &sids); ok(status == STATUS_SOME_NOT_MAPPED, "expected STATUS_SOME_NOT_MAPPED, got %x)\n", status); ok(sids[0].Use == SidTypeWellKnownGroup, "expected SidTypeWellKnownGroup, got %u\n", sids[0].Use); ok(sids[1].Use == SidTypeUnknown, "expected SidTypeUnknown, got %u\n", sids[1].Use); ok(sids[2].Use == SidTypeWellKnownGroup, "expected SidTypeWellKnownGroup, got %u\n", sids[2].Use); ok(sids[0].DomainIndex == 0, "expected 0, got %u\n", sids[0].DomainIndex); ok(domains->Entries == 1, "expected 1, got %u\n", domains->Entries); LsaFreeMemory(sids); LsaFreeMemory(domains); HeapFree(GetProcessHeap(), 0, name[0].Buffer); HeapFree(GetProcessHeap(), 0, name[1].Buffer); HeapFree(GetProcessHeap(), 0, name[2].Buffer); status = LsaClose(handle); ok(status == STATUS_SUCCESS, "LsaClose() failed, returned 0x%08x\n", status); }
_Callback_ NTSTATUS SxStdGetObjectSecurity( _Out_ PSECURITY_DESCRIPTOR *SecurityDescriptor, _In_ SECURITY_INFORMATION SecurityInformation, _In_opt_ PVOID Context ) { NTSTATUS status; PPH_STD_OBJECT_SECURITY stdObjectSecurity; HANDLE handle; stdObjectSecurity = (PPH_STD_OBJECT_SECURITY)Context; if ( PhEqualStringZ(stdObjectSecurity->ObjectType, L"LsaAccount", TRUE) || PhEqualStringZ(stdObjectSecurity->ObjectType, L"LsaPolicy", TRUE) || PhEqualStringZ(stdObjectSecurity->ObjectType, L"LsaSecret", TRUE) || PhEqualStringZ(stdObjectSecurity->ObjectType, L"LsaTrusted", TRUE) ) { PSECURITY_DESCRIPTOR securityDescriptor; status = stdObjectSecurity->OpenObject( &handle, PhGetAccessForGetSecurity(SecurityInformation), stdObjectSecurity->Context ); if (!NT_SUCCESS(status)) return status; status = LsaQuerySecurityObject( handle, SecurityInformation, &securityDescriptor ); if (NT_SUCCESS(status)) { *SecurityDescriptor = PhAllocateCopy( securityDescriptor, RtlLengthSecurityDescriptor(securityDescriptor) ); LsaFreeMemory(securityDescriptor); } LsaClose(handle); } else if ( PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamAlias", TRUE) || PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamDomain", TRUE) || PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamGroup", TRUE) || PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamServer", TRUE) || PhEqualStringZ(stdObjectSecurity->ObjectType, L"SamUser", TRUE) ) { PSECURITY_DESCRIPTOR securityDescriptor; status = stdObjectSecurity->OpenObject( &handle, PhGetAccessForGetSecurity(SecurityInformation), stdObjectSecurity->Context ); if (!NT_SUCCESS(status)) return status; status = SamQuerySecurityObject( handle, SecurityInformation, &securityDescriptor ); if (NT_SUCCESS(status)) { *SecurityDescriptor = PhAllocateCopy( securityDescriptor, RtlLengthSecurityDescriptor(securityDescriptor) ); SamFreeMemory(securityDescriptor); } SamCloseHandle(handle); } else { status = PhStdGetObjectSecurity(SecurityDescriptor, SecurityInformation, Context); } return status; }
static void test_LsaLookupSids(void) { LSA_REFERENCED_DOMAIN_LIST *list; LSA_OBJECT_ATTRIBUTES attrs; LSA_TRANSLATED_NAME *names; LSA_HANDLE policy; TOKEN_USER *user; NTSTATUS status; HANDLE token; DWORD size; BOOL ret; PSID sid; memset(&attrs, 0, sizeof(attrs)); attrs.Length = sizeof(attrs); status = LsaOpenPolicy(NULL, &attrs, POLICY_LOOKUP_NAMES, &policy); ok(status == STATUS_SUCCESS, "got 0x%08x\n", status); ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token); ok(ret, "got %d\n", ret); ret = GetTokenInformation(token, TokenUser, NULL, 0, &size); ok(!ret, "got %d\n", ret); user = HeapAlloc(GetProcessHeap(), 0, size); ret = GetTokenInformation(token, TokenUser, user, size, &size); ok(ret, "got %d\n", ret); status = LsaLookupSids(policy, 1, &user->User.Sid, &list, &names); ok(status == STATUS_SUCCESS, "got 0x%08x\n", status); ok(list->Entries > 0, "got %d\n", list->Entries); if (list->Entries) { ok((char*)list->Domains - (char*)list > 0, "%p, %p\n", list, list->Domains); ok((char*)list->Domains[0].Sid - (char*)list->Domains > 0, "%p, %p\n", list->Domains, list->Domains[0].Sid); ok(list->Domains[0].Name.MaximumLength > list->Domains[0].Name.Length, "got %d, %d\n", list->Domains[0].Name.MaximumLength, list->Domains[0].Name.Length); } LsaFreeMemory(names); LsaFreeMemory(list); HeapFree(GetProcessHeap(), 0, user); CloseHandle(token); ret = ConvertStringSidToSidA("S-1-1-0", &sid); ok(ret == TRUE, "ConvertStringSidToSidA returned false\n"); status = LsaLookupSids(policy, 1, &sid, &list, &names); ok(status == STATUS_SUCCESS, "got 0x%08x\n", status); ok(list->Entries > 0, "got %d\n", list->Entries); if (list->Entries) { ok((char*)list->Domains - (char*)list > 0, "%p, %p\n", list, list->Domains); ok((char*)list->Domains[0].Sid - (char*)list->Domains > 0, "%p, %p\n", list->Domains, list->Domains[0].Sid); ok(list->Domains[0].Name.MaximumLength > list->Domains[0].Name.Length, "got %d, %d\n", list->Domains[0].Name.MaximumLength, list->Domains[0].Name.Length); ok(list->Domains[0].Name.Buffer != NULL, "domain[0] name buffer is null\n"); } LsaFreeMemory(names); LsaFreeMemory(list); FreeSid(sid); status = LsaClose(policy); ok(status == STATUS_SUCCESS, "got 0x%08x\n", status); }
int SetupTokenPrivileges(PTOKEN_PRIVILEGES *pPrivToken, PSID userSid) { DWORD ntStat = 0; int exitCode = 1; LSA_OBJECT_ATTRIBUTES lsaOA = {0}; PLSA_UNICODE_STRING userRights = NULL; ULONG nRights = 0; DWORD size; int i, j; /* * Open local policy. */ LSA_HANDLE hPolicy; lsaOA.Length = sizeof(lsaOA); ACCESS_MASK mask = POLICY_VIEW_LOCAL_INFORMATION | POLICY_LOOKUP_NAMES; debug("Opening local policy..."); ntStat = LsaOpenPolicy(NULL, &lsaOA, mask, &hPolicy); FAIL(ntStat); /* * Retrieve user's privileges. */ debug("Retrieving user's privileges list..."); ntStat = LsaEnumerateAccountRights(hPolicy, userSid, &userRights, &nRights); /* * This error code means there is no any rights. * In this case, we should create empty list. */ if (ntStat == STATUS_OBJECT_NAME_NOT_FOUND) { nRights = 0; ntStat = 0; } FAIL(ntStat); /* * FIXME. Now if some privilege name is not recognized by * LookupPrivilegeName() part of pPrivToken buffer will be * unused. */ /* * Allocate buffer for TOKEN_PRIVILEGES. */ debug("Allocating buffer for TOKEN_PRIVILEGES [%u]...", nRights); size = sizeof(DWORD) + nRights * sizeof(LUID_AND_ATTRIBUTES); (*pPrivToken) = LocalAlloc(LPTR, size); FAIL(pPrivToken == NULL); /* * Fill TOKEN_PRIVILEGES with LUIDs of retrieved privileges. */ j = 0; for (i = 0; i < nRights; i++) { /* * Retrieve unicode name of privilege. * Make sure there is a zero word at the end. */ wchar_t privName[128]; int len = userRights[i].Length; memcpy(privName, userRights[i].Buffer, len * sizeof(wchar_t)); privName[len] = 0; debug("Adding %ls... ", privName); /* * Retrieve LUID for given privilege name. */ if(LookupPrivilegeValueW(NULL, privName, &(*pPrivToken) -> Privileges[i].Luid) == FALSE) { debug("WARNING. Cannot add privilege to token (%u).", GetLastError()); } else { (*pPrivToken) -> Privileges[j].Attributes = SE_PRIVILEGE_ENABLED; j++; } } /* * j = number of privileges, which were recognized by * LookupPrivilegesValue(). */ (*pPrivToken) -> PrivilegeCount = j; exitCode = 0; fail: /* * Clenup. */ if (userRights) { LsaFreeMemory(userRights); } if (hPolicy) { CloseHandle(hPolicy); } if (exitCode) { debug("ERROR. Cannot setup TOKEN_PRIVILEGES (err=%u, ntStat=%x).", GetLastError(), ntStat); } }
NTSTATUS GetRemoteNcpSecretKey ( PUNICODE_STRING SystemName, CHAR *pchNWSecretKey ) { // // this function returns the FPNW LSA Secret for the specified domain // NTSTATUS ntstatus; OBJECT_ATTRIBUTES ObjAttributes; LSA_HANDLE PolicyHandle = NULL; LSA_HANDLE SecretHandle = NULL; UNICODE_STRING SecretNameString; PUNICODE_STRING punicodeCurrentValue; PUNICODE_STRING punicodeOldValue; InitializeObjectAttributes( &ObjAttributes, NULL, 0L, NULL, NULL ); ntstatus = LsaOpenPolicy( SystemName, &ObjAttributes, POLICY_CREATE_SECRET, &PolicyHandle ); if ( !NT_SUCCESS( ntstatus )) { return( ntstatus ); } RtlInitUnicodeString( &SecretNameString, NCP_LSA_SECRET_KEY ); ntstatus = LsaOpenSecret( PolicyHandle, &SecretNameString, SECRET_QUERY_VALUE, &SecretHandle ); if ( !NT_SUCCESS( ntstatus )) { LsaClose( PolicyHandle ); return( ntstatus ); } // // Do not need the policy handle anymore. // LsaClose( PolicyHandle ); ntstatus = LsaQuerySecret( SecretHandle, &punicodeCurrentValue, NULL, &punicodeOldValue, NULL ); // // Do not need the secret handle anymore. // LsaClose( SecretHandle ); if ( NT_SUCCESS(ntstatus) && ( punicodeCurrentValue->Buffer != NULL)) { memcpy( pchNWSecretKey, punicodeCurrentValue->Buffer, min(punicodeCurrentValue->Length, USER_SESSION_KEY_LENGTH)); } LsaFreeMemory( punicodeCurrentValue ); LsaFreeMemory( punicodeOldValue ); return( ntstatus ); }
/****************************************************************************** * NetUserModalsGet (NETAPI32.@) * * Retrieves global information for all users and global groups in the security * database. * * PARAMS * szServer [I] Specifies the DNS or the NetBIOS name of the remote server * on which the function is to execute. * level [I] Information level of the data. * 0 Return global passwords parameters. bufptr points to a * USER_MODALS_INFO_0 struct. * 1 Return logon server and domain controller information. bufptr * points to a USER_MODALS_INFO_1 struct. * 2 Return domain name and identifier. bufptr points to a * USER_MODALS_INFO_2 struct. * 3 Return lockout information. bufptr points to a USER_MODALS_INFO_3 * struct. * pbuffer [I] Buffer that receives the data. * * RETURNS * Success: NERR_Success. * Failure: * ERROR_ACCESS_DENIED - the user does not have access to the info. * NERR_InvalidComputer - computer name is invalid. */ NET_API_STATUS WINAPI NetUserModalsGet( LPCWSTR szServer, DWORD level, LPBYTE *pbuffer) { TRACE("(%s %d %p)\n", debugstr_w(szServer), level, pbuffer); switch (level) { case 0: /* return global passwords parameters */ FIXME("level 0 not implemented!\n"); *pbuffer = NULL; return NERR_InternalError; case 1: /* return logon server and domain controller info */ FIXME("level 1 not implemented!\n"); *pbuffer = NULL; return NERR_InternalError; case 2: { /* return domain name and identifier */ PUSER_MODALS_INFO_2 umi; LSA_HANDLE policyHandle; LSA_OBJECT_ATTRIBUTES objectAttributes; PPOLICY_ACCOUNT_DOMAIN_INFO domainInfo; NTSTATUS ntStatus; PSID domainIdentifier = NULL; int domainNameLen, domainIdLen; ZeroMemory(&objectAttributes, sizeof(objectAttributes)); objectAttributes.Length = sizeof(objectAttributes); ntStatus = LsaOpenPolicy(NULL, &objectAttributes, POLICY_VIEW_LOCAL_INFORMATION, &policyHandle); if (ntStatus != STATUS_SUCCESS) { WARN("LsaOpenPolicy failed with NT status %x\n", LsaNtStatusToWinError(ntStatus)); return ntStatus; } ntStatus = LsaQueryInformationPolicy(policyHandle, PolicyAccountDomainInformation, (PVOID *)&domainInfo); if (ntStatus != STATUS_SUCCESS) { WARN("LsaQueryInformationPolicy failed with NT status %x\n", LsaNtStatusToWinError(ntStatus)); LsaClose(policyHandle); return ntStatus; } domainIdentifier = domainInfo->DomainSid; domainIdLen = (domainIdentifier) ? GetLengthSid(domainIdentifier) : 0; domainNameLen = lstrlenW(domainInfo->DomainName.Buffer) + 1; LsaClose(policyHandle); ntStatus = NetApiBufferAllocate(sizeof(USER_MODALS_INFO_2) + domainIdLen + domainNameLen * sizeof(WCHAR), (LPVOID *)pbuffer); if (ntStatus != NERR_Success) { WARN("NetApiBufferAllocate() failed\n"); LsaFreeMemory(domainInfo); return ntStatus; } umi = (USER_MODALS_INFO_2 *) *pbuffer; umi->usrmod2_domain_id = (domainIdLen > 0) ? (*pbuffer + sizeof(USER_MODALS_INFO_2)) : NULL; umi->usrmod2_domain_name = (LPWSTR)(*pbuffer + sizeof(USER_MODALS_INFO_2) + domainIdLen); lstrcpynW(umi->usrmod2_domain_name, domainInfo->DomainName.Buffer, domainNameLen); if (domainIdLen > 0) CopySid(GetLengthSid(domainIdentifier), umi->usrmod2_domain_id, domainIdentifier); LsaFreeMemory(domainInfo); break; } case 3: /* return lockout information */ FIXME("level 3 not implemented!\n"); *pbuffer = NULL; return NERR_InternalError; default: TRACE("Invalid level %d is specified\n", level); *pbuffer = NULL; return ERROR_INVALID_LEVEL; } return NERR_Success; }
INT_PTR CALLBACK EspServiceOtherDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PSERVICE_OTHER_CONTEXT context; if (uMsg == WM_INITDIALOG) { context = PhAllocate(sizeof(SERVICE_OTHER_CONTEXT)); memset(context, 0, sizeof(SERVICE_OTHER_CONTEXT)); SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PSERVICE_OTHER_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_DESTROY) RemoveProp(hwndDlg, L"Context"); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { NTSTATUS status; LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam; PPH_SERVICE_ITEM serviceItem = (PPH_SERVICE_ITEM)propSheetPage->lParam; HWND privilegesLv; context->ServiceItem = serviceItem; context->PrivilegesLv = privilegesLv = GetDlgItem(hwndDlg, IDC_PRIVILEGES); PhSetListViewStyle(privilegesLv, FALSE, TRUE); PhSetControlTheme(privilegesLv, L"explorer"); PhAddListViewColumn(privilegesLv, 0, 0, 0, LVCFMT_LEFT, 140, L"Name"); PhAddListViewColumn(privilegesLv, 1, 1, 1, LVCFMT_LEFT, 220, L"Display Name"); PhSetExtendedListView(privilegesLv); context->PrivilegeList = PhCreateList(32); if (context->ServiceItem->Type == SERVICE_KERNEL_DRIVER || context->ServiceItem->Type == SERVICE_FILE_SYSTEM_DRIVER) { // Drivers don't support required privileges. EnableWindow(GetDlgItem(hwndDlg, IDC_ADD), FALSE); } EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), FALSE); PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_SIDTYPE), EspServiceSidTypeStrings, sizeof(EspServiceSidTypeStrings) / sizeof(PWSTR)); PhAddComboBoxStrings(GetDlgItem(hwndDlg, IDC_PROTECTION), EspServiceLaunchProtectedStrings, sizeof(EspServiceLaunchProtectedStrings) / sizeof(PWSTR)); if (WindowsVersion < WINDOWS_8_1) EnableWindow(GetDlgItem(hwndDlg, IDC_PROTECTION), FALSE); SetDlgItemText(hwndDlg, IDC_SERVICESID, PhGetStringOrDefault(PH_AUTO(EspGetServiceSidString(&serviceItem->Name->sr)), L"N/A")); status = EspLoadOtherInfo(hwndDlg, context); if (!NT_SUCCESS(status)) { PhShowWarning(hwndDlg, L"Unable to query service information: %s", ((PPH_STRING)PH_AUTO(PhGetNtMessage(status)))->Buffer); } context->Ready = TRUE; } break; case WM_DESTROY: { if (context->PrivilegeList) { PhDereferenceObjects(context->PrivilegeList->Items, context->PrivilegeList->Count); PhDereferenceObject(context->PrivilegeList); } PhFree(context); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_ADD: { NTSTATUS status; LSA_HANDLE policyHandle; LSA_ENUMERATION_HANDLE enumContext; PPOLICY_PRIVILEGE_DEFINITION buffer; ULONG count; ULONG i; PPH_LIST choices; PPH_STRING selectedChoice = NULL; choices = PH_AUTO(PhCreateList(100)); if (!NT_SUCCESS(status = PhOpenLsaPolicy(&policyHandle, POLICY_VIEW_LOCAL_INFORMATION, NULL))) { PhShowStatus(hwndDlg, L"Unable to open LSA policy", status, 0); break; } enumContext = 0; while (TRUE) { status = LsaEnumeratePrivileges( policyHandle, &enumContext, &buffer, 0x100, &count ); if (status == STATUS_NO_MORE_ENTRIES) break; if (!NT_SUCCESS(status)) break; for (i = 0; i < count; i++) { PhAddItemList(choices, PhaCreateStringEx(buffer[i].Name.Buffer, buffer[i].Name.Length)->Buffer); } LsaFreeMemory(buffer); } LsaClose(policyHandle); qsort(choices->Items, choices->Count, sizeof(PWSTR), PrivilegeNameCompareFunction); while (PhaChoiceDialog( hwndDlg, L"Add privilege", L"Select a privilege to add:", (PWSTR *)choices->Items, choices->Count, NULL, PH_CHOICE_DIALOG_CHOICE, &selectedChoice, NULL, NULL )) { BOOLEAN found = FALSE; PPH_STRING privilegeString; INT lvItemIndex; PPH_STRING displayName; // Check for duplicates. for (i = 0; i < context->PrivilegeList->Count; i++) { if (PhEqualString(context->PrivilegeList->Items[i], selectedChoice, FALSE)) { found = TRUE; break; } } if (found) { if (PhShowMessage( hwndDlg, MB_OKCANCEL | MB_ICONERROR, L"The selected privilege has already been added." ) == IDOK) { continue; } else { break; } } PhSetReference(&privilegeString, selectedChoice); PhAddItemList(context->PrivilegeList, privilegeString); lvItemIndex = PhAddListViewItem(context->PrivilegesLv, MAXINT, privilegeString->Buffer, privilegeString); if (PhLookupPrivilegeDisplayName(&privilegeString->sr, &displayName)) { PhSetListViewSubItem(context->PrivilegesLv, lvItemIndex, 1, displayName->Buffer); PhDereferenceObject(displayName); } ExtendedListView_SortItems(context->PrivilegesLv); context->Dirty = TRUE; context->RequiredPrivilegesValid = TRUE; break; } } break; case IDC_REMOVE: { INT lvItemIndex; PPH_STRING privilegeString; ULONG index; lvItemIndex = ListView_GetNextItem(context->PrivilegesLv, -1, LVNI_SELECTED); if (lvItemIndex != -1 && PhGetListViewItemParam(context->PrivilegesLv, lvItemIndex, (PVOID *)&privilegeString)) { index = PhFindItemList(context->PrivilegeList, privilegeString); if (index != -1) { PhDereferenceObject(privilegeString); PhRemoveItemList(context->PrivilegeList, index); PhRemoveListViewItem(context->PrivilegesLv, lvItemIndex); context->Dirty = TRUE; context->RequiredPrivilegesValid = TRUE; } } } break; } switch (HIWORD(wParam)) { case EN_CHANGE: case CBN_SELCHANGE: { if (context->Ready) { context->Dirty = TRUE; switch (LOWORD(wParam)) { case IDC_PRESHUTDOWNTIMEOUT: context->PreshutdownTimeoutValid = TRUE; break; case IDC_SIDTYPE: context->SidTypeValid = TRUE; break; case IDC_PROTECTION: context->LaunchProtectedValid = TRUE; break; } } } break; } } break; case WM_NOTIFY: { LPNMHDR header = (LPNMHDR)lParam; switch (header->code) { case PSN_KILLACTIVE: { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); } return TRUE; case PSN_APPLY: { SC_HANDLE serviceHandle = NULL; ULONG win32Result = 0; BOOLEAN connectedToPhSvc = FALSE; PPH_STRING launchProtectedString; ULONG launchProtected; SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); launchProtectedString = PH_AUTO(PhGetWindowText(GetDlgItem(hwndDlg, IDC_PROTECTION))); launchProtected = EspGetServiceLaunchProtectedInteger(launchProtectedString->Buffer); if (context->LaunchProtectedValid && launchProtected != 0 && launchProtected != context->OriginalLaunchProtected) { if (PhShowMessage( hwndDlg, MB_ICONWARNING | MB_YESNO | MB_DEFBUTTON2, L"Setting service protection will prevent the service from being controlled, modified, or deleted. Do you want to continue?" ) == IDNO) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); return TRUE; } } if (context->Dirty) { SERVICE_PRESHUTDOWN_INFO preshutdownInfo; SERVICE_REQUIRED_PRIVILEGES_INFO requiredPrivilegesInfo; SERVICE_SID_INFO sidInfo; SERVICE_LAUNCH_PROTECTED_INFO launchProtectedInfo; if (!(serviceHandle = PhOpenService(context->ServiceItem->Name->Buffer, SERVICE_CHANGE_CONFIG))) { win32Result = GetLastError(); if (win32Result == ERROR_ACCESS_DENIED && !PhElevated) { // Elevate using phsvc. if (PhUiConnectToPhSvc(hwndDlg, FALSE)) { win32Result = 0; connectedToPhSvc = TRUE; } else { // User cancelled elevation. win32Result = ERROR_CANCELLED; goto Done; } } else { goto Done; } } if (context->PreshutdownTimeoutValid) { preshutdownInfo.dwPreshutdownTimeout = GetDlgItemInt(hwndDlg, IDC_PRESHUTDOWNTIMEOUT, NULL, FALSE); if (!EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_PRESHUTDOWN_INFO, &preshutdownInfo)) { win32Result = GetLastError(); } } if (context->RequiredPrivilegesValid) { PH_STRING_BUILDER sb; ULONG i; PhInitializeStringBuilder(&sb, 100); for (i = 0; i < context->PrivilegeList->Count; i++) { PhAppendStringBuilder(&sb, &((PPH_STRING)context->PrivilegeList->Items[i])->sr); PhAppendCharStringBuilder(&sb, 0); } requiredPrivilegesInfo.pmszRequiredPrivileges = sb.String->Buffer; if (win32Result == 0 && !EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO, &requiredPrivilegesInfo)) { win32Result = GetLastError(); } PhDeleteStringBuilder(&sb); } if (context->SidTypeValid) { PPH_STRING sidTypeString; sidTypeString = PH_AUTO(PhGetWindowText(GetDlgItem(hwndDlg, IDC_SIDTYPE))); sidInfo.dwServiceSidType = EspGetServiceSidTypeInteger(sidTypeString->Buffer); if (win32Result == 0 && !EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_SERVICE_SID_INFO, &sidInfo)) { win32Result = GetLastError(); } } if (context->LaunchProtectedValid) { launchProtectedInfo.dwLaunchProtected = launchProtected; if (!EspChangeServiceConfig2(context->ServiceItem->Name->Buffer, serviceHandle, SERVICE_CONFIG_LAUNCH_PROTECTED, &launchProtectedInfo)) { // For now, ignore errors here. // win32Result = GetLastError(); } } Done: if (connectedToPhSvc) PhUiDisconnectFromPhSvc(); if (serviceHandle) CloseServiceHandle(serviceHandle); if (win32Result != 0) { if (win32Result == ERROR_CANCELLED || PhShowMessage( hwndDlg, MB_ICONERROR | MB_RETRYCANCEL, L"Unable to change service information: %s", ((PPH_STRING)PH_AUTO(PhGetWin32Message(win32Result)))->Buffer ) == IDRETRY) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID); } } } return TRUE; } break; case LVN_ITEMCHANGED: { if (header->hwndFrom == context->PrivilegesLv) { EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVE), ListView_GetSelectedCount(context->PrivilegesLv) == 1); } } break; } } break; } return FALSE; }
mDNSBool LsaGetSecret( const char * inDomain, char * outDomain, unsigned outDomainSize, char * outKey, unsigned outKeySize, char * outSecret, unsigned outSecretSize ) { PLSA_UNICODE_STRING domainLSA; PLSA_UNICODE_STRING keyLSA; PLSA_UNICODE_STRING secretLSA; size_t i; size_t dlen; LSA_OBJECT_ATTRIBUTES attrs; LSA_HANDLE handle = NULL; NTSTATUS res; OSStatus err; check( inDomain ); check( outDomain ); check( outKey ); check( outSecret ); // Initialize domainLSA = NULL; keyLSA = NULL; secretLSA = NULL; // Make sure we have enough space to add trailing dot dlen = strlen( inDomain ); err = strcpy_s( outDomain, outDomainSize - 2, inDomain ); require_noerr( err, exit ); // If there isn't a trailing dot, add one because the mDNSResponder // presents names with the trailing dot. if ( outDomain[ dlen - 1 ] != '.' ) { outDomain[ dlen++ ] = '.'; outDomain[ dlen ] = '\0'; } // Canonicalize name by converting to lower case (keychain and some name servers are case sensitive) for ( i = 0; i < dlen; i++ ) { outDomain[i] = (char) tolower( outDomain[i] ); // canonicalize -> lower case } // attrs are reserved, so initialize to zeroes. ZeroMemory( &attrs, sizeof( attrs ) ); // Get a handle to the Policy object on the local system res = LsaOpenPolicy( NULL, &attrs, POLICY_GET_PRIVATE_INFORMATION, &handle ); err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr ); require_noerr( err, exit ); // Get the encrypted data domainLSA = ( PLSA_UNICODE_STRING ) malloc( sizeof( LSA_UNICODE_STRING ) ); require_action( domainLSA != NULL, exit, err = mStatus_NoMemoryErr ); err = MakeLsaStringFromUTF8String( domainLSA, outDomain ); require_noerr( err, exit ); // Retrieve the key res = LsaRetrievePrivateData( handle, domainLSA, &keyLSA ); err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr ); require_noerr_quiet( err, exit ); // <rdar://problem/4192119> Lsa secrets use a flat naming space. Therefore, we will prepend "$" to the keyname to // make sure it doesn't conflict with a zone name. // Strip off the "$" prefix. err = MakeUTF8StringFromLsaString( outKey, outKeySize, keyLSA ); require_noerr( err, exit ); require_action( outKey[0] == '$', exit, err = kUnknownErr ); memcpy( outKey, outKey + 1, strlen( outKey ) ); // Retrieve the secret res = LsaRetrievePrivateData( handle, keyLSA, &secretLSA ); err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr ); require_noerr_quiet( err, exit ); // Convert the secret to UTF8 string err = MakeUTF8StringFromLsaString( outSecret, outSecretSize, secretLSA ); require_noerr( err, exit ); exit: if ( domainLSA != NULL ) { if ( domainLSA->Buffer != NULL ) { free( domainLSA->Buffer ); } free( domainLSA ); } if ( keyLSA != NULL ) { LsaFreeMemory( keyLSA ); } if ( secretLSA != NULL ) { LsaFreeMemory( secretLSA ); } if ( handle ) { LsaClose( handle ); handle = NULL; } return ( !err ) ? TRUE : FALSE; }
NTSTATUS kuhl_m_token_list_or_elevate(int argc, wchar_t * argv[], BOOL elevate) { KUHL_M_TOKEN_ELEVATE_DATA pData = {NULL, NULL, 0, elevate}; WELL_KNOWN_SID_TYPE type = WinNullSid; PWSTR name, domain; PCWSTR strTokenId; PPOLICY_DNS_DOMAIN_INFO pDomainInfo = NULL; kull_m_string_args_byName(argc, argv, L"user", &pData.pUsername, NULL); if(kull_m_string_args_byName(argc, argv, L"id", &strTokenId, NULL)) { pData.tokenId = wcstoul(strTokenId, NULL, 0); } else if(kull_m_string_args_byName(argc, argv, L"domainadmin", NULL, NULL)) { type = WinAccountDomainAdminsSid; if(!kull_m_net_getCurrentDomainInfo(&pDomainInfo)) PRINT_ERROR_AUTO(L"kull_m_local_domain_user_getCurrentDomainSID"); } else if(kull_m_string_args_byName(argc, argv, L"admin", NULL, NULL)) type = WinBuiltinAdministratorsSid; else if((elevate && !pData.pUsername) || kull_m_string_args_byName(argc, argv, L"system", NULL, NULL)) { type = WinLocalSystemSid; if(pData.pUsername) { PRINT_ERROR(L"No username available when SYSTEM\n"); pData.pUsername = NULL; } } if(!elevate || pData.tokenId || type || pData.pUsername) { kprintf(L"Token Id : %u\nUser name : %s\nSID name : ", pData.tokenId, pData.pUsername ? pData.pUsername : L""); if(type) { if(kull_m_net_CreateWellKnownSid(type, pDomainInfo ? pDomainInfo->Sid : NULL, &pData.pSid)) { if(kull_m_token_getNameDomainFromSID(pData.pSid, &name, &domain, NULL)) { kprintf(L"%s\\%s\n", domain, name); LocalFree(name); LocalFree(domain); } else PRINT_ERROR_AUTO(L"kull_m_token_getNameDomainFromSID"); } else PRINT_ERROR_AUTO(L"kull_m_local_domain_user_CreateWellKnownSid"); } else kprintf(L"\n"); kprintf(L"\n"); if(!elevate || pData.tokenId || pData.pSid || pData.pUsername) kull_m_token_getTokens(kuhl_m_token_list_or_elevate_callback, &pData); if(pData.pSid) LocalFree(pData.pSid); if(pDomainInfo) LsaFreeMemory(pDomainInfo); } return STATUS_SUCCESS; }
NTSTATUS LsapOpenSam( VOID ) /*++ Routine Description: This routine opens SAM for use during authentication. It opens a handle to both the BUILTIN domain and the ACCOUNT domain. Arguments: None. Return Value: STATUS_SUCCESS - Succeeded. --*/ { NTSTATUS Status, IgnoreStatus; PPOLICY_ACCOUNT_DOMAIN_INFO PolicyAccountDomainInfo; SAMPR_HANDLE SamHandle; HANDLE EventHandle; OBJECT_ATTRIBUTES EventAttributes; UNICODE_STRING EventName; LARGE_INTEGER Timeout; if (LsapSamOpened == TRUE) { // Global variable return(STATUS_SUCCESS); } // // Make sure SAM has initialized // RtlInitUnicodeString( &EventName, L"\\SAM_SERVICE_STARTED"); InitializeObjectAttributes( &EventAttributes, &EventName, 0, 0, NULL ); Status = NtOpenEvent( &EventHandle, SYNCHRONIZE, &EventAttributes ); ASSERT( Status == STATUS_SUCCESS || Status == STATUS_OBJECT_NAME_NOT_FOUND ); if (NT_SUCCESS(Status)) { // // See if SAM has signalled that he is initialized. // Timeout.QuadPart = -10000000; // 1000 seconds Timeout.QuadPart *= 1000; Status = NtWaitForSingleObject( EventHandle, FALSE, &Timeout ); IgnoreStatus = NtClose( EventHandle ); ASSERT(NT_SUCCESS(IgnoreStatus)); } if ( !NT_SUCCESS(Status) || Status == STATUS_TIMEOUT ) { return( STATUS_INVALID_SERVER_STATE ); } // // Get the member Sid information for the account domain // Status = LsapGetAccountDomainInfo( &PolicyAccountDomainInfo ); if (!NT_SUCCESS(Status)) { return(Status); } // // Get our handles to the ACCOUNT and BUILTIN domains. // Status = SamIConnect( NULL, // No server name &SamHandle, SAM_SERVER_CONNECT, TRUE ); // Indicate we are privileged if ( NT_SUCCESS(Status) ) { // // Open the ACCOUNT domain. // Status = SamrOpenDomain( SamHandle, DOMAIN_ALL_ACCESS, PolicyAccountDomainInfo->DomainSid, &LsapAccountDomainHandle ); if (NT_SUCCESS(Status)) { // // Open the BUILTIN domain. // Status = SamrOpenDomain( SamHandle, DOMAIN_ALL_ACCESS, LsapBuiltInDomainSid, &LsapBuiltinDomainHandle ); if (NT_SUCCESS(Status)) { LsapSamOpened = TRUE; } else { IgnoreStatus = SamrCloseHandle( &LsapAccountDomainHandle ); ASSERT(NT_SUCCESS(IgnoreStatus)); } } IgnoreStatus = SamrCloseHandle( &SamHandle ); ASSERT(NT_SUCCESS(IgnoreStatus)); } // // Free the ACCOUNT domain information // LsaFreeMemory( PolicyAccountDomainInfo ); return(Status); }
static void test_lsa(void) { NTSTATUS status; LSA_HANDLE handle; LSA_OBJECT_ATTRIBUTES object_attributes; ZeroMemory(&object_attributes, sizeof(object_attributes)); object_attributes.Length = sizeof(object_attributes); status = LsaOpenPolicy( NULL, &object_attributes, POLICY_ALL_ACCESS, &handle); ok(status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED, "LsaOpenPolicy(POLICY_ALL_ACCESS) returned 0x%08x\n", status); /* try a more restricted access mask if necessary */ if (status == STATUS_ACCESS_DENIED) { trace("LsaOpenPolicy(POLICY_ALL_ACCESS) failed, trying POLICY_VIEW_LOCAL_INFORMATION|POLICY_LOOKUP_NAMES\n"); status = LsaOpenPolicy( NULL, &object_attributes, POLICY_VIEW_LOCAL_INFORMATION|POLICY_LOOKUP_NAMES, &handle); ok(status == STATUS_SUCCESS, "LsaOpenPolicy(POLICY_VIEW_LOCAL_INFORMATION|POLICY_LOOKUP_NAMES) returned 0x%08x\n", status); } if (status == STATUS_SUCCESS) { PPOLICY_AUDIT_EVENTS_INFO audit_events_info; PPOLICY_PRIMARY_DOMAIN_INFO primary_domain_info; PPOLICY_ACCOUNT_DOMAIN_INFO account_domain_info; PPOLICY_DNS_DOMAIN_INFO dns_domain_info; HANDLE token; BOOL ret; status = LsaQueryInformationPolicy(handle, PolicyAuditEventsInformation, (void **)&audit_events_info); if (status == STATUS_ACCESS_DENIED) skip("Not enough rights to retrieve PolicyAuditEventsInformation\n"); else ok(status == STATUS_SUCCESS, "LsaQueryInformationPolicy(PolicyAuditEventsInformation) failed, returned 0x%08x\n", status); if (status == STATUS_SUCCESS) LsaFreeMemory(audit_events_info); status = LsaQueryInformationPolicy(handle, PolicyPrimaryDomainInformation, (void **)&primary_domain_info); ok(status == STATUS_SUCCESS, "LsaQueryInformationPolicy(PolicyPrimaryDomainInformation) failed, returned 0x%08x\n", status); if (status == STATUS_SUCCESS) { if (primary_domain_info->Sid) { LPSTR strsid; if (ConvertSidToStringSidA(primary_domain_info->Sid, &strsid)) { if (primary_domain_info->Name.Buffer) { LPSTR name = NULL; UINT len; len = WideCharToMultiByte( CP_ACP, 0, primary_domain_info->Name.Buffer, -1, NULL, 0, NULL, NULL ); name = LocalAlloc( 0, len ); WideCharToMultiByte( CP_ACP, 0, primary_domain_info->Name.Buffer, -1, name, len, NULL, NULL ); trace(" name: %s sid: %s\n", name, strsid); LocalFree( name ); } else trace(" name: NULL sid: %s\n", strsid); LocalFree( strsid ); } else trace("invalid sid\n"); } else trace("Running on a standalone system.\n"); LsaFreeMemory(primary_domain_info); } status = LsaQueryInformationPolicy(handle, PolicyAccountDomainInformation, (void **)&account_domain_info); ok(status == STATUS_SUCCESS, "LsaQueryInformationPolicy(PolicyAccountDomainInformation) failed, returned 0x%08x\n", status); if (status == STATUS_SUCCESS) LsaFreeMemory(account_domain_info); /* This isn't supported in NT4 */ status = LsaQueryInformationPolicy(handle, PolicyDnsDomainInformation, (void **)&dns_domain_info); ok(status == STATUS_SUCCESS || status == STATUS_INVALID_PARAMETER, "LsaQueryInformationPolicy(PolicyDnsDomainInformation) failed, returned 0x%08x\n", status); if (status == STATUS_SUCCESS) { if (dns_domain_info->Sid || !IsEqualGUID(&dns_domain_info->DomainGuid, &GUID_NULL)) { LPSTR strsid = NULL; LPSTR name = NULL; LPSTR domain = NULL; LPSTR forest = NULL; LPSTR guidstr = NULL; WCHAR guidstrW[64]; UINT len; guidstrW[0] = '\0'; ConvertSidToStringSidA(dns_domain_info->Sid, &strsid); StringFromGUID2(&dns_domain_info->DomainGuid, guidstrW, ARRAY_SIZE(guidstrW)); len = WideCharToMultiByte( CP_ACP, 0, guidstrW, -1, NULL, 0, NULL, NULL ); guidstr = LocalAlloc( 0, len ); WideCharToMultiByte( CP_ACP, 0, guidstrW, -1, guidstr, len, NULL, NULL ); if (dns_domain_info->Name.Buffer) { len = WideCharToMultiByte( CP_ACP, 0, dns_domain_info->Name.Buffer, -1, NULL, 0, NULL, NULL ); name = LocalAlloc( 0, len ); WideCharToMultiByte( CP_ACP, 0, dns_domain_info->Name.Buffer, -1, name, len, NULL, NULL ); } if (dns_domain_info->DnsDomainName.Buffer) { len = WideCharToMultiByte( CP_ACP, 0, dns_domain_info->DnsDomainName.Buffer, -1, NULL, 0, NULL, NULL ); domain = LocalAlloc( 0, len ); WideCharToMultiByte( CP_ACP, 0, dns_domain_info->DnsDomainName.Buffer, -1, domain, len, NULL, NULL ); } if (dns_domain_info->DnsForestName.Buffer) { len = WideCharToMultiByte( CP_ACP, 0, dns_domain_info->DnsForestName.Buffer, -1, NULL, 0, NULL, NULL ); forest = LocalAlloc( 0, len ); WideCharToMultiByte( CP_ACP, 0, dns_domain_info->DnsForestName.Buffer, -1, forest, len, NULL, NULL ); } trace(" name: %s domain: %s forest: %s guid: %s sid: %s\n", name ? name : "NULL", domain ? domain : "NULL", forest ? forest : "NULL", guidstr, strsid ? strsid : "NULL"); LocalFree( name ); LocalFree( forest ); LocalFree( domain ); LocalFree( guidstr ); LocalFree( strsid ); } else trace("Running on a standalone system.\n"); LsaFreeMemory(dns_domain_info); } /* We need a valid SID to pass to LsaEnumerateAccountRights */ ret = OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &token ); ok(ret, "Unable to obtain process token, error %u\n", GetLastError( )); if (ret) { char buffer[64]; DWORD len; TOKEN_USER *token_user = (TOKEN_USER *) buffer; ret = GetTokenInformation( token, TokenUser, (LPVOID) token_user, sizeof(buffer), &len ); ok(ret || GetLastError( ) == ERROR_INSUFFICIENT_BUFFER, "Unable to obtain token information, error %u\n", GetLastError( )); if (! ret && GetLastError( ) == ERROR_INSUFFICIENT_BUFFER) { trace("Resizing buffer to %u.\n", len); token_user = LocalAlloc( 0, len ); if (token_user != NULL) ret = GetTokenInformation( token, TokenUser, (LPVOID) token_user, len, &len ); } if (ret) { PLSA_UNICODE_STRING rights; ULONG rights_count; rights = (PLSA_UNICODE_STRING) 0xdeadbeaf; rights_count = 0xcafecafe; status = LsaEnumerateAccountRights(handle, token_user->User.Sid, &rights, &rights_count); ok(status == STATUS_SUCCESS || status == STATUS_OBJECT_NAME_NOT_FOUND, "Unexpected status 0x%x\n", status); if (status == STATUS_SUCCESS) LsaFreeMemory( rights ); else ok(rights == NULL && rights_count == 0, "Expected rights and rights_count to be set to 0 on failure\n"); } if (token_user != NULL && token_user != (TOKEN_USER *) buffer) LocalFree( token_user ); CloseHandle( token ); } status = LsaClose(handle); ok(status == STATUS_SUCCESS, "LsaClose() failed, returned 0x%08x\n", status); } }