s4-smbtorture: use test_GetPrinter_level in RPC-SPOOLSS-NOTIFY.
[ira/wip.git] / source4 / torture / rpc / spoolss_notify.c
index a8a0ca5df63de26f97e4f1675ab339ef44f6e560..2496244b1a83e931d5ca8d9ce7f71e5d5b29f8ee 100644 (file)
@@ -1,35 +1,35 @@
-/* 
+/*
    Unix SMB/CIFS implementation.
    test suite for spoolss rpc notify operations
 
    Copyright (C) Jelmer Vernooij 2007
-   
+   Copyright (C) Guenther Deschner 2010
+
    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, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
 #include "includes.h"
-#include "torture/torture.h"
-#include "torture/rpc/rpc.h"
+#include "system/filesys.h"
 #include "librpc/gen_ndr/ndr_spoolss_c.h"
+#include "librpc/gen_ndr/ndr_spoolss.h"
+#include "torture/rpc/rpc.h"
 #include "rpc_server/dcerpc_server.h"
-#include "lib/events/events.h"
+#include "rpc_server/service_rpc.h"
 #include "smbd/process_model.h"
 #include "smb_server/smb_server.h"
-#include "librpc/rpc/dcerpc_proto.h"
 #include "lib/socket/netif.h"
-#include "../lib/util/dlinklist.h"
 #include "ntvfs/ntvfs.h"
 #include "param/param.h"
 
@@ -70,7 +70,7 @@ static NTSTATUS spoolss__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_
        return NT_STATUS_OK;
 }
 
-/* Note that received_packets are allocated in talloc_autofree_context(), 
+/* Note that received_packets are allocated in talloc_autofree_context(),
  * because no other context appears to stay around long enough. */
 static struct received_packet {
        uint16_t opnum;
@@ -78,6 +78,56 @@ static struct received_packet {
        struct received_packet *prev, *next;
 } *received_packets = NULL;
 
+static WERROR _spoolss_ReplyOpenPrinter(struct dcesrv_call_state *dce_call,
+                                       TALLOC_CTX *mem_ctx,
+                                       struct spoolss_ReplyOpenPrinter *r)
+{
+       DEBUG(1,("_spoolss_ReplyOpenPrinter\n"));
+
+       NDR_PRINT_IN_DEBUG(spoolss_ReplyOpenPrinter, r);
+
+       r->out.handle = talloc(r, struct policy_handle);
+       r->out.handle->handle_type = 42;
+       r->out.handle->uuid = GUID_random();
+       r->out.result = WERR_OK;
+
+       NDR_PRINT_OUT_DEBUG(spoolss_ReplyOpenPrinter, r);
+
+       return WERR_OK;
+}
+
+static WERROR _spoolss_ReplyClosePrinter(struct dcesrv_call_state *dce_call,
+                                        TALLOC_CTX *mem_ctx,
+                                        struct spoolss_ReplyClosePrinter *r)
+{
+       DEBUG(1,("_spoolss_ReplyClosePrinter\n"));
+
+       NDR_PRINT_IN_DEBUG(spoolss_ReplyClosePrinter, r);
+
+       ZERO_STRUCTP(r->out.handle);
+       r->out.result = WERR_OK;
+
+       NDR_PRINT_OUT_DEBUG(spoolss_ReplyClosePrinter, r);
+
+       return WERR_OK;
+}
+
+static WERROR _spoolss_RouterReplyPrinterEx(struct dcesrv_call_state *dce_call,
+                                           TALLOC_CTX *mem_ctx,
+                                           struct spoolss_RouterReplyPrinterEx *r)
+{
+       DEBUG(1,("_spoolss_RouterReplyPrinterEx\n"));
+
+       NDR_PRINT_IN_DEBUG(spoolss_RouterReplyPrinterEx, r);
+
+       r->out.reply_result = talloc(r, uint32_t);
+       *r->out.reply_result = 0;
+       r->out.result = WERR_OK;
+
+       NDR_PRINT_OUT_DEBUG(spoolss_RouterReplyPrinterEx, r);
+
+       return WERR_OK;
+}
 
 static NTSTATUS spoolss__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, void *r)
 {
@@ -93,7 +143,17 @@ static NTSTATUS spoolss__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_
        switch (opnum) {
        case 58: {
                struct spoolss_ReplyOpenPrinter *r2 = (struct spoolss_ReplyOpenPrinter *)r;
-               r2->out.result = WERR_OK;
+               r2->out.result = _spoolss_ReplyOpenPrinter(dce_call, mem_ctx, r2);
+               break;
+       }
+       case 60: {
+               struct spoolss_ReplyClosePrinter *r2 = (struct spoolss_ReplyClosePrinter *)r;
+               r2->out.result = _spoolss_ReplyClosePrinter(dce_call, mem_ctx, r2);
+               break;
+       }
+       case 66: {
+               struct spoolss_RouterReplyPrinterEx *r2 = (struct spoolss_RouterReplyPrinterEx *)r;
+               r2->out.result = _spoolss_RouterReplyPrinterEx(dce_call, mem_ctx, r2);
                break;
        }
 
@@ -161,7 +221,7 @@ static bool spoolss__op_interface_by_name(struct dcesrv_interface *iface, const
                return true;
        }
 
-       return false;   
+       return false;
 }
 
 static NTSTATUS spoolss__op_init_server(struct dcesrv_context *dce_ctx, const struct dcesrv_endpoint_server *ep_server)
@@ -182,43 +242,218 @@ static NTSTATUS spoolss__op_init_server(struct dcesrv_context *dce_ctx, const st
        return NT_STATUS_OK;
 }
 
-static bool test_RFFPCNEx(struct torture_context *tctx, 
-                         struct dcerpc_pipe *p)
+static bool test_OpenPrinter(struct torture_context *tctx,
+                            struct dcerpc_pipe *p,
+                            struct policy_handle *handle,
+                            const char *name)
+{
+       struct spoolss_OpenPrinter r;
+       const char *printername;
+
+       ZERO_STRUCT(r);
+
+       if (name) {
+               printername     = talloc_asprintf(tctx, "\\\\%s\\%s", dcerpc_server_name(p), name);
+       } else {
+               printername     = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
+       }
+
+       r.in.printername        = printername;
+       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);
+
+       torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_OpenPrinter(p, tctx, &r),
+               "OpenPrinter failed");
+       torture_assert_werr_ok(tctx, r.out.result,
+               "OpenPrinter failed");
+
+       return true;
+}
+
+static struct spoolss_NotifyOption *setup_printserver_NotifyOption(struct torture_context *tctx)
+{
+       struct spoolss_NotifyOption *o;
+
+       o = talloc_zero(tctx, struct spoolss_NotifyOption);
+
+       o->version = 2;
+       o->flags = PRINTER_NOTIFY_OPTIONS_REFRESH;
+
+       o->count = 2;
+       o->types = talloc_zero_array(o, struct spoolss_NotifyOptionType, o->count);
+
+       o->types[0].type = PRINTER_NOTIFY_TYPE;
+       o->types[0].count = 1;
+       o->types[0].fields = talloc_array(o->types, union spoolss_Field, o->types[0].count);
+       o->types[0].fields[0].field = PRINTER_NOTIFY_FIELD_SERVER_NAME;
+
+       o->types[1].type = JOB_NOTIFY_TYPE;
+       o->types[1].count = 1;
+       o->types[1].fields = talloc_array(o->types, union spoolss_Field, o->types[1].count);
+       o->types[1].fields[0].field = JOB_NOTIFY_FIELD_MACHINE_NAME;
+
+       return o;
+}
+
+static struct spoolss_NotifyOption *setup_printer_NotifyOption(struct torture_context *tctx)
+{
+       struct spoolss_NotifyOption *o;
+
+       o = talloc_zero(tctx, struct spoolss_NotifyOption);
+
+       o->version = 2;
+       o->flags = PRINTER_NOTIFY_OPTIONS_REFRESH;
+
+       o->count = 1;
+       o->types = talloc_zero_array(o, struct spoolss_NotifyOptionType, o->count);
+
+       o->types[0].type = PRINTER_NOTIFY_TYPE;
+       o->types[0].count = 1;
+       o->types[0].fields = talloc_array(o->types, union spoolss_Field, o->types[0].count);
+       o->types[0].fields[0].field = PRINTER_NOTIFY_FIELD_COMMENT;
+
+       return o;
+}
+
+
+static bool test_RemoteFindFirstPrinterChangeNotifyEx(struct torture_context *tctx,
+                                                     struct dcerpc_pipe *p,
+                                                     struct policy_handle *handle,
+                                                     const char *address,
+                                                     struct spoolss_NotifyOption *option)
 {
-       struct spoolss_OpenPrinter q;
        struct spoolss_RemoteFindFirstPrinterChangeNotifyEx r;
-       struct dcesrv_endpoint_server ep_server;
-       NTSTATUS status;
-       struct dcesrv_context *dce_ctx;
-       const char *endpoints[] = { "spoolss", NULL };
-       struct spoolss_NotifyOption t1;
-       struct spoolss_ClosePrinter cp;
 
-       struct policy_handle handle;
-       const char *address;
-       struct interface *ifaces;
+       torture_comment(tctx, "Testing RemoteFindFirstPrinterChangeNotifyEx\n");
 
-       received_packets = NULL;
+       r.in.flags = 0;
+       r.in.local_machine = talloc_asprintf(tctx, "\\\\%s", address);
+       r.in.options = 0;
+       r.in.printer_local = 0;
+       r.in.notify_options = option;
+       r.in.handle = handle;
 
-       ntvfs_init(tctx->lp_ctx);
+       torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_RemoteFindFirstPrinterChangeNotifyEx(p, tctx, &r),
+               "RemoteFindFirstPrinterChangeNotifyEx failed");
+       torture_assert_werr_ok(tctx, r.out.result,
+               "error return code for RemoteFindFirstPrinterChangeNotifyEx");
 
