INT cmdUser( INT argc, WCHAR **argv) { INT i, j; INT result = 0; BOOL bAdd = FALSE; BOOL bDelete = FALSE; #if 0 BOOL bDomain = FALSE; #endif BOOL bRandomPassword = FALSE; LPWSTR lpUserName = NULL; LPWSTR lpPassword = NULL; PUSER_INFO_4 pUserInfo = NULL; USER_INFO_4 UserInfo; LPWSTR pWorkstations = NULL; LPWSTR p; LPWSTR endptr; DWORD value; BOOL bPasswordAllocated = FALSE; NET_API_STATUS Status; i = 2; if ((i < argc) && (argv[i][0] != L'/')) { lpUserName = argv[i]; // ConPrintf(StdOut, L"User: %s\n", lpUserName); i++; } if ((i < argc) && (argv[i][0] != L'/')) { lpPassword = argv[i]; // ConPrintf(StdOut, L"Password: %s\n", lpPassword); i++; } for (j = i; j < argc; j++) { if (_wcsicmp(argv[j], L"/help") == 0) { PrintNetMessage(MSG_USER_HELP); return 0; } else if (_wcsicmp(argv[j], L"/add") == 0) { bAdd = TRUE; } else if (_wcsicmp(argv[j], L"/delete") == 0) { bDelete = TRUE; } else if (_wcsicmp(argv[j], L"/domain") == 0) { ConPuts(StdErr, L"The /DOMAIN option is not supported yet.\n"); #if 0 bDomain = TRUE; #endif } else if (_wcsicmp(argv[j], L"/random") == 0) { bRandomPassword = TRUE; GenerateRandomPassword(&lpPassword, &bPasswordAllocated); } } if (lpUserName == NULL && lpPassword == NULL) { Status = EnumerateUsers(); ConPrintf(StdOut, L"Status: %lu\n", Status); return 0; } else if (lpUserName != NULL && lpPassword == NULL) { Status = DisplayUser(lpUserName); ConPrintf(StdOut, L"Status: %lu\n", Status); return 0; } if (bAdd && bDelete) { result = 1; goto done; } /* Interactive password input */ if (lpPassword != NULL && wcscmp(lpPassword, L"*") == 0) { ReadPassword(&lpPassword, &bPasswordAllocated); } if (!bAdd && !bDelete) { /* Modify the user */ Status = NetUserGetInfo(NULL, lpUserName, 4, (LPBYTE*)&pUserInfo); if (Status != NERR_Success) { ConPrintf(StdOut, L"Status: %lu\n", Status); result = 1; goto done; } } else if (bAdd && !bDelete) { /* Add the user */ ZeroMemory(&UserInfo, sizeof(USER_INFO_4)); UserInfo.usri4_name = lpUserName; UserInfo.usri4_password = lpPassword; UserInfo.usri4_flags = UF_SCRIPT | UF_NORMAL_ACCOUNT; UserInfo.usri4_acct_expires = TIMEQ_FOREVER; UserInfo.usri4_primary_group_id = DOMAIN_GROUP_RID_USERS; pUserInfo = &UserInfo; } for (j = i; j < argc; j++) { if (_wcsnicmp(argv[j], L"/active:", 8) == 0) { p = &argv[i][8]; if (_wcsicmp(p, L"yes") == 0) { pUserInfo->usri4_flags &= ~UF_ACCOUNTDISABLE; } else if (_wcsicmp(p, L"no") == 0) { pUserInfo->usri4_flags |= UF_ACCOUNTDISABLE; } else { PrintMessageStringV(3952, L"/ACTIVE"); result = 1; goto done; } } else if (_wcsnicmp(argv[j], L"/comment:", 9) == 0) { pUserInfo->usri4_comment = &argv[j][9]; } else if (_wcsnicmp(argv[j], L"/countrycode:", 13) == 0) { p = &argv[i][13]; value = wcstoul(p, &endptr, 10); if (*endptr != 0) { PrintMessageStringV(3952, L"/COUNTRYCODE"); result = 1; goto done; } /* Verify the country code */ if (GetCountryFromCountryCode(value, 0, NULL)) pUserInfo->usri4_country_code = value; } else if (_wcsnicmp(argv[j], L"/expires:", 9) == 0) { p = &argv[i][9]; if (_wcsicmp(p, L"never") == 0) { pUserInfo->usri4_acct_expires = TIMEQ_FOREVER; } else if (!ParseDate(p, &pUserInfo->usri4_acct_expires)) { PrintMessageStringV(3952, L"/EXPIRES"); result = 1; goto done; } } else if (_wcsnicmp(argv[j], L"/fullname:", 10) == 0) { pUserInfo->usri4_full_name = &argv[j][10]; } else if (_wcsnicmp(argv[j], L"/homedir:", 9) == 0) { pUserInfo->usri4_home_dir = &argv[j][9]; } else if (_wcsnicmp(argv[j], L"/passwordchg:", 13) == 0) { p = &argv[i][13]; if (_wcsicmp(p, L"yes") == 0) { pUserInfo->usri4_flags &= ~UF_PASSWD_CANT_CHANGE; } else if (_wcsicmp(p, L"no") == 0) { pUserInfo->usri4_flags |= UF_PASSWD_CANT_CHANGE; } else { PrintMessageStringV(3952, L"/PASSWORDCHG"); result = 1; goto done; } } else if (_wcsnicmp(argv[j], L"/passwordreq:", 13) == 0) { p = &argv[i][13]; if (_wcsicmp(p, L"yes") == 0) { pUserInfo->usri4_flags &= ~UF_PASSWD_NOTREQD; } else if (_wcsicmp(p, L"no") == 0) { pUserInfo->usri4_flags |= UF_PASSWD_NOTREQD; } else { PrintMessageStringV(3952, L"/PASSWORDREQ"); result = 1; goto done; } } else if (_wcsnicmp(argv[j], L"/profilepath:", 13) == 0) { pUserInfo->usri4_profile = &argv[j][13]; } else if (_wcsnicmp(argv[j], L"/scriptpath:", 12) == 0) { pUserInfo->usri4_script_path = &argv[j][12]; } else if (_wcsnicmp(argv[j], L"/times:", 7) == 0) { /* FIXME */ ConPuts(StdErr, L"The /TIMES option is not supported yet.\n"); } else if (_wcsnicmp(argv[j], L"/usercomment:", 13) == 0) { pUserInfo->usri4_usr_comment = &argv[j][13]; } else if (_wcsnicmp(argv[j], L"/workstations:", 14) == 0) { p = &argv[i][14]; if (wcscmp(p, L"*") == 0 || wcscmp(p, L"") == 0) { pUserInfo->usri4_workstations = NULL; } else { Status = BuildWorkstationsList(&pWorkstations, p); if (Status == NERR_Success) { pUserInfo->usri4_workstations = pWorkstations; } else { ConPrintf(StdOut, L"Status %lu\n\n", Status); result = 1; goto done; } } } } if (!bAdd && !bDelete) { /* Modify the user */ Status = NetUserSetInfo(NULL, lpUserName, 4, (LPBYTE)pUserInfo, NULL); ConPrintf(StdOut, L"Status: %lu\n", Status); } else if (bAdd && !bDelete) { /* Add the user */ Status = NetUserAdd(NULL, 4, (LPBYTE)pUserInfo, NULL); ConPrintf(StdOut, L"Status: %lu\n", Status); } else if (!bAdd && bDelete) { /* Delete the user */ Status = NetUserDel(NULL, lpUserName); ConPrintf(StdOut, L"Status: %lu\n", Status); } if (Status == NERR_Success && lpPassword != NULL && bRandomPassword == TRUE) { PrintMessageStringV(3968, lpUserName, lpPassword); } done: if (pWorkstations != NULL) HeapFree(GetProcessHeap(), 0, pWorkstations); if ((bPasswordAllocated == TRUE) && (lpPassword != NULL)) HeapFree(GetProcessHeap(), 0, lpPassword); if (!bAdd && !bDelete && pUserInfo != NULL) NetApiBufferFree(pUserInfo); if (result != 0) { PrintMessageString(4381); ConPuts(StdOut, L"\n"); PrintNetMessage(MSG_USER_SYNTAX); } return result; }
///////////////////////////////////////////////////////////////////// // // 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; }