The branch, master has been updated
       via  b6fb8cf5f38fc434103936b41a5793f5943c129a (commit)
      from  3a367ab10d3da2d9f5261769af06442550a0f029 (commit)

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


- Log -----------------------------------------------------------------
commit b6fb8cf5f38fc434103936b41a5793f5943c129a
Author: Günther Deschner <g...@samba.org>
Date:   Fri Jul 3 09:56:28 2009 +0200

    s4-smbtorture: add RPC-SPOOLSS-PRINTER test.
    
    Guenther

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

Summary of changes:
 source4/torture/rpc/rpc.c     |    1 +
 source4/torture/rpc/spoolss.c |  443 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 444 insertions(+), 0 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/torture/rpc/rpc.c b/source4/torture/rpc/rpc.c
index 4043562..6eeba7f 100644
--- a/source4/torture/rpc/rpc.c
+++ b/source4/torture/rpc/rpc.c
@@ -444,6 +444,7 @@ NTSTATUS torture_rpc_init(void)
        torture_suite_add_simple_test(suite, "SPOOLSS", torture_rpc_spoolss);
        torture_suite_add_suite(suite, torture_rpc_spoolss_notify(suite));
        torture_suite_add_suite(suite, torture_rpc_spoolss_win(suite));
+       torture_suite_add_suite(suite, torture_rpc_spoolss_printer(suite));
        torture_suite_add_simple_test(suite, "SAMR", torture_rpc_samr);
        torture_suite_add_simple_test(suite, "SAMR-USERS", 
torture_rpc_samr_users);
        torture_suite_add_simple_test(suite, "SAMR-PASSWORDS", 
torture_rpc_samr_passwords);
diff --git a/source4/torture/rpc/spoolss.c b/source4/torture/rpc/spoolss.c
index b6ad1a7..a515ef6 100644
--- a/source4/torture/rpc/spoolss.c
+++ b/source4/torture/rpc/spoolss.c
@@ -26,6 +26,11 @@
 #include "torture/rpc/rpc.h"
 #include "librpc/gen_ndr/ndr_spoolss_c.h"
 
