summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/rpc_server/lsa/srv_lsa_nt.c69
1 files changed, 67 insertions, 2 deletions
diff --git a/source3/rpc_server/lsa/srv_lsa_nt.c b/source3/rpc_server/lsa/srv_lsa_nt.c
index 333a583b2f..d190775111 100644
--- a/source3/rpc_server/lsa/srv_lsa_nt.c
+++ b/source3/rpc_server/lsa/srv_lsa_nt.c
@@ -3034,8 +3034,73 @@ NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
struct lsa_EnumTrustedDomainsEx *r)
{
- p->rng_fault_state = True;
- return NT_STATUS_NOT_IMPLEMENTED;
+ struct lsa_info *info;
+ uint32_t count;
+ struct pdb_trusted_domain **domains;
+ struct lsa_TrustDomainInfoInfoEx *entries;
+ int i;
+ NTSTATUS nt_status;
+
+ if (!find_policy_by_hnd(p, r->in.handle, (void **)(void *)&info))
+ return NT_STATUS_INVALID_HANDLE;
+
+ if (info->type != LSA_HANDLE_POLICY_TYPE) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ /* check if the user has enough rights */
+ if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
+ return NT_STATUS_ACCESS_DENIED;
+
+ become_root();
+ nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
+ unbecome_root();
+
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ return nt_status;
+ }
+
+ entries = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
+ count);
+ if (!entries) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ for (i=0; i<count; i++) {
+ init_lsa_StringLarge(&entries[i].netbios_name,
+ domains[i]->netbios_name);
+ entries[i].sid = &domains[i]->security_identifier;
+ }
+
+ if (*r->in.resume_handle >= count) {
+ *r->out.resume_handle = -1;
+ TALLOC_FREE(entries);
+ return NT_STATUS_NO_MORE_ENTRIES;
+ }
+
+ /* 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,
+ (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
+
+ r->out.domains->domains = entries + *r->in.resume_handle;
+
+ 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;
+ }
+
+ /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
+ * always be larger than the previous input resume handle, in
+ * particular when hitting the last query it is vital to set the
+ * resume handle correctly to avoid infinite client loops, as
+ * seen e.g. with Windows XP SP3 when resume handle is 0 and
+ * status is NT_STATUS_OK - gd */
+
+ *r->out.resume_handle = (uint32_t)-1;
+
+ return NT_STATUS_OK;
}
NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,