📄 namequery.c
字号:
ptr = list; while (next_token(&ptr, tok, " ", sizeof(tok))) { unsigned port = LDAP_PORT; char *p = strchr(tok, ':'); if (p) { *p = 0; port = atoi(p+1); } (*return_iplist)[i].ip = *interpret_addr2(tok); (*return_iplist)[i].port = port; /* 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_ip((*return_iplist)[i].ip) ) continue; i++; } SAFE_FREE(list); *return_count = i; return True; } else #endif /* HAVE_ADS */ { return False; }}/******************************************************************* Internal interface to resolve a name into an IP address. Use this function if the string is either an IP address, DNS or host name or NetBIOS name. This uses the name switch in the smb.conf to determine the order of name resolution. Added support for ip addr/port to support ADS ldap servers. the only place we currently care about the port is in the resolve_hosts() when looking up DC's via SRV RR entries in DNS**********************************************************************/BOOL internal_resolve_name(const char *name, int name_type, struct ip_service **return_iplist, int *return_count, const char *resolve_order){ pstring name_resolve_list; fstring tok; const char *ptr; BOOL allones = (strcmp(name,"255.255.255.255") == 0); BOOL allzeros = (strcmp(name,"0.0.0.0") == 0); BOOL is_address = is_ipaddress(name); BOOL result = False; int i; *return_iplist = NULL; *return_count = 0; DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type)); if (allzeros || allones || is_address) { if ( (*return_iplist = SMB_MALLOC_P(struct ip_service)) == NULL ) { DEBUG(0,("internal_resolve_name: malloc fail !\n")); return False; } if(is_address) { /* ignore the port here */ (*return_iplist)->port = PORT_NONE; /* if it's in the form of an IP address then get the lib to interpret it */ if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){ DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name)); return False; } } else { (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0; } *return_count = 1; return True; } /* Check name cache */ if (namecache_fetch(name, name_type, return_iplist, return_count)) { /* This could be a negative response */ return (*return_count > 0); } /* set the name resolution order */ if ( strcmp( resolve_order, "NULL") == 0 ) { DEBUG(8,("internal_resolve_name: all lookups disabled\n")); return False; } if ( !resolve_order ) { pstrcpy(name_resolve_list, lp_name_resolve_order()); } else { pstrcpy(name_resolve_list, resolve_order); if ( !name_resolve_list[0] ) { ptr = "host"; } else { ptr = name_resolve_list; } /* iterate through the name resolution backends */ while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { if((strequal(tok, "host") || strequal(tok, "hosts"))) { if (resolve_hosts(name, name_type, return_iplist, return_count)) { result = True; goto done; } } else if(strequal( tok, "ads")) { /* deal with 0x1c names here. This will result in a SRV record lookup for _ldap._tcp.<domain> if we are using 'security = ads' */ if (resolve_ads(name, name_type, return_iplist, return_count)) { result = True; goto done; } } else if(strequal( tok, "lmhosts")) { if (resolve_lmhosts(name, name_type, return_iplist, return_count)) { result = True; goto done; } } else if(strequal( tok, "wins")) { /* don't resolve 1D via WINS */ if (name_type != 0x1D && resolve_wins(name, name_type, return_iplist, return_count)) { result = True; goto done; } } else if(strequal( tok, "bcast")) { if (name_resolve_bcast(name, name_type, return_iplist, return_count)) { result = True; goto done; } } else { DEBUG(0,("resolve_name: unknown name switch type %s\n", tok)); } } /* All of the resolve_* functions above have returned false. */ SAFE_FREE(*return_iplist); *return_count = 0; return False; done: /* Remove duplicate entries. Some queries, notably #1c (domain controllers) return the PDC in iplist[0] and then all domain controllers including the PDC in iplist[1..n]. Iterating over the iplist when the PDC is down will cause two sets of timeouts. */ if ( *return_count ) { *return_count = remove_duplicate_addrs2( *return_iplist, *return_count ); } /* Save in name cache */ if ( DEBUGLEVEL >= 100 ) { for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name, name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port)); } namecache_store(name, name_type, *return_count, *return_iplist); /* Display some debugging info */ if ( DEBUGLEVEL >= 10 ) { DEBUG(10, ("internal_resolve_name: returning %d addresses: ", *return_count)); for (i = 0; i < *return_count; i++) { DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port)); } DEBUG(10, ("\n")); } } return result;}/******************************************************** Internal interface to resolve a name into one IP address. Use this function if the string is either an IP address, DNS or host name or NetBIOS name. This uses the name switch in the smb.conf to determine the order of name resolution.*********************************************************/BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type){ struct ip_service *ip_list = NULL; int count = 0; if (is_ipaddress(name)) { *return_ip = *interpret_addr2(name); return True; } if (internal_resolve_name(name, name_type, &ip_list, &count, lp_name_resolve_order())) { int i; /* only return valid addresses for TCP connections */ for (i=0; i<count; i++) { char *ip_str = inet_ntoa(ip_list[i].ip); if (ip_str && strcmp(ip_str, "255.255.255.255") != 0 && strcmp(ip_str, "0.0.0.0") != 0) { *return_ip = ip_list[i].ip; SAFE_FREE(ip_list); return True; } } } SAFE_FREE(ip_list); return False;}/******************************************************** Find the IP address of the master browser or DMB for a workgroup.*********************************************************/BOOL find_master_ip(const char *group, struct in_addr *master_ip){ struct ip_service *ip_list = NULL; int count = 0; if (lp_disable_netbios()) { DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group)); return False; } if (internal_resolve_name(group, 0x1D, &ip_list, &count, lp_name_resolve_order())) { *master_ip = ip_list[0].ip; SAFE_FREE(ip_list); return True; } if(internal_resolve_name(group, 0x1B, &ip_list, &count, lp_name_resolve_order())) { *master_ip = ip_list[0].ip; SAFE_FREE(ip_list); return True; } SAFE_FREE(ip_list); return False;}/******************************************************** Get the IP address list of the primary domain controller for a domain.*********************************************************/BOOL get_pdc_ip(const char *domain, struct in_addr *ip){ struct ip_service *ip_list; int count; /* Look up #1B name */ if (!internal_resolve_name(domain, 0x1b, &ip_list, &count, lp_name_resolve_order())) { return False; } /* if we get more than 1 IP back we have to assume it is a multi-homed PDC and not a mess up */ if ( count > 1 ) { DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count)); sort_ip_list2( ip_list, count ); } *ip = ip_list[0].ip; SAFE_FREE(ip_list); return True;}/******************************************************** Get the IP address list of the domain controllers for a domain.*********************************************************/static BOOL get_dc_list(const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only, int *ordered){ fstring resolve_order; /* if we are restricted to solely using DNS for looking up a domain controller, make sure that host lookups are enabled for the 'name resolve order'. If host lookups are disabled and ads_only is True, then set the string to NULL. */ fstrcpy( resolve_order, lp_name_resolve_order() ); strlower_m( resolve_order ); if ( ads_only ) { if ( strstr( resolve_order, "host" ) ) fstrcpy( resolve_order, "ads" ); else fstrcpy( resolve_order, "NULL" ); } *ordered = False; /* If it's our domain then use the 'password server' parameter. */ if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) { const char *p; char *pserver = lp_passwordserver(); /* UNIX charset. */ char *port_str; int port; fstring name; int num_addresses = 0; int local_count, i, j; struct ip_service *return_iplist = NULL; struct ip_service *auto_ip_list = NULL; BOOL done_auto_lookup = False; int auto_count = 0; if (!*pserver) return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order); p = pserver; /* * if '*' appears in the "password server" list then add * an auto lookup to the list of manually configured * DC's. If any DC is listed by name, then the list should be * considered to be ordered */ while (next_token(&p,name,LIST_SEP,sizeof(name))) { if (strequal(name, "*")) { if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count, resolve_order) ) num_addresses += auto_count; done_auto_lookup = True; DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count)); } else { num_addresses++; } } /* if we have no addresses and haven't done the auto lookup, then just return the list of DC's */ if ( (num_addresses == 0) && !done_auto_lookup ) { return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order); } /* maybe we just failed? */ if ( num_addresses == 0 ) { DEBUG(4,("get_dc_list: no servers found\n")); return False; } if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) { DEBUG(3,("get_dc_list: malloc fail !\n")); return False; } p = pserver; local_count = 0; /* fill in the return list now with real IP's */ while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) { struct in_addr name_ip; /* copy any addersses from the auto lookup */ if ( strequal(name, "*") ) { for ( j=0; j<auto_count; j++ ) { /* Check for and don't copy any known bad DC IP's. */ if(!NT_STATUS_IS_OK(check_negative_conn_cache(domain, inet_ntoa(auto_ip_list[j].ip)))) { DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n", inet_ntoa(auto_ip_list[j].ip) )); continue; } return_iplist[local_count].ip = auto_ip_list[j].ip; return_iplist[local_count].port = auto_ip_list[j].port; local_count++; } continue; } /* added support for address:port syntax for ads (not that I think anyone will ever run the LDAP server in an AD domain on something other than port 389 */ port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE; if ( (port_str=strchr(name, ':')) != NULL ) { *port_str = '\0'; port_str++; port = atoi( port_str ); } /* explicit lookup; resolve_name() will handle names & IP addresses */ if ( resolve_name( name, &name_ip, 0x20 ) ) { /* Check for and don't copy any known bad DC IP's. */ if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain, inet_ntoa(name_ip))) ) { DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",name )); continue; } return_iplist[local_count].ip = name_ip; return_iplist[local_count].port = port; local_count++; *ordered = True; } } SAFE_FREE(auto_ip_list); /* need to remove duplicates in the list if we have any explicit password servers */ if ( local_count ) { local_count = remove_duplicate_addrs2( return_iplist, local_count ); } if ( DEBUGLEVEL >= 4 ) { DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count, *ordered ? "":"un")); DEBUG(4,("get_dc_list: ")); for ( i=0; i<local_count; i++ ) DEBUGADD(4,("%s:%d ", inet_ntoa(return_iplist[i].ip), return_iplist[i].port )); DEBUGADD(4,("\n")); } *ip_list = return_iplist; *count = local_count; return (*count != 0); } DEBUG(10,("get_dc_list: defaulting to internal auto lookup for domain %s\n", domain)); return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order);}/********************************************************************* Small wrapper function to get the DC list and sort it if neccessary.*********************************************************************/BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only ){ BOOL ordered; DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n", (ads_only ? "ads" : lp_name_resolve_order()))); if ( !get_dc_list(domain, ip_list, count, ads_only, &ordered) ) { return False; } /* only sort if we don't already have an ordered list */ if ( !ordered ) { sort_ip_list2( *ip_list, *count ); } return True;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -