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; }
static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, const char *domain_name, struct GUID *domain_guid, uint32_t flags, const char *site_name, struct netr_DsRGetDCNameInfo **info_p, bool *expired) { char *key; DATA_BLOB blob; enum ndr_err_code ndr_err; struct netr_DsRGetDCNameInfo *info; struct NETLOGON_SAM_LOGON_RESPONSE_EX r; NTSTATUS status; if (!gencache_init()) { return NT_STATUS_INTERNAL_DB_ERROR; } key = dsgetdcname_cache_key(mem_ctx, domain_name); if (!key) { return NT_STATUS_NO_MEMORY; } if (!gencache_get_data_blob(key, &blob, expired)) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; } info = TALLOC_ZERO_P(mem_ctx, struct netr_DsRGetDCNameInfo); if (!info) { return NT_STATUS_NO_MEMORY; } ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r, (ndr_pull_flags_fn_t)ndr_pull_NETLOGON_SAM_LOGON_RESPONSE_EX); data_blob_free(&blob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { dsgetdcname_cache_delete(mem_ctx, domain_name); return ndr_map_error2ntstatus(ndr_err); } status = make_dc_info_from_cldap_reply(mem_ctx, flags, NULL, &r, &info); if (!NT_STATUS_IS_OK(status)) { return status; } if (DEBUGLEVEL >= 10) { NDR_PRINT_DEBUG(netr_DsRGetDCNameInfo, info); } /* check flags */ if (!check_cldap_reply_required_flags(info->dc_flags, flags)) { DEBUG(10,("invalid flags\n")); return NT_STATUS_INVALID_PARAMETER; } if ((flags & DS_IP_REQUIRED) && (info->dc_address_type != DS_ADDRESS_TYPE_INET)) { return NT_STATUS_INVALID_PARAMETER_MIX; } *info_p = info; return NT_STATUS_OK; }