r3980: added server side support for lsa_LookupNames() and lsa_LookupNames2()
authorAndrew Tridgell <tridge@samba.org>
Fri, 26 Nov 2004 13:02:58 +0000 (13:02 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:06:10 +0000 (13:06 -0500)
(This used to be commit da12780bd98e566af13fe97ce5e84fe829a0fbd5)

source4/rpc_server/lsa/dcesrv_lsa.c

index 8dee8f189de6155e5f693fa81d592f1195f3af76..adfbda5504a4ec20a7b111d2bb19c5d3f41280bf 100644 (file)
@@ -396,16 +396,6 @@ static NTSTATUS lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX
 }
 
 
-/* 
-  lsa_LookupNames 
-*/
-static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
-                      struct lsa_LookupNames *r)
-{
-       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
-}
-
-
 /*
   return the authority name and authority sid, given a sid
 */
@@ -433,6 +423,45 @@ static NTSTATUS lsa_authority_name(struct lsa_policy_state *state,
        return NT_STATUS_OK;
 }
 
+static NTSTATUS lsa_authority_list(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx, 
+                                  struct dom_sid *sid, 
+                                  struct lsa_RefDomainList *domains)
+{
+       NTSTATUS status;
+       const char *authority_name;
+       struct dom_sid *authority_sid;
+       int i;
+
+       /* work out the authority name */
+       status = lsa_authority_name(state, mem_ctx, sid, 
+                                   &authority_name, &authority_sid);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+       
+       /* see if we've already done this authority name */
+       for (i=0;i<domains->count;i++) {
+               if (strcmp(authority_name, domains->domains[i].name.string) == 0) {
+                       break;
+               }
+       }
+       if (i == domains->count) {
+               domains->domains = talloc_realloc_p(domains, 
+                                                   domains->domains,
+                                                   struct lsa_TrustInformation,
+                                                   domains->count+1);
+               if (domains->domains == NULL) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+               domains->domains[i].name.string = authority_name;
+               domains->domains[i].sid         = authority_sid;
+               domains->count++;
+       }
+       
+       return NT_STATUS_OK;
+}
+
+
 /*
   lsa_LookupSids2
 */
@@ -457,7 +486,7 @@ static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
        }
 
        r->out.names = talloc_zero_p(mem_ctx,  struct lsa_TransNameArray2);
