Registrando os SPNs para um serviço
O exemplo de código a seguir registra ou cancela o registro de um ou mais SPNs (nomes de entidade de serviço) para uma instância de serviço.
O exemplo chama a função DsWriteAccountSpn, que armazena os SPNs nos Serviços de Domínio Active Directory sob o atributo servicePrincipalName do objeto de conta especificado pelo parâmetro pszServiceAcctDN. O objeto de conta corresponde à conta de logon especificada na chamada CreateService para esta instância de serviço. Se a conta de logon for uma conta de usuário de domínio, pszServiceAcctDN deverá ser o nome distinto do objeto de conta nos Servidores de Domínio Active Directory para essa conta de usuário. Se a conta de logon do serviço for a conta LocalSystem, pszServiceAcctDN deverá ser o nome distinto do objeto de conta de computador do computador host no qual o serviço está instalado.
/***************************************************************************
SpnRegister()
Register or unregister the SPNs under the service's account.
If the service runs in LocalSystem account, pszServiceAcctDN is the
distinguished name of the local computer account.
Parameters:
pszServiceAcctDN - Contains the distinguished name of the logon
account for this instance of the service.
pspn - Contains an array of SPNs to register.
ulSpn - Contains the number of SPNs in the array.
Operation - Contains one of the DS_SPN_WRITE_OP values that determines
the type of operation to perform on the SPNs.
***************************************************************************/
DWORD SpnRegister(TCHAR *pszServiceAcctDN,
TCHAR **pspn,
unsigned long ulSpn,
DS_SPN_WRITE_OP Operation)
{
DWORD dwStatus;
HANDLE hDs;
TCHAR szSamName[512];
DWORD dwSize = sizeof(szSamName) / sizeof(szSamName[0]);
PDOMAIN_CONTROLLER_INFO pDcInfo;
// Bind to a domain controller.
// Get the domain for the current user.
if(GetUserNameEx(NameSamCompatible, szSamName, &dwSize))
{
TCHAR *pWhack = _tcschr(szSamName, '\\');
if(pWhack)
{
*pWhack = '\0';
}
}
else
{
return GetLastError();
}
// Get the name of a domain controller in that domain.
dwStatus = DsGetDcName(NULL,
szSamName,
NULL,
NULL,
DS_IS_FLAT_NAME |
DS_RETURN_DNS_NAME |
DS_DIRECTORY_SERVICE_REQUIRED,
&pDcInfo);
if(dwStatus != 0)
{
return dwStatus;
}
// Bind to the domain controller.
dwStatus = DsBind(pDcInfo->DomainControllerName, NULL, &hDs);
// Free the DOMAIN_CONTROLLER_INFO buffer.
NetApiBufferFree(pDcInfo);
if(dwStatus != 0)
{
return dwStatus;
}
// Write the SPNs to the service account or computer account.
dwStatus = DsWriteAccountSpn(
hDs, // Handle to the directory.
Operation, // Add or remove SPN from account's existing SPNs.
pszServiceAcctDN, // DN of service account or computer account.
ulSpn, // Number of SPNs to add.
(const TCHAR **)pspn); // Array of SPNs.
// Unbind the DS in any case.
DsUnBind(&hDs);
return dwStatus;
}