static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, const char *domain_name, uint32_t flags, struct ip_service_name *dclist, int num_dcs, struct netr_DsRGetDCNameInfo **info) { int i = 0; bool valid_dc = false; struct netlogon_samlogon_response *r = NULL; uint32_t nt_version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX; uint32_t ret_flags = 0; NTSTATUS status; nt_version |= map_ds_flags_to_nt_version(flags); for (i=0; i<num_dcs; i++) { char addr[INET6_ADDRSTRLEN]; print_sockaddr(addr, sizeof(addr), &dclist[i].ss); DEBUG(10,("LDAP ping to %s (%s)\n", dclist[i].hostname, addr)); if (ads_cldap_netlogon(mem_ctx, &dclist[i].ss, domain_name, nt_version, &r)) { nt_version = r->ntver; ret_flags = get_cldap_reply_server_flags(r, nt_version); if (check_cldap_reply_required_flags(ret_flags, flags)) { valid_dc = true; break; } } continue; } if (!valid_dc) { return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; } status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss, &r->data.nt5_ex, info); if (NT_STATUS_IS_OK(status)) { return store_cldap_reply(mem_ctx, flags, &dclist[i].ss, nt_version, &r->data.nt5_ex); } return status; }
static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, struct messaging_context *msg_ctx, const char *domain_name, uint32_t flags, struct ip_service_name *dclist, int num_dcs, struct netr_DsRGetDCNameInfo **info) { struct sockaddr_storage ss; struct ip_service ip_list; enum nbt_name_type name_type = NBT_NAME_LOGON; NTSTATUS status; int i; const char *dc_name = NULL; fstring tmp_dc_name; struct netlogon_samlogon_response *r = NULL; bool store_cache = false; uint32_t nt_version = NETLOGON_NT_VERSION_1 | NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX_WITH_IP; if (!msg_ctx) { msg_ctx = msg_context(mem_ctx); } if (flags & DS_PDC_REQUIRED) { name_type = NBT_NAME_PDC; } nt_version |= map_ds_flags_to_nt_version(flags); DEBUG(10,("process_dc_netbios\n")); for (i=0; i<num_dcs; i++) { ip_list.ss = dclist[i].ss; ip_list.port = 0; if (!interpret_string_addr(&ss, dclist[i].hostname, AI_NUMERICHOST)) { return NT_STATUS_UNSUCCESSFUL; } if (send_getdc_request(mem_ctx, msg_ctx, &dclist[i].ss, domain_name, NULL, nt_version)) { int k; smb_msleep(300); for (k=0; k<5; k++) { if (receive_getdc_response(mem_ctx, &dclist[i].ss, domain_name, &nt_version, &dc_name, &r)) { store_cache = true; namecache_store(dc_name, NBT_NAME_SERVER, 1, &ip_list); goto make_reply; } smb_msleep(1500); } } if (name_status_find(domain_name, name_type, NBT_NAME_SERVER, &dclist[i].ss, tmp_dc_name)) { struct NETLOGON_SAM_LOGON_RESPONSE_NT40 logon1; r = TALLOC_ZERO_P(mem_ctx, struct netlogon_samlogon_response); NT_STATUS_HAVE_NO_MEMORY(r); ZERO_STRUCT(logon1); nt_version = NETLOGON_NT_VERSION_1; logon1.nt_version = nt_version; logon1.server = tmp_dc_name; logon1.domain = talloc_strdup_upper(mem_ctx, domain_name); NT_STATUS_HAVE_NO_MEMORY(logon1.domain); r->data.nt4 = logon1; r->ntver = nt_version; map_netlogon_samlogon_response(r); namecache_store(tmp_dc_name, NBT_NAME_SERVER, 1, &ip_list); goto make_reply; } } return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; make_reply: status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss, &r->data.nt5_ex, info); if (NT_STATUS_IS_OK(status) && store_cache) { return store_cldap_reply(mem_ctx, flags, &dclist[i].ss, nt_version, &r->data.nt5_ex); } return status; }