r24722: Squashed commit of the following:
authorGerald Carter <jerry@samba.org>
Mon, 27 Aug 2007 20:09:37 +0000 (20:09 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:30:15 +0000 (12:30 -0500)
commit fb52f971986dd298abbcd9745ddf702820ce0184
Author: Gerald Carter <coffeedude@plainjoe.org>
Date:   Mon Aug 27 13:50:26 2007 -0500

    Check correct return type for pam_winbind_request_log() wnibind_upn_to_username

    which is an int and not NSS_STATUS.

commit 7382edf6fc0fe555df89d5b2a94d12b35049b279
Author: Gerald Carter <coffeedude@plainjoe.org>
Date:   Mon Aug 27 13:30:26 2007 -0500

    Allow wbinfo -n to convert a UPN to a SID

commit 8266c0fe1ccf2141e5a983f3213356419e626dda
Author: Gerald Carter <coffeedude@plainjoe.org>
Date:   Fri Aug 3 09:53:16 2007 -0500

    Merge some of Guenther UPN work for pam_winbind.c (check the winbind separator

    and better pam logging when converting a upn to a username).

commit 15156c17bc81dbcadf32757015c4e5158823bf3f
Author: Gerald Carter <coffeedude@plainjoe.org>
Date:   Fri Aug 3 08:52:50 2007 -0500

    Include Universal groups from the cached PAC/SamLogon info when

    generating the list of domain group SIDs for a user's token.

commit 979053c0307b051954261d539445102c55f309c7
Author: Gerald Carter <coffeedude@plainjoe.org>
Date:   Thu Aug 2 17:35:41 2007 -0500

    merge upnlogon patch from my tree
(This used to be commit 98fb5bcd5702d5086bdf9b58105a67efb90950f4)

source3/nsswitch/pam_winbind.c
source3/nsswitch/wbinfo.c
source3/nsswitch/winbindd_cache.c
source3/nsswitch/winbindd_util.c

index db3a0893291140ed91fa5b423bab2e43c77aa72f..a9b55372e923d63b602d5aeba3ba9e5ce7918602 100644 (file)
@@ -1614,6 +1614,89 @@ int get_warn_pwd_expire_from_config(const pam_handle_t *pamh,
        return ret;
 }
 
+/**
+ * Retrieve the winbind separator.
+ *
+ * @param pamh PAM handle
+ * @param ctrl PAM winbind options.
+ *
+ * @return string separator character. NULL on failure.
+ */
+
+static char winbind_get_separator(pam_handle_t *pamh, int ctrl)
+{
+       struct winbindd_request request;
+       struct winbindd_response response;
+
+       ZERO_STRUCT(request);
+       ZERO_STRUCT(response);
+
+       if (pam_winbind_request_log(pamh, ctrl, WINBINDD_INFO, &request, &response, NULL)) {
+               return '\0';
+       }
+
+       return response.data.info.winbind_separator;
+}
+
+/**
+ * Convert a upn to a name.
+ *
+ * @param pamh PAM handle
+ * @param ctrl PAM winbind options.
+ * @param upn  USer UPN to be trabslated.
+ *
+ * @return converted name. NULL pointer on failure. Caller needs to free.
+ */
+
+static char* winbind_upn_to_username(pam_handle_t *pamh, int ctrl, const char *upn)
+{
+       struct winbindd_request req;
+       struct winbindd_response resp;
+       int retval;     
+       char *account_name;     
+       int account_name_len;
+       char sep;       
+
+       /* This cannot work when the winbind separator = @ */
+
+       sep = winbind_get_separator(pamh, ctrl);
+       if (!sep || sep == '@') {
+               return NULL;
+       }
+       
+       /* Convert the UPN to a SID */
+
+       ZERO_STRUCT(req);
+       ZERO_STRUCT(resp);
+
+       strncpy(req.data.name.dom_name, "",
+               sizeof(req.data.name.dom_name) - 1);
+       strncpy(req.data.name.name, upn,
+               sizeof(req.data.name.name) - 1);
+       retval = pam_winbind_request_log(pamh, ctrl, WINBINDD_LOOKUPNAME, 
+                                        &req, &resp, upn);
+       if ( retval != PAM_SUCCESS ) {          
+               return NULL;
+       }
+       
+       /* Convert the the SID back to the sAMAccountName */
+       
+       ZERO_STRUCT(req);
+       strncpy(req.data.sid, resp.data.sid.sid, sizeof(req.data.sid)-1);
+       ZERO_STRUCT(resp);
+       retval =  pam_winbind_request_log(pamh, ctrl, WINBINDD_LOOKUPSID, 
+                                         &req, &resp, upn);
+       if ( retval != PAM_SUCCESS ) {          
+               return NULL;
+       }
+       
+       account_name_len = asprintf(&account_name, "%s\\%s", 
+                                   resp.data.name.dom_name,
+                                   resp.data.name.name);
+
+       return account_name;
+}
+
 PAM_EXTERN
 int pam_sm_authenticate(pam_handle_t *pamh, int flags,
                        int argc, const char **argv)
@@ -1646,6 +1729,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
                goto out;
        }
 
