s3-lsa: make s3 pass against RPC-LSA-LOOKUPNAMES again.
[ira/wip.git] / source3 / rpc_server / srv_lsa_nt.c
index ace045cfa5df3a5addc63119ae60628a09745ae1..23ea045b880476b1bc07476ab49b9e1db35b68d7 100644 (file)
@@ -159,9 +159,13 @@ static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
 
                /* Split name into domain and user component */
 
-               full_name = name[i].string;
-               if (full_name == NULL) {
-                       return NT_STATUS_NO_MEMORY;
+               /* follow w2k8 behavior and return the builtin domain when no
+                * input has been passed in */
+
+               if (name[i].string) {
+                       full_name = name[i].string;
+               } else {
+                       full_name = "BUILTIN";
                }
 
                DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
@@ -192,7 +196,11 @@ static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
                dom_idx = -1;
 
                if (type != SID_NAME_UNKNOWN) {
-                       sid_split_rid(&sid, &rid);
+                       if (type == SID_NAME_DOMAIN) {
+                               rid = (uint32_t)-1;
+                       } else {
+                               sid_split_rid(&sid, &rid);
+                       }
                        dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
                        mapped_count++;
                }
@@ -415,22 +423,11 @@ NTSTATUS _lsa_EnumTrustDom(pipes_struct *p,
                           struct lsa_EnumTrustDom *r)
 {
        struct lsa_info *info;
-       uint32 next_idx;
+       uint32_t count;
        struct trustdom_info **domains;
-       struct lsa_DomainInfo *lsa_domains = NULL;
+       struct lsa_DomainInfo *entries;
        int i;
-
-       /*
-        * preferred length is set to 5 as a "our" preferred length
-        * nt sets this parameter to 2
-        * update (20.08.2002): it's not preferred length, but preferred size!
-        * it needs further investigation how to optimally choose this value
-        */
-       uint32 max_num_domains =
-               r->in.max_size < 5 ? r->in.max_size : 10;
-       uint32 num_domains;
        NTSTATUS nt_status;
-       uint32 num_thistime;
 
        if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
                return NT_STATUS_INVALID_HANDLE;
@@ -444,48 +441,43 @@ NTSTATUS _lsa_EnumTrustDom(pipes_struct *p,
                return NT_STATUS_ACCESS_DENIED;
 
        become_root();
-       nt_status = pdb_enum_trusteddoms(p->mem_ctx, &num_domains, &domains);
+       nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
        unbecome_root();
 
        if (!NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        }
 
-       if (*r->in.resume_handle < num_domains) {
-               num_thistime = MIN(num_domains, max_num_domains);
-
-               nt_status = STATUS_MORE_ENTRIES;
+       entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo, count);
+       if (!entries) {
+               return NT_STATUS_NO_MEMORY;
+       }
 
-               if (*r->in.resume_handle + num_thistime > num_domains) {
-                       num_thistime = num_domains - *r->in.resume_handle;
-                       nt_status = NT_STATUS_OK;
-               }
+       for (i=0; i<count; i++) {
+               init_lsa_StringLarge(&entries[i].name, domains[i]->name);
+               entries[i].sid = &domains[i]->sid;
+       }
 
-               next_idx = *r->in.resume_handle + num_thistime;
-       } else {
-               num_thistime = 0;
-               next_idx = 0xffffffff;
-               nt_status = NT_STATUS_NO_MORE_ENTRIES;
+       if (*r->in.resume_handle >= count) {
+               *r->out.resume_handle = -1;
+               TALLOC_FREE(entries);
+               return NT_STATUS_NO_MORE_ENTRIES;
        }
 
-       /* set up the lsa_enum_trust_dom response */
+       /* return the rest, limit by max_size. Note that we
+          use the w2k3 element size value of 60 */
+       r->out.domains->count = count - *r->in.resume_handle;
+       r->out.domains->count = MIN(r->out.domains->count,
+                                1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
 
-       lsa_domains = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_DomainInfo,
-                                       num_thistime);
-       if (!lsa_domains) {
-               return NT_STATUS_NO_MEMORY;
-       }
+       r->out.domains->domains = entries + *r->in.resume_handle;
 
-       for (i=0; i<num_thistime; i++) {
-               init_lsa_StringLarge(&lsa_domains[i].name, domains[i]->name);
-               lsa_domains[i].sid = &domains[i]->sid;
+       if (r->out.domains->count < count - *r->in.resume_handle) {
+               *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
+               return STATUS_MORE_ENTRIES;
        }
 
-       *r->out.resume_handle = next_idx;
-       r->out.domains->count = num_thistime;
-       r->out.domains->domains = lsa_domains;
-
-       return nt_status;
+       return NT_STATUS_OK;
 }
 
 #define LSA_AUDIT_NUM_CATEGORIES_NT4   7
@@ -1001,8 +993,8 @@ NTSTATUS _lsa_LookupSids3(pipes_struct *p,
        q.in.handle             = NULL;
        q.in.sids               = r->in.sids;
        q.in.level              = r->in.level;
-       q.in.unknown1           = r->in.unknown1;
-       q.in.unknown2           = r->in.unknown2;
+       q.in.lookup_options     = r->in.lookup_options;
+       q.in.client_revision    = r->in.client_revision;
        q.in.names              = r->in.names;
        q.in.count              = r->in.count;
 
@@ -1642,7 +1634,7 @@ NTSTATUS _lsa_CreateAccount(pipes_struct *p,
        struct lsa_info *info;
        uint32_t acc_granted;
        struct security_descriptor *psd;
-       uint32_t sd_size;
+       size_t sd_size;
 
        /* find the connection policy handle. */
        if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&handle))
@@ -1658,6 +1650,11 @@ NTSTATUS _lsa_CreateAccount(pipes_struct *p,
                return NT_STATUS_ACCESS_DENIED;
        }
 
+       /* Work out max allowed. */
+       map_max_allowed_access(p->server_info->ptok,
+                              &p->server_info->utok,
+                              &r->in.access_mask);
+
        /* map the generic bits to the lsa policy ones */
        se_map_generic(&r->in.access_mask, &lsa_account_mapping);