libsmb/namequery.c

ソースコードを見る。

列挙型

enum  dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY }

関数

static char * saf_key (const char *domain)
BOOL saf_store (const char *domain, const char *servername)
BOOL saf_delete (const char *domain)
char * saf_fetch (const char *domain)
static int generate_trn_id (void)
static NODE_STATUS_STRUCTparse_node_status (char *p, int *num_names, struct node_status_extra *extra)
NODE_STATUS_STRUCTnode_status_query (int fd, struct nmb_name *name, struct in_addr to_ip, int *num_names, struct node_status_extra *extra)
BOOL name_status_find (const char *q_name, int q_type, int type, struct in_addr to_ip, fstring name)
static int ip_compare (struct in_addr *ip1, struct in_addr *ip2)
int ip_service_compare (struct ip_service *ip1, struct ip_service *ip2)
static void sort_ip_list (struct in_addr *iplist, int count)
static void sort_ip_list2 (struct ip_service *iplist, int count)
static int remove_duplicate_addrs2 (struct ip_service *iplist, int count)
in_addr * name_query (int fd, const char *name, int name_type, BOOL bcast, BOOL recurse, struct in_addr to_ip, int *count, int *flags, BOOL *timed_out)
XFILEstartlmhosts (char *fname)
BOOL getlmhostsent (XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
void endlmhosts (XFILE *fp)
static BOOL convert_ip2service (struct ip_service **return_iplist, struct in_addr *ip_list, int count)
BOOL name_resolve_bcast (const char *name, int name_type, struct ip_service **return_iplist, int *return_count)
BOOL resolve_wins (const char *name, int name_type, struct ip_service **return_iplist, int *return_count)
static BOOL resolve_lmhosts (const char *name, int name_type, struct ip_service **return_iplist, int *return_count)
static BOOL resolve_hosts (const char *name, int name_type, struct ip_service **return_iplist, int *return_count)
static BOOL resolve_ads (const char *name, int name_type, const char *sitename, struct ip_service **return_iplist, int *return_count)
BOOL internal_resolve_name (const char *name, int name_type, const char *sitename, struct ip_service **return_iplist, int *return_count, const char *resolve_order)
BOOL resolve_name (const char *name, struct in_addr *return_ip, int name_type)
BOOL find_master_ip (const char *group, struct in_addr *master_ip)
BOOL get_pdc_ip (const char *domain, struct in_addr *ip)
static NTSTATUS get_dc_list (const char *domain, const char *sitename, struct ip_service **ip_list, int *count, enum dc_lookup_type lookup_type, int *ordered)
NTSTATUS get_sorted_dc_list (const char *domain, const char *sitename, struct ip_service **ip_list, int *count, BOOL ads_only)
NTSTATUS get_kdc_list (const char *realm, const char *sitename, struct ip_service **ip_list, int *count)

変数

BOOL global_in_nmbd = False


列挙型

enum dc_lookup_type

列挙型の値:
DC_NORMAL_LOOKUP 
DC_ADS_ONLY 
DC_KDC_ONLY 

namequery.c1408 行で定義されています。


関数

static char* saf_key ( const char *  domain  )  [static]

namequery.c38 行で定義されています。

参照先 asprintf()strupper_static().

参照元 saf_delete()saf_fetch()saf_store().

00039 {
00040         char *keystr;
00041         
00042         asprintf( &keystr, SAFKEY_FMT, strupper_static(domain) );
00043 
00044         return keystr;
00045 }

BOOL saf_store ( const char *  domain,
const char *  servername 
)

namequery.c50 行で定義されています。

参照先 gencache_init()gencache_set()saf_key().

参照元 ads_connect()cm_prepare_connection()dcip_to_name()domain_client_validate()net_join_domain()net_make_ipc_connection_ex()rpc_trustdom_establish().

00051 {
00052         char *key;
00053         time_t expire;
00054         BOOL ret = False;
00055         
00056         if ( !domain || !servername ) {
00057                 DEBUG(2,("saf_store: Refusing to store empty domain or servername!\n"));
00058                 return False;
00059         }
00060 
00061         if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
00062                 DEBUG(0,("saf_store: refusing to store 0 length domain or servername!\n"));
00063                 return False;
00064         }
00065         
00066         if ( !gencache_init() ) 
00067                 return False;
00068         
00069         key = saf_key( domain );
00070         expire = time( NULL ) + SAF_TTL;
00071         
00072         
00073         DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n",
00074                 domain, servername, (unsigned int)expire ));
00075                 
00076         ret = gencache_set( key, servername, expire );
00077         
00078         SAFE_FREE( key );
00079         
00080         return ret;
00081 }

BOOL saf_delete ( const char *  domain  ) 

namequery.c83 行で定義されています。

参照先 gencache_del()gencache_init()saf_key().

参照元 net_ads_leave()winbind_add_failed_connection_entry().

00084 {
00085         char *key;
00086         BOOL ret = False;
00087         
00088         if ( !domain ) {
00089                 DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));             
00090                 return False;
00091         }
00092         
00093         if ( !gencache_init() ) 
00094                 return False;
00095         
00096         key = saf_key(domain);
00097         ret = gencache_del(key);
00098         
00099         if (ret) {
00100                 DEBUG(10,("saf_delete: domain = [%s]\n", domain ));             
00101         }
00102 
00103         SAFE_FREE( key );
00104 
00105         return ret;
00106 }

char* saf_fetch ( const char *  domain  ) 

namequery.c111 行で定義されています。

参照先 gencache_get()gencache_init()saf_key()servertimeout.

参照元 cm_open_connection()get_dc_list()smb_krb5_locator_lookup().

00112 {
00113         char *server = NULL;
00114         time_t timeout;
00115         BOOL ret = False;
00116         char *key = NULL;
00117 
00118         if ( !domain || strlen(domain) == 0) {
00119                 DEBUG(2,("saf_fetch: Empty domain name!\n"));
00120                 return NULL;
00121         }
00122         
00123         if ( !gencache_init() ) 
00124                 return False;
00125         
00126         key = saf_key( domain );
00127         
00128         ret = gencache_get( key, &server, &timeout );
00129         
00130         SAFE_FREE( key );
00131         
00132         if ( !ret ) {
00133                 DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n", domain ));
00134         } else {
00135                 DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n", 
00136                         server, domain ));
00137         }
00138                 
00139         return server;
00140 }

static int generate_trn_id ( void   )  [static]

namequery.c146 行で定義されています。

参照先 sys_getpid()sys_random()sys_srandom().

参照元 name_query()node_status_query().

00147 {
00148         static int trn_id;
00149 
00150         if (trn_id == 0) {
00151                 sys_srandom(sys_getpid());
00152         }
00153 
00154         trn_id = sys_random();
00155 
00156         return trn_id % (unsigned)0x7FFF;
00157 }

static NODE_STATUS_STRUCT* parse_node_status ( char *  p,
int *  num_names,
struct node_status_extra extra 
) [static]

namequery.c163 行で定義されています。

参照先 flagsnode_status_::flagsnode_status_extra::mac_addrnametrim_char()typenode_status_::type.

参照元 node_status_query().

00164 {
00165         NODE_STATUS_STRUCT *ret;
00166         int i;
00167 
00168         *num_names = CVAL(p,0);
00169 
00170         if (*num_names == 0)
00171                 return NULL;
00172 
00173         ret = SMB_MALLOC_ARRAY(NODE_STATUS_STRUCT,*num_names);
00174         if (!ret)
00175                 return NULL;
00176 
00177         p++;
00178         for (i=0;i< *num_names;i++) {
00179                 StrnCpy(ret[i].name,p,15);
00180                 trim_char(ret[i].name,'\0',' ');
00181                 ret[i].type = CVAL(p,15);
00182                 ret[i].flags = p[16];
00183                 p += 18;
00184                 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name, 
00185                            ret[i].type, ret[i].flags));
00186         }
00187         /*
00188          * Also, pick up the MAC address ...
00189          */
00190         if (extra) {
00191                 memcpy(&extra->mac_addr, p, 6); /* Fill in the mac addr */
00192         }
00193         return ret;
00194 }

