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); }
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; }
DWORD GrantDesktopAccess( IN const WCHAR *accountName, IN const WCHAR *systemName ) { HWINSTA originalWindowStation; HWINSTA windowStation = NULL; HDESK desktop = NULL; DWORD status = ERROR_UNIDENTIFIED_ERROR; SID *sid = NULL; EXPLICIT_ACCESS newEa[2]; if (!accountName) return ERROR_INVALID_PARAMETER; originalWindowStation = GetProcessWindowStation(); if (!originalWindowStation) { return perror("GetProcessWindowStation"); } windowStation = OpenWindowStation( L"WinSta0", FALSE, READ_CONTROL | WRITE_DAC); if (!windowStation) { return perror("OpenWindowStation"); } if (!SetProcessWindowStation(windowStation)) { status = perror("SetProcessWindowStation"); goto cleanup; } desktop = OpenDesktop( TEXT("Default"), 0, FALSE, READ_CONTROL | WRITE_DAC | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS); if (!desktop) { status = perror("OpenDesktop"); goto cleanup; } if (!SetProcessWindowStation(originalWindowStation)) { status = perror("SetProcessWindowStation(Original)"); goto cleanup; } status = GetAccountSid(accountName, systemName, &sid); if (ERROR_SUCCESS != status) { perror2(status, "GetAccountSid"); goto cleanup; } newEa[0].grfAccessPermissions = GENERIC_ACCESS; newEa[0].grfAccessMode = GRANT_ACCESS; newEa[0].grfInheritance = CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE; newEa[0].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE; newEa[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; newEa[0].Trustee.TrusteeType = TRUSTEE_IS_USER; newEa[0].Trustee.ptstrName = (WCHAR *)sid; newEa[1] = newEa[0]; newEa[1].grfAccessPermissions = WINSTA_ALL; newEa[1].grfInheritance = NO_PROPAGATE_INHERIT_ACE; status = MergeWithExistingDacl(windowStation, 2, newEa); if (ERROR_SUCCESS != status) { perror2(status, "MergeWithExistingDacl(WindowStation)"); goto cleanup; } newEa[0].grfAccessPermissions = DESKTOP_ALL; newEa[0].grfAccessMode = GRANT_ACCESS; newEa[0].grfInheritance = 0; status = MergeWithExistingDacl(desktop, 1, newEa); if (ERROR_SUCCESS != status) { perror2(status, "MergeWithExistingDacl(Desktop)"); goto cleanup; } cleanup: if (desktop) CloseDesktop(desktop); if (windowStation) CloseWindowStation(windowStation); if (sid) LocalFree(sid); return ERROR_SUCCESS; }
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; }
///////////////////////////////////////////////////////////////////// // // Function: // // Description: // ///////////////////////////////////////////////////////////////////// UINT CAGrantBOINCProjectsRights::OnExecution() { PSID pSid; tstring strOSVersion; UINT uiReturnValue; uiReturnValue = GetProperty( _T("VersionNT"), strOSVersion ); if ( uiReturnValue ) return uiReturnValue; // // 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 tstring(L"boinc_projects").c_str(), // 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. // User Rights GrantUserRight(pSid, L"SeNetworkLogonRight", FALSE); GrantUserRight(pSid, L"SeRemoteInteractiveLogonRight", FALSE); GrantUserRight(pSid, L"SeBatchLogonRight", FALSE); GrantUserRight(pSid, L"SeInteractiveLogonRight", FALSE); GrantUserRight(pSid, L"SeServiceLogonRight", FALSE); GrantUserRight(pSid, L"SeDenyNetworkLogonRight", FALSE); GrantUserRight(pSid, L"SeDenyInteractiveLogonRight", FALSE); GrantUserRight(pSid, L"SeDenyBatchLogonRight", FALSE); GrantUserRight(pSid, L"SeDenyServiceLogonRight", FALSE); // Windows 2000 and older does not have the SeDenyRemoteInteractiveLogonRight user right // if (strOSVersion > _T("500")) { GrantUserRight(pSid, L"SeDenyRemoteInteractiveLogonRight", FALSE); } // Privileges GrantUserRight(pSid, L"SeTcbPrivilege", FALSE); GrantUserRight(pSid, L"SeMachineAccountPrivilege", FALSE); GrantUserRight(pSid, L"SeIncreaseQuotaPrivilege", FALSE); GrantUserRight(pSid, L"SeBackupPrivilege", FALSE); if (!GrantUserRight(pSid, L"SeChangeNotifyPrivilege", TRUE)) { LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, NULL, _T("Failed call to GrantUserRight - SeChangeNotifyPrivilege") ); } GrantUserRight(pSid, L"SeSystemTimePrivilege", FALSE); GrantUserRight(pSid, L"SeCreateTokenPrivilege", FALSE); GrantUserRight(pSid, L"SeCreatePagefilePrivilege", FALSE); GrantUserRight(pSid, L"SeCreateGlobalPrivilege", FALSE); GrantUserRight(pSid, L"SeDebugPrivilege", FALSE); GrantUserRight(pSid, L"SeEnableDelegationPrivilege", FALSE); GrantUserRight(pSid, L"SeRemoteShutdownPrivilege", FALSE); GrantUserRight(pSid, L"SeAuditPrivilege", FALSE); GrantUserRight(pSid, L"SeImpersonatePrivilege", FALSE); GrantUserRight(pSid, L"SeIncreaseBasePriorityPrivilege", FALSE); GrantUserRight(pSid, L"SeLoadDriverPrivilege", FALSE); GrantUserRight(pSid, L"SeLockMemoryPrivilege", FALSE); GrantUserRight(pSid, L"SeSecurityPrivilege", FALSE); GrantUserRight(pSid, L"SeSystemEnvironmentPrivilege", FALSE); GrantUserRight(pSid, L"SeManageVolumePrivilege", FALSE); GrantUserRight(pSid, L"SeProfileSingleProcessPrivilege", FALSE); GrantUserRight(pSid, L"SeSystemProfilePrivilege", FALSE); GrantUserRight(pSid, L"SeUndockPrivilege", FALSE); GrantUserRight(pSid, L"SeAssignPrimaryTokenPrivilege", FALSE); GrantUserRight(pSid, L"SeRestorePrivilege", FALSE); GrantUserRight(pSid, L"SeShutdownPrivilege", FALSE); GrantUserRight(pSid, L"SeSynchAgentPrivilege", FALSE); GrantUserRight(pSid, L"SeTakeOwnershipPrivilege", FALSE); } else { LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, NULL, _T("Failed to be able to obtain the SID for the selected user on the localhost") ); return ERROR_INSTALL_FAILURE; } // // Cleanup any handles and memory allocated during the custom action // if(pSid != NULL) HeapFree(GetProcessHeap(), 0, pSid); return ERROR_SUCCESS; }
/*! * \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; }
///////////////////////////////////////////////////////////////////// // // Function: // // Description: // ///////////////////////////////////////////////////////////////////// UINT CACreateBOINCAccounts::OnExecution() { tstring strBOINCMasterAccountUsername; tstring strBOINCMasterAccountPassword; tstring strBOINCProjectAccountUsername; tstring strBOINCProjectAccountPassword; tstring strComputerName; tstring strProductType; tstring strDataDirectory; tstring strEnableProtectedApplicationExecution; PSID pSid; NET_API_STATUS nasReturnValue; BOOL bCreateBOINCMasterAccount = FALSE; BOOL bCreateBOINCProjectAccount = FALSE; BOOL bBOINCMasterAccountCreated = FALSE; BOOL bBOINCProjectAccountCreated = FALSE; BOOL bBOINCMasterAccountModified = FALSE; BOOL bBOINCProjectAccountModified = FALSE; UINT uiReturnValue = -1; uiReturnValue = GetProperty( _T("BOINC_MASTER_USERNAME"), strBOINCMasterAccountUsername ); if ( uiReturnValue ) return uiReturnValue; uiReturnValue = GetProperty( _T("BOINC_MASTER_PASSWORD"), strBOINCMasterAccountPassword ); if ( uiReturnValue ) return uiReturnValue; uiReturnValue = GetProperty( _T("BOINC_PROJECT_USERNAME"), strBOINCProjectAccountUsername ); if ( uiReturnValue ) return uiReturnValue; uiReturnValue = GetProperty( _T("BOINC_PROJECT_PASSWORD"), strBOINCProjectAccountPassword ); if ( uiReturnValue ) return uiReturnValue; uiReturnValue = GetProperty( _T("ComputerName"), strComputerName ); if ( uiReturnValue ) return uiReturnValue; uiReturnValue = GetProperty( _T("MsiNTProductType"), strProductType ); if ( uiReturnValue ) return uiReturnValue; uiReturnValue = GetProperty( _T("ENABLEPROTECTEDAPPLICATIONEXECUTION3"), strEnableProtectedApplicationExecution ); if ( uiReturnValue ) return uiReturnValue; // Only create a new account or change the password on an existing account // if the user hasn't explicitly defined an account if (strBOINCMasterAccountUsername.empty() && strBOINCMasterAccountPassword.empty()) bCreateBOINCMasterAccount = true; if (strBOINCMasterAccountUsername == _T("boinc_master")) bCreateBOINCMasterAccount = true; if (strProductType == tstring(_T("2")) && (strBOINCMasterAccountUsername == (tstring(_T("boinc_master_")) + strComputerName))) bCreateBOINCMasterAccount = true; if (bCreateBOINCMasterAccount) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("Using automatic account creation and management of 'boinc_master' account") ); // Determine what the real values of the usernames should be based off // of the inputs // if (strBOINCMasterAccountUsername.empty()) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("Generating 'boinc_master' account name") ); if (strProductType == tstring(_T("2"))) { // Domain Controller strBOINCMasterAccountUsername = _T("boinc_master_") + strComputerName; } else { strBOINCMasterAccountUsername = _T("boinc_master"); } } // Generate random passwords if needed // if (strBOINCMasterAccountPassword.empty()) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("Generating 'boinc_master' password") ); GenerateRandomPassword(strBOINCMasterAccountPassword, 12); strBOINCMasterAccountPassword = _T("!") + strBOINCMasterAccountPassword; } // Create the 'boinc_master' account if needed, otherwise just update the password. // if(GetAccountSid(NULL, strBOINCMasterAccountUsername.c_str(), &pSid)) { // Check if user exists LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("Resetting 'boinc_master' password") ); // Account already exists, just change the password // USER_INFO_1003 ui; DWORD dwParameterError; ui.usri1003_password = (LPWSTR)strBOINCMasterAccountPassword.c_str(); nasReturnValue = NetUserSetInfo( NULL, strBOINCMasterAccountUsername.c_str(), 1003, (LPBYTE)&ui, &dwParameterError ); if (NERR_Success != nasReturnValue) { LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, nasReturnValue, _T("Failed to reset password on the 'boinc_master' account.") ); return ERROR_INSTALL_FAILURE; } } else { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("Creating 'boinc_master' account") ); // Account does not exist, create it // USER_INFO_1 ui; DWORD dwParameterError; ui.usri1_name = (LPWSTR)strBOINCMasterAccountUsername.c_str(); ui.usri1_password = (LPWSTR)strBOINCMasterAccountPassword.c_str(); ui.usri1_comment = _T("Account used to execute BOINC as a system service"); ui.usri1_priv = USER_PRIV_USER; ui.usri1_home_dir = NULL; ui.usri1_comment = NULL; ui.usri1_flags = UF_SCRIPT | UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD; ui.usri1_script_path = NULL; nasReturnValue = NetUserAdd( NULL, 1, (LPBYTE)&ui, &dwParameterError ); if (NERR_Success != nasReturnValue) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, nasReturnValue, _T("NetUserAdd retval") ); LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, dwParameterError, _T("NetUserAdd dwParameterError") ); LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, nasReturnValue, _T("Failed to create the 'boinc_master' account.") ); return ERROR_INSTALL_FAILURE; } bBOINCMasterAccountCreated = TRUE; } if(pSid != NULL) { HeapFree(GetProcessHeap(), 0, pSid); pSid = NULL; } bBOINCMasterAccountModified = TRUE; } // Only create a new account or change the password on an existing account // if the user hasn't explicitly defined an account if (strBOINCProjectAccountUsername.empty() && strBOINCProjectAccountPassword.empty()) bCreateBOINCProjectAccount = true; if (strBOINCProjectAccountUsername == _T("boinc_project")) bCreateBOINCProjectAccount = true; if (strProductType == tstring(_T("2")) && (strBOINCProjectAccountUsername == (tstring(_T("boinc_project_")) + strComputerName))) bCreateBOINCProjectAccount = true; if (bCreateBOINCProjectAccount) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("Using automatic account creation and management of 'boinc_project' account") ); // Determine what the real values of the usernames should be based off // of the inputs // if (strBOINCProjectAccountUsername.empty()) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("Generating 'boinc_project' account name") ); if (strProductType == tstring(_T("2"))) { // Domain Controller strBOINCProjectAccountUsername = _T("boinc_project_") + strComputerName; } else { strBOINCProjectAccountUsername = _T("boinc_project"); } } // Generate random passwords if needed // if (strBOINCProjectAccountPassword.empty()) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("Generating 'boinc_project' password") ); GenerateRandomPassword(strBOINCProjectAccountPassword, 12); strBOINCProjectAccountPassword = _T("!") + strBOINCProjectAccountPassword; } // Create the 'boinc_project' account if needed, otherwise just update the password. // if(GetAccountSid(NULL, strBOINCProjectAccountUsername.c_str(), &pSid)) { // Check if user exists LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("Resetting 'boinc_project' password") ); // Account already exists, just change the password // USER_INFO_1003 ui; DWORD dwParameterError; ui.usri1003_password = (LPWSTR)strBOINCProjectAccountPassword.c_str(); nasReturnValue = NetUserSetInfo( NULL, strBOINCProjectAccountUsername.c_str(), 1003, (LPBYTE)&ui, &dwParameterError ); if (NERR_Success != nasReturnValue) { LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, nasReturnValue, _T("Failed to reset password on the 'boinc_project' account.") ); return ERROR_INSTALL_FAILURE; } } else { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, NULL, _T("Creating 'boinc_project' account") ); // Account does not exist, create it // USER_INFO_1 ui; DWORD dwParameterError; ui.usri1_name = (LPWSTR)strBOINCProjectAccountUsername.c_str(); ui.usri1_password = (LPWSTR)strBOINCProjectAccountPassword.c_str(); ui.usri1_comment = _T("Account used to execute BOINC applications"); ui.usri1_priv = USER_PRIV_USER; ui.usri1_home_dir = NULL; ui.usri1_comment = NULL; ui.usri1_flags = UF_SCRIPT | UF_PASSWD_CANT_CHANGE | UF_DONT_EXPIRE_PASSWD; ui.usri1_script_path = NULL; nasReturnValue = NetUserAdd( NULL, 1, (LPBYTE)&ui, &dwParameterError ); if (NERR_Success != nasReturnValue) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, nasReturnValue, _T("NetUserAdd retval") ); LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, dwParameterError, _T("NetUserAdd dwParameterError") ); LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, nasReturnValue, _T("Failed to create the 'boinc_project' account.") ); return ERROR_INSTALL_FAILURE; } bBOINCProjectAccountCreated = TRUE; } if(pSid != NULL) { HeapFree(GetProcessHeap(), 0, pSid); pSid = NULL; } bBOINCProjectAccountModified = TRUE; } SetProperty( _T("BOINC_MASTER_USERNAME"), strBOINCMasterAccountUsername ); if (bBOINCMasterAccountModified) { SetProperty( _T("BOINC_MASTER_ISUSERNAME"), tstring(_T(".\\") + strBOINCMasterAccountUsername) ); } else { SetProperty( _T("BOINC_MASTER_ISUSERNAME"), strBOINCMasterAccountUsername ); } SetProperty( _T("BOINC_MASTER_PASSWORD"), strBOINCMasterAccountPassword, false ); SetProperty( _T("BOINC_PROJECT_USERNAME"), strBOINCProjectAccountUsername ); if (bBOINCProjectAccountModified) { SetProperty( _T("BOINC_PROJECT_ISUSERNAME"), tstring(_T(".\\") + strBOINCProjectAccountUsername) ); } else { SetProperty( _T("BOINC_PROJECT_ISUSERNAME"), strBOINCProjectAccountUsername ); } SetProperty( _T("BOINC_PROJECT_PASSWORD"), strBOINCProjectAccountPassword, false ); if (bBOINCMasterAccountCreated || bBOINCProjectAccountCreated) { RebootWhenFinished(); } return ERROR_SUCCESS; }
///////////////////////////////////////////////////////////////////// // // Function: // // Description: // ///////////////////////////////////////////////////////////////////// UINT CACreateBOINCGroups::OnExecution() { NET_API_STATUS nasReturnValue; DWORD dwParameterError; UINT uiReturnValue = -1; BOOL bBOINCAdminsCreated = FALSE; BOOL bBOINCUsersCreated = FALSE; BOOL bBOINCProjectsCreated = FALSE; tstring strUserSID; tstring strUsersGroupName; tstring strBOINCMasterAccountUsername; tstring strBOINCProjectAccountUsername; tstring strEnableProtectedApplicationExecution; PSID pAdminSID = NULL; PSID pInstallingUserSID = NULL; PSID pBOINCMasterSID = NULL; PSID pBOINCProjectSID = NULL; SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY; uiReturnValue = GetProperty( _T("UserSID"), strUserSID ); if ( uiReturnValue ) return uiReturnValue; uiReturnValue = GetProperty( _T("GROUPALIAS_USERS"), strUsersGroupName ); if ( uiReturnValue ) return uiReturnValue; uiReturnValue = GetProperty( _T("BOINC_MASTER_USERNAME"), strBOINCMasterAccountUsername ); if ( uiReturnValue ) return uiReturnValue; uiReturnValue = GetProperty( _T("BOINC_PROJECT_USERNAME"), strBOINCProjectAccountUsername ); if ( uiReturnValue ) return uiReturnValue; uiReturnValue = GetProperty( _T("ENABLEPROTECTEDAPPLICATIONEXECUTION2"), strEnableProtectedApplicationExecution ); if ( uiReturnValue ) return uiReturnValue; // Create a SID for the BUILTIN\Administrators group. if(!AllocateAndInitializeSid( &SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdminSID)) { LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, GetLastError(), _T("AllocateAndInitializeSid Error for BUILTIN\\Administrators") ); return ERROR_INSTALL_FAILURE; } // Create a SID for the current logged in user. if(!ConvertStringSidToSid(strUserSID.c_str(), &pInstallingUserSID)) { LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, GetLastError(), _T("ConvertStringSidToSid Error for installing user") ); return ERROR_INSTALL_FAILURE; } // Create a SID for the 'boinc_master' user account. if (_T("1") == strEnableProtectedApplicationExecution) { if(!GetAccountSid(NULL, strBOINCMasterAccountUsername.c_str(), &pBOINCMasterSID)) { LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, GetLastError(), _T("GetAccountSid Error for 'boinc_master' user account") ); return ERROR_INSTALL_FAILURE; } } // Create a SID for the 'boinc_project' user account. if (_T("1") == strEnableProtectedApplicationExecution) { if(!GetAccountSid(NULL, strBOINCProjectAccountUsername.c_str(), &pBOINCProjectSID)) { LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, GetLastError(), _T("GetAccountSid Error for 'boinc_master' user account") ); return ERROR_INSTALL_FAILURE; } } // Create the 'boinc_admins' group if needed // LOCALGROUP_INFO_1 lgrpiAdmins; lgrpiAdmins.lgrpi1_name = _T("boinc_admins"); lgrpiAdmins.lgrpi1_comment = _T("Accounts in this group can control the BOINC client."); nasReturnValue = NetLocalGroupAdd( NULL, 1, (LPBYTE)&lgrpiAdmins, &dwParameterError ); if ((NERR_Success != nasReturnValue) && (ERROR_ALIAS_EXISTS != nasReturnValue)) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, nasReturnValue, _T("NetLocalGroupAdd retval") ); LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, nasReturnValue, _T("Failed to create the 'boinc_admins' group.") ); return ERROR_INSTALL_FAILURE; } if (NERR_Success == nasReturnValue) { bBOINCAdminsCreated = TRUE; } // If we just created the 'boinc_admins' local group then we need to populate // it with the default accounts. LOCALGROUP_MEMBERS_INFO_0 lgrmiAdmins; lgrmiAdmins.lgrmi0_sid = pAdminSID; nasReturnValue = NetLocalGroupAddMembers( NULL, _T("boinc_admins"), 0, (LPBYTE)&lgrmiAdmins, 1 ); if ((NERR_Success != nasReturnValue) && (ERROR_MEMBER_IN_ALIAS != nasReturnValue)) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, nasReturnValue, _T("NetLocalGroupAddMembers retval") ); LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, nasReturnValue, _T("Failed to add user to the 'boinc_admins' group (Administrator).") ); return ERROR_INSTALL_FAILURE; } lgrmiAdmins.lgrmi0_sid = pInstallingUserSID; nasReturnValue = NetLocalGroupAddMembers( NULL, _T("boinc_admins"), 0, (LPBYTE)&lgrmiAdmins, 1 ); if ((NERR_Success != nasReturnValue) && (ERROR_MEMBER_IN_ALIAS != nasReturnValue)) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, nasReturnValue, _T("NetLocalGroupAddMembers retval") ); LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, nasReturnValue, _T("Failed to add user to the 'boinc_admins' group (Installing User).") ); return ERROR_INSTALL_FAILURE; } if (_T("1") == strEnableProtectedApplicationExecution) { lgrmiAdmins.lgrmi0_sid = pBOINCMasterSID; nasReturnValue = NetLocalGroupAddMembers( NULL, _T("boinc_admins"), 0, (LPBYTE)&lgrmiAdmins, 1 ); if ((NERR_Success != nasReturnValue) && (ERROR_MEMBER_IN_ALIAS != nasReturnValue)) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, nasReturnValue, _T("NetLocalGroupAddMembers retval") ); LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, nasReturnValue, _T("Failed to add user to the 'boinc_admins' group (BOINC Master).") ); return ERROR_INSTALL_FAILURE; } } // Create the 'boinc_users' group if needed // LOCALGROUP_INFO_1 lgrpiUsers; lgrpiUsers.lgrpi1_name = _T("boinc_users"); lgrpiUsers.lgrpi1_comment = _T("Accounts in this group can monitor the BOINC client."); nasReturnValue = NetLocalGroupAdd( NULL, 1, (LPBYTE)&lgrpiUsers, &dwParameterError ); if ((NERR_Success != nasReturnValue) && (ERROR_ALIAS_EXISTS != nasReturnValue)) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, nasReturnValue, _T("NetLocalGroupAdd retval") ); LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, nasReturnValue, _T("Failed to create the 'boinc_users' group.") ); return ERROR_INSTALL_FAILURE; } if (NERR_Success == nasReturnValue) { bBOINCUsersCreated = TRUE; } // Create the 'boinc_project' group if needed // LOCALGROUP_INFO_1 lgrpiProjects; lgrpiProjects.lgrpi1_name = _T("boinc_projects"); lgrpiProjects.lgrpi1_comment = _T("Accounts in this group are used to execute boinc applications."); nasReturnValue = NetLocalGroupAdd( NULL, 1, (LPBYTE)&lgrpiProjects, &dwParameterError ); if ((NERR_Success != nasReturnValue) && (ERROR_ALIAS_EXISTS != nasReturnValue)) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, nasReturnValue, _T("NetLocalGroupAdd retval") ); LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, nasReturnValue, _T("Failed to create the 'boinc_projects' group.") ); return ERROR_INSTALL_FAILURE; } if (NERR_Success == nasReturnValue) { bBOINCProjectsCreated = TRUE; } // If the user has enabled protected application execution then we need to add the 'boinc_project' // account to the local group and the 'Users' local group. As an aside 'boinc_master' is also added // to the 'Users' group. if (_T("1") == strEnableProtectedApplicationExecution) { LOCALGROUP_MEMBERS_INFO_0 lgrmiMembers; lgrmiMembers.lgrmi0_sid = pBOINCProjectSID; nasReturnValue = NetLocalGroupAddMembers( NULL, _T("boinc_projects"), 0, (LPBYTE)&lgrmiMembers, 1 ); if ((NERR_Success != nasReturnValue) && (ERROR_MEMBER_IN_ALIAS != nasReturnValue)) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, nasReturnValue, _T("NetLocalGroupAddMembers retval") ); LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, nasReturnValue, _T("Failed to add user to the 'boinc_projects' group (boinc_project).") ); return ERROR_INSTALL_FAILURE; } nasReturnValue = NetLocalGroupAddMembers( NULL, strUsersGroupName.c_str(), 0, (LPBYTE)&lgrmiMembers, 1 ); if ((NERR_Success != nasReturnValue) && (ERROR_MEMBER_IN_ALIAS != nasReturnValue)) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, nasReturnValue, _T("NetLocalGroupAddMembers retval") ); LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, nasReturnValue, _T("Failed to add user to the 'Users' group (boinc_project).") ); return ERROR_INSTALL_FAILURE; } lgrmiMembers.lgrmi0_sid = pBOINCMasterSID; nasReturnValue = NetLocalGroupAddMembers( NULL, strUsersGroupName.c_str(), 0, (LPBYTE)&lgrmiMembers, 1 ); if ((NERR_Success != nasReturnValue) && (ERROR_MEMBER_IN_ALIAS != nasReturnValue)) { LogMessage( INSTALLMESSAGE_INFO, NULL, NULL, NULL, nasReturnValue, _T("NetLocalGroupAddMembers retval") ); LogMessage( INSTALLMESSAGE_ERROR, NULL, NULL, NULL, nasReturnValue, _T("Failed to add user to the 'Users' group (boinc_master).") ); return ERROR_INSTALL_FAILURE; } } SetProperty( _T("BOINC_ADMINS_GROUPNAME"), _T("boinc_admins") ); SetProperty( _T("BOINC_USERS_GROUPNAME"), _T("boinc_users") ); SetProperty( _T("BOINC_PROJECTS_GROUPNAME"), _T("boinc_projects") ); if (bBOINCAdminsCreated || bBOINCUsersCreated || bBOINCProjectsCreated) { RebootWhenFinished(); } if(pAdminSID != NULL) FreeSid(pAdminSID); if(pInstallingUserSID != NULL) FreeSid(pInstallingUserSID); if(pBOINCMasterSID != NULL) FreeSid(pBOINCMasterSID); if(pBOINCProjectSID != NULL) FreeSid(pBOINCProjectSID); return ERROR_SUCCESS; }
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; }