[SCM] Samba Shared Repository - branch v3-0-test updated - release-3-0-28a-1181-gd41bc18

Günther Deschner gd at samba.org
Fri May 16 12:28:45 GMT 2008


The branch, v3-0-test has been updated
       via  d41bc18b77562ca2fe7360944d9782509b1552fe (commit)
       via  58f22b738e038730dbb0e0d0779099ce364f7b9a (commit)
      from  ce623c0736388838cbb739e483e561316af77834 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-0-test


- Log -----------------------------------------------------------------
commit d41bc18b77562ca2fe7360944d9782509b1552fe
Author: Günther Deschner <gd at samba.org>
Date:   Fri May 16 14:16:19 2008 +0200

    Fix Bug #5461 and implement a very basic _samr_GetDisplayEnumerationIndex().
    
    Citrix PM cannot use a Samba DC when having more then 900 groups as citrix
    insists on calling _samr_GetDisplayEnumerationIndex() after receiving the first
    900 groups via _samr_QueryDisplayInfo() to get the continuation index.
    
    Guenther

commit 58f22b738e038730dbb0e0d0779099ce364f7b9a
Author: Günther Deschner <gd at samba.org>
Date:   Fri May 16 14:14:55 2008 +0200

    Re-add samr getdispinfoindex parsing which got lost in the glue commit.
    
    Guenther

-----------------------------------------------------------------------

Summary of changes:
 source/include/rpc_samr.h       |    2 +-
 source/rpc_parse/parse_samr.c   |   81 ++++++++++++++++++++++++
 source/rpc_server/srv_samr.c    |   35 ++++++++++-
 source/rpc_server/srv_samr_nt.c |  128 ++++++++++++++++++++++++++++++++++++++-
 4 files changed, 242 insertions(+), 4 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/include/rpc_samr.h b/source/include/rpc_samr.h
index a7a9660..1df0bee 100644
--- a/source/include/rpc_samr.h
+++ b/source/include/rpc_samr.h
@@ -130,7 +130,7 @@ SamrTestPrivateFunctionsUser
 #define SAMR_UNKNOWN_2f        0x2f
 #define SAMR_QUERY_DISPINFO3   0x30 /* Alias for SAMR_QUERY_DISPINFO
 				       with info level 3 */
-#define SAMR_UNKNOWN_31        0x31
+#define SAMR_GET_DISPENUM_INDEX2 0x31
 #define SAMR_CREATE_USER       0x32
 #define SAMR_QUERY_DISPINFO4   0x33 /* Alias for SAMR_QUERY_DISPINFO
 				       with info level 4 */
diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c
index c9a6ee3..f0130cd 100644
--- a/source/rpc_parse/parse_samr.c
+++ b/source/rpc_parse/parse_samr.c
@@ -2173,6 +2173,76 @@ BOOL samr_io_r_query_dispinfo(const char *desc, SAMR_R_QUERY_DISPINFO * r_u,
 }
 
 /*******************************************************************
+inits a SAMR_Q_GET_DISPENUM_INDEX structure.
+********************************************************************/
+
+void init_samr_q_get_dispenum_index(SAMR_Q_GET_DISPENUM_INDEX * q_e, POLICY_HND *pol,
+				    uint16 switch_level, const char *name)
+{
+	DEBUG(5, ("init_samr_q_get_dispenum_index\n"));
+
+	q_e->domain_pol = *pol;
+
+	q_e->switch_level = switch_level;
+
+	init_lsa_string(&q_e->name, name);
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+BOOL samr_io_q_get_dispenum_index(const char *desc, SAMR_Q_GET_DISPENUM_INDEX * q_e,
+				  prs_struct *ps, int depth)
+{
+	if (q_e == NULL)
+		return False;
+
+	prs_debug(ps, depth, desc, "samr_io_q_get_dispenum_index");
+	depth++;
+
+	if(!prs_align(ps))
+		return False;
+
+	if(!smb_io_pol_hnd("domain_pol", &q_e->domain_pol, ps, depth))
+		return False;
+
+	if(!prs_uint16("switch_level", ps, depth, &q_e->switch_level))
+		return False;
+
+	if (!smb_io_lsa_string("name", &q_e->name, ps, depth))
+		return False;
+
+	return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+BOOL samr_io_r_get_dispenum_index(const char *desc, SAMR_R_GET_DISPENUM_INDEX * r_u,
+				  prs_struct *ps, int depth)
+{
+	if (r_u == NULL)
+		return False;
+
+	prs_debug(ps, depth, desc, "samr_io_r_get_dispenum_index");
+	depth++;
+
+	if(!prs_align(ps))
+		return False;
+
+	if(!prs_uint32("idx", ps, depth, &r_u->idx))
+		return False;
+	
+	if(!prs_ntstatus("status", ps, depth, &r_u->status))
+		return False;
+
+	return True;
+}
+
+
+/*******************************************************************
 inits a SAMR_Q_OPEN_GROUP structure.
 ********************************************************************/
 
@@ -2188,6 +2258,17 @@ void init_samr_q_open_group(SAMR_Q_OPEN_GROUP * q_c,
 }
 
 /*******************************************************************
+inits a SAMR_R_GET_DISPENUM_INDEX structure.
+********************************************************************/
+
+void init_samr_r_get_dispenum_index(SAMR_R_GET_DISPENUM_INDEX * q_e, uint32 idx)
+{
+	DEBUG(5, ("init_samr_r_get_dispenum_index\n"));
+
+	q_e->idx = idx;
+}
+
+/*******************************************************************
 reads or writes a structure.
 ********************************************************************/
 
diff --git a/source/rpc_server/srv_samr.c b/source/rpc_server/srv_samr.c
index 6ce4f88..12705cf 100644
--- a/source/rpc_server/srv_samr.c
+++ b/source/rpc_server/srv_samr.c
@@ -1496,6 +1496,37 @@ static BOOL api_samr_set_dom_info(pipes_struct *p)
 }
 
 /*******************************************************************
+ api_samr_get_dispenum_index
+ ********************************************************************/
+
+static BOOL api_samr_get_dispenum_index(pipes_struct *p)
+{
+	SAMR_Q_GET_DISPENUM_INDEX q_u;
+	SAMR_R_GET_DISPENUM_INDEX r_u;
+	prs_struct *data = &p->in_data.data;
+	prs_struct *rdata = &p->out_data.rdata;
+
+	ZERO_STRUCT(q_u);
+	ZERO_STRUCT(r_u);
+
+	if(!samr_io_q_get_dispenum_index("", &q_u, data, 0)) {
+		DEBUG(0,("api_samr_get_dispenum_index: unable to unmarshall SAMR_Q_GET_DISPENUM_INDEX.\n"));
+		return False;
+	}
+
+	r_u.status = _samr_get_dispenum_index(p, &q_u, &r_u);
+
+	/* store the response in the SMB stream */
+	if(!samr_io_r_get_dispenum_index("", &r_u, rdata, 0)) {
+		DEBUG(0,("api_samr_get_dispenum_index: unable to marshall SAMR_R_GET_DISPENUM_INDEX.\n"));
+		return False;
+	}
+
+	return True;
+}
+
+
+/*******************************************************************
  array of \PIPE\samr operations
  ********************************************************************/
 
@@ -1555,7 +1586,9 @@ static struct api_struct api_samr_cmds [] =
       {"SAMR_SET_DOMAIN_INFO"   , SAMR_SET_DOMAIN_INFO  , api_samr_set_dom_info     },
       {"SAMR_CONNECT4"          , SAMR_CONNECT4         , api_samr_connect4         },
       {"SAMR_CHGPASSWD_USER3"   , SAMR_CHGPASSWD_USER3  , api_samr_chgpasswd_user3  },
-      {"SAMR_CONNECT5"          , SAMR_CONNECT5         , api_samr_connect5         }
+      {"SAMR_CONNECT5"          , SAMR_CONNECT5         , api_samr_connect5         },
+      {"SAMR_GET_DISPENUM_INDEX", SAMR_GET_DISPENUM_INDEX, api_samr_get_dispenum_index },
+      {"SAMR_GET_DISPENUM_INDEX2",SAMR_GET_DISPENUM_INDEX2, api_samr_get_dispenum_index }
 };
 
 void samr_get_pipe_fns( struct api_struct **fns, int *n_fns )
diff --git a/source/rpc_server/srv_samr_nt.c b/source/rpc_server/srv_samr_nt.c
index c766d56..5f1ef25 100644
--- a/source/rpc_server/srv_samr_nt.c
+++ b/source/rpc_server/srv_samr_nt.c
@@ -1338,8 +1338,7 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
 	if (!NT_STATUS_IS_OK(disp_ret))
 		return disp_ret;
 
-	/* calculate the total size */
-	total_data_size=num_account*struct_size;
+	temp_size = num_account * struct_size;
 
 	if (num_account) {
 		r_u->status = STATUS_MORE_ENTRIES;
@@ -1347,6 +1346,10 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
 		r_u->status = NT_STATUS_OK;
 	}
 
+	if (num_account < max_entries) {
+		r_u->status = NT_STATUS_OK;
+	}
+
 	/* Ensure we cache this enumeration. */
 	set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
 