NODE_STATUS_STRUCT* node_status_query ( int  fd,
struct nmb_name name,
struct in_addr  to_ip,
int *  num_names,
struct node_status_extra extra 
)

namequery.c202 行で定義されています。

参照先 nmb_packet::ancountnmb_packet::answersnmb_packet::arcountdebug_nmb_packet()packet_struct::fdfree_packet()generate_trn_id()GetTimeOfDay()nmb_packet::headerpacket_struct::ipnamenmb_packet::name_trn_idnmb_packet::nm_flagspacket_struct::nmbNMB_PACKETnmb_packet::nscountnmb_packet::opcodepacket_struct::packetpacket_struct::packet_typeparse_node_status()packet_struct::portnmb_packet::qdcountnmb_packet::questionnmb_packet::question_classnmb_packet::question_namenmb_packet::question_typenmb_packet::rcoderes_rec::rdatareceive_nmb_packet()nmb_packet::responseres_rec::rr_typesend_packet()packet_struct::timestamp.

参照元 do_node_status()lookup_byaddr_backend()name_status_find().

00205 {
00206         BOOL found=False;
00207         int retries = 2;
00208         int retry_time = 2000;
00209         struct timeval tval;
00210         struct packet_struct p;
00211         struct packet_struct *p2;
00212         struct nmb_packet *nmb = &p.packet.nmb;
00213         NODE_STATUS_STRUCT *ret;
00214 
00215         ZERO_STRUCT(p);
00216 
00217         nmb->header.name_trn_id = generate_trn_id();
00218         nmb->header.opcode = 0;
00219         nmb->header.response = False;
00220         nmb->header.nm_flags.bcast = False;
00221         nmb->header.nm_flags.recursion_available = False;
00222         nmb->header.nm_flags.recursion_desired = False;
00223         nmb->header.nm_flags.trunc = False;
00224         nmb->header.nm_flags.authoritative = False;
00225         nmb->header.rcode = 0;
00226         nmb->header.qdcount = 1;
00227         nmb->header.ancount = 0;
00228         nmb->header.nscount = 0;
00229         nmb->header.arcount = 0;
00230         nmb->question.question_name = *name;
00231         nmb->question.question_type = 0x21;
00232         nmb->question.question_class = 0x1;
00233 
00234         p.ip = to_ip;
00235         p.port = NMB_PORT;
00236         p.fd = fd;
00237         p.timestamp = time(NULL);
00238         p.packet_type = NMB_PACKET;
00239         
00240         GetTimeOfDay(&tval);
00241   
00242         if (!send_packet(&p)) 
00243                 return NULL;
00244 
00245         retries--;
00246 
00247         while (1) {
00248                 struct timeval tval2;
00249                 GetTimeOfDay(&tval2);
00250                 if (TvalDiff(&tval,&tval2) > retry_time) {
00251                         if (!retries)
00252                                 break;
00253                         if (!found && !send_packet(&p))
00254                                 return NULL;
00255                         GetTimeOfDay(&tval);
00256                         retries--;
00257                 }
00258 
00259                 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {     
00260                         struct nmb_packet *nmb2 = &p2->packet.nmb;
00261                         debug_nmb_packet(p2);
00262                         
00263                         if (nmb2->header.opcode != 0 ||
00264                             nmb2->header.nm_flags.bcast ||
00265                             nmb2->header.rcode ||
00266                             !nmb2->header.ancount ||
00267                             nmb2->answers->rr_type != 0x21) {
00268                                 /* XXXX what do we do with this? could be a
00269                                    redirect, but we'll discard it for the
00270                                    moment */
00271                                 free_packet(p2);
00272                                 continue;
00273                         }
00274 
00275                         ret = parse_node_status(&nmb2->answers->rdata[0], num_names, extra);
00276                         free_packet(p2);
00277                         return ret;
00278                 }
00279         }
00280         
00281         return NULL;
00282 }

BOOL name_status_find ( const char *  q_name,
int  q_type,
int  type,
struct in_addr  to_ip,
fstring  name 
)

namequery.c289 行で定義されています。

参照先 interpret_addr()make_nmb_name()namecache_status_fetch()namecache_status_store()node_status_query()open_socket_in()pull_ascii_nstring()resultstatus.

参照元 change_trust_account_password()get_ipc_connect()get_ipc_connect_master_ip()net_find_pdc()net_find_server()rpc_dc_name()smbc_opendir_ctx()smbc_server().

00290 {
00291         NODE_STATUS_STRUCT *status = NULL;
00292         struct nmb_name nname;
00293         int count, i;
00294         int sock;
00295         BOOL result = False;
00296 
00297         if (lp_disable_netbios()) {
00298                 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type));
00299                 return False;
00300         }
00301 
00302         DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name, 
00303                    q_type, inet_ntoa(to_ip)));
00304 
00305         /* Check the cache first. */
00306 
00307         if (namecache_status_fetch(q_name, q_type, type, to_ip, name))
00308                 return True;
00309 
00310         sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
00311         if (sock == -1)
00312                 goto done;
00313 
00314         /* W2K PDC's seem not to respond to '*'#0. JRA */
00315         make_nmb_name(&nname, q_name, q_type);
00316         status = node_status_query(sock, &nname, to_ip, &count, NULL);
00317         close(sock);
00318         if (!status)
00319                 goto done;
00320 
00321         for (i=0;i<count;i++) {
00322                 if (status[i].type == type)
00323                         break;
00324         }
00325         if (i == count)
00326                 goto done;
00327 
00328         pull_ascii_nstring(name, sizeof(fstring), status[i].name);
00329 
00330         /* Store the result in the cache. */
00331         /* but don't store an entry for 0x1c names here.  Here we have 
00332            a single host and DOMAIN<0x1c> names should be a list of hosts */
00333            
00334         if ( q_type != 0x1c )
00335                 namecache_status_store(q_name, q_type, type, to_ip, name);
00336 
00337         result = True;
00338 
00339  done:
00340         SAFE_FREE(status);
00341 
00342         DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
00343 
00344         if (result)
00345                 DEBUGADD(10, (", name %s ip address is %s", name, inet_ntoa(to_ip)));
00346 
00347         DEBUG(10, ("\n"));      
00348 
00349         return result;
00350 }

static int ip_compare ( struct in_addr *  ip1,
struct in_addr *  ip2 
) [static]

namequery.c356 行で定義されています。

参照先 iface_count()iface_local()iface_n_bcast()matching_quad_bits().

参照元 ip_service_compare()sort_ip_list().

00357 {
00358         int max_bits1=0, max_bits2=0;
00359         int num_interfaces = iface_count();
00360         int i;
00361 
00362         for (i=0;i<num_interfaces;i++) {
00363                 struct in_addr ip;
00364                 int bits1, bits2;
00365                 ip = *iface_n_bcast(i);
00366                 bits1 = matching_quad_bits((uchar *)&ip1->s_addr, (uchar *)&ip.s_addr);
00367                 bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr);
00368                 max_bits1 = MAX(bits1, max_bits1);
00369                 max_bits2 = MAX(bits2, max_bits2);
00370         }       
00371         
00372         /* bias towards directly reachable IPs */
00373         if (iface_local(*ip1)) {
00374                 max_bits1 += 32;
00375         }
00376         if (iface_local(*ip2)) {
00377                 max_bits2 += 32;
00378         }
00379 
00380         return max_bits2 - max_bits1;
00381 }

