#include "libcli/resolve/resolve.h"
#include "lib/cmdline/popt_common.h"
#include "system/filesys.h"
+#include "torture/ndr/ndr.h"
#define TORTURE_WELLKNOWN_PRINTER "torture_wkn_printer"
#define TORTURE_PRINTER "torture_printer"
#define TORTURE_PRINTER_EX "torture_printer_ex"
#define TORTURE_DRIVER "torture_driver"
#define TORTURE_DRIVER_EX "torture_driver_ex"
+#define TORTURE_DRIVER_ADOBE "torture_driver_adobe"
+#define TORTURE_DRIVER_EX_ADOBE "torture_driver_ex_adobe"
+#define TORTURE_DRIVER_ADOBE_CUPSADDSMB "torture_driver_adobe_cupsaddsmb"
#define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print"
#define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers"
#define TOP_LEVEL_CONTROL_ENVIRONMENTS_KEY TOP_LEVEL_CONTROL_KEY "\\Environments"
struct test_spoolss_context {
+ struct dcerpc_pipe *spoolss_pipe;
+
+ /* server environment */
+ const char *environment;
+
/* print server handle */
struct policy_handle server_handle;
};
struct torture_printer_context {
+ struct dcerpc_pipe *spoolss_pipe;
struct spoolss_SetPrinterInfo2 info2;
struct torture_driver_context driver;
bool ex;
bool added_driver;
bool have_driver;
struct spoolss_DeviceMode *devmode;
+ struct policy_handle handle;
};
static bool upload_printer_driver(struct torture_context *tctx,
#define DO_ROUND(size, n) (((size)+((n)-1)) & ~((n)-1))
-#define CHECK_NEEDED_SIZE_ENUM_LEVEL(fn, info, level, count, ic, needed, align) do { \
+#define CHECK_NEEDED_SIZE_ENUM_LEVEL(fn, info, level, count, needed, align) do { \
if (torture_setting_bool(tctx, "spoolss_check_size", false)) {\
- uint32_t size = ndr_size_##fn##_info(tctx, ic, level, count, info);\
+ uint32_t size = ndr_size_##fn##_info(tctx, level, count, info);\
uint32_t round_size = DO_ROUND(size, align);\
if (round_size != needed) {\
torture_warning(tctx, __location__": "#fn" level %d (count: %d) got unexpected needed size: %d, we calculated: %d", level, count, needed, round_size);\
}\
} while(0)
-#define CHECK_NEEDED_SIZE_ENUM(fn, info, count, ic, needed, align) do { \
+#define CHECK_NEEDED_SIZE_ENUM(fn, info, count, needed, align) do { \
if (torture_setting_bool(tctx, "spoolss_check_size", false)) {\
- uint32_t size = ndr_size_##fn##_info(tctx, ic, count, info);\
+ uint32_t size = ndr_size_##fn##_info(tctx, count, info);\
uint32_t round_size = DO_ROUND(size, align);\
if (round_size != needed) {\
torture_warning(tctx, __location__": "#fn" (count: %d) got unexpected needed size: %d, we calculated: %d", count, needed, round_size);\
}\
} while(0)
-#define CHECK_NEEDED_SIZE_LEVEL(fn, info, level, ic, needed, align) do { \
+#define CHECK_NEEDED_SIZE_LEVEL(fn, info, level, needed, align) do { \
if (torture_setting_bool(tctx, "spoolss_check_size", false)) {\
- uint32_t size = ndr_size_##fn(info, level, ic, 0);\
+ uint32_t size = ndr_size_##fn(info, level, 0);\
uint32_t round_size = DO_ROUND(size, align);\
if (round_size != needed) {\
torture_warning(tctx, __location__": "#fn" level %d got unexpected needed size: %d, we calculated: %d", level, needed, round_size);\
}
static bool test_EnumPorts(struct torture_context *tctx,
- struct dcerpc_binding_handle *b,
- struct test_spoolss_context *ctx)
+ void *private_data)
{
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
+ struct dcerpc_binding_handle *b = p->binding_handle;
NTSTATUS status;
struct spoolss_EnumPorts r;
uint16_t levels[] = { 1, 2 };
torture_assert(tctx, info, "EnumPorts returned no info");
- CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPorts, info, r.in.level, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPorts, info, r.in.level, count, needed, 4);
ctx->port_count[level] = count;
ctx->ports[level] = info;
}
static bool test_GetPrintProcessorDirectory(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- const char *environment)
+ void *private_data)
{
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
+
NTSTATUS status;
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
struct dcerpc_binding_handle *b = p->binding_handle;
struct spoolss_GetPrintProcessorDirectory r;
struct {
DATA_BLOB blob;
r.in.server = levels[i].server;
- r.in.environment = environment;
+ r.in.environment = ctx->environment;
r.in.level = level;
r.in.buffer = NULL;
r.in.offered = 0;
torture_assert_werr_ok(tctx, r.out.result, "GetPrintProcessorDirectory failed");
- CHECK_NEEDED_SIZE_LEVEL(spoolss_PrintProcessorDirectoryInfo, r.out.info, r.in.level, lp_iconv_convenience(tctx->lp_ctx), needed, 2);
+ CHECK_NEEDED_SIZE_LEVEL(spoolss_PrintProcessorDirectoryInfo, r.out.info, r.in.level, needed, 2);
}
return true;
static bool test_GetPrinterDriverDirectory(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- const char *environment)
+ void *private_data)
{
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
+
NTSTATUS status;
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
struct dcerpc_binding_handle *b = p->binding_handle;
struct spoolss_GetPrinterDriverDirectory r;
struct {
DATA_BLOB blob;
r.in.server = levels[i].server;
- r.in.environment = environment;
+ r.in.environment = ctx->environment;
r.in.level = level;
r.in.buffer = NULL;
r.in.offered = 0;
torture_assert_werr_ok(tctx, r.out.result, "GetPrinterDriverDirectory failed");
- CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverDirectoryInfo, r.out.info, r.in.level, lp_iconv_convenience(tctx->lp_ctx), needed, 2);
+ CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverDirectoryInfo, r.out.info, r.in.level, needed, 2);
}
return true;
*info_p = info;
}
- CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinterDrivers, info, r.in.level, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinterDrivers, info, r.in.level, count, needed, 4);
return true;
}
static bool test_EnumPrinterDrivers(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- struct test_spoolss_context *ctx,
- const char *architecture)
+ void *private_data)
{
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
struct dcerpc_binding_handle *b = p->binding_handle;
uint16_t levels[] = { 1, 2, 3, 4, 5, 6, 8 };
- int i, j;
+ int i, j, a;
/* FIXME: gd, come back and fix "" as server, and handle
* priority of returned error codes in torture test and samba 3
* server */
const char *server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
+ const char *environments[2];
+
+ environments[0] = SPOOLSS_ARCHITECTURE_ALL;
+ environments[1] = ctx->environment;
+
+ for (a=0;a<ARRAY_SIZE(environments);a++) {
for (i=0;i<ARRAY_SIZE(levels);i++) {
int level = levels[i];
union spoolss_DriverInfo *info;
torture_assert(tctx,
- test_EnumPrinterDrivers_args(tctx, b, server_name, architecture, level, &count, &info),
+ test_EnumPrinterDrivers_args(tctx, b, server_name, environments[a], level, &count, &info),
"failed to enumerate drivers");
ctx->driver_count[level] = count;
}
}
}
+ }
return true;
}
static bool test_EnumMonitors(struct torture_context *tctx,
- struct dcerpc_binding_handle *b,
- struct test_spoolss_context *ctx)
+ void *private_data)
{
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
+ struct dcerpc_binding_handle *b = p->binding_handle;
NTSTATUS status;
struct spoolss_EnumMonitors r;
uint16_t levels[] = { 1, 2 };
torture_assert_werr_ok(tctx, r.out.result, "EnumMonitors failed");
- CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumMonitors, info, r.in.level, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumMonitors, info, r.in.level, count, needed, 4);
ctx->monitor_count[level] = count;
ctx->monitors[level] = info;
return true;
}
-static bool test_EnumPrintProcessors(struct torture_context *tctx,
- struct dcerpc_binding_handle *b,
- struct test_spoolss_context *ctx,
- const char *environment)
+static bool test_EnumPrintProcessors_level(struct torture_context *tctx,
+ struct dcerpc_binding_handle *b,
+ const char *environment,
+ uint32_t level,
+ uint32_t *count_p,
+ union spoolss_PrintProcessorInfo **info_p,
+ WERROR expected_result)
{
- NTSTATUS status;
struct spoolss_EnumPrintProcessors r;
- uint16_t levels[] = { 1 };
- int i, j;
-
- for (i=0;i<ARRAY_SIZE(levels);i++) {
- int level = levels[i];
- DATA_BLOB blob;
- uint32_t needed;
- uint32_t count;
- union spoolss_PrintProcessorInfo *info;
-
- r.in.servername = "";
- r.in.environment = environment;
- r.in.level = level;
- r.in.buffer = NULL;
- r.in.offered = 0;
- r.out.needed = &needed;
- r.out.count = &count;
- r.out.info = &info;
+ DATA_BLOB blob;
+ uint32_t needed;
+ uint32_t count;
+ union spoolss_PrintProcessorInfo *info;
- torture_comment(tctx, "Testing EnumPrintProcessors level %u\n", r.in.level);
+ r.in.servername = "";
+ r.in.environment = environment;
+ r.in.level = level;
+ r.in.buffer = NULL;
+ r.in.offered = 0;
+ r.out.needed = &needed;
+ r.out.count = &count;
+ r.out.info = &info;
- status = dcerpc_spoolss_EnumPrintProcessors_r(b, ctx, &r);
- torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrintProcessors failed");
- if (W_ERROR_IS_OK(r.out.result)) {
- /* TODO: do some more checks here */
- continue;
- }
- torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
- "EnumPrintProcessors unexpected return code");
+ torture_comment(tctx, "Testing EnumPrintProcessors(%s) level %u\n",
+ r.in.environment, r.in.level);
- blob = data_blob_talloc_zero(ctx, needed);
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_spoolss_EnumPrintProcessors_r(b, tctx, &r),
+ "EnumPrintProcessors failed");
+ if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ blob = data_blob_talloc_zero(tctx, needed);
r.in.buffer = &blob;
r.in.offered = needed;
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_spoolss_EnumPrintProcessors_r(b, tctx, &r),
+ "EnumPrintProcessors failed");
+ }
+ torture_assert_werr_equal(tctx, r.out.result, expected_result,
+ "EnumPrintProcessors failed");
+
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrintProcessors, info, level, count, needed, 4);
+
+ if (count_p) {
+ *count_p = count;
+ }
+ if (info_p) {
+ *info_p = info;
+ }
+
+ return true;
+}
+
+static bool test_EnumPrintProcessors(struct torture_context *tctx,
+ void *private_data)
+{
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
- status = dcerpc_spoolss_EnumPrintProcessors_r(b, ctx, &r);
- torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrintProcessors failed");
+ uint16_t levels[] = {0, 1, 2, 3, 32, 256 };
+ uint16_t ok[] = {0, 1, 0, 0, 0, 0 };
+ int i;
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
+ struct dcerpc_binding_handle *b = p->binding_handle;
- torture_assert_werr_ok(tctx, r.out.result, "EnumPrintProcessors failed");
+ torture_assert(tctx,
+ test_EnumPrintProcessors_level(tctx, b, "phantasy", 1, NULL, NULL, WERR_INVALID_ENVIRONMENT),
+ "test_EnumPrintProcessors_level failed");
- CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrintProcessors, info, r.in.level, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+ for (i=0;i<ARRAY_SIZE(levels);i++) {
+ union spoolss_PrintProcessorInfo *info;
+ uint32_t count;
+ WERROR expected_result = ok[i] ? WERR_OK : WERR_INVALID_LEVEL;
- ctx->print_processor_count[level] = count;
- ctx->print_processors[level] = info;
+ torture_assert(tctx,
+ test_EnumPrintProcessors_level(tctx, b, ctx->environment, levels[i], &count, &info, expected_result),
+ "test_EnumPrintProcessors_level failed");
}
- for (i=1;i<ARRAY_SIZE(levels);i++) {
- int level = levels[i];
- int old_level = levels[i-1];
- torture_assert_int_equal(tctx, ctx->print_processor_count[level], ctx->print_processor_count[old_level],
- "EnumPrintProcessors failed");
+ return true;
+}
+
+static bool test_EnumPrintProcDataTypes_level(struct torture_context *tctx,
+ struct dcerpc_binding_handle *b,
+ const char *print_processor_name,
+ uint32_t level,
+ uint32_t *count_p,
+ union spoolss_PrintProcDataTypesInfo **info_p,
+ WERROR expected_result)
+{
+ struct spoolss_EnumPrintProcDataTypes r;
+ DATA_BLOB blob;
+ uint32_t needed;
+ uint32_t count;
+ union spoolss_PrintProcDataTypesInfo *info;
+
+ r.in.servername = "";
+ r.in.print_processor_name = print_processor_name;
+ r.in.level = level;
+ r.in.buffer = NULL;
+ r.in.offered = 0;
+ r.out.needed = &needed;
+ r.out.count = &count;
+ r.out.info = &info;
+
+ torture_comment(tctx, "Testing EnumPrintProcDataTypes(%s) level %u\n",
+ r.in.print_processor_name, r.in.level);
+
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_spoolss_EnumPrintProcDataTypes_r(b, tctx, &r),
+ "EnumPrintProcDataTypes failed");
+ if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ blob = data_blob_talloc_zero(tctx, needed);
+ r.in.buffer = &blob;
+ r.in.offered = needed;
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_spoolss_EnumPrintProcDataTypes_r(b, tctx, &r),
+ "EnumPrintProcDataTypes failed");
}
+ torture_assert_werr_equal(tctx, r.out.result, expected_result,
+ "EnumPrintProcDataTypes failed");
- for (i=0;i<ARRAY_SIZE(levels);i++) {
- int level = levels[i];
- for (j=0;j<ctx->print_processor_count[level];j++) {
-#if 0
- union spoolss_PrintProcessorInfo *cur = &ctx->print_processors[level][j];
- union spoolss_PrintProcessorInfo *ref = &ctx->print_processors[1][j];
-#endif
- switch (level) {
- case 1:
- /* level 1 is our reference, and it makes no sense to compare it to itself */
- break;
- }
- }
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrintProcDataTypes, info, level, count, needed, 4);
+
+ if (count_p) {
+ *count_p = count;
+ }
+ if (info_p) {
+ *info_p = info;
}
return true;
}
static bool test_EnumPrintProcDataTypes(struct torture_context *tctx,
- struct dcerpc_binding_handle *b)
+ void *private_data)
{
- NTSTATUS status;
- struct spoolss_EnumPrintProcDataTypes r;
- uint16_t levels[] = { 1 };
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
+
+ uint16_t levels[] = {0, 1, 2, 3, 32, 256 };
+ uint16_t ok[] = {0, 1, 0, 0, 0, 0 };
int i;
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
+ struct dcerpc_binding_handle *b = p->binding_handle;
+
+ torture_assert(tctx,
+ test_EnumPrintProcDataTypes_level(tctx, b, NULL, 1, NULL, NULL, WERR_UNKNOWN_PRINTPROCESSOR),
+ "test_EnumPrintProcDataTypes_level failed");
+
+ torture_assert(tctx,
+ test_EnumPrintProcDataTypes_level(tctx, b, "nonexisting", 1, NULL, NULL, WERR_UNKNOWN_PRINTPROCESSOR),
+ "test_EnumPrintProcDataTypes_level failed");
for (i=0;i<ARRAY_SIZE(levels);i++) {
int level = levels[i];
- DATA_BLOB blob;
- uint32_t needed;
uint32_t count;
union spoolss_PrintProcDataTypesInfo *info;
+ WERROR expected_result = ok[i] ? WERR_OK : WERR_INVALID_LEVEL;
- r.in.servername = "";
- r.in.print_processor_name = "winprint";
- r.in.level = level;
- r.in.buffer = NULL;
- r.in.offered = 0;
- r.out.needed = &needed;
- r.out.count = &count;
- r.out.info = &info;
-
- torture_comment(tctx, "Testing EnumPrintProcDataTypes level %u\n", r.in.level);
-
- status = dcerpc_spoolss_EnumPrintProcDataTypes_r(b, tctx, &r);
- torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrintProcDataType failed");
- if (W_ERROR_IS_OK(r.out.result)) {
- /* TODO: do some more checks here */
- continue;
- }
- torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
- "EnumPrintProcDataTypes unexpected return code");
-
- blob = data_blob_talloc_zero(tctx, needed);
- r.in.buffer = &blob;
- r.in.offered = needed;
-
- status = dcerpc_spoolss_EnumPrintProcDataTypes_r(b, tctx, &r);
- torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrintProcDataTypes failed");
+ torture_assert(tctx,
+ test_EnumPrintProcDataTypes_level(tctx, b, "winprint", level, &count, &info, expected_result),
+ "test_EnumPrintProcDataTypes_level failed");
+ }
- torture_assert_werr_ok(tctx, r.out.result, "EnumPrintProcDataTypes failed");
+ {
+ union spoolss_PrintProcessorInfo *info;
+ uint32_t count;
- CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrintProcDataTypes, info, r.in.level, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+ torture_assert(tctx,
+ test_EnumPrintProcessors_level(tctx, b, ctx->environment, 1, &count, &info, WERR_OK),
+ "test_EnumPrintProcessors_level failed");
+ for (i=0; i < count; i++) {
+ torture_assert(tctx,
+ test_EnumPrintProcDataTypes_level(tctx, b, info[i].info1.print_processor_name, 1, NULL, NULL, WERR_OK),
+ "test_EnumPrintProcDataTypes_level failed");
+ }
}
+
return true;
}
-
static bool test_EnumPrinters(struct torture_context *tctx,
- struct dcerpc_binding_handle *b,
- struct test_spoolss_context *ctx)
+ void *private_data)
{
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
+ struct dcerpc_binding_handle *b = p->binding_handle;
struct spoolss_EnumPrinters r;
NTSTATUS status;
uint16_t levels[] = { 0, 1, 2, 4, 5 };
torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
- CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinters, info, r.in.level, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinters, info, r.in.level, count, needed, 4);
ctx->printer_count[level] = count;
ctx->printers[level] = info;
torture_assert_werr_ok(tctx, r.out.result, "GetPrinter failed");
- CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterInfo, r.out.info, r.in.level, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+ CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterInfo, r.out.info, r.in.level, needed, 4);
if (info && r.out.info) {
*info = *r.out.info;
bool ret = true;
int i;
+ torture_skip(tctx, "Printer Info test is currently broken, skipping");
+
uint32_t status_list[] = {
/* these do not stick
PRINTER_STATUS_PAUSED,
return ret;
}
-#define torture_assert_sid_equal(torture_ctx,got,expected,cmt)\
- do { struct dom_sid *__got = (got), *__expected = (expected); \
- if (!dom_sid_equal(__got, __expected)) { \
- torture_result(torture_ctx, TORTURE_FAIL, \
- __location__": "#got" was %s, expected %s: %s", \
- dom_sid_string(torture_ctx, __got), dom_sid_string(torture_ctx, __expected), cmt); \
- return false; \
- } \
- } while(0)
-
static bool test_security_descriptor_equal(struct torture_context *tctx,
const struct security_descriptor *sd1,
const struct security_descriptor *sd2)
struct spoolss_DeviceMode *devmode,
struct policy_handle *handle);
-static bool test_ClosePrinter(struct torture_context *tctx,
- struct dcerpc_binding_handle *b,
- struct policy_handle *handle);
-
static bool test_PrinterInfo_DevModes(struct torture_context *tctx,
struct dcerpc_pipe *p,
struct policy_handle *handle,
return ret;
}
-static bool test_ClosePrinter(struct torture_context *tctx,
- struct dcerpc_binding_handle *b,
- struct policy_handle *handle)
+bool test_ClosePrinter(struct torture_context *tctx,
+ struct dcerpc_binding_handle *b,
+ struct policy_handle *handle)
{
NTSTATUS status;
struct spoolss_ClosePrinter r;
torture_assert_werr_ok(tctx, r.out.result, "GetForm failed");
- CHECK_NEEDED_SIZE_LEVEL(spoolss_FormInfo, r.out.info, r.in.level, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+ CHECK_NEEDED_SIZE_LEVEL(spoolss_FormInfo, r.out.info, r.in.level, needed, 4);
if (info_p) {
*info_p = *r.out.info;
torture_assert_werr_ok(tctx, r.out.result, "EnumForms failed");
- CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumForms, info, r.in.level, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumForms, info, r.in.level, count, needed, 4);
if (info_p) {
*info_p = info;
if (winreg_handle && hive_handle && W_ERROR_IS_OK(expected_add_result)) {
+ struct spoolss_FormInfo1 i1;
+
torture_assert(tctx,
test_GetForm_winreg(tctx, winreg_handle, hive_handle, TOP_LEVEL_CONTROL_FORMS_KEY, form_name, &w_type, &w_size, &w_length, &w_data),
"failed to get form via winreg");
+ i1.size.width = IVAL(w_data, 0);
+ i1.size.height = IVAL(w_data, 4);
+ i1.area.left = IVAL(w_data, 8);
+ i1.area.top = IVAL(w_data, 12);
+ i1.area.right = IVAL(w_data, 16);
+ i1.area.bottom = IVAL(w_data, 20);
+ /* skip index here */
+ i1.flags = IVAL(w_data, 28);
+
torture_assert_int_equal(tctx, w_type, REG_BINARY, "unexpected type");
torture_assert_int_equal(tctx, w_size, 0x20, "unexpected size");
torture_assert_int_equal(tctx, w_length, 0x20, "unexpected length");
- torture_assert_mem_equal(tctx, &w_data[0], &add_info.info1->size.width, 4, "width mismatch");
- torture_assert_mem_equal(tctx, &w_data[4], &add_info.info1->size.height, 4, "height mismatch");
- torture_assert_mem_equal(tctx, &w_data[8], &add_info.info1->area.left, 4, "left mismatch");
- torture_assert_mem_equal(tctx, &w_data[12], &add_info.info1->area.top, 4, "top mismatch");
- torture_assert_mem_equal(tctx, &w_data[16], &add_info.info1->area.right, 4, "right mismatch");
- torture_assert_mem_equal(tctx, &w_data[20], &add_info.info1->area.bottom, 4, "bottom mismatch");
- /* skip index here */
- torture_assert_mem_equal(tctx, &w_data[28], &add_info.info1->flags, 4, "flags mismatch");
+ torture_assert_int_equal(tctx, i1.size.width, add_info.info1->size.width, "width mismatch");
+ torture_assert_int_equal(tctx, i1.size.height, add_info.info1->size.height, "height mismatch");
+ torture_assert_int_equal(tctx, i1.area.left, add_info.info1->area.left, "left mismatch");
+ torture_assert_int_equal(tctx, i1.area.top, add_info.info1->area.top, "top mismatch");
+ torture_assert_int_equal(tctx, i1.area.right, add_info.info1->area.right, "right mismatch");
+ torture_assert_int_equal(tctx, i1.area.bottom, add_info.info1->area.bottom, "bottom mismatch");
+ torture_assert_int_equal(tctx, i1.flags, add_info.info1->flags, "flags mismatch");
}
if (!print_server && W_ERROR_IS_OK(expected_add_result)) {
torture_assert_int_equal(tctx, info.info1.flags, add_info.info1->flags, "flags mismatch");
if (winreg_handle && hive_handle) {
- torture_assert_mem_equal(tctx, &w_data[0], &info.info1.size.width, 4, "width mismatch");
- torture_assert_mem_equal(tctx, &w_data[4], &info.info1.size.height, 4, "height mismatch");
- torture_assert_mem_equal(tctx, &w_data[8], &info.info1.area.left, 4, "left mismatch");
- torture_assert_mem_equal(tctx, &w_data[12], &info.info1.area.top, 4, "top mismatch");
- torture_assert_mem_equal(tctx, &w_data[16], &info.info1.area.right, 4, "right mismatch");
- torture_assert_mem_equal(tctx, &w_data[20], &info.info1.area.bottom, 4, "bottom mismatch");
+
+ struct spoolss_FormInfo1 i1;
+
+ i1.size.width = IVAL(w_data, 0);
+ i1.size.height = IVAL(w_data, 4);
+ i1.area.left = IVAL(w_data, 8);
+ i1.area.top = IVAL(w_data, 12);
+ i1.area.right = IVAL(w_data, 16);
+ i1.area.bottom = IVAL(w_data, 20);
/* skip index here */
- torture_assert_mem_equal(tctx, &w_data[28], &info.info1.flags, 4, "flags mismatch");
+ i1.flags = IVAL(w_data, 28);
+
+ torture_assert_int_equal(tctx, i1.size.width, info.info1.size.width, "width mismatch");
+ torture_assert_int_equal(tctx, i1.size.height, info.info1.size.height, "height mismatch");
+ torture_assert_int_equal(tctx, i1.area.left, info.info1.area.left, "left mismatch");
+ torture_assert_int_equal(tctx, i1.area.top, info.info1.area.top, "top mismatch");
+ torture_assert_int_equal(tctx, i1.area.right, info.info1.area.right, "right mismatch");
+ torture_assert_int_equal(tctx, i1.area.bottom, info.info1.area.bottom, "bottom mismatch");
+ torture_assert_int_equal(tctx, i1.flags, info.info1.flags, "flags mismatch");
}
add_info.info1->size.width = 1234;
}
static bool test_EnumPorts_old(struct torture_context *tctx,
- struct dcerpc_pipe *p)
+ void *private_data)
{
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
+
NTSTATUS status;
struct spoolss_EnumPorts r;
uint32_t needed;
uint32_t count;
union spoolss_PortInfo *info;
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
struct dcerpc_binding_handle *b = p->binding_handle;
r.in.servername = talloc_asprintf(tctx, "\\\\%s",
torture_assert_werr_ok(tctx, r.out.result, "EnumPorts failed");
- CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPorts, info, 2, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPorts, info, 2, count, needed, 4);
return true;
}
static bool test_AddPort(struct torture_context *tctx,
- struct dcerpc_pipe *p)
+ void *private_data)
{
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
+
NTSTATUS status;
struct spoolss_AddPort r;
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
struct dcerpc_binding_handle *b = p->binding_handle;
r.in.server_name = talloc_asprintf(tctx, "\\\\%s",
torture_assert_werr_ok(tctx, r.out.result, "GetJob failed");
torture_assert(tctx, r.out.info, "No job info returned");
- CHECK_NEEDED_SIZE_LEVEL(spoolss_JobInfo, r.out.info, r.in.level, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+ CHECK_NEEDED_SIZE_LEVEL(spoolss_JobInfo, r.out.info, r.in.level, needed, 4);
if (info_p) {
*info_p = *r.out.info;
torture_assert_werr_ok(tctx, r.out.result, "EnumJobs failed");
torture_assert(tctx, info, "No jobs returned");
- CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumJobs, *r.out.info, r.in.level, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumJobs, *r.out.info, r.in.level, count, needed, 4);
} else {
torture_assert_werr_ok(tctx, r.out.result, "EnumJobs failed");
if (strequal(ginfo.info1.document_name, document_name)) {
torture_warning(tctx,
- talloc_asprintf(tctx, "document_name did *NOT* change from '%s' to '%s'\n",
- document_name, new_document_name));
+ "document_name did *NOT* change from '%s' to '%s'\n",
+ document_name, new_document_name);
}
}
uint32_t *job_ids;
int i;
+ torture_comment(tctx, "Testing real print operations\n");
+
+ job_ids = talloc_zero_array(tctx, uint32_t, num_jobs);
+
+ for (i=0; i < num_jobs; i++) {
+ ret &= test_DoPrintTest_add_one_job(tctx, b, handle, &job_ids[i]);
+ }
+
+ for (i=0; i < num_jobs; i++) {
+ ret &= test_SetJob(tctx, b, handle, job_ids[i], NULL, SPOOLSS_JOB_CONTROL_DELETE);
+ }
+
+ if (ret == true) {
+ torture_comment(tctx, "real print operations test succeeded\n\n");
+ }
+
+ return ret;
+}
+
+static bool test_DoPrintTest_extended(struct torture_context *tctx,
+ struct dcerpc_binding_handle *b,
+ struct policy_handle *handle)
+{
+ bool ret = true;
+ uint32_t num_jobs = 8;
+ uint32_t *job_ids;
+ int i;
+ torture_comment(tctx, "Testing real print operations (extended)\n");
+
job_ids = talloc_zero_array(tctx, uint32_t, num_jobs);
for (i=0; i < num_jobs; i++) {
ret &= test_SetJob(tctx, b, handle, job_ids[i], NULL, SPOOLSS_JOB_CONTROL_DELETE);
}
+ if (ret == true) {
+ torture_comment(tctx, "real print operations (extended) test succeeded\n\n");
+ }
+
return ret;
}
return true;
}
-static bool test_GetPrinterData(struct torture_context *tctx,
- struct dcerpc_binding_handle *b,
- struct policy_handle *handle,
- const char *value_name,
- enum winreg_Type *type_p,
- uint8_t **data_p,
- uint32_t *needed_p)
+static bool test_GetPrinterData_checktype(struct torture_context *tctx,
+ struct dcerpc_binding_handle *b,
+ struct policy_handle *handle,
+ const char *value_name,
+ enum winreg_Type *expected_type,
+ enum winreg_Type *type_p,
+ uint8_t **data_p,
+ uint32_t *needed_p)
{
NTSTATUS status;
struct spoolss_GetPrinterData r;
torture_assert_ntstatus_ok(tctx, status, "GetPrinterData failed");
if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
+ if (expected_type) {
+ torture_assert_int_equal(tctx, type, *expected_type, "unexpected type");
+ }
r.in.offered = needed;
r.out.data = talloc_zero_array(tctx, uint8_t, r.in.offered);
status = dcerpc_spoolss_GetPrinterData_r(b, tctx, &r);
torture_assert_werr_ok(tctx, r.out.result,
talloc_asprintf(tctx, "GetPrinterData(%s) failed", r.in.value_name));
- CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterData, &data, type, lp_iconv_convenience(tctx->lp_ctx), needed, 1);
+ CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterData, &data, type, needed, 1);
if (type_p) {
*type_p = type;
return true;
}
-static bool test_GetPrinterDataEx(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- struct policy_handle *handle,
- const char *key_name,
- const char *value_name,
- enum winreg_Type *type_p,
- uint8_t **data_p,
- uint32_t *needed_p)
+static bool test_GetPrinterData(struct torture_context *tctx,
+ struct dcerpc_binding_handle *b,
+ struct policy_handle *handle,
+ const char *value_name,
+ enum winreg_Type *type_p,
+ uint8_t **data_p,
+ uint32_t *needed_p)
+{
+ return test_GetPrinterData_checktype(tctx, b, handle, value_name,
+ NULL, type_p, data_p, needed_p);
+}
+
+static bool test_GetPrinterDataEx_checktype(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle,
+ const char *key_name,
+ const char *value_name,
+ enum winreg_Type *expected_type,
+ enum winreg_Type *type_p,
+ uint8_t **data_p,
+ uint32_t *needed_p)
{
NTSTATUS status;
struct spoolss_GetPrinterDataEx r;
}
if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
+ if (expected_type) {
+ torture_assert_int_equal(tctx, type, *expected_type, "unexpected type");
+ }
r.in.offered = needed;
r.out.data = talloc_zero_array(tctx, uint8_t, r.in.offered);
status = dcerpc_spoolss_GetPrinterDataEx_r(b, tctx, &r);
torture_assert_werr_ok(tctx, r.out.result,
talloc_asprintf(tctx, "GetPrinterDataEx(%s - %s) failed", r.in.key_name, r.in.value_name));
- CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterData, &data, type, lp_iconv_convenience(tctx->lp_ctx), needed, 1);
+ CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterData, &data, type, needed, 1);
if (type_p) {
*type_p = type;
return true;
}
+static bool test_GetPrinterDataEx(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle,
+ const char *key_name,
+ const char *value_name,
+ enum winreg_Type *type_p,
+ uint8_t **data_p,
+ uint32_t *needed_p)
+{
+ return test_GetPrinterDataEx_checktype(tctx, p, handle, key_name, value_name,
+ NULL, type_p, data_p, needed_p);
+}
+
static bool test_get_environment(struct torture_context *tctx,
struct dcerpc_binding_handle *b,
struct policy_handle *handle,
torture_assert_int_equal(tctx, type, REG_SZ, "unexpected type");
blob = data_blob_const(data, needed);
- *architecture = reg_val_data_string(tctx, lp_iconv_convenience(tctx->lp_ctx), REG_SZ, blob);
+ *architecture = reg_val_data_string(tctx, REG_SZ, blob);
return true;
}
static bool test_GetPrinterData_list(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- struct policy_handle *handle,
- const char **architecture)
+ void *private_data)
{
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
struct dcerpc_binding_handle *b = p->binding_handle;
const char *list[] = {
"W3SvcInstalled",
uint8_t *data, *data_ex;
uint32_t needed, needed_ex;
- torture_assert(tctx, test_GetPrinterData(tctx, b, handle, list[i], &type, &data, &needed),
+ torture_assert(tctx, test_GetPrinterData(tctx, b, &ctx->server_handle, list[i], &type, &data, &needed),
talloc_asprintf(tctx, "GetPrinterData failed on %s\n", list[i]));
- torture_assert(tctx, test_GetPrinterDataEx(tctx, p, handle, "random_string", list[i], &type_ex, &data_ex, &needed_ex),
+ torture_assert(tctx, test_GetPrinterDataEx(tctx, p, &ctx->server_handle, "random_string", list[i], &type_ex, &data_ex, &needed_ex),
talloc_asprintf(tctx, "GetPrinterDataEx failed on %s\n", list[i]));
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;
}
torture_assert_werr_ok(tctx, r.out.result, "EnumPrinterDataEx failed");
- CHECK_NEEDED_SIZE_ENUM(spoolss_EnumPrinterDataEx, info, count, lp_iconv_convenience(tctx->lp_ctx), needed, 1);
+ CHECK_NEEDED_SIZE_ENUM(spoolss_EnumPrinterDataEx, info, count, needed, 1);
if (count_p) {
*count_p = count;
torture_comment(tctx, "Testing EnumPrinterData vs EnumPrinterDataEx consistency\n");
- torture_assert(tctx,
- reg_string_to_val(tctx, lp_iconv_convenience(tctx->lp_ctx),
- "REG_SZ", "torture_data1", &type, &blob), "");
+ torture_assert(tctx, push_reg_sz(tctx, &blob, "torture_data1"), "");
+ type = REG_SZ;
torture_assert(tctx,
test_SetPrinterData(tctx, b, handle, "torture_value1", type, blob.data, blob.length),
torture_assert_int_equal(tctx, w_type, REG_LINK, "unexpected type");
blob = data_blob(w_data, w_size);
- str = reg_val_data_string(tctx, lp_iconv_convenience(tctx->lp_ctx), REG_SZ, blob);
+ str = reg_val_data_string(tctx, REG_SZ, blob);
torture_assert_str_equal(tctx, str, symlink_destination, "unexpected symlink target string");
"failed to query winreg");\
torture_assert_int_equal(tctx, w_type, REG_SZ, "unexpected type");\
blob = data_blob(w_data, w_size);\
- str = reg_val_data_string(tctx, lp_iconv_convenience(tctx->lp_ctx), REG_SZ, blob);\
+ str = reg_val_data_string(tctx, REG_SZ, blob);\
if (w_size == 2 && iname == NULL) {\
/*torture_comment(tctx, "%s: \"\", %s: (null)\n", #wname, #iname);\ */\
} else {\
"failed to query winreg");\
torture_assert_int_equal(tctx, w_type, REG_BINARY, "unexpected type");\
blob = data_blob(w_data, w_size);\
- ndr_err = ndr_pull_struct_blob(&blob, tctx, lp_iconv_convenience(tctx->lp_ctx), &dm,\
+ ndr_err = ndr_pull_struct_blob(&blob, tctx, &dm,\
(ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);\
torture_assert_ndr_success(tctx, ndr_err, "failed to unmarshall dm");\
torture_assert(tctx, test_devicemode_equal(tctx, &dm, iname),\
"failed to query winreg");\
torture_assert_int_equal(tctx, w_type, REG_BINARY, "unexpected type");\
blob = data_blob(w_data, w_size);\
- ndr_err = ndr_pull_struct_blob(&blob, tctx, lp_iconv_convenience(tctx->lp_ctx), &sd,\
+ ndr_err = ndr_pull_struct_blob(&blob, tctx, &sd,\
(ndr_pull_flags_fn_t)ndr_pull_security_descriptor);\
torture_assert_ndr_success(tctx, ndr_err, "failed to unmarshall sd");\
torture_assert(tctx, test_security_descriptor_equal(tctx, &sd, iname),\
torture_assert_int_equal(tctx, w_type, REG_MULTI_SZ, "unexpected type");\
blob = data_blob(w_data, w_size);\
torture_assert(tctx, \
- pull_reg_multi_sz(tctx, lp_iconv_convenience(tctx->lp_ctx), &blob, &array),\
+ pull_reg_multi_sz(tctx, &blob, &array),\
"failed to pull multi sz");\
for (i=0; array[i] != NULL; i++) {\
torture_assert_str_equal(tctx, array[i], iname[i],\
}\
} while(0);
-
if (!test_winreg_symbolic_link(tctx, winreg_handle, hive_handle,
TOP_LEVEL_CONTROL_PRINTERS_KEY,
"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Print\\Printers"))
torture_warning(tctx, "failed to check for winreg symlink");
}
-
for (i=0; i < ARRAY_SIZE(keys); i++) {
const char *printer_key;
return true;
}
+static bool test_PrintProcessors(struct torture_context *tctx,
+ struct dcerpc_binding_handle *b,
+ const char *environment,
+ struct dcerpc_binding_handle *winreg_handle,
+ struct policy_handle *hive_handle)
+{
+ union spoolss_PrintProcessorInfo *info;
+ uint32_t count;
+ int i;
+
+ torture_comment(tctx, "Testing Print Processor Info and winreg consistency\n");
+
+ torture_assert(tctx,
+ test_EnumPrintProcessors_level(tctx, b, environment, 1, &count, &info, WERR_OK),
+ "failed to enum print processors level 1");
+
+ for (i=0; i < count; i++) {
+
+ const char *processor_key;
+ struct policy_handle key_handle;
+
+ processor_key = talloc_asprintf(tctx, "%s\\%s\\Print Processors\\%s",
+ TOP_LEVEL_CONTROL_ENVIRONMENTS_KEY,
+ environment,
+ info[i].info1.print_processor_name);
+
+ torture_assert(tctx,
+ test_winreg_OpenKey(tctx, winreg_handle, hive_handle, processor_key, &key_handle), "");
+
+ /* nothing to check in there so far */
+
+ torture_assert(tctx,
+ test_winreg_CloseKey(tctx, winreg_handle, &key_handle), "");
+ }
+
+ torture_comment(tctx, "Print Processor Info and winreg consistency test succeeded\n\n");
+
+ return true;
+}
+
static bool test_GetPrinterDriver2_level(struct torture_context *tctx,
struct dcerpc_binding_handle *b,
struct policy_handle *handle,
for (i=0; i < ARRAY_SIZE(values); i++) {
- enum winreg_Type type;
+ enum winreg_Type type, expected_type = REG_SZ;
DATA_BLOB blob;
uint8_t *data;
uint32_t needed;
- torture_assert(tctx,
- reg_string_to_val(tctx, lp_iconv_convenience(tctx->lp_ctx),
- "REG_SZ", "dog", &type, &blob), "");
+ torture_assert(tctx, push_reg_sz(tctx, &blob, "dog"), "");
+ type = REG_SZ;
torture_assert(tctx,
test_SetPrinterData(tctx, b, handle, values[i], REG_SZ, blob.data, blob.length),
"SetPrinterData failed");
torture_assert(tctx,
- test_GetPrinterData(tctx, b, handle, values[i], &type, &data, &needed),
+ test_GetPrinterData_checktype(tctx, b, handle, values[i], &expected_type, &type, &data, &needed),
"GetPrinterData failed");
torture_assert_int_equal(tctx, type, REG_SZ, "type mismatch");
return true;
}
-static bool test_SetPrinterDataEx_matrix(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- struct policy_handle *handle,
- const char *printername,
- struct dcerpc_binding_handle *winreg_handle,
- struct policy_handle *hive_handle)
+static bool test_SetPrinterDataEx_keys(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle)
{
struct dcerpc_binding_handle *b = p->binding_handle;
const char *value_name = "dog";
const char *keys[] = {
"torturedataex",
"torture data ex",
-#if 0
- /* FIXME: not working with s3 atm. */
"torturedataex_with_subkey\\subkey",
"torturedataex_with_subkey\\subkey:0",
"torturedataex_with_subkey\\subkey:1",
"torturedataex_with_subkey\\subkey\\subsubkey",
"torturedataex_with_subkey\\subkey\\subsubkey:0",
"torturedataex_with_subkey\\subkey\\subsubkey:1",
-#endif
"torture,data",
-#if 0
- /* FIXME: not working with s3 atm. */
-
"torture,data,ex",
"torture,data\\ex",
- "torture\\data,ex"
-#endif
+ "torture\\data,ex",
+ "torture/data",
+ "torture/data ex",
+ "torture/data ex/sub",
+ "torture//data",
+ "torture//data ex",
+ "torture//data ex/sub",
+ "torture//data ex//sub",
+ };
+ int i;
+
+ for (i=0; i < ARRAY_SIZE(keys); i++) {
+
+ char *c;
+ const char *key;
+ enum winreg_Type type;
+ DATA_BLOB blob_in, blob_out;
+ const char **subkeys;
+ uint32_t ecount;
+ struct spoolss_PrinterEnumValues *einfo;
+ uint32_t needed;
+
+ blob_in = data_blob_talloc(tctx, NULL, 42);
+
+ generate_random_buffer(blob_in.data, blob_in.length);
+
+ torture_assert(tctx,
+ test_SetPrinterDataEx(tctx, b, handle, keys[i], value_name, REG_BINARY, blob_in.data, blob_in.length),
+ "failed to call SetPrinterDataEx");
+
+ torture_assert(tctx,
+ test_GetPrinterDataEx(tctx, p, handle, keys[i], value_name, &type, &blob_out.data, &needed),
+ "failed to call GetPrinterDataEx");
+
+ blob_out.length = needed;
+ torture_assert(tctx,
+ test_EnumPrinterDataEx(tctx, b, handle, keys[i], &ecount, &einfo),
+ "failed to call EnumPrinterDataEx");
+
+ torture_assert_int_equal(tctx, type, REG_BINARY, "type mismatch");
+ torture_assert_int_equal(tctx, blob_out.length, blob_in.length, "size mismatch");
+ torture_assert_mem_equal(tctx, blob_out.data, blob_in.data, blob_in.length, "buffer mismatch");
+
+ torture_assert_int_equal(tctx, ecount, 1, "unexpected enum count");
+ torture_assert_str_equal(tctx, einfo[0].value_name, value_name, "value_name mismatch");
+ torture_assert_int_equal(tctx, einfo[0].value_name_len, strlen_m_term(value_name)*2, "unexpected value_name_len");
+ torture_assert_int_equal(tctx, einfo[0].type, REG_BINARY, "type mismatch");
+ torture_assert_int_equal(tctx, einfo[0].data_length, blob_in.length, "size mismatch");
+ if (einfo[0].data_length > 0) {
+ torture_assert_mem_equal(tctx, einfo[0].data->data, blob_in.data, blob_in.length, "buffer mismatch");
+ }
+
+ key = talloc_strdup(tctx, keys[i]);
+
+ if (!test_DeletePrinterDataEx(tctx, b, handle, keys[i], value_name)) {
+ return false;
+ }
+
+ c = strchr(key, '\\');
+ if (c) {
+ int k;
+
+ /* we have subkeys */
+
+ *c = 0;
+
+ if (!test_EnumPrinterKey(tctx, b, handle, key, &subkeys)) {
+ return false;
+ }
+
+ for (k=0; subkeys && subkeys[k]; k++) {
+
+ const char *current_key = talloc_asprintf(tctx, "%s\\%s", key, subkeys[k]);
+
+ if (!test_DeletePrinterKey(tctx, b, handle, current_key)) {
+ return false;
+ }
+ }
+
+ if (!test_DeletePrinterKey(tctx, b, handle, key)) {
+ return false;
+ }
+
+ } else {
+ if (!test_DeletePrinterKey(tctx, b, handle, key)) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+static bool test_SetPrinterDataEx_values(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle)
+{
+ struct dcerpc_binding_handle *b = p->binding_handle;
+ const char *key = "torturedataex";
+ const char *values[] = {
+ "torture_value",
+ "torture value",
+ "torture,value",
+ "torture/value",
+ "torture\\value",
+ "torture\\\\value"
};
+ int i;
+
+ for (i=0; i < ARRAY_SIZE(values); i++) {
+
+ enum winreg_Type type;
+ DATA_BLOB blob_in, blob_out;
+ uint32_t ecount;
+ struct spoolss_PrinterEnumValues *einfo;
+ uint32_t needed;
+
+ if (torture_setting_bool(tctx, "samba3", false)) {
+ char *q;
+ q = strrchr(values[i], ',');
+ if (q) {
+ torture_comment(tctx, "skipping valuename '%s' including ',' character against Samba3\n",
+ values[i]);
+ continue;
+ }
+ }
+
+ blob_in = data_blob_talloc(tctx, NULL, 42);
+
+ generate_random_buffer(blob_in.data, blob_in.length);
+
+ torture_assert(tctx,
+ test_SetPrinterDataEx(tctx, b, handle, key, values[i], REG_BINARY, blob_in.data, blob_in.length),
+ "failed to call SetPrinterDataEx");
+
+ torture_assert(tctx,
+ test_GetPrinterDataEx(tctx, p, handle, key, values[i], &type, &blob_out.data, &needed),
+ "failed to call GetPrinterDataEx");
+
+ blob_out.length = needed;
+ torture_assert(tctx,
+ test_EnumPrinterDataEx(tctx, b, handle, key, &ecount, &einfo),
+ "failed to call EnumPrinterDataEx");
+
+ torture_assert_int_equal(tctx, type, REG_BINARY, "type mismatch");
+ torture_assert_int_equal(tctx, blob_out.length, blob_in.length, "size mismatch");
+ torture_assert_mem_equal(tctx, blob_out.data, blob_in.data, blob_in.length, "buffer mismatch");
+
+ torture_assert_int_equal(tctx, ecount, 1, "unexpected enum count");
+ torture_assert_str_equal(tctx, einfo[0].value_name, values[i], "value_name mismatch");
+ torture_assert_int_equal(tctx, einfo[0].value_name_len, strlen_m_term(values[i])*2, "unexpected value_name_len");
+ torture_assert_int_equal(tctx, einfo[0].type, REG_BINARY, "type mismatch");
+ torture_assert_int_equal(tctx, einfo[0].data_length, blob_in.length, "size mismatch");
+ if (einfo[0].data_length > 0) {
+ torture_assert_mem_equal(tctx, einfo[0].data->data, blob_in.data, blob_in.length, "buffer mismatch");
+ }
+
+ torture_assert(tctx,
+ test_DeletePrinterDataEx(tctx, b, handle, key, values[i]),
+ "failed to call DeletePrinterDataEx");
+ }
+
+ return true;
+}
+
+
+static bool test_SetPrinterDataEx_matrix(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct policy_handle *handle,
+ const char *printername,
+ struct dcerpc_binding_handle *winreg_handle,
+ struct policy_handle *hive_handle)
+{
+ struct dcerpc_binding_handle *b = p->binding_handle;
+ const char *value_name = "dog";
+ const char *key_name = "torturedataex";
enum winreg_Type types[] = {
REG_SZ,
REG_MULTI_SZ,
REG_DWORD,
REG_BINARY
};
- const char *str = "abcdefghijklmnopqrstuvwxzy";
- int i, t, s;
-
+ const char *str = "abcdefghi";
+ int t, s;
- for (i=0; i < ARRAY_SIZE(keys); i++) {
for (t=0; t < ARRAY_SIZE(types); t++) {
for (s=0; s < strlen(str); s++) {
- char *c;
- const char *key;
enum winreg_Type type;
const char *string = talloc_strndup(tctx, str, s);
+ const char *array[2];
DATA_BLOB blob = data_blob_string_const(string);
- const char **subkeys;
DATA_BLOB data;
uint8_t *data_out;
uint32_t needed, offered = 0;
uint32_t ecount;
struct spoolss_PrinterEnumValues *einfo;
+ array[0] = talloc_strdup(tctx, string);
+ array[1] = NULL;
+
if (types[t] == REG_DWORD) {
s = 0xffff;
}
- if (torture_setting_bool(tctx, "samba3", false)) {
- if ((types[t] == REG_MULTI_SZ) && s == 0) {
- torture_warning(tctx, "samba3 does not handle 4 byte emtpy REG_MULTI_SZ buffers");
- continue;
- }
- }
-
switch (types[t]) {
case REG_BINARY:
data = blob;
offered = 4;
break;
case REG_SZ:
- torture_assert(tctx,
- reg_string_to_val(tctx, lp_iconv_convenience(tctx->lp_ctx),
- "REG_SZ", string, &type, &data), "");
+ torture_assert(tctx, push_reg_sz(tctx, &data, string), "");
+ type = REG_SZ;
offered = data.length;
/*strlen_m_term(data.string)*2;*/
break;
case REG_MULTI_SZ:
- torture_assert(tctx,
- reg_string_to_val(tctx, lp_iconv_convenience(tctx->lp_ctx),
- "REG_SZ", string, &type, &data), "");
- torture_assert(tctx, data_blob_realloc(tctx, &data, data.length + 2), "");
- memset(&data.data[data.length - 2], '\0', 2);
+ torture_assert(tctx, push_reg_multi_sz(tctx, &data, array), "");
+ type = REG_MULTI_SZ;
offered = data.length;
break;
default:
}
torture_assert(tctx,
- test_SetPrinterDataEx(tctx, b, handle, keys[i], value_name, types[t], data.data, offered),
+ test_SetPrinterDataEx(tctx, b, handle, key_name, value_name, types[t], data.data, offered),
"failed to call SetPrinterDataEx");
torture_assert(tctx,
- test_GetPrinterDataEx(tctx, p, handle, keys[i], value_name, &type, &data_out, &needed),
+ test_GetPrinterDataEx_checktype(tctx, p, handle, key_name, value_name, &types[t], &type, &data_out, &needed),
"failed to call GetPrinterDataEx");
torture_assert(tctx,
- test_EnumPrinterDataEx(tctx, b, handle, keys[i], &ecount, &einfo),
+ test_EnumPrinterDataEx(tctx, b, handle, key_name, &ecount, &einfo),
"failed to call EnumPrinterDataEx");
torture_assert_int_equal(tctx, types[t], type, "type mismatch");
torture_assert(tctx,
test_winreg_query_printerdata(tctx, winreg_handle, hive_handle,
- printername, keys[i], value_name,
+ printername, key_name, value_name,
&w_type, &w_size, &w_length, &w_data), "");
torture_assert_int_equal(tctx, w_type, types[t], "winreg type mismatch");
torture_assert_mem_equal(tctx, w_data, data.data, offered, "winreg buffer mismatch");
}
- key = talloc_strdup(tctx, keys[i]);
-
- if (!test_DeletePrinterDataEx(tctx, b, handle, keys[i], value_name)) {
- return false;
- }
-
- c = strchr(key, '\\');
- if (c) {
- int k;
-
- /* we have subkeys */
-
- *c = 0;
-
- if (!test_EnumPrinterKey(tctx, b, handle, key, &subkeys)) {
- return false;
- }
-
- for (k=0; subkeys && subkeys[k]; k++) {
-
- const char *current_key = talloc_asprintf(tctx, "%s\\%s", key, subkeys[k]);
-
- if (!test_DeletePrinterKey(tctx, b, handle, current_key)) {
- return false;
- }
- }
-
- if (!test_DeletePrinterKey(tctx, b, handle, key)) {
- return false;
- }
-
- } else {
- if (!test_DeletePrinterKey(tctx, b, handle, key)) {
- return false;
- }
- }
- }
+ torture_assert(tctx,
+ test_DeletePrinterDataEx(tctx, b, handle, key_name, value_name),
+ "failed to call DeletePrinterDataEx");
}
}
return ret;
}
+static bool test_PrintProcessors_winreg(struct torture_context *tctx,
+ struct dcerpc_binding_handle *b,
+ const char *environment)
+{
+ struct dcerpc_pipe *p2;
+ bool ret = true;
+ struct policy_handle hive_handle;
+ struct dcerpc_binding_handle *b2;
+
+ torture_assert_ntstatus_ok(tctx,
+ torture_rpc_connection(tctx, &p2, &ndr_table_winreg),
+ "could not open winreg pipe");
+ b2 = p2->binding_handle;
+
+ torture_assert(tctx, test_winreg_OpenHKLM(tctx, b2, &hive_handle), "");
+
+ ret = test_PrintProcessors(tctx, b, environment, b2, &hive_handle);
+
+ test_winreg_CloseKey(tctx, b2, &hive_handle);
+
+ talloc_free(p2);
+
+ return ret;
+}
+
static bool test_PrinterData_DsSpooler(struct torture_context *tctx,
struct dcerpc_pipe *p,
struct policy_handle *handle,
union spoolss_SetPrinterInfo sinfo;
union spoolss_PrinterInfo info;
struct dcerpc_binding_handle *b = p->binding_handle;
+ const char *pname;
ZERO_STRUCT(info_ctr);
ZERO_STRUCT(devmode_ctr);
torture_assert_int_equal(tctx, type, REG_SZ, "unexpected type");\
blob = data_blob_const(data, needed);\
torture_assert(tctx,\
- pull_reg_sz(tctx, lp_iconv_convenience(tctx->lp_ctx), &blob, &str),\
+ pull_reg_sz(tctx, &blob, &str),\
"failed to pull REG_SZ");\
torture_assert_str_equal(tctx, str, iname, "unexpected result");\
} while(0);
torture_assert_int_equal(tctx, type, REG_SZ, "unexpected type");\
blob = data_blob_const(data, needed);\
torture_assert(tctx,\
- pull_reg_sz(tctx, lp_iconv_convenience(tctx->lp_ctx), &blob, &str),\
+ pull_reg_sz(tctx, &blob, &str),\
"failed to pull REG_SZ");\
torture_assert_str_equal(tctx, str, val, "unexpected result");\
} while(0);
TEST_SZ("description", info.info2.comment);
TEST_SZ("driverName", info.info2.drivername);
TEST_SZ("location", info.info2.location);
- TEST_SZ("printerName", info.info2.printername);
+
+ pname = strrchr(info.info2.printername, '\\');
+ if (pname == NULL) {
+ pname = info.info2.printername;
+ } else {
+ pname++;
+ }
+ TEST_SZ("printerName", pname);
/* TEST_SZ("printSeparatorFile", info.info2.sepfile); */
/* TEST_SZ("printShareName", info.info2.sharename); */
return true;
}
+static bool test_print_processors_winreg(struct torture_context *tctx,
+ void *private_data)
+{
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
+ struct dcerpc_binding_handle *b = p->binding_handle;
+
+ return test_PrintProcessors_winreg(tctx, b, ctx->environment);
+}
+
static bool test_GetChangeID_PrinterData(struct torture_context *tctx,
struct dcerpc_binding_handle *b,
struct policy_handle *handle,
}
static bool test_OpenPrinter_badname_list(struct torture_context *tctx,
- struct dcerpc_binding_handle *b,
- const char *server_name)
+ void *private_data)
{
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
+
const char *badnames[] = {
"__INVALID_PRINTER__",
"\\\\__INVALID_HOST__",
"\\\\\\__INVALID_PRINTER__"
};
const char *badname;
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
+ const char *server_name = dcerpc_server_name(p);
+ struct dcerpc_binding_handle *b = p->binding_handle;
int i;
for (i=0; i < ARRAY_SIZE(badnames); i++) {
static bool test_OpenPrinter(struct torture_context *tctx,
struct dcerpc_pipe *p,
const char *name,
- const char *environment)
+ const char *environment,
+ bool open_only)
{
NTSTATUS status;
struct spoolss_OpenPrinter r;
bool ret = true;
struct dcerpc_binding_handle *b = p->binding_handle;
- r.in.printername = talloc_asprintf(tctx, "\\\\%s\\%s", dcerpc_server_name(p), name);
+ r.in.printername = name;
r.in.datatype = NULL;
r.in.devmode_ctr.devmode= NULL;
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
torture_assert_werr_ok(tctx, r.out.result, "OpenPrinter failed");
+ if (open_only) {
+ goto close_printer;
+ }
+
if (!test_GetPrinter(tctx, b, &handle, environment)) {
ret = false;
}
}
}
+ close_printer:
if (!test_ClosePrinter(tctx, b, &handle)) {
ret = false;
}
return ret;
}
+static bool test_OpenPrinterEx(struct torture_context *tctx,
+ struct dcerpc_binding_handle *b,
+ const char *printername,
+ const char *datatype,
+ struct spoolss_DeviceMode *devmode,
+ uint32_t access_mask,
+ uint32_t level,
+ union spoolss_UserLevel *userlevel,
+ struct policy_handle *handle,
+ WERROR expected_result)
+{
+ struct spoolss_OpenPrinterEx r;
+
+ r.in.printername = printername;
+ r.in.datatype = datatype;
+ r.in.devmode_ctr.devmode= devmode;
+ r.in.access_mask = access_mask;
+ r.in.level = level;
+ r.in.userlevel = *userlevel;
+ r.out.handle = handle;
+
+ torture_comment(tctx, "Testing OpenPrinterEx(%s)\n", r.in.printername);
+
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &r),
+ "OpenPrinterEx failed");
+
+ torture_assert_werr_equal(tctx, r.out.result, expected_result,
+ "OpenPrinterEx failed");
+
+ return true;
+}
+
static bool call_OpenPrinterEx(struct torture_context *tctx,
struct dcerpc_pipe *p,
const char *name,
struct spoolss_DeviceMode *devmode,
struct policy_handle *handle)
{
- struct spoolss_OpenPrinterEx r;
+ union spoolss_UserLevel userlevel;
struct spoolss_UserLevel1 userlevel1;
- NTSTATUS status;
struct dcerpc_binding_handle *b = p->binding_handle;
- if (name && name[0]) {
- r.in.printername = talloc_asprintf(tctx, "\\\\%s\\%s",
- dcerpc_server_name(p), name);
- } else {
- r.in.printername = talloc_asprintf(tctx, "\\\\%s",
- dcerpc_server_name(p));
- }
-
- r.in.datatype = NULL;
- r.in.devmode_ctr.devmode= devmode;
- r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r.in.level = 1;
- r.in.userlevel.level1 = &userlevel1;
- r.out.handle = handle;
-
userlevel1.size = 1234;
userlevel1.client = "hello";
userlevel1.user = "spottyfoot!";
userlevel1.minor = 3;
userlevel1.processor = 4;
- torture_comment(tctx, "Testing OpenPrinterEx(%s)\n", r.in.printername);
-
- status = dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &r);
-
- torture_assert_ntstatus_ok(tctx, status, "OpenPrinterEx failed");
-
- torture_assert_werr_ok(tctx, r.out.result, "OpenPrinterEx failed");
+ userlevel.level1 = &userlevel1;
- return true;
+ return test_OpenPrinterEx(tctx, b, name, NULL, devmode,
+ SEC_FLAG_MAXIMUM_ALLOWED,
+ 1,
+ &userlevel,
+ handle,
+ WERR_OK);
}
static bool test_printer_rename(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- struct policy_handle *handle,
- const char *name)
+ void *private_data)
{
+ struct torture_printer_context *t =
+ (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+ struct dcerpc_pipe *p = t->spoolss_pipe;
+
bool ret = true;
union spoolss_PrinterInfo info;
union spoolss_SetPrinterInfo sinfo;
torture_comment(tctx, "Testing Printer rename operations\n");
torture_assert(tctx,
- test_GetPrinter_level(tctx, b, handle, 2, &info),
+ test_GetPrinter_level(tctx, b, &t->handle, 2, &info),
"failed to call GetPrinter level 2");
printer_name_orig = talloc_strdup(tctx, info.info2.printername);
info_ctr.info = sinfo;
torture_assert(tctx,
- test_SetPrinter(tctx, b, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),
+ test_SetPrinter(tctx, b, &t->handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),
"failed to call SetPrinter level 2");
torture_assert(tctx,
- test_GetPrinter_level(tctx, b, handle, 2, &info),
+ test_GetPrinter_level(tctx, b, &t->handle, 2, &info),
"failed to call GetPrinter level 2");
printer_name = talloc_strdup(tctx, info.info2.printername);
test_GetPrinter_level(tctx, b, &new_handle, 2, &info),
"failed to call GetPrinter level 2");
- /* FIXME: we openend with servername! */
- printer_name = talloc_asprintf(tctx, "\\\\%s\\%s",
- dcerpc_server_name(p), printer_name_new);
-
- torture_assert_str_equal(tctx, info.info2.printername, printer_name,
+ torture_assert_str_equal(tctx, info.info2.printername, printer_name_new,
"new printer name was not set");
torture_assert(tctx,
return ret;
}
+static bool test_openprinter(struct torture_context *tctx,
+ struct dcerpc_binding_handle *b,
+ const char *real_printername)
+{
+ union spoolss_UserLevel userlevel;
+ struct policy_handle handle;
+ struct spoolss_UserLevel1 userlevel1;
+ const char *printername = NULL;
+ int i;
-static bool test_OpenPrinterEx(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- const char *name,
- const char *environment)
+ struct {
+ const char *suffix;
+ WERROR expected_result;
+ } tests[] = {
+ {
+ .suffix = "rubbish",
+ .expected_result = WERR_INVALID_PRINTER_NAME
+ },{
+ .suffix = ", LocalOnl",
+ .expected_result = WERR_INVALID_PRINTER_NAME
+ },{
+ .suffix = ", localOnly",
+ .expected_result = WERR_INVALID_PRINTER_NAME
+ },{
+ .suffix = ", localonl",
+ .expected_result = WERR_INVALID_PRINTER_NAME
+ },{
+ .suffix = ",LocalOnl",
+ .expected_result = WERR_INVALID_PRINTER_NAME
+ },{
+ .suffix = ",localOnl2",
+ .expected_result = WERR_INVALID_PRINTER_NAME
+ },{
+ .suffix = ", DrvConver2t",
+ .expected_result = WERR_INVALID_PRINTER_NAME
+ },{
+ .suffix = ", drvconvert",
+ .expected_result = WERR_INVALID_PRINTER_NAME
+ },{
+ .suffix = ",drvconvert",
+ .expected_result = WERR_INVALID_PRINTER_NAME
+ },{
+ .suffix = ", DrvConvert",
+ .expected_result = WERR_OK
+ },{
+ .suffix = " , DrvConvert",
+ .expected_result = WERR_INVALID_PRINTER_NAME
+ },{
+ .suffix = ",DrvConvert",
+ .expected_result = WERR_OK
+ },{
+ .suffix = ", DrvConvertsadfasdf",
+ .expected_result = WERR_OK
+ },{
+ .suffix = ",DrvConvertasdfasd",
+ .expected_result = WERR_OK
+ },{
+ .suffix = ", LocalOnly",
+ .expected_result = WERR_OK
+ },{
+ .suffix = " , LocalOnly",
+ .expected_result = WERR_INVALID_PRINTER_NAME
+ },{
+ .suffix = ",LocalOnly",
+ .expected_result = WERR_OK
+ },{
+ .suffix = ", LocalOnlysagi4gjfkd",
+ .expected_result = WERR_OK
+ },{
+ .suffix = ",LocalOnlysagi4gjfkd",
+ .expected_result = WERR_OK
+ }
+ };
+
+ userlevel1.size = 1234;
+ userlevel1.client = "hello";
+ userlevel1.user = "spottyfoot!";
+ userlevel1.build = 1;
+ userlevel1.major = 2;
+ userlevel1.minor = 3;
+ userlevel1.processor = 4;
+
+ userlevel.level1 = &userlevel1;
+
+ torture_comment(tctx, "Testing openprinterex printername pattern\n");
+
+ torture_assert(tctx,
+ test_OpenPrinterEx(tctx, b, real_printername, NULL, NULL, 0, 1,
+ &userlevel, &handle,
+ WERR_OK),
+ "OpenPrinterEx failed");
+ test_ClosePrinter(tctx, b, &handle);
+
+ for (i=0; i < ARRAY_SIZE(tests); i++) {
+
+ printername = talloc_asprintf(tctx, "%s%s",
+ real_printername,
+ tests[i].suffix);
+
+ torture_assert(tctx,
+ test_OpenPrinterEx(tctx, b, printername, NULL, NULL, 0, 1,
+ &userlevel, &handle,
+ tests[i].expected_result),
+ "OpenPrinterEx failed");
+ if (W_ERROR_IS_OK(tests[i].expected_result)) {
+ test_ClosePrinter(tctx, b, &handle);
+ }
+ }
+
+ return true;
+}
+
+
+static bool test_existing_printer_openprinterex(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ const char *name,
+ const char *environment)
{
struct policy_handle handle;
bool ret = true;
struct dcerpc_binding_handle *b = p->binding_handle;
+ if (!test_openprinter(tctx, b, name)) {
+ return false;
+ }
+
if (!call_OpenPrinterEx(tctx, p, name, NULL, &handle)) {
return false;
}
ret = false;
}
- if (!test_printer_keys(tctx, b, &handle)) {
+ if (!test_printer_all_keys(tctx, b, &handle)) {
ret = false;
}
}
static bool test_EnumPrinters_old(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- const char *environment)
+ void *private_data)
{
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
struct spoolss_EnumPrinters r;
NTSTATUS status;
uint16_t levels[] = {1, 2, 4, 5};
int i;
bool ret = true;
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
struct dcerpc_binding_handle *b = p->binding_handle;
for (i=0;i<ARRAY_SIZE(levels);i++) {
torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
- CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinters, info, r.in.level, count, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinters, info, r.in.level, count, needed, 4);
if (!info) {
torture_comment(tctx, "No printers returned\n");
for (j=0;j<count;j++) {
if (r.in.level == 1) {
char *unc = talloc_strdup(tctx, info[j].info1.name);
- char *slash, *name;
+ char *slash, *name, *full_name;
name = unc;
if (unc[0] == '\\' && unc[1] == '\\') {
unc +=2;
slash++;
name = slash;
}
- if (!test_OpenPrinter(tctx, p, name, environment)) {
+ full_name = talloc_asprintf(tctx, "\\\\%s\\%s",
+ dcerpc_server_name(p), name);
+ if (!test_OpenPrinter(tctx, p, name, ctx->environment, true)) {
+ ret = false;
+ }
+ if (!test_OpenPrinter(tctx, p, full_name, ctx->environment, true)) {
+ ret = false;
+ }
+ if (!test_OpenPrinter(tctx, p, name, ctx->environment, false)) {
ret = false;
}
- if (!test_OpenPrinterEx(tctx, p, name, environment)) {
+ if (!test_existing_printer_openprinterex(tctx, p, name, ctx->environment)) {
ret = false;
}
}
return ret;
}
+static bool test_EnumPrinters_level(struct torture_context *tctx,
+ struct dcerpc_binding_handle *b,
+ uint32_t flags,
+ const char *servername,
+ uint32_t level,
+ uint32_t *count_p,
+ union spoolss_PrinterInfo **info_p)
+{
+ struct spoolss_EnumPrinters r;
+ union spoolss_PrinterInfo *info;
+ uint32_t needed;
+ uint32_t count;
+
+ r.in.flags = flags;
+ r.in.server = servername;
+ r.in.level = level;
+ r.in.buffer = NULL;
+ r.in.offered = 0;
+ r.out.needed = &needed;
+ r.out.count = &count;
+ r.out.info = &info;
+
+ torture_comment(tctx, "Testing EnumPrinters(%s) level %u\n",
+ r.in.server, r.in.level);
+
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
+ "EnumPrinters failed");
+ if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
+ r.in.buffer = &blob;
+ r.in.offered = needed;
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
+ "EnumPrinters failed");
+ }
+
+ torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
+
+ CHECK_NEEDED_SIZE_ENUM_LEVEL(spoolss_EnumPrinters, info, r.in.level, count, needed, 4);
+
+ if (count_p) {
+ *count_p = count;
+ }
+ if (info_p) {
+ *info_p = info;
+ }
+
+ return true;
+}
+
+static const char *get_short_printername(struct torture_context *tctx,
+ const char *name)
+{
+ const char *short_name;
+
+ if (name[0] == '\\' && name[1] == '\\') {
+ name += 2;
+ short_name = strchr(name, '\\');
+ if (short_name) {
+ return talloc_strdup(tctx, short_name+1);
+ }
+ }
+
+ return name;
+}
+
+static const char *get_full_printername(struct torture_context *tctx,
+ const char *name)
+{
+ const char *full_name = talloc_strdup(tctx, name);
+ char *p;
+
+ if (name && name[0] == '\\' && name[1] == '\\') {
+ name += 2;
+ p = strchr(name, '\\');
+ if (p) {
+ return full_name;
+ }
+ }
+
+ return NULL;
+}
+
+static bool test_OnePrinter_servername(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct dcerpc_binding_handle *b,
+ const char *servername,
+ const char *printername)
+{
+ union spoolss_PrinterInfo info;
+ const char *short_name = get_short_printername(tctx, printername);
+ const char *full_name = get_full_printername(tctx, printername);
+
+ if (short_name) {
+ struct policy_handle handle;
+ torture_assert(tctx,
+ call_OpenPrinterEx(tctx, p, short_name, NULL, &handle),
+ "failed to open printer");
+
+ torture_assert(tctx,
+ test_GetPrinter_level(tctx, b, &handle, 2, &info),
+ "failed to get printer info");
+
+ torture_assert_casestr_equal(tctx, info.info2.servername, NULL,
+ "unexpected servername");
+ torture_assert_casestr_equal(tctx, info.info2.printername, short_name,
+ "unexpected printername");
+
+ if (info.info2.devmode) {
+ const char *expected_devicename;
+ expected_devicename = talloc_strndup(tctx, short_name, MIN(strlen(short_name), 31));
+ torture_assert_casestr_equal(tctx, info.info2.devmode->devicename, expected_devicename,
+ "unexpected devicemode devicename");
+ }
+
+ torture_assert(tctx,
+ test_ClosePrinter(tctx, b, &handle),
+ "failed to close printer");
+ }
+
+ if (full_name) {
+ struct policy_handle handle;
+
+ torture_assert(tctx,
+ call_OpenPrinterEx(tctx, p, full_name, NULL, &handle),
+ "failed to open printer");
+
+ torture_assert(tctx,
+ test_GetPrinter_level(tctx, b, &handle, 2, &info),
+ "failed to get printer info");
+
+ torture_assert_casestr_equal(tctx, info.info2.servername, servername,
+ "unexpected servername");
+ torture_assert_casestr_equal(tctx, info.info2.printername, full_name,
+ "unexpected printername");
+
+ if (info.info2.devmode) {
+ const char *expected_devicename;
+ expected_devicename = talloc_strndup(tctx, full_name, MIN(strlen(full_name), 31));
+ torture_assert_casestr_equal(tctx, info.info2.devmode->devicename, expected_devicename,
+ "unexpected devicemode devicename");
+ }
+
+ torture_assert(tctx,
+ test_ClosePrinter(tctx, b, &handle),
+ "failed to close printer");
+ }
+
+ return true;
+}
+
+static bool test_EnumPrinters_servername(struct torture_context *tctx,
+ void *private_data)
+{
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
+ int i;
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
+ struct dcerpc_binding_handle *b = p->binding_handle;
+ uint32_t count;
+ union spoolss_PrinterInfo *info;
+ const char *servername;
+ uint32_t flags = PRINTER_ENUM_NAME|PRINTER_ENUM_LOCAL;
+
+ torture_comment(tctx, "Testing servername behaviour in EnumPrinters and GetPrinters\n");
+
+ servername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
+
+ torture_assert(tctx,
+ test_EnumPrinters_level(tctx, b, flags, servername, 2, &count, &info),
+ "failed to enumerate printers");
+
+ for (i=0; i < count; i++) {
+
+ torture_assert_casestr_equal(tctx, info[i].info2.servername, servername,
+ "unexpected servername");
+
+ torture_assert(tctx,
+ test_OnePrinter_servername(tctx, p, b, servername, info[i].info2.printername),
+ "failed to check printer");
+ }
+
+ servername = "";
+
+ torture_assert(tctx,
+ test_EnumPrinters_level(tctx, b, flags, servername, 2, &count, &info),
+ "failed to enumerate printers");
+
+ for (i=0; i < count; i++) {
+
+ torture_assert_casestr_equal(tctx, info[i].info2.servername, NULL,
+ "unexpected servername");
+
+ torture_assert(tctx,
+ test_OnePrinter_servername(tctx, p, b, servername, info[i].info2.printername),
+ "failed to check printer");
+ }
+
+
+ return true;
+}
+
+
static bool test_GetPrinterDriver(struct torture_context *tctx,
struct dcerpc_binding_handle *b,
struct policy_handle *handle,
torture_assert_werr_ok(tctx, r.out.result,
"failed to call GetPrinterDriver");
- CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverInfo, r.out.info, r.in.level, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+ CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverInfo, r.out.info, r.in.level, needed, 4);
return true;
}
torture_assert_werr_ok(tctx, r.out.result,
"failed to call GetPrinterDriver2");
- CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverInfo, r.out.info, r.in.level, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
+ CHECK_NEEDED_SIZE_LEVEL(spoolss_DriverInfo, r.out.info, r.in.level, needed, 4);
if (info_p) {
*info_p = *r.out.info;
}
static bool test_EnumPrinterDrivers_old(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- const char *environment)
+ void *private_data)
{
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
uint16_t levels[] = {1, 2, 3, 4, 5, 6};
int i;
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
struct dcerpc_binding_handle *b = p->binding_handle;
const char *server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
union spoolss_DriverInfo *info;
torture_assert(tctx,
- test_EnumPrinterDrivers_args(tctx, b, server_name, environment, levels[i], &count, &info),
+ test_EnumPrinterDrivers_args(tctx, b, server_name, ctx->environment, levels[i], &count, &info),
"failed to enumerate drivers");
if (!info) {
ZERO_STRUCT(userlevel_ctr);
ZERO_STRUCT(info1);
- torture_comment(tctx, "Testing AddPrinter%s level 1\n", ex ? "Ex":"");
+ torture_comment(tctx, "Testing AddPrinter%s(%s) level 1\n",
+ ex ? "Ex":"", printername);
/* try to add printer to wellknown printer list (level 1) */
ZERO_STRUCT(secdesc_ctr);
ZERO_STRUCT(userlevel_ctr);
- torture_comment(tctx, "Testing AddPrinter%s level 2\n", ex ? "Ex":"");
+ torture_comment(tctx, "Testing AddPrinter%s(%s) level 2\n",
+ ex ? "Ex":"", printername);
devmode_ctr.devmode = devmode;
}
static bool test_printer_info(struct torture_context *tctx,
- struct dcerpc_binding_handle *b,
- struct policy_handle *handle)
+ void *private_data)
{
+ struct torture_printer_context *t =
+ (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+ struct dcerpc_pipe *p = t->spoolss_pipe;
+ struct dcerpc_binding_handle *b = p->binding_handle;
+
bool ret = true;
if (torture_setting_bool(tctx, "samba3", false)) {
torture_skip(tctx, "skipping printer info cross tests against samba 3");
}
- if (!test_PrinterInfo(tctx, b, handle)) {
+ if (!test_PrinterInfo(tctx, b, &t->handle)) {
ret = false;
}
- if (!test_SetPrinter_errors(tctx, b, handle)) {
+ if (!test_SetPrinter_errors(tctx, b, &t->handle)) {
ret = false;
}
return true;
}
-bool test_printer_keys(struct torture_context *tctx,
- struct dcerpc_binding_handle *b,
- struct policy_handle *handle)
+bool test_printer_all_keys(struct torture_context *tctx,
+ struct dcerpc_binding_handle *b,
+ struct policy_handle *handle)
{
const char **key_array = NULL;
int i;
return true;
}
-static bool test_one_printer(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- struct policy_handle *handle,
- const char *name,
- const char *drivername,
- const char *environment,
- bool have_driver,
- struct spoolss_DeviceMode *devmode)
+static bool test_openprinter_wrap(struct torture_context *tctx,
+ void *private_data)
{
- bool ret = true;
+ struct torture_printer_context *t =
+ (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+ struct dcerpc_pipe *p = t->spoolss_pipe;
struct dcerpc_binding_handle *b = p->binding_handle;
+ const char *printername = t->info2.printername;
- if (!test_PausePrinter(tctx, b, handle)) {
- ret = false;
- }
-
- if (!test_DoPrintTest(tctx, b, handle)) {
- ret = false;
- }
+ return test_openprinter(tctx, b, printername);
+}
- if (!test_ResumePrinter(tctx, b, handle)) {
- ret = false;
- }
+static bool test_csetprinter(struct torture_context *tctx,
+ void *private_data)
+{
+ struct torture_printer_context *t =
+ (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+ struct dcerpc_pipe *p = t->spoolss_pipe;
- if (!test_printer_info(tctx, b, handle)) {
- ret = false;
- }
+ const char *printername = talloc_asprintf(tctx, "%s2", t->info2.printername);
+ const char *drivername = t->added_driver ? t->driver.info8.driver_name : t->info2.drivername;
+ const char *portname = t->info2.portname;
- if (!test_PrinterInfo_SD(tctx, b, handle)) {
- ret = false;
- }
+ union spoolss_PrinterInfo info;
+ struct policy_handle new_handle, new_handle2;
+ struct dcerpc_binding_handle *b = p->binding_handle;
- if (!test_PrinterInfo_DevMode(tctx, p, handle, name, devmode)) {
- ret = false;
- }
-
- if (!test_PrinterInfo_winreg(tctx, p, handle, name)) {
- ret = false;
- }
-
- if (!test_ChangeID(tctx, p, handle)) {
- ret = false;
- }
-
- if (!test_printer_keys(tctx, b, handle)) {
- ret = false;
- }
-
- if (!test_EnumPrinterData_consistency(tctx, p, handle)) {
- ret = false;
- }
-
- if (!test_SetPrinterDataEx_matrix(tctx, p, handle, name, NULL, NULL)) {
- ret = false;
- }
-
- if (!test_PrinterData_winreg(tctx, p, handle, name)) {
- ret = false;
- }
-
- if (!test_PrinterData_DsSpooler(tctx, p, handle, name)) {
- ret = false;
- }
-
- if (have_driver) {
- if (!test_DriverInfo_winreg(tctx, p, handle, name, drivername, environment)) {
- ret = false;
- }
- }
-
- if (!test_printer_rename(tctx, p, handle, name)) {
- ret = false;
- }
-
- return ret;
-}
-
-static bool test_csetprinter(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- struct policy_handle *handle,
- const char *printername,
- const char *drivername,
- const char *portname)
-{
- union spoolss_PrinterInfo info;
- struct policy_handle new_handle, new_handle2;
- struct dcerpc_binding_handle *b = p->binding_handle;
-
- torture_comment(tctx, "Testing c_setprinter\n");
+ torture_comment(tctx, "Testing c_setprinter\n");
torture_assert(tctx,
- test_GetPrinter_level(tctx, b, handle, 0, &info),
+ test_GetPrinter_level(tctx, b, &t->handle, 0, &info),
"failed to get level 0 printer info");
torture_comment(tctx, "csetprinter on initial printer handle: %d\n",
info.info0.c_setprinter);
test_AddPrinter_normal(tctx, p, &new_handle, printername, drivername, portname, NULL, false),
"failed to add new printer");
torture_assert(tctx,
- test_GetPrinter_level(tctx, b, handle, 0, &info),
+ test_GetPrinter_level(tctx, b, &t->handle, 0, &info),
"failed to get level 0 printer info");
torture_comment(tctx, "csetprinter on initial printer handle (after add): %d\n",
info.info0.c_setprinter);
return true;
}
-static bool test_add_printer_args_with_driver(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- struct torture_printer_context *t)
-{
- bool ret = true;
- struct policy_handle handle;
- bool found = false;
- struct dcerpc_binding_handle *b = p->binding_handle;
- const char *printer_name = t->info2.printername;
- const char *driver_name = t->added_driver ? t->driver.info8.driver_name : t->info2.drivername;
- const char *port_name = t->info2.portname;
- const char *printer_name2 = talloc_asprintf(tctx, "%s2", printer_name);
-
- if (t->wellknown) {
- torture_assert(tctx,
- test_AddPrinter_wellknown(tctx, p, printer_name, t->ex),
- "failed to add wellknown printer");
- } else {
- torture_assert(tctx,
- test_AddPrinter_normal(tctx, p, &handle, printer_name, driver_name, port_name, t->devmode, t->ex),
- "failed to add printer");
- }
-
- if (!test_csetprinter(tctx, p, &handle, printer_name2, driver_name, port_name)) {
- ret = false;
- }
-
- if (!test_one_printer(tctx, p, &handle, printer_name, driver_name, t->driver.remote.environment, t->have_driver, t->devmode)) {
- ret = false;
- }
-
- if (!test_DeletePrinter(tctx, b, &handle)) {
- ret = false;
- }
-
- if (!test_EnumPrinters_findname(tctx, b, PRINTER_ENUM_LOCAL, 1,
- printer_name, &found)) {
- ret = false;
- }
-
- torture_assert(tctx, !found, "deleted printer still there");
-
- return ret;
-}
-
static bool compose_local_driver_directory(struct torture_context *tctx,
const char *environment,
const char *local_dir,
return true;
}
-static bool test_add_printer_args(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- struct torture_printer_context *t)
+static struct spoolss_DeviceMode *torture_devicemode(TALLOC_CTX *mem_ctx,
+ const char *devicename)
{
- bool ret = true;
+ struct spoolss_DeviceMode *r;
+
+ r = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
+ if (r == NULL) {
+ return NULL;
+ }
+
+ r->devicename = talloc_strdup(r, devicename);
+ r->specversion = DMSPEC_NT4_AND_ABOVE;
+ r->driverversion = 0x0600;
+ r->size = 0x00dc;
+ r->__driverextra_length = 0;
+ r->fields = DEVMODE_FORMNAME |
+ DEVMODE_TTOPTION |
+ DEVMODE_PRINTQUALITY |
+ DEVMODE_DEFAULTSOURCE |
+ DEVMODE_COPIES |
+ DEVMODE_SCALE |
+ DEVMODE_PAPERSIZE |
+ DEVMODE_ORIENTATION;
+ r->orientation = DMORIENT_PORTRAIT;
+ r->papersize = DMPAPER_LETTER;
+ r->paperlength = 0;
+ r->paperwidth = 0;
+ r->scale = 100;
+ r->copies = 55;
+ r->defaultsource = DMBIN_FORMSOURCE;
+ r->printquality = DMRES_HIGH;
+ r->color = DMRES_MONOCHROME;
+ r->duplex = DMDUP_SIMPLEX;
+ r->yresolution = 0;
+ r->ttoption = DMTT_SUBDEV;
+ r->collate = DMCOLLATE_FALSE;
+ r->formname = talloc_strdup(r, "Letter");
+
+ return r;
+}
+
+static bool test_architecture_buffer(struct torture_context *tctx,
+ void *private_data)
+{
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
+
+ struct spoolss_OpenPrinterEx r;
+ struct spoolss_UserLevel1 u1;
+ struct policy_handle handle;
+ uint32_t architectures[] = {
+ PROCESSOR_ARCHITECTURE_INTEL,
+ PROCESSOR_ARCHITECTURE_IA64,
+ PROCESSOR_ARCHITECTURE_AMD64
+ };
+ uint32_t needed[3];
+ int i;
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
struct dcerpc_binding_handle *b = p->binding_handle;
- const char *server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
- if (t->wellknown && torture_setting_bool(tctx, "samba3", false)) {
- torture_skip(tctx, "skipping AddPrinter level 1 against samba");
+ for (i=0; i < ARRAY_SIZE(architectures); i++) {
+
+ torture_comment(tctx, "Testing OpenPrinterEx with architecture %d\n", architectures[i]);
+
+ u1.size = 0;
+ u1.client = NULL;
+ u1.user = NULL;
+ u1.build = 0;
+ u1.major = 3;
+ u1.minor = 0;
+ u1.processor = architectures[i];
+
+ r.in.printername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
+ r.in.datatype = NULL;
+ r.in.devmode_ctr.devmode= NULL;
+ r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ r.in.level = 1;
+ r.in.userlevel.level1 = &u1;
+ r.out.handle = &handle;
+
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &r), "");
+ torture_assert_werr_ok(tctx, r.out.result, "");
+
+ {
+ struct spoolss_EnumPrinters e;
+ uint32_t count;
+ union spoolss_PrinterInfo *info;
+
+ e.in.flags = PRINTER_ENUM_LOCAL;
+ e.in.server = NULL;
+ e.in.level = 2;
+ e.in.buffer = NULL;
+ e.in.offered = 0;
+ e.out.count = &count;
+ e.out.info = &info;
+ e.out.needed = &needed[i];
+
+ torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters_r(b, tctx, &e), "");
+#if 0
+ torture_comment(tctx, "needed was %d\n", needed[i]);
+#endif
+ }
+
+ torture_assert(tctx, test_ClosePrinter(tctx, b, &handle), "");
}
+ for (i=1; i < ARRAY_SIZE(architectures); i++) {
+ if (needed[i-1] != needed[i]) {
+ torture_fail(tctx,
+ talloc_asprintf(tctx, "needed size %d for architecture %d != needed size %d for architecture %d\n",
+ needed[i-1], architectures[i-1], needed[i], architectures[i]));
+ }
+ }
+
+ return true;
+}
+
+static bool test_PrintServer_Forms_Winreg(struct torture_context *tctx,
+ void *private_data)
+{
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
+ struct dcerpc_binding_handle *b = p->binding_handle;
+
+ return test_Forms_winreg(tctx, b, &ctx->server_handle, true, NULL);
+}
+
+static bool test_PrintServer_Forms(struct torture_context *tctx,
+ void *private_data)
+{
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
+ struct dcerpc_binding_handle *b = p->binding_handle;
+
+ return test_Forms(tctx, b, &ctx->server_handle, true, NULL, NULL, NULL);
+}
+
+static bool test_PrintServer_EnumForms(struct torture_context *tctx,
+ void *private_data)
+{
+ struct test_spoolss_context *ctx =
+ talloc_get_type_abort(private_data, struct test_spoolss_context);
+ struct dcerpc_pipe *p = ctx->spoolss_pipe;
+ struct dcerpc_binding_handle *b = p->binding_handle;
+
+ return test_EnumForms_all(tctx, b, &ctx->server_handle, true);
+}
+
+static bool torture_rpc_spoolss_setup_common(struct torture_context *tctx, struct test_spoolss_context *t)
+{
+ NTSTATUS status;
+
+ status = torture_rpc_connection(tctx, &t->spoolss_pipe, &ndr_table_spoolss);
+
+ torture_assert_ntstatus_ok(tctx, status, "Error connecting to server");
+
+ torture_assert(tctx,
+ test_OpenPrinter_server(tctx, t->spoolss_pipe, &t->server_handle),
+ "failed to open printserver");
+ torture_assert(tctx,
+ test_get_environment(tctx, t->spoolss_pipe->binding_handle, &t->server_handle, &t->environment),
+ "failed to get environment");
+
+ return true;
+}
+
+static bool torture_rpc_spoolss_setup(struct torture_context *tctx, void **data)
+{
+ struct test_spoolss_context *t;
+
+ *data = t = talloc_zero(tctx, struct test_spoolss_context);
+
+ return torture_rpc_spoolss_setup_common(tctx, t);
+}
+
+static bool torture_rpc_spoolss_teardown_common(struct torture_context *tctx, struct test_spoolss_context *t)
+{
+ test_ClosePrinter(tctx, t->spoolss_pipe->binding_handle, &t->server_handle);
+
+ return true;
+}
+
+static bool torture_rpc_spoolss_teardown(struct torture_context *tctx, void *data)
+{
+ struct test_spoolss_context *t = talloc_get_type(data, struct test_spoolss_context);
+ bool ret;
+
+ ret = torture_rpc_spoolss_teardown_common(tctx, t);
+ talloc_free(t);
+
+ return ret;
+}
+
+static bool torture_rpc_spoolss_printer_setup_common(struct torture_context *tctx, struct torture_printer_context *t)
+{
+ struct dcerpc_pipe *p;
+ struct dcerpc_binding_handle *b;
+ const char *server_name_slash;
+ const char *driver_name;
+ const char *printer_name;
+ const char *port_name;
+
+ torture_assert_ntstatus_ok(tctx,
+ torture_rpc_connection(tctx, &t->spoolss_pipe, &ndr_table_spoolss),
+ "Error connecting to server");
+
+ p = t->spoolss_pipe;
+ b = p->binding_handle;
+ server_name_slash = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
+
+ t->driver.info8.version = SPOOLSS_DRIVER_VERSION_200X;
+ t->driver.info8.driver_name = TORTURE_DRIVER;
+ t->driver.info8.driver_path = "pscript5.dll";
+ t->driver.info8.data_file = "cups6.ppd";
+ t->driver.info8.config_file = "ps5ui.dll";
+ t->driver.info8.help_file = "pscript.hlp";
+ t->driver.info8.default_datatype = "RAW";
+ t->driver.info8.dependent_files = talloc_zero(t, struct spoolss_StringArray);
+ t->driver.info8.dependent_files->string = talloc_zero_array(t, const char *, 8 + 1);
+ t->driver.info8.dependent_files->string[0] = "pscript5.dll";
+ t->driver.info8.dependent_files->string[1] = "cups6.ppd";
+ t->driver.info8.dependent_files->string[2] = "ps5ui.dll";
+ t->driver.info8.dependent_files->string[3] = "pscript.hlp";
+ t->driver.info8.dependent_files->string[4] = "pscript.ntf";
+ t->driver.info8.dependent_files->string[5] = "cups6.ini";
+ t->driver.info8.dependent_files->string[6] = "cupsps6.dll";
+ t->driver.info8.dependent_files->string[7] = "cupsui6.dll";
+
+ t->driver.local.driver_directory= "/usr/share/cups/drivers";
+
+ t->info2.drivername = "Microsoft XPS Document Writer";
+ t->info2.portname = "LPT1:";
+
+ printer_name = t->info2.printername;
+ port_name = t->info2.portname;
+
torture_assert(tctx,
fillup_printserver_info(tctx, p, &t->driver),
"failed to fillup printserver info");
"failed to compose local driver directory");
if (test_EnumPrinterDrivers_findone(tctx, b, server_name_slash, t->driver.remote.environment, 3, t->info2.drivername)) {
+ torture_comment(tctx, "driver '%s' (architecture: %s, version: 3) is present on server\n",
+ t->info2.drivername, t->driver.remote.environment);
t->have_driver = true;
- goto try_run;
+ goto try_add;
}
torture_comment(tctx, "driver '%s' (architecture: %s, version: 3) does not exist on the server\n",
if (!directory_exist(t->driver.local.driver_directory)) {
torture_warning(tctx, "no local driver is available!");
t->have_driver = false;
- goto try_run;
+ goto try_add;
}
torture_assert(tctx,
t->added_driver = true;
t->have_driver = true;
- try_run:
- ret = test_add_printer_args_with_driver(tctx, p, t);
+ try_add:
+ driver_name = t->added_driver ? t->driver.info8.driver_name : t->info2.drivername;
+
+ if (t->wellknown) {
+ torture_assert(tctx,
+ test_AddPrinter_wellknown(tctx, p, printer_name, t->ex),
+ "failed to add wellknown printer");
+ } else {
+ torture_assert(tctx,
+ test_AddPrinter_normal(tctx, p, &t->handle, printer_name, driver_name, port_name, t->devmode, t->ex),
+ "failed to add printer");
+ }
+
+ return true;
+}
+
+static bool torture_rpc_spoolss_printer_setup(struct torture_context *tctx, void **data)
+{
+ struct torture_printer_context *t;
+
+ *data = t = talloc_zero(tctx, struct torture_printer_context);
+
+ t->ex = false;
+ t->wellknown = false;
+ t->info2.printername = TORTURE_PRINTER;
+ t->devmode = NULL;
+
+ return torture_rpc_spoolss_printer_setup_common(tctx, t);
+}
+
+static bool torture_rpc_spoolss_printerex_setup(struct torture_context *tctx, void **data)
+{
+ struct torture_printer_context *t;
+
+ *data = t = talloc_zero(tctx, struct torture_printer_context);
+
+ t->ex = true;
+ t->wellknown = false;
+ t->info2.printername = TORTURE_PRINTER_EX;
+ t->devmode = NULL;
+
+ return torture_rpc_spoolss_printer_setup_common(tctx, t);
+}
+
+static bool torture_rpc_spoolss_printerwkn_setup(struct torture_context *tctx, void **data)
+{
+ struct torture_printer_context *t;
+
+ *data = t = talloc_zero(tctx, struct torture_printer_context);
+
+ t->ex = false;
+ t->wellknown = true;
+ t->info2.printername = TORTURE_WELLKNOWN_PRINTER;
+ t->devmode = NULL;
+
+ if (t->wellknown && torture_setting_bool(tctx, "samba3", false)) {
+ torture_skip(tctx, "skipping AddPrinter level 1 against samba");
+ }
+
+ return torture_rpc_spoolss_printer_setup_common(tctx, t);
+}
+
+static bool torture_rpc_spoolss_printerexwkn_setup(struct torture_context *tctx, void **data)
+{
+ struct torture_printer_context *t;
+
+ *data = t = talloc_zero(tctx, struct torture_printer_context);
+
+ t->ex = true;
+ t->wellknown = true;
+ t->info2.printername = TORTURE_WELLKNOWN_PRINTER_EX;
+ t->devmode = NULL;
+
+ if (t->wellknown && torture_setting_bool(tctx, "samba3", false)) {
+ torture_skip(tctx, "skipping AddPrinter level 1 against samba");
+ }
+
+ return torture_rpc_spoolss_printer_setup_common(tctx, t);
+}
+
+static bool torture_rpc_spoolss_printerdm_setup(struct torture_context *tctx, void **data)
+{
+ struct torture_printer_context *t;
+
+ *data = t = talloc_zero(tctx, struct torture_printer_context);
+
+ t->ex = true;
+ t->wellknown = false;
+ t->info2.printername = TORTURE_PRINTER_EX;
+ t->devmode = torture_devicemode(t, TORTURE_PRINTER_EX);
+
+ return torture_rpc_spoolss_printer_setup_common(tctx, t);
+}
+
+static bool torture_rpc_spoolss_printer_teardown_common(struct torture_context *tctx, struct torture_printer_context *t)
+{
+ bool found = false;
+ struct dcerpc_pipe *p = t->spoolss_pipe;
+ struct dcerpc_binding_handle *b;
+ const char *printer_name = t->info2.printername;
+
+ if (t->added_driver) {
+ torture_assert(tctx,
+ remove_printer_driver(tctx, dcerpc_server_name(t->spoolss_pipe), &t->driver),
+ "failed to remove printer driver");
+ }
+
+ if (p) {
+ b = p->binding_handle;
+ }
+
+ if (!t->wellknown) {
+ torture_assert(tctx,
+ test_DeletePrinter(tctx, b, &t->handle),
+ "failed to delete printer");
+
+ torture_assert(tctx,
+ test_EnumPrinters_findname(tctx, b, PRINTER_ENUM_LOCAL, 1,
+ printer_name, &found),
+ "failed to enumerate printers");
+
+ torture_assert(tctx, !found, "deleted printer still there");
+ }
+
+ return true;
+}
+
+static bool torture_rpc_spoolss_printer_teardown(struct torture_context *tctx, void *data)
+{
+ struct torture_printer_context *t = talloc_get_type(data, struct torture_printer_context);
+ bool ret;
+
+ ret = torture_rpc_spoolss_printer_teardown_common(tctx, t);
+ talloc_free(t);
+
+ return ret;
+}
+
+static bool test_print_test(struct torture_context *tctx,
+ void *private_data)
+{
+ struct torture_printer_context *t =
+ (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+ struct dcerpc_pipe *p = t->spoolss_pipe;
+ struct dcerpc_binding_handle *b = p->binding_handle;
+
+ torture_assert(tctx,
+ test_PausePrinter(tctx, b, &t->handle),
+ "failed to pause printer");
+
+ torture_assert(tctx,
+ test_DoPrintTest(tctx, b, &t->handle),
+ "failed to do print test");
+
+ torture_assert(tctx,
+ test_ResumePrinter(tctx, b, &t->handle),
+ "failed to resume printer");
+
+ return true;
+}
+
+static bool test_print_test_extended(struct torture_context *tctx,
+ void *private_data)
+{
+ struct torture_printer_context *t =
+ (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+ struct dcerpc_pipe *p = t->spoolss_pipe;
+ struct dcerpc_binding_handle *b = p->binding_handle;
+ bool ret = true;
+
+ torture_assert(tctx,
+ test_PausePrinter(tctx, b, &t->handle),
+ "failed to pause printer");
+
+ ret = test_DoPrintTest_extended(tctx, b, &t->handle);
+ if (ret == false) {
+ torture_comment(tctx, "WARNING! failed to do extended print test\n");
+ if (torture_setting_bool(tctx, "samba3", false)) {
+ torture_comment(tctx, "non-critical for samba3\n");
+ ret = true;
+ tctx->last_result = TORTURE_SKIP;
+ }
+ }
+
+ torture_assert(tctx,
+ test_ResumePrinter(tctx, b, &t->handle),
+ "failed to resume printer");
+
+ return ret;
+}
+
+static bool test_printer_sd(struct torture_context *tctx,
+ void *private_data)
+{
+ struct torture_printer_context *t =
+ (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+ struct dcerpc_pipe *p = t->spoolss_pipe;
+ struct dcerpc_binding_handle *b = p->binding_handle;
- if (t->added_driver) {
- torture_assert(tctx,
- remove_printer_driver(tctx, dcerpc_server_name(p), &t->driver),
- "failed to remove printer driver");
- }
+ torture_assert(tctx,
+ test_PrinterInfo_SD(tctx, b, &t->handle),
+ "failed to test security descriptors");
- return ret;
+ return true;
}
-static bool test_add_printer(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- void *private_data)
+static bool test_printer_dm(struct torture_context *tctx,
+ void *private_data)
{
struct torture_printer_context *t =
(struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+ struct dcerpc_pipe *p = t->spoolss_pipe;
- t->ex = false;
- t->wellknown = false;
- t->info2.printername = TORTURE_PRINTER;
+ torture_assert(tctx,
+ test_PrinterInfo_DevMode(tctx, p, &t->handle, t->info2.printername, t->devmode),
+ "failed to test devicemodes");
- return test_add_printer_args(tctx, p, t);
+ return true;
}
-static bool test_add_printer_wellknown(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- void *private_data)
+static bool test_printer_info_winreg(struct torture_context *tctx,
+ void *private_data)
{
struct torture_printer_context *t =
(struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+ struct dcerpc_pipe *p = t->spoolss_pipe;
- t->ex = false;
- t->wellknown = true;
- t->info2.printername = TORTURE_WELLKNOWN_PRINTER;
- t->devmode = NULL;
+ torture_assert(tctx,
+ test_PrinterInfo_winreg(tctx, p, &t->handle, t->info2.printername),
+ "failed to test printer info winreg");
- return test_add_printer_args(tctx, p, t);
+ return true;
}
-static bool test_add_printer_ex(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- void *private_data)
+static bool test_printer_change_id(struct torture_context *tctx,
+ void *private_data)
{
struct torture_printer_context *t =
(struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+ struct dcerpc_pipe *p = t->spoolss_pipe;
- t->ex = true;
- t->wellknown = false;
- t->info2.printername = TORTURE_PRINTER_EX;
- t->devmode = NULL;
+ torture_assert(tctx,
+ test_ChangeID(tctx, p, &t->handle),
+ "failed to test change id");
- return test_add_printer_args(tctx, p, t);
+ return true;
}
-static bool test_add_printer_ex_wellknown(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- void *private_data)
+static bool test_printer_keys(struct torture_context *tctx,
+ void *private_data)
{
struct torture_printer_context *t =
(struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+ struct dcerpc_pipe *p = t->spoolss_pipe;
+ struct dcerpc_binding_handle *b = p->binding_handle;
- t->ex = true;
- t->wellknown = true;
- t->info2.printername = TORTURE_WELLKNOWN_PRINTER_EX;
- t->devmode = NULL;
+ torture_assert(tctx,
+ test_printer_all_keys(tctx, b, &t->handle),
+ "failed to test printer keys");
- return test_add_printer_args(tctx, p, t);
+ return true;
}
-static struct spoolss_DeviceMode *torture_devicemode(TALLOC_CTX *mem_ctx,
- const char *devicename)
+static bool test_printer_data_consistency(struct torture_context *tctx,
+ void *private_data)
{
- struct spoolss_DeviceMode *r;
-
- r = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
- if (r == NULL) {
- return NULL;
- }
+ struct torture_printer_context *t =
+ (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+ struct dcerpc_pipe *p = t->spoolss_pipe;
- r->devicename = talloc_strdup(r, devicename);
- r->specversion = DMSPEC_NT4_AND_ABOVE;
- r->driverversion = 0x0600;
- r->size = 0x00dc;
- r->__driverextra_length = 0;
- r->fields = DEVMODE_FORMNAME |
- DEVMODE_TTOPTION |
- DEVMODE_PRINTQUALITY |
- DEVMODE_DEFAULTSOURCE |
- DEVMODE_COPIES |
- DEVMODE_SCALE |
- DEVMODE_PAPERSIZE |
- DEVMODE_ORIENTATION;
- r->orientation = DMORIENT_PORTRAIT;
- r->papersize = DMPAPER_LETTER;
- r->paperlength = 0;
- r->paperwidth = 0;
- r->scale = 100;
- r->copies = 55;
- r->defaultsource = DMBIN_FORMSOURCE;
- r->printquality = DMRES_HIGH;
- r->color = DMRES_MONOCHROME;
- r->duplex = DMDUP_SIMPLEX;
- r->yresolution = 0;
- r->ttoption = DMTT_SUBDEV;
- r->collate = DMCOLLATE_FALSE;
- r->formname = talloc_strdup(r, "Letter");
+ torture_assert(tctx,
+ test_EnumPrinterData_consistency(tctx, p, &t->handle),
+ "failed to test printer data consistency");
- return r;
+ return true;
}
-static bool test_add_printer_with_devmode(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- void *private_data)
+static bool test_printer_data_keys(struct torture_context *tctx,
+ void *private_data)
{
struct torture_printer_context *t =
(struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+ struct dcerpc_pipe *p = t->spoolss_pipe;
- t->ex = true;
- t->wellknown = false;
- t->info2.printername = TORTURE_PRINTER_EX;
- t->devmode = torture_devicemode(t, TORTURE_PRINTER_EX);
+ torture_assert(tctx,
+ test_SetPrinterDataEx_keys(tctx, p, &t->handle),
+ "failed to test printer data keys");
- return test_add_printer_args(tctx, p, t);
+ return true;
}
-static bool test_architecture_buffer(struct torture_context *tctx,
- struct dcerpc_pipe *p)
+static bool test_printer_data_values(struct torture_context *tctx,
+ void *private_data)
{
- struct spoolss_OpenPrinterEx r;
- struct spoolss_UserLevel1 u1;
- struct policy_handle handle;
- uint32_t architectures[] = {
- PROCESSOR_ARCHITECTURE_INTEL,
- PROCESSOR_ARCHITECTURE_IA64,
- PROCESSOR_ARCHITECTURE_AMD64
- };
- uint32_t needed[3];
- int i;
- struct dcerpc_binding_handle *b = p->binding_handle;
+ struct torture_printer_context *t =
+ (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+ struct dcerpc_pipe *p = t->spoolss_pipe;
- for (i=0; i < ARRAY_SIZE(architectures); i++) {
+ torture_assert(tctx,
+ test_SetPrinterDataEx_values(tctx, p, &t->handle),
+ "failed to test printer data values");
- torture_comment(tctx, "Testing OpenPrinterEx with architecture %d\n", architectures[i]);
+ return true;
+}
- u1.size = 0;
- u1.client = NULL;
- u1.user = NULL;
- u1.build = 0;
- u1.major = 3;
- u1.minor = 0;
- u1.processor = architectures[i];
+static bool test_printer_data_set(struct torture_context *tctx,
+ void *private_data)
+{
+ struct torture_printer_context *t =
+ (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+ struct dcerpc_pipe *p = t->spoolss_pipe;
- r.in.printername = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
- r.in.datatype = NULL;
- r.in.devmode_ctr.devmode= NULL;
- r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r.in.level = 1;
- r.in.userlevel.level1 = &u1;
- r.out.handle = &handle;
+ torture_assert(tctx,
+ test_SetPrinterDataEx_matrix(tctx, p, &t->handle, t->info2.printername, NULL, NULL),
+ "failed to test printer data set");
- torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_OpenPrinterEx_r(b, tctx, &r), "");
- torture_assert_werr_ok(tctx, r.out.result, "");
+ return true;
+}
- {
- struct spoolss_EnumPrinters e;
- uint32_t count;
- union spoolss_PrinterInfo *info;
+static bool test_printer_data_winreg(struct torture_context *tctx,
+ void *private_data)
+{
+ struct torture_printer_context *t =
+ (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+ struct dcerpc_pipe *p = t->spoolss_pipe;
- e.in.flags = PRINTER_ENUM_LOCAL;
- e.in.server = NULL;
- e.in.level = 2;
- e.in.buffer = NULL;
- e.in.offered = 0;
- e.out.count = &count;
- e.out.info = &info;
- e.out.needed = &needed[i];
+ torture_assert(tctx,
+ test_PrinterData_winreg(tctx, p, &t->handle, t->info2.printername),
+ "failed to test printer data winreg");
- torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters_r(b, tctx, &e), "");
-#if 0
- torture_comment(tctx, "needed was %d\n", needed[i]);
-#endif
- }
+ return true;
+}
- torture_assert(tctx, test_ClosePrinter(tctx, b, &handle), "");
- }
+static bool test_printer_data_dsspooler(struct torture_context *tctx,
+ void *private_data)
+{
+ struct torture_printer_context *t =
+ (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+ struct dcerpc_pipe *p = t->spoolss_pipe;
- for (i=1; i < ARRAY_SIZE(architectures); i++) {
- if (needed[i-1] != needed[i]) {
- torture_fail(tctx,
- talloc_asprintf(tctx, "needed size %d for architecture %d != needed size %d for architecture %d\n",
- needed[i-1], architectures[i-1], needed[i], architectures[i]));
- }
- }
+ torture_assert(tctx,
+ test_PrinterData_DsSpooler(tctx, p, &t->handle, t->info2.printername),
+ "failed to test printer data winreg dsspooler");
return true;
}
-bool torture_rpc_spoolss(struct torture_context *torture)
+static bool test_driver_info_winreg(struct torture_context *tctx,
+ void *private_data)
{
- NTSTATUS status;
- struct dcerpc_pipe *p;
- struct dcerpc_binding_handle *b;
- bool ret = true;
- struct test_spoolss_context *ctx;
- const char *environment = SPOOLSS_ARCHITECTURE_NT_X86;
+ struct torture_printer_context *t =
+ (struct torture_printer_context *)talloc_get_type_abort(private_data, struct torture_printer_context);
+ struct dcerpc_pipe *p = t->spoolss_pipe;
+ const char *driver_name = t->added_driver ? t->driver.info8.driver_name : t->info2.drivername;
- status = torture_rpc_connection(torture, &p, &ndr_table_spoolss);
- if (!NT_STATUS_IS_OK(status)) {
- return false;
+ if (!t->have_driver) {
+ torture_skip(tctx, "skipping driver info winreg test as we don't have a driver");
}
- b = p->binding_handle;
- ctx = talloc_zero(torture, struct test_spoolss_context);
-
- ret &= test_OpenPrinter_server(torture, p, &ctx->server_handle);
- ret &= test_GetPrinterData_list(torture, p, &ctx->server_handle, &environment);
- ret &= test_EnumForms_all(torture, b, &ctx->server_handle, true);
- ret &= test_Forms(torture, b, &ctx->server_handle, true, NULL, NULL, NULL);
- ret &= test_Forms_winreg(torture, b, &ctx->server_handle, true, NULL);
- ret &= test_EnumPorts(torture, b, ctx);
- ret &= test_GetPrinterDriverDirectory(torture, p, environment);
- ret &= test_GetPrintProcessorDirectory(torture, p, environment);
- ret &= test_EnumPrinterDrivers(torture, p, ctx, environment);
- ret &= test_EnumPrinterDrivers(torture, p, ctx, SPOOLSS_ARCHITECTURE_ALL);
- ret &= test_EnumMonitors(torture, b, ctx);
- ret &= test_EnumPrintProcessors(torture, b, ctx, environment);
- ret &= test_EnumPrintProcDataTypes(torture, b);
- ret &= test_EnumPrinters(torture, b, ctx);
- ret &= test_OpenPrinter_badname_list(torture, b, dcerpc_server_name(p));
-
- ret &= test_AddPort(torture, p);
- ret &= test_EnumPorts_old(torture, p);
- ret &= test_EnumPrinters_old(torture, p, environment);
- ret &= test_EnumPrinterDrivers_old(torture, p, environment);
- ret &= test_architecture_buffer(torture, p);
+ torture_assert(tctx,
+ test_DriverInfo_winreg(tctx, p, &t->handle, t->info2.printername, driver_name, t->driver.remote.environment),
+ "failed to test driver info winreg");
- return ret;
+ return true;
+}
+
+void torture_tcase_printer(struct torture_tcase *tcase)
+{
+ torture_tcase_add_simple_test(tcase, "openprinter", test_openprinter_wrap);
+ torture_tcase_add_simple_test(tcase, "csetprinter", test_csetprinter);
+ torture_tcase_add_simple_test(tcase, "print_test", test_print_test);
+ torture_tcase_add_simple_test(tcase, "print_test_extended", test_print_test_extended);
+ torture_tcase_add_simple_test(tcase, "printer_info", test_printer_info);
+ torture_tcase_add_simple_test(tcase, "sd", test_printer_sd);
+ torture_tcase_add_simple_test(tcase, "dm", test_printer_dm);
+ torture_tcase_add_simple_test(tcase, "printer_info_winreg", test_printer_info_winreg);
+ torture_tcase_add_simple_test(tcase, "change_id", test_printer_change_id);
+ torture_tcase_add_simple_test(tcase, "keys", test_printer_keys);
+ torture_tcase_add_simple_test(tcase, "printerdata_consistency", test_printer_data_consistency);
+ torture_tcase_add_simple_test(tcase, "printerdata_keys", test_printer_data_keys);
+ torture_tcase_add_simple_test(tcase, "printerdata_values", test_printer_data_values);
+ torture_tcase_add_simple_test(tcase, "printerdata_set", test_printer_data_set);
+ torture_tcase_add_simple_test(tcase, "printerdata_winreg", test_printer_data_winreg);
+ torture_tcase_add_simple_test(tcase, "printerdata_dsspooler", test_printer_data_dsspooler);
+ torture_tcase_add_simple_test(tcase, "driver_info_winreg", test_driver_info_winreg);
+ torture_tcase_add_simple_test(tcase, "printer_rename", test_printer_rename);
}
struct torture_suite *torture_rpc_spoolss_printer(TALLOC_CTX *mem_ctx)
{
- struct torture_suite *suite = torture_suite_create(mem_ctx, "SPOOLSS-PRINTER");
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "PRINTER");
+ struct torture_tcase *tcase;
- struct torture_rpc_tcase *tcase = torture_suite_add_rpc_iface_tcase(suite,
- "printer", &ndr_table_spoolss);
+ tcase = torture_suite_add_tcase(suite, "addprinter");
- struct torture_printer_context *t;
+ torture_tcase_set_fixture(tcase,
+ torture_rpc_spoolss_printer_setup,
+ torture_rpc_spoolss_printer_teardown);
- t = talloc_zero(mem_ctx, struct torture_printer_context);
+ torture_tcase_printer(tcase);
- t->driver.info8.version = SPOOLSS_DRIVER_VERSION_200X;
- t->driver.info8.driver_name = TORTURE_DRIVER;
- t->driver.info8.driver_path = "pscript5.dll";
- t->driver.info8.data_file = "cups6.ppd";
- t->driver.info8.config_file = "ps5ui.dll";
- t->driver.info8.help_file = "pscript.hlp";
- t->driver.info8.default_datatype = "RAW";
- t->driver.info8.dependent_files = talloc_zero(t, struct spoolss_StringArray);
- t->driver.info8.dependent_files->string = talloc_zero_array(t, const char *, 8 + 1);
- t->driver.info8.dependent_files->string[0] = "pscript5.dll";
- t->driver.info8.dependent_files->string[1] = "cups6.ppd";
- t->driver.info8.dependent_files->string[2] = "ps5ui.dll";
- t->driver.info8.dependent_files->string[3] = "pscript.hlp";
- t->driver.info8.dependent_files->string[4] = "pscript.ntf";
- t->driver.info8.dependent_files->string[5] = "cups6.ini";
- t->driver.info8.dependent_files->string[6] = "cupsps6.dll";
- t->driver.info8.dependent_files->string[7] = "cupsui6.dll";
+ tcase = torture_suite_add_tcase(suite, "addprinterex");
- t->driver.local.driver_directory= "/usr/share/cups/drivers";
+ torture_tcase_set_fixture(tcase,
+ torture_rpc_spoolss_printerex_setup,
+ torture_rpc_spoolss_printer_teardown);
- t->info2.drivername = "Microsoft XPS Document Writer";
- t->info2.portname = "LPT1:";
+ torture_tcase_printer(tcase);
+
+ tcase = torture_suite_add_tcase(suite, "addprinterwkn");
+
+ torture_tcase_set_fixture(tcase,
+ torture_rpc_spoolss_printerwkn_setup,
+ torture_rpc_spoolss_printer_teardown);
+
+ tcase = torture_suite_add_tcase(suite, "addprinterexwkn");
+
+ torture_tcase_set_fixture(tcase,
+ torture_rpc_spoolss_printerexwkn_setup,
+ torture_rpc_spoolss_printer_teardown);
+
+#if 0
+ /* test is not correct */
+ tcase = torture_suite_add_tcase(suite, "addprinterdm");
+
+ torture_tcase_set_fixture(tcase,
+ torture_rpc_spoolss_printerdm_setup,
+ torture_rpc_spoolss_printer_teardown);
- torture_rpc_tcase_add_test_ex(tcase, "add_printer", test_add_printer, t);
- torture_rpc_tcase_add_test_ex(tcase, "add_printer_wellknown", test_add_printer_wellknown, t);
- torture_rpc_tcase_add_test_ex(tcase, "add_printer_ex", test_add_printer_ex, t);
- torture_rpc_tcase_add_test_ex(tcase, "add_printer_ex_wellknown", test_add_printer_ex_wellknown, t);
+ torture_tcase_printer(tcase);
+#endif
+ return suite;
+}
- torture_rpc_tcase_add_test_ex(tcase, "add_printer_with_devmode", test_add_printer_with_devmode, t);
+struct torture_suite *torture_rpc_spoolss(TALLOC_CTX *mem_ctx)
+{
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "SPOOLSS");
+ struct torture_tcase *tcase = torture_suite_add_tcase(suite, "PRINTSERVER");
+
+ torture_tcase_set_fixture(tcase,
+ torture_rpc_spoolss_setup,
+ torture_rpc_spoolss_teardown);
+
+ torture_tcase_add_simple_test(tcase, "openprinter_badnamelist", test_OpenPrinter_badname_list);
+ torture_tcase_add_simple_test(tcase, "printer_data_list", test_GetPrinterData_list);
+ torture_tcase_add_simple_test(tcase, "enum_forms", test_PrintServer_EnumForms);
+ torture_tcase_add_simple_test(tcase, "forms", test_PrintServer_Forms);
+ torture_tcase_add_simple_test(tcase, "forms_winreg", test_PrintServer_Forms_Winreg);
+ torture_tcase_add_simple_test(tcase, "enum_ports", test_EnumPorts);
+ torture_tcase_add_simple_test(tcase, "add_port", test_AddPort);
+ torture_tcase_add_simple_test(tcase, "get_printer_driver_directory", test_GetPrinterDriverDirectory);
+ torture_tcase_add_simple_test(tcase, "get_print_processor_directory", test_GetPrintProcessorDirectory);
+ torture_tcase_add_simple_test(tcase, "enum_printer_drivers", test_EnumPrinterDrivers);
+ torture_tcase_add_simple_test(tcase, "enum_monitors", test_EnumMonitors);
+ torture_tcase_add_simple_test(tcase, "enum_print_processors", test_EnumPrintProcessors);
+ torture_tcase_add_simple_test(tcase, "print_processors_winreg", test_print_processors_winreg);
+ torture_tcase_add_simple_test(tcase, "enum_printprocdata", test_EnumPrintProcDataTypes);
+ torture_tcase_add_simple_test(tcase, "enum_printers", test_EnumPrinters);
+ torture_tcase_add_simple_test(tcase, "enum_ports_old", test_EnumPorts_old);
+ torture_tcase_add_simple_test(tcase, "enum_printers_old", test_EnumPrinters_old);
+ torture_tcase_add_simple_test(tcase, "enum_printers_servername", test_EnumPrinters_servername);
+ torture_tcase_add_simple_test(tcase, "enum_printer_drivers_old", test_EnumPrinterDrivers_old);
+ torture_tcase_add_simple_test(tcase, "architecture_buffer", test_architecture_buffer);
+
+ torture_suite_add_suite(suite, torture_rpc_spoolss_printer(suite));
return suite;
}
const char *local_name = talloc_asprintf(tctx, "%s/%s", d->local.driver_directory, file_name);
const char *remote_name = talloc_asprintf(tctx, "%s\\%s", remote_dir, file_name);
- if (!file_name) {
+ if (!file_name || strlen(file_name) == 0) {
return true;
}
torture_comment(tctx, "Connecting printer driver share '%s' on '%s'\n",
share_name, server_name);
- lp_smbcli_options(tctx->lp_ctx, &smb_options);
- lp_smbcli_session_options(tctx->lp_ctx, &smb_session_options);
+ lpcfg_smbcli_options(tctx->lp_ctx, &smb_options);
+ lpcfg_smbcli_session_options(tctx->lp_ctx, &smb_session_options);
torture_assert_ntstatus_ok(tctx,
smbcli_full_connection(tctx, cli, server_name,
- lp_smb_ports(tctx->lp_ctx),
+ lpcfg_smb_ports(tctx->lp_ctx),
share_name, NULL,
- lp_socket_options(tctx->lp_ctx),
+ lpcfg_socket_options(tctx->lp_ctx),
cmdline_credentials,
- lp_resolve_context(tctx->lp_ctx),
+ lpcfg_resolve_context(tctx->lp_ctx),
tctx->ev,
&smb_options,
&smb_session_options,
- lp_iconv_convenience(tctx->lp_ctx),
- lp_gensec_settings(tctx, tctx->lp_ctx)),
+ lpcfg_gensec_settings(tctx, tctx->lp_ctx)),
"failed to open driver share");
return true;
const char *remote_name;
const char *remote_dir = driver_directory_dir(d->remote.driver_directory);
- if (!file_name) {
+ if (!file_name || strlen(file_name) == 0) {
return true;
}
torture_assert(tctx,
remove_printer_driver_file(tctx, cli, d, d->info8.data_file),
"failed to remove data_file");
- torture_assert(tctx,
- remove_printer_driver_file(tctx, cli, d, d->info8.config_file),
- "failed to remove config_file");
+ if (!strequal(d->info8.config_file, d->info8.driver_path)) {
+ torture_assert(tctx,
+ remove_printer_driver_file(tctx, cli, d, d->info8.config_file),
+ "failed to remove config_file");
+ }
torture_assert(tctx,
remove_printer_driver_file(tctx, cli, d, d->info8.help_file),
"failed to remove help_file");
info8.driver_path = talloc_asprintf(tctx, "%s\\%s", d->remote.driver_directory, d->info8.driver_path);
info8.data_file = talloc_asprintf(tctx, "%s\\%s", d->remote.driver_directory, d->info8.data_file);
- info8.config_file = talloc_asprintf(tctx, "%s\\%s", d->remote.driver_directory, d->info8.config_file);
+ if (d->info8.config_file) {
+ info8.config_file = talloc_asprintf(tctx, "%s\\%s", d->remote.driver_directory, d->info8.config_file);
+ }
for (i=0; i < ARRAY_SIZE(levels); i++) {
}
static bool test_add_driver_ex_64(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- void *private_data)
+ struct dcerpc_pipe *p)
{
- struct torture_driver_context *d =
- (struct torture_driver_context *)talloc_get_type_abort(private_data, struct torture_driver_context);
+ struct torture_driver_context *d;
+
+ d = talloc_zero(tctx, struct torture_driver_context);
+ d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
+ d->info8.driver_name = TORTURE_DRIVER_EX;
+ d->info8.architecture = NULL;
+ d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
+ d->info8.data_file = talloc_strdup(d, "cups6.ppd");
+ d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
d->local.environment = talloc_strdup(d, "Windows x64");
d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/x64");
- d->info8.driver_name = TORTURE_DRIVER_EX;
d->ex = true;
return test_add_driver_arg(tctx, p, d);
}
static bool test_add_driver_ex_32(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- void *private_data)
+ struct dcerpc_pipe *p)
{
- struct torture_driver_context *d =
- (struct torture_driver_context *)talloc_get_type_abort(private_data, struct torture_driver_context);
+ struct torture_driver_context *d;
+ d = talloc_zero(tctx, struct torture_driver_context);
+
+ d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
+ d->info8.driver_name = TORTURE_DRIVER_EX;
+ d->info8.architecture = NULL;
+ d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
+ d->info8.data_file = talloc_strdup(d, "cups6.ppd");
+ d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
d->local.environment = talloc_strdup(d, "Windows NT x86");
d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/i386");
- d->info8.driver_name = TORTURE_DRIVER_EX;
d->ex = true;
return test_add_driver_arg(tctx, p, d);
}
static bool test_add_driver_64(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- void *private_data)
+ struct dcerpc_pipe *p)
{
- struct torture_driver_context *d =
- (struct torture_driver_context *)talloc_get_type_abort(private_data, struct torture_driver_context);
+ struct torture_driver_context *d;
+ d = talloc_zero(tctx, struct torture_driver_context);
+
+ d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
+ d->info8.driver_name = TORTURE_DRIVER;
+ d->info8.architecture = NULL;
+ d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
+ d->info8.data_file = talloc_strdup(d, "cups6.ppd");
+ d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
d->local.environment = talloc_strdup(d, "Windows x64");
d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/x64");
- d->info8.driver_name = TORTURE_DRIVER;
d->ex = false;
return test_add_driver_arg(tctx, p, d);
}
static bool test_add_driver_32(struct torture_context *tctx,
- struct dcerpc_pipe *p,
- void *private_data)
+ struct dcerpc_pipe *p)
{
- struct torture_driver_context *d =
- (struct torture_driver_context *)talloc_get_type_abort(private_data, struct torture_driver_context);
+ struct torture_driver_context *d;
+ d = talloc_zero(tctx, struct torture_driver_context);
+
+ d->info8.version = SPOOLSS_DRIVER_VERSION_200X;
+ d->info8.driver_name = TORTURE_DRIVER;
+ d->info8.architecture = NULL;
+ d->info8.driver_path = talloc_strdup(d, "pscript5.dll");
+ d->info8.data_file = talloc_strdup(d, "cups6.ppd");
+ d->info8.config_file = talloc_strdup(d, "cupsui6.dll");
d->local.environment = talloc_strdup(d, "Windows NT x86");
d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/i386");
- d->info8.driver_name = TORTURE_DRIVER;
+ d->ex = false;
+
+ return test_add_driver_arg(tctx, p, d);
+}
+
+static bool test_add_driver_adobe(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ struct torture_driver_context *d;
+
+ d = talloc_zero(tctx, struct torture_driver_context);
+
+ d->info8.version = SPOOLSS_DRIVER_VERSION_9X;
+ d->info8.driver_name = TORTURE_DRIVER_ADOBE;
+ d->info8.architecture = NULL;
+ d->info8.driver_path = talloc_strdup(d, "ADOBEPS4.DRV");
+ d->info8.data_file = talloc_strdup(d, "DEFPRTR2.PPD");
+ d->info8.config_file = talloc_strdup(d, "ADOBEPS4.DRV");
+#if 0
+ d->info8.help_file = talloc_strdup(d, "ADOBEPS4.HLP");
+ d->info8.monitor_name = talloc_strdup(d, "PSMON.DLL");
+#endif
+ d->local.environment = talloc_strdup(d, "Windows 4.0");
+ d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/adobe/");
+ d->ex = false;
+
+ return test_add_driver_arg(tctx, p, d);
+}
+
+static bool test_add_driver_adobe_cupsaddsmb(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ struct torture_driver_context *d;
+ struct spoolss_StringArray *a;
+
+ if (!torture_setting_bool(tctx, "samba3", false)) {
+ torture_skip(tctx, "skipping cupsaddsmb test which only works against samba3");
+ }
+
+ d = talloc_zero(tctx, struct torture_driver_context);
+
+ d->info8.version = SPOOLSS_DRIVER_VERSION_9X;
+ d->info8.driver_name = TORTURE_DRIVER_ADOBE_CUPSADDSMB;
+ d->info8.architecture = NULL;
+ d->info8.driver_path = talloc_strdup(d, "ADOBEPS4.DRV");
+ d->info8.data_file = talloc_strdup(d, "DEFPRTR2.PPD");
+ d->info8.config_file = NULL;
+ d->info8.help_file = talloc_strdup(d, "ADOBEPS4.HLP");
+ d->info8.monitor_name = talloc_strdup(d, "PSMON.DLL");
+ d->info8.default_datatype = talloc_strdup(d, "RAW");
+
+ a = talloc_zero(d, struct spoolss_StringArray);
+ a->string = talloc_zero_array(a, const char *, 7);
+ a->string[0] = talloc_strdup(a->string, "ADOBEPS4.DRV");
+ a->string[1] = talloc_strdup(a->string, "DEFPRTR2.PPD");
+ a->string[2] = talloc_strdup(a->string, "ADOBEPS4.HLP");
+ a->string[3] = talloc_strdup(a->string, "PSMON.DLL");
+ a->string[4] = talloc_strdup(a->string, "ADFONTS.MFM");
+ a->string[5] = talloc_strdup(a->string, "ICONLIB.DLL");
+
+ d->info8.dependent_files = a;
+ d->local.environment = talloc_strdup(d, "Windows 4.0");
+ d->local.driver_directory = talloc_strdup(d, "/usr/share/cups/drivers/adobe/");
d->ex = false;
return test_add_driver_arg(tctx, p, d);
struct torture_rpc_tcase *tcase = torture_suite_add_rpc_iface_tcase(suite,
"driver", &ndr_table_spoolss);
- struct torture_driver_context *t;
-
- t = talloc_zero(mem_ctx, struct torture_driver_context);
+ torture_rpc_tcase_add_test(tcase, "add_driver_64", test_add_driver_64);
+ torture_rpc_tcase_add_test(tcase, "add_driver_ex_64", test_add_driver_ex_64);
- t->info8.version = SPOOLSS_DRIVER_VERSION_200X;
- t->info8.driver_name = NULL;
- t->info8.architecture = NULL;
- t->info8.driver_path = talloc_strdup(t, "pscript5.dll");
- t->info8.data_file = talloc_strdup(t, "cups6.ppd");
- t->info8.config_file = talloc_strdup(t, "cupsui6.dll");
+ torture_rpc_tcase_add_test(tcase, "add_driver_32", test_add_driver_32);
+ torture_rpc_tcase_add_test(tcase, "add_driver_ex_32", test_add_driver_ex_32);
- torture_rpc_tcase_add_test_ex(tcase, "add_driver_64", test_add_driver_64, t);
- torture_rpc_tcase_add_test_ex(tcase, "add_driver_ex_64", test_add_driver_ex_64, t);
+ torture_rpc_tcase_add_test(tcase, "add_driver_adobe", test_add_driver_adobe);
- torture_rpc_tcase_add_test_ex(tcase, "add_driver_32", test_add_driver_32, t);
- torture_rpc_tcase_add_test_ex(tcase, "add_driver_ex_32", test_add_driver_ex_32, t);
+ torture_rpc_tcase_add_test(tcase, "add_driver_adobe_cupsaddsmb", test_add_driver_adobe_cupsaddsmb);
return suite;
}