The Samba-Bugzilla – Attachment 1846 Details for
Bug 3661
idmap_ad doesn't find users in trusted domains
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Enable idmap_ad to manage connections to multiple domains
samba-multiple_connections.patch (text/plain), 10.64 KB, created by
Bob Gautier (550 Unknown Recipient)
on 2006-04-05 09:57:18 UTC
(
hide
)
Description:
Enable idmap_ad to manage connections to multiple domains
Filename:
MIME Type:
Creator:
Bob Gautier (550 Unknown Recipient)
Created:
2006-04-05 09:57:18 UTC
Size:
10.64 KB
patch
obsolete
>--- samba-3.0.21c/source/sam/idmap_ad.c.multiple_connections 2006-04-04 15:34:00.000000000 +0100 >+++ samba-3.0.21c/source/sam/idmap_ad.c 2006-04-04 15:53:16.000000000 +0100 >@@ -25,7 +25,14 @@ > * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. > */ > >+/* >+ * With changes to make multi-AD domains work >+ * (cf ../nsswitch/winbindd_ads.c) >+ */ >+ >+ > #include "includes.h" >+#include "../nsswitch/winbindd.h" > > #undef DBGC_CLASS > #define DBGC_CLASS DBGC_IDMAP >@@ -35,133 +42,153 @@ > > NTSTATUS init_module(void); > >-static ADS_STRUCT *ad_idmap_ads = NULL; >-static char *ad_idmap_uri = NULL; >+/* >+ * Connection management. >+ * >+ * Like winbindd_ads.c, use a separate connection to each domain. Maybe this should be integrated >+ * with the code there, or with the winbindd_cm connection manager? >+ */ > >-static char *attr_uidnumber = NULL; >-static char *attr_gidnumber = NULL; >+/* >+ * Create a new connection for the cache. This ought to be the same as code in winbindd_ads >+ * but I have factored out the domain->private_data checking. So the >+ * code here is simply an edited version of the original code from idmap_ad.c >+ */ > >-static BOOL ad_idmap_check_attr_mapping(ADS_STRUCT *ads) >+static ADS_STRUCT *ad_idmap_new_cached_connection(struct winbindd_domain *domain) > { >- if (attr_uidnumber != NULL && attr_gidnumber != NULL) { >- return True; >+ ADS_STRUCT *ads; >+ ADS_STATUS status; >+ >+ DEBUG(3,("ad_idmap_new_cached_connection to %s [%s]\n", >+ domain->name, sid_string_static(&domain->sid))); >+ >+ SMB_ASSERT(domain->private_data == NULL); >+ >+ /* we don't want this to affect the users ccache */ >+ setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1); >+ >+ ads = ads_init(domain->alt_name, domain->name, NULL); >+ if (!ads) { >+ DEBUG(1,("ads_init failed\n")); >+ return NULL; > } > >- if (use_nss_info("sfu")) { >- >- if (!ads_check_sfu_mapping(ads)) { >- DEBUG(0,("ad_idmap_check_attr_mapping: failed to check for SFU schema\n")); >- return False; >+ ads->server.ldap_uri = NULL; >+ ads->server.ldap_server = NULL; >+ >+ /* the machine acct password might have change - fetch it every time */ >+ >+ SAFE_FREE(ads->auth.password); >+ SAFE_FREE(ads->auth.realm); >+ >+ if ( IS_DC ) { >+ DOM_SID sid; >+ time_t last_set_time; >+ >+ if ( !secrets_fetch_trusted_domain_password( domain->name, &ads->auth.password, &sid, &last_set_time ) ) { >+ ads_destroy( &ads ); >+ return NULL; > } >+ ads->auth.realm = SMB_STRDUP( ads->server.realm ); >+ strupper_m( ads->auth.realm ); >+ } >+ else { >+ struct winbindd_domain *our_domain = domain; >+ >+ ads->auth.password = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL); >+ >+ /* always give preference to the alt_name in our >+ primary domain if possible */ >+ >+ if ( !domain->primary ) >+ our_domain = find_our_domain(); > >- attr_uidnumber = SMB_STRDUP(ads->schema.sfu_uidnumber_attr); >- attr_gidnumber = SMB_STRDUP(ads->schema.sfu_gidnumber_attr); >+ if ( our_domain->alt_name[0] != '\0' ) { >+ ads->auth.realm = SMB_STRDUP( our_domain->alt_name ); >+ strupper_m( ads->auth.realm ); >+ } else { >+ ads->auth.realm = SMB_STRDUP( lp_realm() ); >+ } >+ } > >- } else { >- attr_uidnumber = SMB_STRDUP("uidNumber"); >- attr_gidnumber = SMB_STRDUP("gidNumber"); >+ status = ads_connect(ads); >+ if (!ADS_ERR_OK(status)) { >+ DEBUG(1, ("ad_idmap_new_cached_connection: failed to connect to AD %s\n", >+ domain->name)); >+ ads_destroy(&ads); >+ return NULL; > } > >- return True; >+ ads->is_mine = False; >+ >+ domain->private_data = (void *) ads; /* cache it! */ >+ return ads; > } > >-static ADS_STRUCT *ad_idmap_cached_connection(void) >+static ADS_STRUCT *ad_idmap_live_connection(struct winbindd_domain *d) > { >- ADS_STRUCT *ads; >- ADS_STATUS status; >- BOOL local = False; >+ ADS_STRUCT *ads = (ADS_STRUCT *) d->private_data; > >-#ifdef ADS_AUTH_EXTERNAL_BIND >- local = ((strncmp(ad_idmap_uri, "ldapi://", sizeof("ldapi://") - 1)) == 0); >-#endif /* ADS_AUTH_EXTERNAL_BIND */ >- >- if (ad_idmap_ads != NULL) { >- ads = ad_idmap_ads; >+ if (ads) { > >+ DEBUG(7,("Found cached connection to realm %s for [%s]\n", >+ ads->server.realm, sid_string_static(&d->sid))); >+ > /* check for a valid structure */ > > DEBUG(7, ("Current tickets expire at %d, time is now %d\n", > (uint32) ads->auth.expire, (uint32) time(NULL))); > if ( ads->config.realm && (ads->auth.expire > time(NULL))) { > return ads; >- } else { >- /* we own this ADS_STRUCT so make sure it goes away */ >- ads->is_mine = True; >- ads_destroy( &ads ); >- ads_kdestroy(WINBIND_CCACHE_NAME); >- ad_idmap_ads = NULL; > } >- } > >- if (!local) { >- /* we don't want this to affect the users ccache */ >- setenv("KRB5CCNAME", WINBIND_CCACHE_NAME, 1); >- } >+ /* tickets have expired so we need a new connection */ >+ /* we own this ADS_STRUCT so make sure it goes away */ > >- ads = ads_init(NULL, NULL, NULL); >- if (!ads) { >- DEBUG(1,("ads_init failed\n")); >- return NULL; >+ ads->is_mine = True; >+ ads_destroy( &ads ); >+ ads_kdestroy(WINBIND_CCACHE_NAME); >+ ads = NULL; >+ d->private_data = NULL; > } > >- /* if ad_imap_uri is not empty we try to connect to >- * the given URI in smb.conf. Else try to connect to >- * one of the DCs >- */ >- if (*ad_idmap_uri != '\0') { >- ads->server.ldap_uri = SMB_STRDUP(ad_idmap_uri); >- if (ads->server.ldap_uri == NULL) { >- return NULL; >- } >- } >- else { >- ads->server.ldap_uri = NULL; >- ads->server.ldap_server = NULL; >- } >+ return ad_idmap_new_cached_connection(d); >+} > >-#ifdef ADS_AUTH_EXTERNAL_BIND >- if (local) >- ads->auth.flags |= ADS_AUTH_EXTERNAL_BIND; >- else >-#endif >- { >- /* 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); >+static ADS_STRUCT *ad_idmap_cached_connection(const DOM_SID *sid) >+{ >+ struct winbindd_domain *d; >+ ADS_STRUCT *ads = NULL; > >- SAFE_FREE(ads->auth.realm); >- ads->auth.realm = SMB_STRDUP(lp_realm()); >- } >+ d = find_domain_from_sid(sid); > >- status = ads_connect(ads); >- if (!ADS_ERR_OK(status)) { >- DEBUG(1, ("ad_idmap_init: failed to connect to AD\n")); >- ads_destroy(&ads); >+ if (d == NULL) { >+ DEBUG(1,("Tried to find connection to unknown domain [%s]\n", >+ sid_string_static(sid))); > return NULL; > } > >- ads->is_mine = False; >- >- if (!ad_idmap_check_attr_mapping(ads)) { >- DEBUG(1, ("ad_idmap_init: failed to check attribute mapping\n")); >+ if (!d->active_directory) { >+ DEBUG(1,("ad_idmap_cached_connection found non-AD domain %s\n", >+ d->name)); > return NULL; > } > >- ad_idmap_ads = ads; >- return ads; >+ return ad_idmap_live_connection(d); > } > >+ > static NTSTATUS ad_idmap_init(char *uri) > { >- ad_idmap_uri = SMB_STRDUP(uri); >- if (ad_idmap_uri == NULL) { >- return NT_STATUS_NO_MEMORY; >+ if (*uri) { >+ DEBUG(0,("Warning: idmap_ad no longer supports a URI (%s)\n",uri)); > } > > return NT_STATUS_OK; > } > >-static NTSTATUS ad_idmap_get_sid_from_id(DOM_SID *sid, unid_t unid, int id_type) >+static NTSTATUS ad_idmap_get_sid_from_id_in_domain(ADS_STRUCT *ads,DOM_SID *sid, unid_t unid, int id_type) > { > ADS_STATUS rc; > NTSTATUS status = NT_STATUS_NONE_MAPPED; >@@ -171,18 +198,11 @@ > char *expr = NULL; > fstring sid_string; > int count; >- ADS_STRUCT *ads; > > if (sid == NULL) { > return NT_STATUS_INVALID_PARAMETER; > } > >- ads = ad_idmap_cached_connection(); >- if (ads == NULL) { >- DEBUG(1, ("ad_idmap_get_id_from_sid ADS uninitialized\n")); >- return NT_STATUS_NOT_SUPPORTED; >- } >- > switch (id_type & ID_TYPEMASK) { > case ID_USERID: > if (asprintf(&expr, "(&(|(sAMAccountType=%d)(sAMAccountType=%d)(sAMAccountType=%d))(%s=%d))", >@@ -243,14 +263,43 @@ > return status; > } > >+/* >+ * Scan all known domains to try to map an id into a sid >+ */ >+ >+static NTSTATUS ad_idmap_get_sid_from_id(DOM_SID *sid, unid_t unid, int id_type) >+{ >+ struct winbindd_domain *d; >+ ADS_STRUCT *ads; >+ NTSTATUS status; >+ >+ for (d = domain_list(); d; d = d->next) { >+ ads = ad_idmap_live_connection(d); >+ if (!ads) { >+ DEBUG(1,("ad_idmap_get_sid_from_id: could not check %s\n", >+ d->name)); >+ continue; >+ } >+ >+ status = ad_idmap_get_sid_from_id_in_domain(ads,sid,unid,id_type); >+ if (NT_STATUS_IS_OK(status)) >+ return status; >+ } >+ >+ return NT_STATUS_UNSUCCESSFUL; >+} >+ >+ > static NTSTATUS ad_idmap_get_id_from_sid(unid_t *unid, int *id_type, const DOM_SID *sid) > { > ADS_STATUS rc; > NTSTATUS status = NT_STATUS_NONE_MAPPED; >- const char *attrs[] = { "sAMAccountType", >- NULL /* [1] ATTR_UIDNUMBER */, >- NULL /* [2] ATTR_GIDNUMBER */, >- NULL }; >+ const char *attrs[] = { >+ "sAMAccountType", >+ NULL, /* space for (e.g.) uidNumber */ >+ NULL, /* space for (e.g.) gidNumber */ >+ NULL >+ }; > void *res = NULL; > void *msg = NULL; > char *expr = NULL; >@@ -260,18 +309,26 @@ > int count; > ADS_STRUCT *ads; > >- if (unid == NULL) { >+ if ((unid == NULL) || (sid == NULL)) { > return NT_STATUS_INVALID_PARAMETER; > } > >- ads = ad_idmap_cached_connection(); >+ ads = ad_idmap_cached_connection(sid); > if (ads == NULL) { >- DEBUG(1, ("ad_idmap_get_id_from_sid ADS uninitialized\n")); >+ DEBUG(1, ("ad_idmap_get_id_from_sid [%s] could not get connection\n", >+ sid_string_static(sid))); >+ return NT_STATUS_NOT_SUPPORTED; >+ } >+ >+ if ((!ads->schema.sfu_uidnumber_attr) >+ && (!ads_check_sfu_mapping(ads))) { >+ DEBUG(7,("ad_idmap_get_id_from_sid [%s] could not get LDAP attribute mappings\n", >+ sid_string_static(sid))); > return NT_STATUS_NOT_SUPPORTED; > } > >- attrs[1] = attr_uidnumber; >- attrs[2] = attr_gidnumber; >+ attrs[1] = ads->schema.sfu_uidnumber_attr; >+ attrs[2] = ads->schema.sfu_gidnumber_attr; > > sidstr = sid_binstring(sid); > if (asprintf(&expr, "(objectSid=%s)", sidstr) == -1) { >@@ -323,9 +380,9 @@ > break; > } > >- if (!ads_pull_uint32(ads, msg, (*id_type == ID_GROUPID) ? attr_gidnumber : attr_uidnumber, &uid)) { >+ if (!ads_pull_uint32(ads, msg, (*id_type == ID_GROUPID) ? ads->schema.sfu_gidnumber_attr : ads->schema.sfu_uidnumber_attr, &uid)) { > DEBUG(1, ("ad_idmap_get_id_from_sid: ads_pull_uint32: could not read attribute '%s'\n", >- (*id_type == ID_GROUPID) ? attr_gidnumber : attr_uidnumber)); >+ (*id_type == ID_GROUPID) ? ads->schema.sfu_gidnumber_attr : ads->schema.sfu_uidnumber_attr)); > goto done; > } > >@@ -355,18 +412,8 @@ > > static NTSTATUS ad_idmap_close(void) > { >- ADS_STRUCT *ads = ad_idmap_ads; >- >- if (ads != NULL) { >- /* we own this ADS_STRUCT so make sure it goes away */ >- ads->is_mine = True; >- ads_destroy( &ads ); >- ad_idmap_ads = NULL; >- } >+ /* We might not own all those connections, so don't mess with them */ > >- SAFE_FREE(attr_uidnumber); >- SAFE_FREE(attr_gidnumber); >- > return NT_STATUS_OK; > } > >@@ -401,6 +448,7 @@ > /* support for new authentication subsystem */ > NTSTATUS init_module(void) > { >+ DEBUG(1,("idmap_ad: This version has the multiple-connection patch\n")); > return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "ad", &ad_methods); > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 3661
: 1846 |
2073
|
2089
|
3528
|
3529
|
3603
|
3613
|
3614
|
3630
|
3635