[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