2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1994-1998
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 /* nmbd.c sets this to True. */
23 BOOL global_in_nmbd = False;
25 /****************************
26 * SERVER AFFINITY ROUTINES *
27 ****************************/
29 /* Server affinity is the concept of preferring the last domain
30 controller with whom you had a successful conversation */
32 /****************************************************************************
33 ****************************************************************************/
34 #define SAFKEY_FMT "SAF/DOMAIN/%s"
37 static char *saf_key(const char *domain)
41 asprintf( &keystr, SAFKEY_FMT, strupper_static(domain) );
46 /****************************************************************************
47 ****************************************************************************/
49 BOOL saf_store( const char *domain, const char *servername )
55 if ( !domain || !servername ) {
56 DEBUG(2,("saf_store: Refusing to store empty domain or servername!\n"));
60 if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) {
61 DEBUG(0,("saf_store: refusing to store 0 length domain or servername!\n"));
65 if ( !gencache_init() )
68 key = saf_key( domain );
69 expire = time( NULL ) + SAF_TTL;
72 DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n",
73 domain, servername, (unsigned int)expire ));
75 ret = gencache_set( key, servername, expire );
82 BOOL saf_delete( const char *domain )
88 DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));
92 if ( !gencache_init() )
95 key = saf_key(domain);
96 ret = gencache_del(key);
99 DEBUG(10,("saf_delete: domain = [%s]\n", domain ));
107 /****************************************************************************
108 ****************************************************************************/
110 char *saf_fetch( const char *domain )
117 if ( !domain || strlen(domain) == 0) {
118 DEBUG(2,("saf_fetch: Empty domain name!\n"));
122 if ( !gencache_init() )
125 key = saf_key( domain );
127 ret = gencache_get( key, &server, &timeout );
132 DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n", domain ));
134 DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n",
141 /****************************************************************************
142 Generate a random trn_id.
143 ****************************************************************************/
145 static int generate_trn_id(void)
149 generate_random_buffer((uint8 *)&id, sizeof(id));
151 return id % (unsigned)0x7FFF;
154 /****************************************************************************
155 Parse a node status response into an array of structures.
156 ****************************************************************************/
158 static NODE_STATUS_STRUCT *parse_node_status(char *p, int *num_names, struct node_status_extra *extra)
160 NODE_STATUS_STRUCT *ret;
163 *num_names = CVAL(p,0);
168 ret = SMB_MALLOC_ARRAY(NODE_STATUS_STRUCT,*num_names);
173 for (i=0;i< *num_names;i++) {
174 StrnCpy(ret[i].name,p,15);
175 trim_char(ret[i].name,'\0',' ');
176 ret[i].type = CVAL(p,15);
177 ret[i].flags = p[16];
179 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name,
180 ret[i].type, ret[i].flags));
183 * Also, pick up the MAC address ...
186 memcpy(&extra->mac_addr, p, 6); /* Fill in the mac addr */
192 /****************************************************************************
193 Do a NBT node status query on an open socket and return an array of
194 structures holding the returned names or NULL if the query failed.
195 **************************************************************************/
197 NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name,
198 struct in_addr to_ip, int *num_names,
199 struct node_status_extra *extra)
203 int retry_time = 2000;
205 struct packet_struct p;
206 struct packet_struct *p2;
207 struct nmb_packet *nmb = &p.packet.nmb;
208 NODE_STATUS_STRUCT *ret;
212 nmb->header.name_trn_id = generate_trn_id();
213 nmb->header.opcode = 0;
214 nmb->header.response = False;
215 nmb->header.nm_flags.bcast = False;
216 nmb->header.nm_flags.recursion_available = False;
217 nmb->header.nm_flags.recursion_desired = False;
218 nmb->header.nm_flags.trunc = False;
219 nmb->header.nm_flags.authoritative = False;
220 nmb->header.rcode = 0;
221 nmb->header.qdcount = 1;
222 nmb->header.ancount = 0;
223 nmb->header.nscount = 0;
224 nmb->header.arcount = 0;
225 nmb->question.question_name = *name;
226 nmb->question.question_type = 0x21;
227 nmb->question.question_class = 0x1;
232 p.timestamp = time(NULL);
233 p.packet_type = NMB_PACKET;
237 if (!send_packet(&p))
243 struct timeval tval2;
244 GetTimeOfDay(&tval2);
245 if (TvalDiff(&tval,&tval2) > retry_time) {
248 if (!found && !send_packet(&p))
254 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
255 struct nmb_packet *nmb2 = &p2->packet.nmb;
256 debug_nmb_packet(p2);
258 if (nmb2->header.opcode != 0 ||
259 nmb2->header.nm_flags.bcast ||
260 nmb2->header.rcode ||
261 !nmb2->header.ancount ||
262 nmb2->answers->rr_type != 0x21) {
263 /* XXXX what do we do with this? could be a
264 redirect, but we'll discard it for the
270 ret = parse_node_status(&nmb2->answers->rdata[0], num_names, extra);
279 /****************************************************************************
280 Find the first type XX name in a node status reply - used for finding
281 a servers name given its IP. Return the matched name in *name.
282 **************************************************************************/
284 BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, fstring name)
286 NODE_STATUS_STRUCT *status = NULL;
287 struct nmb_name nname;
292 if (lp_disable_netbios()) {
293 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type));
297 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
298 q_type, inet_ntoa(to_ip)));
300 /* Check the cache first. */
302 if (namecache_status_fetch(q_name, q_type, type, to_ip, name))
305 sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True);
309 /* W2K PDC's seem not to respond to '*'#0. JRA */
310 make_nmb_name(&nname, q_name, q_type);
311 status = node_status_query(sock, &nname, to_ip, &count, NULL);
316 for (i=0;i<count;i++) {
317 if (status[i].type == type)
323 pull_ascii_nstring(name, sizeof(fstring), status[i].name);
325 /* Store the result in the cache. */
326 /* but don't store an entry for 0x1c names here. Here we have
327 a single host and DOMAIN<0x1c> names should be a list of hosts */
329 if ( q_type != 0x1c )
330 namecache_status_store(q_name, q_type, type, to_ip, name);
337 DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not "));
340 DEBUGADD(10, (", name %s ip address is %s", name, inet_ntoa(to_ip)));
348 comparison function used by sort_ip_list
351 static int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
353 int max_bits1=0, max_bits2=0;
354 int num_interfaces = iface_count();
357 for (i=0;i<num_interfaces;i++) {
360 ip = *iface_n_bcast(i);
361 bits1 = matching_quad_bits((uchar *)&ip1->s_addr, (uchar *)&ip.s_addr);
362 bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr);
363 max_bits1 = MAX(bits1, max_bits1);
364 max_bits2 = MAX(bits2, max_bits2);
367 /* bias towards directly reachable IPs */
368 if (iface_local(*ip1)) {
371 if (iface_local(*ip2)) {
375 return max_bits2 - max_bits1;
378 /*******************************************************************
379 compare 2 ldap IPs by nearness to our interfaces - used in qsort
380 *******************************************************************/
382 int ip_service_compare(struct ip_service *ip1, struct ip_service *ip2)
386 if ( (result = ip_compare(&ip1->ip, &ip2->ip)) != 0 )
389 if ( ip1->port > ip2->port )
392 if ( ip1->port < ip2->port )
399 sort an IP list so that names that are close to one of our interfaces
400 are at the top. This prevents the problem where a WINS server returns an IP that
401 is not reachable from our subnet as the first match
404 static void sort_ip_list(struct in_addr *iplist, int count)
410 qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare);
413 static void sort_ip_list2(struct ip_service *iplist, int count)
419 qsort(iplist, count, sizeof(struct ip_service), QSORT_CAST ip_service_compare);
422 /**********************************************************************
423 Remove any duplicate address/port pairs in the list
424 *********************************************************************/
426 static int remove_duplicate_addrs2( struct ip_service *iplist, int count )
430 DEBUG(10,("remove_duplicate_addrs2: looking for duplicate address/port pairs\n"));
432 /* one loop to remove duplicates */
433 for ( i=0; i<count; i++ ) {
434 if ( is_zero_ip(iplist[i].ip) )
437 for ( j=i+1; j<count; j++ ) {
438 if ( ip_service_equal(iplist[i], iplist[j]) )
439 zero_ip(&iplist[j].ip);
443 /* one loop to clean up any holes we left */
444 /* first ip should never be a zero_ip() */
445 for (i = 0; i<count; ) {
446 if ( is_zero_ip(iplist[i].ip) ) {
448 memmove(&iplist[i], &iplist[i+1], (count - i - 1)*sizeof(iplist[i]));
458 /****************************************************************************
459 Do a netbios name query to find someones IP.
460 Returns an array of IP addresses or NULL if none.
461 *count will be set to the number of addresses returned.
462 *timed_out is set if we failed by timing out
463 ****************************************************************************/
465 struct in_addr *name_query(int fd,const char *name,int name_type,
466 BOOL bcast,BOOL recurse,
467 struct in_addr to_ip, int *count, int *flags,
472 int retry_time = bcast?250:2000;
474 struct packet_struct p;
475 struct packet_struct *p2;
476 struct nmb_packet *nmb = &p.packet.nmb;
477 struct in_addr *ip_list = NULL;
479 if (lp_disable_netbios()) {
480 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type));
488 memset((char *)&p,'\0',sizeof(p));
492 nmb->header.name_trn_id = generate_trn_id();
493 nmb->header.opcode = 0;
494 nmb->header.response = False;
495 nmb->header.nm_flags.bcast = bcast;
496 nmb->header.nm_flags.recursion_available = False;
497 nmb->header.nm_flags.recursion_desired = recurse;
498 nmb->header.nm_flags.trunc = False;
499 nmb->header.nm_flags.authoritative = False;
500 nmb->header.rcode = 0;
501 nmb->header.qdcount = 1;
502 nmb->header.ancount = 0;
503 nmb->header.nscount = 0;
504 nmb->header.arcount = 0;
506 make_nmb_name(&nmb->question.question_name,name,name_type);
508 nmb->question.question_type = 0x20;
509 nmb->question.question_class = 0x1;
514 p.timestamp = time(NULL);
515 p.packet_type = NMB_PACKET;
519 if (!send_packet(&p))
525 struct timeval tval2;
527 GetTimeOfDay(&tval2);
528 if (TvalDiff(&tval,&tval2) > retry_time) {
531 if (!found && !send_packet(&p))
537 if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) {
538 struct nmb_packet *nmb2 = &p2->packet.nmb;
539 debug_nmb_packet(p2);
541 /* If we get a Negative Name Query Response from a WINS
542 * server, we should report it and give up.
544 if( 0 == nmb2->header.opcode /* A query response */
545 && !(bcast) /* from a WINS server */
546 && nmb2->header.rcode /* Error returned */
549 if( DEBUGLVL( 3 ) ) {
550 /* Only executed if DEBUGLEVEL >= 3 */
551 dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode );
552 switch( nmb2->header.rcode ) {
554 dbgtext( "Request was invalidly formatted.\n" );
557 dbgtext( "Problem with NBNS, cannot process name.\n");
560 dbgtext( "The name requested does not exist.\n" );
563 dbgtext( "Unsupported request error.\n" );
566 dbgtext( "Query refused error.\n" );
569 dbgtext( "Unrecognized error code.\n" );
577 if (nmb2->header.opcode != 0 ||
578 nmb2->header.nm_flags.bcast ||
579 nmb2->header.rcode ||
580 !nmb2->header.ancount) {
582 * XXXX what do we do with this? Could be a
583 * redirect, but we'll discard it for the
590 ip_list = SMB_REALLOC_ARRAY( ip_list, struct in_addr,
591 (*count) + nmb2->answers->rdlength/6 );
594 DEBUG(0,("name_query: Realloc failed.\n"));
599 DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip)));
600 for (i=0;i<nmb2->answers->rdlength/6;i++) {
601 putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]);
602 DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)])));
609 /* We add the flags back ... */
610 if (nmb2->header.response)
611 (*flags) |= NM_FLAGS_RS;
612 if (nmb2->header.nm_flags.authoritative)
613 (*flags) |= NM_FLAGS_AA;
614 if (nmb2->header.nm_flags.trunc)
615 (*flags) |= NM_FLAGS_TC;
616 if (nmb2->header.nm_flags.recursion_desired)
617 (*flags) |= NM_FLAGS_RD;
618 if (nmb2->header.nm_flags.recursion_available)
619 (*flags) |= NM_FLAGS_RA;
620 if (nmb2->header.nm_flags.bcast)
621 (*flags) |= NM_FLAGS_B;
624 * If we're doing a unicast lookup we only
625 * expect one reply. Don't wait the full 2
626 * seconds if we got one. JRA.
633 /* only set timed_out if we didn't fund what we where looking for*/
635 if ( !found && timed_out ) {
639 /* sort the ip list so we choose close servers first if possible */
640 sort_ip_list(ip_list, *count);
645 /********************************************************
646 Start parsing the lmhosts file.
647 *********************************************************/
649 XFILE *startlmhosts(const char *fname)
651 XFILE *fp = x_fopen(fname,O_RDONLY, 0);
653 DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n",
654 fname, strerror(errno)));
660 /********************************************************
661 Parse the next line in the lmhosts file.
662 *********************************************************/
664 BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
668 while(!x_feof(fp) && !x_ferror(fp)) {
669 pstring ip,flags,extra;
676 if (!fgets_slash(line,sizeof(pstring),fp)) {
690 if (next_token(&ptr,ip ,NULL,sizeof(ip)))
692 if (next_token(&ptr,name ,NULL, sizeof(pstring)))
694 if (next_token(&ptr,flags,NULL, sizeof(flags)))
696 if (next_token(&ptr,extra,NULL, sizeof(extra)))
702 if (count > 0 && count < 2) {
703 DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line));
708 DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n"));
712 DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags));
714 if (strchr_m(flags,'G') || strchr_m(flags,'S')) {
715 DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n"));
719 *ipaddr = *interpret_addr2(ip);
721 /* Extra feature. If the name ends in '#XX', where XX is a hex number,
722 then only add that name type. */
723 if((ptr1 = strchr_m(name, '#')) != NULL) {
727 *name_type = (int)strtol(ptr1, &endptr, 16);
728 if(!*ptr1 || (endptr == ptr1)) {
729 DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name));
733 *(--ptr1) = '\0'; /* Truncate at the '#' */
742 /********************************************************
743 Finish parsing the lmhosts file.
744 *********************************************************/
746 void endlmhosts(XFILE *fp)
751 /********************************************************
752 convert an array if struct in_addrs to struct ip_service
753 return False on failure. Port is set to PORT_NONE;
754 *********************************************************/
756 static BOOL convert_ip2service( struct ip_service **return_iplist, struct in_addr *ip_list, int count )
760 if ( count==0 || !ip_list )
763 /* copy the ip address; port will be PORT_NONE */
764 if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) {
765 DEBUG(0,("convert_ip2service: malloc failed for %d enetries!\n", count ));
769 for ( i=0; i<count; i++ ) {
770 (*return_iplist)[i].ip = ip_list[i];
771 (*return_iplist)[i].port = PORT_NONE;
776 /********************************************************
777 Resolve via "bcast" method.
778 *********************************************************/
780 NTSTATUS name_resolve_bcast(const char *name, int name_type,
781 struct ip_service **return_iplist,
785 int num_interfaces = iface_count();
786 struct in_addr *ip_list;
789 if (lp_disable_netbios()) {
790 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
791 return NT_STATUS_INVALID_PARAMETER;
794 *return_iplist = NULL;
798 * "bcast" means do a broadcast lookup on all the local interfaces.
801 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
803 sock = open_socket_in( SOCK_DGRAM, 0, 3,
804 interpret_addr(lp_socket_address()), True );
806 if (sock == -1) return NT_STATUS_UNSUCCESSFUL;
808 set_socket_options(sock,"SO_BROADCAST");
810 * Lookup the name on all the interfaces, return on
811 * the first successful match.
813 for( i = num_interfaces-1; i >= 0; i--) {
814 struct in_addr sendto_ip;
816 /* Done this way to fix compiler error on IRIX 5.x */
817 sendto_ip = *iface_n_bcast(i);
818 ip_list = name_query(sock, name, name_type, True,
819 True, sendto_ip, return_count, &flags, NULL);
824 /* failed - no response */
827 return NT_STATUS_UNSUCCESSFUL;
830 status = NT_STATUS_OK;
831 if ( !convert_ip2service(return_iplist, ip_list, *return_count) )
832 status = NT_STATUS_INVALID_PARAMETER;
834 SAFE_FREE( ip_list );
839 /********************************************************
840 Resolve via "wins" method.
841 *********************************************************/
843 NTSTATUS resolve_wins(const char *name, int name_type,
844 struct ip_service **return_iplist,
849 struct in_addr src_ip, *ip_list = NULL;
852 if (lp_disable_netbios()) {
853 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
854 return NT_STATUS_INVALID_PARAMETER;
857 *return_iplist = NULL;
860 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
862 if (wins_srv_count() < 1) {
863 DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n"));
864 return NT_STATUS_INVALID_PARAMETER;
867 /* we try a lookup on each of the WINS tags in turn */
868 wins_tags = wins_srv_tags();
871 /* huh? no tags?? give up in disgust */
872 return NT_STATUS_INVALID_PARAMETER;
875 /* the address we will be sending from */
876 src_ip = *interpret_addr2(lp_socket_address());
878 /* in the worst case we will try every wins server with every
880 for (t=0; wins_tags && wins_tags[t]; t++) {
881 int srv_count = wins_srv_count_tag(wins_tags[t]);
882 for (i=0; i<srv_count; i++) {
883 struct in_addr wins_ip;
887 wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip);
889 if (global_in_nmbd && ismyip(wins_ip)) {
890 /* yikes! we'll loop forever */
894 /* skip any that have been unresponsive lately */
895 if (wins_srv_is_dead(wins_ip, src_ip)) {
899 DEBUG(3,("resolve_wins: using WINS server %s and tag '%s'\n", inet_ntoa(wins_ip), wins_tags[t]));
901 sock = open_socket_in(SOCK_DGRAM, 0, 3, src_ip.s_addr, True);
906 ip_list = name_query(sock,name,name_type, False,
907 True, wins_ip, return_count, &flags,
910 /* exit loop if we got a list of addresses */
918 /* Timed out wating for WINS server to respond. Mark it dead. */
919 wins_srv_died(wins_ip, src_ip);
921 /* The name definately isn't in this
922 group of WINS servers. goto the next group */
928 wins_srv_tags_free(wins_tags);
929 return NT_STATUS_NO_LOGON_SERVERS;
932 status = NT_STATUS_OK;
933 if ( !convert_ip2service( return_iplist, ip_list, *return_count ) )
934 status = NT_STATUS_INVALID_PARAMETER;
936 SAFE_FREE( ip_list );
937 wins_srv_tags_free(wins_tags);
943 /********************************************************
944 Resolve via "lmhosts" method.
945 *********************************************************/
947 static NTSTATUS resolve_lmhosts(const char *name, int name_type,
948 struct ip_service **return_iplist,
952 * "lmhosts" means parse the local lmhosts file.
958 struct in_addr return_ip;
959 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
961 *return_iplist = NULL;
964 DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
966 fp = startlmhosts(dyn_LMHOSTSFILE);
969 return NT_STATUS_NO_SUCH_FILE;
971 while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip))
974 if (!strequal(name, lmhost_name))
977 if ((name_type2 != -1) && (name_type != name_type2))
980 *return_iplist = SMB_REALLOC_ARRAY((*return_iplist), struct ip_service,
983 if ((*return_iplist) == NULL) {
985 DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
986 return NT_STATUS_NO_MEMORY;
989 (*return_iplist)[*return_count].ip = return_ip;
990 (*return_iplist)[*return_count].port = PORT_NONE;
993 /* we found something */
994 status = NT_STATUS_OK;
996 /* Multiple names only for DC lookup */
997 if (name_type != 0x1c)
1007 /********************************************************
1008 Resolve via "hosts" method.
1009 *********************************************************/
1011 static NTSTATUS resolve_hosts(const char *name, int name_type,
1012 struct ip_service **return_iplist,
1016 * "host" means do a localhost, or dns lookup.
1020 if ( name_type != 0x20 && name_type != 0x0) {
1021 DEBUG(5, ("resolve_hosts: not appropriate for name type <0x%x>\n", name_type));
1022 return NT_STATUS_INVALID_PARAMETER;
1025 *return_iplist = NULL;
1028 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n", name, name_type));
1030 if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
1031 struct in_addr return_ip;
1032 putip((char *)&return_ip,(char *)hp->h_addr);
1033 *return_iplist = SMB_MALLOC_P(struct ip_service);
1034 if(*return_iplist == NULL) {
1035 DEBUG(3,("resolve_hosts: malloc fail !\n"));
1036 return NT_STATUS_NO_MEMORY;
1038 (*return_iplist)->ip = return_ip;
1039 (*return_iplist)->port = PORT_NONE;
1041 return NT_STATUS_OK;
1043 return NT_STATUS_UNSUCCESSFUL;
1046 /********************************************************
1047 Resolve via "ADS" method.
1048 *********************************************************/
1050 NTSTATUS resolve_ads(const char *name, int name_type,
1051 const char *sitename,
1052 struct ip_service **return_iplist,
1058 struct dns_rr_srv *dcs = NULL;
1062 if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE) &&
1063 (name_type != 0x1b)) {
1064 return NT_STATUS_INVALID_PARAMETER;
1067 if ( (ctx = talloc_init("resolve_ads")) == NULL ) {
1068 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
1069 return NT_STATUS_NO_MEMORY;
1072 switch (name_type) {
1074 DEBUG(5,("resolve_ads: Attempting to resolve "
1075 "PDC for %s using DNS\n", name));
1076 status = ads_dns_query_pdc(ctx, name, &dcs, &numdcs);
1080 DEBUG(5,("resolve_ads: Attempting to resolve "
1081 "DCs for %s using DNS\n", name));
1082 status = ads_dns_query_dcs(ctx, name, sitename, &dcs,
1086 DEBUG(5,("resolve_ads: Attempting to resolve "
1087 "KDCs for %s using DNS\n", name));
1088 status = ads_dns_query_kdcs(ctx, name, sitename, &dcs,
1092 status = NT_STATUS_INVALID_PARAMETER;
1096 if ( !NT_STATUS_IS_OK( status ) ) {
1097 talloc_destroy(ctx);
1101 for (i=0;i<numdcs;i++) {
1102 numaddrs += MAX(dcs[i].num_ips,1);
1105 if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) == NULL ) {
1106 DEBUG(0,("resolve_ads: malloc failed for %d entries\n", numaddrs ));
1107 talloc_destroy(ctx);
1108 return NT_STATUS_NO_MEMORY;
1111 /* now unroll the list of IP addresses */
1116 while ( i < numdcs && (*return_count<numaddrs) ) {
1117 struct ip_service *r = &(*return_iplist)[*return_count];
1119 r->port = dcs[i].port;
1121 /* If we don't have an IP list for a name, lookup it up */
1123 if ( !dcs[i].ips ) {
1124 r->ip = *interpret_addr2(dcs[i].hostname);
1128 /* use the IP addresses from the SRV sresponse */
1130 if ( j >= dcs[i].num_ips ) {
1136 r->ip = dcs[i].ips[j];
1140 /* make sure it is a valid IP. I considered checking the negative
1141 connection cache, but this is the wrong place for it. Maybe only
1142 as a hac. After think about it, if all of the IP addresses retuend
1143 from DNS are dead, what hope does a netbios name lookup have?
1144 The standard reason for falling back to netbios lookups is that
1145 our DNS server doesn't know anything about the DC's -- jerry */
1147 if ( ! is_zero_ip(r->ip) )
1151 talloc_destroy(ctx);
1152 return NT_STATUS_OK;
1155 /*******************************************************************
1156 Internal interface to resolve a name into an IP address.
1157 Use this function if the string is either an IP address, DNS
1158 or host name or NetBIOS name. This uses the name switch in the
1159 smb.conf to determine the order of name resolution.
1161 Added support for ip addr/port to support ADS ldap servers.
1162 the only place we currently care about the port is in the
1163 resolve_hosts() when looking up DC's via SRV RR entries in DNS
1164 **********************************************************************/
1166 NTSTATUS internal_resolve_name(const char *name, int name_type,
1167 const char *sitename,
1168 struct ip_service **return_iplist,
1169 int *return_count, const char *resolve_order)
1171 pstring name_resolve_list;
1174 BOOL allones = (strcmp(name,"255.255.255.255") == 0);
1175 BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
1176 BOOL is_address = is_ipaddress(name);
1177 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1180 *return_iplist = NULL;
1183 DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
1184 name, name_type, sitename ? sitename : NULL));
1186 if (allzeros || allones || is_address) {
1188 if ( (*return_iplist = SMB_MALLOC_P(struct ip_service)) == NULL ) {
1189 DEBUG(0,("internal_resolve_name: malloc fail !\n"));
1190 return NT_STATUS_NO_MEMORY;
1194 /* ignore the port here */
1195 (*return_iplist)->port = PORT_NONE;
1197 /* if it's in the form of an IP address then get the lib to interpret it */
1198 if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){
1199 DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name));
1200 SAFE_FREE(*return_iplist);
1201 return NT_STATUS_INVALID_PARAMETER;
1204 (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0;
1207 return NT_STATUS_OK;
1210 /* Check name cache */
1212 if (namecache_fetch(name, name_type, return_iplist, return_count)) {
1213 /* This could be a negative response */
1214 if (*return_count > 0) {
1215 return NT_STATUS_OK;
1217 return NT_STATUS_UNSUCCESSFUL;
1221 /* set the name resolution order */
1223 if ( strcmp( resolve_order, "NULL") == 0 ) {
1224 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
1225 return NT_STATUS_INVALID_PARAMETER;
1228 if ( !resolve_order ) {
1229 pstrcpy(name_resolve_list, lp_name_resolve_order());
1231 pstrcpy(name_resolve_list, resolve_order);
1234 if ( !name_resolve_list[0] ) {
1237 ptr = name_resolve_list;
1240 /* iterate through the name resolution backends */
1242 while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
1243 if((strequal(tok, "host") || strequal(tok, "hosts"))) {
1244 status = resolve_hosts(name, name_type, return_iplist,
1246 if (NT_STATUS_IS_OK(status)) {
1249 } else if(strequal( tok, "kdc")) {
1250 /* deal with KDC_NAME_TYPE names here. This will result in a
1251 SRV record lookup */
1252 status = resolve_ads(name, KDC_NAME_TYPE, sitename,
1253 return_iplist, return_count);
1254 if (NT_STATUS_IS_OK(status)) {
1255 /* Ensure we don't namecache this with the KDC port. */
1256 name_type = KDC_NAME_TYPE;
1259 } else if(strequal( tok, "ads")) {
1260 /* deal with 0x1c and 0x1b names here. This will result in a
1261 SRV record lookup */
1262 status = resolve_ads(name, name_type, sitename,
1263 return_iplist, return_count);
1264 if (NT_STATUS_IS_OK(status)) {
1267 } else if(strequal( tok, "lmhosts")) {
1268 status = resolve_lmhosts(name, name_type,
1269 return_iplist, return_count);
1270 if (NT_STATUS_IS_OK(status)) {
1273 } else if(strequal( tok, "wins")) {
1274 /* don't resolve 1D via WINS */
1275 if (name_type != 0x1D) {
1276 status = resolve_wins(name, name_type,
1279 if (NT_STATUS_IS_OK(status)) {
1283 } else if(strequal( tok, "bcast")) {
1284 status = name_resolve_bcast(name, name_type,
1287 if (NT_STATUS_IS_OK(status)) {
1291 DEBUG(0,("resolve_name: unknown name switch type %s\n",
1296 /* All of the resolve_* functions above have returned false. */
1298 SAFE_FREE(*return_iplist);
1301 return NT_STATUS_UNSUCCESSFUL;
1305 /* Remove duplicate entries. Some queries, notably #1c (domain
1306 controllers) return the PDC in iplist[0] and then all domain
1307 controllers including the PDC in iplist[1..n]. Iterating over
1308 the iplist when the PDC is down will cause two sets of timeouts. */
1310 if ( *return_count ) {
1311 *return_count = remove_duplicate_addrs2( *return_iplist, *return_count );
1314 /* Save in name cache */
1315 if ( DEBUGLEVEL >= 100 ) {
1316 for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++)
1317 DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name,
1318 name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1321 namecache_store(name, name_type, *return_count, *return_iplist);
1323 /* Display some debugging info */
1325 if ( DEBUGLEVEL >= 10 ) {
1326 DEBUG(10, ("internal_resolve_name: returning %d addresses: ", *return_count));
1328 for (i = 0; i < *return_count; i++) {
1329 DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port));
1337 /********************************************************
1338 Internal interface to resolve a name into one IP address.
1339 Use this function if the string is either an IP address, DNS
1340 or host name or NetBIOS name. This uses the name switch in the
1341 smb.conf to determine the order of name resolution.
1342 *********************************************************/
1344 BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
1346 struct ip_service *ip_list = NULL;
1347 char *sitename = sitename_fetch(lp_realm()); /* wild guess */
1350 if (is_ipaddress(name)) {
1351 *return_ip = *interpret_addr2(name);
1352 SAFE_FREE(sitename);
1356 if (NT_STATUS_IS_OK(internal_resolve_name(name, name_type, sitename,
1358 lp_name_resolve_order()))) {
1361 /* only return valid addresses for TCP connections */
1362 for (i=0; i<count; i++) {
1363 char *ip_str = inet_ntoa(ip_list[i].ip);
1365 strcmp(ip_str, "255.255.255.255") != 0 &&
1366 strcmp(ip_str, "0.0.0.0") != 0)
1368 *return_ip = ip_list[i].ip;
1370 SAFE_FREE(sitename);
1377 SAFE_FREE(sitename);
1381 /********************************************************
1382 Find the IP address of the master browser or DMB for a workgroup.
1383 *********************************************************/
1385 BOOL find_master_ip(const char *group, struct in_addr *master_ip)
1387 struct ip_service *ip_list = NULL;
1391 if (lp_disable_netbios()) {
1392 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
1396 status = internal_resolve_name(group, 0x1D, NULL, &ip_list, &count,
1397 lp_name_resolve_order());
1398 if (NT_STATUS_IS_OK(status)) {
1399 *master_ip = ip_list[0].ip;
1404 status = internal_resolve_name(group, 0x1B, NULL, &ip_list, &count,
1405 lp_name_resolve_order());
1406 if (NT_STATUS_IS_OK(status)) {
1407 *master_ip = ip_list[0].ip;
1416 /********************************************************
1417 Get the IP address list of the primary domain controller
1419 *********************************************************/
1421 BOOL get_pdc_ip(const char *domain, struct in_addr *ip)
1423 struct ip_service *ip_list = NULL;
1425 NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1427 /* Look up #1B name */
1429 if (lp_security() == SEC_ADS) {
1430 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1434 if (!NT_STATUS_IS_OK(status) || count == 0) {
1435 status = internal_resolve_name(domain, 0x1b, NULL, &ip_list,
1437 lp_name_resolve_order());
1438 if (!NT_STATUS_IS_OK(status)) {
1443 /* if we get more than 1 IP back we have to assume it is a
1444 multi-homed PDC and not a mess up */
1447 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count));
1448 sort_ip_list2( ip_list, count );
1451 *ip = ip_list[0].ip;
1458 /* Private enum type for lookups. */
1460 enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY };
1462 /********************************************************
1463 Get the IP address list of the domain controllers for
1465 *********************************************************/
1467 static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_service **ip_list,
1468 int *count, enum dc_lookup_type lookup_type, int *ordered)
1470 fstring resolve_order;
1471 char *saf_servername;
1477 int num_addresses = 0;
1478 int local_count, i, j;
1479 struct ip_service *return_iplist = NULL;
1480 struct ip_service *auto_ip_list = NULL;
1481 BOOL done_auto_lookup = False;
1487 /* if we are restricted to solely using DNS for looking
1488 up a domain controller, make sure that host lookups
1489 are enabled for the 'name resolve order'. If host lookups
1490 are disabled and ads_only is True, then set the string to
1493 fstrcpy( resolve_order, lp_name_resolve_order() );
1494 strlower_m( resolve_order );
1495 if ( lookup_type == DC_ADS_ONLY) {
1496 if ( strstr( resolve_order, "host" ) ) {
1497 fstrcpy( resolve_order, "ads" );
1499 /* DNS SRV lookups used by the ads resolver
1500 are already sorted by priority and weight */
1503 fstrcpy( resolve_order, "NULL" );
1505 } else if (lookup_type == DC_KDC_ONLY) {
1506 /* DNS SRV lookups used by the ads/kdc resolver
1507 are already sorted by priority and weight */
1509 fstrcpy( resolve_order, "kdc" );
1512 /* fetch the server we have affinity for. Add the
1513 'password server' list to a search for our domain controllers */
1515 saf_servername = saf_fetch( domain);
1517 if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) {
1518 pstr_sprintf( pserver, "%s, %s",
1519 saf_servername ? saf_servername : "",
1520 lp_passwordserver() );
1522 pstr_sprintf( pserver, "%s, *",
1523 saf_servername ? saf_servername : "" );
1526 SAFE_FREE( saf_servername );
1528 /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
1531 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
1532 return internal_resolve_name(domain, 0x1C, sitename, ip_list,
1533 count, resolve_order);
1536 DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver ));
1539 * if '*' appears in the "password server" list then add
1540 * an auto lookup to the list of manually configured
1541 * DC's. If any DC is listed by name, then the list should be
1542 * considered to be ordered
1546 while (next_token(&p,name,LIST_SEP,sizeof(name))) {
1547 if (strequal(name, "*")) {
1548 status = internal_resolve_name(domain, 0x1C, sitename,
1552 if (NT_STATUS_IS_OK(status)) {
1553 num_addresses += auto_count;
1555 done_auto_lookup = True;
1556 DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count));
1562 /* if we have no addresses and haven't done the auto lookup, then
1563 just return the list of DC's. Or maybe we just failed. */
1565 if ( (num_addresses == 0) ) {
1566 if ( done_auto_lookup ) {
1567 DEBUG(4,("get_dc_list: no servers found\n"));
1568 SAFE_FREE(auto_ip_list);
1569 return NT_STATUS_NO_LOGON_SERVERS;
1571 return internal_resolve_name(domain, 0x1C, sitename, ip_list,
1572 count, resolve_order);
1575 if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) {
1576 DEBUG(3,("get_dc_list: malloc fail !\n"));
1577 SAFE_FREE(auto_ip_list);
1578 return NT_STATUS_NO_MEMORY;
1584 /* fill in the return list now with real IP's */
1586 while ( (local_count<num_addresses) && next_token(&p,name,LIST_SEP,sizeof(name)) ) {
1587 struct in_addr name_ip;
1589 /* copy any addersses from the auto lookup */
1591 if ( strequal(name, "*") ) {
1592 for ( j=0; j<auto_count; j++ ) {
1593 /* Check for and don't copy any known bad DC IP's. */
1594 if(!NT_STATUS_IS_OK(check_negative_conn_cache(domain,
1595 inet_ntoa(auto_ip_list[j].ip)))) {
1596 DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",
1597 inet_ntoa(auto_ip_list[j].ip) ));
1600 return_iplist[local_count].ip = auto_ip_list[j].ip;
1601 return_iplist[local_count].port = auto_ip_list[j].port;
1608 /* added support for address:port syntax for ads (not that I think
1609 anyone will ever run the LDAP server in an AD domain on something
1610 other than port 389 */
1612 port = (lp_security() == SEC_ADS) ? LDAP_PORT : PORT_NONE;
1613 if ( (port_str=strchr(name, ':')) != NULL ) {
1616 port = atoi( port_str );
1619 /* explicit lookup; resolve_name() will handle names & IP addresses */
1620 if ( resolve_name( name, &name_ip, 0x20 ) ) {
1622 /* Check for and don't copy any known bad DC IP's. */
1623 if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain, inet_ntoa(name_ip))) ) {
1624 DEBUG(5,("get_dc_list: negative entry %s removed from DC list\n",name ));
1628 return_iplist[local_count].ip = name_ip;
1629 return_iplist[local_count].port = port;
1635 SAFE_FREE(auto_ip_list);
1637 /* need to remove duplicates in the list if we have any
1638 explicit password servers */
1640 if ( local_count ) {
1641 local_count = remove_duplicate_addrs2( return_iplist, local_count );
1644 if ( DEBUGLEVEL >= 4 ) {
1645 DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count,
1646 *ordered ? "":"un"));
1647 DEBUG(4,("get_dc_list: "));
1648 for ( i=0; i<local_count; i++ )
1649 DEBUGADD(4,("%s:%d ", inet_ntoa(return_iplist[i].ip), return_iplist[i].port ));
1653 *ip_list = return_iplist;
1654 *count = local_count;
1656 return ( *count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS );
1659 /*********************************************************************
1660 Small wrapper function to get the DC list and sort it if neccessary.
1661 *********************************************************************/
1663 NTSTATUS get_sorted_dc_list( const char *domain, const char *sitename, struct ip_service **ip_list, int *count, BOOL ads_only )
1667 enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP;
1669 DEBUG(8,("get_sorted_dc_list: attempting lookup for name %s (sitename %s) "
1672 sitename ? sitename : "NULL",
1673 (ads_only ? "ads" : lp_name_resolve_order())));
1676 lookup_type = DC_ADS_ONLY;
1679 status = get_dc_list(domain, sitename, ip_list, count, lookup_type, &ordered);
1680 if (!NT_STATUS_IS_OK(status)) {
1684 /* only sort if we don't already have an ordered list */
1686 sort_ip_list2( *ip_list, *count );
1689 return NT_STATUS_OK;
1692 /*********************************************************************
1693 Get the KDC list - re-use all the logic in get_dc_list.
1694 *********************************************************************/
1696 NTSTATUS get_kdc_list( const char *realm, const char *sitename, struct ip_service **ip_list, int *count)
1704 status = get_dc_list(realm, sitename, ip_list, count, DC_KDC_ONLY, &ordered);
1706 if (!NT_STATUS_IS_OK(status)) {
1710 /* only sort if we don't already have an ordered list */
1712 sort_ip_list2( *ip_list, *count );
1715 return NT_STATUS_OK;
1719 BOOL translate_name(const char *realm, fstring dns_domain_name,
1720 fstring nb_domain_name)
1722 struct winbindd_request request;
1723 struct winbindd_response response;
1724 NSS_STATUS wb_result;
1728 ZERO_STRUCT(request);
1729 ZERO_STRUCT(response);
1731 fstrcpy(request.domain_name, realm);
1732 wb_result = winbindd_request_response(WINBINDD_DOMAIN_INFO,
1733 &request, &response);
1735 if (wb_result != NSS_STATUS_SUCCESS) {
1736 DEBUG(0, ("Failed to translate %s\n", realm));
1740 fstrcpy(dns_domain_name, response.data.domain_info.alt_name);
1741 fstrcpy(nb_domain_name, response.data.domain_info.name);