int ip_service_compare ( struct ip_service ip1,
struct ip_service ip2 
)

namequery.c387 行で定義されています。

参照先 ip_service::ipip_compare()ip_service::portresult.

参照元 get_kdc_ip_string()sort_ip_list2().

00388 {
00389         int result;
00390         
00391         if ( (result = ip_compare(&ip1->ip, &ip2->ip)) != 0 )
00392                 return result;
00393                 
00394         if ( ip1->port > ip2->port )
00395                 return 1;
00396         
00397         if ( ip1->port < ip2->port )
00398                 return -1;
00399                 
00400         return 0;
00401 }

static void sort_ip_list ( struct in_addr *  iplist,
int  count 
) [static]

namequery.c409 行で定義されています。

参照先 ip_compare().

参照元 name_query().

00410 {
00411         if (count <= 1) {
00412                 return;
00413         }
00414 
00415         qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);    
00416 }

static void sort_ip_list2 ( struct ip_service iplist,
int  count 
) [static]

namequery.c418 行で定義されています。

参照先 ip_service_compare().

参照元 get_kdc_list()get_pdc_ip()get_sorted_dc_list().

00419 {
00420         if (count <= 1) {
00421                 return;
00422         }
00423 
00424         qsort(iplist, count, sizeof(struct ip_service), QSORT_CAST ip_service_compare); 
00425 }

static int remove_duplicate_addrs2 ( struct ip_service iplist,
int  count 
) [static]

namequery.c431 行で定義されています。

参照先 is_zero_ip()zero_ip().

参照元 get_dc_list()internal_resolve_name().

00432 {
00433         int i, j;
00434         
00435         DEBUG(10,("remove_duplicate_addrs2: looking for duplicate address/port pairs\n"));
00436         
00437         /* one loop to remove duplicates */
00438         for ( i=0; i<count; i++ ) {
00439                 if ( is_zero_ip(iplist[i].ip) )
00440                         continue;
00441                                         
00442                 for ( j=i+1; j<count; j++ ) {
00443                         if ( ip_service_equal(iplist[i], iplist[j]) )
00444                                 zero_ip(&iplist[j].ip);
00445                 }
00446         }
00447                         
00448         /* one loop to clean up any holes we left */
00449         /* first ip should never be a zero_ip() */
00450         for (i = 0; i<count; ) {
00451                 if ( is_zero_ip(iplist[i].ip) ) {
00452                         if (i != count-1 )
00453                                 memmove(&iplist[i], &iplist[i+1], (count - i - 1)*sizeof(iplist[i]));
00454                         count--;
00455                         continue;
00456                 }
00457                 i++;
00458         }
00459 
00460         return count;
00461 }

struct in_addr* name_query ( int  fd,
const char *  name,
int  name_type,
BOOL  bcast,
BOOL  recurse,
struct in_addr  to_ip,
int *  count,
int *  flags,
BOOL timed_out 
)

namequery.c470 行で定義されています。

参照先 nmb_packet::ancountnmb_packet::answersnmb_packet::arcountdbgtext()debug_nmb_packet()free_packet()generate_trn_id()GetTimeOfDay()nmb_packet::headerpacket_struct::ipmake_nmb_name()nmb_packet::name_trn_idnmb_packet::nm_flagspacket_struct::nmbNMB_PACKETnmb_packet::nscountnmb_packet::opcodepacket_struct::packetnmb_packet::qdcountnmb_packet::questionnmb_packet::question_classnmb_packet::question_namenmb_packet::question_typenmb_packet::rcoderes_rec::rdatares_rec::rdlengthreceive_nmb_packet()nmb_packet::responsesend_packet()sort_ip_list().

参照元 lookup_byname_backend()name_resolve_bcast()nmbd_running()query_one()resolve_wins().

00474 {
00475         BOOL found=False;
00476         int i, retries = 3;
00477         int retry_time = bcast?250:2000;
00478         struct timeval tval;
00479         struct packet_struct p;
00480         struct packet_struct *p2;
00481         struct nmb_packet *nmb = &p.packet.nmb;
00482         struct in_addr *ip_list = NULL;
00483 
00484         if (lp_disable_netbios()) {
00485                 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type));
00486                 return NULL;
00487         }
00488 
00489         if (timed_out) {
00490                 *timed_out = False;
00491         }
00492         
00493         memset((char *)&p,'\0',sizeof(p));
00494         (*count) = 0;
00495         (*flags) = 0;
00496         
00497         nmb->header.name_trn_id = generate_trn_id();
00498         nmb->header.opcode = 0;
00499         nmb->header.response = False;
00500         nmb->header.nm_flags.bcast = bcast;
00501         nmb->header.nm_flags.recursion_available = False;
00502         nmb->header.nm_flags.recursion_desired = recurse;
00503         nmb->header.nm_flags.trunc = False;
00504         nmb->header.nm_flags.authoritative = False;
00505         nmb->header.rcode = 0;
00506         nmb->header.qdcount = 1;
00507         nmb->header.ancount = 0;
00508         nmb->header.nscount = 0;
00509         nmb->header.arcount = 0;
00510         
00511         make_nmb_name(&nmb->question.question_name,name,name_type);
00512         
00513         nmb->question.question_type = 0x20;
00514         nmb->question.question_class = 0x1;
00515         
00516         p.ip = to_ip;
00517         p.port = NMB_PORT;
00518         p.fd = fd;
00519         p.timestamp = time(NULL);
00520         p.packet_type = NMB_PACKET;
00521         
00522         GetTimeOfDay(&tval);
00523         
00524         if (!send_packet(&p)) 
00525                 return NULL;
00526         
00527         retries--;
00528         
00529         while (1) {
00530                 struct timeval tval2;
00531                 
00532                 GetTimeOfDay(&tval2);
00533                 if (TvalDiff(&tval,&tval2) > retry_time) {
00534                         if (!retries)
00535                                 break;
00536                         if (!found && !send_packet(&p))
00537                                 return NULL;
00538                         GetTimeOfDay(&tval);
00539                         retries--;
00540                 }
00541                 
00542                 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {     
00543                         struct nmb_packet *nmb2 = &p2->packet.nmb;
00544                         debug_nmb_packet(p2);
00545                         
00546                         /* If we get a Negative Name Query Response from a WINS
00547                          * server, we should report it and give up.
00548                          */
00549                         if( 0 == nmb2->header.opcode            /* A query response   */
00550                             && !(bcast)                 /* from a WINS server */
00551                             && nmb2->header.rcode               /* Error returned     */
00552                                 ) {
00553                                 
00554                                 if( DEBUGLVL( 3 ) ) {
00555                                         /* Only executed if DEBUGLEVEL >= 3 */
00556                                         dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode );
00557                                         switch( nmb2->header.rcode ) {
00558                                         case 0x01:
00559                                                 dbgtext( "Request was invalidly formatted.\n" );
00560                                                 break;
00561                                         case 0x02:
00562                                                 dbgtext( "Problem with NBNS, cannot process name.\n");
00563                                                 break;
00564                                         case 0x03:
00565                                                 dbgtext( "The name requested does not exist.\n" );
00566                                                 break;
00567                                         case 0x04:
00568                                                 dbgtext( "Unsupported request error.\n" );
00569                                                 break;
00570                                         case 0x05:
00571                                                 dbgtext( "Query refused error.\n" );
00572                                                 break;
00573                                         default:
00574                                                 dbgtext( "Unrecognized error code.\n" );
00575                                                 break;
00576                                         }
00577                                 }
00578                                 free_packet(p2);
00579                                 return( NULL );
00580                         }
00581                         
00582                         if (nmb2->header.opcode != 0 ||
00583                             nmb2->header.nm_flags.bcast ||
00584                             nmb2->header.rcode ||
00585                             !nmb2->header.ancount) {
00586                                 /* 
00587                                  * XXXX what do we do with this? Could be a
00588                                  * redirect, but we'll discard it for the
00589                                  * moment.
00590                                  */
00591                                 free_packet(p2);
00592                                 continue;
00593                         }
00594                         
00595                         ip_list = SMB_REALLOC_ARRAY( ip_list, struct in_addr,
00596                                                 (*count) + nmb2->answers->rdlength/6 );
00597                         
00598                         if (!ip_list) {
00599                                 DEBUG(0,("name_query: Realloc failed.\n"));
00600                                 free_packet(p2);
00601                                 return( NULL );
00602                         }
00603                         
00604                         DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
00605                         for (i=0;i<nmb2->answers->rdlength/6;i++) {
00606                                 putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
00607                                 DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
00608                                 (*count)++;
00609                         }
00610                         DEBUGADD(2,(")\n"));
00611                         
00612                         found=True;
00613                         retries=0;
00614                         /* We add the flags back ... */
00615                         if (nmb2->header.response)
00616                                 (*flags) |= NM_FLAGS_RS;
00617                         if (nmb2->header.nm_flags.authoritative)
00618                                 (*flags) |= NM_FLAGS_AA;
00619                         if (nmb2->header.nm_flags.trunc)
00620                                 (*flags) |= NM_FLAGS_TC;
00621                         if (nmb2->header.nm_flags.recursion_desired)
00622                                 (*flags) |= NM_FLAGS_RD;
00623                         if (nmb2->header.nm_flags.recursion_available)
00624                                 (*flags) |= NM_FLAGS_RA;
00625                         if (nmb2->header.nm_flags.bcast)
00626                                 (*flags) |= NM_FLAGS_B;
00627                         free_packet(p2);
00628                         /*
00629                          * If we're doing a unicast lookup we only
00630                          * expect one reply. Don't wait the full 2
00631                          * seconds if we got one. JRA.
00632                          */
00633                         if(!bcast && found)
00634                                 break;
00635                 }
00636         }
00637 
00638         /* only set timed_out if we didn't fund what we where looking for*/
00639         
00640         if ( !found && timed_out ) {
00641                 *timed_out = True;
00642         }
00643 
00644         /* sort the ip list so we choose close servers first if possible */
00645         sort_ip_list(ip_list, *count);
00646 
00647         return ip_list;
00648 }

