s4-smbtorture: move test_ReplyOpenPrinter from RPC-SPOOLSS to RPC-SPOOLSS-NOTIFY.
[ab/samba.git/.git] / source4 / torture / rpc / spoolss.c
index de600e8fb3f0a531d8bc0ddc492e8b9e8e95b2f9..6c78cf3cc2e0b063ec774cad0d2ea6015b2dd889 100644 (file)
@@ -108,6 +108,7 @@ static bool test_EnumPorts(struct torture_context *tctx,
                DATA_BLOB blob;
                uint32_t needed;
                uint32_t count;
+               union spoolss_PortInfo *info;
 
                r.in.servername = "";
                r.in.level = level;
@@ -115,6 +116,7 @@ static bool test_EnumPorts(struct torture_context *tctx,
                r.in.offered = 0;
                r.out.needed = &needed;
                r.out.count = &count;
+               r.out.info = &info;
 
                torture_comment(tctx, "Testing EnumPorts level %u\n", r.in.level);
 
@@ -137,8 +139,10 @@ static bool test_EnumPorts(struct torture_context *tctx,
 
                torture_assert_werr_ok(tctx, r.out.result, "EnumPorts failed");
 
+               torture_assert(tctx, info, "EnumPorts returned no info");
+
                ctx->port_count[level]  = count;
-               ctx->ports[level]       = r.out.info;
+               ctx->ports[level]       = info;
        }
 
        for (i=1;i<ARRAY_SIZE(levels);i++) {
@@ -168,6 +172,69 @@ static bool test_EnumPorts(struct torture_context *tctx,
        return true;
 }
 
+static bool test_GetPrintProcessorDirectory(struct torture_context *tctx,
+                                           struct dcerpc_pipe *p,
+                                           struct test_spoolss_context *ctx)
+{
+       NTSTATUS status;
+       struct spoolss_GetPrintProcessorDirectory 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;i<ARRAY_SIZE(levels);i++) {
+               int level = levels[i].level;
+               DATA_BLOB blob;
+
+               r.in.server             = levels[i].server;
+               r.in.environment        = SPOOLSS_ARCHITECTURE_NT_X86;
+               r.in.level              = level;
+               r.in.buffer             = NULL;
+               r.in.offered            = 0;
+               r.out.needed            = &needed;
+
+               torture_comment(tctx, "Testing GetPrintProcessorDirectory level %u\n", r.in.level);
+
+               status = dcerpc_spoolss_GetPrintProcessorDirectory(p, ctx, &r);
+               torture_assert_ntstatus_ok(tctx, status,
+                       "dcerpc_spoolss_GetPrintProcessorDirectory failed");
+               torture_assert_werr_equal(tctx, r.out.result, WERR_INSUFFICIENT_BUFFER,
+                       "GetPrintProcessorDirectory unexpected return code");
+
+               blob = data_blob_talloc(ctx, NULL, needed);
+               data_blob_clear(&blob);
+               r.in.buffer = &blob;
+               r.in.offered = needed;
+
+               status = dcerpc_spoolss_GetPrintProcessorDirectory(p, ctx, &r);
+               torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_GetPrintProcessorDirectory failed");
+
+               torture_assert_werr_ok(tctx, r.out.result, "GetPrintProcessorDirectory failed");
+       }
+
+       return true;
+}
+
+
 static bool test_GetPrinterDriverDirectory(struct torture_context *tctx, 
                                           struct dcerpc_pipe *p, 
                                           struct test_spoolss_context *ctx)
@@ -244,6 +311,7 @@ static bool test_EnumPrinterDrivers(struct torture_context *tctx,
                DATA_BLOB blob;
                uint32_t needed;
                uint32_t count;
+               union spoolss_DriverInfo *info;
 
                r.in.server             = "";
                r.in.environment        = SPOOLSS_ARCHITECTURE_NT_X86;
@@ -252,6 +320,7 @@ static bool test_EnumPrinterDrivers(struct torture_context *tctx,
                r.in.offered            = 0;
                r.out.needed            = &needed;
                r.out.count             = &count;
+               r.out.info              = &info;
 
                torture_comment(tctx, "Testing EnumPrinterDrivers level %u\n", r.in.level);
 
@@ -276,7 +345,7 @@ static bool test_EnumPrinterDrivers(struct torture_context *tctx,
                torture_assert_werr_ok(tctx, r.out.result, "EnumPrinterDrivers failed");
 
                ctx->driver_count[level]        = count;
-               ctx->drivers[level]             = r.out.info;
+               ctx->drivers[level]             = info;
        }
 
        for (i=1;i<ARRAY_SIZE(levels);i++) {
@@ -363,6 +432,7 @@ static bool test_EnumMonitors(struct torture_context *tctx,
                DATA_BLOB blob;
                uint32_t needed;
                uint32_t count;
+               union spoolss_MonitorInfo *info;
 
                r.in.servername = "";
                r.in.level = level;
@@ -370,6 +440,7 @@ static bool test_EnumMonitors(struct torture_context *tctx,
                r.in.offered = 0;
                r.out.needed = &needed;
                r.out.count = &count;
+               r.out.info = &info;
 
                torture_comment(tctx, "Testing EnumMonitors level %u\n", r.in.level);
 
@@ -393,7 +464,7 @@ static bool test_EnumMonitors(struct torture_context *tctx,
                torture_assert_werr_ok(tctx, r.out.result, "EnumMonitors failed");
 
                ctx->monitor_count[level]       = count;
-               ctx->monitors[level]            = r.out.info;
+               ctx->monitors[level]            = info;
        }
 
        for (i=1;i<ARRAY_SIZE(levels);i++) {
@@ -436,6 +507,7 @@ static bool test_EnumPrintProcessors(struct torture_context *tctx,
                DATA_BLOB blob;
                uint32_t needed;
                uint32_t count;
+               union spoolss_PrintProcessorInfo *info;
 
                r.in.servername = "";
                r.in.environment = "Windows NT x86";
@@ -444,6 +516,7 @@ static bool test_EnumPrintProcessors(struct torture_context *tctx,
                r.in.offered = 0;
                r.out.needed = &needed;
                r.out.count = &count;
+               r.out.info = &info;
 
                torture_comment(tctx, "Testing EnumPrintProcessors level %u\n", r.in.level);
 
@@ -467,7 +540,7 @@ static bool test_EnumPrintProcessors(struct torture_context *tctx,
                torture_assert_werr_ok(tctx, r.out.result, "EnumPrintProcessors failed");
 
                ctx->print_processor_count[level]       = count;
-               ctx->print_processors[level]            = r.out.info;
+               ctx->print_processors[level]            = info;
        }
 
        for (i=1;i<ARRAY_SIZE(levels);i++) {
@@ -495,6 +568,57 @@ static bool test_EnumPrintProcessors(struct torture_context *tctx,
        return true;
 }
 
+static bool test_EnumPrintProcDataTypes(struct torture_context *tctx,
+                                       struct dcerpc_pipe *p,
+                                       struct test_spoolss_context *ctx)
+{
+       NTSTATUS status;
+       struct spoolss_EnumPrintProcDataTypes r;
+       uint16_t levels[] = { 1 };
+       int i;
+
+       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;
+
+               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(p, ctx, &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(ctx, NULL, needed);
+               data_blob_clear(&blob);
+               r.in.buffer = &blob;
+               r.in.offered = needed;
+
+               status = dcerpc_spoolss_EnumPrintProcDataTypes(p, ctx, &r);
+               torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EnumPrintProcDataTypes failed");
+
+               torture_assert_werr_ok(tctx, r.out.result, "EnumPrintProcDataTypes failed");
+       }
+
+       return true;
+}
+
+
 static bool test_EnumPrinters(struct torture_context *tctx, 
                              struct dcerpc_pipe *p,
                              struct test_spoolss_context *ctx)
@@ -509,6 +633,7 @@ static bool test_EnumPrinters(struct torture_context *tctx,
                DATA_BLOB blob;
                uint32_t needed;
                uint32_t count;
+               union spoolss_PrinterInfo *info;
 
                r.in.flags      = PRINTER_ENUM_LOCAL;
                r.in.server     = "";
@@ -517,6 +642,7 @@ static bool test_EnumPrinters(struct torture_context *tctx,
                r.in.offered    = 0;
                r.out.needed    = &needed;
                r.out.count     = &count;
+               r.out.info      = &info;
 
                torture_comment(tctx, "Testing EnumPrinters level %u\n", r.in.level);
 
@@ -540,7 +666,7 @@ static bool test_EnumPrinters(struct torture_context *tctx,
                torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
 
                ctx->printer_count[level]       = count;
-               ctx->printers[level]            = r.out.info;
+               ctx->printers[level]            = info;
        }
 
        for (i=1;i<ARRAY_SIZE(levels);i++) {
@@ -679,7 +805,8 @@ static bool test_ClosePrinter(struct torture_context *tctx,
 static bool test_GetForm(struct torture_context *tctx, 
                         struct dcerpc_pipe *p, 
                         struct policy_handle *handle, 
-                        const char *form_name)
+                        const char *form_name,
+                        uint32_t level)
 {
        NTSTATUS status;
        struct spoolss_GetForm r;
@@ -687,12 +814,12 @@ static bool test_GetForm(struct torture_context *tctx,
 
        r.in.handle = handle;
        r.in.form_name = form_name;
-       r.in.level = 1;
+       r.in.level = level;
        r.in.buffer = NULL;
        r.in.offered = 0;
        r.out.needed = &needed;
 
-       torture_comment(tctx, "Testing GetForm\n");
+       torture_comment(tctx, "Testing GetForm level %d\n", r.in.level);
 
        status = dcerpc_spoolss_GetForm(p, tctx, &r);
        torture_assert_ntstatus_ok(tctx, status, "GetForm failed");
@@ -724,45 +851,54 @@ static bool test_EnumForms(struct torture_context *tctx,
        bool ret = true;
        uint32_t needed;
        uint32_t count;
+       uint32_t levels[] = { 1, 2 };
+       int i;
 
-       r.in.handle = handle;
-       r.in.level = 1;
-       r.in.buffer = NULL;
-       r.in.offered = 0;
-       r.out.needed = &needed;
-       r.out.count = &count;
-
-       torture_comment(tctx, "Testing EnumForms\n");
+       for (i=0; i<ARRAY_SIZE(levels); i++) {
 
-       status = dcerpc_spoolss_EnumForms(p, tctx, &r);
-       torture_assert_ntstatus_ok(tctx, status, "EnumForms failed");
+               union spoolss_FormInfo *info;
 
-       if (print_server && W_ERROR_EQUAL(r.out.result, WERR_BADFID))
-               torture_fail(tctx, "EnumForms on the PrintServer isn't supported by test server (NT4)");
+               r.in.handle = handle;
+               r.in.level = levels[i];
+               r.in.buffer = NULL;
+               r.in.offered = 0;
+               r.out.needed = &needed;
+               r.out.count = &count;
+               r.out.info = &info;
 
-       if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
-               union spoolss_FormInfo *info;
-               int j;
-               DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
-               data_blob_clear(&blob);
-               r.in.buffer = &blob;
-               r.in.offered = needed;
+               torture_comment(tctx, "Testing EnumForms level %d\n", levels[i]);
 
                status = dcerpc_spoolss_EnumForms(p, tctx, &r);
+               torture_assert_ntstatus_ok(tctx, status, "EnumForms failed");
 
-               torture_assert(tctx, r.out.info, "No forms returned");
+               if ((r.in.level == 2) && (W_ERROR_EQUAL(r.out.result, WERR_UNKNOWN_LEVEL))) {
+                       break;
+               }
 
-               info = r.out.info;
+               if (print_server && W_ERROR_EQUAL(r.out.result, WERR_BADFID))
+                       torture_fail(tctx, "EnumForms on the PrintServer isn't supported by test server (NT4)");
 
-               for (j = 0; j < count; j++) {
-                       if (!print_server) 
-                               ret &= test_GetForm(tctx, p, handle, info[j].info1.form_name);
+               if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+                       int j;
+                       DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
+                       data_blob_clear(&blob);
+                       r.in.buffer = &blob;
+                       r.in.offered = needed;
+
+                       status = dcerpc_spoolss_EnumForms(p, tctx, &r);
+
+                       torture_assert(tctx, info, "No forms returned");
+
+                       for (j = 0; j < count; j++) {
+                               if (!print_server)
+                                       ret &= test_GetForm(tctx, p, handle, info[j].info1.form_name, levels[i]);
+                       }
                }
-       }
 
-       torture_assert_ntstatus_ok(tctx, status, "EnumForms failed");
+               torture_assert_ntstatus_ok(tctx, status, "EnumForms failed");
 
-       torture_assert_werr_ok(tctx, r.out.result, "EnumForms failed");
+               torture_assert_werr_ok(tctx, r.out.result, "EnumForms failed");
+       }
 
        return true;
 }
@@ -815,7 +951,7 @@ static bool test_AddForm(struct torture_context *tctx,
 
        torture_assert_werr_ok(tctx, r.out.result, "AddForm failed");
 
-       if (!print_server) ret &= test_GetForm(tctx, p, handle, form_name);
+       if (!print_server) ret &= test_GetForm(tctx, p, handle, form_name, 1);
 
        {
                struct spoolss_SetForm sf;
@@ -839,7 +975,7 @@ static bool test_AddForm(struct torture_context *tctx,
                torture_assert_werr_ok(tctx, r.out.result, "SetForm failed");
        }
 
-       if (!print_server) ret &= test_GetForm(tctx, p, handle, form_name);
+       if (!print_server) ret &= test_GetForm(tctx, p, handle, form_name, 1);
 
        if (!test_DeleteForm(tctx, p, handle, form_name)) {
                ret = false;
@@ -855,6 +991,7 @@ static bool test_EnumPorts_old(struct torture_context *tctx,
        struct spoolss_EnumPorts r;
        uint32_t needed;
        uint32_t count;
+       union spoolss_PortInfo *info;
 
        r.in.servername = talloc_asprintf(tctx, "\\\\%s", 
                                          dcerpc_server_name(p));
@@ -863,6 +1000,7 @@ static bool test_EnumPorts_old(struct torture_context *tctx,
        r.in.offered = 0;
        r.out.needed = &needed;
        r.out.count = &count;
+       r.out.info = &info;
 
        torture_comment(tctx, "Testing EnumPorts\n");
 
@@ -879,7 +1017,7 @@ static bool test_EnumPorts_old(struct torture_context *tctx,
                status = dcerpc_spoolss_EnumPorts(p, tctx, &r);
                torture_assert_ntstatus_ok(tctx, status, "EnumPorts failed");
 
-               torture_assert(tctx, r.out.info, "No ports returned");
+               torture_assert(tctx, info, "No ports returned");
        }
 
        return true;
@@ -972,6 +1110,33 @@ static bool test_SetJob(struct torture_context *tctx,
        return true;
 }
 
+static bool test_AddJob(struct torture_context *tctx,
+                       struct dcerpc_pipe *p,
+                       struct policy_handle *handle)
+{
+       NTSTATUS status;
+       struct spoolss_AddJob r;
+       uint32_t needed;
+
+       r.in.level = 0;
+       r.in.handle = handle;
+       r.in.offered = 0;
+       r.out.needed = &needed;
+
+       torture_comment(tctx, "Testing AddJob\n");
+
+       status = dcerpc_spoolss_AddJob(p, tctx, &r);
+       torture_assert_werr_equal(tctx, r.out.result, WERR_UNKNOWN_LEVEL, "AddJob failed");
+
+       r.in.level = 1;
+
+       status = dcerpc_spoolss_AddJob(p, tctx, &r);
+       torture_assert_werr_equal(tctx, r.out.result, WERR_INVALID_PARAM, "AddJob failed");
+
+       return true;
+}
+
+
 static bool test_EnumJobs(struct torture_context *tctx, 
                          struct dcerpc_pipe *p, 
                          struct policy_handle *handle)
@@ -980,6 +1145,7 @@ static bool test_EnumJobs(struct torture_context *tctx,
        struct spoolss_EnumJobs r;
        uint32_t needed;
        uint32_t count;
+       union spoolss_JobInfo *info;
 
        r.in.handle = handle;
        r.in.firstjob = 0;
@@ -989,6 +1155,7 @@ static bool test_EnumJobs(struct torture_context *tctx,
        r.in.offered = 0;
        r.out.needed = &needed;
        r.out.count = &count;
+       r.out.info = &info;
 
        torture_comment(tctx, "Testing EnumJobs\n");
 
@@ -997,7 +1164,6 @@ static bool test_EnumJobs(struct torture_context *tctx,
        torture_assert_ntstatus_ok(tctx, status, "EnumJobs failed");
 
        if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
-               union spoolss_JobInfo *info;
                int j;
                DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
                data_blob_clear(&blob);
@@ -1006,11 +1172,10 @@ static bool test_EnumJobs(struct torture_context *tctx,
 
                status = dcerpc_spoolss_EnumJobs(p, tctx, &r);
 
-               torture_assert(tctx, r.out.info, "No jobs returned");
-
-               info = r.out.info;
+               torture_assert(tctx, info, "No jobs returned");
 
                for (j = 0; j < count; j++) {
+
                        test_GetJob(tctx, p, handle, info[j].info1.job_id);
                        test_SetJob(tctx, p, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_PAUSE);
                        test_SetJob(tctx, p, handle, info[j].info1.job_id, SPOOLSS_JOB_CONTROL_RESUME);
@@ -1090,6 +1255,7 @@ static bool test_DoPrintTest(struct torture_context *tctx,
        torture_assert_ntstatus_ok(tctx, status, "dcerpc_spoolss_EndDocPrinter failed");
        torture_assert_werr_ok(tctx, e.out.result, "EndDocPrinter failed");
 
+       ret &= test_AddJob(tctx, p, handle);
        ret &= test_EnumJobs(tctx, p, handle);
 
        ret &= test_SetJob(tctx, p, handle, job_id, SPOOLSS_JOB_CONTROL_DELETE);
@@ -1171,13 +1337,15 @@ static bool test_GetPrinterData(struct torture_context *tctx,
        NTSTATUS status;
        struct spoolss_GetPrinterData r;
        uint32_t needed;
-       enum spoolss_PrinterDataType type;
+       enum winreg_Type type;
+       union spoolss_PrinterData data;
 
        r.in.handle = handle;
        r.in.value_name = value_name;
        r.in.offered = 0;
        r.out.needed = &needed;
        r.out.type = &type;
+       r.out.data = &data;
 
        torture_comment(tctx, "Testing GetPrinterData\n");
 
@@ -1204,7 +1372,7 @@ static bool test_GetPrinterDataEx(struct torture_context *tctx,
 {
        NTSTATUS status;
        struct spoolss_GetPrinterDataEx r;
-       uint32_t type;
+       enum winreg_Type type;
        uint32_t needed;
 
        r.in.handle = handle;
@@ -1251,16 +1419,15 @@ static bool test_EnumPrinterData(struct torture_context *tctx, struct dcerpc_pip
        do {
                uint32_t value_size = 0;
                uint32_t data_size = 0;
-               uint32_t printerdata_type = 0;
-               DATA_BLOB data = data_blob(NULL,0);
+               enum winreg_Type type = 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;
+               r.out.type = &type;
+               r.out.data = talloc_zero_array(tctx, uint8_t, 0);
 
                torture_comment(tctx, "Testing EnumPrinterData\n");
 
@@ -1269,7 +1436,9 @@ static bool test_EnumPrinterData(struct torture_context *tctx, struct dcerpc_pip
                torture_assert_ntstatus_ok(tctx, status, "EnumPrinterData failed");
 
                r.in.value_offered = value_size;
+               r.out.value_name = talloc_zero_array(tctx, const char, value_size);
                r.in.data_offered = data_size;
+               r.out.data = talloc_zero_array(tctx, uint8_t, data_size);
 
                status = dcerpc_spoolss_EnumPrinterData(p, tctx, &r);
 
@@ -1294,6 +1463,7 @@ static bool test_EnumPrinterDataEx(struct torture_context *tctx,
 {
        NTSTATUS status;
        struct spoolss_EnumPrinterDataEx r;
+       struct spoolss_PrinterEnumValues *info;
        uint32_t needed;
        uint32_t count;
 
@@ -1302,6 +1472,7 @@ static bool test_EnumPrinterDataEx(struct torture_context *tctx,
        r.in.offered = 0;
        r.out.needed = &needed;
        r.out.count = &count;
+       r.out.info = &info;
 
        torture_comment(tctx, "Testing EnumPrinterDataEx\n");
 
@@ -1309,7 +1480,6 @@ static bool test_EnumPrinterDataEx(struct torture_context *tctx,
        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);
 
@@ -1349,7 +1519,7 @@ static bool test_SetPrinterData(struct torture_context *tctx,
        
        r.in.handle = handle;
        r.in.value_name = value_name;
-       r.in.type = SPOOLSS_PRINTER_DATA_TYPE_STRING;
+       r.in.type = REG_SZ;
        r.in.data.string = "dog";
 
        torture_comment(tctx, "Testing SetPrinterData\n");
@@ -1620,6 +1790,7 @@ static bool test_EnumPrinters_old(struct torture_context *tctx, struct dcerpc_pi
                r.in.offered    = 0;
                r.out.needed    = &needed;
                r.out.count     = &count;
+               r.out.info      = &info;
 
                torture_comment(tctx, "Testing EnumPrinters level %u\n", r.in.level);
 
@@ -1638,19 +1809,24 @@ static bool test_EnumPrinters_old(struct torture_context *tctx, struct dcerpc_pi
 
                torture_assert_werr_ok(tctx, r.out.result, "EnumPrinters failed");
 
-               if (!r.out.info) {
+               if (!info) {
                        torture_comment(tctx, "No printers returned\n");
                        return true;
                }
 
-               info = r.out.info;
-
                for (j=0;j<count;j++) {
                        if (r.in.level == 1) {
-                               /* the names appear to be comma-separated name lists? */
-                               char *name = talloc_strdup(tctx, info[j].info1.name);
-                               char *comma = strchr(name, ',');
-                               if (comma) *comma = 0;
+                               char *unc = talloc_strdup(tctx, info[j].info1.name);
+                               char *slash, *name;
+                               name = unc;
+                               if (unc[0] == '\\' && unc[1] == '\\') {
+                                       unc +=2;
+                               }
+                               slash = strchr(unc, '\\');
+                               if (slash) {
+                                       slash++;
+                                       name = slash;
+                               }
                                if (!test_OpenPrinter(tctx, p, name)) {
                                        ret = false;
                                }
@@ -1727,6 +1903,7 @@ static bool test_EnumPrinterDrivers_old(struct torture_context *tctx,
 
                uint32_t needed;
                uint32_t count;
+               union spoolss_DriverInfo *info;
 
                r.in.server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
                r.in.environment = "Windows NT x86";
@@ -1735,6 +1912,7 @@ static bool test_EnumPrinterDrivers_old(struct torture_context *tctx,
                r.in.offered = 0;
                r.out.needed = &needed;
                r.out.count = &count;
+               r.out.info = &info;
 
                torture_comment(tctx, "Testing EnumPrinterDrivers level %u\n", r.in.level);
 
@@ -1754,7 +1932,7 @@ static bool test_EnumPrinterDrivers_old(struct torture_context *tctx,
 
                torture_assert_werr_ok(tctx, r.out.result, "EnumPrinterDrivers failed");
 
-               if (!r.out.info) {
+               if (!info) {
                        torture_comment(tctx, "No printer drivers returned\n");
                        break;
                }
@@ -1763,41 +1941,6 @@ static bool test_EnumPrinterDrivers_old(struct torture_context *tctx,
        return true;
 }
 
-/** Test that makes sure that calling ReplyOpenPrinter()
- * on Samba 4 will cause an irpc broadcast call.
- */
-static bool test_ReplyOpenPrinter(struct torture_context *tctx, 
-                                 struct dcerpc_pipe *pipe)
-{
-       struct spoolss_ReplyOpenPrinter r;
-       struct spoolss_ReplyClosePrinter s;
-       struct policy_handle h;
-
-       r.in.server_name = "earth";
-       r.in.printer_local = 2;
-       r.in.type = REG_DWORD;
-       r.in.bufsize = 0;
-       r.in.buffer = NULL;
-       r.out.handle = &h;
-
-       torture_assert_ntstatus_ok(tctx, 
-                       dcerpc_spoolss_ReplyOpenPrinter(pipe, tctx, &r),
-                       "spoolss_ReplyOpenPrinter call failed");
-
-       torture_assert_werr_ok(tctx, r.out.result, "error return code");
-
-       s.in.handle = &h;
-       s.out.handle = &h;
-
-       torture_assert_ntstatus_ok(tctx,
-                       dcerpc_spoolss_ReplyClosePrinter(pipe, tctx, &s),
-                       "spoolss_ReplyClosePrinter call failed");
-
-       torture_assert_werr_ok(tctx, r.out.result, "error return code");
-
-       return true;
-}
-
 bool torture_rpc_spoolss(struct torture_context *torture)
 {
        NTSTATUS status;
@@ -1831,9 +1974,11 @@ bool torture_rpc_spoolss(struct torture_context *torture)
        ret &= test_AddForm(torture, p, &ctx->server_handle, true);
        ret &= test_EnumPorts(torture, p, ctx);
        ret &= test_GetPrinterDriverDirectory(torture, p, ctx);
+       ret &= test_GetPrintProcessorDirectory(torture, p, ctx);
        ret &= test_EnumPrinterDrivers(torture, p, ctx);
        ret &= test_EnumMonitors(torture, p, ctx);
        ret &= test_EnumPrintProcessors(torture, p, ctx);
+       ret &= test_EnumPrintProcDataTypes(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__");
@@ -1849,7 +1994,6 @@ bool torture_rpc_spoolss(struct torture_context *torture)
        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;
 }