NTSTATUS AddPrivilegeToAcccount(LPTSTR name, LPWSTR PrivilegeName) { LSA_HANDLE PolicyHandle; TCHAR AccountName[256]; /* static account name buffer */ PSID pSid; NTSTATUS Status; unsigned long err; /* * Open the policy on the target machine. */ if ((Status = OpenPolicy(NULL, POLICY_ALL_ACCESS, &PolicyHandle)) != STATUS_SUCCESS) return (RTN_ERROR); /* * Let's see if the account exists. Return if not */ wsprintf(AccountName, TEXT("%hS"), name); if (!GetAccountSid(NULL, AccountName, &pSid)) return (RTN_NOACCOUNT); err = LsaNtStatusToWinError(SetPrivilegeOnAccount(PolicyHandle, pSid, PrivilegeName, TRUE)); LsaClose(PolicyHandle); if (err == ERROR_SUCCESS) return (RTN_OK); else return (err); }
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 SetPrivilegeOnAccount( LPTSTR AccountName, // account name to check on LPWSTR PrivilegeName, // privilege to grant (Unicode) BOOL bEnable // enable or disable ) { NTSTATUS res = 0; LSA_HANDLE policy_handle = NULL; PSID account_sid = NULL; // // Open the policy on the target machine. // if((res=OpenPolicy( NULL, // target machine POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES, &policy_handle // resultant policy handle )) != STATUS_SUCCESS) { DisplayNtStatus("OpenPolicy", res); return false; } if (policy_handle == NULL){ printf("..Failed.\nGetPolicyHandle() failed\r\n"); return false; } if (!GetAccountSid(NULL, AccountName, &account_sid)) { DisplayLastWin32Error(); if (policy_handle != NULL){ myLsaClose(policy_handle); } return false; } bool rv = false; if (SetPrivilegeOnAccount(policy_handle, account_sid, L"SeServiceLogonRight", TRUE) == STATUS_SUCCESS) rv = true; if (policy_handle != NULL){ myLsaClose(policy_handle); } if (account_sid != NULL){ HeapFree(GetProcessHeap(), 0, account_sid); } return rv; }
BOOL GrantUserRight( PSID psidAccountSid, LPWSTR pszUserRight, BOOL bEnable ) { LSA_HANDLE PolicyHandle = NULL; NTSTATUS Status; // // Open the policy on the local host. // Status = OpenPolicy( _T(""), POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES, &PolicyHandle ); if(Status != STATUS_SUCCESS) { return FALSE; } // // Grant the requested user right represented by psidAccountSid. // Status = SetPrivilegeOnAccount( PolicyHandle, // policy handle psidAccountSid, // SID to grant privilege pszUserRight, // Unicode privilege bEnable // enable the privilege ); if(Status != STATUS_SUCCESS) { LsaClose(PolicyHandle); return FALSE; } // // Cleanup any handles and memory allocated during the custom action // LsaClose(PolicyHandle); return TRUE; }
void RevokePrivilege(PSID sid, LPCWSTR userRight) { LSA_HANDLE hPolicy = OpenPolicy(POLICY_LOOKUP_NAMES); try { LSA_UNICODE_STRING lsaUserRight; InitLsaString(&lsaUserRight, (LPWSTR)userRight); CheckRetVal(LsaRemoveAccountRights(hPolicy, sid, FALSE, &lsaUserRight, 1)); LsaClose(hPolicy); } catch (const std::exception&) { LsaClose(hPolicy); throw; } }
void GrantPrivilege(PSID sid, LPCWSTR userRight) { LSA_HANDLE hPolicy = OpenPolicy(POLICY_LOOKUP_NAMES | POLICY_CREATE_ACCOUNT); try { LSA_UNICODE_STRING lsaUserRight; InitLsaString(&lsaUserRight, (LPWSTR)userRight); CheckRetVal(LsaAddAccountRights(hPolicy, sid, &lsaUserRight, 1)); LsaClose(hPolicy); } catch (const std::exception&) { LsaClose(hPolicy); throw; } }
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; } }
int __cdecl main( int argc, char *argv[] ) { LSA_HANDLE PolicyHandle; WCHAR wComputerName[256]=L""; // static machine name buffer TCHAR AccountName[256]; // static account name buffer PSID pSid; NTSTATUS Status; int iRetVal=RTN_ERROR; // assume error from main if(argc == 1) { fprintf(stderr,"Usage: %s <Account> [TargetMachine]\n", argv[0]); return RTN_USAGE; } // // Pick up account name on argv[1]. // Assumes source is ANSI. Resultant string is ANSI or Unicode // _snwprintf_s(AccountName, 256, 255, TEXT("%hS"), argv[1]); // // Pick up machine name on argv[2], if appropriate // assumes source is ANSI. Resultant string is Unicode. // if(argc == 3) _snwprintf_s(wComputerName, 256, 255, L"%hS", argv[2]); // // Open the policy on the target machine. // Status = OpenPolicy( wComputerName, // target machine POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES, &PolicyHandle // resultant policy handle ); if(Status != STATUS_SUCCESS) { DisplayNtStatus("OpenPolicy", Status); return RTN_ERROR; } // // Obtain the SID of the user/group. // Note that we could target a specific machine, but we don't. // Specifying NULL for target machine searches for the SID in the // following order: well-known, Built-in and local, primary domain, // trusted domains. // if(GetAccountSid( NULL, // default lookup logic AccountName,// account to obtain SID &pSid // buffer to allocate to contain resultant SID )) { // // We only grant the privilege if we succeeded in obtaining the // SID. We can actually add SIDs which cannot be looked up, but // looking up the SID is a good sanity check which is suitable for // most cases. // // Grant the SeServiceLogonRight to users represented by pSid. // Status = SetPrivilegeOnAccount( PolicyHandle, // policy handle pSid, // SID to grant privilege L"SeServiceLogonRight", // Unicode privilege TRUE // enable the privilege ); if(Status == STATUS_SUCCESS) iRetVal=RTN_OK; else DisplayNtStatus("SetPrivilegeOnAccount", Status); } else { // // Error obtaining SID. // DisplayWinError("GetAccountSid", GetLastError()); } // // Close the policy handle. // LsaClose(PolicyHandle); // // Free memory allocated for SID. // if(pSid != NULL) HeapFree(GetProcessHeap(), 0, pSid); return iRetVal; }
// // unicode entry point and argv // int __cdecl wmain( int argc, wchar_t *argv[] ) { LPWSTR wComputerName; LSA_HANDLE PolicyHandle; NTSTATUS Status; // // pickup machine name if appropriate // if(argc == 2) wComputerName = argv[1]; else wComputerName = NULL; // local machine // // display current audit state // Status = OpenPolicy( wComputerName, POLICY_VIEW_AUDIT_INFORMATION, &PolicyHandle ); if(Status == STATUS_SUCCESS) { // // display current auditing status // Status = DisplayAudit(PolicyHandle); LsaClose(PolicyHandle); if(Status != STATUS_SUCCESS) { DisplayNtStatus("DisplayAudit", Status); return RTN_ERROR; } } else { DisplayNtStatus("OpenPolicy", Status); return RTN_ERROR; } // // enable success and failure audits of logon/logoff events // Status = OpenPolicy( wComputerName, POLICY_VIEW_AUDIT_INFORMATION | POLICY_SET_AUDIT_REQUIREMENTS, &PolicyHandle ); if(Status == STATUS_SUCCESS) { // // enable success and failure auditing of logon/logoff // Status = SetAuditEvent( PolicyHandle, AuditCategoryLogon, POLICY_AUDIT_EVENT_SUCCESS | POLICY_AUDIT_EVENT_FAILURE ); // // enable audits // if( Status == STATUS_SUCCESS ) Status = SetAuditMode(PolicyHandle, TRUE); LsaClose(PolicyHandle); if(Status != STATUS_SUCCESS) { DisplayNtStatus("SetAuditMode", Status); return RTN_ERROR; } } else { DisplayNtStatus("OpenPolicy", Status); return RTN_ERROR; } return RTN_OK; }
/*! * \breif Checks to see if the user has the correct privilages * \param user the username to check * \param priv the privilage to check * \param dc (default to NULL to check local machine) else the dc of the machine to check * \returns true if the user has all the right privs else false */ bool CheckSingleUserPriv(char *user, WCHAR *priv, char *dc) { WCHAR wComputerName[256]=L""; // static machine name buffer PSID account_sid = NULL; PLSA_UNICODE_STRING user_rights = NULL; ULONG num_rights = 0; LPTSTR referenced_domain = NULL; DWORD cb_sid = 0; // zero so we can get the needed size DWORD cch_referenced_domain = 0; // zero so we can get the needed size BOOL bSuccess = FALSE; // assume this function will fail DWORD dwResult = 0; NTSTATUS res = 0; LSA_HANDLE policy_handle = NULL; LPWSTR u_dc = NULL; LPWSTR u_user = NULL; bool found_priv = false; DWORD dwRet = 0; LPTSTR pszDNS = NULL; char lwszSysErr[512]; DWORD dw_syserr = sizeof(lwszSysErr); unsigned int i = 0; bool rc = false; if (!svcLib) { svcLib = LoadLibrary("Advapi32.dll"); if (!svcLib) return false; } if (!myConvertSidToStringSid) { // Get the function pointers #ifdef UNICODE myConvertSidToStringSid = (lpfnConvertSidToStringSid)GetProcAddress(svcLib, "ConvertSidToStringSidW"); #else myConvertSidToStringSid = (lpfnConvertSidToStringSid)GetProcAddress(svcLib, "ConvertSidToStringSidA"); #endif // !UNICODE myCreateWellKnownSid = (lpfnCreateWellKnownSid)GetProcAddress(svcLib, "CreateWellKnownSid"); myLsaAddAccountRights = (lpfnLsaAddAccountRights)GetProcAddress(svcLib, "LsaAddAccountRights"); myLsaClose = (lpfnLsaClose)GetProcAddress(svcLib, "LsaClose"); myLsaEnumerateAccountRights = (lpfnLsaEnumerateAccountRights)GetProcAddress(svcLib, "LsaEnumerateAccountRights"); myLsaFreeMemory = (lpfnLsaFreeMemory)GetProcAddress(svcLib, "LsaFreeMemory"); myLsaNtStatusToWinError = (lpfnLsaNtStatusToWinError)GetProcAddress(svcLib, "LsaNtStatusToWinError"); myLsaOpenPolicy = (lpfnLsaOpenPolicy)GetProcAddress(svcLib, "LsaOpenPolicy"); if (!myConvertSidToStringSid || !myCreateWellKnownSid || !myLsaAddAccountRights || !myLsaClose || !myLsaEnumerateAccountRights || !myLsaNtStatusToWinError || !myLsaOpenPolicy) return false; } // // Open the policy on the target machine. // if((res=OpenPolicy( wComputerName, // target machine POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES, &policy_handle // resultant policy handle )) != STATUS_SUCCESS) { DisplayNtStatus("OpenPolicy", res); return false; } if (policy_handle == NULL){ printf("..Failed.\nGetPolicyHandle() failed\r\n"); goto LBL_CLEANUP; } if (!GetAccountSid(NULL, user, &account_sid)) { DisplayLastWin32Error(); return false; } res = myLsaEnumerateAccountRights( policy_handle, account_sid, &user_rights, &num_rights); if (res != STATUS_SUCCESS){ dwRet = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, myLsaNtStatusToWinError(res), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) lwszSysErr, dw_syserr, NULL); printf("..Failed. %s\r\n", lwszSysErr); rc = false; goto LBL_CLEANUP; } for (i = 0 ; i <num_rights; i++){ if ( wcscmp(user_rights[i].Buffer, priv) == 0){ // Found it found_priv = true; } } if (user_rights != NULL){ myLsaFreeMemory(user_rights); user_rights = NULL; } if (!found_priv){ DWORD sid_size; PSID well_know_sid; LPTSTR sid_str; sid_size = SECURITY_MAX_SID_SIZE; // Allocate enough memory for the largest possible SID. if(!(well_know_sid = LocalAlloc(LMEM_FIXED, sid_size))){ // fprintf(stderr, "Could not allocate memory.\n"); } // Create a SID for the Everyone group on the local computer. if(!myCreateWellKnownSid(WinWorldSid, NULL, well_know_sid, &sid_size)){ dwRet = GetLastError(); dwRet = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwRet, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) lwszSysErr, dw_syserr, NULL); printf("..Failed. %s\r\n", lwszSysErr); goto LBL_CLEANUP; } else { // Get the string version of the SID (S-1-1-0). if(!(myConvertSidToStringSid(well_know_sid, &sid_str))){ dwRet = GetLastError(); dwRet = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwRet, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) lwszSysErr, dw_syserr, NULL); printf("..Failed. %s\r\n", lwszSysErr); goto LBL_CLEANUP; } res = myLsaEnumerateAccountRights( policy_handle, well_know_sid, &user_rights, &num_rights); if (res != STATUS_SUCCESS){ dwRet = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, myLsaNtStatusToWinError(res), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) lwszSysErr, dw_syserr, NULL); printf("..Failed. %s\r\n", lwszSysErr); goto LBL_CLEANUP; } for (i = 0 ; i < num_rights; i++){ if ( wcscmp(user_rights[i].Buffer, priv) == 0){ // Found it found_priv = true; } } } if (sid_str){ LocalFree(sid_str); } if(well_know_sid){ LocalFree(well_know_sid); } } rc = (found_priv == true); LBL_CLEANUP: if (policy_handle != NULL){ myLsaClose(policy_handle); } if (user_rights != NULL){ myLsaFreeMemory(user_rights); } if (account_sid != NULL){ HeapFree(GetProcessHeap(), 0, account_sid); } if (referenced_domain != NULL){ HeapFree(GetProcessHeap(), 0, referenced_domain); } return rc; }
int GetAccountPrivileges(char *name, wchar_t **PrivList, unsigned int *PrivCount, char **Accounts, unsigned int *totalAccounts, int maxAccounts) { LSA_HANDLE PolicyHandle; TCHAR AccountName[256]; /* static account name buffer */ PSID pSid; unsigned int i; NTSTATUS Status; isc_result_t istatus; int iRetVal = RTN_ERROR; /* assume error from main */ /* * Open the policy on the target machine. */ if ((Status = OpenPolicy(NULL, POLICY_LOOKUP_NAMES, &PolicyHandle)) != STATUS_SUCCESS) return (RTN_ERROR); /* * Let's see if the account exists. Return if not */ wsprintf(AccountName, TEXT("%hS"), name); if (!GetAccountSid(NULL, AccountName, &pSid)) return (RTN_NOACCOUNT); /* * Find out what groups the account belongs to */ istatus = isc_ntsecurity_getaccountgroups(name, Accounts, maxAccounts, totalAccounts); if (istatus == ISC_R_NOMEMORY) return (RTN_NOMEMORY); else if (istatus != ISC_R_SUCCESS) return (RTN_ERROR); Accounts[*totalAccounts] = name; /* Add the account to the list */ (*totalAccounts)++; /* * Loop through each Account to get the list of privileges */ for (i = 0; i < *totalAccounts; i++) { wsprintf(AccountName, TEXT("%hS"), Accounts[i]); /* Obtain the SID of the user/group. */ if (!GetAccountSid(NULL, AccountName, &pSid)) continue; /* Try the next one */ /* Get the Privileges allocated to this SID */ if ((Status = GetPrivilegesOnAccount(PolicyHandle, pSid, PrivList, PrivCount)) == STATUS_SUCCESS) { iRetVal=RTN_OK; if (pSid != NULL) HeapFree(GetProcessHeap(), 0, pSid); } else { if (pSid != NULL) HeapFree(GetProcessHeap(), 0, pSid); continue; /* Try the next one */ } } /* * Close the policy handle. */ LsaClose(PolicyHandle); (*totalAccounts)--; /* Correct for the number of groups */ return iRetVal; }