XFILE* startlmhosts ( char *  fname  ) 

namequery.c654 行で定義されています。

参照先 errnofpstrerror()x_fopen().

参照元 load_lmhosts_file()resolve_lmhosts().

00655 {
00656         XFILE *fp = x_fopen(fname,O_RDONLY, 0);
00657         if (!fp) {
00658                 DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
00659                          fname, strerror(errno)));
00660                 return NULL;
00661         }
00662         return fp;
00663 }

BOOL getlmhostsent ( XFILE fp,
pstring  name,
int *  name_type,
struct in_addr *  ipaddr 
)

namequery.c669 行で定義されています。

参照先 fgets_slash()flagsfpinterpret_addr2()linenext_token()strchr_m()x_feof()x_ferror().

参照元 load_lmhosts_file()resolve_lmhosts().

00670 {
00671         pstring line;
00672 
00673         while(!x_feof(fp) && !x_ferror(fp)) {
00674                 pstring ip,flags,extra;
00675                 const char *ptr;
00676                 char *ptr1;
00677                 int count = 0;
00678 
00679                 *name_type = -1;
00680 
00681                 if (!fgets_slash(line,sizeof(pstring),fp)) {
00682                         continue;
00683                 }
00684 
00685                 if (*line == '#') {
00686                         continue;
00687                 }
00688 
00689                 pstrcpy(ip,"");
00690                 pstrcpy(name,"");
00691                 pstrcpy(flags,"");
00692 
00693                 ptr = line;
00694 
00695                 if (next_token(&ptr,ip   ,NULL,sizeof(ip)))
00696                         ++count;
00697                 if (next_token(&ptr,name ,NULL, sizeof(pstring)))
00698                         ++count;
00699                 if (next_token(&ptr,flags,NULL, sizeof(flags)))
00700                         ++count;
00701                 if (next_token(&ptr,extra,NULL, sizeof(extra)))
00702                         ++count;
00703 
00704                 if (count <= 0)
00705                         continue;
00706 
00707                 if (count > 0 && count < 2) {
00708                         DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
00709                         continue;
00710                 }
00711 
00712                 if (count >= 4) {
00713                         DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
00714                         continue;
00715                 }
00716 
00717                 DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
00718 
00719                 if (strchr_m(flags,'G') || strchr_m(flags,'S')) {
00720                         DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
00721                         continue;
00722                 }
00723 
00724                 *ipaddr = *interpret_addr2(ip);
00725 
00726                 /* Extra feature. If the name ends in '#XX', where XX is a hex number,
00727                         then only add that name type. */
00728                 if((ptr1 = strchr_m(name, '#')) != NULL) {
00729                         char *endptr;
00730                         ptr1++;
00731 
00732                         *name_type = (int)strtol(ptr1, &endptr, 16);
00733                         if(!*ptr1 || (endptr == ptr1)) {
00734                                 DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
00735                                 continue;
00736                         }
00737 
00738                         *(--ptr1) = '\0'; /* Truncate at the '#' */
00739                 }
00740 
00741                 return True;
00742         }
00743 
00744         return False;
00745 }

void endlmhosts ( XFILE fp  ) 

namequery.c751 行で定義されています。

参照先 fpx_fclose().

参照元 load_lmhosts_file()resolve_lmhosts().

00752 {
00753         x_fclose(fp);
00754 }

static BOOL convert_ip2service ( struct ip_service **  return_iplist,
struct in_addr *  ip_list,
int  count 
) [static]

namequery.c761 行で定義されています。

参照元 name_resolve_bcast()resolve_wins().

00762 {
00763         int i;
00764 
00765         if ( count==0 || !ip_list )
00766                 return False;
00767                 
00768         /* copy the ip address; port will be PORT_NONE */
00769         if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
00770                 DEBUG(0,("convert_ip2service: malloc failed for %d enetries!\n", count ));
00771                 return False;
00772         }
00773         
00774         for ( i=0; i<count; i++ ) {
00775                 (*return_iplist)[i].ip   = ip_list[i];
00776                 (*return_iplist)[i].port = PORT_NONE;
00777         }
00778 
00779         return True;
00780 }       

BOOL name_resolve_bcast ( const char *  name,
int  name_type,
struct ip_service **  return_iplist,
int *  return_count 
)

namequery.c785 行で定義されています。

参照先 convert_ip2service()flagsiface_count()iface_n_bcast()interpret_addr()name_query()open_socket_in()set_socket_options().

参照元 get_ipc_connect_master_ip_bcast()internal_resolve_name()smbc_opendir_ctx().

00787 {
00788         int sock, i;
00789         int num_interfaces = iface_count();
00790         struct in_addr *ip_list;
00791         BOOL ret;
00792 
00793         if (lp_disable_netbios()) {
00794                 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
00795                 return False;
00796         }
00797 
00798         *return_iplist = NULL;
00799         *return_count = 0;
00800         
00801         /*
00802          * "bcast" means do a broadcast lookup on all the local interfaces.
00803          */
00804 
00805         DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
00806 
00807         sock = open_socket_in( SOCK_DGRAM, 0, 3,
00808                                interpret_addr(lp_socket_address()), True );
00809 
00810         if (sock == -1) return False;
00811 
00812         set_socket_options(sock,"SO_BROADCAST");
00813         /*
00814          * Lookup the name on all the interfaces, return on
00815          * the first successful match.
00816          */
00817         for( i = num_interfaces-1; i >= 0; i--) {
00818                 struct in_addr sendto_ip;
00819                 int flags;
00820                 /* Done this way to fix compiler error on IRIX 5.x */
00821                 sendto_ip = *iface_n_bcast(i);
00822                 ip_list = name_query(sock, name, name_type, True, 
00823                                     True, sendto_ip, return_count, &flags, NULL);
00824                 if( ip_list ) 
00825                         goto success;
00826         }
00827         
00828         /* failed - no response */
00829         
00830         close(sock);
00831         return False;
00832         
00833 success:
00834         ret = True;
00835         if ( !convert_ip2service(return_iplist, ip_list, *return_count) )
00836                 ret = False;
00837         
00838         SAFE_FREE( ip_list );
00839         close(sock);
00840         return ret;
00841 }

