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"); } }
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 VOID AddImpersonatePrivilege(VOID) { /* S-1-5-6 -- "Service" group */ static SID ServiceSid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } }; NTSTATUS Status; LSA_HANDLE PolicyHandle; LSA_OBJECT_ATTRIBUTES ObjectAttributes; LSA_UNICODE_STRING RightString; ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes)); Status = LsaOpenPolicy(NULL, &ObjectAttributes, POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES, &PolicyHandle); if (!NT_SUCCESS(Status)) { ERR("LsaOpenPolicy() failed with Status 0x%08lx\n", Status); return; } RtlInitUnicodeString(&RightString, L"SeImpersonatePrivilege"); Status = LsaAddAccountRights(PolicyHandle, &ServiceSid, &RightString, 1); if (!NT_SUCCESS(Status)) { ERR("LsaAddAccountRights(\"S-1-5-6\", \"%wZ\") failed with Status 0x%08lx\n", Status, &RightString); } LsaClose(PolicyHandle); }
NTSTATUS OpenPolicy(LPWSTR ServerName, DWORD DesiredAccess, PLSA_HANDLE PolicyHandle){ LSA_OBJECT_ATTRIBUTES ObjectAttributes; LSA_UNICODE_STRING ServerString; PLSA_UNICODE_STRING Server = NULL; /* * Always initialize the object attributes to all zeroes. */ ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes)); if (ServerName != NULL) { /* * Make a LSA_UNICODE_STRING out of the LPWSTR passed in */ InitLsaString(&ServerString, ServerName); Server = &ServerString; } /* * Attempt to open the policy. */ return (LsaOpenPolicy(Server, &ObjectAttributes, DesiredAccess, PolicyHandle)); }
/** * @brief * add_privilege - add_privilege: returns 0 if privname has been added for account * referenced by sid; otherwise, 1. * * @param[in] sid - The security identifier (SID) structure is a variable-length structure * used to uniquely identify users or groups. * @param[in] privname - privilege name * * @return int * @retval 1 : if privname has not been added for account referenced by sid * @retval 0 : if privname has been added for account referenced by sid */ int add_privilege(SID *sid, char *privname) { LSA_UNICODE_STRING rights; LSA_HANDLE h_policy = INVALID_HANDLE_VALUE; LSA_OBJECT_ATTRIBUTES obj_attrs; NTSTATUS lsa_stat; BOOL rval = 1; WCHAR *privnameW = NULL; int priv_len = 0; if (privname == NULL) { fprintf(stderr, "add_privilege: NULL privname\n"); return (1); } if (!IsValidSid(sid)) { fprintf(stderr, "add_privilege: Not a valid sid\n"); return (1); } priv_len = strlen(privname) + 1; privnameW = (WCHAR *)malloc(priv_len * sizeof(WCHAR)); if (privnameW == NULL) { fprintf(stderr, "add_privilege: malloc failed\n"); return (1); } mbstowcs(privnameW, privname, priv_len); init_lsa_string(&rights, privnameW); ZeroMemory(&obj_attrs, sizeof(obj_attrs)); if( LsaOpenPolicy(NULL, &obj_attrs, POLICY_ALL_ACCESS, &h_policy) \ != ERROR_SUCCESS ) { fprintf(stderr, "add_privilege: Unable to open policy!\n"); goto add_privilege_end; } if( (lsa_stat=LsaAddAccountRights( h_policy, sid, &rights, 1 )) != \ ERROR_SUCCESS ) { fprintf(stderr, "add_privilege: adding privilege %s failed! - err %d\n", privname, LsaNtStatusToWinError(lsa_stat)); goto add_privilege_end; } printf("\tadded %s\n", privname); rval = 0; add_privilege_end: if (h_policy != INVALID_HANDLE_VALUE) LsaClose(h_policy); if (privnameW != NULL) (void)free(privnameW); return (rval); }
static VOID InstallBuiltinAccounts(VOID) { LPWSTR BuiltinAccounts[] = { L"S-1-1-0", /* Everyone */ L"S-1-5-4", /* Interactive */ L"S-1-5-6", /* Service */ L"S-1-5-19", /* Local Service */ L"S-1-5-20", /* Network Service */ L"S-1-5-32-544", /* Administrators */ L"S-1-5-32-545", /* Users */ L"S-1-5-32-547", /* Power Users */ L"S-1-5-32-551", /* Backup Operators */ L"S-1-5-32-555"}; /* Remote Desktop Users */ LSA_OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; LSA_HANDLE PolicyHandle = NULL; LSA_HANDLE AccountHandle = NULL; PSID AccountSid; ULONG i; DPRINT("InstallBuiltinAccounts()\n"); memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES)); Status = LsaOpenPolicy(NULL, &ObjectAttributes, POLICY_CREATE_ACCOUNT, &PolicyHandle); if (!NT_SUCCESS(Status)) { DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status); return; } for (i = 0; i < 10; i++) { if (!ConvertStringSidToSid(BuiltinAccounts[i], &AccountSid)) { DPRINT1("ConvertStringSidToSid(%S) failed: %lu\n", BuiltinAccounts[i], GetLastError()); continue; } Status = LsaCreateAccount(PolicyHandle, AccountSid, 0, &AccountHandle); if (NT_SUCCESS(Status)) { LsaClose(AccountHandle); } LocalFree(AccountSid); } LsaClose(PolicyHandle); }
NTSTATUS InstallNetWare( LPWSTR lpNcpSecretKey ) { NTSTATUS ntstatus; OBJECT_ATTRIBUTES ObjAttributes; LSA_HANDLE PolicyHandle; LSA_HANDLE SecretHandle; UNICODE_STRING SecretNameString; UNICODE_STRING unicodeCurrentValue; UNICODE_STRING unicodeOldValue; InitializeObjectAttributes( &ObjAttributes, NULL, 0L, NULL, NULL); ntstatus = LsaOpenPolicy( NULL, &ObjAttributes, POLICY_CREATE_SECRET, &PolicyHandle ); if ( !NT_SUCCESS( ntstatus )) { return( ntstatus ); } RtlInitUnicodeString( &SecretNameString, NCP_LSA_SECRET_KEY ); ntstatus = LsaCreateSecret( PolicyHandle, &SecretNameString, SECRET_SET_VALUE | DELETE, &SecretHandle ); if ( ntstatus == STATUS_OBJECT_NAME_COLLISION ) { ntstatus = LsaOpenSecret( PolicyHandle, &SecretNameString, SECRET_SET_VALUE, &SecretHandle ); } if ( NT_SUCCESS( ntstatus )) { RtlInitUnicodeString( &unicodeOldValue, NULL ); RtlInitUnicodeString( &unicodeCurrentValue, lpNcpSecretKey ); ntstatus = LsaSetSecret( SecretHandle, &unicodeCurrentValue, &unicodeOldValue ); LsaClose( SecretHandle ); } LsaClose( PolicyHandle ); return( ntstatus ); }
LSA_HANDLE OpenPolicy(DWORD accessMask) { LSA_OBJECT_ATTRIBUTES objectAttributes; ZeroMemory(&objectAttributes, sizeof(objectAttributes)); LSA_UNICODE_STRING lsaMachineName; InitLsaString(&lsaMachineName, L"."); LSA_HANDLE hPolicy = NULL; CheckRetVal(LsaOpenPolicy(&lsaMachineName, &objectAttributes, accessMask, &hPolicy)); return hPolicy; }
BOOL lsa_open(LSA_HANDLE* lsa_handle) { LSA_OBJECT_ATTRIBUTES object_attributes; NTSTATUS nt_status; *lsa_handle = NULL; ZeroMemory(&object_attributes, sizeof(object_attributes)); nt_status = LsaOpenPolicy(NULL, &object_attributes, POLICY_ALL_ACCESS, lsa_handle); if (nt_status != STATUS_SUCCESS) return lsa_error(nt_status, L"LsaOpenPolicy"); return TRUE; }
DWORD ScmSetServicePassword( IN PCWSTR pszServiceName, IN PCWSTR pszPassword) { OBJECT_ATTRIBUTES ObjectAttributes; LSA_HANDLE PolicyHandle = NULL; UNICODE_STRING ServiceName = {0, 0, NULL}; UNICODE_STRING Password; NTSTATUS Status; DWORD dwError = ERROR_SUCCESS; RtlZeroMemory(&ObjectAttributes, sizeof(OBJECT_ATTRIBUTES)); Status = LsaOpenPolicy(NULL, &ObjectAttributes, POLICY_CREATE_SECRET, &PolicyHandle); if (!NT_SUCCESS(Status)) return RtlNtStatusToDosError(Status); ServiceName.Length = (wcslen(pszServiceName) + 4) * sizeof(WCHAR); ServiceName.MaximumLength = ServiceName.Length + sizeof(WCHAR); ServiceName.Buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ServiceName.MaximumLength); if (ServiceName.Buffer == NULL) return ERROR_NOT_ENOUGH_MEMORY; wcscpy(ServiceName.Buffer, L"_SC_"); wcscat(ServiceName.Buffer, pszServiceName); RtlInitUnicodeString(&Password, pszPassword); Status = LsaStorePrivateData(PolicyHandle, &ServiceName, pszPassword ? &Password : NULL); if (!NT_SUCCESS(Status)) { dwError = RtlNtStatusToDosError(Status); goto done; } done: if (ServiceName.Buffer != NULL) HeapFree(GetProcessHeap(), 0, ServiceName.Buffer); if (PolicyHandle != NULL) LsaClose(PolicyHandle); return dwError; }
BOOL kull_m_net_getCurrentDomainInfo(PPOLICY_DNS_DOMAIN_INFO * pDomainInfo) { BOOL status = FALSE; LSA_HANDLE hLSA; LSA_OBJECT_ATTRIBUTES oaLsa = {0}; if(NT_SUCCESS(LsaOpenPolicy(NULL, &oaLsa, POLICY_VIEW_LOCAL_INFORMATION, &hLSA))) { status = NT_SUCCESS(LsaQueryInformationPolicy(hLSA, PolicyDnsDomainInformation, (PVOID *) pDomainInfo)); LsaClose(hLSA); } return status; }
PLSA_UNICODE_STRING CDialupass::GetLsaData(LPSTR KeyName) { LSA_OBJECT_ATTRIBUTES LsaObjectAttribs; LSA_HANDLE LsaHandle; LSA_UNICODE_STRING LsaKeyName; NTSTATUS nts; PLSA_UNICODE_STRING OutData; ZeroMemory(&LsaObjectAttribs,sizeof(LsaObjectAttribs)); nts=LsaOpenPolicy(NULL,&LsaObjectAttribs,POLICY_GET_PRIVATE_INFORMATION,&LsaHandle); if(nts!=0)return NULL; AnsiStringToLsaStr(KeyName, &LsaKeyName); nts=LsaRetrievePrivateData(LsaHandle, &LsaKeyName,&OutData); if(nts!=0)return NULL; nts=LsaClose(LsaHandle); if(nts!=0)return NULL; return OutData; }
static BOOL ObtainLockPagesPrivilege() { HANDLE token; PTOKEN_USER user = NULL; if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) == TRUE) { DWORD size = 0; GetTokenInformation(token, TokenUser, NULL, 0, &size); if (size) { user = (PTOKEN_USER) LocalAlloc(LPTR, size); } GetTokenInformation(token, TokenUser, user, size, &size); CloseHandle(token); } if (!user) { return FALSE; } LSA_HANDLE handle; LSA_OBJECT_ATTRIBUTES attributes; ZeroMemory(&attributes, sizeof(attributes)); BOOL result = FALSE; if (LsaOpenPolicy(NULL, &attributes, POLICY_ALL_ACCESS, &handle) == 0) { LSA_UNICODE_STRING str = StringToLsaUnicodeString(_T(SE_LOCK_MEMORY_NAME)); if (LsaAddAccountRights(handle, user->User.Sid, &str, 1) == 0) { LOG_NOTICE("Huge pages support was successfully enabled, but reboot required to use it"); result = TRUE; } LsaClose(handle); } LocalFree(user); return result; }
static int ondata_no_sid(struct lm_sam_s *This, PUNICODE_STRING uname, HASH hash, NTSTATUS *result){ LSA_HANDLE h_policy; LSA_OBJECT_ATTRIBUTES objattr; POLICY_ACCOUNT_DOMAIN_INFO *pdomain_info; NTSTATUS status; char dname[64]; memset(&objattr, 0, sizeof(objattr)); objattr.Length = sizeof(objattr); if((status = LsaOpenPolicy(NULL, &objattr, POLICY_VIEW_LOCAL_INFORMATION, &h_policy)) != STATUS_SUCCESS){ DOUTST2("LsaOpenPolicy", status); *result = status; return 0; } if((status = LsaQueryInformationPolicy(h_policy, PolicyAccountDomainInformation, &pdomain_info)) != STATUS_SUCCESS){ DOUTST2("LsaQueryInformationPolicy", status); LsaClose(h_policy); *result = status; return 0; } if(unicode2ansi(pdomain_info->DomainName.Buffer, pdomain_info->DomainName.Length, dname, sizeof(dname)) == 0){ strcpy(dname, "<unknown>"); } dout(va("Current domain is %s.\n", dname)); This->lsa_policy_info_buffer = pdomain_info; This->domain_sid = pdomain_info->DomainSid; // delegate processing to no_sam state This->state = &state_no_sam; return This->state->data(This, uname, hash, result); }
NTSTATUS OpenPolicy( LPWSTR ServerName, DWORD DesiredAccess, PLSA_HANDLE PolicyHandle ) { PLSA_UNICODE_STRING Server; LSA_OBJECT_ATTRIBUTES ObjectAttributes; LSA_UNICODE_STRING ServerString; // // Always initialize the object attributes to all zeroes // ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes)); if(ServerName != NULL) { // // Make a LSA_UNICODE_STRING out of the LPWSTR passed in // InitLsaString(&ServerString, ServerName); Server = &ServerString; } else { Server = NULL; // default to local machine } // // Attempt to open the policy and return NTSTATUS // return LsaOpenPolicy( Server, &ObjectAttributes, DesiredAccess, PolicyHandle ); }
/* 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; }
static VOID InstallPrivileges(VOID) { HINF hSecurityInf = INVALID_HANDLE_VALUE; LSA_OBJECT_ATTRIBUTES ObjectAttributes; WCHAR szPrivilegeString[256]; WCHAR szSidString[256]; INFCONTEXT InfContext; DWORD i; PRIVILEGE_SET PrivilegeSet; PSID AccountSid; NTSTATUS Status; LSA_HANDLE PolicyHandle = NULL; LSA_HANDLE AccountHandle; DPRINT("InstallPrivileges()\n"); hSecurityInf = SetupOpenInfFileW(L"defltws.inf", //szNameBuffer, NULL, INF_STYLE_WIN4, NULL); if (hSecurityInf == INVALID_HANDLE_VALUE) { DPRINT1("SetupOpenInfFileW failed\n"); return; } memset(&ObjectAttributes, 0, sizeof(LSA_OBJECT_ATTRIBUTES)); Status = LsaOpenPolicy(NULL, &ObjectAttributes, POLICY_CREATE_ACCOUNT, &PolicyHandle); if (!NT_SUCCESS(Status)) { DPRINT1("LsaOpenPolicy failed (Status %08lx)\n", Status); goto done; } if (!SetupFindFirstLineW(hSecurityInf, L"Privilege Rights", NULL, &InfContext)) { DPRINT1("SetupFindfirstLineW failed\n"); goto done; } PrivilegeSet.PrivilegeCount = 1; PrivilegeSet.Control = 0; do { /* Retrieve the privilege name */ if (!SetupGetStringFieldW(&InfContext, 0, szPrivilegeString, 256, NULL)) { DPRINT1("SetupGetStringFieldW() failed\n"); goto done; } DPRINT("Privilege: %S\n", szPrivilegeString); if (!LookupPrivilegeValueW(NULL, szPrivilegeString, &(PrivilegeSet.Privilege[0].Luid))) { DPRINT1("LookupPrivilegeNameW() failed\n"); goto done; } PrivilegeSet.Privilege[0].Attributes = 0; for (i = 0; i < SetupGetFieldCount(&InfContext); i++) { if (!SetupGetStringFieldW(&InfContext, i + 1, szSidString, 256, NULL)) { DPRINT1("SetupGetStringFieldW() failed\n"); goto done; } DPRINT("SID: %S\n", szSidString); ConvertStringSidToSid(szSidString, &AccountSid); Status = LsaOpenAccount(PolicyHandle, AccountSid, ACCOUNT_VIEW | ACCOUNT_ADJUST_PRIVILEGES, &AccountHandle); if (NT_SUCCESS(Status)) { Status = LsaAddPrivilegesToAccount(AccountHandle, &PrivilegeSet); if (!NT_SUCCESS(Status)) { DPRINT1("LsaAddPrivilegesToAccount() failed (Status %08lx)\n", Status); } LsaClose(AccountHandle); } LocalFree(AccountSid); } } while (SetupFindNextLine(&InfContext, &InfContext)); done: if (PolicyHandle != NULL) LsaClose(PolicyHandle); if (hSecurityInf != INVALID_HANDLE_VALUE) SetupCloseInfFile(hSecurityInf); }
/************************************************************ * 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; }
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); } }
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); }
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 ); }
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; }
mDNSBool LsaSetSecret( const char * inDomain, const char * inKey, const char * inSecret ) { size_t inDomainLength; size_t inKeyLength; char domain[ 1024 ]; char key[ 1024 ]; LSA_OBJECT_ATTRIBUTES attrs; LSA_HANDLE handle = NULL; NTSTATUS res; LSA_UNICODE_STRING lucZoneName; LSA_UNICODE_STRING lucKeyName; LSA_UNICODE_STRING lucSecretName; BOOL ok = TRUE; OSStatus err; require_action( inDomain != NULL, exit, ok = FALSE ); require_action( inKey != NULL, exit, ok = FALSE ); require_action( inSecret != NULL, exit, ok = FALSE ); // If there isn't a trailing dot, add one because the mDNSResponder // presents names with the trailing dot. ZeroMemory( domain, sizeof( domain ) ); inDomainLength = strlen( inDomain ); require_action( inDomainLength > 0, exit, ok = FALSE ); err = strcpy_s( domain, sizeof( domain ) - 2, inDomain ); require_action( !err, exit, ok = FALSE ); if ( domain[ inDomainLength - 1 ] != '.' ) { domain[ inDomainLength++ ] = '.'; domain[ inDomainLength ] = '\0'; } // <rdar://problem/4192119> // // Prepend "$" to the key name, so that there will // be no conflict between the zone name and the key // name ZeroMemory( key, sizeof( key ) ); inKeyLength = strlen( inKey ); require_action( inKeyLength > 0 , exit, ok = FALSE ); key[ 0 ] = '$'; err = strcpy_s( key + 1, sizeof( key ) - 3, inKey ); require_action( !err, exit, ok = FALSE ); inKeyLength++; if ( key[ inKeyLength - 1 ] != '.' ) { key[ inKeyLength++ ] = '.'; key[ inKeyLength ] = '\0'; } // 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_ALL_ACCESS, &handle ); err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr ); require_noerr( err, exit ); // Intializing PLSA_UNICODE_STRING structures err = MakeLsaStringFromUTF8String( &lucZoneName, domain ); require_noerr( err, exit ); err = MakeLsaStringFromUTF8String( &lucKeyName, key ); require_noerr( err, exit ); err = MakeLsaStringFromUTF8String( &lucSecretName, inSecret ); require_noerr( err, exit ); // Store the private data. res = LsaStorePrivateData( handle, &lucZoneName, &lucKeyName ); err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr ); require_noerr( err, exit ); res = LsaStorePrivateData( handle, &lucKeyName, &lucSecretName ); err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr ); require_noerr( err, exit ); exit: if ( handle ) { LsaClose( handle ); handle = NULL; } return ok; }
/****************************************************************************** * 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; }
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); }
NTSTATUS LsapGetAccountDomainInfo( PPOLICY_ACCOUNT_DOMAIN_INFO *PolicyAccountDomainInfo ) /*++ Routine Description: This routine retrieves ACCOUNT domain information from the LSA policy database. Arguments: PolicyAccountDomainInfo - Receives a pointer to a POLICY_ACCOUNT_DOMAIN_INFO structure containing the account domain info. Return Value: STATUS_SUCCESS - Succeeded. Other status values that may be returned from: LsaOpenPolicy() LsaQueryInformationPolicy() --*/ { NTSTATUS Status, IgnoreStatus; LSA_HANDLE PolicyHandle; OBJECT_ATTRIBUTES PolicyObjectAttributes; // // Open the policy database // InitializeObjectAttributes( &PolicyObjectAttributes, NULL, // Name 0, // Attributes NULL, // Root NULL ); // Security Descriptor Status = LsaOpenPolicy( NULL, &PolicyObjectAttributes, POLICY_VIEW_LOCAL_INFORMATION, &PolicyHandle ); if ( NT_SUCCESS(Status) ) { // // Query the account domain information // Status = LsaQueryInformationPolicy( PolicyHandle, PolicyAccountDomainInformation, (PVOID *) PolicyAccountDomainInfo ); #if DBG if ( NT_SUCCESS(Status) ) { ASSERT( (*PolicyAccountDomainInfo) != NULL ); ASSERT( (*PolicyAccountDomainInfo)->DomainSid != NULL ); } #endif // DBG IgnoreStatus = LsaClose( PolicyHandle ); ASSERT(NT_SUCCESS(IgnoreStatus)); } 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); } }