Modifica della password nell'account utente di un servizio
Per un'istanza del servizio che accede con un account utente, anziché con l'account LocalSystem, Service Control Manager (SCM) nel computer host archivia la password dell'account, che usa per accedere al servizio all'avvio del servizio. Come per qualsiasi account utente, è necessario modificare periodicamente la password per mantenere la sicurezza. Quando si modifica la password in un account del servizio, aggiornare la password archiviata da SCM. Nell'esempio di codice seguente viene illustrato come eseguire entrambe le operazioni.
Gli esempi di codice usano IADsUser.SetPassword per impostare la password dell'account. Questo metodo usa il nome distinto dell'account. L'esempio apre quindi un handle al servizio installato nel computer host specificato e usa la funzione ChangeServiceConfig per aggiornare la password memorizzata nella cache da SCM. Questa funzione usa il nome SAM ("<dominio>\<nomeutente>") dell'account.
Nota
Questo codice deve essere eseguito da un amministratore di dominio.
Per un servizio replicabile in cui ogni replica usa un account di accesso diverso, è possibile aggiornare le password per tutte le repliche enumerando le istanze del servizio. Per altre informazioni e un esempio di codice, vedere Enumerazione delle repliche di un servizio.
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;
}