BOOL resolve_wins ( const char *  name,
int  name_type,
struct ip_service **  return_iplist,
int *  return_count 
)

namequery.c847 行で定義されています。

参照先 convert_ip2service()flagsglobal_in_nmbdinterpret_addr2()ismyip()name_query()open_socket_in()twins_srv_count()wins_srv_count_tag()wins_srv_died()wins_srv_ip_tag()wins_srv_is_dead()wins_srv_tags()wins_srv_tags_free().

参照元 internal_resolve_name()lookup_byname_backend().

00849 {
00850         int sock, t, i;
00851         char **wins_tags;
00852         struct in_addr src_ip, *ip_list = NULL;
00853         BOOL ret;
00854 
00855         if (lp_disable_netbios()) {
00856                 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
00857                 return False;
00858         }
00859 
00860         *return_iplist = NULL;
00861         *return_count = 0;
00862         
00863         DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
00864 
00865         if (wins_srv_count() < 1) {
00866                 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
00867                 return False;
00868         }
00869 
00870         /* we try a lookup on each of the WINS tags in turn */
00871         wins_tags = wins_srv_tags();
00872 
00873         if (!wins_tags) {
00874                 /* huh? no tags?? give up in disgust */
00875                 return False;
00876         }
00877 
00878         /* the address we will be sending from */
00879         src_ip = *interpret_addr2(lp_socket_address());
00880 
00881         /* in the worst case we will try every wins server with every
00882            tag! */
00883         for (t=0; wins_tags && wins_tags[t]; t++) {
00884                 int srv_count = wins_srv_count_tag(wins_tags[t]);
00885                 for (i=0; i<srv_count; i++) {
00886                         struct in_addr wins_ip;
00887                         int flags;
00888                         BOOL timed_out;
00889 
00890                         wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
00891 
00892                         if (global_in_nmbd && ismyip(wins_ip)) {
00893                                 /* yikes! we'll loop forever */
00894                                 continue;
00895                         }
00896 
00897                         /* skip any that have been unresponsive lately */
00898                         if (wins_srv_is_dead(wins_ip, src_ip)) {
00899                                 continue;
00900                         }
00901 
00902                         DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", inet_ntoa(wins_ip), wins_tags[t]));
00903 
00904                         sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True);
00905                         if (sock == -1) {
00906                                 continue;
00907                         }
00908 
00909                         ip_list = name_query(sock,name,name_type, False, 
00910                                                     True, wins_ip, return_count, &flags, 
00911                                                     &timed_out);
00912                                                     
00913                         /* exit loop if we got a list of addresses */
00914                         
00915                         if ( ip_list ) 
00916                                 goto success;
00917                                 
00918                         close(sock);
00919 
00920                         if (timed_out) {
00921                                 /* Timed out wating for WINS server to respond.  Mark it dead. */
00922                                 wins_srv_died(wins_ip, src_ip);
00923                         } else {
00924                                 /* The name definately isn't in this
00925                                    group of WINS servers. goto the next group  */
00926                                 break;
00927                         }
00928                 }
00929         }
00930 
00931         wins_srv_tags_free(wins_tags);
00932         return False;
00933 
00934 success:
00935         ret = True;
00936         if ( !convert_ip2service( return_iplist, ip_list, *return_count ) )
00937                 ret = False;
00938         
00939         SAFE_FREE( ip_list );
00940         wins_srv_tags_free(wins_tags);
00941         close(sock);
00942         
00943         return ret;
00944 }

static BOOL resolve_lmhosts ( const char *  name,
int  name_type,
struct ip_service **  return_iplist,
int *  return_count 
) [static]

namequery.c950 行で定義されています。

参照先 dyn_LMHOSTSFILEendlmhosts()fpgetlmhostsent()resultstartlmhosts()strequal().

参照元 internal_resolve_name().

00952 {
00953         /*
00954          * "lmhosts" means parse the local lmhosts file.
00955          */
00956         
00957         XFILE *fp;
00958         pstring lmhost_name;
00959         int name_type2;
00960         struct in_addr return_ip;
00961         BOOL result = False;
00962 
00963         *return_iplist = NULL;
00964         *return_count = 0;
00965 
00966         DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
00967 
00968         fp = startlmhosts(dyn_LMHOSTSFILE);
00969 
00970         if ( fp == NULL )
00971                 return False;
00972 
00973         while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) 
00974         {
00975 
00976                 if (!strequal(name, lmhost_name))
00977                         continue;
00978 
00979                 if ((name_type2 != -1) && (name_type != name_type2))
00980                         continue;
00981 
00982                 *return_iplist = SMB_REALLOC_ARRAY((*return_iplist), struct ip_service,
00983                                         (*return_count)+1);
00984 
00985                 if ((*return_iplist) == NULL) {
00986                         endlmhosts(fp);
00987                         DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
00988                         return False;
00989                 }
00990 
00991                 (*return_iplist)[*return_count].ip   = return_ip;
00992                 (*return_iplist)[*return_count].port = PORT_NONE;
00993                 *return_count += 1;
00994 
00995                 /* we found something */
00996                 result = True;
00997 
00998                 /* Multiple names only for DC lookup */
00999                 if (name_type != 0x1c)
01000                         break;
01001         }
01002 
01003         endlmhosts(fp);
01004 
01005         return result;
01006 }

static BOOL resolve_hosts ( const char *  name,
int  name_type,
struct ip_service **  return_iplist,
int *  return_count 
) [static]

namequery.c1013 行で定義されています。

参照先 sys_gethostbyname().

参照元 internal_resolve_name().

01015 {
01016         /*
01017          * "host" means do a localhost, or dns lookup.
01018          */
01019         struct hostent *hp;
01020         
01021         if ( name_type != 0x20 && name_type != 0x0) {
01022                 DEBUG(5, ("resolve_hosts: not appropriate for name type <0x%x>\n", name_type));
01023                 return False;
01024         }
01025 
01026         *return_iplist = NULL;
01027         *return_count = 0;
01028 
01029         DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n", name, name_type));
01030         
01031         if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
01032                 struct in_addr return_ip;
01033                 putip((char *)&return_ip,(char *)hp->h_addr);
01034                 *return_iplist = SMB_MALLOC_P(struct ip_service);
01035                 if(*return_iplist == NULL) {
01036                         DEBUG(3,("resolve_hosts: malloc fail !\n"));
01037                         return False;
01038                 }
01039                 (*return_iplist)->ip   = return_ip;
01040                 (*return_iplist)->port = PORT_NONE;
01041                 *return_count = 1;
01042                 return True;
01043         }
01044         return False;
01045 }

static BOOL resolve_ads ( const char *  name,
int  name_type,
const char *  sitename,
struct ip_service **  return_iplist,
int *  return_count 
) [static]

namequery.c1051 行で定義されています。

参照先 ads_dns_query_dcs()ads_dns_query_kdcs()ctxinterpret_addr2()ip_service::ipdns_rr_srv::ipsis_zero_ip()dns_rr_srv::num_ipsdns_rr_srv::portip_service::portstatustalloc_init().