-       if (r->out.domains == NULL) {
+       if (r->out.names == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -473,10 +502,9 @@ static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
                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, j;
+               int ret;
                struct ldb_message **res;
-               const char *name, *authority_name;
-               struct dom_sid *authority_sid;
+               const char *name;
                uint32_t atype, rtype;
                NTSTATUS status2;
 
@@ -495,31 +523,11 @@ static NTSTATUS lsa_LookupSids2(struct dcesrv_call_state *dce_call,
                }
 
                /* work out the authority name */
-               status2 = lsa_authority_name(state, mem_ctx, sid, 
-                                            &authority_name, &authority_sid);
+               status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains);
                if (!NT_STATUS_IS_OK(status2)) {
                        return status2;
                }
 
-               /* see if we've already done this authority name */
-               for (j=0;j<r->out.domains->count;j++) {
-                       if (strcmp(authority_name, r->out.domains->domains[j].name.string) == 0) {
-                               break;
-                       }
-               }
-               if (j == r->out.domains->count) {
-                       r->out.domains->domains = talloc_realloc_p(r->out.domains, 
-                                                                  r->out.domains->domains,
-                                                                  struct lsa_TrustInformation,
-                                                                  r->out.domains->count+1);
-                       if (r->out.domains == NULL) {
-                               return NT_STATUS_NO_MEMORY;
-                       }
-                       r->out.domains->domains[j].name.string = authority_name;
-                       r->out.domains->domains[j].sid         = authority_sid;
-                       r->out.domains->count++;
-               }
-
                ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, "objectSid=%s", sid_str);
                if (ret != 1) {
                        status = STATUS_SOME_UNMAPPED;
@@ -995,9 +1003,144 @@ static NTSTATUS lsa_LookupNames2(struct dcesrv_call_state *dce_call,
                                 TALLOC_CTX *mem_ctx,
                                 struct lsa_LookupNames2 *r)
 {
-       DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
+       struct lsa_policy_state *state;
+       struct dcesrv_handle *h;
+       int i;
+       NTSTATUS status = NT_STATUS_OK;
+
+       r->out.domains = NULL;
+
+       DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
+
+       state = h->data;
+
+       r->out.domains = talloc_zero_p(mem_ctx,  struct lsa_RefDomainList);
+       if (r->out.domains == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       r->out.sids = talloc_zero_p(mem_ctx,  struct lsa_TransSidArray2);
+       if (r->out.sids == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       *r->out.count = 0;
+
+       r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_TranslatedSid2, 
+                                          r->in.num_names);
+       if (r->out.sids->sids == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       for (i=0;i<r->in.num_names;i++) {
+               const char * const attrs[] = { "objectSid", "sAMAccountType", NULL};
+               const char *name = r->in.names[i].string;
+               int ret;
+               const char *sid_str;
+               struct ldb_message **res;
+               struct dom_sid *sid;
+               uint32_t atype, rtype;
+               NTSTATUS status2;
+
+               r->out.sids->count++;
+               (*r->out.count)++;
+
+               r->out.sids->sids[i].sid_type    = SID_NAME_UNKNOWN;
+               r->out.sids->sids[i].rid         = 0xFFFFFFFF;
+               r->out.sids->sids[i].sid_index   = 0xFFFFFFFF;
+               r->out.sids->sids[i].unknown     = 0;
+
+               ret = samdb_search(state->sam_ctx, mem_ctx, NULL, &res, attrs, "sAMAccountName=%s", name);
+               if (ret != 1) {
+                       status = STATUS_SOME_UNMAPPED;
+                       continue;
+               }
+
+               sid_str = ldb_msg_find_string(res[0], "objectSid", NULL);
+               if (sid_str == NULL) {
+                       status = STATUS_SOME_UNMAPPED;
+                       continue;
+               }
+
+               sid = dom_sid_parse_talloc(mem_ctx, sid_str);
+               if (sid == NULL || sid->num_auths == 0) {
+                       status = STATUS_SOME_UNMAPPED;
+                       continue;
+               }
+
+               atype = samdb_result_uint(res[0], "sAMAccountType", 0);
+               if (atype == 0) {
+                       status = STATUS_SOME_UNMAPPED;
+                       continue;
+               }
+
+               rtype = samdb_atype_map(atype);
+               if (rtype == SID_NAME_UNKNOWN) {
+                       status = STATUS_SOME_UNMAPPED;
+                       continue;
+               }
+
+               r->out.sids->sids[i].sid_type    = rtype;
+               r->out.sids->sids[i].rid         = sid->sub_auths[sid->num_auths-1];
+               r->out.sids->sids[i].sid_index   = 0;
+               r->out.sids->sids[i].unknown     = 0;
+
+               status2 = lsa_authority_list(state, mem_ctx, sid, r->out.domains);
+               if (!NT_STATUS_IS_OK(status2)) {
+                       return status2;
+               }
+       }
+       
+       return status;
+}
+
+/* 
+  lsa_LookupNames 
+*/
+static NTSTATUS lsa_LookupNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
+                      struct lsa_LookupNames *r)
+{
+       struct lsa_LookupNames2 r2;
+       NTSTATUS status;
+       int i;
+
+       r2.in.handle    = r->in.handle;
+       r2.in.num_names = r->in.num_names;
+       r2.in.names     = r->in.names;
+       r2.in.sids      = NULL;
+       r2.in.level     = r->in.level;
+       r2.in.count     = r->in.count;
+       r2.in.unknown1  = 0;
+       r2.in.unknown2  = 0;
+       r2.out.count    = r->out.count;
+
+       status = lsa_LookupNames2(dce_call, mem_ctx, &r2);
+       if (dce_call->fault_code != 0) {
+               return status;
+       }
+
+       r->out.domains = r2.out.domains;
+       r->out.sids = talloc_p(mem_ctx, struct lsa_TransSidArray);
+       if (r->out.sids == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       r->out.sids->count = r2.out.sids->count;
+       r->out.sids->sids = talloc_array_p(r->out.sids, struct lsa_TranslatedSid, 
+                                          r->out.sids->count);
+       if (r->out.sids->sids == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       for (i=0;i<r->out.sids->count;i++) {
+               r->out.sids->sids[i].sid_type    = r2.out.sids->sids[i].sid_type;
+               r->out.sids->sids[i].rid         = r2.out.sids->sids[i].rid;
+               r->out.sids->sids[i].sid_index   = r2.out.sids->sids[i].sid_index;
+       }
+
+       return status;
 }
 
+
+
 /*
   lsa_CreateTrustedDomainEx2
 */