// Creates a spn if the user hasn't specified one. void MakeSpn(unsigned char **pszSpn) { DWORD status = ERROR_SUCCESS; ULONG ulSpn = 1; unsigned char ** arrSpn = NULL; HANDLE hDS; PDOMAIN_CONTROLLER_INFO pDomainControllerInfo; char lpCompDN[128]; ULONG ulCompDNSize = sizeof(lpCompDN); BOOL NoFailure = TRUE; status = DsGetSpn(DS_SPN_NB_HOST, "dynept", NULL, // DN of this service. 0, // Use the default instance port. 0, // Number of additional instance names. NULL, // No additional instance names. NULL, // No additional instance ports. &ulSpn, // Size of SPN array. &arrSpn); // Returned SPN(s). printf_s("DsGetSpn returned 0x%x\n", status); if (status != ERROR_SUCCESS) { exit(status); } // Get the name of domain if it is domain-joined if (status = DsGetDcName(NULL, NULL, NULL, NULL, DS_RETURN_DNS_NAME, &pDomainControllerInfo) != NO_ERROR) { printf_s("DsGetDcName returned %d\n", GetLastError()); NoFailure = FALSE; } // if it is domain joined if (NoFailure) { // Bind to the domain controller for our domain if ((status = DsBind(NULL, pDomainControllerInfo->DomainName, &hDS)) != ERROR_SUCCESS) { printf_s("DsBind returned %d\n", GetLastError()); NoFailure = FALSE; } } if (NoFailure) { if ((status = NetApiBufferFree(pDomainControllerInfo)) != NERR_Success) { printf_s("NetApiBufferFree returned %d\n", status); exit(status); } if (GetComputerObjectName(NameFullyQualifiedDN, lpCompDN, &ulCompDNSize) == 0) { printf_s("GetComputerObjectName returned %d\n", GetLastError()); exit(status); } /* We could check whether the SPN is already registered for this computer's DN, but we don't have to. Modification is performed permissiely by this function, so that adding a value that already exists does not return an error. This way we can opt for the internal check instead of doing it ourselves. */ status = DsWriteAccountSpn(hDS, DS_SPN_ADD_SPN_OP, lpCompDN, ulSpn, arrSpn); if (status != NO_ERROR) { printf_s("DsWriteAccountSpn returned %d\n", status); exit(status); } DsUnBind(&hDS); } *pszSpn = *arrSpn; }
int smpd_register_spn(const char *dc, const char *dn, const char *dh) { DWORD len; char err_msg[256]; LPSTR *spns; HANDLE ds; DWORD result; char domain_controller[SMPD_MAX_HOST_LENGTH] = ""; char domain_name[SMPD_MAX_HOST_LENGTH] = ""; char domain_host[SMPD_MAX_HOST_LENGTH] = ""; char host[SMPD_MAX_HOST_LENGTH] = ""; int really = 0; char *really_env; PDOMAIN_CONTROLLER_INFO pInfo; result = DsGetDcName(NULL/*local computer*/, NULL, NULL, NULL, /*DS_IS_FLAT_NAME | DS_RETURN_DNS_NAME | DS_DIRECTORY_SERVICE_REQUIRED, */ DS_DIRECTORY_SERVICE_REQUIRED | DS_KDC_REQUIRED, &pInfo); if (result == ERROR_SUCCESS) { strcpy(domain_controller, pInfo->DomainControllerName); strcpy(domain_name, pInfo->DomainName); NetApiBufferFree(pInfo); } if (dc && *dc != '\0') { strcpy(domain_controller, dc); } if (dn && *dn != '\0') { strcpy(domain_name, dn); } if (dh && *dh != '\0') { strcpy(domain_host, dh); } if (domain_host[0] == '\0') { smpd_get_hostname(host, SMPD_MAX_HOST_LENGTH); if (domain_name[0] != '\0') { sprintf(domain_host, "%s\\%s", domain_name, host); } else { strcpy(domain_host, host); } } printf("DsBind(%s, %s, ...)\n", domain_controller[0] == '\0' ? NULL : domain_controller, domain_name[0] == '\0' ? NULL : domain_name); result = DsBind( domain_controller[0] == '\0' ? NULL : domain_controller, domain_name[0] == '\0' ? NULL : domain_name, &ds); if (result != ERROR_SUCCESS) { smpd_translate_win_error(result, err_msg, 256, NULL); smpd_err_printf("DsBind failed: %s\n", err_msg); return SMPD_FAIL; } really_env = getenv("really"); if (really_env) really = 1; #if 1 len = 1; /*result = DsGetSpn(DS_SPN_SERVICE, SMPD_SERVICE_NAME, SMPD_SERVICE_NAME, 0, 0, NULL, NULL, &len, &spns);*/ result = DsGetSpn(DS_SPN_DNS_HOST, SMPD_SERVICE_NAME, NULL, SMPD_LISTENER_PORT, 0, NULL, NULL, &len, &spns); if (result != ERROR_SUCCESS) { smpd_translate_win_error(result, err_msg, 256, NULL); smpd_err_printf("DsGetSpn failed: %s\n", err_msg); return SMPD_FAIL; } if (really) { printf("registering: %s\n", spns[0]); len = SMPD_MAX_HOST_LENGTH; GetComputerObjectName(NameFullyQualifiedDN, domain_host, &len); printf("on account: %s\n", domain_host); result = DsWriteAccountSpn(ds, DS_SPN_ADD_SPN_OP, domain_host, 1, (LPCSTR*)spns); if (result != ERROR_SUCCESS) { DsFreeSpnArray(1, spns); smpd_translate_win_error(result, err_msg, 256, NULL); smpd_err_printf("DsWriteAccountSpn failed: %s\n", err_msg); return SMPD_FAIL; } } else { printf("would register '%s' on %s\n", spns[0], domain_host); } DsFreeSpnArray(1, spns); #else if (really) { result = DsServerRegisterSpn(DS_SPN_ADD_SPN_OP, SMPD_SERVICE_NAME, domain_host); if (result != ERROR_SUCCESS) { smpd_translate_win_error(result, err_msg, 256, NULL); smpd_err_printf("DsServerRegisterSpn failed: %s\n", err_msg); return SMPD_FAIL; } } else { printf("would register '%s' on %s\n", SMPD_SERVICE_NAME, domain_host); } #endif result = DsUnBind(&ds); return SMPD_SUCCESS; }