参照元 internal_resolve_name().

01054 {
01055         int                     i, j;
01056         NTSTATUS                status;
01057         TALLOC_CTX              *ctx;
01058         struct dns_rr_srv       *dcs = NULL;
01059         int                     numdcs = 0;
01060         int                     numaddrs = 0;
01061 
01062         if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE))
01063                 return False;
01064                 
01065         DEBUG(5,("resolve_ads: Attempting to resolve DC's for %s using DNS\n",
01066                 name));
01067                         
01068         if ( (ctx = talloc_init("resolve_ads")) == NULL ) {
01069                 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
01070                 return False;
01071         }
01072 
01073         if (name_type == KDC_NAME_TYPE) {
01074                 status = ads_dns_query_kdcs(ctx, name, sitename, &dcs, &numdcs);
01075         } else {
01076                 status = ads_dns_query_dcs(ctx, name, sitename, &dcs, &numdcs);
01077         }
01078         if ( !NT_STATUS_IS_OK( status ) ) {
01079                 talloc_destroy(ctx);
01080                 return False;
01081         }
01082 
01083         for (i=0;i<numdcs;i++) {
01084                 numaddrs += MAX(dcs[i].num_ips,1);
01085         }
01086                 
01087         if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) == NULL ) {
01088                 DEBUG(0,("resolve_ads: malloc failed for %d entries\n", numaddrs ));
01089                 talloc_destroy(ctx);
01090                 return False;
01091         }
01092         
01093         /* now unroll the list of IP addresses */
01094 
01095         *return_count = 0;
01096         i = 0;
01097         j = 0;
01098         while ( i < numdcs && (*return_count<numaddrs) ) {
01099                 struct ip_service *r = &(*return_iplist)[*return_count];
01100 
01101                 r->port = dcs[i].port;
01102                 
01103                 /* If we don't have an IP list for a name, lookup it up */
01104                 
01105                 if ( !dcs[i].ips ) {
01106                         r->ip = *interpret_addr2(dcs[i].hostname);
01107                         i++;
01108                         j = 0;
01109                 } else {
01110                         /* use the IP addresses from the SRV sresponse */
01111                         
01112                         if ( j >= dcs[i].num_ips ) {
01113                                 i++;
01114                                 j = 0;
01115                                 continue;
01116                         }
01117                         
01118                         r->ip = dcs[i].ips[j];
01119                         j++;
01120                 }
01121                         
01122                 /* make sure it is a valid IP.  I considered checking the negative
01123                    connection cache, but this is the wrong place for it.  Maybe only
01124                    as a hac.  After think about it, if all of the IP addresses retuend
01125                    from DNS are dead, what hope does a netbios name lookup have?
01126                    The standard reason for falling back to netbios lookups is that 
01127                    our DNS server doesn't know anything about the DC's   -- jerry */    
01128                            
01129                 if ( ! is_zero_ip(r->ip) )
01130                         (*return_count)++;
01131         }
01132                 
01133         talloc_destroy(ctx);
01134         return True;
01135 }

BOOL internal_resolve_name ( const char *  name,
int  name_type,
const char *  sitename,
struct ip_service **  return_iplist,
int *  return_count,
const char *  resolve_order 
)

namequery.c1148 行で定義されています。

参照先 DEBUGLEVELip_service::ipis_ipaddress()name_resolve_bcast()namecache_fetch()namecache_store()next_token()portremove_duplicate_addrs2()resolve_ads()resolve_hosts()resolve_lmhosts()resolve_wins()resultstrequal().

参照元 find_master_ip()get_dc_list()get_pdc_ip()resolve_name().

01152 {
01153         pstring name_resolve_list;
01154         fstring tok;
01155         const char *ptr;
01156         BOOL allones = (strcmp(name,"255.255.255.255") == 0);
01157         BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
01158         BOOL is_address = is_ipaddress(name);
01159         BOOL result = False;
01160         int i;
01161 
01162         *return_iplist = NULL;
01163         *return_count = 0;
01164 
01165         DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
01166                         name, name_type, sitename ? sitename : NULL));
01167 
01168         if (allzeros || allones || is_address) {
01169   
01170                 if ( (*return_iplist = SMB_MALLOC_P(struct ip_service)) == NULL ) {
01171                         DEBUG(0,("internal_resolve_name: malloc fail !\n"));
01172                         return False;
01173                 }
01174         
01175                 if(is_address) { 
01176                         /* ignore the port here */
01177                         (*return_iplist)->port = PORT_NONE;
01178                 
01179                         /* if it's in the form of an IP address then get the lib to interpret it */
01180                         if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){
01181                                 DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
01182                                 SAFE_FREE(*return_iplist);
01183                                 return False;
01184                         }
01185                 } else {
01186                         (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0;
01187                 }
01188                 *return_count = 1;
01189                 return True;
01190         }
01191   
01192         /* Check name cache */
01193 
01194         if (namecache_fetch(name, name_type, return_iplist, return_count)) {
01195                 /* This could be a negative response */
01196                 return (*return_count > 0);
01197         }
01198 
01199         /* set the name resolution order */
01200 
01201         if ( strcmp( resolve_order, "NULL") == 0 ) {
01202                 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
01203                 return False;
01204         }
01205   
01206         if ( !resolve_order ) {
01207                 pstrcpy(name_resolve_list, lp_name_resolve_order());
01208         } else {
01209                 pstrcpy(name_resolve_list, resolve_order);
01210         }
01211 
01212         if ( !name_resolve_list[0] ) {
01213                 ptr = "host";
01214         } else {
01215                 ptr = name_resolve_list;
01216         }
01217 
01218         /* iterate through the name resolution backends */
01219   
01220         while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
01221                 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
01222                         if (resolve_hosts(name, name_type, return_iplist, return_count)) {
01223                                 result = True;
01224                                 goto done;
01225                         }
01226                 } else if(strequal( tok, "kdc")) {
01227                         /* deal with KDC_NAME_TYPE names here.  This will result in a
01228                                 SRV record lookup */
01229                         if (resolve_ads(name, KDC_NAME_TYPE, sitename, return_iplist, return_count)) {
01230                                 result = True;
01231                                 /* Ensure we don't namecache this with the KDC port. */
01232                                 name_type = KDC_NAME_TYPE;
01233                                 goto done;
01234                         }
01235                 } else if(strequal( tok, "ads")) {
01236                         /* deal with 0x1c names here.  This will result in a
01237                                 SRV record lookup */
01238                         if (resolve_ads(name, name_type, sitename, return_iplist, return_count)) {
01239                                 result = True;
01240                                 goto done;
01241                         }
01242                 } else if(strequal( tok, "lmhosts")) {
01243                         if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
01244                                 result = True;
01245                                 goto done;
01246                         }
01247                 } else if(strequal( tok, "wins")) {
01248                         /* don't resolve 1D via WINS */
01249                         if (name_type != 0x1D && resolve_wins(name, name_type, return_iplist, return_count)) {
01250                                 result = True;
01251                                 goto done;
01252                         }
01253                 } else if(strequal( tok, "bcast")) {
01254                         if (name_resolve_bcast(name, name_type, return_iplist, return_count)) {
01255                                 result = True;
01256                                 goto done;
01257                         }
01258                 } else {
01259                         DEBUG(0,("resolve_name: unknown name switch type %s\n", tok));
01260                 }
01261         }
01262 
01263         /* All of the resolve_* functions above have returned false. */
01264 
01265         SAFE_FREE(*return_iplist);
01266         *return_count = 0;
01267 
01268         return False;
01269 
01270   done:
01271 
01272         /* Remove duplicate entries.  Some queries, notably #1c (domain
01273         controllers) return the PDC in iplist[0] and then all domain
01274         controllers including the PDC in iplist[1..n].  Iterating over
01275         the iplist when the PDC is down will cause two sets of timeouts. */
01276 
01277         if ( *return_count ) {
01278                 *return_count = remove_duplicate_addrs2( *return_iplist, *return_count );
01279         }
01280  
01281         /* Save in name cache */
01282         if ( DEBUGLEVEL >= 100 ) {
01283                 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
01284                         DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name,
01285                                 name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
01286         }
01287    
01288         namecache_store(name, name_type, *return_count, *return_iplist);
01289 
01290         /* Display some debugging info */
01291 
01292         if ( DEBUGLEVEL >= 10 ) {
01293                 DEBUG(10, ("internal_resolve_name: returning %d addresses: ", *return_count));
01294 
01295                 for (i = 0; i < *return_count; i++) {
01296                         DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
01297                 }
01298                 DEBUG(10, ("\n"));
01299         }
01300   
01301         return result;
01302 }