@@ -5078,3 +5081,124 @@ NTSTATUS _samr_set_dom_info(pipes_struct *p, SAMR_Q_SET_DOMAIN_INFO *q_u, SAMR_R
 
 	return r_u->status;
 }
+
+/*******************************************************************
+ _samr_get_dispenum_index
+ ********************************************************************/
+
+NTSTATUS _samr_get_dispenum_index(pipes_struct *p, SAMR_Q_GET_DISPENUM_INDEX *q_u, SAMR_R_GET_DISPENUM_INDEX *r_u)
+{
+	struct samr_info *info = NULL;
+	uint32 max_entries = (uint32) -1;
+	uint32 enum_context = 0;
+	int i;
+	uint32 num_account = 0;
+	struct samr_displayentry *entries = NULL;
+	fstring account_name;
+
+	DEBUG(5, ("_samr_get_dispenum_index: %d\n", __LINE__));
+
+	r_u->status = NT_STATUS_UNSUCCESSFUL;
+
+	/* find the policy handle.  open a policy on it. */
+	if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)(void *)&info))
+		return NT_STATUS_INVALID_HANDLE;
+
+	if ((q_u->switch_level < 1) || (q_u->switch_level > 3)) {
+		DEBUG(0,("_samr_get_dispenum_index: Unknown info level (%u)\n",
+			 (unsigned int)q_u->switch_level ));
+		return NT_STATUS_INVALID_INFO_CLASS;
+	}
+
+	if (!rpcstr_pull_unistr2_fstring(account_name, &q_u->name.unistring)) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	become_root();
+
+	/* The following done as ROOT. Don't return without unbecome_root(). */
+
+	switch (q_u->switch_level) {
+	case 0x1:
+		if (info->disp_info->users == NULL) {
+			info->disp_info->users = pdb_search_users(ACB_NORMAL);
+			if (info->disp_info->users == NULL) {
+				unbecome_root();
+				return NT_STATUS_ACCESS_DENIED;
+			}
+			DEBUG(10,("_samr_get_dispenum_index: starting user enumeration at index %u\n",
+				(unsigned  int)enum_context ));
+		} else {
+			DEBUG(10,("_samr_get_dispenum_index: using cached user enumeration at index %u\n",
+				(unsigned  int)enum_context ));
+		}
+
+		num_account = pdb_search_entries(info->disp_info->users,
+						 enum_context, max_entries,
+						 &entries);
+		break;
+	case 0x2:
+		if (info->disp_info->machines == NULL) {
+			info->disp_info->machines =
+				pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST);
+			if (info->disp_info->machines == NULL) {
+				unbecome_root();
+				return NT_STATUS_ACCESS_DENIED;
+			}
+			DEBUG(10,("_samr_get_dispenum_index: starting machine enumeration at index %u\n",
+				(unsigned  int)enum_context ));
+		} else {
+			DEBUG(10,("_samr_get_dispenum_index: using cached machine enumeration at index %u\n",
+				(unsigned  int)enum_context ));
+		}
+
+		num_account = pdb_search_entries(info->disp_info->machines,
+						 enum_context, max_entries,
+						 &entries);
+		break;
+	case 0x3:
+		if (info->disp_info->groups == NULL) {
+			info->disp_info->groups = pdb_search_groups();
+			if (info->disp_info->groups == NULL) {
+				unbecome_root();
+				return NT_STATUS_ACCESS_DENIED;
+			}
+			DEBUG(10,("_samr_get_dispenum_index: starting group enumeration at index %u\n",
+				(unsigned  int)enum_context ));
+		} else {
+			DEBUG(10,("_samr_get_dispenum_index: using cached group enumeration at index %u\n",
+				(unsigned  int)enum_context ));
+		}
+
+		num_account = pdb_search_entries(info->disp_info->groups,
+						 enum_context, max_entries,
+						 &entries);
+		break;
+	default:
+		unbecome_root();
+		smb_panic("info class changed");
+		break;
+	}
+	unbecome_root();
+
+	/* Ensure we cache this enumeration. */
+	set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT);
+
+	DEBUG(10,("_samr_get_dispenum_index: looking for :%s\n", account_name));
+
+	for (i=0; i<num_account; i++) {
+		if (strequal(entries[i].account_name, account_name)) {
+			DEBUG(10,("_samr_get_dispenum_index: found %s at idx %d\n",
+				account_name, i));
+
+			init_samr_r_get_dispenum_index(r_u, i);
+
+			return NT_STATUS_OK;
+		}
+	}
+
+	/* assuming account_name lives at the very end */
+	init_samr_r_get_dispenum_index(r_u, num_account);
+
+	return NT_STATUS_OK;
+}


-- 
Samba Shared Repository


More information about the samba-cvs mailing list