svn commit: samba r24053 - in branches/SAMBA_4_0/source: rpc_server/samr torture/rpc

abartlet at samba.org abartlet at samba.org
Thu Jul 26 07:27:47 GMT 2007


Author: abartlet
Date: 2007-07-26 07:27:46 +0000 (Thu, 26 Jul 2007)
New Revision: 24053

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=24053

Log:
Ensure we filter EnumDomainUsers with the supplied mask.

Should fix another part (list of domains in usrmgr incorrectly
including accounts) of bug #4815 by mwallnoefer at yahoo.de.

Andrew Bartlett

Modified:
   branches/SAMBA_4_0/source/rpc_server/samr/dcesrv_samr.c
   branches/SAMBA_4_0/source/torture/rpc/samr.c


Changeset:
Modified: branches/SAMBA_4_0/source/rpc_server/samr/dcesrv_samr.c
===================================================================
--- branches/SAMBA_4_0/source/rpc_server/samr/dcesrv_samr.c	2007-07-26 03:50:24 UTC (rev 24052)
+++ branches/SAMBA_4_0/source/rpc_server/samr/dcesrv_samr.c	2007-07-26 07:27:46 UTC (rev 24053)
@@ -1428,9 +1428,9 @@
 	struct dcesrv_handle *h;
 	struct samr_domain_state *d_state;
 	struct ldb_message **res;
-	int count, i, first;
+	int count, num_filtered_entries, i, first;
 	struct samr_SamEntry *entries;
-	const char * const attrs[3] = { "objectSid", "sAMAccountName", NULL };
+	const char * const attrs[] = { "objectSid", "sAMAccountName", "userAccountControl", NULL };
 
 	*r->out.resume_handle = 0;
 	r->out.sam = NULL;
@@ -1456,27 +1456,31 @@
 	if (!entries) {
 		return NT_STATUS_NO_MEMORY;
 	}
+	num_filtered_entries = 0;
 	for (i=0;i<count;i++) {
-		entries[i].idx = samdb_result_rid_from_sid(mem_ctx, res[i], "objectSid", 0);
-		entries[i].name.string = samdb_result_string(res[i], "sAMAccountName", "");
+		/* Check if a mask has been requested */
+		if (r->in.acct_flags
+		    && ((samdb_result_acct_flags(res[i], 
+						 "userAccountControl") & r->in.acct_flags) == 0)) {
+			continue;
+		}
+		entries[num_filtered_entries].idx = samdb_result_rid_from_sid(mem_ctx, res[i], "objectSid", 0);
+		entries[num_filtered_entries].name.string = samdb_result_string(res[i], "sAMAccountName", "");
+		num_filtered_entries++;
 	}
 
 	/* sort the results by rid */
