Exemple #1
0
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;
}
Exemple #3
0
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;
}
Exemple #9
0
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;
}