s3: Use wbcSidsToUnixIds in create_local_token
authorVolker Lendecke <vl@samba.org>
Wed, 23 Mar 2011 17:31:38 +0000 (18:31 +0100)
committerJeremy Allison <jra@samba.org>
Wed, 13 Apr 2011 21:13:25 +0000 (14:13 -0700)
Signed-off-by: Jeremy Allison <jra@samba.org>
source3/auth/auth_util.c
source3/passdb/lookup_sid.c
source3/passdb/lookup_sid.h

index 1cc78f07577c3d57eb2a5bb885a1ec7923fe2706..b7ec9fff704d9b9e5cf5b14ab660d188747c54b1 100644 (file)
@@ -447,10 +447,12 @@ NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
                            DATA_BLOB *session_key,
                            struct auth_serversupplied_info **session_info_out)
 {
+       struct security_token *t;
        NTSTATUS status;
        size_t i;
        struct dom_sid tmp_sid;
        struct auth_serversupplied_info *session_info;
+       struct wbcUnixId *ids;
 
        /* Ensure we can't possible take a code path leading to a
         * null defref. */
@@ -516,18 +518,30 @@ NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
        session_info->utok.ngroups = 0;
        session_info->utok.groups = NULL;
 
+       t = session_info->security_token;
+
+       ids = TALLOC_ARRAY(talloc_tos(), struct wbcUnixId,
+                          t->num_sids);
+       if (ids == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (!sids_to_unix_ids(t->sids, t->num_sids, ids)) {
+               TALLOC_FREE(ids);
+               return NT_STATUS_NO_MEMORY;
+       }
+
        /* Start at index 1, where the groups start. */
 
-       for (i=1; i<session_info->security_token->num_sids; i++) {
-               gid_t gid;
-               struct dom_sid *sid = &session_info->security_token->sids[i];
+       for (i=1; i<t->num_sids; i++) {
 
-               if (!sid_to_gid(sid, &gid)) {
+               if (ids[i].type != WBC_ID_TYPE_GID) {
                        DEBUG(10, ("Could not convert SID %s to gid, "
-                                  "ignoring it\n", sid_string_dbg(sid)));
+                                  "ignoring it\n",
+                                  sid_string_dbg(&t->sids[i])));
                        continue;
                }
-               if (!add_gid_to_array_unique(session_info, gid,
+               if (!add_gid_to_array_unique(session_info, ids[i].id.gid,
                                             &session_info->utok.groups,
                                             &session_info->utok.ngroups)) {
                        return NT_STATUS_NO_MEMORY;
index 677566187c88991b13b98f5611cef40a6303ebf7..5cf391f11c7376c87d9d32413039f64bf63c82ab 100644 (file)
@@ -1395,6 +1395,109 @@ void gid_to_sid(struct dom_sid *psid, gid_t gid)
        return;
 }
 
+bool sids_to_unix_ids(const struct dom_sid *sids, uint32_t num_sids,
+                     struct wbcUnixId *ids)
+{
+       struct wbcDomainSid *wbc_sids = NULL;
+       struct wbcUnixId *wbc_ids = NULL;
+       uint32_t i, num_not_cached;
+       wbcErr err;
+       bool ret = false;
+
+       wbc_sids = TALLOC_ARRAY(talloc_tos(), struct wbcDomainSid, num_sids);
+       if (wbc_sids == NULL) {
+               return false;
+       }
+
+       num_not_cached = 0;
+
+       for (i=0; i<num_sids; i++) {
+               bool expired;
+               uint32_t rid;
+
+               if (fetch_uid_from_cache(&ids[i].id.uid, &sids[i])) {
+                       ids[i].type = WBC_ID_TYPE_UID;
+                       continue;
+               }
+               if (fetch_gid_from_cache(&ids[i].id.gid, &sids[i])) {
+                       ids[i].type = WBC_ID_TYPE_GID;
+                       continue;
+               }
+               if (sid_peek_check_rid(&global_sid_Unix_Users,
+                                      &sids[i], &rid)) {
+                       ids[i].type = WBC_ID_TYPE_UID;
+                       ids[i].id.uid = rid;
+                       continue;
+               }
+               if (sid_peek_check_rid(&global_sid_Unix_Groups,
+                                      &sids[i], &rid)) {
+                       ids[i].type = WBC_ID_TYPE_GID;
+                       ids[i].id.gid = rid;
+                       continue;
+               }
+               if (idmap_cache_find_sid2uid(&sids[i], &ids[i].id.uid,
+                                            &expired)
+                   && !expired) {
+                       ids[i].type = WBC_ID_TYPE_UID;
+                       continue;
+               }
+               if (idmap_cache_find_sid2gid(&sids[i], &ids[i].id.gid,
+                                            &expired)
+                   && !expired) {
+                       ids[i].type = WBC_ID_TYPE_GID;
+                       continue;
+               }
+               ids[i].type = WBC_ID_TYPE_NOT_SPECIFIED;
+               memcpy(&wbc_sids[num_not_cached], &sids[i],
+                      ndr_size_dom_sid(&sids[i], 0));
+               num_not_cached += 1;
+       }
+       if (num_not_cached == 0) {
+               goto done;
+       }
+       wbc_ids = TALLOC_ARRAY(talloc_tos(), struct wbcUnixId, num_not_cached);
+       if (wbc_ids == NULL) {
+               goto fail;
+       }
+       for (i=0; i<num_not_cached; i++) {
+               wbc_ids[i].type = WBC_ID_TYPE_NOT_SPECIFIED;
+       }
+       err = wbcSidsToUnixIds(wbc_sids, num_not_cached, wbc_ids);
+       if (!WBC_ERROR_IS_OK(err)) {
+               DEBUG(10, ("wbcSidsToUnixIds returned %s\n",
+                          wbcErrorString(err)));
+       }
+
+       num_not_cached = 0;
+
+       for (i=0; i<num_sids; i++) {
+               if (ids[i].type == WBC_ID_TYPE_NOT_SPECIFIED) {
+                       ids[i] = wbc_ids[num_not_cached];
+                       num_not_cached += 1;
+               }
+       }
+
+       for (i=0; i<num_sids; i++) {
+               if (ids[i].type != WBC_ID_TYPE_NOT_SPECIFIED) {
+                       continue;
+               }
+               if (legacy_sid_to_gid(&sids[i], &ids[i].id.gid)) {
+                       ids[i].type = WBC_ID_TYPE_GID;
+                       continue;
+               }
+               if (legacy_sid_to_uid(&sids[i], &ids[i].id.uid)) {
+                       ids[i].type = WBC_ID_TYPE_UID;
+                       continue;
+               }
+       }
+done:
+       ret = true;
+fail:
+       TALLOC_FREE(wbc_ids);
+       TALLOC_FREE(wbc_sids);
+       return ret;
+}
+
 /*****************************************************************
  *THE CANONICAL* convert SID to uid function.
 *****************************************************************/  
index 3c3d278c2ac5067b49df41e04c4f454c11465e0d..b56aaba039586c58b7d09feafeb83aaa8752a049 100644 (file)
@@ -24,6 +24,7 @@
 #define _PASSDB_LOOKUP_SID_H_
 
 #include "../librpc/gen_ndr/lsa.h"
+#include "../nsswitch/libwbclient/wbclient.h"
 
 #define LOOKUP_NAME_NONE               0x00000000
 #define LOOKUP_NAME_ISOLATED             0x00000001  /* Look up unqualified names */
@@ -84,6 +85,8 @@ void uid_to_sid(struct dom_sid *psid, uid_t uid);
 void gid_to_sid(struct dom_sid *psid, gid_t gid);
 bool sid_to_uid(const struct dom_sid *psid, uid_t *puid);
 bool sid_to_gid(const struct dom_sid *psid, gid_t *pgid);
+bool sids_to_unix_ids(const struct dom_sid *sids, uint32_t num_sids,
+                     struct wbcUnixId *ids);
 NTSTATUS get_primary_group_sid(TALLOC_CTX *mem_ctx,
                                const char *username,
                                struct passwd **_pwd,