BOOL resolve_name ( const char *  name,
struct in_addr *  return_ip,
int  name_type 
)

namequery.c1311 行で定義されています。

参照先 internal_resolve_name()interpret_addr2()ip_service::ipis_ipaddress()sitename_fetch().

参照元 cli_connect()cli_get_backup_list()cm_open_connection()fetch_domain_sid()get_dc_list()get_dc_name_via_netlogon()net_ads_printer_publish()net_find_server()net_lookup_host()print_ldap_srvlist()remote_password_change()server_cryptkey()smbc_opendir_ctx()spoolss_connect_to_client()start_filter().

01312 {
01313         struct ip_service *ip_list = NULL;
01314         char *sitename = sitename_fetch(lp_realm()); /* wild guess */
01315         int count = 0;
01316 
01317         if (is_ipaddress(name)) {
01318                 *return_ip = *interpret_addr2(name);
01319                 SAFE_FREE(sitename);
01320                 return True;
01321         }
01322 
01323         if (internal_resolve_name(name, name_type, sitename, &ip_list, &count, lp_name_resolve_order())) {
01324                 int i;
01325                 
01326                 /* only return valid addresses for TCP connections */
01327                 for (i=0; i<count; i++) {
01328                         char *ip_str = inet_ntoa(ip_list[i].ip);
01329                         if (ip_str &&
01330                             strcmp(ip_str, "255.255.255.255") != 0 &&
01331                             strcmp(ip_str, "0.0.0.0") != 0) 
01332                         {
01333                                 *return_ip = ip_list[i].ip;
01334                                 SAFE_FREE(ip_list);
01335                                 SAFE_FREE(sitename);
01336                                 return True;
01337                         }
01338                 }
01339         }
01340         
01341         SAFE_FREE(ip_list);
01342         SAFE_FREE(sitename);
01343         return False;
01344 }

BOOL find_master_ip ( const char *  group,
struct in_addr *  master_ip 
)

namequery.c1350 行で定義されています。

参照先 internal_resolve_name()ip_service::ip.

参照元 get_ipc_connect_master_ip()get_servers()get_workgroups()net_lookup_master()net_time()smbc_opendir_ctx().

01351 {
01352         struct ip_service *ip_list = NULL;
01353         int count = 0;
01354 
01355         if (lp_disable_netbios()) {
01356                 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
01357                 return False;
01358         }
01359 
01360         if (internal_resolve_name(group, 0x1D, NULL, &ip_list, &count, lp_name_resolve_order())) {
01361                 *master_ip = ip_list[0].ip;
01362                 SAFE_FREE(ip_list);
01363                 return True;
01364         }
01365         if(internal_resolve_name(group, 0x1B, NULL, &ip_list, &count, lp_name_resolve_order())) {
01366                 *master_ip = ip_list[0].ip;
01367                 SAFE_FREE(ip_list);
01368                 return True;
01369         }
01370 
01371         SAFE_FREE(ip_list);
01372         return False;
01373 }

BOOL get_pdc_ip ( const char *  domain,
struct in_addr *  ip 
)

namequery.c1380 行で定義されています。

参照先 internal_resolve_name()ip_service::ipsort_ip_list2().

参照元 change_trust_account_password()net_find_pdc()net_find_server()net_lookup_dc()net_lookup_ldap().

01381 {
01382         struct ip_service *ip_list = NULL;
01383         int count = 0;
01384 
01385         /* Look up #1B name */
01386 
01387         if (!internal_resolve_name(domain, 0x1b, NULL, &ip_list, &count, lp_name_resolve_order())) {
01388                 return False;
01389         }
01390 
01391         /* if we get more than 1 IP back we have to assume it is a
01392            multi-homed PDC and not a mess up */
01393 
01394         if ( count > 1 ) {
01395                 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));             
01396                 sort_ip_list2( ip_list, count );
01397         }
01398 
01399         *ip = ip_list[0].ip;
01400         
01401         SAFE_FREE(ip_list);
01402 
01403         return True;
01404 }

static NTSTATUS get_dc_list ( const char *  domain,
const char *  sitename,
struct ip_service **  ip_list,
int *  count,
enum dc_lookup_type  lookup_type,
int *  ordered 
) [static]

namequery.c1415 行で定義されています。

参照先 check_negative_conn_cache()DC_ADS_ONLYDC_KDC_ONLYDEBUGLEVELinternal_resolve_name()ip_service::iplp_workgroup()namenext_token()ip_service::portportpstr_sprintf()remove_duplicate_addrs2()resolve_name()saf_fetch()SEC_ADSstatusstrequal()strlower_m().

参照元 get_kdc_list()get_sorted_dc_list().

