2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1994-1998
5 Copyright (C) Jeremy Allison 2007.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 /* nmbd.c sets this to True. */
24 bool global_in_nmbd
= False
;
26 /****************************
27 * SERVER AFFINITY ROUTINES *
28 ****************************/
30 /* Server affinity is the concept of preferring the last domain
31 controller with whom you had a successful conversation */
33 /****************************************************************************
34 ****************************************************************************/
35 #define SAFKEY_FMT "SAF/DOMAIN/%s"
37 #define SAFJOINKEY_FMT "SAFJOIN/DOMAIN/%s"
38 #define SAFJOIN_TTL 3600
40 static char *saf_key(const char *domain
)
44 asprintf_strupper_m(&keystr
, SAFKEY_FMT
, domain
);
49 static char *saf_join_key(const char *domain
)
53 asprintf_strupper_m(&keystr
, SAFJOINKEY_FMT
, domain
);
58 /****************************************************************************
59 ****************************************************************************/
61 bool saf_store( const char *domain
, const char *servername
)
67 if ( !domain
|| !servername
) {
68 DEBUG(2,("saf_store: "
69 "Refusing to store empty domain or servername!\n"));
73 if ( (strlen(domain
) == 0) || (strlen(servername
) == 0) ) {
74 DEBUG(0,("saf_store: "
75 "refusing to store 0 length domain or servername!\n"));
79 if ( !gencache_init() )
82 key
= saf_key( domain
);
83 expire
= time( NULL
) + lp_parm_int(-1, "saf","ttl", SAF_TTL
);
85 DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n",
86 domain
, servername
, (unsigned int)expire
));
88 ret
= gencache_set( key
, servername
, expire
);
95 bool saf_join_store( const char *domain
, const char *servername
)
101 if ( !domain
|| !servername
) {
102 DEBUG(2,("saf_join_store: Refusing to store empty domain or servername!\n"));
106 if ( (strlen(domain
) == 0) || (strlen(servername
) == 0) ) {
107 DEBUG(0,("saf_join_store: refusing to store 0 length domain or servername!\n"));
111 if ( !gencache_init() )
114 key
= saf_join_key( domain
);
115 expire
= time( NULL
) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL
);
117 DEBUG(10,("saf_join_store: domain = [%s], server = [%s], expire = [%u]\n",
118 domain
, servername
, (unsigned int)expire
));
120 ret
= gencache_set( key
, servername
, expire
);
127 bool saf_delete( const char *domain
)
133 DEBUG(2,("saf_delete: Refusing to delete empty domain\n"));
137 if ( !gencache_init() )
140 key
= saf_join_key(domain
);
141 ret
= gencache_del(key
);
145 DEBUG(10,("saf_delete[join]: domain = [%s]\n", domain
));
148 key
= saf_key(domain
);
149 ret
= gencache_del(key
);
153 DEBUG(10,("saf_delete: domain = [%s]\n", domain
));
159 /****************************************************************************
160 ****************************************************************************/
162 char *saf_fetch( const char *domain
)
169 if ( !domain
|| strlen(domain
) == 0) {
170 DEBUG(2,("saf_fetch: Empty domain name!\n"));
174 if ( !gencache_init() )
177 key
= saf_join_key( domain
);
179 ret
= gencache_get( key
, &server
, &timeout
);
184 DEBUG(5,("saf_fetch[join]: Returning \"%s\" for \"%s\" domain\n",
189 key
= saf_key( domain
);
191 ret
= gencache_get( key
, &server
, &timeout
);
196 DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n",
199 DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n",
206 /****************************************************************************
207 Generate a random trn_id.
208 ****************************************************************************/
210 static int generate_trn_id(void)
214 generate_random_buffer((uint8
*)&id
, sizeof(id
));
216 return id
% (unsigned)0x7FFF;
219 /****************************************************************************
220 Parse a node status response into an array of structures.
221 ****************************************************************************/
223 static NODE_STATUS_STRUCT
*parse_node_status(char *p
,
225 struct node_status_extra
*extra
)
227 NODE_STATUS_STRUCT
*ret
;
230 *num_names
= CVAL(p
,0);
235 ret
= SMB_MALLOC_ARRAY(NODE_STATUS_STRUCT
,*num_names
);
240 for (i
=0;i
< *num_names
;i
++) {
241 StrnCpy(ret
[i
].name
,p
,15);
242 trim_char(ret
[i
].name
,'\0',' ');
243 ret
[i
].type
= CVAL(p
,15);
244 ret
[i
].flags
= p
[16];
246 DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret
[i
].name
,
247 ret
[i
].type
, ret
[i
].flags
));
250 * Also, pick up the MAC address ...
253 memcpy(&extra
->mac_addr
, p
, 6); /* Fill in the mac addr */
259 /****************************************************************************
260 Do a NBT node status query on an open socket and return an array of
261 structures holding the returned names or NULL if the query failed.
262 **************************************************************************/
264 NODE_STATUS_STRUCT
*node_status_query(int fd
,
265 struct nmb_name
*name
,
266 const struct sockaddr_storage
*to_ss
,
268 struct node_status_extra
*extra
)
272 int retry_time
= 2000;
274 struct packet_struct p
;
275 struct packet_struct
*p2
;
276 struct nmb_packet
*nmb
= &p
.packet
.nmb
;
277 NODE_STATUS_STRUCT
*ret
;
281 if (to_ss
->ss_family
!= AF_INET
) {
282 /* Can't do node status to IPv6 */
285 nmb
->header
.name_trn_id
= generate_trn_id();
286 nmb
->header
.opcode
= 0;
287 nmb
->header
.response
= false;
288 nmb
->header
.nm_flags
.bcast
= false;
289 nmb
->header
.nm_flags
.recursion_available
= false;
290 nmb
->header
.nm_flags
.recursion_desired
= false;
291 nmb
->header
.nm_flags
.trunc
= false;
292 nmb
->header
.nm_flags
.authoritative
= false;
293 nmb
->header
.rcode
= 0;
294 nmb
->header
.qdcount
= 1;
295 nmb
->header
.ancount
= 0;
296 nmb
->header
.nscount
= 0;
297 nmb
->header
.arcount
= 0;
298 nmb
->question
.question_name
= *name
;
299 nmb
->question
.question_type
= 0x21;
300 nmb
->question
.question_class
= 0x1;
302 p
.ip
= ((const struct sockaddr_in
*)to_ss
)->sin_addr
;
305 p
.timestamp
= time(NULL
);
306 p
.packet_type
= NMB_PACKET
;
310 if (!send_packet(&p
))
316 struct timeval tval2
;
317 GetTimeOfDay(&tval2
);
318 if (TvalDiff(&tval
,&tval2
) > retry_time
) {
321 if (!found
&& !send_packet(&p
))
327 if ((p2
=receive_nmb_packet(fd
,90,nmb
->header
.name_trn_id
))) {
328 struct nmb_packet
*nmb2
= &p2
->packet
.nmb
;
329 debug_nmb_packet(p2
);
331 if (nmb2
->header
.opcode
!= 0 ||
332 nmb2
->header
.nm_flags
.bcast
||
333 nmb2
->header
.rcode
||
334 !nmb2
->header
.ancount
||
335 nmb2
->answers
->rr_type
!= 0x21) {
336 /* XXXX what do we do with this? could be a
337 redirect, but we'll discard it for the
343 ret
= parse_node_status(&nmb2
->answers
->rdata
[0],
353 /****************************************************************************
354 Find the first type XX name in a node status reply - used for finding
355 a servers name given its IP. Return the matched name in *name.
356 **************************************************************************/
358 bool name_status_find(const char *q_name
,
361 const struct sockaddr_storage
*to_ss
,
364 char addr
[INET6_ADDRSTRLEN
];
365 struct sockaddr_storage ss
;
366 NODE_STATUS_STRUCT
*status
= NULL
;
367 struct nmb_name nname
;
372 if (lp_disable_netbios()) {
373 DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n",
378 print_sockaddr(addr
, sizeof(addr
), to_ss
);
380 DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name
,
383 /* Check the cache first. */
385 if (namecache_status_fetch(q_name
, q_type
, type
, to_ss
, name
)) {
389 if (to_ss
->ss_family
!= AF_INET
) {
390 /* Can't do node status to IPv6 */
394 if (!interpret_string_addr(&ss
, lp_socket_address(),
395 AI_NUMERICHOST
|AI_PASSIVE
)) {
399 sock
= open_socket_in(SOCK_DGRAM
, 0, 3, &ss
, True
);
403 /* W2K PDC's seem not to respond to '*'#0. JRA */
404 make_nmb_name(&nname
, q_name
, q_type
);
405 status
= node_status_query(sock
, &nname
, to_ss
, &count
, NULL
);
410 for (i
=0;i
<count
;i
++) {
411 if (status
[i
].type
== type
)
417 pull_ascii_nstring(name
, sizeof(fstring
), status
[i
].name
);
419 /* Store the result in the cache. */
420 /* but don't store an entry for 0x1c names here. Here we have
421 a single host and DOMAIN<0x1c> names should be a list of hosts */
423 if ( q_type
!= 0x1c ) {
424 namecache_status_store(q_name
, q_type
, type
, to_ss
, name
);
432 DEBUG(10, ("name_status_find: name %sfound", result
? "" : "not "));
435 DEBUGADD(10, (", name %s ip address is %s", name
, addr
));
443 comparison function used by sort_addr_list
446 static int addr_compare(const struct sockaddr
*ss1
,
447 const struct sockaddr
*ss2
)
449 int max_bits1
=0, max_bits2
=0;
450 int num_interfaces
= iface_count();
453 /* Sort IPv6 addresses first. */
454 if (ss1
->sa_family
!= ss2
->sa_family
) {
455 if (ss2
->sa_family
== AF_INET
) {
462 /* Here we know both addresses are of the same
465 for (i
=0;i
<num_interfaces
;i
++) {
466 const struct sockaddr_storage
*pss
= iface_n_bcast(i
);
467 unsigned char *p_ss1
= NULL
;
468 unsigned char *p_ss2
= NULL
;
469 unsigned char *p_if
= NULL
;
473 if (pss
->ss_family
!= ss1
->sa_family
) {
474 /* Ignore interfaces of the wrong type. */
477 if (pss
->ss_family
== AF_INET
) {
478 p_if
= (unsigned char *)
479 &((const struct sockaddr_in
*)pss
)->sin_addr
;
480 p_ss1
= (unsigned char *)
481 &((const struct sockaddr_in
*)ss1
)->sin_addr
;
482 p_ss2
= (unsigned char *)
483 &((const struct sockaddr_in
*)ss2
)->sin_addr
;
486 #if defined(HAVE_IPV6)
487 if (pss
->ss_family
== AF_INET6
) {
488 p_if
= (unsigned char *)
489 &((const struct sockaddr_in6
*)pss
)->sin6_addr
;
490 p_ss1
= (unsigned char *)
491 &((const struct sockaddr_in6
*)ss1
)->sin6_addr
;
492 p_ss2
= (unsigned char *)
493 &((const struct sockaddr_in6
*)ss2
)->sin6_addr
;
497 if (!p_ss1
|| !p_ss2
|| !p_if
|| len
== 0) {
500 bits1
= matching_len_bits(p_ss1
, p_if
, len
);
501 bits2
= matching_len_bits(p_ss2
, p_if
, len
);
502 max_bits1
= MAX(bits1
, max_bits1
);
503 max_bits2
= MAX(bits2
, max_bits2
);
506 /* Bias towards directly reachable IPs */
507 if (iface_local(ss1
)) {
508 if (ss1
->sa_family
== AF_INET
) {
514 if (iface_local(ss2
)) {
515 if (ss2
->sa_family
== AF_INET
) {
521 return max_bits2
- max_bits1
;
524 /*******************************************************************
525 compare 2 ldap IPs by nearness to our interfaces - used in qsort
526 *******************************************************************/
528 int ip_service_compare(struct ip_service
*ss1
, struct ip_service
*ss2
)
532 if ((result
= addr_compare((struct sockaddr
*)&ss1
->ss
, (struct sockaddr
*)&ss2
->ss
)) != 0) {
536 if (ss1
->port
> ss2
->port
) {
540 if (ss1
->port
< ss2
->port
) {
548 sort an IP list so that names that are close to one of our interfaces
549 are at the top. This prevents the problem where a WINS server returns an IP
550 that is not reachable from our subnet as the first match
553 static void sort_addr_list(struct sockaddr_storage
*sslist
, int count
)
559 qsort(sslist
, count
, sizeof(struct sockaddr_storage
),
560 QSORT_CAST addr_compare
);
563 static void sort_service_list(struct ip_service
*servlist
, int count
)
569 qsort(servlist
, count
, sizeof(struct ip_service
),
570 QSORT_CAST ip_service_compare
);
573 /**********************************************************************
574 Remove any duplicate address/port pairs in the list
575 *********************************************************************/
577 static int remove_duplicate_addrs2(struct ip_service
*iplist
, int count
)
581 DEBUG(10,("remove_duplicate_addrs2: "
582 "looking for duplicate address/port pairs\n"));
584 /* one loop to remove duplicates */
585 for ( i
=0; i
<count
; i
++ ) {
586 if ( is_zero_addr((struct sockaddr
*)&iplist
[i
].ss
)) {
590 for ( j
=i
+1; j
<count
; j
++ ) {
591 if (sockaddr_equal((struct sockaddr
*)&iplist
[i
].ss
, (struct sockaddr
*)&iplist
[j
].ss
) &&
592 iplist
[i
].port
== iplist
[j
].port
) {
593 zero_sockaddr(&iplist
[j
].ss
);
598 /* one loop to clean up any holes we left */
599 /* first ip should never be a zero_ip() */
600 for (i
= 0; i
<count
; ) {
601 if (is_zero_addr((struct sockaddr
*)&iplist
[i
].ss
) ) {
603 memmove(&iplist
[i
], &iplist
[i
+1],
604 (count
- i
- 1)*sizeof(iplist
[i
]));
615 /****************************************************************************
616 Do a netbios name query to find someones IP.
617 Returns an array of IP addresses or NULL if none.
618 *count will be set to the number of addresses returned.
619 *timed_out is set if we failed by timing out
620 ****************************************************************************/
622 struct sockaddr_storage
*name_query(int fd
,
627 const struct sockaddr_storage
*to_ss
,
634 int retry_time
= bcast
?250:2000;
636 struct packet_struct p
;
637 struct packet_struct
*p2
;
638 struct nmb_packet
*nmb
= &p
.packet
.nmb
;
639 struct sockaddr_storage
*ss_list
= NULL
;
641 if (lp_disable_netbios()) {
642 DEBUG(5,("name_query(%s#%02x): netbios is disabled\n",
647 if (to_ss
->ss_family
!= AF_INET
) {
655 memset((char *)&p
,'\0',sizeof(p
));
659 nmb
->header
.name_trn_id
= generate_trn_id();
660 nmb
->header
.opcode
= 0;
661 nmb
->header
.response
= false;
662 nmb
->header
.nm_flags
.bcast
= bcast
;
663 nmb
->header
.nm_flags
.recursion_available
= false;
664 nmb
->header
.nm_flags
.recursion_desired
= recurse
;
665 nmb
->header
.nm_flags
.trunc
= false;
666 nmb
->header
.nm_flags
.authoritative
= false;
667 nmb
->header
.rcode
= 0;
668 nmb
->header
.qdcount
= 1;
669 nmb
->header
.ancount
= 0;
670 nmb
->header
.nscount
= 0;
671 nmb
->header
.arcount
= 0;
673 make_nmb_name(&nmb
->question
.question_name
,name
,name_type
);
675 nmb
->question
.question_type
= 0x20;
676 nmb
->question
.question_class
= 0x1;
678 p
.ip
= ((struct sockaddr_in
*)to_ss
)->sin_addr
;
681 p
.timestamp
= time(NULL
);
682 p
.packet_type
= NMB_PACKET
;
686 if (!send_packet(&p
))
692 struct timeval tval2
;
694 GetTimeOfDay(&tval2
);
695 if (TvalDiff(&tval
,&tval2
) > retry_time
) {
698 if (!found
&& !send_packet(&p
))
704 if ((p2
=receive_nmb_packet(fd
,90,nmb
->header
.name_trn_id
))) {
705 struct nmb_packet
*nmb2
= &p2
->packet
.nmb
;
706 debug_nmb_packet(p2
);
708 /* If we get a Negative Name Query Response from a WINS
709 * server, we should report it and give up.
711 if( 0 == nmb2
->header
.opcode
/* A query response */
712 && !(bcast
) /* from a WINS server */
713 && nmb2
->header
.rcode
/* Error returned */
716 if( DEBUGLVL( 3 ) ) {
717 /* Only executed if DEBUGLEVEL >= 3 */
718 dbgtext( "Negative name query "
719 "response, rcode 0x%02x: ",
720 nmb2
->header
.rcode
);
721 switch( nmb2
->header
.rcode
) {
724 "was invalidly formatted.\n" );
727 dbgtext( "Problem with NBNS, "
728 "cannot process name.\n");
731 dbgtext( "The name requested "
732 "does not exist.\n" );
735 dbgtext( "Unsupported request "
739 dbgtext( "Query refused "
743 dbgtext( "Unrecognized error "
752 if (nmb2
->header
.opcode
!= 0 ||
753 nmb2
->header
.nm_flags
.bcast
||
754 nmb2
->header
.rcode
||
755 !nmb2
->header
.ancount
) {
757 * XXXX what do we do with this? Could be a
758 * redirect, but we'll discard it for the
765 ss_list
= SMB_REALLOC_ARRAY(ss_list
,
766 struct sockaddr_storage
,
768 nmb2
->answers
->rdlength
/6);
771 DEBUG(0,("name_query: Realloc failed.\n"));
776 DEBUG(2,("Got a positive name query response "
780 for (i
=0;i
<nmb2
->answers
->rdlength
/6;i
++) {
782 putip((char *)&ip
,&nmb2
->answers
->rdata
[2+i
*6]);
783 in_addr_to_sockaddr_storage(&ss_list
[(*count
)],
785 DEBUGADD(2,("%s ",inet_ntoa(ip
)));
792 /* We add the flags back ... */
793 if (nmb2
->header
.response
)
794 (*flags
) |= NM_FLAGS_RS
;
795 if (nmb2
->header
.nm_flags
.authoritative
)
796 (*flags
) |= NM_FLAGS_AA
;
797 if (nmb2
->header
.nm_flags
.trunc
)
798 (*flags
) |= NM_FLAGS_TC
;
799 if (nmb2
->header
.nm_flags
.recursion_desired
)
800 (*flags
) |= NM_FLAGS_RD
;
801 if (nmb2
->header
.nm_flags
.recursion_available
)
802 (*flags
) |= NM_FLAGS_RA
;
803 if (nmb2
->header
.nm_flags
.bcast
)
804 (*flags
) |= NM_FLAGS_B
;
807 * If we're doing a unicast lookup we only
808 * expect one reply. Don't wait the full 2
809 * seconds if we got one. JRA.
816 /* only set timed_out if we didn't fund what we where looking for*/
818 if ( !found
&& timed_out
) {
822 /* sort the ip list so we choose close servers first if possible */
823 sort_addr_list(ss_list
, *count
);
828 /********************************************************
829 Start parsing the lmhosts file.
830 *********************************************************/
832 XFILE
*startlmhosts(const char *fname
)
834 XFILE
*fp
= x_fopen(fname
,O_RDONLY
, 0);
836 DEBUG(4,("startlmhosts: Can't open lmhosts file %s. "
838 fname
, strerror(errno
)));
844 /********************************************************
845 Parse the next line in the lmhosts file.
846 *********************************************************/
848 bool getlmhostsent(TALLOC_CTX
*ctx
, XFILE
*fp
, char **pp_name
, int *name_type
,
849 struct sockaddr_storage
*pss
)
855 while(!x_feof(fp
) && !x_ferror(fp
)) {
866 if (!fgets_slash(line
,sizeof(line
),fp
)) {
876 if (next_token_talloc(ctx
, &ptr
, &ip
, NULL
))
878 if (next_token_talloc(ctx
, &ptr
, &name
, NULL
))
880 if (next_token_talloc(ctx
, &ptr
, &flags
, NULL
))
882 if (next_token_talloc(ctx
, &ptr
, &extra
, NULL
))
888 if (count
> 0 && count
< 2) {
889 DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",
895 DEBUG(0,("getlmhostsent: too many columns "
896 "in lmhosts file (obsolete syntax)\n"));
901 flags
= talloc_strdup(ctx
, "");
907 DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n",
910 if (strchr_m(flags
,'G') || strchr_m(flags
,'S')) {
911 DEBUG(0,("getlmhostsent: group flag "
912 "in lmhosts ignored (obsolete)\n"));
916 if (!interpret_string_addr(pss
, ip
, AI_NUMERICHOST
)) {
917 DEBUG(0,("getlmhostsent: invalid address "
921 /* Extra feature. If the name ends in '#XX',
922 * where XX is a hex number, then only add that name type. */
923 if((ptr1
= strchr_m(name
, '#')) != NULL
) {
927 *name_type
= (int)strtol(ptr1
, &endptr
, 16);
928 if(!*ptr1
|| (endptr
== ptr1
)) {
929 DEBUG(0,("getlmhostsent: invalid name "
930 "%s containing '#'.\n", name
));
934 *(--ptr1
) = '\0'; /* Truncate at the '#' */
937 *pp_name
= talloc_strdup(ctx
, name
);
947 /********************************************************
948 Finish parsing the lmhosts file.
949 *********************************************************/
951 void endlmhosts(XFILE
*fp
)
956 /********************************************************
957 convert an array if struct sockaddr_storage to struct ip_service
958 return false on failure. Port is set to PORT_NONE;
959 *********************************************************/
961 static bool convert_ss2service(struct ip_service
**return_iplist
,
962 const struct sockaddr_storage
*ss_list
,
967 if ( count
==0 || !ss_list
)
970 /* copy the ip address; port will be PORT_NONE */
971 if ((*return_iplist
= SMB_MALLOC_ARRAY(struct ip_service
, count
)) ==
973 DEBUG(0,("convert_ip2service: malloc failed "
974 "for %d enetries!\n", count
));
978 for ( i
=0; i
<count
; i
++ ) {
979 (*return_iplist
)[i
].ss
= ss_list
[i
];
980 (*return_iplist
)[i
].port
= PORT_NONE
;
986 /********************************************************
987 Resolve via "bcast" method.
988 *********************************************************/
990 NTSTATUS
name_resolve_bcast(const char *name
,
992 struct ip_service
**return_iplist
,
996 int num_interfaces
= iface_count();
997 struct sockaddr_storage
*ss_list
;
998 struct sockaddr_storage ss
;
1001 if (lp_disable_netbios()) {
1002 DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n",
1004 return NT_STATUS_INVALID_PARAMETER
;
1007 *return_iplist
= NULL
;
1011 * "bcast" means do a broadcast lookup on all the local interfaces.
1014 DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup "
1015 "for name %s<0x%x>\n", name
, name_type
));
1017 if (!interpret_string_addr(&ss
, lp_socket_address(),
1018 AI_NUMERICHOST
|AI_PASSIVE
)) {
1022 sock
= open_socket_in( SOCK_DGRAM
, 0, 3, &ss
, true );
1024 return NT_STATUS_UNSUCCESSFUL
;
1027 set_socket_options(sock
,"SO_BROADCAST");
1029 * Lookup the name on all the interfaces, return on
1030 * the first successful match.
1032 for( i
= num_interfaces
-1; i
>= 0; i
--) {
1033 const struct sockaddr_storage
*pss
= iface_n_bcast(i
);
1036 /* Done this way to fix compiler error on IRIX 5.x */
1040 ss_list
= name_query(sock
, name
, name_type
, true,
1041 true, pss
, return_count
, &flags
, NULL
);
1047 /* failed - no response */
1050 return NT_STATUS_UNSUCCESSFUL
;
1054 status
= NT_STATUS_OK
;
1055 if (!convert_ss2service(return_iplist
, ss_list
, *return_count
) )
1056 status
= NT_STATUS_INVALID_PARAMETER
;
1063 /********************************************************
1064 Resolve via "wins" method.
1065 *********************************************************/
1067 NTSTATUS
resolve_wins(const char *name
,
1069 struct ip_service
**return_iplist
,
1074 struct sockaddr_storage src_ss
, *ss_list
= NULL
;
1075 struct in_addr src_ip
;
1078 if (lp_disable_netbios()) {
1079 DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n",
1081 return NT_STATUS_INVALID_PARAMETER
;
1084 *return_iplist
= NULL
;
1087 DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n",
1090 if (wins_srv_count() < 1) {
1091 DEBUG(3,("resolve_wins: WINS server resolution selected "
1092 "and no WINS servers listed.\n"));
1093 return NT_STATUS_INVALID_PARAMETER
;
1096 /* we try a lookup on each of the WINS tags in turn */
1097 wins_tags
= wins_srv_tags();
1100 /* huh? no tags?? give up in disgust */
1101 return NT_STATUS_INVALID_PARAMETER
;
1104 /* the address we will be sending from */
1105 if (!interpret_string_addr(&src_ss
, lp_socket_address(),
1106 AI_NUMERICHOST
|AI_PASSIVE
)) {
1107 zero_sockaddr(&src_ss
);
1110 if (src_ss
.ss_family
!= AF_INET
) {
1111 char addr
[INET6_ADDRSTRLEN
];
1112 print_sockaddr(addr
, sizeof(addr
), &src_ss
);
1113 DEBUG(3,("resolve_wins: cannot receive WINS replies "
1114 "on IPv6 address %s\n",
1116 wins_srv_tags_free(wins_tags
);
1117 return NT_STATUS_INVALID_PARAMETER
;
1120 src_ip
= ((struct sockaddr_in
*)&src_ss
)->sin_addr
;
1122 /* in the worst case we will try every wins server with every
1124 for (t
=0; wins_tags
&& wins_tags
[t
]; t
++) {
1125 int srv_count
= wins_srv_count_tag(wins_tags
[t
]);
1126 for (i
=0; i
<srv_count
; i
++) {
1127 struct sockaddr_storage wins_ss
;
1128 struct in_addr wins_ip
;
1132 wins_ip
= wins_srv_ip_tag(wins_tags
[t
], src_ip
);
1134 if (global_in_nmbd
&& ismyip_v4(wins_ip
)) {
1135 /* yikes! we'll loop forever */
1139 /* skip any that have been unresponsive lately */
1140 if (wins_srv_is_dead(wins_ip
, src_ip
)) {
1144 DEBUG(3,("resolve_wins: using WINS server %s "
1146 inet_ntoa(wins_ip
), wins_tags
[t
]));
1148 sock
= open_socket_in(SOCK_DGRAM
, 0, 3, &src_ss
, true);
1153 in_addr_to_sockaddr_storage(&wins_ss
, wins_ip
);
1154 ss_list
= name_query(sock
,
1164 /* exit loop if we got a list of addresses */
1172 /* Timed out wating for WINS server to respond.
1174 wins_srv_died(wins_ip
, src_ip
);
1176 /* The name definately isn't in this
1177 group of WINS servers.
1178 goto the next group */
1184 wins_srv_tags_free(wins_tags
);
1185 return NT_STATUS_NO_LOGON_SERVERS
;
1189 status
= NT_STATUS_OK
;
1190 if (!convert_ss2service(return_iplist
, ss_list
, *return_count
))
1191 status
= NT_STATUS_INVALID_PARAMETER
;
1194 wins_srv_tags_free(wins_tags
);
1200 /********************************************************
1201 Resolve via "lmhosts" method.
1202 *********************************************************/
1204 static NTSTATUS
resolve_lmhosts(const char *name
, int name_type
,
1205 struct ip_service
**return_iplist
,
1209 * "lmhosts" means parse the local lmhosts file.
1213 char *lmhost_name
= NULL
;
1215 struct sockaddr_storage return_ss
;
1216 NTSTATUS status
= NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND
;
1217 TALLOC_CTX
*ctx
= NULL
;
1219 *return_iplist
= NULL
;
1222 DEBUG(3,("resolve_lmhosts: "
1223 "Attempting lmhosts lookup for name %s<0x%x>\n",
1226 fp
= startlmhosts(get_dyn_LMHOSTSFILE());
1229 return NT_STATUS_NO_SUCH_FILE
;
1231 ctx
= talloc_init("resolve_lmhosts");
1234 return NT_STATUS_NO_MEMORY
;
1237 while (getlmhostsent(ctx
, fp
, &lmhost_name
, &name_type2
, &return_ss
)) {
1239 if (!strequal(name
, lmhost_name
)) {
1240 TALLOC_FREE(lmhost_name
);
1244 if ((name_type2
!= -1) && (name_type
!= name_type2
)) {
1245 TALLOC_FREE(lmhost_name
);
1249 *return_iplist
= SMB_REALLOC_ARRAY((*return_iplist
),
1253 if ((*return_iplist
) == NULL
) {
1256 DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
1257 return NT_STATUS_NO_MEMORY
;
1260 (*return_iplist
)[*return_count
].ss
= return_ss
;
1261 (*return_iplist
)[*return_count
].port
= PORT_NONE
;
1264 /* we found something */
1265 status
= NT_STATUS_OK
;
1267 /* Multiple names only for DC lookup */
1268 if (name_type
!= 0x1c)
1278 /********************************************************
1279 Resolve via "hosts" method.
1280 *********************************************************/
1282 static NTSTATUS
resolve_hosts(const char *name
, int name_type
,
1283 struct ip_service
**return_iplist
,
1287 * "host" means do a localhost, or dns lookup.
1289 struct addrinfo hints
;
1290 struct addrinfo
*ailist
= NULL
;
1291 struct addrinfo
*res
= NULL
;
1295 if ( name_type
!= 0x20 && name_type
!= 0x0) {
1296 DEBUG(5, ("resolve_hosts: not appropriate "
1297 "for name type <0x%x>\n",
1299 return NT_STATUS_INVALID_PARAMETER
;
1302 *return_iplist
= NULL
;
1305 DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n",
1309 /* By default make sure it supports TCP. */
1310 hints
.ai_socktype
= SOCK_STREAM
;
1311 hints
.ai_flags
= AI_ADDRCONFIG
;
1313 #if !defined(HAVE_IPV6)
1314 /* Unless we have IPv6, we really only want IPv4 addresses back. */
1315 hints
.ai_family
= AF_INET
;
1318 ret
= getaddrinfo(name
,
1323 DEBUG(3,("resolve_hosts: getaddrinfo failed for name %s [%s]\n",
1325 gai_strerror(ret
) ));
1328 for (res
= ailist
; res
; res
= res
->ai_next
) {
1329 struct sockaddr_storage ss
;
1331 if (!res
->ai_addr
|| res
->ai_addrlen
== 0) {
1336 memcpy(&ss
, res
->ai_addr
, res
->ai_addrlen
);
1340 *return_iplist
= SMB_REALLOC_ARRAY(*return_iplist
,
1343 if (!*return_iplist
) {
1344 DEBUG(3,("resolve_hosts: malloc fail !\n"));
1345 freeaddrinfo(ailist
);
1346 return NT_STATUS_NO_MEMORY
;
1348 (*return_iplist
)[i
].ss
= ss
;
1349 (*return_iplist
)[i
].port
= PORT_NONE
;
1353 freeaddrinfo(ailist
);
1355 if (*return_count
) {
1356 return NT_STATUS_OK
;
1358 return NT_STATUS_UNSUCCESSFUL
;
1361 /********************************************************
1362 Resolve via "ADS" method.
1363 *********************************************************/
1365 static NTSTATUS
resolve_ads(const char *name
,
1367 const char *sitename
,
1368 struct ip_service
**return_iplist
,
1374 struct dns_rr_srv
*dcs
= NULL
;
1378 if ((name_type
!= 0x1c) && (name_type
!= KDC_NAME_TYPE
) &&
1379 (name_type
!= 0x1b)) {
1380 return NT_STATUS_INVALID_PARAMETER
;
1383 if ( (ctx
= talloc_init("resolve_ads")) == NULL
) {
1384 DEBUG(0,("resolve_ads: talloc_init() failed!\n"));
1385 return NT_STATUS_NO_MEMORY
;
1388 /* The DNS code needs fixing to find IPv6 addresses... JRA. */
1390 switch (name_type
) {
1392 DEBUG(5,("resolve_ads: Attempting to resolve "
1393 "PDC for %s using DNS\n", name
));
1394 status
= ads_dns_query_pdc(ctx
, name
, &dcs
, &numdcs
);
1398 DEBUG(5,("resolve_ads: Attempting to resolve "
1399 "DCs for %s using DNS\n", name
));
1400 status
= ads_dns_query_dcs(ctx
, name
, sitename
, &dcs
,
1404 DEBUG(5,("resolve_ads: Attempting to resolve "
1405 "KDCs for %s using DNS\n", name
));
1406 status
= ads_dns_query_kdcs(ctx
, name
, sitename
, &dcs
,
1410 status
= NT_STATUS_INVALID_PARAMETER
;
1414 if ( !NT_STATUS_IS_OK( status
) ) {
1415 talloc_destroy(ctx
);
1419 for (i
=0;i
<numdcs
;i
++) {
1420 numaddrs
+= MAX(dcs
[i
].num_ips
,1);
1423 if ((*return_iplist
= SMB_MALLOC_ARRAY(struct ip_service
, numaddrs
)) ==
1425 DEBUG(0,("resolve_ads: malloc failed for %d entries\n",
1427 talloc_destroy(ctx
);
1428 return NT_STATUS_NO_MEMORY
;
1431 /* now unroll the list of IP addresses */
1436 while ( i
< numdcs
&& (*return_count
<numaddrs
) ) {
1437 struct ip_service
*r
= &(*return_iplist
)[*return_count
];
1439 r
->port
= dcs
[i
].port
;
1441 /* If we don't have an IP list for a name, lookup it up */
1444 interpret_string_addr(&r
->ss
, dcs
[i
].hostname
, 0);
1448 /* use the IP addresses from the SRV sresponse */
1450 if ( j
>= dcs
[i
].num_ips
) {
1456 r
->ss
= dcs
[i
].ss_s
[j
];
1460 /* make sure it is a valid IP. I considered checking the
1461 * negative connection cache, but this is the wrong place
1462 * for it. Maybe only as a hack. After think about it, if
1463 * all of the IP addresses returned from DNS are dead, what
1464 * hope does a netbios name lookup have ? The standard reason
1465 * for falling back to netbios lookups is that our DNS server
1466 * doesn't know anything about the DC's -- jerry */
1468 if (!is_zero_addr((struct sockaddr
*)&r
->ss
)) {
1473 talloc_destroy(ctx
);
1474 return NT_STATUS_OK
;
1477 /*******************************************************************
1478 Internal interface to resolve a name into an IP address.
1479 Use this function if the string is either an IP address, DNS
1480 or host name or NetBIOS name. This uses the name switch in the
1481 smb.conf to determine the order of name resolution.
1483 Added support for ip addr/port to support ADS ldap servers.
1484 the only place we currently care about the port is in the
1485 resolve_hosts() when looking up DC's via SRV RR entries in DNS
1486 **********************************************************************/
1488 NTSTATUS
internal_resolve_name(const char *name
,
1490 const char *sitename
,
1491 struct ip_service
**return_iplist
,
1493 const char *resolve_order
)
1497 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
1499 TALLOC_CTX
*frame
= NULL
;
1501 *return_iplist
= NULL
;
1504 DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n",
1505 name
, name_type
, sitename
? sitename
: "(null)"));
1507 if (is_ipaddress(name
)) {
1508 if ((*return_iplist
= SMB_MALLOC_P(struct ip_service
)) ==
1510 DEBUG(0,("internal_resolve_name: malloc fail !\n"));
1511 return NT_STATUS_NO_MEMORY
;
1514 /* ignore the port here */
1515 (*return_iplist
)->port
= PORT_NONE
;
1517 /* if it's in the form of an IP address then get the lib to interpret it */
1518 if (!interpret_string_addr(&(*return_iplist
)->ss
,
1519 name
, AI_NUMERICHOST
)) {
1520 DEBUG(1,("internal_resolve_name: interpret_string_addr "
1523 SAFE_FREE(*return_iplist
);
1524 return NT_STATUS_INVALID_PARAMETER
;
1527 return NT_STATUS_OK
;
1530 /* Check name cache */
1532 if (namecache_fetch(name
, name_type
, return_iplist
, return_count
)) {
1533 /* This could be a negative response */
1534 if (*return_count
> 0) {
1535 return NT_STATUS_OK
;
1537 return NT_STATUS_UNSUCCESSFUL
;
1541 /* set the name resolution order */
1543 if (strcmp( resolve_order
, "NULL") == 0) {
1544 DEBUG(8,("internal_resolve_name: all lookups disabled\n"));
1545 return NT_STATUS_INVALID_PARAMETER
;
1548 if (!resolve_order
[0]) {
1551 ptr
= resolve_order
;
1554 /* iterate through the name resolution backends */
1556 frame
= talloc_stackframe();
1557 while (next_token_talloc(frame
, &ptr
, &tok
, LIST_SEP
)) {
1558 if((strequal(tok
, "host") || strequal(tok
, "hosts"))) {
1559 status
= resolve_hosts(name
, name_type
, return_iplist
,
1561 if (NT_STATUS_IS_OK(status
)) {
1564 } else if(strequal( tok
, "kdc")) {
1565 /* deal with KDC_NAME_TYPE names here.
1566 * This will result in a SRV record lookup */
1567 status
= resolve_ads(name
, KDC_NAME_TYPE
, sitename
,
1568 return_iplist
, return_count
);
1569 if (NT_STATUS_IS_OK(status
)) {
1570 /* Ensure we don't namecache
1571 * this with the KDC port. */
1572 name_type
= KDC_NAME_TYPE
;
1575 } else if(strequal( tok
, "ads")) {
1576 /* deal with 0x1c and 0x1b names here.
1577 * This will result in a SRV record lookup */
1578 status
= resolve_ads(name
, name_type
, sitename
,
1579 return_iplist
, return_count
);
1580 if (NT_STATUS_IS_OK(status
)) {
1583 } else if(strequal( tok
, "lmhosts")) {
1584 status
= resolve_lmhosts(name
, name_type
,
1585 return_iplist
, return_count
);
1586 if (NT_STATUS_IS_OK(status
)) {
1589 } else if(strequal( tok
, "wins")) {
1590 /* don't resolve 1D via WINS */
1591 if (name_type
!= 0x1D) {
1592 status
= resolve_wins(name
, name_type
,
1595 if (NT_STATUS_IS_OK(status
)) {
1599 } else if(strequal( tok
, "bcast")) {
1600 status
= name_resolve_bcast(name
, name_type
,
1603 if (NT_STATUS_IS_OK(status
)) {
1607 DEBUG(0,("resolve_name: unknown name switch type %s\n",
1612 /* All of the resolve_* functions above have returned false. */
1615 SAFE_FREE(*return_iplist
);
1618 return NT_STATUS_UNSUCCESSFUL
;
1622 /* Remove duplicate entries. Some queries, notably #1c (domain
1623 controllers) return the PDC in iplist[0] and then all domain
1624 controllers including the PDC in iplist[1..n]. Iterating over
1625 the iplist when the PDC is down will cause two sets of timeouts. */
1627 if ( *return_count
) {
1628 *return_count
= remove_duplicate_addrs2(*return_iplist
,
1632 /* Save in name cache */
1633 if ( DEBUGLEVEL
>= 100 ) {
1634 for (i
= 0; i
< *return_count
&& DEBUGLEVEL
== 100; i
++) {
1635 char addr
[INET6_ADDRSTRLEN
];
1636 print_sockaddr(addr
, sizeof(addr
),
1637 &(*return_iplist
)[i
].ss
);
1638 DEBUG(100, ("Storing name %s of type %d (%s:%d)\n",
1642 (*return_iplist
)[i
].port
));
1646 namecache_store(name
, name_type
, *return_count
, *return_iplist
);
1648 /* Display some debugging info */
1650 if ( DEBUGLEVEL
>= 10 ) {
1651 DEBUG(10, ("internal_resolve_name: returning %d addresses: ",
1654 for (i
= 0; i
< *return_count
; i
++) {
1655 char addr
[INET6_ADDRSTRLEN
];
1656 print_sockaddr(addr
, sizeof(addr
),
1657 &(*return_iplist
)[i
].ss
);
1658 DEBUGADD(10, ("%s:%d ",
1660 (*return_iplist
)[i
].port
));
1669 /********************************************************
1670 Internal interface to resolve a name into one IP address.
1671 Use this function if the string is either an IP address, DNS
1672 or host name or NetBIOS name. This uses the name switch in the
1673 smb.conf to determine the order of name resolution.
1674 *********************************************************/
1676 bool resolve_name(const char *name
,
1677 struct sockaddr_storage
*return_ss
,
1680 struct ip_service
*ss_list
= NULL
;
1681 char *sitename
= NULL
;
1684 if (is_ipaddress(name
)) {
1685 return interpret_string_addr(return_ss
, name
, AI_NUMERICHOST
);
1688 sitename
= sitename_fetch(lp_realm()); /* wild guess */
1690 if (NT_STATUS_IS_OK(internal_resolve_name(name
, name_type
, sitename
,
1692 lp_name_resolve_order()))) {
1695 /* only return valid addresses for TCP connections */
1696 for (i
=0; i
<count
; i
++) {
1697 if (!is_zero_addr((struct sockaddr
*)&ss_list
[i
].ss
) &&
1698 !is_broadcast_addr((struct sockaddr
*)&ss_list
[i
].ss
)) {
1699 *return_ss
= ss_list
[i
].ss
;
1701 SAFE_FREE(sitename
);
1708 SAFE_FREE(sitename
);
1712 /********************************************************
1713 Internal interface to resolve a name into a list of IP addresses.
1714 Use this function if the string is either an IP address, DNS
1715 or host name or NetBIOS name. This uses the name switch in the
1716 smb.conf to determine the order of name resolution.
1717 *********************************************************/
1719 NTSTATUS
resolve_name_list(TALLOC_CTX
*ctx
,
1722 struct sockaddr_storage
**return_ss_arr
,
1723 unsigned int *p_num_entries
)
1725 struct ip_service
*ss_list
= NULL
;
1726 char *sitename
= NULL
;
1729 unsigned int num_entries
;
1733 *return_ss_arr
= NULL
;
1735 if (is_ipaddress(name
)) {
1736 *return_ss_arr
= TALLOC_P(ctx
, struct sockaddr_storage
);
1737 if (!*return_ss_arr
) {
1738 return NT_STATUS_NO_MEMORY
;
1740 if (!interpret_string_addr(*return_ss_arr
, name
, AI_NUMERICHOST
)) {
1741 TALLOC_FREE(*return_ss_arr
);
1742 return NT_STATUS_BAD_NETWORK_NAME
;
1745 return NT_STATUS_OK
;
1748 sitename
= sitename_fetch(lp_realm()); /* wild guess */
1750 status
= internal_resolve_name(name
, name_type
, sitename
,
1752 lp_name_resolve_order());
1753 SAFE_FREE(sitename
);
1755 if (!NT_STATUS_IS_OK(status
)) {
1759 /* only return valid addresses for TCP connections */
1760 for (i
=0, num_entries
= 0; i
<count
; i
++) {
1761 if (!is_zero_addr((struct sockaddr
*)&ss_list
[i
].ss
) &&
1762 !is_broadcast_addr((struct sockaddr
*)&ss_list
[i
].ss
)) {
1766 if (num_entries
== 0) {
1768 return NT_STATUS_BAD_NETWORK_NAME
;
1771 *return_ss_arr
= TALLOC_ARRAY(ctx
,
1772 struct sockaddr_storage
,
1774 if (!(*return_ss_arr
)) {
1776 return NT_STATUS_NO_MEMORY
;
1779 for (i
=0, num_entries
= 0; i
<count
; i
++) {
1780 if (!is_zero_addr((struct sockaddr
*)&ss_list
[i
].ss
) &&
1781 !is_broadcast_addr((struct sockaddr
*)&ss_list
[i
].ss
)) {
1782 (*return_ss_arr
)[num_entries
++] = ss_list
[i
].ss
;
1786 status
= NT_STATUS_OK
;
1787 *p_num_entries
= num_entries
;
1790 return NT_STATUS_OK
;
1793 /********************************************************
1794 Find the IP address of the master browser or DMB for a workgroup.
1795 *********************************************************/
1797 bool find_master_ip(const char *group
, struct sockaddr_storage
*master_ss
)
1799 struct ip_service
*ip_list
= NULL
;
1803 if (lp_disable_netbios()) {
1804 DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group
));
1808 status
= internal_resolve_name(group
, 0x1D, NULL
, &ip_list
, &count
,
1809 lp_name_resolve_order());
1810 if (NT_STATUS_IS_OK(status
)) {
1811 *master_ss
= ip_list
[0].ss
;
1816 status
= internal_resolve_name(group
, 0x1B, NULL
, &ip_list
, &count
,
1817 lp_name_resolve_order());
1818 if (NT_STATUS_IS_OK(status
)) {
1819 *master_ss
= ip_list
[0].ss
;
1828 /********************************************************
1829 Get the IP address list of the primary domain controller
1831 *********************************************************/
1833 bool get_pdc_ip(const char *domain
, struct sockaddr_storage
*pss
)
1835 struct ip_service
*ip_list
= NULL
;
1837 NTSTATUS status
= NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND
;
1839 /* Look up #1B name */
1841 if (lp_security() == SEC_ADS
) {
1842 status
= internal_resolve_name(domain
, 0x1b, NULL
, &ip_list
,
1846 if (!NT_STATUS_IS_OK(status
) || count
== 0) {
1847 status
= internal_resolve_name(domain
, 0x1b, NULL
, &ip_list
,
1849 lp_name_resolve_order());
1850 if (!NT_STATUS_IS_OK(status
)) {
1855 /* if we get more than 1 IP back we have to assume it is a
1856 multi-homed PDC and not a mess up */
1859 DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count
));
1860 sort_service_list(ip_list
, count
);
1863 *pss
= ip_list
[0].ss
;
1868 /* Private enum type for lookups. */
1870 enum dc_lookup_type
{ DC_NORMAL_LOOKUP
, DC_ADS_ONLY
, DC_KDC_ONLY
};
1872 /********************************************************
1873 Get the IP address list of the domain controllers for
1875 *********************************************************/
1877 static NTSTATUS
get_dc_list(const char *domain
,
1878 const char *sitename
,
1879 struct ip_service
**ip_list
,
1881 enum dc_lookup_type lookup_type
,
1884 char *resolve_order
= NULL
;
1885 char *saf_servername
= NULL
;
1886 char *pserver
= NULL
;
1888 char *port_str
= NULL
;
1891 int num_addresses
= 0;
1892 int local_count
, i
, j
;
1893 struct ip_service
*return_iplist
= NULL
;
1894 struct ip_service
*auto_ip_list
= NULL
;
1895 bool done_auto_lookup
= false;
1898 TALLOC_CTX
*ctx
= talloc_init("get_dc_list");
1904 return NT_STATUS_NO_MEMORY
;
1909 /* if we are restricted to solely using DNS for looking
1910 up a domain controller, make sure that host lookups
1911 are enabled for the 'name resolve order'. If host lookups
1912 are disabled and ads_only is True, then set the string to
1915 resolve_order
= talloc_strdup(ctx
, lp_name_resolve_order());
1916 if (!resolve_order
) {
1917 status
= NT_STATUS_NO_MEMORY
;
1920 strlower_m(resolve_order
);
1921 if (lookup_type
== DC_ADS_ONLY
) {
1922 if (strstr( resolve_order
, "host")) {
1923 resolve_order
= talloc_strdup(ctx
, "ads");
1925 /* DNS SRV lookups used by the ads resolver
1926 are already sorted by priority and weight */
1929 resolve_order
= talloc_strdup(ctx
, "NULL");
1931 } else if (lookup_type
== DC_KDC_ONLY
) {
1932 /* DNS SRV lookups used by the ads/kdc resolver
1933 are already sorted by priority and weight */
1935 resolve_order
= talloc_strdup(ctx
, "kdc");
1937 if (!resolve_order
) {
1938 status
= NT_STATUS_NO_MEMORY
;
1942 /* fetch the server we have affinity for. Add the
1943 'password server' list to a search for our domain controllers */
1945 saf_servername
= saf_fetch( domain
);
1947 if (strequal(domain
, lp_workgroup()) || strequal(domain
, lp_realm())) {
1948 pserver
= talloc_asprintf(NULL
, "%s, %s",
1949 saf_servername
? saf_servername
: "",
1950 lp_passwordserver());
1952 pserver
= talloc_asprintf(NULL
, "%s, *",
1953 saf_servername
? saf_servername
: "");
1956 SAFE_FREE(saf_servername
);
1958 status
= NT_STATUS_NO_MEMORY
;
1962 /* if we are starting from scratch, just lookup DOMAIN<0x1c> */
1965 DEBUG(10,("get_dc_list: no preferred domain controllers.\n"));
1966 status
= internal_resolve_name(domain
, 0x1C, sitename
, ip_list
,
1967 count
, resolve_order
);
1971 DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver
));
1974 * if '*' appears in the "password server" list then add
1975 * an auto lookup to the list of manually configured
1976 * DC's. If any DC is listed by name, then the list should be
1977 * considered to be ordered
1981 while (next_token_talloc(ctx
, &p
, &name
, LIST_SEP
)) {
1982 if (!done_auto_lookup
&& strequal(name
, "*")) {
1983 status
= internal_resolve_name(domain
, 0x1C, sitename
,
1987 if (NT_STATUS_IS_OK(status
)) {
1988 num_addresses
+= auto_count
;
1990 done_auto_lookup
= true;
1991 DEBUG(8,("Adding %d DC's from auto lookup\n",
1998 /* if we have no addresses and haven't done the auto lookup, then
1999 just return the list of DC's. Or maybe we just failed. */
2001 if ((num_addresses
== 0)) {
2002 if (done_auto_lookup
) {
2003 DEBUG(4,("get_dc_list: no servers found\n"));
2004 status
= NT_STATUS_NO_LOGON_SERVERS
;
2007 status
= internal_resolve_name(domain
, 0x1C, sitename
, ip_list
,
2008 count
, resolve_order
);
2012 if ((return_iplist
= SMB_MALLOC_ARRAY(struct ip_service
,
2013 num_addresses
)) == NULL
) {
2014 DEBUG(3,("get_dc_list: malloc fail !\n"));
2015 status
= NT_STATUS_NO_MEMORY
;
2022 /* fill in the return list now with real IP's */
2024 while ((local_count
<num_addresses
) &&
2025 next_token_talloc(ctx
, &p
, &name
, LIST_SEP
)) {
2026 struct sockaddr_storage name_ss
;
2028 /* copy any addersses from the auto lookup */
2030 if (strequal(name
, "*")) {
2031 for (j
=0; j
<auto_count
; j
++) {
2032 char addr
[INET6_ADDRSTRLEN
];
2033 print_sockaddr(addr
,
2035 &auto_ip_list
[j
].ss
);
2036 /* Check for and don't copy any
2037 * known bad DC IP's. */
2038 if(!NT_STATUS_IS_OK(check_negative_conn_cache(
2041 DEBUG(5,("get_dc_list: "
2042 "negative entry %s removed "
2047 return_iplist
[local_count
].ss
=
2049 return_iplist
[local_count
].port
=
2050 auto_ip_list
[j
].port
;
2056 /* added support for address:port syntax for ads
2057 * (not that I think anyone will ever run the LDAP
2058 * server in an AD domain on something other than
2061 port
= (lp_security() == SEC_ADS
) ? LDAP_PORT
: PORT_NONE
;
2062 if ((port_str
=strchr(name
, ':')) != NULL
) {
2065 port
= atoi(port_str
);
2068 /* explicit lookup; resolve_name() will
2069 * handle names & IP addresses */
2070 if (resolve_name( name
, &name_ss
, 0x20 )) {
2071 char addr
[INET6_ADDRSTRLEN
];
2072 print_sockaddr(addr
,
2076 /* Check for and don't copy any known bad DC IP's. */
2077 if( !NT_STATUS_IS_OK(check_negative_conn_cache(domain
,
2079 DEBUG(5,("get_dc_list: negative entry %s "
2080 "removed from DC list\n",
2085 return_iplist
[local_count
].ss
= name_ss
;
2086 return_iplist
[local_count
].port
= port
;
2092 /* need to remove duplicates in the list if we have any
2093 explicit password servers */
2096 local_count
= remove_duplicate_addrs2(return_iplist
,
2100 if ( DEBUGLEVEL
>= 4 ) {
2101 DEBUG(4,("get_dc_list: returning %d ip addresses "
2102 "in an %sordered list\n",
2104 *ordered
? "":"un"));
2105 DEBUG(4,("get_dc_list: "));
2106 for ( i
=0; i
<local_count
; i
++ ) {
2107 char addr
[INET6_ADDRSTRLEN
];
2108 print_sockaddr(addr
,
2110 &return_iplist
[i
].ss
);
2111 DEBUGADD(4,("%s:%d ", addr
, return_iplist
[i
].port
));
2116 *ip_list
= return_iplist
;
2117 *count
= local_count
;
2119 status
= ( *count
!= 0 ? NT_STATUS_OK
: NT_STATUS_NO_LOGON_SERVERS
);
2123 if (!NT_STATUS_IS_OK(status
)) {
2124 SAFE_FREE(return_iplist
);
2129 SAFE_FREE(auto_ip_list
);
2134 /*********************************************************************
2135 Small wrapper function to get the DC list and sort it if neccessary.
2136 *********************************************************************/
2138 NTSTATUS
get_sorted_dc_list( const char *domain
,
2139 const char *sitename
,
2140 struct ip_service
**ip_list
,
2144 bool ordered
= false;
2146 enum dc_lookup_type lookup_type
= DC_NORMAL_LOOKUP
;
2151 DEBUG(8,("get_sorted_dc_list: attempting lookup "
2152 "for name %s (sitename %s) using [%s]\n",
2154 sitename
? sitename
: "NULL",
2155 (ads_only
? "ads" : lp_name_resolve_order())));
2158 lookup_type
= DC_ADS_ONLY
;
2161 status
= get_dc_list(domain
, sitename
, ip_list
,
2162 count
, lookup_type
, &ordered
);
2163 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_LOGON_SERVERS
)
2165 DEBUG(3,("get_sorted_dc_list: no server for name %s available"
2166 " in site %s, fallback to all servers\n",
2168 status
= get_dc_list(domain
, NULL
, ip_list
,
2169 count
, lookup_type
, &ordered
);
2172 if (!NT_STATUS_IS_OK(status
)) {
2173 SAFE_FREE(*ip_list
);
2178 /* only sort if we don't already have an ordered list */
2180 sort_service_list(*ip_list
, *count
);
2183 return NT_STATUS_OK
;
2186 /*********************************************************************
2187 Get the KDC list - re-use all the logic in get_dc_list.
2188 *********************************************************************/
2190 NTSTATUS
get_kdc_list( const char *realm
,
2191 const char *sitename
,
2192 struct ip_service
**ip_list
,
2201 status
= get_dc_list(realm
, sitename
, ip_list
,
2202 count
, DC_KDC_ONLY
, &ordered
);
2204 if (!NT_STATUS_IS_OK(status
)) {
2205 SAFE_FREE(*ip_list
);
2210 /* only sort if we don't already have an ordered list */
2212 sort_service_list(*ip_list
, *count
);
2215 return NT_STATUS_OK
;