diff options
author | Günther Deschner <gd@samba.org> | 2009-10-20 18:35:49 +0200 |
---|---|---|
committer | Günther Deschner <gd@samba.org> | 2009-10-20 21:46:06 +0200 |
commit | 49a13234957ad241e6457bbf0edc15875321f03f (patch) | |
tree | 0840d48ebb5b4d7a4709235be7a7c4f2ff241441 /source3/rpc_server | |
parent | d168d7fe3c7ec4b90cd526c4ea02e972ffac7835 (diff) | |
download | samba-49a13234957ad241e6457bbf0edc15875321f03f.tar.gz samba-49a13234957ad241e6457bbf0edc15875321f03f.tar.bz2 samba-49a13234957ad241e6457bbf0edc15875321f03f.zip |
s3-lsa: Fix _lsa_EnumTrustDom().
Windows clients were showing a lot of duplicates in their list of trusted
domains.
Found by RPC-LSA-TRUSTED-DOMAIN torture test.
Guenther
Diffstat (limited to 'source3/rpc_server')
-rw-r--r-- | source3/rpc_server/srv_lsa_nt.c | 66 |
1 files changed, 25 insertions, 41 deletions
diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 9d1b5b91a1..eafbd51b5c 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -422,22 +422,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; @@ -451,48 +440,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 |