00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "includes.h"
00022
00023
00024 BOOL global_in_nmbd = False;
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #define SAFKEY_FMT "SAF/DOMAIN/%s"
00036 #define SAF_TTL 900
00037
00038 static char *saf_key(const char *domain)
00039 {
00040 char *keystr;
00041
00042 asprintf( &keystr, SAFKEY_FMT, strupper_static(domain) );
00043
00044 return keystr;
00045 }
00046
00047
00048
00049
00050 BOOL saf_store( const char *domain, const char *servername )
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 }
00082
00083 BOOL saf_delete( const char *domain )
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 }
00107
00108
00109
00110
00111 char *saf_fetch( const char *domain )
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 }
00141
00142
00143
00144
00145
00146 static int generate_trn_id(void)
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 }
00158
00159
00160
00161
00162
00163 static NODE_STATUS_STRUCT *parse_node_status(char *p, int *num_names, struct node_status_extra *extra)
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
00189
00190 if (extra) {
00191 memcpy(&extra->mac_addr, p, 6);
00192 }
00193 return ret;
00194 }
00195
00196
00197
00198
00199
00200
00201
00202 NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name,
00203 struct in_addr to_ip, int *num_names,
00204 struct node_status_extra *extra)
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
00269
00270
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 }
00283
00284
00285
00286
00287
00288
00289 BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, fstring name)
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
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
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
00331
00332
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 }
00351
00352
00353
00354
00355
00356 static int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
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
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 }
00382
00383
00384
00385
00386
00387 int ip_service_compare(struct ip_service *ip1, struct ip_service *ip2)
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 }
00402
00403
00404
00405
00406
00407
00408
00409 static void sort_ip_list(struct in_addr *iplist, int count)
00410 {
00411 if (count <= 1) {
00412 return;
00413 }
00414
00415 qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
00416 }
00417
00418 static void sort_ip_list2(struct ip_service *iplist, int count)
00419 {
00420 if (count <= 1) {
00421 return;
00422 }
00423
00424 qsort(iplist, count, sizeof(struct ip_service), QSORT_CAST ip_service_compare);
00425 }
00426
00427
00428
00429
00430
00431 static int remove_duplicate_addrs2( struct ip_service *iplist, int count )
00432 {
00433 int i, j;
00434
00435 DEBUG(10,("remove_duplicate_addrs2: looking for duplicate address/port pairs\n"));
00436
00437
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
00449
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 }
00462
00463
00464
00465
00466
00467
00468
00469
00470 struct in_addr *name_query(int fd,const char *name,int name_type,
00471 BOOL bcast,BOOL recurse,
00472 struct in_addr to_ip, int *count, int *flags,
00473 BOOL *timed_out)
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
00547
00548
00549 if( 0 == nmb2->header.opcode
00550 && !(bcast)
00551 && nmb2->header.rcode
00552 ) {
00553
00554 if( DEBUGLVL( 3 ) ) {
00555
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
00588
00589
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
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
00630
00631
00632
00633 if(!bcast && found)
00634 break;
00635 }
00636 }
00637
00638
00639
00640 if ( !found && timed_out ) {
00641 *timed_out = True;
00642 }
00643
00644
00645 sort_ip_list(ip_list, *count);
00646
00647 return ip_list;
00648 }
00649
00650
00651
00652
00653
00654 XFILE *startlmhosts(char *fname)
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 }
00664
00665
00666
00667
00668
00669 BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
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
00727
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';
00739 }
00740
00741 return True;
00742 }
00743
00744 return False;
00745 }
00746
00747
00748
00749
00750
00751 void endlmhosts(XFILE *fp)
00752 {
00753 x_fclose(fp);
00754 }
00755
00756
00757
00758
00759
00760
00761 static BOOL convert_ip2service( struct ip_service **return_iplist, struct in_addr *ip_list, int count )
00762 {
00763 int i;
00764
00765 if ( count==0 || !ip_list )
00766 return False;
00767
00768
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 }
00781
00782
00783
00784
00785 BOOL name_resolve_bcast(const char *name, int name_type,
00786 struct ip_service **return_iplist, int *return_count)
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
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
00815
00816
00817 for( i = num_interfaces-1; i >= 0; i--) {
00818 struct in_addr sendto_ip;
00819 int flags;
00820
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
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 }
00842
00843
00844
00845
00846
00847 BOOL resolve_wins(const char *name, int name_type,
00848 struct ip_service **return_iplist, int *return_count)
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
00871 wins_tags = wins_srv_tags();
00872
00873 if (!wins_tags) {
00874
00875 return False;
00876 }
00877
00878
00879 src_ip = *interpret_addr2(lp_socket_address());
00880
00881
00882
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
00894 continue;
00895 }
00896
00897
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
00914
00915 if ( ip_list )
00916 goto success;
00917
00918 close(sock);
00919
00920 if (timed_out) {
00921
00922 wins_srv_died(wins_ip, src_ip);
00923 } else {
00924
00925
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 }
00945
00946
00947
00948
00949
00950 static BOOL resolve_lmhosts(const char *name, int name_type,
00951 struct ip_service **return_iplist, int *return_count)
00952 {
00953
00954
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
00996 result = True;
00997
00998
00999 if (name_type != 0x1c)
01000 break;
01001 }
01002
01003 endlmhosts(fp);
01004
01005 return result;
01006 }
01007
01008
01009
01010
01011
01012
01013 static BOOL resolve_hosts(const char *name, int name_type,
01014 struct ip_service **return_iplist, int *return_count)
01015 {
01016
01017
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 }
01046
01047
01048
01049
01050
01051 static BOOL resolve_ads(const char *name, int name_type,
01052 const char *sitename,
01053 struct ip_service **return_iplist, int *return_count)
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
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
01104
01105 if ( !dcs[i].ips ) {
01106 r->ip = *interpret_addr2(dcs[i].hostname);
01107 i++;
01108 j = 0;
01109 } else {
01110
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
01123
01124
01125
01126
01127
01128
01129 if ( ! is_zero_ip(r->ip) )
01130 (*return_count)++;
01131 }
01132
01133 talloc_destroy(ctx);
01134 return True;
01135 }
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148 BOOL internal_resolve_name(const char *name, int name_type,
01149 const char *sitename,
01150 struct ip_service **return_iplist,
01151 int *return_count, const char *resolve_order)
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
01177 (*return_iplist)->port = PORT_NONE;
01178
01179
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
01193
01194 if (namecache_fetch(name, name_type, return_iplist, return_count)) {
01195
01196 return (*return_count > 0);
01197 }
01198
01199
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
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
01228
01229 if (resolve_ads(name, KDC_NAME_TYPE, sitename, return_iplist, return_count)) {
01230 result = True;
01231
01232 name_type = KDC_NAME_TYPE;
01233 goto done;
01234 }
01235 } else if(strequal( tok, "ads")) {
01236
01237
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
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
01264
01265 SAFE_FREE(*return_iplist);
01266 *return_count = 0;
01267
01268 return False;
01269
01270 done:
01271
01272
01273
01274
01275
01276
01277 if ( *return_count ) {
01278 *return_count = remove_duplicate_addrs2( *return_iplist, *return_count );
01279 }
01280
01281
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
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 }
01303
01304
01305
01306
01307
01308
01309
01310
01311 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
01312 {
01313 struct ip_service *ip_list = NULL;
01314 char *sitename = sitename_fetch(lp_realm());
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
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 }
01345
01346
01347
01348
01349
01350 BOOL find_master_ip(const char *group, struct in_addr *master_ip)
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 }
01374
01375
01376
01377
01378
01379
01380 BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
01381 {
01382 struct ip_service *ip_list = NULL;
01383 int count = 0;
01384
01385
01386
01387 if (!internal_resolve_name(domain, 0x1b, NULL, &ip_list, &count, lp_name_resolve_order())) {
01388 return False;
01389 }
01390
01391
01392
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 }
01405
01406
01407
01408 enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
01409
01410
01411
01412
01413
01414
01415 static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_service **ip_list,
01416 int *count, enum dc_lookup_type lookup_type, int *ordered)
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
01439
01440
01441
01442
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
01451
01452 *ordered = True;
01453 } else {
01454 fstrcpy( resolve_order, "NULL" );
01455 }
01456 } else if (lookup_type == DC_KDC_ONLY) {
01457
01458
01459 *ordered = True;
01460 fstrcpy( resolve_order, "kdc" );
01461 }
01462
01463
01464
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
01480
01481 if ( !*pserver ) {
01482 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
01483
01484
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
01499
01500
01501
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
01518
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
01546
01547 while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
01548 struct in_addr name_ip;
01549
01550
01551
01552 if ( strequal(name, "*") ) {
01553 for ( j=0; j<auto_count; j++ ) {
01554
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
01570
01571
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
01581 if ( resolve_name( name, &name_ip, 0x20 ) ) {
01582
01583
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
01597
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 }
01629
01630
01631
01632
01633
01634 NTSTATUS get_sorted_dc_list( const char *domain, const char *sitename, struct ip_service **ip_list, int *count, BOOL ads_only )
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
01656 if ( !ordered ) {
01657 sort_ip_list2( *ip_list, *count );
01658 }
01659
01660 return NT_STATUS_OK;
01661 }
01662
01663
01664
01665
01666
01667 NTSTATUS get_kdc_list( const char *realm, const char *sitename, struct ip_service **ip_list, int *count)
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
01682 if ( !ordered ) {
01683 sort_ip_list2( *ip_list, *count );
01684 }
01685
01686 return NT_STATUS_OK;
01687 }