static bool rpc_dc_name(const char *domain, fstring srv_name, struct sockaddr_storage *ss_out) { struct ip_service *ip_list = NULL; struct sockaddr_storage dc_ss; int count, i; NTSTATUS result; char addr[INET6_ADDRSTRLEN]; /* get a list of all domain controllers */ if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, NULL, &ip_list, &count, False))) { DEBUG(3, ("Could not look up dc's for domain %s\n", domain)); return False; } /* Remove the entry we've already failed with (should be the PDC). */ for (i = 0; i < count; i++) { if (is_zero_addr((struct sockaddr *)&ip_list[i].ss)) continue; if (name_status_find(domain, 0x1c, 0x20, &ip_list[i].ss, srv_name)) { result = check_negative_conn_cache( domain, srv_name ); if ( NT_STATUS_IS_OK(result) ) { dc_ss = ip_list[i].ss; goto done; } } } SAFE_FREE(ip_list); /* No-one to talk to )-: */ return False; /* Boo-hoo */ done: /* We have the netbios name and IP address of a domain controller. Ideally we should sent a SAMLOGON request to determine whether the DC is alive and kicking. If we can catch a dead DC before performing a cli_connect() we can avoid a 30-second timeout. */ print_sockaddr(addr, sizeof(addr), &dc_ss); DEBUG(3, ("rpc_dc_name: Returning DC %s (%s) for domain %s\n", srv_name, addr, domain)); *ss_out = dc_ss; SAFE_FREE(ip_list); return True; }
bool net_find_pdc(struct sockaddr_storage *server_ss, fstring server_name, const char *domain_name) { if (!get_pdc_ip(domain_name, server_ss)) { return false; } if (is_zero_addr(server_ss)) { return false; } if (!name_status_find(domain_name, 0x1b, 0x20, server_ss, server_name)) { return false; } return true; }
bool net_find_server(struct net_context *c, const char *domain, unsigned flags, struct sockaddr_storage *server_ss, char **server_name) { const char *d = domain ? domain : c->opt_target_workgroup; if (c->opt_host) { *server_name = SMB_STRDUP(c->opt_host); } if (c->opt_have_ip) { *server_ss = c->opt_dest_ip; if (!*server_name) { char addr[INET6_ADDRSTRLEN]; print_sockaddr(addr, sizeof(addr), &c->opt_dest_ip); *server_name = SMB_STRDUP(addr); } } else if (*server_name) { /* resolve the IP address */ if (!resolve_name(*server_name, server_ss, 0x20, false)) { DEBUG(1,("Unable to resolve server name\n")); return false; } } else if (flags & NET_FLAGS_PDC) { fstring dc_name; struct sockaddr_storage pdc_ss; if (!get_pdc_ip(d, &pdc_ss)) { DEBUG(1,("Unable to resolve PDC server address\n")); return false; } if (is_zero_addr(&pdc_ss)) { return false; } if (!name_status_find(d, 0x1b, 0x20, &pdc_ss, dc_name)) { return false; } *server_name = SMB_STRDUP(dc_name); *server_ss = pdc_ss; } else if (flags & NET_FLAGS_DMB) { struct sockaddr_storage msbrow_ss; char addr[INET6_ADDRSTRLEN]; /* if (!resolve_name(MSBROWSE, &msbrow_ip, 1, false)) */ if (!resolve_name(d, &msbrow_ss, 0x1B, false)) { DEBUG(1,("Unable to resolve domain browser via name lookup\n")); return false; } *server_ss = msbrow_ss; print_sockaddr(addr, sizeof(addr), server_ss); *server_name = SMB_STRDUP(addr); } else if (flags & NET_FLAGS_MASTER) { struct sockaddr_storage brow_ss; char addr[INET6_ADDRSTRLEN]; if (!resolve_name(d, &brow_ss, 0x1D, false)) { /* go looking for workgroups */ DEBUG(1,("Unable to resolve master browser via name lookup\n")); return false; } *server_ss = brow_ss; print_sockaddr(addr, sizeof(addr), server_ss); *server_name = SMB_STRDUP(addr); } else if (!(flags & NET_FLAGS_LOCALHOST_DEFAULT_INSANE)) { if (!interpret_string_addr(server_ss, "127.0.0.1", AI_NUMERICHOST)) { DEBUG(1,("Unable to resolve 127.0.0.1\n")); return false; } *server_name = SMB_STRDUP("127.0.0.1"); } if (!*server_name) { DEBUG(1,("no server to connect to\n")); return false; } return true; }
static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, const char *domain_name, struct GUID *domain_guid, uint32_t flags, const char *site_name, struct ip_service_name **returned_dclist, int *return_count) { int i, j; NTSTATUS status; struct dns_rr_srv *dcs = NULL; int numdcs = 0; int numaddrs = 0; struct ip_service_name *dclist = NULL; int count = 0; if (flags & DS_PDC_REQUIRED) { status = ads_dns_query_pdc(mem_ctx, domain_name, &dcs, &numdcs); } else if (flags & DS_GC_SERVER_REQUIRED) { status = ads_dns_query_gcs(mem_ctx, domain_name, site_name, &dcs, &numdcs); } else if (flags & DS_KDC_REQUIRED) { status = ads_dns_query_kdcs(mem_ctx, domain_name, site_name, &dcs, &numdcs); } else if (flags & DS_DIRECTORY_SERVICE_REQUIRED) { status = ads_dns_query_dcs(mem_ctx, domain_name, site_name, &dcs, &numdcs); } else if (domain_guid) { status = ads_dns_query_dcs_guid(mem_ctx, domain_name, domain_guid, &dcs, &numdcs); } else { status = ads_dns_query_dcs(mem_ctx, domain_name, site_name, &dcs, &numdcs); } if (!NT_STATUS_IS_OK(status)) { return status; } if (numdcs == 0) { return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; } for (i=0;i<numdcs;i++) { numaddrs += MAX(dcs[i].num_ips,1); } dclist = TALLOC_ZERO_ARRAY(mem_ctx, struct ip_service_name, numaddrs); if (!dclist) { return NT_STATUS_NO_MEMORY; } /* now unroll the list of IP addresses */ *return_count = 0; i = 0; j = 0; while ((i < numdcs) && (count < numaddrs)) { struct ip_service_name *r = &dclist[count]; r->port = dcs[i].port; r->hostname = dcs[i].hostname; /* If we don't have an IP list for a name, lookup it up */ if (!dcs[i].ss_s) { interpret_string_addr(&r->ss, dcs[i].hostname, 0); i++; j = 0; } else { /* use the IP addresses from the SRV sresponse */ if (j >= dcs[i].num_ips) { i++; j = 0; continue; } r->ss = dcs[i].ss_s[j]; j++; } /* make sure it is a valid IP. I considered checking the * negative connection cache, but this is the wrong place for * it. Maybe only as a hac. After think about it, if all of * the IP addresses retuend from DNS are dead, what hope does a * netbios name lookup have? The standard reason for falling * back to netbios lookups is that our DNS server doesn't know * anything about the DC's -- jerry */ if (!is_zero_addr(&r->ss)) { count++; continue; } } *returned_dclist = dclist; *return_count = count; if (count > 0) { return NT_STATUS_OK; } return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; }
static int is_eth_addr_valid(uint8_t *addr) { return !is_mcast_addr(addr) && !is_zero_addr(addr); }