+
 #if defined(AIX)
        /* Decode the user name since AIX does not support logn user
           names by default.  The name is encoded as _#uid.  */
@@ -1670,6 +1754,19 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
                }
        }       
 
+       /* Maybe this was a UPN */
+
+       if (strchr(real_username, '@') != NULL) {
+               char *samaccountname = NULL;
+               
+               samaccountname = winbind_upn_to_username(pamh, ctrl, 
+                                                        real_username);
+               if (samaccountname) {
+                       free(real_username);
+                       real_username = samaccountname;
+               }
+       }
+
        retval = _winbind_read_password(pamh, ctrl, NULL, 
                                        "Password: ", NULL,
                                        &password);
@@ -1697,8 +1794,8 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
                                                          ctrl, d);
 
        /* Now use the username to look up password */
-       retval = winbind_auth_request(pamh, ctrl, username, password, member,
-                                     cctype, warn_pwd_expire, NULL, NULL,
+       retval = winbind_auth_request(pamh, ctrl, real_username, password, member,
+                                     cctype, warn_pwd_expire, NULL, NULL, 
                                      &username_ret);
 
        if (retval == PAM_NEW_AUTHTOK_REQD ||
index e0bda948ed13c270e99ad064b5313e3c91ec68cf..be51618820ba3fc3db07b6c823cb58315d768da2 100644 (file)
@@ -105,6 +105,13 @@ static BOOL parse_wbinfo_domain_user(const char *domuser, fstring domain,
        char *p = strchr(domuser,winbind_separator());
 
        if (!p) {
+               /* Maybe it was a UPN? */
+               if ((p = strchr(domuser, '@')) != NULL) {
+                       fstrcpy(domain, "");
+                       fstrcpy(user, domuser);
+                       return True;
+               }
+               
                fstrcpy(user, domuser);
                fstrcpy(domain, get_winbind_domain());
                return True;
index 72ea7e4e780d9faaf4d0ceab86cf560febc77733..9daee1c9f69f0a5ea96a1cd814a135ea2f668c7f 100644 (file)
@@ -1411,7 +1411,8 @@ do_query:
                wcache_save_name_to_sid(domain, status, domain_name, name, sid, *type);
        }
 
-       if (NT_STATUS_IS_OK(status)) {
+       /* Only save the reverse mapping if this was not a UPN */
+       if (NT_STATUS_IS_OK(status) && !strchr(name, '@')) {
                strupper_m(CONST_DISCARD(char *,domain_name));
                strlower_m(CONST_DISCARD(char *,name));
                wcache_save_sid_to_name(domain, status, sid, domain_name, name, *type);
index 7170e0fc6e1e39996a255965bdfae1af42d6f634..591d2355d96f89f98992bf73615a9a5c939b391b 100644 (file)
@@ -1076,6 +1076,8 @@ BOOL parse_domain_user(const char *domuser, fstring domain, fstring user)
 
                if ( assume_domain(lp_workgroup())) {
                        fstrcpy(domain, lp_workgroup());
+               } else if ((p = strchr(domuser, '@')) != NULL) {
+                       fstrcpy(domain, "");                    
                } else {
                        return False;
                }
@@ -1262,6 +1264,23 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain,
                }
        }
 
+       /* Add any Universal groups in the other_sids list */
+
+       for (i=0; i<info3->num_other_sids; i++) {
+               /* Skip Domain local groups outside our domain.
+                  We'll get these from the getsidaliases() RPC call. */
+               if (info3->other_sids_attrib[i] & SE_GROUP_RESOURCE)
+                       continue;
+
+               if (!add_sid_to_array(mem_ctx, &info3->other_sids[i].sid,
+                                     user_sids, &num_groups))
+               {
+                       TALLOC_FREE(info3);
+                       return NT_STATUS_NO_MEMORY;                     
+               }
+       }
+       
+
        TALLOC_FREE(info3);
        *p_num_groups = num_groups;
        status = (user_sids != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;