/* Unix SMB/CIFS implementation. test suite for spoolss rpc operations Copyright (C) Tim Potter 2003 Copyright (C) Stefan Metzmacher 2005 Copyright (C) Jelmer Vernooij 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "includes.h" #include "torture/torture.h" #include "torture/rpc/rpc.h" #include "librpc/gen_ndr/ndr_spoolss_c.h" struct test_spoolss_context { /* print server handle */ struct policy_handle server_handle; /* for EnumPorts */ uint32_t port_count[3]; union spoolss_PortInfo *ports[3]; /* for EnumPrinterDrivers */ uint32_t driver_count[7]; union spoolss_DriverInfo *drivers[7]; /* for EnumMonitors */ uint32_t monitor_count[3]; union spoolss_MonitorInfo *monitors[3]; /* for EnumPrintProcessors */ uint32_t print_processor_count[2]; union spoolss_PrintProcessorInfo *print_processors[2]; /* for EnumPrinters */ uint32_t printer_count[6]; union spoolss_PrinterInfo *printers[6]; }; #define COMPARE_STRING(tctx, c,r,e) \ torture_assert_str_equal(tctx, c.e, r.e, "invalid value") /* not every compiler supports __typeof__() */ #if (__GNUC__ >= 3) #define _CHECK_FIELD_SIZE(c,r,e,type) do {\ if (sizeof(__typeof__(c.e)) != sizeof(type)) { \ torture_fail(tctx, #c "." #e "field is not " #type "\n"); \ }\ if (sizeof(__typeof__(r.e)) != sizeof(type)) { \ torture_fail(tctx, #r "." #e "field is not " #type "\n"); \ }\ } while(0) #else #define _CHECK_FIELD_SIZE(c,r,e,type) do {} while(0) #endif #define COMPARE_UINT32(tctx, c, r, e) do {\ _CHECK_FIELD_SIZE(c, r, e, uint32_t); \ torture_assert_int_equal(tctx, c.e, r.e, "invalid value"); \ } while(0) #define COMPARE_STRING_ARRAY(tctx, c,r,e) static bool test_OpenPrinter_server(struct torture_context *tctx, struct dcerpc_pipe *p, struct test_spoolss_context *ctx) { NTSTATUS status; struct spoolss_OpenPrinter op; op.in.printername = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p)); op.in.datatype = NULL; op.in.devmode_ctr.devmode= NULL; op.in.access_mask = 0; op.out.handle = &ctx->server_handle; torture_comment(tctx, "Testing OpenPrinter(%s)\n", op.in.printername); status = dcerpc_spoolss_OpenPrinter(p, ctx, &op); torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_OpenPrinter failed"); torture_assert_werr_ok(tctx, op.out.result, "dcerpc_spoolss_OpenPrinter failed"); return true; } static bool test_EnumPorts(struct torture_context *tctx, struct dcerpc_pipe *p, struct test_spoolss_context *ctx) { NTSTATUS status; struct spoolss_EnumPorts r; uint16_t levels[] = { 1, 2 }; int i, j; for (i=0;iport_count[level] = r.out.count; ctx->ports[level] = r.out.info; } for (i=1;iport_count[level], ctx->port_count[old_level], "EnumPorts invalid value"); } /* if the array sizes are not the same we would maybe segfault in the following code */ for (i=0;iport_count[level];j++) { union spoolss_PortInfo *cur = &ctx->ports[level][j]; union spoolss_PortInfo *ref = &ctx->ports[2][j]; switch (level) { case 1: COMPARE_STRING(tctx, cur->info1, ref->info2, port_name); break; case 2: /* level 2 is our reference, and it makes no sense to compare it to itself */ break; } } } return true; } static bool test_GetPrinterDriverDirectory(struct torture_context *tctx, struct dcerpc_pipe *p, struct test_spoolss_context *ctx) { NTSTATUS status; struct spoolss_GetPrinterDriverDirectory r; struct { uint16_t level; const char *server; } levels[] = {{ .level = 1, .server = NULL },{ .level = 1, .server = "" },{ .level = 78, .server = "" },{ .level = 1, .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p)) },{ .level = 1024, .server = talloc_asprintf(ctx, "\\\\%s", dcerpc_server_name(p)) } }; int i; uint32_t needed; for (i=0;idriver_count[level] = r.out.count; ctx->drivers[level] = r.out.info; } for (i=1;idriver_count[level], ctx->driver_count[old_level], "EnumPrinterDrivers invalid value"); } for (i=0;idriver_count[level];j++) { union spoolss_DriverInfo *cur = &ctx->drivers[level][j]; union spoolss_DriverInfo *ref = &ctx->drivers[6][j]; switch (level) { case 1: COMPARE_STRING(tctx, cur->info1, ref->info6, driver_name); break; case 2: COMPARE_UINT32(tctx, cur->info2, ref->info6, version); COMPARE_STRING(tctx, cur->info2, ref->info6, driver_name); COMPARE_STRING(tctx, cur->info2, ref->info6, architecture); COMPARE_STRING(tctx, cur->info2, ref->info6, driver_path); COMPARE_STRING(tctx, cur->info2, ref->info6, data_file); COMPARE_STRING(tctx, cur->info2, ref->info6, config_file); break; case 3: COMPARE_UINT32(tctx, cur->info3, ref->info6, version); COMPARE_STRING(tctx, cur->info3, ref->info6, driver_name); COMPARE_STRING(tctx, cur->info3, ref->info6, architecture); COMPARE_STRING(tctx, cur->info3, ref->info6, driver_path); COMPARE_STRING(tctx, cur->info3, ref->info6, data_file); COMPARE_STRING(tctx, cur->info3, ref->info6, config_file); COMPARE_STRING(tctx, cur->info3, ref->info6, help_file); COMPARE_STRING_ARRAY(tctx, cur->info3, ref->info6, dependent_files); COMPARE_STRING(tctx, cur->info3, ref->info6, monitor_name); COMPARE_STRING(tctx, cur->info3, ref->info6, default_datatype); break; case 4: COMPARE_UINT32(tctx, cur->info4, ref->info6, version); COMPARE_STRING(tctx, cur->info4, ref->info6, driver_name); COMPARE_STRING(tctx, cur->info4, ref->info6, architecture); COMPARE_STRING(tctx, cur->info4, ref->info6, driver_path); COMPARE_STRING(tctx, cur->info4, ref->info6, data_file); COMPARE_STRING(tctx, cur->info4, ref->info6, config_file); COMPARE_STRING(tctx, cur->info4, ref->info6, help_file); COMPARE_STRING_ARRAY(tctx, cur->info4, ref->info6, dependent_files); COMPARE_STRING(tctx, cur->info4, ref->info6, monitor_name); COMPARE_STRING(tctx, cur->info4, ref->info6, default_datatype); COMPARE_STRING_ARRAY(tctx, cur->info4, ref->info6, previous_names); break; case 5: COMPARE_UINT32(tctx, cur->info5, ref->info6, version); COMPARE_STRING(tctx, cur->info5, ref->info6, driver_name); COMPARE_STRING(tctx, cur->info5, ref->info6, architecture); COMPARE_STRING(tctx, cur->info5, ref->info6, driver_path); COMPARE_STRING(tctx, cur->info5, ref->info6, data_file); COMPARE_STRING(tctx, cur->info5, ref->info6, config_file); /*COMPARE_UINT32(tctx, cur->info5, ref->info6, driver_attributes);*/ /*COMPARE_UINT32(tctx, cur->info5, ref->info6, config_version);*/ /*TODO: ! COMPARE_UINT32(tctx, cur->info5, ref->info6, driver_version); */ break; case 6: /* level 6 is our reference, and it makes no sense to compare it to itself */ break; } } } return true; } static bool test_EnumMonitors(struct torture_context *tctx, struct dcerpc_pipe *p, struct test_spoolss_context *ctx) { NTSTATUS status; struct spoolss_EnumMonitors r; uint16_t levels[] = { 1, 2 }; int i, j; for (i=0;imonitor_count[level] = r.out.count; ctx->monitors[level] = r.out.info; } for (i=1;imonitor_count[level], ctx->monitor_count[old_level], "EnumMonitors invalid value"); } for (i=0;imonitor_count[level];j++) { union spoolss_MonitorInfo *cur = &ctx->monitors[level][j]; union spoolss_MonitorInfo *ref = &ctx->monitors[2][j]; switch (level) { case 1: COMPARE_STRING(tctx, cur->info1, ref->info2, monitor_name); break; case 2: /* level 2 is our reference, and it makes no sense to compare it to itself */ break; } } } return true; } static bool test_EnumPrintProcessors(struct torture_context *tctx, struct dcerpc_pipe *p, struct test_spoolss_context *ctx) { NTSTATUS status; struct spoolss_EnumPrintProcessors r; uint16_t levels[] = { 1 }; int i, j; for (i=0;iprint_processor_count[level] = r.out.count; ctx->print_processors[level] = r.out.info; } for (i=1;iprint_processor_count[level], ctx->print_processor_count[old_level], "EnumPrintProcessors failed"); } for (i=0;iprint_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; } } } return true; } static bool test_EnumPrinters(struct torture_context *tctx, struct dcerpc_pipe *p, struct test_spoolss_context *ctx) { struct spoolss_EnumPrinters r; NTSTATUS status; uint16_t levels[] = { 0, 1, 2, 4, 5 }; int i, j; for (i=0;iprinter_count[level] = r.out.count; ctx->printers[level] = r.out.info; } for (i=1;iprinter_count[level], ctx->printer_count[old_level], "EnumPrinters invalid value"); } for (i=0;iprinter_count[level];j++) { union spoolss_PrinterInfo *cur = &ctx->printers[level][j]; union spoolss_PrinterInfo *ref = &ctx->printers[2][j]; switch (level) { case 0: COMPARE_STRING(tctx, cur->info0, ref->info2, printername); COMPARE_STRING(tctx, cur->info0, ref->info2, servername); COMPARE_UINT32(tctx, cur->info0, ref->info2, cjobs); /*COMPARE_UINT32(tctx, cur->info0, ref->info2, total_jobs); COMPARE_UINT32(tctx, cur->info0, ref->info2, total_bytes); COMPARE_SPOOLSS_TIME(cur->info0, ref->info2, spoolss_Time time); COMPARE_UINT32(tctx, cur->info0, ref->info2, global_counter); COMPARE_UINT32(tctx, cur->info0, ref->info2, total_pages); COMPARE_UINT32(tctx, cur->info0, ref->info2, version); COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown10); COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown11); COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown12); COMPARE_UINT32(tctx, cur->info0, ref->info2, session_counter); COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown14); COMPARE_UINT32(tctx, cur->info0, ref->info2, printer_errors); COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown16); COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown17); COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown18); COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown19); COMPARE_UINT32(tctx, cur->info0, ref->info2, change_id); COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown21);*/ COMPARE_UINT32(tctx, cur->info0, ref->info2, status); /*COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown23); COMPARE_UINT32(tctx, cur->info0, ref->info2, c_setprinter); COMPARE_UINT16(cur->info0, ref->info2, unknown25); COMPARE_UINT16(cur->info0, ref->info2, unknown26); COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown27); COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown28); COMPARE_UINT32(tctx, cur->info0, ref->info2, unknown29);*/ break; case 1: /*COMPARE_UINT32(tctx, cur->info1, ref->info2, flags);*/ /*COMPARE_STRING(tctx, cur->info1, ref->info2, name);*/ /*COMPARE_STRING(tctx, cur->info1, ref->info2, description);*/ COMPARE_STRING(tctx, cur->info1, ref->info2, comment); break; case 2: /* level 2 is our reference, and it makes no sense to compare it to itself */ break; case 4: COMPARE_STRING(tctx, cur->info4, ref->info2, printername); COMPARE_STRING(tctx, cur->info4, ref->info2, servername); COMPARE_UINT32(tctx, cur->info4, ref->info2, attributes); break; case 5: COMPARE_STRING(tctx, cur->info5, ref->info2, printername); COMPARE_STRING(tctx, cur->info5, ref->info2, portname); COMPARE_UINT32(tctx, cur->info5, ref->info2, attributes); /*COMPARE_UINT32(tctx, cur->info5, ref->info2, device_not_selected_timeout); COMPARE_UINT32(tctx, cur->info5, ref->info2, transmission_retry_timeout);*/ break; } } } /* TODO: * - verify that the port of a printer was in the list returned by EnumPorts */ return true; } static bool test_GetPrinter(struct torture_context *tctx, struct dcerpc_pipe *p, struct policy_handle *handle) { NTSTATUS status; struct spoolss_GetPrinter r; uint16_t levels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8}; int i; uint32_t needed; for (i=0;ilast_fault_code == DCERPC_FAULT_OP_RNG_ERROR) { torture_skip(tctx, "GetPrinterDataEx not supported by server\n"); } torture_assert_ntstatus_ok(tctx, status, "GetPrinterDataEx failed"); } if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) { r.in.offered = needed; r.out.buffer = talloc_array(tctx, uint8_t, needed); status = dcerpc_spoolss_GetPrinterDataEx(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "GetPrinterDataEx failed"); torture_assert_werr_ok(tctx, r.out.result, "GetPrinterDataEx failed"); } return true; } static bool test_EnumPrinterData(struct torture_context *tctx, struct dcerpc_pipe *p, struct policy_handle *handle) { NTSTATUS status; struct spoolss_EnumPrinterData r; ZERO_STRUCT(r); r.in.handle = handle; r.in.enum_index = 0; do { uint32_t value_size = 0; uint32_t data_size = 0; uint32_t printerdata_type = 0; DATA_BLOB data = data_blob(NULL,0); r.in.value_offered = value_size; r.out.value_needed = &value_size; r.in.data_offered = data_size; r.out.data_needed = &data_size; r.out.printerdata_type = &printerdata_type; r.out.buffer = &data; torture_comment(tctx, "Testing EnumPrinterData\n"); status = dcerpc_spoolss_EnumPrinterData(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "EnumPrinterData failed"); r.in.value_offered = value_size; r.in.data_offered = data_size; status = dcerpc_spoolss_EnumPrinterData(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "EnumPrinterData failed"); test_GetPrinterData(tctx, p, handle, r.out.value_name); test_GetPrinterDataEx(tctx, p, handle, "PrinterDriverData", r.out.value_name); r.in.enum_index++; } while (W_ERROR_IS_OK(r.out.result)); return true; } static bool test_EnumPrinterDataEx(struct torture_context *tctx, struct dcerpc_pipe *p, struct policy_handle *handle) { NTSTATUS status; struct spoolss_EnumPrinterDataEx r; uint32_t needed; uint32_t count; r.in.handle = handle; r.in.key_name = "PrinterDriverData"; r.in.offered = 0; r.out.needed = &needed; r.out.count = &count; torture_comment(tctx, "Testing EnumPrinterDataEx\n"); status = dcerpc_spoolss_EnumPrinterDataEx(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "EnumPrinterDataEx failed"); r.in.offered = needed; r.out.buffer = talloc_array(tctx, uint8_t, needed); status = dcerpc_spoolss_EnumPrinterDataEx(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "EnumPrinterDataEx failed"); return true; } static bool test_DeletePrinterData(struct torture_context *tctx, struct dcerpc_pipe *p, struct policy_handle *handle, const char *value_name) { NTSTATUS status; struct spoolss_DeletePrinterData r; r.in.handle = handle; r.in.value_name = value_name; torture_comment(tctx, "Testing DeletePrinterData\n"); status = dcerpc_spoolss_DeletePrinterData(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "DeletePrinterData failed"); return true; } static bool test_SetPrinterData(struct torture_context *tctx, struct dcerpc_pipe *p, struct policy_handle *handle) { NTSTATUS status; struct spoolss_SetPrinterData r; const char *value_name = "spottyfoot"; r.in.handle = handle; r.in.value_name = value_name; r.in.type = SPOOLSS_PRINTER_DATA_TYPE_STRING; r.in.data.string = "dog"; torture_comment(tctx, "Testing SetPrinterData\n"); status = dcerpc_spoolss_SetPrinterData(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "SetPrinterData failed"); if (!test_GetPrinterData(tctx, p, handle, value_name)) { return false; } if (!test_DeletePrinterData(tctx, p, handle, value_name)) { return false; } return true; } static bool test_SecondaryClosePrinter(struct torture_context *tctx, struct dcerpc_pipe *p, struct policy_handle *handle) { NTSTATUS status; struct dcerpc_binding *b; struct dcerpc_pipe *p2; struct spoolss_ClosePrinter cp; /* only makes sense on SMB */ if (p->conn->transport.transport != NCACN_NP) { return true; } torture_comment(tctx, "testing close on secondary pipe\n"); status = dcerpc_parse_binding(tctx, p->conn->binding_string, &b); torture_assert_ntstatus_ok(tctx, status, "Failed to parse dcerpc binding"); status = dcerpc_secondary_connection(p, &p2, b); torture_assert_ntstatus_ok(tctx, status, "Failed to create secondary connection"); status = dcerpc_bind_auth_none(p2, &ndr_table_spoolss); torture_assert_ntstatus_ok(tctx, status, "Failed to create bind on secondary connection"); cp.in.handle = handle; cp.out.handle = handle; status = dcerpc_spoolss_ClosePrinter(p2, tctx, &cp); torture_assert_ntstatus_equal(tctx, status, NT_STATUS_NET_WRITE_FAULT, "ERROR: Allowed close on secondary connection"); torture_assert_int_equal(tctx, p2->last_fault_code, DCERPC_FAULT_CONTEXT_MISMATCH, "Unexpected fault code"); talloc_free(p2); return true; } static bool test_OpenPrinter_badname(struct torture_context *tctx, struct dcerpc_pipe *p, const char *name) { NTSTATUS status; struct spoolss_OpenPrinter op; struct spoolss_OpenPrinterEx opEx; struct policy_handle handle; bool ret = true; op.in.printername = name; op.in.datatype = NULL; op.in.devmode_ctr.devmode= NULL; op.in.access_mask = 0; op.out.handle = &handle; torture_comment(tctx, "\nTesting OpenPrinter(%s) with bad name\n", op.in.printername); status = dcerpc_spoolss_OpenPrinter(p, tctx, &op); torture_assert_ntstatus_ok(tctx, status, "OpenPrinter failed"); if (!W_ERROR_EQUAL(WERR_INVALID_PRINTER_NAME,op.out.result)) { torture_comment(tctx, "OpenPrinter(%s) unexpected result[%s] should be WERR_INVALID_PRINTER_NAME\n", name, win_errstr(op.out.result)); } if (W_ERROR_IS_OK(op.out.result)) { ret &=test_ClosePrinter(tctx, p, &handle); } opEx.in.printername = name; opEx.in.datatype = NULL; opEx.in.devmode_ctr.devmode = NULL; opEx.in.access_mask = 0; opEx.in.level = 1; opEx.in.userlevel.level1 = NULL; opEx.out.handle = &handle; torture_comment(tctx, "Testing OpenPrinterEx(%s) with bad name\n", opEx.in.printername); status = dcerpc_spoolss_OpenPrinterEx(p, tctx, &opEx); torture_assert_ntstatus_ok(tctx, status, "OpenPrinterEx failed"); if (!W_ERROR_EQUAL(WERR_INVALID_PARAM,opEx.out.result)) { torture_comment(tctx, "OpenPrinterEx(%s) unexpected result[%s] should be WERR_INVALID_PARAM\n", name, win_errstr(opEx.out.result)); } if (W_ERROR_IS_OK(opEx.out.result)) { ret &=test_ClosePrinter(tctx, p, &handle); } return ret; } static bool test_OpenPrinter(struct torture_context *tctx, struct dcerpc_pipe *p, const char *name) { NTSTATUS status; struct spoolss_OpenPrinter r; struct policy_handle handle; bool ret = true; r.in.printername = talloc_asprintf(tctx, "\\\\%s\\%s", dcerpc_server_name(p), name); r.in.datatype = NULL; r.in.devmode_ctr.devmode= NULL; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r.out.handle = &handle; torture_comment(tctx, "Testing OpenPrinter(%s)\n", r.in.printername); status = dcerpc_spoolss_OpenPrinter(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "OpenPrinter failed"); torture_assert_werr_ok(tctx, r.out.result, "OpenPrinter failed"); if (!test_GetPrinter(tctx, p, &handle)) { ret = false; } if (!test_SecondaryClosePrinter(tctx, p, &handle)) { ret = false; } if (!test_ClosePrinter(tctx, p, &handle)) { ret = false; } return ret; } static bool call_OpenPrinterEx(struct torture_context *tctx, struct dcerpc_pipe *p, const char *name, struct policy_handle *handle) { struct spoolss_OpenPrinterEx r; struct spoolss_UserLevel1 userlevel1; NTSTATUS status; 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= NULL; 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.build = 1; userlevel1.major = 2; userlevel1.minor = 3; userlevel1.processor = 4; torture_comment(tctx, "Testing OpenPrinterEx(%s)\n", r.in.printername); status = dcerpc_spoolss_OpenPrinterEx(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "OpenPrinterEx failed"); torture_assert_werr_ok(tctx, r.out.result, "OpenPrinterEx failed"); return true; } static bool test_OpenPrinterEx(struct torture_context *tctx, struct dcerpc_pipe *p, const char *name) { struct policy_handle handle; bool ret = true; if (!call_OpenPrinterEx(tctx, p, name, &handle)) { return false; } if (!test_GetPrinter(tctx, p, &handle)) { ret = false; } if (!test_EnumForms(tctx, p, &handle, false)) { ret = false; } if (!test_AddForm(tctx, p, &handle, false)) { ret = false; } if (!test_EnumPrinterData(tctx, p, &handle)) { ret = false; } if (!test_EnumPrinterDataEx(tctx, p, &handle)) { ret = false; } if (!test_PausePrinter(tctx, p, &handle)) { ret = false; } if (!test_DoPrintTest(tctx, p, &handle)) { ret = false; } if (!test_ResumePrinter(tctx, p, &handle)) { ret = false; } if (!test_SetPrinterData(tctx, p, &handle)) { ret = false; } if (!test_SecondaryClosePrinter(tctx, p, &handle)) { ret = false; } if (!test_ClosePrinter(tctx, p, &handle)) { ret = false; } return ret; } static bool test_EnumPrinters_old(struct torture_context *tctx, struct dcerpc_pipe *p) { struct spoolss_EnumPrinters r; NTSTATUS status; uint16_t levels[] = {1, 2, 4, 5}; int i; bool ret = true; for (i=0;iserver_handle, "W3SvcInstalled"); ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "BeepEnabled"); ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "EventLog"); ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "NetPopup"); ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "NetPopupToComputer"); ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "MajorVersion"); ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "MinorVersion"); ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "DefaultSpoolDirectory"); ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "Architecture"); ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "DsPresent"); ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "OSVersion"); ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "OSVersionEx"); ret &= test_GetPrinterData(torture, p, &ctx->server_handle, "DNSMachineName"); ret &= test_EnumForms(torture, p, &ctx->server_handle, true); ret &= test_AddForm(torture, p, &ctx->server_handle, true); ret &= test_EnumPorts(torture, p, ctx); ret &= test_GetPrinterDriverDirectory(torture, p, ctx); ret &= test_EnumPrinterDrivers(torture, p, ctx); ret &= test_EnumMonitors(torture, p, ctx); ret &= test_EnumPrintProcessors(torture, p, ctx); ret &= test_EnumPrinters(torture, p, ctx); ret &= test_OpenPrinter_badname(torture, p, "__INVALID_PRINTER__"); ret &= test_OpenPrinter_badname(torture, p, "\\\\__INVALID_HOST__"); ret &= test_OpenPrinter_badname(torture, p, ""); ret &= test_OpenPrinter_badname(torture, p, "\\\\\\"); ret &= test_OpenPrinter_badname(torture, p, "\\\\\\__INVALID_PRINTER__"); ret &= test_OpenPrinter_badname(torture, p, talloc_asprintf(torture, "\\\\%s\\", dcerpc_server_name(p))); ret &= test_OpenPrinter_badname(torture, p, talloc_asprintf(torture, "\\\\%s\\__INVALID_PRINTER__", dcerpc_server_name(p))); ret &= test_AddPort(torture, p); ret &= test_EnumPorts_old(torture, p); ret &= test_EnumPrinters_old(torture, p); ret &= test_EnumPrinterDrivers_old(torture, p); ret &= test_ReplyOpenPrinter(torture, p); return ret; }