Index: source/nsswitch/winbindd_cm.c =================================================================== --- source/nsswitch/winbindd_cm.c (revision 5286) +++ source/nsswitch/winbindd_cm.c (working copy) @@ -459,63 +459,30 @@ return True; } -static BOOL get_dcs_1c(TALLOC_CTX *mem_ctx, - const struct winbindd_domain *domain, - struct dc_name_ip **dcs, int *num_dcs) -{ - struct ip_service *iplist = NULL; - int i, num = 0; - - if (!internal_resolve_name(domain->name, 0x1c, &iplist, &num, - lp_name_resolve_order())) - return False; - - /* Now try to find the server names of at least one IP address, hosts - * not replying are cached as such */ - - for (i=0; iname, 0x1c, 0x20, iplist[i].ip, - dcname)) - continue; - - if (add_one_dc_unique(mem_ctx, domain->name, dcname, - iplist[i].ip, dcs, num_dcs)) { - /* One DC responded, so we assume that he will also - work on 139/445 */ - break; - } - } - - SAFE_FREE(iplist); - - return True; -} - static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain, struct dc_name_ip **dcs, int *num_dcs) { fstring dcname; - struct in_addr ip; - BOOL is_our_domain; + struct in_addr ip; + struct ip_service *ip_list = NULL; + int iplist_size = 0; + int i; + BOOL is_our_domain; - const char *p; is_our_domain = strequal(domain->name, lp_workgroup()); - if (!is_our_domain && get_dc_name_via_netlogon(domain, dcname, &ip) && - add_one_dc_unique(mem_ctx, domain->name, dcname, ip, dcs, num_dcs)) - return True; - - if (!is_our_domain) { - /* NETLOGON to our own domain could not give us a DC name - * (which is an error), fall back to looking up domain#1c */ - return get_dcs_1c(mem_ctx, domain, dcs, num_dcs); + if ( !is_our_domain + && get_dc_name_via_netlogon(domain, dcname, &ip) + && add_one_dc_unique(mem_ctx, domain->name, dcname, ip, dcs, num_dcs) ) + { + return True; } - if (must_use_pdc(domain->name) && get_pdc_ip(domain->name, &ip)) { + if ( is_our_domain + && must_use_pdc(domain->name) + && get_pdc_ip(domain->name, &ip)) + { if (!name_status_find(domain->name, 0x1b, 0x20, ip, dcname)) return False; @@ -525,31 +492,30 @@ return True; } - p = lp_passwordserver(); + /* check for security = ads and use DNS if we can */ - if (*p == 0) - return get_dcs_1c(mem_ctx, domain, dcs, num_dcs); + if ( lp_security() == SEC_ADS ) { + if ( get_sorted_dc_list(domain->alt_name, &ip_list, &iplist_size, True) ) { + for ( i=0; iname, "", ip_list[i].ip, dcs, num_dcs); - while (next_token(&p, dcname, LIST_SEP, sizeof(dcname))) { - - if (strequal(dcname, "*")) { - get_dcs_1c(mem_ctx, domain, dcs, num_dcs); - continue; + goto out; } + } - if (!resolve_name(dcname, &ip, 0x20)) - continue; + /* fall back to standard netbios queries */ - /* Even if we got the dcname, double check the name to use for - * the netlogon auth2 */ + if ( !get_sorted_dc_list(domain->name, &ip_list, &iplist_size, False) ) + return False; - if (!name_status_find(domain->name, 0x1c, 0x20, ip, dcname)) - continue; + /* now add to the dc array */ - add_one_dc_unique(mem_ctx, domain->name, dcname, ip, - dcs, num_dcs); - } + for ( i=0; iname, "", ip_list[i].ip, dcs, num_dcs); +out: + SAFE_FREE( ip_list ); + return True; } @@ -596,9 +562,52 @@ return False; } + *addr = addrs[fd_index]; fstrcpy(dcname, dcnames[fd_index]); - *addr = addrs[fd_index]; + /* if we have no name on the server, now try to get the name */ + + if ( *dcname == '\0' ) + { + /* try node status request first */ + + if ( name_status_find(domain->name, 0x1c, 0x20, addr->sin_addr, dcname) ) + return True; + + /* backup in case the ads stuff fails */ + + fstrcpy( dcname, inet_ntoa(addr->sin_addr) ); + + /* for active directory servers, try to get the ldap server name. + None of these failure should be considered critical for now */ + + if ( lp_security() == SEC_ADS ) + { + ADS_STRUCT *ads; + ADS_STATUS status; + + ads = ads_init( domain->alt_name, domain->name, NULL ); + ads->auth.flags |= ADS_AUTH_NO_BIND; + + if ( !ads_try_connect( ads, inet_ntoa(addr->sin_addr), LDAP_PORT ) ) { + ads_destroy( &ads ); + return True; + } + + status = ads_server_info(ads); + if ( !ADS_ERR_OK(status) ) { + ads_destroy( &ads ); + return True; + } + + fstrcpy(dcname, ads->config.ldap_server_name); + + ads_destroy( &ads ); + return True; + } + + } + return True; } @@ -883,6 +892,11 @@ done: + DEBUG(3,("add_trusted_domain: %s is an %s %s domain\n", domain->name, + domain->active_directory ? "ADS" : "NT4", + domain->native_mode ? "native mode" : + ((domain->active_directory && !domain->native_mode) ? "mixed mode" : ""))); + /* close the connection; no other calls use this pipe and it is called only on reestablishing the domain list --jerry */ Index: source/nsswitch/winbindd_util.c =================================================================== --- source/nsswitch/winbindd_util.c (revision 5286) +++ source/nsswitch/winbindd_util.c (working copy) @@ -167,11 +167,6 @@ sid_copy(&domain->sid, sid); } - DEBUG(3,("add_trusted_domain: %s is an %s %s domain\n", domain->name, - domain->active_directory ? "ADS" : "NT4", - domain->native_mode ? "native mode" : - ((domain->active_directory && !domain->native_mode) ? "mixed mode" : ""))); - /* Link to domain list */ DLIST_ADD(_domain_list, domain); Index: source/libads/ldap.c =================================================================== --- source/libads/ldap.c (revision 5286) +++ source/libads/ldap.c (working copy) @@ -112,7 +112,7 @@ TODO : add a negative connection cache in here leveraged off of the one found in the rpc code. --jerry */ -static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) +BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, unsigned port) { char *srv;