-       ZERO_STRUCT(q);
+       return true;
+}
 
-       q.in.printername        = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
-       q.in.datatype           = NULL;
-       q.in.devmode_ctr.devmode= NULL;
-       q.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
-       q.out.handle            = &handle;
+static bool test_RouterRefreshPrinterChangeNotify(struct torture_context *tctx,
+                                                 struct dcerpc_pipe *p,
+                                                 struct policy_handle *handle,
+                                                 struct spoolss_NotifyOption *options)
+{
+       struct spoolss_RouterRefreshPrinterChangeNotify r;
+       struct spoolss_NotifyInfo *info;
 
-       torture_comment(tctx, "Testing OpenPrinter(%s)\n", q.in.printername);
+       torture_comment(tctx, "Testing RouterRefreshPrinterChangeNotify\n");
 
-       status = dcerpc_spoolss_OpenPrinter(p, tctx, &q);
+       r.in.handle = handle;
+       r.in.change_low = 0;
+       r.in.options = options;
+       r.out.info = &info;
 
-       torture_assert_ntstatus_ok(tctx, status, "OpenPrinter failed");
+       torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_RouterRefreshPrinterChangeNotify(p, tctx, &r),
+               "RouterRefreshPrinterChangeNotify failed");
+       torture_assert_werr_ok(tctx, r.out.result,
+               "error return code for RouterRefreshPrinterChangeNotify");
 