-	qsort(entries, count, sizeof(struct samr_SamEntry), 
+	qsort(entries, num_filtered_entries, sizeof(struct samr_SamEntry), 
 	      (comparison_fn_t)compare_SamEntry);
 
 	/* find the first entry to return */
 	for (first=0;
-	     first<count && entries[first].idx <= *r->in.resume_handle;
+	     first<num_filtered_entries && entries[first].idx <= *r->in.resume_handle;
 	     first++) ;
 
-	if (first == count) {
-		return NT_STATUS_OK;
-	}
-
 	/* return the rest, limit by max_size. Note that we 
 	   use the w2k3 element size value of 54 */
-	r->out.num_entries = count - first;
+	r->out.num_entries = num_filtered_entries - first;
 	r->out.num_entries = MIN(r->out.num_entries, 
 				 1+(r->in.max_size/SAMR_ENUM_USERS_MULTIPLIER));
 
@@ -1488,7 +1492,11 @@
 	r->out.sam->entries = entries+first;
 	r->out.sam->count = r->out.num_entries;
 
-	if (r->out.num_entries < count - first) {
+	if (first == num_filtered_entries) {
+		return NT_STATUS_OK;
+	}
+
+	if (r->out.num_entries < num_filtered_entries - first) {
 		*r->out.resume_handle = entries[first+r->out.num_entries-1].idx;
 		return STATUS_MORE_ENTRIES;
 	}

Modified: branches/SAMBA_4_0/source/torture/rpc/samr.c
===================================================================
--- branches/SAMBA_4_0/source/torture/rpc/samr.c	2007-07-26 03:50:24 UTC (rev 24052)
+++ branches/SAMBA_4_0/source/torture/rpc/samr.c	2007-07-26 07:27:46 UTC (rev 24053)
@@ -2861,43 +2861,101 @@
 	return ret;
 }
 
-static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
-				 struct policy_handle *handle)
+static BOOL check_mask(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
+		       struct policy_handle *handle, uint32_t rid, 
+		       uint32_t acct_flag_mask)
 {
 	NTSTATUS status;
-	struct samr_EnumDomainUsers r;
-	uint32_t resume_handle=0;
-	int i;
+	struct samr_OpenUser r;
+	struct samr_QueryUserInfo q;
+	struct policy_handle user_handle;
 	BOOL ret = True;
-	struct samr_LookupNames n;
-	struct samr_LookupRids  lr ;
 
-	printf("Testing EnumDomainUsers\n");
+	printf("Testing OpenUser(%u)\n", rid);
 
 	r.in.domain_handle = handle;
-	r.in.resume_handle = &resume_handle;
-	r.in.acct_flags = 0;
-	r.in.max_size = (uint32_t)-1;
-	r.out.resume_handle = &resume_handle;
+	r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+	r.in.rid = rid;
+	r.out.user_handle = &user_handle;
 
-	status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
+	status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
 	if (!NT_STATUS_IS_OK(status)) {
-		printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
+		printf("OpenUser(%u) failed - %s\n", rid, nt_errstr(status));
 		return False;
 	}
+
+	q.in.user_handle = &user_handle;
+	q.in.level = 16;
 	
-	if (!r.out.sam) {
-		return False;
+	status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
+	if (!NT_STATUS_IS_OK(status)) {
+		printf("QueryUserInfo level 16 failed - %s\n", 
+		       nt_errstr(status));
+		ret = False;
+	} else {
+		if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
+			printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
+			       acct_flag_mask, q.out.info->info16.acct_flags, rid);
+			ret = False;
+		}
 	}
-
-	if (r.out.sam->count == 0) {
-		return True;
+	
+	if (!test_samr_handle_Close(p, mem_ctx, &user_handle)) {
+		ret = False;
 	}
 
-	for (i=0;i<r.out.sam->count;i++) {
-		if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
-			ret = False;
+	return ret;
+}
+
+static BOOL test_EnumDomainUsers(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, 
+				 struct policy_handle *handle)
+{
+	NTSTATUS status = STATUS_MORE_ENTRIES;
+	struct samr_EnumDomainUsers r;
+	uint32_t mask, resume_handle=0;
+	int i, mask_idx;
+	BOOL ret = True;
+	struct samr_LookupNames n;
+	struct samr_LookupRids  lr ;
+	uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST, 
+			    ACB_DISABLED, ACB_NORMAL | ACB_DISABLED, 
+			    ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST, 
+			    ACB_PWNOEXP, 0};
+
+	printf("Testing EnumDomainUsers\n");
+
+	for (mask_idx=0;mask_idx<ARRAY_SIZE(masks);mask_idx++) {
+		r.in.domain_handle = handle;
+		r.in.resume_handle = &resume_handle;
+		r.in.acct_flags = mask = masks[mask_idx];
+		r.in.max_size = (uint32_t)-1;
+		r.out.resume_handle = &resume_handle;
+
+		status = dcerpc_samr_EnumDomainUsers(p, mem_ctx, &r);
+		if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&  
+		    !NT_STATUS_IS_OK(status)) {
+			printf("EnumDomainUsers failed - %s\n", nt_errstr(status));
+			return False;
 		}
+	
+		if (!r.out.sam) {
+			printf("EnumDomainUsers failed: r.out.sam unexpectedly NULL\n");
+			return False;
+		}
+
+		if (r.out.sam->count == 0) {
+			continue;
+		}
+
+		for (i=0;i<r.out.sam->count;i++) {
+			if (mask) {
+				if (!check_mask(p, mem_ctx, handle, r.out.sam->entries[i].idx, mask)) {
+					ret = False;
+				}
+			} else if (!test_OpenUser(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
+				ret = False;
+			}
+		}
 	}
 
 	printf("Testing LookupNames\n");



More information about the samba-cvs mailing list