added trusted realm support to ADS authentication
authorAndrew Tridgell <tridge@samba.org>
Wed, 19 Dec 2001 09:53:30 +0000 (09:53 +0000)
committerAndrew Tridgell <tridge@samba.org>
Wed, 19 Dec 2001 09:53:30 +0000 (09:53 +0000)
the method used for checking if a domain is a trusted domain is very
crude, we should really call a backend fn of some sort. For now I'm
using winbindd to do the dirty work.

source/auth/auth.c
source/auth/auth_util.c
source/libsmb/clikrb5.c
source/nsswitch/winbindd.h
source/nsswitch/winbindd_ads.c
source/nsswitch/winbindd_util.c
source/smbd/sesssetup.c

index fc5a88ad64a1aa5d0794b6d0ea494650775be4a3..710b5f27fbf796be3567387ca6238d2922e5a852 100644 (file)
 
 static BOOL check_domain_match(char *user, char *domain) 
 {
-  /*
-   * If we aren't serving to trusted domains, we must make sure that
-   * the validation request comes from an account in the same domain
-   * as the Samba server
-   */
-
-  if (!lp_allow_trusted_domains() &&
-      !(strequal("", domain) || strequal(lp_workgroup(), domain) || is_netbios_alias_or_name(domain))) {
-      DEBUG(1, ("check_domain_match: Attempt to connect as user %s from domain %s denied.\n", user, domain));
-      return False;
-  } else {
-      return True;
-  }
+       /*
+        * If we aren't serving to trusted domains, we must make sure that
+        * the validation request comes from an account in the same domain
+        * as the Samba server
+        */
+
+       if (!lp_allow_trusted_domains() &&
+           !(strequal("", domain) || 
+             strequal(lp_workgroup(), domain) || 
+             is_netbios_alias_or_name(domain))) {
+               DEBUG(1, ("check_domain_match: Attempt to connect as user %s from domain %s denied.\n", user, domain));
+               return False;
+       } else {
+               return True;
+       }
 }
 
 /****************************************************************************
index 60495ad23b8c355a78cd7a08c550b332e072eac3..3e480b4fd18347e82f405c2291ae1d01740f964e 100644 (file)
@@ -215,7 +215,26 @@ BOOL make_user_info_map(auth_usersupplied_info **user_info,
        map_username(internal_username); 
        
        if (lp_allow_trusted_domains()) {
-               domain = client_domain;
+               char *user;
+               /* the client could have given us a workstation name
+                  or other crap for the workgroup - we really need a
+                  way of telling if this domain name is one of our
+                  trusted domain names 
+
+                  The way I do it here is by checking if the fully
+                  qualified username exists. This is rather reliant
+                  on winbind, but until we have a better method this
+                  will have to do 
+               */
+               asprintf(&user, "%s%s%s", 
+                        client_domain, lp_winbind_separator(), 
+                        smb_name);
+               if (Get_Pwnam(user) != NULL) {
+                       domain = client_domain;
+               } else {
+                       domain = lp_workgroup();
+               }
+               free(user);
        } else {
                domain = lp_workgroup();
        }
index 03fb6a566902e160803101fa9863e08701c78f49..cc77c08d26a46df96c9ced6d93f7ff18590eb27b 100644 (file)
@@ -60,8 +60,8 @@ static krb5_error_code krb5_mk_req2(krb5_context context,
 
        if ((retval = krb5_get_credentials(context, 0,
                                           ccache, &creds, &credsp))) {
-               DEBUG(1,("krb5_get_credentials failed (%s)\n", 
-                        error_message(retval)));
+               DEBUG(1,("krb5_get_credentials failed for %s (%s)\n", 
+                        principal, error_message(retval)));
                goto cleanup_creds;
        }
 
index 2a6fa22961a739520f7755bce9015e30675a4556..74206da9ef07543887ef5ebbb31225575bd8ca51 100644 (file)
@@ -153,6 +153,7 @@ struct winbindd_methods {
 /* Structures to hold per domain information */
 struct winbindd_domain {
        fstring name;                          /* Domain name */        
+       fstring full_name;                     /* full Domain name (realm) */   
        DOM_SID sid;                           /* SID for this domain */
        struct winbindd_methods *methods;      /* lookup methods for
                                                   this domain (LDAP or
index 4ce0894ab3e00b47eb3d50b5112fbdc8d1a4f9d9..c988e697ee95462374d7848999b783add6599df8 100644 (file)
@@ -147,6 +147,8 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain)
                primary_realm = strdup(ads->realm);
        }
 
+       fstrcpy(domain->full_name, ads->server_realm);
+
        domain->private = (void *)ads;
        return ads;
 }
index f760b635d643aeb61767d7ac5acad1a17452cc69..2f21f81ea8738a27abcffacb986fcd4ccf62d6ca 100644 (file)
@@ -55,7 +55,8 @@ struct winbindd_domain *find_domain_from_name(char *domain_name)
        /* Search through list */
 
        for (tmp = domain_list; tmp != NULL; tmp = tmp->next) {
-               if (strcasecmp(domain_name, tmp->name) == 0)
+               if (strcasecmp(domain_name, tmp->name) == 0 ||
+                   strcasecmp(domain_name, tmp->full_name) == 0)
                        return tmp;
        }
 
@@ -164,6 +165,9 @@ BOOL get_domain_info(void)
                        DEBUG(1,("Added domain %s (%s)\n", 
                                 domain->name, 
                                 sid_string_static(&domain->sid)));
+
+                       /* this primes the connection */
+                       cache_methods.domain_sid(domain, &domain->sid);
                }
        }
 
index 4c26bda4dbd60dbba974fdcaa631eaa2b106b397..60c9cd30e5fc512c77b0baf14ecd19ca47f5cc07 100644 (file)
@@ -107,14 +107,18 @@ static int reply_spnego_kerberos(connection_struct *conn,
 
        *p = 0;
        if (strcasecmp(p+1, ads->realm) != 0) {
-               DEBUG(3,("Ticket for incorrect realm %s\n", p+1));
-               ads_destroy(&ads);
-               return ERROR_NT(NT_STATUS_LOGON_FAILURE);
+               DEBUG(3,("Ticket for foreign realm %s@%s\n", client, p+1));
+               if (!lp_allow_trusted_domains()) {
+                       return ERROR_NT(NT_STATUS_LOGON_FAILURE);
+               }
+               /* this gives a fully qualified user name (ie. with full realm).
+                  that leads to very long usernames, but what else can we do? */
+               asprintf(&user, "%s%s%s", p+1, lp_winbind_separator(), client);
+       } else {
+               user = strdup(client);
        }
        ads_destroy(&ads);
 
-       user = client;
-
        /* the password is good - let them in */
        pw = smb_getpwnam(user,False);
        if (!pw) {
@@ -129,6 +133,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
        
        sess_vuid = register_vuid(server_info, user);
 
+       free(user);
        free_server_info(&server_info);
 
        if (sess_vuid == -1) {