[SCM] Samba Shared Repository - branch master updated

Günther Deschner gd at samba.org
Fri Mar 12 17:13:31 MST 2010


The branch, master has been updated
       via  5e48aa7... s3-spoolss: wrap _spoolss_EnumPrinterData() around _spoolss_EnumPrinterDataEx().
       via  d39ece1... s4-smbtorture: add spoolss EnumPrinterData vs EnumPrinterDataEx consistency test.
       via  ab33b99... s4-smbtorture: refactor spoolss EnumPrinterData test.
       via  1d9d617... s4-smbtorture: refactor SetPrinterData() calls a little more.
       via  3de2f04... s4-smbtorture: re-arrange spoolss_SetPrinterData() tests.
       via  f064a18... s4-smbtorture: make sure RPC-SPOOLSS passes against 64bit archs (w2k8r2).
      from  a2be29d... Missed a couple more uses of conn->server_info->ptok that need to be get_current_nttok(conn)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 5e48aa7ebbf0b3c589093867be12523d6f98e4d2
Author: Günther Deschner <gd at samba.org>
Date:   Fri Mar 12 18:31:22 2010 +0100

    s3-spoolss: wrap _spoolss_EnumPrinterData() around _spoolss_EnumPrinterDataEx().
    
    This removes some dependencies to registry code.
    
    Guenther

commit d39ece17e0590aa7fd484cf273a7402f704a7ebb
Author: Günther Deschner <gd at samba.org>
Date:   Sat Mar 13 01:07:43 2010 +0100

    s4-smbtorture: add spoolss EnumPrinterData vs EnumPrinterDataEx consistency test.
    
    Guenther

commit ab33b991de6dcd3d27668ad4710e58f4b5e228f4
Author: Günther Deschner <gd at samba.org>
Date:   Sat Mar 13 01:05:24 2010 +0100

    s4-smbtorture: refactor spoolss EnumPrinterData test.
    
    Guenther

commit 1d9d617d971a38670b359403f76f9effad994bfa
Author: Günther Deschner <gd at samba.org>
Date:   Fri Mar 12 22:45:33 2010 +0100

    s4-smbtorture: refactor SetPrinterData() calls a little more.
    
    Guenther

commit 3de2f0475dfcaf1df54054b9afce70cc0e9afeb1
Author: Günther Deschner <gd at samba.org>
Date:   Fri Mar 12 22:11:14 2010 +0100

    s4-smbtorture: re-arrange spoolss_SetPrinterData() tests.
    
    Guenther

commit f064a182eb3a28e49cec6aa3d9baaad8d85f13e6
Author: Günther Deschner <gd at samba.org>
Date:   Sat Mar 13 00:20:52 2010 +0100

    s4-smbtorture: make sure RPC-SPOOLSS passes against 64bit archs (w2k8r2).
    
    Guenther

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

Summary of changes:
 source3/rpc_server/srv_spoolss_nt.c |  104 +++-----
 source4/torture/rpc/spoolss.c       |  509 ++++++++++++++++++++++++-----------
 2 files changed, 394 insertions(+), 219 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index a35c5f6..157a4e2 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -7666,66 +7666,51 @@ WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
 				struct spoolss_EnumPrinterData *r)
 {
-	NT_PRINTER_INFO_LEVEL *printer = NULL;
-	Printer_entry 	*Printer = find_printer_index_by_hnd(p, r->in.handle);
-	int 		snum;
-	WERROR 		result;
-	struct regval_blob	*val = NULL;
-	NT_PRINTER_DATA *p_data;
-	int		i, key_index, num_values;
-	int		name_length;
-
-	*r->out.value_needed	= 0;
-	*r->out.type		= REG_NONE;
-	*r->out.data_needed	= 0;
+	WERROR result;
+	struct spoolss_EnumPrinterDataEx r2;
+	uint32_t count;
+	struct spoolss_PrinterEnumValues *info, *val = NULL;
+	uint32_t needed;
 
-	DEBUG(5,("_spoolss_EnumPrinterData\n"));
+	r2.in.handle	= r->in.handle;
+	r2.in.key_name	= "PrinterDriverData";
+	r2.in.offered	= 0;
+	r2.out.count	= &count;
+	r2.out.info	= &info;
+	r2.out.needed	= &needed;
 
-	if (!Printer) {
-		DEBUG(2,("_spoolss_EnumPrinterData: Invalid handle (%s:%u:%u).\n",
-			OUR_HANDLE(r->in.handle)));
-		return WERR_BADFID;
+	result = _spoolss_EnumPrinterDataEx(p, &r2);
+	if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
+		r2.in.offered = needed;
+		result = _spoolss_EnumPrinterDataEx(p, &r2);
 	}
-
-	if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
-		return WERR_BADFID;
-	}
-
-	result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
 	if (!W_ERROR_IS_OK(result)) {
 		return result;
 	}
 
