變更服務用戶帳戶上的密碼
如果是使用使用者帳戶登入的服務實例,而不是 LocalSystem 帳戶,主電腦上的服務控制管理員 (SCM) 會儲存帳戶密碼,以在服務啟動時用來登入服務。 如同任何用戶帳戶,您必須定期變更密碼,以維護安全性。 當您變更服務帳戶的密碼時,請更新 SCM 所儲存的密碼。 下列程式代碼範例示範如何執行這兩個動作。
程式代碼範例會使用 IADsUser.SetPassword 來設定帳戶密碼。 這個方法會使用帳戶的辨別名稱。 然後,此範例會開啟指定主計算機上的已安裝服務的句柄,並使用 ChangeServiceConfig 函式來更新 SCM 快取的密碼。 此函式會使用帳戶的 SAM 名稱 (“<domain>\<username>”) 。
注意
此程式代碼必須由網域管理員執行。
對於每個復本使用不同的登入帳戶的可複製服務,您可以列舉服務實例來更新所有複本的密碼。 如需詳細資訊和程式代碼範例,請參閱 列舉服務的複本。
DWORD UpdateAccountPassword(
LPTSTR szServerDNS, // DNS name of host computer
LPTSTR szAccountDN, // Distinguished name of service
// logon account
LPTSTR szServiceName, // Name of the service
LPTSTR szOldPassword, // Old password
LPTSTR szNewPassword // New password
)
{
SC_HANDLE schService = NULL;
SC_HANDLE schSCManager = NULL;
DWORD dwLen = MAX_PATH;
TCHAR szAccountPath[MAX_PATH];
IADsUser *pUser = NULL;
HRESULT hr;
DWORD dwStatus = 0;
SC_LOCK sclLock = NULL;
if( !szServerDNS ||
!szAccountDN ||
!szServiceName ||
!szOldPassword ||
!szNewPassword)
{
_tprintf(TEXT("Invalid parameter"));
goto cleanup;
}
// Set the password on the account.
// Use the distinguished name to bind to the account object.
_tcsncpy_s(szAccountPath, TEXT("LDAP://"), MAX_PATH);
_tcscat_s(szAccountPath,
MAX_PATH,
szAccountDN);
hr = CoInitialize(NULL);
if (FAILED(hr))
{
_tprintf(TEXT("Initializing COM failed - 0x%x\n"), dwStatus = hr);
goto cleanup;
}
hr = ADsGetObject(szAccountPath, IID_IADsUser, (void**)&pUser);
if (FAILED(hr))
{
_tprintf(TEXT("Get IADsUser failed - 0x%x\n"), dwStatus = hr);
goto cleanup;
}
// Set the password on the account.
hr = pUser->ChangePassword(CComBSTR(szOldPassword),
CComBSTR(szNewPassword));
if (FAILED(hr))
{
_tprintf(TEXT("ChangePassword failed - 0x%x\n"),
dwStatus = hr);
goto cleanup;
}
// Update the account and password in the SCM database.
// Open the Service Control Manager on the specified computer.
schSCManager = OpenSCManager(
szServerDNS, // DNS name of host computer
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if (! schSCManager)
{
_tprintf(TEXT("OpenSCManager failed - %d\n"),
dwStatus = GetLastError());
goto cleanup;
}
// Open a handle to the service instance.
schService = OpenService(schSCManager,
szServiceName,
SERVICE_ALL_ACCESS);
if (! schService)
{
_tprintf(TEXT("OpenService failed - %d\n"),
dwStatus = GetLastError());
goto cleanup;
}
// Get the SCM database lock before changing the password.
sclLock = LockServiceDatabase(schSCManager);
if (sclLock == NULL) {
_tprintf(TEXT("LockServiceDatabase failed - %d\n"),
dwStatus = GetLastError());
goto cleanup;
}
// Set the account and password that the service uses at startup.
if (! ChangeServiceConfig(
schService, // Handle of service
SERVICE_NO_CHANGE, // Service type: no change
SERVICE_NO_CHANGE, // Change service start type
SERVICE_NO_CHANGE, // Error control: no change
NULL, // Binary path: no change
NULL, // Load order group: no change
NULL, // Tag ID: no change
NULL, // Dependencies: no change
NULL, // Account name: no change
szNewPassword, // New password
NULL) ) // Display name: no change
{
_tprintf(TEXT("ChangeServiceConfig failed - %d\n"),
dwStatus = GetLastError());
goto cleanup;
}
_tprintf(TEXT("Password changed for service instance on: %s\n"),
szServerDNS);
cleanup:
if (sclLock)
UnlockServiceDatabase(sclLock);
if (schService)
CloseServiceHandle(schService);
if (schSCManager)
CloseServiceHandle(schSCManager);
if (pUser)
pUser->Release();
return dwStatus;
}