diff options
-rw-r--r-- | source3/libads/kerberos.c | 19 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_ads.c | 34 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_cache.c | 57 |
3 files changed, 82 insertions, 28 deletions
diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 7f855add06..d5b4b11fa2 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -130,8 +130,25 @@ int ads_kinit_password(ADS_STRUCT *ads) { char *s; int ret; + const char *account_name; + fstring acct_name; - if (asprintf(&s, "%s@%s", ads->auth.user_name, ads->auth.realm) == -1) { + if ( IS_DC ) { + /* this will end up getting a ticket for DOMAIN@RUSTED.REA.LM */ + account_name = lp_workgroup(); + } else { + /* always use the sAMAccountName for security = domain */ + /* global_myname()$@REA.LM */ + if ( lp_security() == SEC_DOMAIN ) { + fstr_sprintf( acct_name, "%s$", global_myname() ); + account_name = acct_name; + } + else + /* This looks like host/global_myname()@REA.LM */ + account_name = ads->auth.user_name; + } + + if (asprintf(&s, "%s@%s", account_name, ads->auth.realm) == -1) { return KRB5_CC_NOMEM; } diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index 6b170c3330..32bc641b6a 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -68,11 +68,39 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain) } /* 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.password); SAFE_FREE(ads->auth.realm); - ads->auth.realm = SMB_STRDUP(lp_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(); + + 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() ); + } status = ads_connect(ads); if (!ADS_ERR_OK(status) || !ads->config.realm) { diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c index 9164a135c5..993e6d96e8 100644 --- a/source3/nsswitch/winbindd_cache.c +++ b/source3/nsswitch/winbindd_cache.c @@ -100,43 +100,52 @@ void winbindd_check_cache_size(time_t t) static struct winbind_cache *get_cache(struct winbindd_domain *domain) { struct winbind_cache *ret = wcache; + struct winbindd_domain *our_domain = domain; /* we have to know what type of domain we are dealing with first */ if ( !domain->initialized ) set_dc_type_and_flags( domain ); + /* + OK. listen up becasue I'm only going to say this once. + We have the following scenarios to consider + (a) trusted AD domains on a Samba DC, + (b) trusted AD domains and we are joined to a non-kerberos domain + (c) trusted AD domains and we are joined to a kerberos (AD) domain + + For (a) we can always contact the trusted domain using krb5 + since we have the domain trust account password + + For (b) we can only use RPC since we have no way of + getting a krb5 ticket in our own domain + + For (c) we can always use krb5 since we have a kerberos trust + + --jerry + */ + if (!domain->backend) { extern struct winbindd_methods reconnect_methods; - switch (lp_security()) { #ifdef HAVE_ADS - case SEC_ADS: { - extern struct winbindd_methods ads_methods; - /* always obey the lp_security parameter for our domain */ - if (domain->primary) { - domain->backend = &ads_methods; - break; - } + extern struct winbindd_methods ads_methods; - /* only use ADS for native modes at the momment. - The problem is the correct detection of mixed - mode domains from NT4 BDC's --jerry */ - - if ( domain->native_mode ) { - DEBUG(5,("get_cache: Setting ADS methods for domain %s\n", - domain->name)); - domain->backend = &ads_methods; - break; - } + /* find our domain first so we can figure out if we + are joined to a kerberized domain */ - /* fall through */ - } -#endif - default: - DEBUG(5,("get_cache: Setting MS-RPC methods for domain %s\n", - domain->name)); + if ( !domain->primary ) + our_domain = find_our_domain(); + + if ( (our_domain->active_directory || IS_DC) && domain->active_directory ) { + DEBUG(5,("get_cache: Setting ADS methods for domain %s\n", domain->name)); + domain->backend = &ads_methods; + } else { +#endif /* HAVE_ADS */ + DEBUG(5,("get_cache: Setting MS-RPC methods for domain %s\n", domain->name)); domain->backend = &reconnect_methods; +#ifdef HAVE_ADS } +#endif /* HAVE_ADS */ } if (ret) |