From baf9b78d47079b81cf33682ee481cf6e30ed89e9 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Thu, 21 Feb 2013 12:31:37 -0700 Subject: [PATCH] s3-winbindd: Use common helper function for connecting to ADS Reviewed-by: Andrew Bartlett --- source3/winbindd/idmap_ad.c | 41 ++----------- source3/winbindd/winbindd_ads.c | 125 +++++++++++++++++++++++--------------- source3/winbindd/winbindd_proto.h | 7 +++ 3 files changed, 87 insertions(+), 86 deletions(-) diff --git a/source3/winbindd/idmap_ad.c b/source3/winbindd/idmap_ad.c index 0e00a340bf2..5b9c3774f66 100644 --- a/source3/winbindd/idmap_ad.c +++ b/source3/winbindd/idmap_ad.c @@ -58,13 +58,8 @@ struct idmap_ad_context { static ADS_STATUS ad_idmap_cached_connection_internal(struct idmap_domain *dom) { - ADS_STRUCT *ads; - ADS_STATUS status; - fstring dc_name; - struct sockaddr_storage dc_ip; struct idmap_ad_context *ctx; - char *ldap_server = NULL; - char *realm = NULL; + char *ldap_server, *realm, *password; struct winbindd_domain *wb_dom; DEBUG(10, ("ad_idmap_cached_connection: called for domain '%s'\n", @@ -77,9 +72,6 @@ static ADS_STATUS ad_idmap_cached_connection_internal(struct idmap_domain *dom) return ADS_SUCCESS; } - /* we don't want this to affect the users ccache */ - setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1); - /* * At this point we only have the NetBIOS domain name. * Check if we can get server nam and realm from SAF cache @@ -99,35 +91,12 @@ static ADS_STATUS ad_idmap_cached_connection_internal(struct idmap_domain *dom) realm = wb_dom->alt_name; } - if ( (ads = ads_init(realm, dom->name, ldap_server)) == NULL ) { - DEBUG(1,("ads_init failed\n")); - return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); - } - /* the machine acct password might have change - fetch it every time */ - SAFE_FREE(ads->auth.password); - ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); - - SAFE_FREE(ads->auth.realm); - ads->auth.realm = SMB_STRDUP(lp_realm()); - - /* setup server affinity */ - - get_dc_name(dom->name, realm, dc_name, &dc_ip ); - - status = ads_connect(ads); - if (!ADS_ERR_OK(status)) { - DEBUG(1, ("ad_idmap_cached_connection_internal: failed to " - "connect to AD\n")); - ads_destroy(&ads); - return status; - } - - ads->is_mine = False; - - ctx->ads = ads; + password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); + realm = SMB_STRDUP(lp_realm()); - return ADS_SUCCESS; + return ads_cached_connection_connect(&ctx->ads, realm, dom->name, + ldap_server, password, realm, 0); } /************************************************************************ diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c index 03cbcf23a33..e806aa87f0c 100644 --- a/source3/winbindd/winbindd_ads.c +++ b/source3/winbindd/winbindd_ads.c @@ -72,16 +72,73 @@ void ads_cached_connection_reuse(ADS_STRUCT **adsp) } } +ADS_STATUS ads_cached_connection_connect(ADS_STRUCT **adsp, + const char *dom_name_alt, + const char *dom_name, + const char *ldap_server, + char *password, + char *realm, + time_t renewable) +{ + ADS_STRUCT *ads; + ADS_STATUS status; + struct sockaddr_storage dc_ss; + fstring dc_name; + + /* we don't want this to affect the users ccache */ + setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1); + + ads = ads_init(dom_name_alt, dom_name, ldap_server); + if (!ads) { + DEBUG(1,("ads_init for domain %s failed\n", dom_name)); + return ADS_ERROR(LDAP_NO_MEMORY); + } + + SAFE_FREE(ads->auth.password); + SAFE_FREE(ads->auth.realm); + + ads->auth.renewable = renewable; + ads->auth.password = password; + ads->auth.realm = realm; + + ads->auth.realm = SMB_STRDUP(realm); + if (!strupper_m(ads->auth.realm)) { + ads_destroy(&ads); + return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR); + } + + /* Setup the server affinity cache. We don't reaally care + about the name. Just setup affinity and the KRB5_CONFIG + file. */ + get_dc_name(ads->server.workgroup, ads->server.realm, dc_name, &dc_ss); + + status = ads_connect(ads); + if (!ADS_ERR_OK(status)) { + DEBUG(1,("ads_connect for domain %s failed: %s\n", + dom_name, ads_errstr(status))); + ads_destroy(&ads); + return status; + } + + /* set the flag that says we don't own the memory even + though we do so that ads_destroy() won't destroy the + structure we pass back by reference */ + + ads->is_mine = False; + + *adsp = ads; + + return status; +} + /* return our ads connections structure for a domain. We keep the connection open to make things faster */ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain) { - ADS_STRUCT *ads; ADS_STATUS status; - fstring dc_name; - struct sockaddr_storage dc_ss; + char *password, *realm; DEBUG(10,("ads_cached_connection\n")); ads_cached_connection_reuse((ADS_STRUCT **)&domain->private_data); @@ -90,37 +147,22 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain) return (ADS_STRUCT *)domain->private_data; } - ads = ads_init(domain->alt_name, domain->name, NULL); - if (!ads) { - DEBUG(1,("ads_init for domain %s failed\n", domain->name)); - return NULL; - } - - /* we don't want ads operations to affect the default ccache */ - ads->auth.ccache_name = SMB_STRDUP("MEMORY:winbind_ccache"); - /* the machine acct password might have change - fetch it every time */ - SAFE_FREE(ads->auth.password); - SAFE_FREE(ads->auth.realm); - if ( IS_DC ) { - if ( !pdb_get_trusteddom_pw( domain->name, &ads->auth.password, NULL, NULL ) ) { - ads_destroy( &ads ); - return NULL; - } - ads->auth.realm = SMB_STRDUP( ads->server.realm ); - if (!strupper_m( ads->auth.realm )) { - ads_destroy( &ads ); + if ( !pdb_get_trusteddom_pw( domain->name, &password, NULL, + NULL ) ) { return NULL; } + realm = NULL; } else { struct winbindd_domain *our_domain = domain; - ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); + password = secrets_fetch_machine_password(lp_workgroup(), NULL, + NULL); /* always give preference to the alt_name in our primary domain if possible */ @@ -128,30 +170,21 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain) our_domain = find_our_domain(); if (our_domain->alt_name != NULL) { - ads->auth.realm = SMB_STRDUP( our_domain->alt_name ); - if (!strupper_m( ads->auth.realm )) { - ads_destroy( &ads ); - return NULL; - } + realm = SMB_STRDUP( our_domain->alt_name ); } else - ads->auth.realm = SMB_STRDUP( lp_realm() ); + realm = SMB_STRDUP( lp_realm() ); } - ads->auth.renewable = WINBINDD_PAM_AUTH_KRB5_RENEW_TIME; + status = ads_cached_connection_connect( + (ADS_STRUCT **)&domain->private_data, + domain->alt_name, + domain->name, NULL, + password, realm, + WINBINDD_PAM_AUTH_KRB5_RENEW_TIME); - /* Setup the server affinity cache. We don't reaally care - about the name. Just setup affinity and the KRB5_CONFIG - file. */ - - get_dc_name( ads->server.workgroup, ads->server.realm, dc_name, &dc_ss ); - - status = ads_connect(ads); - if (!ADS_ERR_OK(status) || !ads->config.realm) { - DEBUG(1,("ads_connect for domain %s failed: %s\n", - domain->name, ads_errstr(status))); - ads_destroy(&ads); + if (!ADS_ERR_OK(status)) { /* if we get ECONNREFUSED then it might be a NT4 server, fall back to MSRPC */ if (status.error_type == ENUM_ADS_ERROR_SYSTEM && @@ -163,17 +196,9 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain) return NULL; } - /* set the flag that says we don't own the memory even - though we do so that ads_destroy() won't destroy the - structure we pass back by reference */ - - ads->is_mine = False; - - domain->private_data = (void *)ads; - return ads; + return (ADS_STRUCT *)domain->private_data; } - /* Query display info for a realm. This is the basic user list fn */ static NTSTATUS query_user_list(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 0d757910206..8bd7a392f2e 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -895,5 +895,12 @@ NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx, /* The following definitions come from winbindd/winbindd_ads.c */ #define WINBIND_CCACHE_NAME "MEMORY:winbind_ccache" void ads_cached_connection_reuse(ADS_STRUCT **ads); +ADS_STATUS ads_cached_connection_connect(ADS_STRUCT **adsp, + const char *dom_name_alt, + const char *dom_name, + const char *ldap_server, + char *password, + char *realm, + time_t renewable); #endif /* _WINBINDD_PROTO_H_ */ -- 2.11.4.GIT