-       torture_assert_werr_ok(tctx, q.out.result, "OpenPrinter failed");
+       return true;
+}
 
-       /* Start DCE/RPC server */
+static bool test_ClosePrinter(struct torture_context *tctx,
+                             struct dcerpc_pipe *p,
+                             struct policy_handle *handle)
+{
+       struct spoolss_ClosePrinter r;
+
+       r.in.handle = handle;
+       r.out.handle = handle;
+
+       torture_comment(tctx, "Testing ClosePrinter\n");
+
+       torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_ClosePrinter(p, tctx, &r),
+               "ClosePrinter failed");
+       torture_assert_werr_ok(tctx, r.out.result,
+               "ClosePrinter failed");
+
+       return true;
+}
+
+static bool test_SetPrinter(struct torture_context *tctx,
+                           struct dcerpc_pipe *p,
+                           struct policy_handle *handle)
+{
+       union spoolss_PrinterInfo info;
+       struct spoolss_SetPrinter r;
+       struct spoolss_SetPrinterInfo2 info2;
+       struct spoolss_SetPrinterInfoCtr info_ctr;
+       struct spoolss_DevmodeContainer devmode_ctr;
+       struct sec_desc_buf secdesc_ctr;
+
+       torture_assert(tctx, test_GetPrinter_level(tctx, p, handle, 2, &info), "");
+
+       ZERO_STRUCT(devmode_ctr);
+       ZERO_STRUCT(secdesc_ctr);
+
+       info2.servername        = info.info2.servername;
+       info2.printername       = info.info2.printername;
+       info2.sharename         = info.info2.sharename;
+       info2.portname          = info.info2.portname;
+       info2.drivername        = info.info2.drivername;
+       info2.comment           = talloc_asprintf(tctx, "torture_comment %d\n", (int)time(NULL));
+       info2.location          = info.info2.location;
+       info2.devmode_ptr       = 0;
+       info2.sepfile           = info.info2.sepfile;
+       info2.printprocessor    = info.info2.printprocessor;
+       info2.datatype          = info.info2.datatype;
+       info2.parameters        = info.info2.parameters;
+       info2.secdesc_ptr       = 0;
+       info2.attributes        = info.info2.attributes;
+       info2.priority          = info.info2.priority;
+       info2.defaultpriority   = info.info2.defaultpriority;
+       info2.starttime         = info.info2.starttime;
+       info2.untiltime         = info.info2.untiltime;
+       info2.status            = info.info2.status;
+       info2.cjobs             = info.info2.cjobs;
+       info2.averageppm        = info.info2.averageppm;
+
+       info_ctr.level = 2;
+       info_ctr.info.info2 = &info2;
+
+       r.in.handle = handle;
+       r.in.info_ctr = &info_ctr;
+       r.in.devmode_ctr = &devmode_ctr;
+       r.in.secdesc_ctr = &secdesc_ctr;
+       r.in.command = 0;
+
+       torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_SetPrinter(p, tctx, &r), "SetPrinter failed");
+       torture_assert_werr_ok(tctx, r.out.result, "SetPrinter failed");
+
+       return true;
+}
+
+static bool test_start_dcerpc_server(struct torture_context *tctx,
+                                    struct tevent_context *event_ctx,
+                                    struct dcesrv_context **dce_ctx_p,
+                                    const char **address_p)
+{
+       struct dcesrv_endpoint_server ep_server;
+       NTSTATUS status;
+       struct dcesrv_context *dce_ctx;
+       const char *endpoints[] = { "spoolss", NULL };
+       struct dcesrv_endpoint *e;
+       const char *address;
+       struct interface *ifaces;
+
+       ntvfs_init(tctx->lp_ctx);
 
        /* fill in our name */
        ep_server.name = "spoolss";
@@ -236,53 +471,79 @@ static bool test_RFFPCNEx(struct torture_context *tctx,
 
        load_interfaces(tctx, lp_interfaces(tctx->lp_ctx), &ifaces);
        address = iface_n_ip(ifaces, 0);
+
        torture_comment(tctx, "Listening for callbacks on %s\n", address);
-       status = smbsrv_add_socket(p->conn->event_ctx, tctx->lp_ctx, &single_ops, address);
+
+       status = smbsrv_add_socket(event_ctx, tctx->lp_ctx, &single_ops, address);
        torture_assert_ntstatus_ok(tctx, status, "starting smb server");
 
        status = dcesrv_init_context(tctx, tctx->lp_ctx, endpoints, &dce_ctx);
-       torture_assert_ntstatus_ok(tctx, status, 
+       torture_assert_ntstatus_ok(tctx, status,
                                   "unable to initialize DCE/RPC server");
 
-       r.in.flags = 0;
-       r.in.local_machine = talloc_asprintf(tctx, "\\\\%s", address);
-       r.in.options = 0;
-       r.in.printer_local = 123;
-       t1.version = 2;
-       t1.flags = 0;
-       t1.count = 2;
-       t1.types = talloc_zero_array(tctx, struct spoolss_NotifyOptionType, 2);
-       t1.types[0].type = PRINTER_NOTIFY_TYPE;
-       t1.types[0].count = 1;
-       t1.types[0].fields = talloc_array(t1.types, union spoolss_Field, 1);
-       t1.types[0].fields[0].field = PRINTER_NOTIFY_FIELD_SERVER_NAME;
-
-       t1.types[1].type = JOB_NOTIFY_TYPE;
-       t1.types[1].count = 1;
-       t1.types[1].fields = talloc_array(t1.types, union spoolss_Field, 1);
-       t1.types[1].fields[0].field = PRINTER_NOTIFY_FIELD_PRINTER_NAME;
-
-       r.in.notify_options = &t1;
-       r.in.handle = &handle;
-
-       status = dcerpc_spoolss_RemoteFindFirstPrinterChangeNotifyEx(p, tctx, &r);
+       for (e=dce_ctx->endpoint_list;e;e=e->next) {
+               status = dcesrv_add_ep(dce_ctx, tctx->lp_ctx,
+                                      e, tctx->ev, &single_ops);
+               torture_assert_ntstatus_ok(tctx, status,
+                               "unable listen on dcerpc endpoint server");
+       }
 
-       torture_assert_ntstatus_ok(tctx, status, "FFPCNEx failed");
-       
-       torture_assert_werr_ok(tctx, r.out.result, "error return code for FFPCNEx");
+       *dce_ctx_p = dce_ctx;
+       *address_p = address;
 
-       cp.in.handle = &handle;
-       cp.out.handle = &handle;
+       return true;
+}
 
-       torture_comment(tctx, "Testing ClosePrinter\n");
+static struct received_packet *last_packet(struct received_packet *p)
+{
+       struct received_packet *tmp;
+       for (tmp = p; tmp->next; tmp = tmp->next) ;;
+       return tmp;
+}
 
-       status = dcerpc_spoolss_ClosePrinter(p, tctx, &cp);
-       torture_assert_ntstatus_ok(tctx, status, "ClosePrinter failed");
+static bool test_RFFPCNEx(struct torture_context *tctx,
+                         struct dcerpc_pipe *p)
+{
+       struct dcesrv_context *dce_ctx;
+       struct policy_handle handle;
+       const char *address;
+       struct received_packet *tmp;
+       struct spoolss_NotifyOption *server_option = setup_printserver_NotifyOption(tctx);
+       struct spoolss_NotifyOption *printer_option = setup_printer_NotifyOption(tctx);
 
-       /* We should've had an incoming packet 58 (ReplyOpenPrinter) */
-       torture_assert(tctx, received_packets != NULL, "no packets received");
-       torture_assert_int_equal(tctx, received_packets->opnum, 58, "invalid opnum");
+       received_packets = NULL;
 
+       /* Start DCE/RPC server */
+       torture_assert(tctx, test_start_dcerpc_server(tctx, p->conn->event_ctx, &dce_ctx, &address), "");
+
+       torture_assert(tctx, test_OpenPrinter(tctx, p, &handle, NULL), "");
+       torture_assert(tctx, test_RemoteFindFirstPrinterChangeNotifyEx(tctx, p, &handle, address, server_option), "");
+       torture_assert(tctx, received_packets, "no packets received");
+       torture_assert_int_equal(tctx, received_packets->opnum, NDR_SPOOLSS_REPLYOPENPRINTER,
+               "no ReplyOpenPrinter packet after RemoteFindFirstPrinterChangeNotifyEx");
+       torture_assert(tctx, test_RouterRefreshPrinterChangeNotify(tctx, p, &handle, NULL), "");
+       torture_assert(tctx, test_RouterRefreshPrinterChangeNotify(tctx, p, &handle, server_option), "");
+       torture_assert(tctx, test_ClosePrinter(tctx, p, &handle), "");
+       tmp = last_packet(received_packets);
+       torture_assert_int_equal(tctx, tmp->opnum, NDR_SPOOLSS_REPLYCLOSEPRINTER,
+               "no ReplyClosePrinter packet after ClosePrinter");
+#if 0
+       torture_assert(tctx, test_OpenPrinter(tctx, p, &handle, "Epson AL-2600"), "");
+       torture_assert(tctx, test_RemoteFindFirstPrinterChangeNotifyEx(tctx, p, &handle, address, printer_option), "");
+       tmp = last_packet(received_packets);
+       torture_assert_int_equal(tctx, tmp->opnum, NDR_SPOOLSS_REPLYOPENPRINTER,
+               "no ReplyOpenPrinter packet after RemoteFindFirstPrinterChangeNotifyEx");
+       torture_assert(tctx, test_RouterRefreshPrinterChangeNotify(tctx, p, &handle, NULL), "");
+       torture_assert(tctx, test_RouterRefreshPrinterChangeNotify(tctx, p, &handle, printer_option), "");
+       torture_assert(tctx, test_SetPrinter(tctx, p, &handle), "");
+       tmp = last_packet(received_packets);
+       torture_assert_int_equal(tctx, tmp->opnum, NDR_SPOOLSS_ROUTERREPLYPRINTEREX,
+               "no RouterReplyPrinterEx packet after ClosePrinter");
+       torture_assert(tctx, test_ClosePrinter(tctx, p, &handle), "");
+       tmp = last_packet(received_packets);
+       torture_assert_int_equal(tctx, tmp->opnum, NDR_SPOOLSS_REPLYCLOSEPRINTER,
+               "no ReplyClosePrinter packet after ClosePrinter");
+#endif
        /* Shut down DCE/RPC server */
        talloc_free(dce_ctx);
 
@@ -293,12 +554,16 @@ static bool test_RFFPCNEx(struct torture_context *tctx,
  * on Samba 4 will cause an irpc broadcast call.
  */
 static bool test_ReplyOpenPrinter(struct torture_context *tctx,
-                                 struct dcerpc_pipe *pipe)
+                                 struct dcerpc_pipe *p)
 {
        struct spoolss_ReplyOpenPrinter r;
        struct spoolss_ReplyClosePrinter s;
        struct policy_handle h;
 
+       if (torture_setting_bool(tctx, "samba3", false)) {
+               torture_skip(tctx, "skipping ReplyOpenPrinter server implementation test against s3\n");
+       }
+
        r.in.server_name = "earth";
        r.in.printer_local = 2;
        r.in.type = REG_DWORD;
@@ -307,7 +572,7 @@ static bool test_ReplyOpenPrinter(struct torture_context *tctx,
        r.out.handle = &h;
 
        torture_assert_ntstatus_ok(tctx,
-                       dcerpc_spoolss_ReplyOpenPrinter(pipe, tctx, &r),
+                       dcerpc_spoolss_ReplyOpenPrinter(p, tctx, &r),
                        "spoolss_ReplyOpenPrinter call failed");
 
        torture_assert_werr_ok(tctx, r.out.result, "error return code");
@@ -316,7 +581,7 @@ static bool test_ReplyOpenPrinter(struct torture_context *tctx,
        s.out.handle = &h;
 
        torture_assert_ntstatus_ok(tctx,
-                       dcerpc_spoolss_ReplyClosePrinter(pipe, tctx, &s),
+                       dcerpc_spoolss_ReplyClosePrinter(p, tctx, &s),
                        "spoolss_ReplyClosePrinter call failed");
 
        torture_assert_werr_ok(tctx, r.out.result, "error return code");
@@ -327,12 +592,12 @@ static bool test_ReplyOpenPrinter(struct torture_context *tctx,
 struct torture_suite *torture_rpc_spoolss_notify(TALLOC_CTX *mem_ctx)
 {
        struct torture_suite *suite = torture_suite_create(mem_ctx, "SPOOLSS-NOTIFY");
-       
-       struct torture_rpc_tcase *tcase = torture_suite_add_rpc_iface_tcase(suite, 
+
+       struct torture_rpc_tcase *tcase = torture_suite_add_rpc_iface_tcase(suite,
                                                        "notify", &ndr_table_spoolss);
 
        torture_rpc_tcase_add_test(tcase, "testRFFPCNEx", test_RFFPCNEx);
        torture_rpc_tcase_add_test(tcase, "testReplyOpenPrinter", test_ReplyOpenPrinter);
-       
+
        return suite;
 }