DWORD mlsvc_netlogon(char *server, char *domain) { mlsvc_handle_t netr_handle; DWORD status; status = netr_open(server, domain, &netr_handle); if (status != 0) { syslog(LOG_NOTICE, "Failed to connect to %s " "for domain %s (%s)", server, domain, xlate_nt_status(status)); return (status); } status = netlogon_auth(server, &netr_handle, NETR_FLG_INIT); if (status != NT_STATUS_SUCCESS) { syslog(LOG_NOTICE, "Failed to establish NETLOGON " "credential chain with DC: %s (%s)", server, xlate_nt_status(status)); syslog(LOG_NOTICE, "The machine account information on the " "domain controller does not match the local storage."); syslog(LOG_NOTICE, "To correct this, use 'smbadm join'"); } (void) netr_close(&netr_handle); return (status); }
static uint32_t netlogon_logon(smb_logon_t *user_info, smb_token_t *token) { char resource_domain[SMB_PI_MAX_DOMAIN]; char server[NETBIOS_NAME_SZ * 2]; mlsvc_handle_t netr_handle; smb_domainex_t di; uint32_t status; int retries = 0; (void) smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN); /* Avoid interfering with DC discovery. */ if (smb_ddiscover_wait() != 0 || !smb_domain_getinfo(&di)) { netr_invalidate_chain(); return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); } do { if (netr_open(di.d_dc, di.d_primary.di_nbname, &netr_handle) != 0) return (NT_STATUS_OPEN_FAILED); if (di.d_dc && (*netr_global_info.server != '\0')) { (void) snprintf(server, sizeof (server), "\\\\%s", di.d_dc); if (strncasecmp(netr_global_info.server, server, strlen(server)) != 0) netr_invalidate_chain(); } if ((netr_global_info.flags & NETR_FLG_VALID) == 0 || !smb_match_netlogon_seqnum()) { status = netlogon_auth(di.d_dc, &netr_handle, NETR_FLG_NULL); if (status != 0) { (void) netr_close(&netr_handle); return (NT_STATUS_LOGON_FAILURE); } netr_global_info.flags |= NETR_FLG_VALID; } status = netr_server_samlogon(&netr_handle, &netr_global_info, di.d_dc, user_info, token); (void) netr_close(&netr_handle); } while (status == NT_STATUS_INSUFFICIENT_LOGON_INFO && retries++ < 3); if (retries >= 3) status = NT_STATUS_LOGON_FAILURE; return (status); }