01417 {
01418         fstring resolve_order;
01419         char *saf_servername;
01420         pstring pserver;
01421         const char *p;
01422         char *port_str;
01423         int port;
01424         fstring name;
01425         int num_addresses = 0;
01426         int  local_count, i, j;
01427         struct ip_service *return_iplist = NULL;
01428         struct ip_service *auto_ip_list = NULL;
01429         BOOL done_auto_lookup = False;
01430         int auto_count = 0;
01431         NTSTATUS status;
01432 
01433         *ip_list = NULL;
01434         *count = 0;
01435 
01436         *ordered = False;
01437 
01438         /* if we are restricted to solely using DNS for looking
01439            up a domain controller, make sure that host lookups
01440            are enabled for the 'name resolve order'.  If host lookups
01441            are disabled and ads_only is True, then set the string to
01442            NULL. */
01443 
01444         fstrcpy( resolve_order, lp_name_resolve_order() );
01445         strlower_m( resolve_order );
01446         if ( lookup_type == DC_ADS_ONLY)  {
01447                 if ( strstr( resolve_order, "host" ) ) {
01448                         fstrcpy( resolve_order, "ads" );
01449 
01450                         /* DNS SRV lookups used by the ads resolver
01451                            are already sorted by priority and weight */
01452                         *ordered = True;
01453                 } else {
01454                         fstrcpy( resolve_order, "NULL" );
01455                 }
01456         } else if (lookup_type == DC_KDC_ONLY) {
01457                 /* DNS SRV lookups used by the ads/kdc resolver
01458                    are already sorted by priority and weight */
01459                 *ordered = True;
01460                 fstrcpy( resolve_order, "kdc" );
01461         }
01462 
01463         /* fetch the server we have affinity for.  Add the 
01464            'password server' list to a search for our domain controllers */
01465         
01466         saf_servername = saf_fetch( domain);
01467         
01468         if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) {
01469                 pstr_sprintf( pserver, "%s, %s", 
01470                         saf_servername ? saf_servername : "",
01471                         lp_passwordserver() );
01472         } else {
01473                 pstr_sprintf( pserver, "%s, *", 
01474                         saf_servername ? saf_servername : "" );
01475         }
01476 
01477         SAFE_FREE( saf_servername );
01478 
01479         /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
01480 
01481         if ( !*pserver ) {
01482                 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
01483                 /* TODO: change return type of internal_resolve_name to
01484                  * NTSTATUS */
01485                 if (internal_resolve_name(domain, 0x1C, sitename, ip_list, count,
01486                                           resolve_order)) {
01487                         status = NT_STATUS_OK;
01488                         goto out;
01489                 } else {
01490                         status = NT_STATUS_NO_LOGON_SERVERS;
01491                         goto out;
01492                 }
01493         }
01494 
01495         DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
01496         
01497         /*
01498          * if '*' appears in the "password server" list then add
01499          * an auto lookup to the list of manually configured
01500          * DC's.  If any DC is listed by name, then the list should be 
01501          * considered to be ordered 
01502          */
01503 
01504         p = pserver;
01505         while (next_token(&p,name,LIST_SEP,sizeof(name))) {
01506                 if (!done_auto_lookup && strequal(name, "*")) {
01507                         if (internal_resolve_name(domain, 0x1C, sitename, &auto_ip_list,
01508                                                   &auto_count, resolve_order))
01509                                 num_addresses += auto_count;
01510                         done_auto_lookup = True;
01511                         DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
01512                 } else  {
01513                         num_addresses++;
01514                 }
01515         }
01516 
01517         /* if we have no addresses and haven't done the auto lookup, then
01518            just return the list of DC's.  Or maybe we just failed. */
01519                    
01520         if ( (num_addresses == 0) ) {
01521                 if ( done_auto_lookup ) {
01522                         DEBUG(4,("get_dc_list: no servers found\n")); 
01523                         status = NT_STATUS_NO_LOGON_SERVERS;
01524                         goto out;
01525                 }
01526                 if (internal_resolve_name(domain, 0x1C, sitename, ip_list, count,
01527                                           resolve_order)) {
01528                         status = NT_STATUS_OK;
01529                         goto out;
01530                 } else {
01531                         status = NT_STATUS_NO_LOGON_SERVERS;
01532                         goto out;
01533                 }
01534         }
01535 
01536         if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) {
01537                 DEBUG(3,("get_dc_list: malloc fail !\n"));
01538                 status = NT_STATUS_NO_MEMORY;
01539                 goto out;
01540         }
01541 
01542         p = pserver;
01543         local_count = 0;
01544 
01545         /* fill in the return list now with real IP's */
01546                                 
01547         while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
01548                 struct in_addr name_ip;
01549                         
01550                 /* copy any addersses from the auto lookup */
01551                         
01552                 if ( strequal(name, "*") ) {
01553                         for ( j=0; j<auto_count; j++ ) {
01554                                 /* Check for and don't copy any known bad DC IP's. */
01555                                 if(!NT_STATUS_IS_OK(check_negative_conn_cache(domain, 
01556                                                 inet_ntoa(auto_ip_list[j].ip)))) {
01557                                         DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",
01558                                                 inet_ntoa(auto_ip_list[j].ip) ));
01559                                         continue;
01560                                 }
01561                                 return_iplist[local_count].ip   = auto_ip_list[j].ip;
01562                                 return_iplist[local_count].port = auto_ip_list[j].port;
01563                                 local_count++;
01564                         }
01565                         continue;
01566                 }
01567                         
01568                         
01569                 /* added support for address:port syntax for ads (not that I think 
01570                    anyone will ever run the LDAP server in an AD domain on something 
01571                    other than port 389 */
01572                         
01573                 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
01574                 if ( (port_str=strchr(name, ':')) != NULL ) {
01575                         *port_str = '\0';
01576                         port_str++;
01577                         port = atoi( port_str );
01578                 }
01579 
01580                 /* explicit lookup; resolve_name() will handle names & IP addresses */
01581                 if ( resolve_name( name, &name_ip, 0x20 ) ) {
01582 
01583                         /* Check for and don't copy any known bad DC IP's. */
01584                         if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain, inet_ntoa(name_ip))) ) {
01585                                 DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",name ));
01586                                 continue;
01587                         }
01588 
01589                         return_iplist[local_count].ip   = name_ip;
01590                         return_iplist[local_count].port = port;
01591                         local_count++;
01592                         *ordered = True;
01593                 }
01594         }
01595                                 
01596         /* need to remove duplicates in the list if we have any 
01597            explicit password servers */
01598            
01599         if ( local_count ) {
01600                 local_count = remove_duplicate_addrs2( return_iplist, local_count );
01601         }
01602                 
01603         if ( DEBUGLEVEL >= 4 ) {
01604                 DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count, 
01605                         *ordered ? "":"un"));
01606                 DEBUG(4,("get_dc_list: "));
01607                 for ( i=0; i<local_count; i++ )
01608                         DEBUGADD(4,("%s:%d ", inet_ntoa(return_iplist[i].ip), return_iplist[i].port ));
01609                 DEBUGADD(4,("\n"));
01610         }
01611                         
01612         *ip_list = return_iplist;
01613         *count = local_count;
01614 
01615         status = ( *count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS );
01616 
01617   out:
01618 
01619         if (!NT_STATUS_IS_OK(status)) {
01620                 SAFE_FREE(return_iplist);
01621                 *ip_list = NULL;
01622                 *count = 0;
01623         }
01624 
01625         SAFE_FREE(auto_ip_list);
01626 
01627         return status;
01628 }

NTSTATUS get_sorted_dc_list ( const char *  domain,
const char *  sitename,
struct ip_service **  ip_list,
int *  count,
BOOL  ads_only 
)

namequery.c1634 行で定義されています。

参照先 DC_ADS_ONLYDC_NORMAL_LOOKUPget_dc_list()sort_ip_list2()status.

参照元 ads_find_dc()get_dcs()net_lookup_dc()rpc_dc_name().

01635 {
01636         BOOL ordered;
01637         NTSTATUS status;
01638         enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
01639 
01640         DEBUG(8,("get_sorted_dc_list: attempting lookup for name %s (sitename %s) "
01641                 "using [%s]\n",
01642                 domain,
01643                 sitename ? sitename : "NULL",
01644                 (ads_only ? "ads" : lp_name_resolve_order())));
01645         
01646         if (ads_only) {
01647                 lookup_type = DC_ADS_ONLY;
01648         }
01649 
01650         status = get_dc_list(domain, sitename, ip_list, count, lookup_type, &ordered);
01651         if (!NT_STATUS_IS_OK(status)) {
01652                 return status; 
01653         }
01654                 
01655         /* only sort if we don't already have an ordered list */
01656         if ( !ordered ) {
01657                 sort_ip_list2( *ip_list, *count );
01658         }
01659                 
01660         return NT_STATUS_OK;
01661 }

NTSTATUS get_kdc_list ( const char *  realm,
const char *  sitename,
struct ip_service **  ip_list,
int *  count 
)

namequery.c1667 行で定義されています。

参照先 DC_KDC_ONLYget_dc_list()sort_ip_list2()status.

参照元 get_kdc_ip_string()smb_krb5_locator_lookup().

01668 {
01669         BOOL ordered;
01670         NTSTATUS status;
01671 
01672         *count = 0;
01673         *ip_list = NULL;
01674 
01675         status = get_dc_list(realm, sitename, ip_list, count, DC_KDC_ONLY, &ordered);
01676 
01677         if (!NT_STATUS_IS_OK(status)) {
01678                 return status; 
01679         }
01680 
01681         /* only sort if we don't already have an ordered list */
01682         if ( !ordered ) {
01683                 sort_ip_list2( *ip_list, *count );
01684         }
01685 
01686         return NT_STATUS_OK;
01687 }


変数

BOOL global_in_nmbd = False

namequery.c24 行で定義されています。

参照元 main()resolve_wins().


Sambaに対してSat Aug 29 21:23:49 2009に生成されました。  doxygen 1.4.7