From 7c5c2de3f621e6638a0dda65bd97d389446e4d87 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 22 Oct 2008 10:36:21 +0200 Subject: [PATCH] s3: correctly detect if the current dc is the closest one ads->config.tried_closest_dc was never set. metze Signed-off-by: Stefan Metzmacher --- source/include/ads.h | 1 - source/utils/net_ads.c | 2 +- 2 files changed, 1 insertions(+), 2 deletions(-) diff --git a/source/include/ads.h b/source/include/ads.h index 24884f5..1f4cc7a 100644 --- a/source/include/ads.h +++ b/source/include/ads.h @@ -56,7 +56,6 @@ typedef struct { char *server_site_name; char *client_site_name; time_t current_time; - int tried_closest_dc; } config; } ADS_STRUCT; diff --git a/source/utils/net_ads.c b/source/utils/net_ads.c index d6a52b8..f0ffe34 100644 --- a/source/utils/net_ads.c +++ b/source/utils/net_ads.c @@ -306,7 +306,7 @@ retry: tried_closest_dc = True; /* avoid loop */ - if (!ads->config.tried_closest_dc) { + if (!ads_closest_dc(ads)) { namecache_delete(ads->server.realm, 0x1C); namecache_delete(ads->server.workgroup, 0x1C); -- 1.5.4.3 From 9c82d38d0c4922355c319233c1cc1ae7680aaad5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 22 Oct 2008 11:14:10 +0200 Subject: [PATCH] s3: libads: use get_dc_name() instead of get_sorted_dc_list() in the LDAP case We use get_dc_name() for LDAP because it generates the selfwritten krb5.conf with the correct kdc addresses and sets KRB5_CONFIG. For CLDAP we need to use get_sorted_dc_list() to avoid recursion. metze Signed-off-by: Stefan Metzmacher --- source/libads/ldap.c | 26 +++++++++++++++++++++++++- 1 files changed, 25 insertions(+), 1 deletions(-) diff --git a/source/libads/ldap.c b/source/libads/ldap.c index 67c5470..a57a0d1 100644 --- a/source/libads/ldap.c +++ b/source/libads/ldap.c @@ -286,11 +286,35 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) pstrcpy( realm, c_realm ); + /* + * In case of LDAP we use get_dc_name() as that + * creates the custom krb5.conf file + */ + if (!(ads->auth.flags & ADS_AUTH_NO_BIND)) { + fstring srv_name; + struct in_addr ip_out; + + DEBUG(6,("ads_find_dc: (ldap) looking for %s '%s'\n", + (got_realm ? "realm" : "domain"), realm)); + + if (get_dc_name(realm, realm, srv_name, &ip_out)) { + /* + * we call ads_try_connect() to fill in the + * ads->config details + */ + if (ads_try_connect(ads, srv_name)) { + return NT_STATUS_OK; + } + } + + return NT_STATUS_NO_LOGON_SERVERS; + } + sitename = sitename_fetch(realm); again: - DEBUG(6,("ads_find_dc: looking for %s '%s'\n", + DEBUG(6,("ads_find_dc: (cldap) looking for %s '%s'\n", (got_realm ? "realm" : "domain"), realm)); status = get_sorted_dc_list(realm, sitename, &ip_list, &count, got_realm); -- 1.5.4.3 From 12ecbffaabf3204993726abd9df56b946a1017e2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 27 Oct 2008 09:40:25 +0100 Subject: [PATCH] libsmb/namequery: fallback to returning all dcs, when none is available in the requested site It could happen that all dcs in a site are unavailable (some sites have only one dc) and then we need to fallback to get all dcs. metze Signed-off-by: Stefan Metzmacher --- source/libsmb/namequery.c | 8 ++++++++ 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c index b2a4156..0eb34e9 100644 --- a/source/libsmb/namequery.c +++ b/source/libsmb/namequery.c @@ -1648,6 +1648,14 @@ NTSTATUS get_sorted_dc_list( const char *domain, const char *sitename, struct ip } status = get_dc_list(domain, sitename, ip_list, count, lookup_type, &ordered); + if (NT_STATUS_EQUAL(status, NT_STATUS_NO_LOGON_SERVERS) && sitename) { + DEBUG(3,("get_sorted_dc_list: no server for name %s available" + " in site %s, fallback to all servers\n", + domain, sitename)); + status = get_dc_list(domain, NULL, ip_list, count, + lookup_type, &ordered); + } + if (!NT_STATUS_IS_OK(status)) { return status; } -- 1.5.4.3 From 65c687c71ed27b90fafacd6954ecb3663e1d5852 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 27 Oct 2008 19:31:30 +0100 Subject: [PATCH] libsmb/namequery.c: add saf_join_store() function saf_join_store() should be called after a successful domain join, the affinity to the dc used at join time has a larger ttl, to avoid problems with delayed replication. metze Signed-off-by: Stefan Metzmacher --- source/libsmb/namequery.c | 72 +++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 67 insertions(+), 5 deletions(-) diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c index 0eb34e9..023fd3f 100644 --- a/source/libsmb/namequery.c +++ b/source/libsmb/namequery.c @@ -34,6 +34,8 @@ BOOL global_in_nmbd = False; ****************************************************************************/ #define SAFKEY_FMT "SAF/DOMAIN/%s" #define SAF_TTL 900 +#define SAFJOINKEY_FMT "SAFJOIN/DOMAIN/%s" +#define SAFJOIN_TTL 3600 static char *saf_key(const char *domain) { @@ -44,6 +46,15 @@ static char *saf_key(const char *domain) return keystr; } +static char *saf_join_key(const char *domain) +{ + char *keystr; + + asprintf( &keystr, SAFJOINKEY_FMT, strupper_static(domain) ); + + return keystr; +} + /**************************************************************************** ****************************************************************************/ @@ -67,7 +78,7 @@ BOOL saf_store( const char *domain, const char *servername ) return False; key = saf_key( domain ); - expire = time( NULL ) + SAF_TTL; + expire = time( NULL ) + lp_parm_int(-1, "saf","ttl", SAF_TTL); DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n", @@ -80,6 +91,38 @@ BOOL saf_store( const char *domain, const char *servername ) return ret; } +BOOL saf_join_store( const char *domain, const char *servername ) +{ + char *key; + time_t expire; + BOOL ret = False; + + if ( !domain || !servername ) { + DEBUG(2,("saf_join_store: Refusing to store empty domain or servername!\n")); + return False; + } + + if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) { + DEBUG(0,("saf_join_store: refusing to store 0 length domain or servername!\n")); + return False; + } + + if ( !gencache_init() ) + return False; + + key = saf_join_key( domain ); + expire = time( NULL ) + lp_parm_int(-1, "saf","join ttl", SAFJOIN_TTL); + + DEBUG(10,("saf_join_store: domain = [%s], server = [%s], expire = [%u]\n", + domain, servername, (unsigned int)expire )); + + ret = gencache_set( key, servername, expire ); + + SAFE_FREE( key ); + + return ret; +} + BOOL saf_delete( const char *domain ) { char *key; @@ -93,15 +136,22 @@ BOOL saf_delete( const char *domain ) if ( !gencache_init() ) return False; + key = saf_join_key(domain); + ret = gencache_del(key); + SAFE_FREE(key); + + if (ret) { + DEBUG(10,("saf_delete[join]: domain = [%s]\n", domain )); + } + key = saf_key(domain); ret = gencache_del(key); - + SAFE_FREE(key); + if (ret) { DEBUG(10,("saf_delete: domain = [%s]\n", domain )); } - SAFE_FREE( key ); - return ret; } @@ -122,7 +172,19 @@ char *saf_fetch( const char *domain ) if ( !gencache_init() ) return False; - + + key = saf_join_key( domain ); + + ret = gencache_get( key, &server, &timeout ); + + SAFE_FREE( key ); + + if ( ret ) { + DEBUG(5,("saf_fetch[join]: Returning \"%s\" for \"%s\" domain\n", + server, domain )); + return server; + } + key = saf_key( domain ); ret = gencache_get( key, &server, &timeout ); -- 1.5.4.3 From 1a330771921e1eb1ff148875bf5db5708d533521 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 27 Oct 2008 19:36:25 +0100 Subject: [PATCH] libads/ldap.c: pass the real workgroup name to get_dc_name() metze Signed-off-by: Stefan Metzmacher --- source/libads/ldap.c | 13 +++++++++++-- 1 files changed, 11 insertions(+), 2 deletions(-) diff --git a/source/libads/ldap.c b/source/libads/ldap.c index a57a0d1..424f975 100644 --- a/source/libads/ldap.c +++ b/source/libads/ldap.c @@ -243,9 +243,11 @@ BOOL ads_try_connect(ADS_STRUCT *ads, const char *server ) static NTSTATUS ads_find_dc(ADS_STRUCT *ads) { + const char *c_domain; const char *c_realm; int count, i=0; struct ip_service *ip_list; + pstring domain; pstring realm; BOOL got_realm = False; BOOL use_own_domain = False; @@ -283,7 +285,14 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) return NT_STATUS_INVALID_PARAMETER; /* rather need MISSING_PARAMETER ... */ } } - + + if ( use_own_domain ) { + c_domain = lp_workgroup(); + } else { + c_domain = ads->server.workgroup; + } + + pstrcpy( domain, c_domain ); pstrcpy( realm, c_realm ); /* @@ -297,7 +306,7 @@ static NTSTATUS ads_find_dc(ADS_STRUCT *ads) DEBUG(6,("ads_find_dc: (ldap) looking for %s '%s'\n", (got_realm ? "realm" : "domain"), realm)); - if (get_dc_name(realm, realm, srv_name, &ip_out)) { + if (get_dc_name(domain, realm, srv_name, &ip_out)) { /* * we call ads_try_connect() to fill in the * ads->config details -- 1.5.4.3 From 613612fa01cc9aed8734c5f1c994a2f7f106dd61 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 27 Oct 2008 19:38:15 +0100 Subject: [PATCH] libads/ldap.c: if the client belongs to no site at all any dc is the closest metze Signed-off-by: Stefan Metzmacher --- source/libads/ldap.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/source/libads/ldap.c b/source/libads/ldap.c index 424f975..a93bd56 100644 --- a/source/libads/ldap.c +++ b/source/libads/ldap.c @@ -156,6 +156,11 @@ BOOL ads_closest_dc(ADS_STRUCT *ads) return True; } + if (ads->config.client_site_name == NULL) { + DEBUG(10,("ads_closest_dc: client belongs to no site\n")); + return True; + } + DEBUG(10,("ads_closest_dc: %s is not the closest DC\n", ads->config.ldap_server_name)); -- 1.5.4.3 From 154b23e0a35dd2566a9ba52dcab3ada68b287d7b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 27 Oct 2008 19:39:30 +0100 Subject: [PATCH] libads/ldap.c: store the dc name in the saf cache as in all other places metze Signed-off-by: Stefan Metzmacher --- source/libads/ldap.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/libads/ldap.c b/source/libads/ldap.c index a93bd56..4e18ff7 100644 --- a/source/libads/ldap.c +++ b/source/libads/ldap.c @@ -473,8 +473,8 @@ got_connection: /* cache the successful connection for workgroup and realm */ if (ads_closest_dc(ads)) { - saf_store( ads->server.workgroup, inet_ntoa(ads->ldap_ip)); - saf_store( ads->server.realm, inet_ntoa(ads->ldap_ip)); + saf_store( ads->server.workgroup, ads->config.ldap_server_name); + saf_store( ads->server.realm, ads->config.ldap_server_name); } ldap_set_option(ads->ld, LDAP_OPT_PROTOCOL_VERSION, &version); -- 1.5.4.3 From 0571855864d9c32644a8afc07e43e161bf085dd1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 27 Oct 2008 19:40:23 +0100 Subject: [PATCH] utils/net_ads.c: call saf_join_store() after a the join. metze Signed-off-by: Stefan Metzmacher --- source/utils/net_ads.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/source/utils/net_ads.c b/source/utils/net_ads.c index f0ffe34..6d06466 100644 --- a/source/utils/net_ads.c +++ b/source/utils/net_ads.c @@ -1575,6 +1575,9 @@ int net_ads_join(int argc, const char **argv) goto fail; } + saf_join_store(ads->server.workgroup, ads->config.ldap_server_name); + saf_join_store(ads->server.realm, ads->config.ldap_server_name); + /* Verify that everything is ok */ if ( net_rpc_join_ok(short_domain_name, ads->config.ldap_server_name, &ads->ldap_ip) != 0 ) { -- 1.5.4.3