r11651: After talking to Jeremy, commit my winbindd "Do the Right Thing" patch.
authorGerald Carter <jerry@samba.org>
Thu, 10 Nov 2005 19:50:09 +0000 (19:50 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:05:22 +0000 (11:05 -0500)
Still needs some more testing ni domains with multiple DCs. Coming next....
(This used to be commit aaed605206a8549cec575dab31e56bf6d32f26a6)

source3/libads/kerberos.c
source3/nsswitch/winbindd_ads.c
source3/nsswitch/winbindd_cache.c

index 7f855add06ecd836941e3c3c6190c309a36cebc9..d5b4b11fa2453df428397c2d7b4b49e3d5adc561 100644 (file)
@@ -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;
        }
 
index 6b170c33305ecb898a11863081957733e63da6ae..32bc641b6a6143e8b21ee2d0a777e61c09ea2f25 100644 (file)
@@ -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) {
index 9164a135c5bab351dd8b819c351c80ed3f777a06..993e6d96e8eeaab7d0eae30dc8f54f5d2519d569 100644 (file)
@@ -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)