+#define TORTURE_WELLKNOWN_PRINTER      "torture_wkn_printer"
+#define TORTURE_PRINTER                        "torture_printer"
+#define TORTURE_WELLKNOWN_PRINTER_EX   "torture_wkn_printer_ex"
+#define TORTURE_PRINTER_EX             "torture_printer_ex"
+
 struct test_spoolss_context {
        /* print server handle */
        struct policy_handle server_handle;
@@ -2633,6 +2638,432 @@ static bool test_EnumPrinterDrivers_old(struct 
torture_context *tctx,
        return true;
 }
 
+static bool test_DeletePrinter(struct torture_context *tctx,
+                              struct dcerpc_pipe *p,
+                              struct policy_handle *handle)
+{
+       struct spoolss_DeletePrinter r;
+
+       torture_comment(tctx, "Testing DeletePrinter\n");
+
+       r.in.handle = handle;
+
+       torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_DeletePrinter(p, tctx, 
&r),
+               "failed to delete printer");
+       torture_assert_werr_ok(tctx, r.out.result,
+               "failed to delete printer");
+
+       return true;
+}
+
+static bool test_EnumPrinters_findname(struct torture_context *tctx,
+                                      struct dcerpc_pipe *p,
+                                      uint32_t flags,
+                                      uint32_t level,
+                                      const char *name,
+                                      bool *found)
+{
+       struct spoolss_EnumPrinters e;
+       uint32_t count;
+       union spoolss_PrinterInfo *info;
+       uint32_t needed;
+       int i;
+
+       *found = false;
+
+       e.in.flags = flags;
+       e.in.server = NULL;
+       e.in.level = level;
+       e.in.buffer = NULL;
+       e.in.offered = 0;
+       e.out.count = &count;
+       e.out.info = &info;
+       e.out.needed = &needed;
+
+       torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters(p, tctx, 
&e),
+               "failed to enum printers");
+
+       if (W_ERROR_EQUAL(e.out.result, WERR_INSUFFICIENT_BUFFER)) {
+               DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
+               data_blob_clear(&blob);
+               e.in.buffer = &blob;
+               e.in.offered = needed;
+
+               torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_EnumPrinters(p, 
tctx, &e),
+                       "failed to enum printers");
+       }
+
+       torture_assert_werr_ok(tctx, e.out.result,
+               "failed to enum printers");
+
+       for (i=0; i < count; i++) {
+
+               const char *current = NULL;
+
+               switch (level) {
+               case 1:
+                       current = info[i].info1.name;
+                       break;
+               }
+
+               if (strequal(current, name)) {
+                       *found = true;
+                       break;
+               }
+       }
+
+       return true;
+}
+
+static bool test_AddPrinter_wellknown(struct torture_context *tctx,
+                                     struct dcerpc_pipe *p,
+                                     const char *printername,
+                                     bool ex)
+{
+       WERROR result;
+       struct spoolss_AddPrinter r;
+       struct spoolss_AddPrinterEx rex;
+       struct spoolss_SetPrinterInfoCtr info_ctr;
+       struct spoolss_SetPrinterInfo1 info1;
+       struct spoolss_DevmodeContainer devmode_ctr;
+       struct sec_desc_buf secdesc_ctr;
+       struct spoolss_UserLevelCtr userlevel_ctr;
+       struct policy_handle handle;
+       bool found = false;
+
+       ZERO_STRUCT(devmode_ctr);
+       ZERO_STRUCT(secdesc_ctr);
+       ZERO_STRUCT(userlevel_ctr);
+       ZERO_STRUCT(info1);
+
+       torture_comment(tctx, "Testing AddPrinter%s level 1\n", ex ? "Ex":"");
+
+       /* try to add printer to wellknown printer list (level 1) */
+
+       userlevel_ctr.level = 1;
+
+       info_ctr.info.info1 = &info1;
+       info_ctr.level = 1;
+
+       rex.in.server = NULL;
+       rex.in.info_ctr = &info_ctr;
+       rex.in.devmode_ctr = &devmode_ctr;
+       rex.in.secdesc_ctr = &secdesc_ctr;
+       rex.in.userlevel_ctr = &userlevel_ctr;
+       rex.out.handle = &handle;
+
+       r.in.server = NULL;
+       r.in.info_ctr = &info_ctr;
+       r.in.devmode_ctr = &devmode_ctr;
+       r.in.secdesc_ctr = &secdesc_ctr;
+       r.out.handle = &handle;
+
+       torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, 
tctx, &rex) :
+                                             dcerpc_spoolss_AddPrinter(p, 
tctx, &r),
+               "failed to add printer");
+       result = ex ? rex.out.result : r.out.result;
+       torture_assert_werr_equal(tctx, result, WERR_INVALID_PRINTER_NAME,
+               "unexpected result code");
+
+       info1.name = printername;
+       info1.flags = PRINTER_ATTRIBUTE_SHARED;
+
+       torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, 
tctx, &rex) :
+                                             dcerpc_spoolss_AddPrinter(p, 
tctx, &r),
+               "failed to add printer");
+       result = ex ? rex.out.result : r.out.result;
+       torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
+               "unexpected result code");
+
+       /* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here,
+          better do a real check to see the printer is really there */
+
+       torture_assert(tctx, test_EnumPrinters_findname(tctx, p,
+                                                       PRINTER_ENUM_NETWORK, 1,
+                                                       printername,
+                                                       &found),
+                       "failed to enum printers");
+
+       torture_assert(tctx, found, "failed to find newly added printer");
+
+       info1.flags = 0;
+
+       torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, 
tctx, &rex) :
+                                             dcerpc_spoolss_AddPrinter(p, 
tctx, &r),
+               "failed to add printer");
+       result = ex ? rex.out.result : r.out.result;
+       torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
+               "unexpected result code");
+
+       /* bizarre protocol, WERR_PRINTER_ALREADY_EXISTS means success here,
+          better do a real check to see the printer has really been removed
+          from the well known printer list */
+
+       found = false;
+
+       torture_assert(tctx, test_EnumPrinters_findname(tctx, p,
+                                                       PRINTER_ENUM_NETWORK, 1,
+                                                       printername,
+                                                       &found),
+                       "failed to enum printers");
+#if 0
+       torture_assert(tctx, !found, "printer still in well known printer 
list");
+#endif
+       return true;
+}
+
+static bool test_AddPrinter_normal(struct torture_context *tctx,
+                                  struct dcerpc_pipe *p,
+                                  struct policy_handle *handle_p,
+                                  const char *printername,
+                                  const char *drivername,
+                                  const char *portname,
+                                  bool ex)
+{
+       WERROR result;
+       struct spoolss_AddPrinter r;
+       struct spoolss_AddPrinterEx rex;
+       struct spoolss_SetPrinterInfoCtr info_ctr;
+       struct spoolss_SetPrinterInfo2 info2;
+       struct spoolss_DevmodeContainer devmode_ctr;
+       struct sec_desc_buf secdesc_ctr;
+       struct spoolss_UserLevelCtr userlevel_ctr;
+       struct policy_handle handle;
+       bool found = false;
+
+       ZERO_STRUCT(devmode_ctr);
+       ZERO_STRUCT(secdesc_ctr);
+       ZERO_STRUCT(userlevel_ctr);
+
+       torture_comment(tctx, "Testing AddPrinter%s level 2\n", ex ? "Ex":"");
+
+       userlevel_ctr.level = 1;
+
+       rex.in.server = NULL;
+       rex.in.info_ctr = &info_ctr;
+       rex.in.devmode_ctr = &devmode_ctr;
+       rex.in.secdesc_ctr = &secdesc_ctr;
+       rex.in.userlevel_ctr = &userlevel_ctr;
+       rex.out.handle = &handle;
+
+       r.in.server = NULL;
+       r.in.info_ctr = &info_ctr;
+       r.in.devmode_ctr = &devmode_ctr;
+       r.in.secdesc_ctr = &secdesc_ctr;
+       r.out.handle = &handle;
+
+ again:
+
+       /* try to add printer to printer list (level 2) */
+
+       ZERO_STRUCT(info2);
+
+       info_ctr.info.info2 = &info2;
+       info_ctr.level = 2;
+
+       torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, 
tctx, &rex) :
+                                             dcerpc_spoolss_AddPrinter(p, 
tctx, &r),
+               "failed to add printer");
+       result = ex ? rex.out.result : r.out.result;
+       torture_assert_werr_equal(tctx, result, WERR_INVALID_PRINTER_NAME,
+               "unexpected result code");
+
+       info2.printername = printername;
+
+       torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, 
tctx, &rex) :
+                                             dcerpc_spoolss_AddPrinter(p, 
tctx, &r),
+               "failed to add printer");
+       result = ex ? rex.out.result : r.out.result;
+
+       if (W_ERROR_EQUAL(result, WERR_PRINTER_ALREADY_EXISTS)) {
+               struct policy_handle printer_handle;
+
+               torture_assert(tctx, call_OpenPrinterEx(tctx, p, printername, 
&printer_handle),
+                       "failed to open printer handle");
+
+               torture_assert(tctx, test_DeletePrinter(tctx, p, 
&printer_handle),
+                       "failed to delete printer");
+
+               torture_assert(tctx, test_ClosePrinter(tctx, p, 
&printer_handle),
+                       "failed to close server handle");
+
+               goto again;
+       }
+
+       torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PORT,
+               "unexpected result code");
+
+       info2.portname = portname;
+
+       torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, 
tctx, &rex) :
+                                             dcerpc_spoolss_AddPrinter(p, 
tctx, &r),
+               "failed to add printer");
+       result = ex ? rex.out.result : r.out.result;
+       torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PRINTER_DRIVER,
+               "unexpected result code");
+
+       info2.drivername = drivername;
+
+       torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, 
tctx, &rex) :
+                                             dcerpc_spoolss_AddPrinter(p, 
tctx, &r),
+               "failed to add printer");
+       result = ex ? rex.out.result : r.out.result;
+       torture_assert_werr_equal(tctx, result, WERR_UNKNOWN_PRINTPROCESSOR,
+               "unexpected result code");
+
+       info2.printprocessor = "winprint";
+
+       torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, 
tctx, &rex) :
+                                             dcerpc_spoolss_AddPrinter(p, 
tctx, &r),
+               "failed to add printer");
+       result = ex ? rex.out.result : r.out.result;
+       torture_assert_werr_ok(tctx, result,
+               "failed to add printer");
+
+       *handle_p = handle;
+
+       /* we are paranoid, really check if the printer is there now */
+
+       torture_assert(tctx, test_EnumPrinters_findname(tctx, p,
+                                                       PRINTER_ENUM_LOCAL, 1,
+                                                       printername,
+                                                       &found),
+                       "failed to enum printers");
+       torture_assert(tctx, found, "failed to find newly added printer");
+
+       torture_assert_ntstatus_ok(tctx, ex ? dcerpc_spoolss_AddPrinterEx(p, 
tctx, &rex) :
+                                             dcerpc_spoolss_AddPrinter(p, 
tctx, &r),
+               "failed to add printer");
+       result = ex ? rex.out.result : r.out.result;
+       torture_assert_werr_equal(tctx, result, WERR_PRINTER_ALREADY_EXISTS,
+               "unexpected result code");
+
+       return true;
+}
+
+static bool test_AddPrinterEx(struct torture_context *tctx,
+                             struct dcerpc_pipe *p,
+                             struct policy_handle *handle_p,
+                             const char *printername,
+                             const char *drivername,
+                             const char *portname)
+{
+       bool ret = true;
+
+       if (!torture_setting_bool(tctx, "samba3", false)) {
+               if (!test_AddPrinter_wellknown(tctx, p, 
TORTURE_WELLKNOWN_PRINTER_EX, true)) {
+                       torture_comment(tctx, "failed to add printer to well 
known list\n");
+                       ret = false;
+               }
+       }
+
+       if (!test_AddPrinter_normal(tctx, p, handle_p,
+                                   printername, drivername, portname,
+                                   true)) {
+               torture_comment(tctx, "failed to add printer to printer 
list\n");
+               ret = false;
+       }
+
+       return ret;
+}
+
+static bool test_AddPrinter(struct torture_context *tctx,
+                           struct dcerpc_pipe *p,
+                           struct policy_handle *handle_p,
+                           const char *printername,
+                           const char *drivername,
+                           const char *portname)
+{
+       bool ret = true;
+
+       if (!torture_setting_bool(tctx, "samba3", false)) {
+               if (!test_AddPrinter_wellknown(tctx, p, 
TORTURE_WELLKNOWN_PRINTER, false)) {
+                       torture_comment(tctx, "failed to add printer to well 
known list\n");
+                       ret = false;
+               }
+       }
+
+       if (!test_AddPrinter_normal(tctx, p, handle_p,
+                                   printername, drivername, portname,
+                                   false)) {
+               torture_comment(tctx, "failed to add printer to printer 
list\n");
+               ret = false;
+       }
+
+       return ret;
+}
+
+static bool test_printer_info(struct torture_context *tctx,
+                             struct dcerpc_pipe *p,
+                             struct policy_handle *handle)
+{
+       bool ret = true;
+
+       if (!test_PrinterInfo(tctx, p, handle)) {
+               ret = false;
+       }
+
+       if (!test_SetPrinter_errors(tctx, p, handle)) {
+               ret = false;
+       }
+
+       return ret;
+}
+
+static bool test_printer(struct torture_context *tctx,
+                        struct dcerpc_pipe *p)
+{
+       bool ret = true;
+       struct policy_handle handle[2];
+       bool found = false;
+       const char *drivername = "Microsoft XPS Document Writer";
+       const char *portname = "LPT1:";
+
+       /* test printer created via AddPrinter */
+
+       if (!test_AddPrinter(tctx, p, &handle[0], TORTURE_PRINTER, drivername, 
portname)) {
+               return false;
+       }
+
+       if (!test_printer_info(tctx, p, &handle[0])) {
+               ret = false;
+       }
+
+       if (!test_DeletePrinter(tctx, p, &handle[0])) {
+               ret = false;
+       }
+
+       if (!test_EnumPrinters_findname(tctx, p, PRINTER_ENUM_LOCAL, 1,
+                                       TORTURE_PRINTER, &found)) {
+               ret = false;
+       }
+
+       torture_assert(tctx, !found, "deleted printer still there");
+
+       /* test printer created via AddPrinterEx */
+
+       if (!test_AddPrinterEx(tctx, p, &handle[1], TORTURE_PRINTER_EX, 
drivername, portname)) {
+               return false;
+       }
+
+       if (!test_printer_info(tctx, p, &handle[1])) {
+               ret = false;
+       }
+
+       if (!test_DeletePrinter(tctx, p, &handle[1])) {
+               ret = false;
+       }
+
+       if (!test_EnumPrinters_findname(tctx, p, PRINTER_ENUM_LOCAL, 1,
+                                       TORTURE_PRINTER_EX, &found)) {
+               ret = false;
+       }
+
+       torture_assert(tctx, !found, "deleted printer still there");
+
+       return ret;
+}
+
 bool torture_rpc_spoolss(struct torture_context *torture)
 {
        NTSTATUS status;
@@ -2689,3 +3120,15 @@ bool torture_rpc_spoolss(struct torture_context *torture)
 
        return ret;
 }
+
+struct torture_suite *torture_rpc_spoolss_printer(TALLOC_CTX *mem_ctx)
+{
+       struct torture_suite *suite = torture_suite_create(mem_ctx, 
"SPOOLSS-PRINTER");
+
+       struct torture_rpc_tcase *tcase = 
torture_suite_add_rpc_iface_tcase(suite,
+                                                       "printer", 
&ndr_table_spoolss);
+
+       torture_rpc_tcase_add_test(tcase, "printer", test_printer);
+
+       return suite;
+}


-- 
Samba Shared Repository

Reply via email to