s3-lsa: Fix _lsa_EnumTrustDom().
authorGünther Deschner <gd@samba.org>
Tue, 20 Oct 2009 16:35:49 +0000 (18:35 +0200)
committerGünther Deschner <gd@samba.org>
Tue, 20 Oct 2009 19:46:06 +0000 (21:46 +0200)
Windows clients were showing a lot of duplicates in their list of trusted
domains.

Found by RPC-LSA-TRUSTED-DOMAIN torture test.

Guenther

source3/rpc_server/srv_lsa_nt.c

index 9d1b5b91a1d921c8e1966f798e024403ea761438..eafbd51b5c0d2ad7818e8ce5bca22d9de9942ce1 100644 (file)
@@ -422,22 +422,11 @@ NTSTATUS _lsa_EnumTrustDom(pipes_struct *p,
                           struct lsa_EnumTrustDom *r)
 {
        struct lsa_info *info;
                           struct lsa_EnumTrustDom *r)
 {
        struct lsa_info *info;
-       uint32 next_idx;
+       uint32_t count;
        struct trustdom_info **domains;
        struct trustdom_info **domains;
-       struct lsa_DomainInfo *lsa_domains = NULL;
+       struct lsa_DomainInfo *entries;
        int i;
        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;
        NTSTATUS nt_status;
-       uint32 num_thistime;
 
        if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
                return NT_STATUS_INVALID_HANDLE;
 
        if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
                return NT_STATUS_INVALID_HANDLE;
@@ -451,48 +440,43 @@ NTSTATUS _lsa_EnumTrustDom(pipes_struct *p,
                return NT_STATUS_ACCESS_DENIED;
 
        become_root();
                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;
        }
 
        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
 }
 
 #define LSA_AUDIT_NUM_CATEGORIES_NT4   7