-	p_data = printer->info_2->data;
-	key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
-
-	result = WERR_OK;
-
 	/*
 	 * The NT machine wants to know the biggest size of value and data
 	 *
 	 * cf: MSDN EnumPrinterData remark section
 	 */
 
-	if (!r->in.value_offered && !r->in.data_offered && (key_index != -1)) {
-
+	if (!r->in.value_offered && !r->in.data_offered) {
 		uint32_t biggest_valuesize = 0;
 		uint32_t biggest_datasize = 0;
+		int i, name_length;
 
 		DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
 
-		num_values = regval_ctr_numvals( p_data->keys[key_index].values );
+		for (i=0; i<count; i++) {
 
-		for ( i=0; i<num_values; i++ )
-		{
-			val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
-
-			name_length = strlen(val->valuename);
-			if ( strlen(val->valuename) > biggest_valuesize )
+			name_length = strlen(info[i].value_name);
+			if (strlen(info[i].value_name) > biggest_valuesize) {
 				biggest_valuesize = name_length;
+			}
 
-			if ( val->size > biggest_datasize )
-				biggest_datasize = val->size;
+			if (info[i].data_length > biggest_datasize) {
+				biggest_datasize = info[i].data_length;
+			}
 
 			DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
 				biggest_datasize));
@@ -7740,21 +7725,14 @@ WERROR _spoolss_EnumPrinterData(pipes_struct *p,
 		DEBUG(6,("final values: [%d], [%d]\n",
 			*r->out.value_needed, *r->out.data_needed));
 
-		goto done;
+		return WERR_OK;
 	}
 
-	/*
-	 * the value len is wrong in NT sp3
-	 * that's the number of bytes not the number of unicode chars
-	 */
-
-	if (key_index != -1) {
-		val = regval_ctr_specific_value(p_data->keys[key_index].values,
-						r->in.enum_index);
+	if (r->in.enum_index < count) {
+		val = &info[r->in.enum_index];
 	}
 
-	if (!val) {
-
+	if (val == NULL) {
 		/* out_value should default to "" or else NT4 has
 		   problems unmarshalling the response */
 
@@ -7762,8 +7740,7 @@ WERROR _spoolss_EnumPrinterData(pipes_struct *p,
 			*r->out.value_needed = 1;
 			r->out.value_name = talloc_strdup(r, "");
 			if (!r->out.value_name) {
-				result = WERR_NOMEM;
-				goto done;
+				return WERR_NOMEM;
 			}
 		} else {
 			r->out.value_name = NULL;
@@ -7787,12 +7764,11 @@ WERROR _spoolss_EnumPrinterData(pipes_struct *p,
 
 		/* name */
 		if (r->in.value_offered) {
-			r->out.value_name = talloc_strdup(r, regval_name(val));
+			r->out.value_name = talloc_strdup(r, val->value_name);
 			if (!r->out.value_name) {
-				result = WERR_NOMEM;
-				goto done;
+				return WERR_NOMEM;
 			}
-			*r->out.value_needed = strlen_m(regval_name(val));
+			*r->out.value_needed = strlen_m(val->value_name);
 		} else {
 			r->out.value_name = NULL;
 			*r->out.value_needed = 0;
@@ -7800,7 +7776,7 @@ WERROR _spoolss_EnumPrinterData(pipes_struct *p,
 
 		/* type */
 
-		*r->out.type = regval_type(val);
+		*r->out.type = val->type;
 
 		/* data - counted in bytes */
 
@@ -7809,17 +7785,17 @@ WERROR _spoolss_EnumPrinterData(pipes_struct *p,
  		 * in MS-RPRN.
  		 */
 
-		if (r->out.data && regval_data_p(val) &&
-				regval_size(val) && r->in.data_offered) {
-			memcpy(r->out.data, regval_data_p(val),
-				MIN(regval_size(val),r->in.data_offered));
+		if (r->out.data && val->data &&
+				val->data_length && r->in.data_offered) {
+			memcpy(r->out.data, val->data,
+				MIN(val->data_length,r->in.data_offered));
 		}
 
-		*r->out.data_needed = regval_size(val);
+		*r->out.data_needed = val->data_length;
+
+		result = WERR_OK;
 	}
 
-done:
-	free_a_printer(&printer, 2);
 	return result;
 }
 
diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c
index 5b2bc86..65b964a 100644
--- a/source4/torture/rpc/spoolss.c
+++ b/source4/torture/rpc/spoolss.c
@@ -38,6 +38,8 @@
 #define TORTURE_WELLKNOWN_PRINTER_EX	"torture_wkn_printer_ex"
 #define TORTURE_PRINTER_EX		"torture_printer_ex"
 
+#define TOP_LEVEL_PRINTER_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers"
+
 struct test_spoolss_context {
 	/* print server handle */
 	struct policy_handle server_handle;
@@ -2958,7 +2960,8 @@ static bool test_GetPrinterDataEx(struct torture_context *tctx,
 
 static bool test_GetPrinterData_list(struct torture_context *tctx,
 				     struct dcerpc_pipe *p,
-				     struct policy_handle *handle)
+				     struct policy_handle *handle,
+				     const char **architecture)
 {
 	const char *list[] = {
 		"W3SvcInstalled",
@@ -2989,67 +2992,111 @@ static bool test_GetPrinterData_list(struct torture_context *tctx,
 		torture_assert_int_equal(tctx, type, type_ex, "type mismatch");
 		torture_assert_int_equal(tctx, needed, needed_ex, "needed mismatch");
 		torture_assert_mem_equal(tctx, data, data_ex, needed, "data mismatch");
+
+		if (strequal(list[i], "Architecture")) {
+			if (architecture) {
+				DATA_BLOB blob = data_blob_const(data, needed);
+				*architecture = reg_val_data_string(tctx, lp_iconv_convenience(tctx->lp_ctx), REG_SZ, blob);
+			}
+		}
 	}
 
 	return true;
 }
 
-static bool test_EnumPrinterData(struct torture_context *tctx, struct dcerpc_pipe *p,
-				 struct policy_handle *handle)
+static bool test_EnumPrinterData(struct torture_context *tctx,
+				 struct dcerpc_pipe *p,
+				 struct policy_handle *handle,
+				 uint32_t enum_index,
+				 uint32_t value_offered,
+				 uint32_t data_offered,
+				 enum winreg_Type *type_p,
+				 uint32_t *value_needed_p,
+				 uint32_t *data_needed_p,
+				 const char **value_name_p,
+				 uint8_t **data_p,
+				 WERROR *result_p)
 {
-	NTSTATUS status;
 	struct spoolss_EnumPrinterData r;
+	uint32_t data_needed;
+	uint32_t value_needed;
+	enum winreg_Type type;
 
-	ZERO_STRUCT(r);
 	r.in.handle = handle;
-	r.in.enum_index = 0;
-
-	do {
-		uint32_t value_size = 0;
-		uint32_t data_size = 0;
-		enum winreg_Type type = 0;
+	r.in.enum_index = enum_index;
+	r.in.value_offered = value_offered;
+	r.in.data_offered = data_offered;
+	r.out.data_needed = &data_needed;
+	r.out.value_needed = &value_needed;
+	r.out.type = &type;
+	r.out.data = talloc_zero_array(tctx, uint8_t, r.in.data_offered);
+	r.out.value_name = talloc_zero_array(tctx, const char, r.in.value_offered);
 
-		r.in.value_offered = value_size;
-		r.out.value_needed = &value_size;
-		r.in.data_offered = data_size;
-		r.out.data_needed = &data_size;
+	torture_comment(tctx, "Testing EnumPrinterData(%d)\n", enum_index);
 
-		r.out.type = &type;
-		r.out.data = talloc_zero_array(tctx, uint8_t, 0);
+	torture_assert_ntstatus_ok(tctx,
+		dcerpc_spoolss_EnumPrinterData(p, tctx, &r),
+		"EnumPrinterData failed");
 
-		torture_comment(tctx, "Testing EnumPrinterData\n");
+	if (type_p) {
+		*type_p = type;
+	}
+	if (value_needed_p) {
+		*value_needed_p = value_needed;
+	}
+	if (data_needed_p) {
+		*data_needed_p = data_needed;
+	}
+	if (value_name_p) {
+		*value_name_p = r.out.value_name;
+	}
+	if (data_p) {
+		*data_p = r.out.data;
+	}
+	if (result_p) {
+		*result_p = r.out.result;
+	}
 
-		status = dcerpc_spoolss_EnumPrinterData(p, tctx, &r);
+	return true;
+}
 
-		torture_assert_ntstatus_ok(tctx, status, "EnumPrinterData failed");
-		if (W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
-			break;
-		}
-		torture_assert_werr_ok(tctx, r.out.result, "EnumPrinterData");
 
-		r.in.value_offered = value_size;
-		r.out.value_name = talloc_zero_array(tctx, const char, value_size);
-		r.in.data_offered = data_size;
-		r.out.data = talloc_zero_array(tctx, uint8_t, data_size);
+static bool test_EnumPrinterData_all(struct torture_context *tctx,
+				     struct dcerpc_pipe *p,
+				     struct policy_handle *handle)
+{
+	uint32_t enum_index = 0;
+	enum winreg_Type type;
+	uint32_t value_needed;
+	uint32_t data_needed;
+	uint8_t *data;
+	const char *value_name;
+	WERROR result;
 
-		status = dcerpc_spoolss_EnumPrinterData(p, tctx, &r);
+	do {
+		torture_assert(tctx,
+			test_EnumPrinterData(tctx, p, handle, enum_index, 0, 0,
+					     &type, &value_needed, &data_needed,
+					     &value_name, &data, &result),
+			"EnumPrinterData failed");
 
-		torture_assert_ntstatus_ok(tctx, status, "EnumPrinterData failed");
-		if (W_ERROR_EQUAL(r.out.result, WERR_NO_MORE_ITEMS)) {
+		if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS)) {
 			break;
 		}
 
-		torture_assert_werr_ok(tctx, r.out.result, "EnumPrinterData failed");
-
-		torture_assert(tctx, test_GetPrinterData(tctx, p, handle, r.out.value_name, NULL, NULL, NULL),
-			talloc_asprintf(tctx, "failed to call GetPrinterData for %s\n", r.out.value_name));
+		torture_assert(tctx,
+			test_EnumPrinterData(tctx, p, handle, enum_index, value_needed, data_needed,
+					     &type, &value_needed, &data_needed,
+					     &value_name, &data, &result),
+			"EnumPrinterData failed");
 
-		torture_assert(tctx, test_GetPrinterDataEx(tctx, p, handle, "PrinterDriverData", r.out.value_name, NULL, NULL, NULL),
-			talloc_asprintf(tctx, "failed to call GetPrinterDataEx on PrinterDriverData for %s\n", r.out.value_name));
+		if (W_ERROR_EQUAL(result, WERR_NO_MORE_ITEMS)) {
+			break;
+		}
 
-		r.in.enum_index++;
+		enum_index++;
 
-	} while (W_ERROR_IS_OK(r.out.result));
+	} while (W_ERROR_IS_OK(result));
 
 	return true;
 }
@@ -3097,6 +3144,87 @@ static bool test_EnumPrinterDataEx(struct torture_context *tctx,
 	return true;
 }
 
+static bool test_EnumPrinterData_consistency(struct torture_context *tctx,
+					     struct dcerpc_pipe *p,
+					     struct policy_handle *handle)
+{
+	uint32_t count;
+	struct spoolss_PrinterEnumValues *info;
+	int i;
+	uint32_t value_needed, data_needed;
+	uint32_t value_offered, data_offered;
+	WERROR result;
+
+	torture_comment(tctx, "Testing EnumPrinterData vs EnumPrinterDataEx consistency");
+
+	torture_assert(tctx,
+		test_EnumPrinterDataEx(tctx, p, handle, "PrinterDriverData", &count, &info),
+		"failed to call EnumPrinterDataEx");
+
+	/* get the max sizes for value and data */
+
+	torture_assert(tctx,
+		test_EnumPrinterData(tctx, p, handle, 0, 0, 0,
+				     NULL, &value_needed, &data_needed,
+				     NULL, NULL, &result),
+		"EnumPrinterData failed");
+	torture_assert_werr_ok(tctx, result, "unexpected result");
+
+	/* check if the reply from the EnumPrinterData really matches max values */
+
+	for (i=0; i < count; i++) {
+		if (info[i].value_name_len > value_needed) {
+			torture_fail(tctx,
+				talloc_asprintf(tctx,
+				"EnumPrinterDataEx gave a reply with value length %d which is larger then expected max value length %d from EnumPrinterData",
+				info[i].value_name_len, value_needed));
+		}
+		if (info[i].data_length > data_needed) {
+			torture_fail(tctx,
+				talloc_asprintf(tctx,
+				"EnumPrinterDataEx gave a reply with data length %d which is larger then expected max data length %d from EnumPrinterData",
+				info[i].data_length, data_needed));
+		}
+	}
+
+	/* assuming that both EnumPrinterData and EnumPrinterDataEx do either
+	 * sort or not sort the replies by value name, we should be able to do
+	 * the following entry comparison */
+
+	data_offered = data_needed;
+	value_offered = value_needed;
+
+	for (i=0; i < count; i++) {
+
+		enum winreg_Type type;
+		const char *value_name;
+		uint8_t *data;
+		WERROR result;
+		uint32_t value_needed, data_needed;
+
+		torture_assert(tctx,
+			test_EnumPrinterData(tctx, p, handle, i, value_offered, data_offered,
+					     &type, &value_needed, &data_needed,
+					     &value_name, &data, &result),
+			"EnumPrinterData failed");
+
+		if (i -1 == count) {
+			torture_assert_werr_equal(tctx, result, WERR_NO_MORE_ITEMS,
+				"unexpected result");
+			break;
+		} else {
+			torture_assert_werr_ok(tctx, result, "unexpected result");
+		}
+
+		torture_assert_int_equal(tctx, type, info[i].type, "type mismatch");
+		torture_assert_int_equal(tctx, value_needed, info[i].value_name_len, "value name length mismatch");
+		torture_assert_str_equal(tctx, value_name, info[i].value_name, "value name mismatch");
+		torture_assert_int_equal(tctx, data_needed, info[i].data_length, "data length mismatch");
+		torture_assert_mem_equal(tctx, data, info[i].data->data, info[i].data_length, "data mismatch");
+	}
+
+	return true;
+}
 
 static bool test_DeletePrinterData(struct torture_context *tctx,
 				   struct dcerpc_pipe *p,
@@ -3170,107 +3298,6 @@ static bool test_DeletePrinterKey(struct torture_context *tctx,
 	return true;
 }
 
-static bool test_SetPrinterData(struct torture_context *tctx,
-				struct dcerpc_pipe *p,
-				struct policy_handle *handle)
-{
-	NTSTATUS status;
-	struct spoolss_SetPrinterData r;
-	const char *values[] = {
-		"spootyfoot",
-		"spooty\\foot",
-#if 0
-	/* FIXME: not working with s3 atm. */
-		"spooty,foot",
-		"spooty,fo,ot",
-#endif
-		"spooty foot",
-#if 0
-	/* FIXME: not working with s3 atm. */
-		"spooty\\fo,ot",
-		"spooty,fo\\ot"
-#endif
-	};
-	int i;
-
-	for (i=0; i < ARRAY_SIZE(values); i++) {
-
-		enum winreg_Type type;
-		uint8_t *data;
-		DATA_BLOB blob;
-		uint32_t needed;
-
-		torture_assert(tctx,
-			reg_string_to_val(tctx, lp_iconv_convenience(tctx->lp_ctx),
-					  "REG_SZ", "dog", &r.in.type, &blob), "");
-
-		r.in.handle = handle;
-		r.in.value_name = values[i];
-		r.in.data = blob.data;
-		r.in.offered = blob.length;
-
-		torture_comment(tctx, "Testing SetPrinterData(%s)\n",
-			r.in.value_name);
-
-		status = dcerpc_spoolss_SetPrinterData(p, tctx, &r);
-
-		torture_assert_ntstatus_ok(tctx, status, "SetPrinterData failed");
-		torture_assert_werr_ok(tctx, r.out.result, "SetPrinterData failed");
-
-		if (!test_GetPrinterData(tctx, p, handle, r.in.value_name, &type, &data, &needed)) {
-			return false;
-		}
-
-		torture_assert_int_equal(tctx, r.in.type, type, "type mismatch");
-		torture_assert_int_equal(tctx, r.in.offered, needed, "size mismatch");
-		torture_assert_mem_equal(tctx, blob.data, data, needed, "buffer mismatch");


-- 
Samba Shared Repository


More information about the samba-cvs mailing list