r3992: provide hooks for lsa to lookup sids allocated using the linear id->sid mapping
authorAndrew Tridgell <tridge@samba.org>
Mon, 29 Nov 2004 04:24:50 +0000 (04:24 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:06:11 +0000 (13:06 -0500)
source/ntvfs/common/sidmap.c
source/rpc_server/lsa/dcesrv_lsa.c

index 209982ec5845df760a13f98fac5344ada8a90180..89ad2e24306e50093158197c58ea7226da3555db 100644 (file)
@@ -540,3 +540,64 @@ allocate_sid:
 
        return NT_STATUS_OK;
 }
+
+/*
+  check if a sid is in the range of auto-allocated SIDs from our primary domain,
+  and if it is, then return the name and atype
+*/
+NTSTATUS sidmap_allocated_sid_lookup(struct sidmap_context *sidmap, 
+                                    TALLOC_CTX *mem_ctx, 
+                                    const struct dom_sid *sid,
+                                    const char **name,
+                                    uint32_t *atype)
+{
+       NTSTATUS status;
+       struct dom_sid *domain_sid;
+       void *ctx = talloc(mem_ctx, 0);
+       uint32_t rid;
+
+       status = sidmap_primary_domain_sid(sidmap, ctx, &domain_sid);
+       if (!NT_STATUS_IS_OK(status)) {
+               return NT_STATUS_NO_SUCH_DOMAIN;
+       }
+
+       if (!dom_sid_in_domain(domain_sid, sid)) {
+               talloc_free(ctx);
+               return NT_STATUS_INVALID_SID;
+       }
+
+       talloc_free(ctx);
+
+       rid = sid->sub_auths[sid->num_auths-1];
+       if (rid < SIDMAP_LOCAL_USER_BASE) {
+               return NT_STATUS_INVALID_SID;
+       }
+
+       if (rid < SIDMAP_LOCAL_GROUP_BASE) {
+               struct passwd *pwd;
+               uid_t uid = rid - SIDMAP_LOCAL_USER_BASE;
+               *atype = ATYPE_NORMAL_ACCOUNT;
+               pwd = getpwuid(uid);
+               if (pwd == NULL) {
+                       *name = talloc_asprintf(mem_ctx, "uid%u", uid);
+               } else {
+                       *name = talloc_strdup(mem_ctx, pwd->pw_name);
+               }
+       } else {
+               struct group *grp;
+               gid_t gid = rid - SIDMAP_LOCAL_GROUP_BASE;
+               *atype = ATYPE_LOCAL_GROUP;
+               grp = getgrgid(gid);
+               if (grp == NULL) {
+                       *name = talloc_asprintf(mem_ctx, "gid%u", gid);
+               } else {
+                       *name = talloc_strdup(mem_ctx, grp->gr_name);
+               }
+       }
+
+       if (*name == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       return NT_STATUS_OK;
+}
index adfbda5504a4ec20a7b111d2bb19c5d3f41280bf..4cebc3f5aa53f187ac2eea2ed63d479507f232e4 100644 (file)
@@ -42,6 +42,7 @@ enum lsa_handle {
 struct lsa_policy_state {
        int reference_count;
        void *sam_ctx;
+       struct sidmap_context *sidmap;
        uint32_t access_mask;
        const char *domain_dn;
        const char *domain_name;
@@ -166,6 +167,12 @@ static NTSTATUS lsa_OpenPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *
                return NT_STATUS_INVALID_SYSTEM_SERVICE;
        }
 
+       state->sidmap = sidmap_open(state);
+       if (state->sidmap == NULL) {
+               talloc_free(state);
+               return NT_STATUS_INVALID_SYSTEM_SERVICE;
+       }
+
        /* work out the domain_dn - useful for so many calls its worth
           fetching here */
        state->domain_dn = samdb_search_string(state->sam_ctx, state, NULL,
@@ -423,6 +430,9 @@ static NTSTATUS lsa_authority_name(struct lsa_policy_state *state,
        return NT_STATUS_OK;
 }
 
+/*
+  add to the lsa_RefDomainList for LookupSids and LookupNames
+*/
 static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, 
                                   struct dom_sid *sid, 
                                   struct lsa_RefDomainList *domains)
@@ -461,6 +471,36 @@ static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *m
        return NT_STATUS_OK;
 }
 
+/*
+  lookup a name for 1 SID
+*/
+static NTSTATUS lsa_lookup_sid(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
+                              struct dom_sid *sid, const char *sid_str,
+                              const char **name, uint32_t *atype)
+{
+       int ret;
+       struct ldb_message **res;
+       const char * const attrs[] = { "sAMAccountName", "sAMAccountType", NULL};
+       NTSTATUS status;
+
+       ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, 
+                          "objectSid=%s", sid_str);
+       if (ret == 1) {
+               *name = ldb_msg_find_string(res[0], "sAMAccountName", NULL);
+               if (*name == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+       
+               *atype = samdb_result_uint(res[0], "sAMAccountType", 0);
+
+               return NT_STATUS_OK;
+       }
+
+       status = sidmap_allocated_sid_lookup(state->sidmap, mem_ctx, sid, name, atype);
+
+       return status;
+}
+
 
 /*
   lsa_LookupSids2
@@ -499,11 +539,8 @@ static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
        }
 
        for (i=0;i<r->in.sids->num_sids;i++) {
-               const char * const attrs[] = { "sAMAccountName", "sAMAccountType", NULL};
                struct dom_sid *sid = r->in.sids->sids[i].sid;
                char *sid_str = dom_sid_string(mem_ctx, sid);
-               int ret;
-               struct ldb_message **res;
                const char *name;
                uint32_t atype, rtype;
                NTSTATUS status2;
@@ -528,20 +565,9 @@ static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
                        return status2;
                }
 
-               ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, "objectSid=%s", sid_str);
-               if (ret != 1) {
-                       status = STATUS_SOME_UNMAPPED;
-                       continue;
-               }
-
-               name = ldb_msg_find_string(res[0], "sAMAccountName", NULL);
-               if (name == NULL) {
-                       status = STATUS_SOME_UNMAPPED;
-                       continue;
-               }
-
-               atype = samdb_result_uint(res[0], "sAMAccountType", 0);
-               if (atype == 0) {
+               status2 = lsa_lookup_sid(state, mem_ctx, sid, sid_str, 
+                                        &name, &atype);
+               if (!NT_STATUS_IS_OK(status2)) {
                        status = STATUS_SOME_UNMAPPED;
                        continue;
                }