s3: Lift the smbd_messaging_context from winreg_printer_enumforms1
[amitay/samba.git] / source3 / rpc_server / srv_spoolss_nt.c
index ab1678ffef424071dbb923bc09931b338d8614aa..33d318ea374701b001157f4b4dd5054862d36ed6 100644 (file)
@@ -28,6 +28,7 @@
    up, all the errors returned are DOS errors, not NT status codes. */
 
 #include "includes.h"
+#include "nt_printing.h"
 #include "srv_spoolss_util.h"
 #include "../librpc/gen_ndr/srv_spoolss.h"
 #include "../librpc/gen_ndr/cli_spoolss.h"
@@ -36,6 +37,9 @@
 #include "librpc/gen_ndr/ndr_security.h"
 #include "registry.h"
 #include "registry/reg_objects.h"
+#include "include/printing.h"
+#include "secrets.h"
+#include "../librpc/gen_ndr/netlogon.h"
 
 /* macros stolen from s4 spoolss server */
 #define SPOOLSS_BUFFER_UNION(fn,info,level) \
 
 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
 
-
-extern userdom_struct current_user_info;
-
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
 
-#ifndef MAX_OPEN_PRINTER_EXS
-#define MAX_OPEN_PRINTER_EXS 50
-#endif
-
-#define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
-
 static Printer_entry *printers_list;
 
 typedef struct _counter_printer_0 {
@@ -77,9 +72,23 @@ static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pip
 static uint32_t smb_connections = 0;
 
 
-/* in printing/nt_printing.c */
+/* Map generic permissions to printer object specific permissions */
+
+const struct standard_mapping printer_std_mapping = {
+       PRINTER_READ,
+       PRINTER_WRITE,
+       PRINTER_EXECUTE,
+       PRINTER_ALL_ACCESS
+};
+
+/* Map generic permissions to print server object specific permissions */
 
-extern struct standard_mapping printer_std_mapping, printserver_std_mapping;
+const struct standard_mapping printserver_std_mapping = {
+       SERVER_READ,
+       SERVER_WRITE,
+       SERVER_EXECUTE,
+       SERVER_ALL_ACCESS
+};
 
 /* API table for Xcv Monitor functions */
 
@@ -150,7 +159,9 @@ static int nt_printq_status(int v)
  Disconnect from the client
 ****************************************************************************/
 
-static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle)
+static void srv_spoolss_replycloseprinter(
+       int snum, struct policy_handle *handle,
+       struct messaging_context *msg_ctx)
 {
        WERROR result;
        NTSTATUS status;
@@ -163,7 +174,7 @@ static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle
        if (!print_notify_deregister_pid(snum))
                DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
 
-       /* weird if the test succeds !!! */
+       /* weird if the test succeeds !!! */
        if (smb_connections==0) {
                DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
                return;
@@ -180,17 +191,24 @@ static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle
        if (smb_connections==1) {
 
                cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
-               notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */
+               /*
+                * The above call shuts down the pipe also.
+                */
+               notify_cli_pipe = NULL;
 
-               messaging_deregister(smbd_messaging_context(),
-                                    MSG_PRINTER_NOTIFY2, NULL);
+               if (msg_ctx != NULL) {
+                       messaging_deregister(msg_ctx, MSG_PRINTER_NOTIFY2,
+                                            NULL);
 
-               /* Tell the connections db we're no longer interested in
-                * printer notify messages. */
+                       /*
+                        * Tell the serverid.tdb we're no longer
+                        * interested in printer notify messages.
+                        */
 
-               serverid_register_msg_flags(
-                       messaging_server_id(smbd_messaging_context()),
-                       false, FLAG_MSG_PRINT_NOTIFY);
+                       serverid_register_msg_flags(
+                               messaging_server_id(msg_ctx),
+                               false, FLAG_MSG_PRINT_NOTIFY);
+               }
        }
 
        smb_connections--;
@@ -207,12 +225,15 @@ static int printer_entry_destructor(Printer_entry *Printer)
 
                if ( Printer->printer_type == SPLHND_SERVER) {
                        snum = -1;
-                       srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
+                       srv_spoolss_replycloseprinter(
+                               snum, &Printer->notify.client_hnd,
+                               Printer->notify.msg_ctx);
                } else if (Printer->printer_type == SPLHND_PRINTER) {
                        snum = print_queue_snum(Printer->sharename);
                        if (snum != -1)
-                               srv_spoolss_replycloseprinter(snum,
-                                               &Printer->notify.client_hnd);
+                               srv_spoolss_replycloseprinter(
+                                       snum, &Printer->notify.client_hnd,
+                                       Printer->notify.msg_ctx);
                }
        }
 
@@ -224,7 +245,6 @@ static int printer_entry_destructor(Printer_entry *Printer)
        Printer->notify.client_connected = false;
 
        TALLOC_FREE(Printer->devmode);
-       free_a_printer( &Printer->printer_info, 2 );
 
        /* Remove from the internal list. */
        DLIST_REMOVE(printers_list, Printer);
@@ -235,7 +255,7 @@ static int printer_entry_destructor(Printer_entry *Printer)
   find printer index by handle
 ****************************************************************************/
 
-static Printer_entry *find_printer_index_by_hnd(pipes_struct *p,
+static Printer_entry *find_printer_index_by_hnd(struct pipes_struct *p,
                                                struct policy_handle *hnd)
 {
        Printer_entry *find_printer = NULL;
@@ -252,7 +272,7 @@ static Printer_entry *find_printer_index_by_hnd(pipes_struct *p,
  Close printer index by handle.
 ****************************************************************************/
 
-static bool close_printer_handle(pipes_struct *p, struct policy_handle *hnd)
+static bool close_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
 {
        Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
 
@@ -271,7 +291,9 @@ static bool close_printer_handle(pipes_struct *p, struct policy_handle *hnd)
  Delete a printer given a handle.
 ****************************************************************************/
 
-static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename)
+static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
+                                 const char *sharename,
+                                 struct messaging_context *msg_ctx)
 {
        char *cmd = lp_deleteprinter_cmd();
        char *command = NULL;
@@ -302,8 +324,7 @@ static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const c
 
        if ( (ret = smbrun(command, NULL)) == 0 ) {
                /* Tell everyone we updated smb.conf. */
-               message_send_all(smbd_messaging_context(),
-                                MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
+               message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
        }
 
        if ( is_print_op )
@@ -333,9 +354,10 @@ static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const c
  Delete a printer given a handle.
 ****************************************************************************/
 
-static WERROR delete_printer_handle(pipes_struct *p, struct policy_handle *hnd)
+static WERROR delete_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
 {
        Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
+       WERROR result;
 
        if (!Printer) {
                DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
@@ -358,20 +380,22 @@ static WERROR delete_printer_handle(pipes_struct *p, struct policy_handle *hnd)
        /* this does not need a become root since the access check has been
           done on the handle already */
 
-       if (del_a_printer( Printer->sharename ) != 0) {
+       result = winreg_delete_printer_key(p->mem_ctx, p->server_info,
+                                          p->msg_ctx, Printer->sharename, "");
+       if (!W_ERROR_IS_OK(result)) {
                DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
                return WERR_BADFID;
        }
 
        return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
-                                  Printer->sharename );
+                                  Printer->sharename, p->msg_ctx);
 }
 
 /****************************************************************************
  Return the snum of a printer corresponding to an handle.
 ****************************************************************************/
 
-static bool get_printer_snum(pipes_struct *p, struct policy_handle *hnd,
+static bool get_printer_snum(struct pipes_struct *p, struct policy_handle *hnd,
                             int *number, struct share_params **params)
 {
        Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
@@ -438,7 +462,7 @@ static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
        int n_services=lp_numservices();
        char *aprinter;
        const char *printername;
-       const char *servername;
+       const char *servername = NULL;
        fstring sname;
        bool found = false;
        struct spoolss_PrinterInfo2 *info2 = NULL;
@@ -515,11 +539,12 @@ static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
 
                result = winreg_get_printer(mem_ctx,
                                            server_info,
+                                           smbd_messaging_context(),
                                            servername,
                                            sname,
                                            &info2);
                if ( !W_ERROR_IS_OK(result) ) {
-                       DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
+                       DEBUG(2,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
                                 sname, win_errstr(result)));
                        continue;
                }
@@ -557,7 +582,7 @@ static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
  Find first available printer slot. creates a printer handle for you.
  ****************************************************************************/
 
-static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd,
+static bool open_printer_hnd(struct pipes_struct *p, struct policy_handle *hnd,
                             const char *name, uint32_t access_granted)
 {
        Printer_entry *new_printer;
@@ -1255,7 +1280,8 @@ static void receive_notify2_message_list(struct messaging_context *msg,
  driver
  ********************************************************************/
 
-static bool srv_spoolss_drv_upgrade_printer(const char *drivername)
+static bool srv_spoolss_drv_upgrade_printer(const char *drivername,
+                                           struct messaging_context *msg_ctx)
 {
        int len = strlen(drivername);
 
@@ -1265,8 +1291,7 @@ static bool srv_spoolss_drv_upgrade_printer(const char *drivername)
        DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
                drivername));
 
-       messaging_send_buf(smbd_messaging_context(),
-                          messaging_server_id(smbd_messaging_context()),
+       messaging_send_buf(msg_ctx, messaging_server_id(msg_ctx),
                           MSG_PRINTER_DRVUPGRADE,
                           (uint8_t *)drivername, len+1);
 
@@ -1321,7 +1346,8 @@ void do_drv_upgrade_printer(struct messaging_context *msg,
                        continue;
                }
 
-               result = winreg_get_printer(tmp_ctx, server_info, NULL,
+               result = winreg_get_printer(tmp_ctx, server_info, msg,
+                                           NULL,
                                            lp_const_servicename(snum),
                                            &pinfo2);
 
@@ -1329,6 +1355,10 @@ void do_drv_upgrade_printer(struct messaging_context *msg,
                        continue;
                }
 
+               if (!pinfo2->drivername) {
+                       continue;
+               }
+
                if (strcmp(drivername, pinfo2->drivername) != 0) {
                        continue;
                }
@@ -1338,6 +1368,7 @@ void do_drv_upgrade_printer(struct messaging_context *msg,
                /* all we care about currently is the change_id */
                result = winreg_printer_update_changeid(tmp_ctx,
                                                        server_info,
+                                                       msg,
                                                        pinfo2->printername);
 
                if (!W_ERROR_IS_OK(result)) {
@@ -1383,7 +1414,7 @@ void update_monitored_printq_cache( void )
  _spoolss_OpenPrinter
 ****************************************************************/
 
-WERROR _spoolss_OpenPrinter(pipes_struct *p,
+WERROR _spoolss_OpenPrinter(struct pipes_struct *p,
                            struct spoolss_OpenPrinter *r)
 {
        struct spoolss_OpenPrinterEx e;
@@ -1451,7 +1482,7 @@ static WERROR copy_devicemode(TALLOC_CTX *mem_ctx,
  _spoolss_OpenPrinterEx
 ****************************************************************/
 
-WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
+WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
                              struct spoolss_OpenPrinterEx *r)
 {
        int snum;
@@ -1642,6 +1673,7 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
 
                winreg_create_printer(p->mem_ctx,
                                      p->server_info,
+                                     p->msg_ctx,
                                      Printer->servername,
                                      lp_const_servicename(snum));
 
@@ -1685,7 +1717,7 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
  _spoolss_ClosePrinter
 ****************************************************************/
 
-WERROR _spoolss_ClosePrinter(pipes_struct *p,
+WERROR _spoolss_ClosePrinter(struct pipes_struct *p,
                             struct spoolss_ClosePrinter *r)
 {
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
@@ -1715,7 +1747,7 @@ WERROR _spoolss_ClosePrinter(pipes_struct *p,
  _spoolss_DeletePrinter
 ****************************************************************/
 
-WERROR _spoolss_DeletePrinter(pipes_struct *p,
+WERROR _spoolss_DeletePrinter(struct pipes_struct *p,
                              struct spoolss_DeletePrinter *r)
 {
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
@@ -1733,6 +1765,7 @@ WERROR _spoolss_DeletePrinter(pipes_struct *p,
        if (get_printer_snum(p, r->in.handle, &snum, NULL)) {
                winreg_delete_printer_key(p->mem_ctx,
                                          p->server_info,
+                                         p->msg_ctx,
                                          lp_const_servicename(snum),
                                          "");
        }
@@ -1776,7 +1809,7 @@ static int get_version_id(const char *arch)
  _spoolss_DeletePrinterDriver
 ****************************************************************/
 
-WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
+WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
                                    struct spoolss_DeletePrinterDriver *r)
 {
 
@@ -1869,7 +1902,7 @@ done:
  _spoolss_DeletePrinterDriverEx
 ****************************************************************/
 
-WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
+WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
                                      struct spoolss_DeletePrinterDriverEx *r)
 {
        struct spoolss_DriverInfo8      *info = NULL;
@@ -2022,19 +2055,6 @@ done:
 }
 
 
-/****************************************************************************
- Internal routine for storing printerdata
- ***************************************************************************/
-
-WERROR set_printer_dataex(NT_PRINTER_INFO_LEVEL *printer,
-                         const char *key, const char *value,
-                         uint32_t type, uint8_t *data, int real_len)
-{
-       /* the registry objects enforce uniqueness based on value name */
-
-       return add_printer_data( printer->info_2, key, value, type, data, real_len );
-}
-
 /********************************************************************
  GetPrinterData on a printer server Handle.
 ********************************************************************/
@@ -2179,7 +2199,7 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
  _spoolss_GetPrinterData
 ****************************************************************/
 
-WERROR _spoolss_GetPrinterData(pipes_struct *p,
+WERROR _spoolss_GetPrinterData(struct pipes_struct *p,
                               struct spoolss_GetPrinterData *r)
 {
        struct spoolss_GetPrinterDataEx r2;
@@ -2222,7 +2242,7 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
                        addr));
        }
 
-       if (ismyaddr((struct sockaddr *)&rm_addr)) {
+       if (ismyaddr((struct sockaddr *)(void *)&rm_addr)) {
                DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
                        addr));
                return false;
@@ -2271,7 +2291,8 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
                                        uint32_t localprinter, uint32_t type,
                                        struct policy_handle *handle,
-                                       struct sockaddr_storage *client_ss)
+                                       struct sockaddr_storage *client_ss,
+                                       struct messaging_context *msg_ctx)
 {
        WERROR result;
        NTSTATUS status;
@@ -2288,14 +2309,12 @@ static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
                if ( !spoolss_connect_to_client( &notify_cli_pipe, client_ss, unix_printer ))
                        return false;
 
-               messaging_register(smbd_messaging_context(), NULL,
-                                  MSG_PRINTER_NOTIFY2,
+               messaging_register(msg_ctx, NULL, MSG_PRINTER_NOTIFY2,
                                   receive_notify2_message_list);
                /* Tell the connections db we're now interested in printer
                 * notify messages. */
-               serverid_register_msg_flags(
-                       messaging_server_id(smbd_messaging_context()),
-                       true, FLAG_MSG_PRINT_NOTIFY);
+               serverid_register_msg_flags(messaging_server_id(msg_ctx),
+                                           true, FLAG_MSG_PRINT_NOTIFY);
        }
 
        /*
@@ -2384,7 +2403,7 @@ static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx
  * called from api_spoolss_rffpcnex
 ****************************************************************/
 
-WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
+WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct pipes_struct *p,
                                                     struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
 {
        int snum = -1;
@@ -2405,6 +2424,7 @@ WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
        Printer->notify.flags           = r->in.flags;
        Printer->notify.options         = r->in.options;
        Printer->notify.printerlocal    = r->in.printer_local;
+       Printer->notify.msg_ctx         = p->msg_ctx;
 
        TALLOC_FREE(Printer->notify.option);
        Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
@@ -2429,7 +2449,8 @@ WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
 
        if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
                                        Printer->notify.printerlocal, 1,
-                                       &Printer->notify.client_hnd, &client_ss))
+                                       &Printer->notify.client_hnd,
+                                       &client_ss, p->msg_ctx))
                return WERR_SERVER_UNAVAILABLE;
 
        Printer->notify.client_connected = true;
@@ -3169,7 +3190,7 @@ static bool construct_notify_jobs_info(print_queue_struct *queue,
  *
  ********************************************************************/
 
-static WERROR printserver_notify_info(pipes_struct *p,
+static WERROR printserver_notify_info(struct pipes_struct *p,
                                      struct policy_handle *hnd,
                                      struct spoolss_NotifyInfo *info,
                                      TALLOC_CTX *mem_ctx)
@@ -3213,8 +3234,9 @@ static WERROR printserver_notify_info(pipes_struct *p,
                                continue; /* skip */
                        }
 
-                       /* FIXME: should we use a SYSTEM server_info here? */
+                       /* Maybe we should use the SYSTEM server_info here... */
                        result = winreg_get_printer(mem_ctx, p->server_info,
+                                                   p->msg_ctx,
                                                    Printer->servername,
                                                    lp_servicename(snum),
                                                    &pinfo2);
@@ -3260,7 +3282,8 @@ static WERROR printserver_notify_info(pipes_struct *p,
  *
  ********************************************************************/
 
-static WERROR printer_notify_info(pipes_struct *p, struct policy_handle *hnd,
+static WERROR printer_notify_info(struct pipes_struct *p,
+                                 struct policy_handle *hnd,
                                  struct spoolss_NotifyInfo *info,
                                  TALLOC_CTX *mem_ctx)
 {
@@ -3296,8 +3319,8 @@ static WERROR printer_notify_info(pipes_struct *p, struct policy_handle *hnd,
 
        get_printer_snum(p, hnd, &snum, NULL);
 
-       /* FIXME: should we use a SYSTEM server_info here ? */
-       result = winreg_get_printer(mem_ctx, p->server_info,
+       /* Maybe we should use the SYSTEM server_info here... */
+       result = winreg_get_printer(mem_ctx, p->server_info, p->msg_ctx,
                                    Printer->servername,
                                    lp_servicename(snum), &pinfo2);
        if (!W_ERROR_IS_OK(result)) {
@@ -3357,7 +3380,7 @@ static WERROR printer_notify_info(pipes_struct *p, struct policy_handle *hnd,
  _spoolss_RouterRefreshPrinterChangeNotify
 ****************************************************************/
 
-WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
+WERROR _spoolss_RouterRefreshPrinterChangeNotify(struct pipes_struct *p,
                                                 struct spoolss_RouterRefreshPrinterChangeNotify *r)
 {
        struct spoolss_NotifyInfo *info;
@@ -3491,7 +3514,12 @@ static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
        r->number_of_processors         = 0x1;
        r->processor_type               = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
        r->high_part_total_bytes        = 0x0;
-       winreg_printer_get_changeid(mem_ctx, server_info, info2->sharename, &r->change_id); /* ChangeID in milliseconds*/
+
+       /* ChangeID in milliseconds*/
+       winreg_printer_get_changeid(mem_ctx, server_info,
+                                   smbd_messaging_context(),
+                                   info2->sharename, &r->change_id);
+
        r->last_error                   = WERR_OK;
        r->status                       = nt_printq_status(status.status);
        r->enumerate_network_printers   = 0x0;
@@ -3706,9 +3734,19 @@ static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
                                      struct spoolss_PrinterInfo7 *r,
                                      int snum)
 {
+       struct auth_serversupplied_info *server_info;
        struct GUID guid;
+       NTSTATUS status;
+
+       status = make_server_info_system(mem_ctx, &server_info);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("construct_printer_info7: "
+                         "Could not create system server_info\n"));
+               return WERR_NOMEM;
+       }
 
-       if (is_printer_published(print_hnd, snum, &guid)) {
+       if (is_printer_published(mem_ctx, server_info, print_hnd->servername,
+                                lp_servicename(snum), &guid, NULL)) {
                r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
                r->action = DSPRINT_PUBLISH;
        } else {
@@ -3717,6 +3755,7 @@ static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
        }
        W_ERROR_HAVE_NO_MEMORY(r->guid);
 
+       TALLOC_FREE(server_info);
        return WERR_OK;
 }
 
@@ -3783,6 +3822,7 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
 
                result = winreg_create_printer(mem_ctx,
                                               server_info,
+                                              smbd_messaging_context(),
                                               NULL,
                                               printer);
                if (!W_ERROR_IS_OK(result)) {
@@ -3798,6 +3838,7 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
                }
 
                result = winreg_get_printer(mem_ctx, server_info,
+                                           smbd_messaging_context(),
                                            NULL, printer, &info2);
                if (!W_ERROR_IS_OK(result)) {
                        goto out;
@@ -4065,7 +4106,7 @@ static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
  _spoolss_EnumPrinters
 ****************************************************************/
 
-WERROR _spoolss_EnumPrinters(pipes_struct *p,
+WERROR _spoolss_EnumPrinters(struct pipes_struct *p,
                             struct spoolss_EnumPrinters *r)
 {
        const char *name = NULL;
@@ -4149,7 +4190,7 @@ WERROR _spoolss_EnumPrinters(pipes_struct *p,
  _spoolss_GetPrinter
 ****************************************************************/
 
-WERROR _spoolss_GetPrinter(pipes_struct *p,
+WERROR _spoolss_GetPrinter(struct pipes_struct *p,
                           struct spoolss_GetPrinter *r)
 {
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
@@ -4176,6 +4217,7 @@ WERROR _spoolss_GetPrinter(pipes_struct *p,
 
        result = winreg_get_printer(p->mem_ctx,
                                    p->server_info,
+                                   p->msg_ctx,
                                    servername,
                                    lp_const_servicename(snum),
                                    &info2);
@@ -4244,30 +4286,52 @@ WERROR _spoolss_GetPrinter(pipes_struct *p,
 /********************************************************************
  ********************************************************************/
 
-static const char **string_array_from_driver_info(TALLOC_CTX *mem_ctx,
+#define FILL_DRIVER_STRING(mem_ctx, in, out) \
+       do { \
+               if (in && strlen(in)) { \
+                       out = talloc_strdup(mem_ctx, in); \
+               } else { \
+                       out = talloc_strdup(mem_ctx, ""); \
+               } \
+               W_ERROR_HAVE_NO_MEMORY(out); \
+       } while (0);
+
+#define FILL_DRIVER_UNC_STRING(mem_ctx, server, arch, ver, in, out) \
+       do { \
+               if (in && strlen(in)) { \
+                       out = talloc_asprintf(mem_ctx, "\\\\%s\\print$\\%s\\%d\\%s", server, get_short_archi(arch), ver, in); \
+               } else { \
+                       out = talloc_strdup(mem_ctx, ""); \
+               } \
+               W_ERROR_HAVE_NO_MEMORY(out); \
+       } while (0);
+
+static WERROR string_array_from_driver_info(TALLOC_CTX *mem_ctx,
                                                  const char **string_array,
-                                                 const char *cservername)
+                                                 const char ***presult,
+                                                 const char *cservername,
+                                                 const char *arch,
+                                                 int version)
 {
        int i, num_strings = 0;
        const char **array = NULL;
 
-       if (!string_array) {
-               return NULL;
+       if (string_array == NULL) {
+               return WERR_INVALID_PARAMETER;;
        }
 
        for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
+               const char *str = NULL;
 
-               const char *str = talloc_asprintf(mem_ctx, "\\\\%s%s",
-                                                 cservername, string_array[i]);
-               if (!str) {
-                       TALLOC_FREE(array);
-                       return NULL;
+               if (cservername == NULL || arch == NULL) {
+                       FILL_DRIVER_STRING(mem_ctx, string_array[i], str);
+               } else {
+                       FILL_DRIVER_UNC_STRING(mem_ctx, cservername, arch, version, string_array[i], str);
                }
 
-
                if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
                        TALLOC_FREE(array);
-                       return NULL;
+                       return WERR_NOMEM;
                }
        }
 
@@ -4276,28 +4340,12 @@ static const char **string_array_from_driver_info(TALLOC_CTX *mem_ctx,
                             &array, &num_strings);
        }
 
-       return array;
-}
-
-#define FILL_DRIVER_STRING(mem_ctx, in, out) \
-       do { \
-               if (in && strlen(in)) { \
-                       out = talloc_strdup(mem_ctx, in); \
-                       W_ERROR_HAVE_NO_MEMORY(out); \
-               } else { \
-                       out = NULL; \
-               } \
-       } while (0);
+       if (presult) {
+               *presult = array;
+       }
 
-#define FILL_DRIVER_UNC_STRING(mem_ctx, server, in, out) \
-       do { \
-               if (in && strlen(in)) { \
-                       out = talloc_asprintf(mem_ctx, "\\\\%s%s", server, in); \
-               } else { \
-                       out = talloc_strdup(mem_ctx, ""); \
-               } \
-               W_ERROR_HAVE_NO_MEMORY(out); \
-       } while (0);
+       return WERR_OK;
+}
 
 /********************************************************************
  * fill a spoolss_DriverInfo1 struct
@@ -4334,14 +4382,20 @@ static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->driver_path,
                               r->driver_path);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->data_file,
                               r->data_file);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->config_file,
                               r->config_file);
 
@@ -4367,18 +4421,26 @@ static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->driver_path,
                               r->driver_path);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->data_file,
                               r->data_file);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->config_file,
                               r->config_file);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->help_file,
                               r->help_file);
 
@@ -4390,10 +4452,12 @@ static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
                           driver->default_datatype,
                           r->default_datatype);
 
-       r->dependent_files = string_array_from_driver_info(mem_ctx,
-                                                          driver->dependent_files,
-                                                          cservername);
-       return WERR_OK;
+       return string_array_from_driver_info(mem_ctx,
+                                            driver->dependent_files,
+                                            &r->dependent_files,
+                                            cservername,
+                                            driver->architecture,
+                                            driver->version);
 }
 
 /********************************************************************
@@ -4406,6 +4470,7 @@ static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
                                        const char *servername)
 {
        const char *cservername = canon_servername(servername);
+       WERROR result;
 
        r->version              = driver->version;
 
@@ -4415,24 +4480,38 @@ static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->driver_path,
                               r->driver_path);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->data_file,
                               r->data_file);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->config_file,
                               r->config_file);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->help_file,
                               r->help_file);
 
-       r->dependent_files = string_array_from_driver_info(mem_ctx,
-                                                          driver->dependent_files,
-                                                          cservername);
+       result = string_array_from_driver_info(mem_ctx,
+                                              driver->dependent_files,
+                                              &r->dependent_files,
+                                              cservername,
+                                              driver->architecture,
+                                              driver->version);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
 
        FILL_DRIVER_STRING(mem_ctx,
                           driver->monitor_name,
@@ -4442,11 +4521,13 @@ static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
                           driver->default_datatype,
                           r->default_datatype);
 
-       r->previous_names = string_array_from_driver_info(mem_ctx,
-                                                         driver->previous_names,
-                                                         cservername);
 
-       return WERR_OK;
+       result = string_array_from_driver_info(mem_ctx,
+                                              driver->previous_names,
+                                              &r->previous_names,
+                                              NULL, NULL, 0);
+
+       return result;
 }
 
 /********************************************************************
@@ -4468,14 +4549,20 @@ static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->driver_path,
                               r->driver_path);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->data_file,
                               r->data_file);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->config_file,
                               r->config_file);
 
@@ -4495,6 +4582,7 @@ static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
                                        const char *servername)
 {
        const char *cservername = canon_servername(servername);
+       WERROR result;
 
        r->version              = driver->version;
 
@@ -4504,18 +4592,26 @@ static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->driver_path,
                               r->driver_path);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->data_file,
                               r->data_file);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->config_file,
                               r->config_file);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->help_file,
                               r->help_file);
 
@@ -4527,12 +4623,23 @@ static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
                           driver->default_datatype,
                           r->default_datatype);
 
-       r->dependent_files = string_array_from_driver_info(mem_ctx,
-                                                          driver->dependent_files,
-                                                          cservername);
-       r->previous_names = string_array_from_driver_info(mem_ctx,
-                                                         driver->previous_names,
-                                                         cservername);
+       result = string_array_from_driver_info(mem_ctx,
+                                              driver->dependent_files,
+                                              &r->dependent_files,
+                                              cservername,
+                                              driver->architecture,
+                                              driver->version);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
+       result = string_array_from_driver_info(mem_ctx,
+                                              driver->previous_names,
+                                              &r->previous_names,
+                                              NULL, NULL, 0);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
 
        r->driver_date          = driver->driver_date;
        r->driver_version       = driver->driver_version;
@@ -4563,6 +4670,7 @@ static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
                                        const char *servername)
 {
        const char *cservername = canon_servername(servername);
+       WERROR result;
 
        r->version              = driver->version;
 
@@ -4572,18 +4680,26 @@ static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->driver_path,
                               r->driver_path);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->data_file,
                               r->data_file);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->config_file,
                               r->config_file);
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
+                              driver->architecture,
+                              driver->version,
                               driver->help_file,
                               r->help_file);
 
@@ -4595,12 +4711,23 @@ static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
                           driver->default_datatype,
                           r->default_datatype);
 
-       r->dependent_files = string_array_from_driver_info(mem_ctx,
-                                                          driver->dependent_files,
-                                                          cservername);
-       r->previous_names = string_array_from_driver_info(mem_ctx,
-                                                         driver->previous_names,
-                                                         cservername);
+       result = string_array_from_driver_info(mem_ctx,
+                                              driver->dependent_files,
+                                              &r->dependent_files,
+                                              cservername,
+                                              driver->architecture,
+                                              driver->version);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
+       result = string_array_from_driver_info(mem_ctx,
+                                              driver->previous_names,
+                                              &r->previous_names,
+                                              NULL, NULL, 0);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
 
        r->driver_date          = driver->driver_date;
        r->driver_version       = driver->driver_version;
@@ -4625,9 +4752,13 @@ static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
                           driver->vendor_setup,
                           r->vendor_setup);
 
-       r->color_profiles = string_array_from_driver_info(mem_ctx,
-                                                         driver->color_profiles,
-                                                         cservername);
+       result = string_array_from_driver_info(mem_ctx,
+                                              driver->color_profiles,
+                                              &r->color_profiles,
+                                              NULL, NULL, 0);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
 
        FILL_DRIVER_STRING(mem_ctx,
                           driver->inf_path,
@@ -4635,9 +4766,13 @@ static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
 
        r->printer_driver_attributes    = driver->printer_driver_attributes;
 
-       r->core_driver_dependencies = string_array_from_driver_info(mem_ctx,
-                                                                   driver->core_driver_dependencies,
-                                                                   cservername);
+       result = string_array_from_driver_info(mem_ctx,
+                                              driver->core_driver_dependencies,
+                                              &r->core_driver_dependencies,
+                                              NULL, NULL, 0);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
 
        r->min_inbox_driver_ver_date    = driver->min_inbox_driver_ver_date;
        r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
@@ -4798,9 +4933,14 @@ static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
                           driver->default_datatype,
                           r->default_datatype);
 
-       r->previous_names = string_array_from_driver_info(mem_ctx,
-                                                         driver->previous_names,
-                                                         cservername);
+       result = string_array_from_driver_info(mem_ctx,
+                                              driver->previous_names,
+                                              &r->previous_names,
+                                              NULL, NULL, 0);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
        r->driver_date          = driver->driver_date;
        r->driver_version       = driver->driver_version;
 
@@ -4838,6 +4978,7 @@ static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
 
        result = winreg_get_printer(mem_ctx,
                                    server_info,
+                                   smbd_messaging_context(),
                                    servername,
                                    lp_const_servicename(snum),
                                    &pinfo2);
@@ -4920,13 +5061,12 @@ static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
  _spoolss_GetPrinterDriver2
 ****************************************************************/
 
-WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
+WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p,
                                  struct spoolss_GetPrinterDriver2 *r)
 {
        Printer_entry *printer;
        WERROR result;
 
-       const char *servername;
        int snum;
 
        /* that's an [in out] buffer */
@@ -4946,15 +5086,13 @@ WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
        *r->out.server_major_version = 0;
        *r->out.server_minor_version = 0;
 
-       servername = get_server_name(printer);
-
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
                return WERR_BADFID;
        }
 
        result = construct_printer_driver_info_level(p->mem_ctx, p->server_info,
                                                     r->in.level, r->out.info,
-                                                    snum, servername,
+                                                    snum, printer->servername,
                                                     r->in.architecture,
                                                     r->in.client_major_version);
        if (!W_ERROR_IS_OK(result)) {
@@ -4974,7 +5112,7 @@ WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
  _spoolss_StartPagePrinter
 ****************************************************************/
 
-WERROR _spoolss_StartPagePrinter(pipes_struct *p,
+WERROR _spoolss_StartPagePrinter(struct pipes_struct *p,
                                 struct spoolss_StartPagePrinter *r)
 {
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
@@ -4993,7 +5131,7 @@ WERROR _spoolss_StartPagePrinter(pipes_struct *p,
  _spoolss_EndPagePrinter
 ****************************************************************/
 
-WERROR _spoolss_EndPagePrinter(pipes_struct *p,
+WERROR _spoolss_EndPagePrinter(struct pipes_struct *p,
                               struct spoolss_EndPagePrinter *r)
 {
        int snum;
@@ -5019,12 +5157,13 @@ WERROR _spoolss_EndPagePrinter(pipes_struct *p,
  _spoolss_StartDocPrinter
 ****************************************************************/
 
-WERROR _spoolss_StartDocPrinter(pipes_struct *p,
+WERROR _spoolss_StartDocPrinter(struct pipes_struct *p,
                                struct spoolss_StartDocPrinter *r)
 {
        struct spoolss_DocumentInfo1 *info_1;
        int snum;
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
+       WERROR werr;
 
        if (!Printer) {
                DEBUG(2,("_spoolss_StartDocPrinter: "
@@ -5033,6 +5172,13 @@ WERROR _spoolss_StartDocPrinter(pipes_struct *p,
                return WERR_BADFID;
        }
 
+       if (Printer->jobid) {
+               DEBUG(2, ("_spoolss_StartDocPrinter: "
+                         "StartDocPrinter called twice! "
+                         "(existing jobid = %d)\n", Printer->jobid));
+               return WERR_INVALID_HANDLE;
+       }
+
        if (r->in.level != 1) {
                return WERR_UNKNOWN_LEVEL;
        }
@@ -5059,15 +5205,15 @@ WERROR _spoolss_StartDocPrinter(pipes_struct *p,
                return WERR_BADFID;
        }
 
-       Printer->jobid = print_job_start(p->server_info, snum,
-                                        info_1->document_name,
-                                        Printer->devmode);
+       werr = print_job_start(p->server_info, snum,
+                               info_1->document_name, info_1->output_file,
+                               Printer->devmode, &Printer->jobid);
 
        /* An error occured in print_job_start() so return an appropriate
           NT error code. */
 
-       if (Printer->jobid == -1) {
-               return map_werror_from_unix(errno);
+       if (!W_ERROR_IS_OK(werr)) {
+               return werr;
        }
 
        Printer->document_started = true;
@@ -5080,10 +5226,11 @@ WERROR _spoolss_StartDocPrinter(pipes_struct *p,
  _spoolss_EndDocPrinter
 ****************************************************************/
 
-WERROR _spoolss_EndDocPrinter(pipes_struct *p,
+WERROR _spoolss_EndDocPrinter(struct pipes_struct *p,
                              struct spoolss_EndDocPrinter *r)
 {
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
+       NTSTATUS status;
        int snum;
 
        if (!Printer) {
@@ -5097,17 +5244,22 @@ WERROR _spoolss_EndDocPrinter(pipes_struct *p,
        }
 
        Printer->document_started = false;
-       print_job_end(snum, Printer->jobid, NORMAL_CLOSE);
-       /* error codes unhandled so far ... */
+       status = print_job_end(snum, Printer->jobid, NORMAL_CLOSE);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(2, ("_spoolss_EndDocPrinter: "
+                         "print_job_end failed [%s]\n",
+                         nt_errstr(status)));
+       }
 
-       return WERR_OK;
+       Printer->jobid = 0;
+       return ntstatus_to_werror(status);
 }
 
 /****************************************************************
  _spoolss_WritePrinter
 ****************************************************************/
 
-WERROR _spoolss_WritePrinter(pipes_struct *p,
+WERROR _spoolss_WritePrinter(struct pipes_struct *p,
                             struct spoolss_WritePrinter *r)
 {
        ssize_t buffer_written;
@@ -5124,6 +5276,7 @@ WERROR _spoolss_WritePrinter(pipes_struct *p,
        if (!get_printer_snum(p, r->in.handle, &snum, NULL))
                return WERR_BADFID;
 
+       /* print_job_write takes care of checking for PJOB_SMBD_SPOOLING */
        buffer_written = print_job_write(snum, Printer->jobid,
                                                   (const char *)r->in.data.data,
                                                   (SMB_OFF_T)-1,
@@ -5148,7 +5301,7 @@ WERROR _spoolss_WritePrinter(pipes_struct *p,
  ********************************************************************/
 
 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
-                             pipes_struct *p)
+                             struct pipes_struct *p)
 {
        int snum;
        WERROR errcode = WERR_BADFUNC;
@@ -5188,7 +5341,7 @@ static WERROR control_printer(struct policy_handle *handle, uint32_t command,
  * for spooling"
 ****************************************************************/
 
-WERROR _spoolss_AbortPrinter(pipes_struct *p,
+WERROR _spoolss_AbortPrinter(struct pipes_struct *p,
                             struct spoolss_AbortPrinter *r)
 {
        Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
@@ -5204,7 +5357,11 @@ WERROR _spoolss_AbortPrinter(pipes_struct *p,
        if (!get_printer_snum(p, r->in.handle, &snum, NULL))
                return WERR_BADFID;
 
-       print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
+       if (!Printer->document_started) {
+               return WERR_SPL_NO_STARTDOC;
+       }
+
+       errcode = print_job_delete(p->server_info, snum, Printer->jobid);
 
        return errcode;
 }
@@ -5215,7 +5372,8 @@ WERROR _spoolss_AbortPrinter(pipes_struct *p,
  ********************************************************************/
 
 static WERROR update_printer_sec(struct policy_handle *handle,
-                                pipes_struct *p, struct sec_desc_buf *secdesc_ctr)
+                                struct pipes_struct *p,
+                                struct sec_desc_buf *secdesc_ctr)
 {
        struct spoolss_security_descriptor *new_secdesc = NULL;
        struct spoolss_security_descriptor *old_secdesc = NULL;
@@ -5255,6 +5413,7 @@ static WERROR update_printer_sec(struct policy_handle *handle,
           nothing may have actually changed. */
        result = winreg_get_printer_secdesc(p->mem_ctx,
                                            p->server_info,
+                                           p->msg_ctx,
                                            printer,
                                            &old_secdesc);
        if (!W_ERROR_IS_OK(result)) {
@@ -5267,7 +5426,7 @@ static WERROR update_printer_sec(struct policy_handle *handle,
                struct security_acl *the_acl;
                int i;
 
-               the_acl = secdesc_ctr->sd->dacl;
+               the_acl = old_secdesc->dacl;
                DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
                           printer, the_acl->num_aces));
 
@@ -5306,6 +5465,7 @@ static WERROR update_printer_sec(struct policy_handle *handle,
 
        result = winreg_set_printer_secdesc(p->mem_ctx,
                                            p->server_info,
+                                           p->msg_ctx,
                                            printer,
                                            new_secdesc);
 
@@ -5315,11 +5475,6 @@ static WERROR update_printer_sec(struct policy_handle *handle,
 
 /********************************************************************
  Canonicalize printer info from a client
-
- ATTN: It does not matter what we set the servername to hear
- since we do the necessary work in get_a_printer() to set it to
- the correct value based on what the client sent in the
- _spoolss_open_printer_ex().
  ********************************************************************/
 
 static bool check_printer_ok(TALLOC_CTX *mem_ctx,
@@ -5423,8 +5578,10 @@ static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *p
 /****************************************************************************
 ****************************************************************************/
 
-bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
-                     struct spoolss_SetPrinterInfo2 *info2)
+static bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
+                            struct spoolss_SetPrinterInfo2 *info2,
+                            const char *remote_machine,
+                            struct messaging_context *msg_ctx)
 {
        char *cmd = lp_addprinter_cmd();
        char **qlines;
@@ -5434,18 +5591,10 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
        int fd;
        SE_PRIV se_printop = SE_PRINT_OPERATOR;
        bool is_print_op = false;
-       char *remote_machine = talloc_strdup(ctx, "%m");
 
        if (!remote_machine) {
                return false;
        }
-       remote_machine = talloc_sub_basic(ctx,
-                               current_user_info.smb_name,
-                               current_user_info.domain,
-                               remote_machine);
-       if (!remote_machine) {
-               return false;
-       }
 
        command = talloc_asprintf(ctx,
                        "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
@@ -5468,8 +5617,7 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
 
        if ( (ret = smbrun(command, &fd)) == 0 ) {
                /* Tell everyone we updated smb.conf. */
-               message_send_all(smbd_messaging_context(),
-                                MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
+               message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
        }
 
        if ( is_print_op )
@@ -5480,7 +5628,6 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
        DEBUGADD(10,("returned [%d]\n", ret));
 
        TALLOC_FREE(command);
-       TALLOC_FREE(remote_machine);
 
        if ( ret != 0 ) {
                if (fd != -1)
@@ -5512,221 +5659,381 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
        return true;
 }
 
-
-/********************************************************************
- * Called by spoolss_api_setprinter
- * when updating a printer description.
- ********************************************************************/
-
-static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
-                            struct spoolss_SetPrinterInfoCtr *info_ctr,
-                            struct spoolss_DeviceMode *devmode)
+static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
+                              struct auth_serversupplied_info *server_info,
+                              int snum,
+                              struct spoolss_SetPrinterInfo2 *printer,
+                              struct spoolss_PrinterInfo2 *old_printer)
 {
-       uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
-       struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
-       struct spoolss_PrinterInfo2 *old_printer;
-       Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
-       const char *servername = NULL;
-       int snum;
-       WERROR result;
+       bool force_update = (old_printer == NULL);
+       const char *dnsdomname;
+       const char *longname;
+       const char *uncname;
+       const char *spooling;
        DATA_BLOB buffer;
-       fstring asc_buffer;
+       WERROR result = WERR_OK;
 
-       DEBUG(8,("update_printer\n"));
+       if (force_update || !strequal(printer->drivername, old_printer->drivername)) {
+               push_reg_sz(mem_ctx, &buffer, printer->drivername);
+               winreg_set_printer_dataex(mem_ctx,
+                                         server_info,
+                                         smbd_messaging_context(),
+                                         printer->sharename,
+                                         SPOOL_DSSPOOLER_KEY,
+                                         SPOOL_REG_DRIVERNAME,
+                                         REG_SZ,
+                                         buffer.data,
+                                         buffer.length);
 
-       result = WERR_OK;
+               if (!force_update) {
+                       DEBUG(10,("update_printer: changing driver [%s]!  Sending event!\n",
+                               printer->drivername));
 
-       if (!Printer) {
-               result = WERR_BADFID;
-               goto done;
+                       notify_printer_driver(snum, printer->drivername);
+               }
        }
 
-       if (!get_printer_snum(p, handle, &snum, NULL)) {
-               result = WERR_BADFID;
-               goto done;
-       }
+       if (force_update || !strequal(printer->comment, old_printer->comment)) {
+               push_reg_sz(mem_ctx, &buffer, printer->comment);
+               winreg_set_printer_dataex(mem_ctx,
+                                         server_info,
+                                         smbd_messaging_context(),
+                                         printer->sharename,
+                                         SPOOL_DSSPOOLER_KEY,
+                                         SPOOL_REG_DESCRIPTION,
+                                         REG_SZ,
+                                         buffer.data,
+                                         buffer.length);
 
-       if (Printer != NULL || Printer->servername != NULL) {
-               servername = Printer->servername;
+               if (!force_update) {
+                       notify_printer_comment(snum, printer->comment);
+               }
        }
 
-       result = winreg_get_printer(p->mem_ctx,
-                                   p->server_info,
-                                   servername,
-                                   lp_const_servicename(snum),
-                                   &old_printer);
-       if (!W_ERROR_IS_OK(result)) {
-               result = WERR_BADFID;
-               goto done;
-       }
+       if (force_update || !strequal(printer->sharename, old_printer->sharename)) {
+               push_reg_sz(mem_ctx, &buffer, printer->sharename);
+               winreg_set_printer_dataex(mem_ctx,
+                                         server_info,
+                                         smbd_messaging_context(),
+                                         printer->sharename,
+                                         SPOOL_DSSPOOLER_KEY,
+                                         SPOOL_REG_PRINTSHARENAME,
+                                         REG_SZ,
+                                         buffer.data,
+                                         buffer.length);
 
-       /* Do sanity check on the requested changes for Samba */
-       if (!check_printer_ok(p->mem_ctx, printer, snum)) {
-               result = WERR_INVALID_PARAM;
-               goto done;
+               if (!force_update) {
+                       notify_printer_sharename(snum, printer->sharename);
+               }
        }
 
-       /* FIXME!!! If the driver has changed we really should verify that
-          it is installed before doing much else   --jerry */
+       if (force_update || !strequal(printer->printername, old_printer->printername)) {
+               const char *p;
 
-       /* Check calling user has permission to update printer description */
-       if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
-               DEBUG(3, ("update_printer: printer property change denied by handle\n"));
-               result = WERR_ACCESS_DENIED;
-               goto done;
-       }
+               p = strrchr(printer->printername, '\\' );
+               if (p != NULL) {
+                       p++;
+               } else {
+                       p = printer->printername;
+               }
 
-       /* Call addprinter hook */
-       /* Check changes to see if this is really needed */
+               push_reg_sz(mem_ctx, &buffer, p);
+               winreg_set_printer_dataex(mem_ctx,
+                                         server_info,
+                                         smbd_messaging_context(),
+                                         printer->sharename,
+                                         SPOOL_DSSPOOLER_KEY,
+                                         SPOOL_REG_PRINTERNAME,
+                                         REG_SZ,
+                                         buffer.data,
+                                         buffer.length);
 
-       if (*lp_addprinter_cmd() &&
-                       (!strequal(printer->drivername, old_printer->drivername) ||
-                        !strequal(printer->comment, old_printer->comment) ||
-                        !strequal(printer->portname, old_printer->portname) ||
-                        !strequal(printer->location, old_printer->location)) )
-       {
-               /* add_printer_hook() will call reload_services() */
-               if (!add_printer_hook(p->mem_ctx, p->server_info->ptok,
-                                     printer) ) {
-                       result = WERR_ACCESS_DENIED;
-                       goto done;
+               if (!force_update) {
+                       notify_printer_printername(snum, p);
                }
        }
 
-       /*
-        * When a *new* driver is bound to a printer, the drivername is used to
-        * lookup previously saved driver initialization info, which is then
-        * bound to the printer, simulating what happens in the Windows arch.
-        */
-       if (!strequal(printer->drivername, old_printer->drivername)) {
-               DEBUG(10,("update_printer: changing driver [%s]!  Sending event!\n",
-                       printer->drivername));
+       if (force_update || !strequal(printer->portname, old_printer->portname)) {
+               push_reg_sz(mem_ctx, &buffer, printer->portname);
+               winreg_set_printer_dataex(mem_ctx,
+                                         server_info,
+                                         smbd_messaging_context(),
+                                         printer->sharename,
+                                         SPOOL_DSSPOOLER_KEY,
+                                         SPOOL_REG_PORTNAME,
+                                         REG_SZ,
+                                         buffer.data,
+                                         buffer.length);
 
-               notify_printer_driver(snum, printer->drivername);
+               if (!force_update) {
+                       notify_printer_port(snum, printer->portname);
+               }
        }
 
-       /*
-        * flag which changes actually occured.  This is a small subset of
-        * all the possible changes.  We also have to update things in the
-        * DsSpooler key.
-        */
-       if (!strequal(printer->comment, old_printer->comment)) {
-               push_reg_sz(talloc_tos(), &buffer, printer->comment);
-               winreg_set_printer_dataex(p->mem_ctx,
-                                         p->server_info,
+       if (force_update || !strequal(printer->location, old_printer->location)) {
+               push_reg_sz(mem_ctx, &buffer, printer->location);
+               winreg_set_printer_dataex(mem_ctx,
+                                         server_info,
+                                         smbd_messaging_context(),
                                          printer->sharename,
                                          SPOOL_DSSPOOLER_KEY,
-                                         "description",
+                                         SPOOL_REG_LOCATION,
                                          REG_SZ,
                                          buffer.data,
                                          buffer.length);
 
-               notify_printer_comment(snum, printer->comment);
+               if (!force_update) {
+                       notify_printer_location(snum, printer->location);
+               }
        }
 
-       if (!strequal(printer->sharename, old_printer->sharename)) {
-               push_reg_sz(talloc_tos(), &buffer, printer->sharename);
-               winreg_set_printer_dataex(p->mem_ctx,
-                                         p->server_info,
+       if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) {
+               push_reg_sz(mem_ctx, &buffer, printer->sepfile);
+               winreg_set_printer_dataex(mem_ctx,
+                                         server_info,
+                                         smbd_messaging_context(),
                                          printer->sharename,
                                          SPOOL_DSSPOOLER_KEY,
-                                         "shareName",
+                                         SPOOL_REG_PRINTSEPARATORFILE,
                                          REG_SZ,
                                          buffer.data,
                                          buffer.length);
 
-               notify_printer_sharename(snum, printer->sharename);
+               if (!force_update) {
+                       notify_printer_location(snum, printer->location);
+               }
        }
 
-       if (!strequal(printer->printername, old_printer->printername)) {
-               const char *pname;
-
-               if ( (pname = strchr_m( printer->printername+2, '\\' )) != NULL )
-                       pname++;
-               else
-                       pname = printer->printername;
-
-               push_reg_sz(talloc_tos(), &buffer, pname);
-               winreg_set_printer_dataex(p->mem_ctx,
-                                         p->server_info,
+       if (force_update || printer->starttime != old_printer->starttime) {
+               buffer = data_blob_talloc(mem_ctx, NULL, 4);
+               SIVAL(buffer.data, 0, printer->starttime);
+               winreg_set_printer_dataex(mem_ctx,
+                                         server_info,
+                                         smbd_messaging_context(),
                                          printer->sharename,
                                          SPOOL_DSSPOOLER_KEY,
-                                         "printerName",
-                                         REG_SZ,
+                                         SPOOL_REG_PRINTSTARTTIME,
+                                         REG_DWORD,
                                          buffer.data,
                                          buffer.length);
-
-               notify_printer_printername( snum, pname );
        }
 
-       if (!strequal(printer->portname, old_printer->portname)) {
-               push_reg_sz(talloc_tos(), &buffer, printer->portname);
-               winreg_set_printer_dataex(p->mem_ctx,
-                                         p->server_info,
+       if (force_update || printer->untiltime != old_printer->untiltime) {
+               buffer = data_blob_talloc(mem_ctx, NULL, 4);
+               SIVAL(buffer.data, 0, printer->untiltime);
+               winreg_set_printer_dataex(mem_ctx,
+                                         server_info,
+                                         smbd_messaging_context(),
                                          printer->sharename,
                                          SPOOL_DSSPOOLER_KEY,
-                                         "portName",
-                                         REG_SZ,
+                                         SPOOL_REG_PRINTENDTIME,
+                                         REG_DWORD,
                                          buffer.data,
                                          buffer.length);
+       }
 
-               notify_printer_port(snum, printer->portname);
+       if (force_update || printer->priority != old_printer->priority) {
+               buffer = data_blob_talloc(mem_ctx, NULL, 4);
+               SIVAL(buffer.data, 0, printer->priority);
+               winreg_set_printer_dataex(mem_ctx,
+                                         server_info,
+                                         smbd_messaging_context(),
+                                         printer->sharename,
+                                         SPOOL_DSSPOOLER_KEY,
+                                         SPOOL_REG_PRIORITY,
+                                         REG_DWORD,
+                                         buffer.data,
+                                         buffer.length);
        }
 
-       if (!strequal(printer->location, old_printer->location)) {
-               push_reg_sz(talloc_tos(), &buffer, printer->location);
-               winreg_set_printer_dataex(p->mem_ctx,
-                                         p->server_info,
+       if (force_update || printer->attributes != old_printer->attributes) {
+               buffer = data_blob_talloc(mem_ctx, NULL, 4);
+               SIVAL(buffer.data, 0, (printer->attributes &
+                                      PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
+               winreg_set_printer_dataex(mem_ctx,
+                                         server_info,
+                                         smbd_messaging_context(),
                                          printer->sharename,
                                          SPOOL_DSSPOOLER_KEY,
-                                         "location",
-                                         REG_SZ,
+                                         SPOOL_REG_PRINTKEEPPRINTEDJOBS,
+                                         REG_DWORD,
                                          buffer.data,
                                          buffer.length);
 
-               notify_printer_location(snum, printer->location);
+               switch (printer->attributes & 0x3) {
+                       case 0:
+                               spooling = SPOOL_REGVAL_PRINTWHILESPOOLING;
+                               break;
+                       case 1:
+                               spooling = SPOOL_REGVAL_PRINTAFTERSPOOLED;
+                               break;
+                       case 2:
+                               spooling = SPOOL_REGVAL_PRINTDIRECT;
+                               break;
+                       default:
+                               spooling = "unknown";
+               }
+               push_reg_sz(mem_ctx, &buffer, spooling);
+               winreg_set_printer_dataex(mem_ctx,
+                                         server_info,
+                                         smbd_messaging_context(),
+                                         printer->sharename,
+                                         SPOOL_DSSPOOLER_KEY,
+                                         SPOOL_REG_PRINTSPOOLING,
+                                         REG_SZ,
+                                         buffer.data,
+                                         buffer.length);
        }
 
-       /* here we need to update some more DsSpooler keys */
-       /* uNCName, serverName, shortServerName */
-
-       push_reg_sz(talloc_tos(), &buffer, global_myname());
-       winreg_set_printer_dataex(p->mem_ctx,
-                                 p->server_info,
+       push_reg_sz(mem_ctx, &buffer, global_myname());
+       winreg_set_printer_dataex(mem_ctx,
+                                 server_info,
+                                 smbd_messaging_context(),
                                  printer->sharename,
                                  SPOOL_DSSPOOLER_KEY,
-                                 "serverName",
+                                 SPOOL_REG_SHORTSERVERNAME,
                                  REG_SZ,
                                  buffer.data,
                                  buffer.length);
-       winreg_set_printer_dataex(p->mem_ctx,
-                                 p->server_info,
+
+       dnsdomname = get_mydnsfullname();
+       if (dnsdomname != NULL && dnsdomname[0] != '\0') {
+               longname = talloc_strdup(mem_ctx, dnsdomname);
+       } else {
+               longname = talloc_strdup(mem_ctx, global_myname());
+       }
+       if (longname == NULL) {
+               result = WERR_NOMEM;
+               goto done;
+       }
+
+       push_reg_sz(mem_ctx, &buffer, longname);
+       winreg_set_printer_dataex(mem_ctx,
+                                 server_info,
+                                 smbd_messaging_context(),
                                  printer->sharename,
                                  SPOOL_DSSPOOLER_KEY,
-                                 "shortServerName",
+                                 SPOOL_REG_SERVERNAME,
                                  REG_SZ,
                                  buffer.data,
                                  buffer.length);
 
-       slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
-                 global_myname(), printer->sharename );
-       push_reg_sz(talloc_tos(), &buffer, asc_buffer);
-       winreg_set_printer_dataex(p->mem_ctx,
-                                 p->server_info,
+       uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
+                                 global_myname(), printer->sharename);
+       push_reg_sz(mem_ctx, &buffer, uncname);
+       winreg_set_printer_dataex(mem_ctx,
+                                 server_info,
+                                 smbd_messaging_context(),
                                  printer->sharename,
                                  SPOOL_DSSPOOLER_KEY,
-                                 "uNCName",
+                                 SPOOL_REG_UNCNAME,
                                  REG_SZ,
                                  buffer.data,
                                  buffer.length);
 
+done:
+       return result;
+}
+
+/********************************************************************
+ * Called by spoolss_api_setprinter
+ * when updating a printer description.
+ ********************************************************************/
+
+static WERROR update_printer(struct pipes_struct *p,
+                            struct policy_handle *handle,
+                            struct spoolss_SetPrinterInfoCtr *info_ctr,
+                            struct spoolss_DeviceMode *devmode)
+{
+       uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
+       struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
+       struct spoolss_PrinterInfo2 *old_printer;
+       Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+       const char *servername = NULL;
+       int snum;
+       WERROR result = WERR_OK;
+       TALLOC_CTX *tmp_ctx;
+
+       DEBUG(8,("update_printer\n"));
+
+       tmp_ctx = talloc_new(p->mem_ctx);
+       if (tmp_ctx == NULL) {
+               return WERR_NOMEM;
+       }
+
+       if (!Printer) {
+               result = WERR_BADFID;
+               goto done;
+       }
+
+       if (!get_printer_snum(p, handle, &snum, NULL)) {
+               result = WERR_BADFID;
+               goto done;
+       }
+
+       if (Printer != NULL || Printer->servername != NULL) {
+               servername = Printer->servername;
+       }
+
+       result = winreg_get_printer(tmp_ctx,
+                                   p->server_info,
+                                   p->msg_ctx,
+                                   servername,
+                                   lp_const_servicename(snum),
+                                   &old_printer);
+       if (!W_ERROR_IS_OK(result)) {
+               result = WERR_BADFID;
+               goto done;
+       }
+
+       /* Do sanity check on the requested changes for Samba */
+       if (!check_printer_ok(tmp_ctx, printer, snum)) {
+               result = WERR_INVALID_PARAM;
+               goto done;
+       }
+
+       /* FIXME!!! If the driver has changed we really should verify that
+          it is installed before doing much else   --jerry */
+
+       /* Check calling user has permission to update printer description */
+       if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
+               DEBUG(3, ("update_printer: printer property change denied by handle\n"));
+               result = WERR_ACCESS_DENIED;
+               goto done;
+       }
+
+       /* Call addprinter hook */
+       /* Check changes to see if this is really needed */
+
+       if (*lp_addprinter_cmd() &&
+                       (!strequal(printer->drivername, old_printer->drivername) ||
+                        !strequal(printer->comment, old_printer->comment) ||
+                        !strequal(printer->portname, old_printer->portname) ||
+                        !strequal(printer->location, old_printer->location)) )
+       {
+               /* add_printer_hook() will call reload_services() */
+               if (!add_printer_hook(tmp_ctx, p->server_info->ptok,
+                                     printer, p->client_address,
+                                     p->msg_ctx)) {
+                       result = WERR_ACCESS_DENIED;
+                       goto done;
+               }
+       }
+
+       update_dsspooler(tmp_ctx,
+                        p->server_info,
+                        snum,
+                        printer,
+                        old_printer);
+
        printer_mask &= ~SPOOLSS_PRINTER_INFO_SECDESC;
 
        if (devmode == NULL) {
                printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
        }
-       result = winreg_update_printer(p->mem_ctx,
+       result = winreg_update_printer(tmp_ctx,
                                       p->server_info,
+                                      p->msg_ctx,
                                       printer->sharename,
                                       printer_mask,
                                       printer,
@@ -5734,18 +6041,20 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
                                       NULL);
 
 done:
-       talloc_free(old_printer);
+       talloc_free(tmp_ctx);
 
        return result;
 }
 
 /****************************************************************************
 ****************************************************************************/
-static WERROR publish_or_unpublish_printer(pipes_struct *p,
+static WERROR publish_or_unpublish_printer(struct pipes_struct *p,
                                           struct policy_handle *handle,
                                           struct spoolss_SetPrinterInfo7 *info7)
 {
 #ifdef HAVE_ADS
+       struct spoolss_PrinterInfo2 *pinfo2 = NULL;
+       WERROR result;
        int snum;
        Printer_entry *Printer;
 
@@ -5763,8 +6072,16 @@ static WERROR publish_or_unpublish_printer(pipes_struct *p,
        if (!get_printer_snum(p, handle, &snum, NULL))
                return WERR_BADFID;
 
-       nt_printer_publish(Printer, snum, info7->action);
+       result = winreg_get_printer(p->mem_ctx, p->server_info, p->msg_ctx,
+                                   Printer->servername,
+                                   lp_servicename(snum), &pinfo2);
+       if (!W_ERROR_IS_OK(result)) {
+               return WERR_BADFID;
+       }
+
+       nt_printer_publish(pinfo2, p->server_info, pinfo2, info7->action);
 
+       TALLOC_FREE(pinfo2);
        return WERR_OK;
 #else
        return WERR_UNKNOWN_LEVEL;
@@ -5774,7 +6091,8 @@ static WERROR publish_or_unpublish_printer(pipes_struct *p,
 /********************************************************************
  ********************************************************************/
 
-static WERROR update_printer_devmode(pipes_struct *p, struct policy_handle *handle,
+static WERROR update_printer_devmode(struct pipes_struct *p,
+                                    struct policy_handle *handle,
                                     struct spoolss_DeviceMode *devmode)
 {
        int snum;
@@ -5799,6 +6117,7 @@ static WERROR update_printer_devmode(pipes_struct *p, struct policy_handle *hand
 
        return winreg_update_printer(p->mem_ctx,
                                     p->server_info,
+                                    p->msg_ctx,
                                     lp_const_servicename(snum),
                                     info2_mask,
                                     NULL,
@@ -5811,7 +6130,7 @@ static WERROR update_printer_devmode(pipes_struct *p, struct policy_handle *hand
  _spoolss_SetPrinter
 ****************************************************************/
 
-WERROR _spoolss_SetPrinter(pipes_struct *p,
+WERROR _spoolss_SetPrinter(struct pipes_struct *p,
                           struct spoolss_SetPrinter *r)
 {
        WERROR result;
@@ -5856,7 +6175,7 @@ WERROR _spoolss_SetPrinter(pipes_struct *p,
  _spoolss_FindClosePrinterNotify
 ****************************************************************/
 
-WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
+WERROR _spoolss_FindClosePrinterNotify(struct pipes_struct *p,
                                       struct spoolss_FindClosePrinterNotify *r)
 {
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
@@ -5876,7 +6195,8 @@ WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
                                !get_printer_snum(p, r->in.handle, &snum, NULL) )
                        return WERR_BADFID;
 
-               srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
+               srv_spoolss_replycloseprinter(
+                       snum, &Printer->notify.client_hnd, p->msg_ctx);
        }
 
        Printer->notify.flags=0;
@@ -5893,7 +6213,7 @@ WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
  _spoolss_AddJob
 ****************************************************************/
 
-WERROR _spoolss_AddJob(pipes_struct *p,
+WERROR _spoolss_AddJob(struct pipes_struct *p,
                       struct spoolss_AddJob *r)
 {
        if (!r->in.buffer && (r->in.offered != 0)) {
@@ -6083,7 +6403,6 @@ static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
                              union spoolss_JobInfo **info_p,
                              uint32_t *count)
 {
-       struct spoolss_DeviceMode *devmode;
        union spoolss_JobInfo *info;
        int i;
        WERROR result = WERR_OK;
@@ -6094,16 +6413,11 @@ static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
        *count = num_queues;
 
        for (i=0; i<*count; i++) {
+               struct spoolss_DeviceMode *devmode;
 
-               if (!pinfo2->devmode) {
-                       result = spoolss_create_default_devmode(info,
+               result = spoolss_create_default_devmode(info,
                                                        pinfo2->printername,
                                                        &devmode);
-               } else {
-                       result = copy_devicemode(info,
-                                                pinfo2->devmode,
-                                                &devmode);
-               }
                if (!W_ERROR_IS_OK(result)) {
                        DEBUG(3, ("Can't proceed w/o a devmode!"));
                        goto out;
@@ -6188,7 +6502,7 @@ static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
  _spoolss_EnumJobs
 ****************************************************************/
 
-WERROR _spoolss_EnumJobs(pipes_struct *p,
+WERROR _spoolss_EnumJobs(struct pipes_struct *p,
                         struct spoolss_EnumJobs *r)
 {
        WERROR result;
@@ -6216,8 +6530,8 @@ WERROR _spoolss_EnumJobs(pipes_struct *p,
                return WERR_BADFID;
        }
 
-       result = winreg_get_printer(talloc_tos(), p->server_info, NULL,
-                                   lp_servicename(snum), &pinfo2);
+       result = winreg_get_printer(p->mem_ctx, p->server_info, p->msg_ctx,
+                                   NULL, lp_servicename(snum), &pinfo2);
        if (!W_ERROR_IS_OK(result)) {
                return result;
        }
@@ -6271,7 +6585,7 @@ WERROR _spoolss_EnumJobs(pipes_struct *p,
  _spoolss_ScheduleJob
 ****************************************************************/
 
-WERROR _spoolss_ScheduleJob(pipes_struct *p,
+WERROR _spoolss_ScheduleJob(struct pipes_struct *p,
                            struct spoolss_ScheduleJob *r)
 {
        return WERR_OK;
@@ -6306,7 +6620,7 @@ static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
  _spoolss_SetJob
 ****************************************************************/
 
-WERROR _spoolss_SetJob(pipes_struct *p,
+WERROR _spoolss_SetJob(struct pipes_struct *p,
                       struct spoolss_SetJob *r)
 {
        int snum;
@@ -6323,7 +6637,9 @@ WERROR _spoolss_SetJob(pipes_struct *p,
        switch (r->in.command) {
        case SPOOLSS_JOB_CONTROL_CANCEL:
        case SPOOLSS_JOB_CONTROL_DELETE:
-               if (print_job_delete(p->server_info, snum, r->in.job_id, &errcode)) {
+               errcode = print_job_delete(p->server_info,
+                                          snum, r->in.job_id);
+               if (W_ERROR_EQUAL(errcode, WERR_PRINTER_HAS_JOBS_QUEUED)) {
                        errcode = WERR_OK;
                }
                break;
@@ -6540,7 +6856,7 @@ static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
  _spoolss_EnumPrinterDrivers
 ****************************************************************/
 
-WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
+WERROR _spoolss_EnumPrinterDrivers(struct pipes_struct *p,
                                   struct spoolss_EnumPrinterDrivers *r)
 {
        const char *cservername;
@@ -6589,7 +6905,7 @@ WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
  _spoolss_EnumForms
 ****************************************************************/
 
-WERROR _spoolss_EnumForms(pipes_struct *p,
+WERROR _spoolss_EnumForms(struct pipes_struct *p,
                          struct spoolss_EnumForms *r)
 {
        WERROR result;
@@ -6612,6 +6928,7 @@ WERROR _spoolss_EnumForms(pipes_struct *p,
        case 1:
                result = winreg_printer_enumforms1(p->mem_ctx,
                                                   p->server_info,
+                                                  p->msg_ctx,
                                                   r->out.count,
                                                   r->out.info);
                break;
@@ -6642,7 +6959,7 @@ WERROR _spoolss_EnumForms(pipes_struct *p,
  _spoolss_GetForm
 ****************************************************************/
 
-WERROR _spoolss_GetForm(pipes_struct *p,
+WERROR _spoolss_GetForm(struct pipes_struct *p,
                        struct spoolss_GetForm *r)
 {
        WERROR result;
@@ -6887,7 +7204,7 @@ out:
  _spoolss_EnumPorts
 ****************************************************************/
 
-WERROR _spoolss_EnumPorts(pipes_struct *p,
+WERROR _spoolss_EnumPorts(struct pipes_struct *p,
                          struct spoolss_EnumPorts *r)
 {
        WERROR result;
@@ -6934,7 +7251,7 @@ WERROR _spoolss_EnumPorts(pipes_struct *p,
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
+static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p,
                                           const char *server,
                                           struct spoolss_SetPrinterInfoCtr *info_ctr,
                                           struct spoolss_DeviceMode *devmode,
@@ -6991,7 +7308,8 @@ static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
 
        if (*lp_addprinter_cmd() ) {
                if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
-                                      info2) ) {
+                                      info2, p->client_address,
+                                      p->msg_ctx) ) {
                        return WERR_ACCESS_DENIED;
                }
        } else {
@@ -7022,8 +7340,15 @@ static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
                info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
        }
 
+       update_dsspooler(p->mem_ctx,
+                        p->server_info,
+                        0,
+                        info2,
+                        NULL);
+
        err = winreg_update_printer(p->mem_ctx,
                                    p->server_info,
+                                   p->msg_ctx,
                                    info2->sharename,
                                    info2_mask,
                                    info2,
@@ -7046,7 +7371,7 @@ static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
  _spoolss_AddPrinterEx
 ****************************************************************/
 
-WERROR _spoolss_AddPrinterEx(pipes_struct *p,
+WERROR _spoolss_AddPrinterEx(struct pipes_struct *p,
                             struct spoolss_AddPrinterEx *r)
 {
        switch (r->in.info_ctr->level) {
@@ -7070,7 +7395,7 @@ WERROR _spoolss_AddPrinterEx(pipes_struct *p,
  _spoolss_AddPrinter
 ****************************************************************/
 
-WERROR _spoolss_AddPrinter(pipes_struct *p,
+WERROR _spoolss_AddPrinter(struct pipes_struct *p,
                           struct spoolss_AddPrinter *r)
 {
        struct spoolss_AddPrinterEx a;
@@ -7094,7 +7419,7 @@ WERROR _spoolss_AddPrinter(pipes_struct *p,
  _spoolss_AddPrinterDriverEx
 ****************************************************************/
 
-WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
+WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
                                   struct spoolss_AddPrinterDriverEx *r)
 {
        WERROR err = WERR_OK;
@@ -7160,7 +7485,7 @@ WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
         * to update each printer bound to this driver.   --jerry
         */
 
-       if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
+       if (!srv_spoolss_drv_upgrade_printer(driver_name, p->msg_ctx)) {
                DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
                        fn, driver_name));
        }
@@ -7173,7 +7498,7 @@ done:
  _spoolss_AddPrinterDriver
 ****************************************************************/
 
-WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
+WERROR _spoolss_AddPrinterDriver(struct pipes_struct *p,
                                 struct spoolss_AddPrinterDriver *r)
 {
        struct spoolss_AddPrinterDriverEx a;
@@ -7299,7 +7624,7 @@ static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
  _spoolss_GetPrinterDriverDirectory
 ****************************************************************/
 
-WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
+WERROR _spoolss_GetPrinterDriverDirectory(struct pipes_struct *p,
                                          struct spoolss_GetPrinterDriverDirectory *r)
 {
        WERROR werror;
@@ -7337,7 +7662,7 @@ WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
  _spoolss_EnumPrinterData
 ****************************************************************/
 
-WERROR _spoolss_EnumPrinterData(pipes_struct *p,
+WERROR _spoolss_EnumPrinterData(struct pipes_struct *p,
                                struct spoolss_EnumPrinterData *r)
 {
        WERROR result;
@@ -7477,7 +7802,7 @@ WERROR _spoolss_EnumPrinterData(pipes_struct *p,
  _spoolss_SetPrinterData
 ****************************************************************/
 
-WERROR _spoolss_SetPrinterData(pipes_struct *p,
+WERROR _spoolss_SetPrinterData(struct pipes_struct *p,
                               struct spoolss_SetPrinterData *r)
 {
        struct spoolss_SetPrinterDataEx r2;
@@ -7496,7 +7821,7 @@ WERROR _spoolss_SetPrinterData(pipes_struct *p,
  _spoolss_ResetPrinter
 ****************************************************************/
 
-WERROR _spoolss_ResetPrinter(pipes_struct *p,
+WERROR _spoolss_ResetPrinter(struct pipes_struct *p,
                             struct spoolss_ResetPrinter *r)
 {
        Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
@@ -7528,7 +7853,7 @@ WERROR _spoolss_ResetPrinter(pipes_struct *p,
  _spoolss_DeletePrinterData
 ****************************************************************/
 
-WERROR _spoolss_DeletePrinterData(pipes_struct *p,
+WERROR _spoolss_DeletePrinterData(struct pipes_struct *p,
                                  struct spoolss_DeletePrinterData *r)
 {
        struct spoolss_DeletePrinterDataEx r2;
@@ -7544,7 +7869,7 @@ WERROR _spoolss_DeletePrinterData(pipes_struct *p,
  _spoolss_AddForm
 ****************************************************************/
 
-WERROR _spoolss_AddForm(pipes_struct *p,
+WERROR _spoolss_AddForm(struct pipes_struct *p,
                        struct spoolss_AddForm *r)
 {
        struct spoolss_AddFormInfo1 *form = r->in.info.info1;
@@ -7585,7 +7910,8 @@ WERROR _spoolss_AddForm(pipes_struct *p,
                return WERR_INVALID_PARAM;
        }
 
-       status = winreg_printer_addform1(p->mem_ctx, p->server_info, form);
+       status = winreg_printer_addform1(p->mem_ctx, p->server_info,
+                                        p->msg_ctx, form);
        if (!W_ERROR_IS_OK(status)) {
                return status;
        }
@@ -7600,6 +7926,7 @@ WERROR _spoolss_AddForm(pipes_struct *p,
 
                status = winreg_printer_update_changeid(p->mem_ctx,
                                                        p->server_info,
+                                                       p->msg_ctx,
                                                        lp_const_servicename(snum));
                if (!W_ERROR_IS_OK(status)) {
                        return status;
@@ -7613,7 +7940,7 @@ WERROR _spoolss_AddForm(pipes_struct *p,
  _spoolss_DeleteForm
 ****************************************************************/
 
-WERROR _spoolss_DeleteForm(pipes_struct *p,
+WERROR _spoolss_DeleteForm(struct pipes_struct *p,
                           struct spoolss_DeleteForm *r)
 {
        const char *form_name = r->in.form_name;
@@ -7658,6 +7985,7 @@ WERROR _spoolss_DeleteForm(pipes_struct *p,
 
                status = winreg_printer_update_changeid(p->mem_ctx,
                                                        p->server_info,
+                                                       p->msg_ctx,
                                                        lp_const_servicename(snum));
                if (!W_ERROR_IS_OK(status)) {
                        return status;
@@ -7671,7 +7999,7 @@ WERROR _spoolss_DeleteForm(pipes_struct *p,
  _spoolss_SetForm
 ****************************************************************/
 
-WERROR _spoolss_SetForm(pipes_struct *p,
+WERROR _spoolss_SetForm(struct pipes_struct *p,
                        struct spoolss_SetForm *r)
 {
        struct spoolss_AddFormInfo1 *form = r->in.info.info1;
@@ -7722,6 +8050,7 @@ WERROR _spoolss_SetForm(pipes_struct *p,
 
                status = winreg_printer_update_changeid(p->mem_ctx,
                                                        p->server_info,
+                                                       p->msg_ctx,
                                                        lp_const_servicename(snum));
                if (!W_ERROR_IS_OK(status)) {
                        return status;
@@ -7782,7 +8111,7 @@ static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
  _spoolss_EnumPrintProcessors
 ****************************************************************/
 
-WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
+WERROR _spoolss_EnumPrintProcessors(struct pipes_struct *p,
                                    struct spoolss_EnumPrintProcessors *r)
 {
        WERROR result;
@@ -7880,7 +8209,7 @@ static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
  _spoolss_EnumPrintProcDataTypes
 ****************************************************************/
 
-WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
+WERROR _spoolss_EnumPrintProcDataTypes(struct pipes_struct *p,
                                       struct spoolss_EnumPrintProcDataTypes *r)
 {
        WERROR result;
@@ -8038,7 +8367,7 @@ out:
  _spoolss_EnumMonitors
 ****************************************************************/
 
-WERROR _spoolss_EnumMonitors(pipes_struct *p,
+WERROR _spoolss_EnumMonitors(struct pipes_struct *p,
                             struct spoolss_EnumMonitors *r)
 {
        WERROR result;
@@ -8180,7 +8509,7 @@ static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
  _spoolss_GetJob
 ****************************************************************/
 
-WERROR _spoolss_GetJob(pipes_struct *p,
+WERROR _spoolss_GetJob(struct pipes_struct *p,
                       struct spoolss_GetJob *r)
 {
        WERROR result = WERR_OK;
@@ -8204,8 +8533,8 @@ WERROR _spoolss_GetJob(pipes_struct *p,
                return WERR_BADFID;
        }
 
-       result = winreg_get_printer(talloc_tos(), p->server_info, NULL,
-                                   lp_servicename(snum), &pinfo2);
+       result = winreg_get_printer(p->mem_ctx, p->server_info, p->msg_ctx,
+                                   NULL, lp_servicename(snum), &pinfo2);
        if (!W_ERROR_IS_OK(result)) {
                return result;
        }
@@ -8250,7 +8579,7 @@ WERROR _spoolss_GetJob(pipes_struct *p,
  _spoolss_GetPrinterDataEx
 ****************************************************************/
 
-WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
+WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
                                 struct spoolss_GetPrinterDataEx *r)
 {
 
@@ -8330,6 +8659,7 @@ WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
 
                        result = winreg_printer_get_changeid(p->mem_ctx,
                                                             p->server_info,
+                                                            p->msg_ctx,
                                                             printer,
                                                             &changeid);
                        if (!W_ERROR_IS_OK(result)) {
@@ -8344,6 +8674,7 @@ WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
 
        result = winreg_get_printer_dataex(p->mem_ctx,
                                           p->server_info,
+                                          p->msg_ctx,
                                           printer,
                                           r->in.key_name,
                                           r->in.value_name,
@@ -8372,7 +8703,7 @@ WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
  _spoolss_SetPrinterDataEx
 ****************************************************************/
 
-WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
+WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
                                 struct spoolss_SetPrinterDataEx *r)
 {
        struct spoolss_PrinterInfo2 *pinfo2 = NULL;
@@ -8416,7 +8747,7 @@ WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
                return WERR_ACCESS_DENIED;
        }
 
-       result = winreg_get_printer(Printer, p->server_info,
+       result = winreg_get_printer(Printer, p->server_info, p->msg_ctx,
                                    Printer->servername,
                                    lp_servicename(snum),
                                    &pinfo2);
@@ -8436,6 +8767,7 @@ WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
 
        result = winreg_set_printer_dataex(p->mem_ctx,
                                           p->server_info,
+                                          p->msg_ctx,
                                           pinfo2->sharename,
                                           r->in.key_name,
                                           r->in.value_name,
@@ -8461,6 +8793,7 @@ WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
                         */
                        winreg_set_printer_dataex(p->mem_ctx,
                                                  p->server_info,
+                                                 p->msg_ctx,
                                                  pinfo2->sharename,
                                                  str,
                                                  r->in.value_name,
@@ -8471,6 +8804,7 @@ WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
 
                result = winreg_printer_update_changeid(p->mem_ctx,
                                                        p->server_info,
+                                                       p->msg_ctx,
                                                        lp_const_servicename(snum));
 
        }
@@ -8484,7 +8818,7 @@ done:
  _spoolss_DeletePrinterDataEx
 ****************************************************************/
 
-WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
+WERROR _spoolss_DeletePrinterDataEx(struct pipes_struct *p,
                                    struct spoolss_DeletePrinterDataEx *r)
 {
        const char *printer;
@@ -8518,12 +8852,14 @@ WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
 
        status = winreg_delete_printer_dataex(p->mem_ctx,
                                              p->server_info,
+                                             p->msg_ctx,
                                              printer,
                                              r->in.key_name,
                                              r->in.value_name);
        if (W_ERROR_IS_OK(status)) {
                status = winreg_printer_update_changeid(p->mem_ctx,
                                                        p->server_info,
+                                                       p->msg_ctx,
                                                        printer);
        }
 
@@ -8534,7 +8870,7 @@ WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
  _spoolss_EnumPrinterKey
 ****************************************************************/
 
-WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
+WERROR _spoolss_EnumPrinterKey(struct pipes_struct *p,
                               struct spoolss_EnumPrinterKey *r)
 {
        uint32_t        num_keys;
@@ -8558,6 +8894,7 @@ WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
 
        result = winreg_enum_printer_key(p->mem_ctx,
                                         p->server_info,
+                                        p->msg_ctx,
                                         lp_const_servicename(snum),
                                         r->in.key_name,
                                         &num_keys,
@@ -8596,7 +8933,7 @@ WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
  _spoolss_DeletePrinterKey
 ****************************************************************/
 
-WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
+WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
                                 struct spoolss_DeletePrinterKey *r)
 {
        Printer_entry           *Printer = find_printer_index_by_hnd(p, r->in.handle);
@@ -8631,11 +8968,13 @@ WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
        /* delete the key and all subkeys */
        status = winreg_delete_printer_key(p->mem_ctx,
                                           p->server_info,
+                                          p->msg_ctx,
                                           printer,
                                           r->in.key_name);
        if (W_ERROR_IS_OK(status)) {
                status = winreg_printer_update_changeid(p->mem_ctx,
                                                        p->server_info,
+                                                       p->msg_ctx,
                                                        printer);
        }
 
@@ -8646,7 +8985,7 @@ WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
  _spoolss_EnumPrinterDataEx
 ****************************************************************/
 
-WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
+WERROR _spoolss_EnumPrinterDataEx(struct pipes_struct *p,
                                  struct spoolss_EnumPrinterDataEx *r)
 {
        uint32_t        count = 0;
@@ -8686,6 +9025,7 @@ WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
        /* now look for a match on the key name */
        result = winreg_enum_printer_dataex(p->mem_ctx,
                                            p->server_info,
+                                           p->msg_ctx,
                                            lp_const_servicename(snum),
                                            r->in.key_name,
                                            &count,
@@ -8755,7 +9095,7 @@ static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
  _spoolss_GetPrintProcessorDirectory
 ****************************************************************/
 
-WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
+WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p,
                                           struct spoolss_GetPrintProcessorDirectory *r)
 {
        WERROR result;
@@ -9042,7 +9382,7 @@ static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
  _spoolss_XcvData
 ****************************************************************/
 
-WERROR _spoolss_XcvData(pipes_struct *p,
+WERROR _spoolss_XcvData(struct pipes_struct *p,
                        struct spoolss_XcvData *r)
 {
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
@@ -9115,7 +9455,7 @@ WERROR _spoolss_XcvData(pipes_struct *p,
  _spoolss_AddPrintProcessor
 ****************************************************************/
 
-WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
+WERROR _spoolss_AddPrintProcessor(struct pipes_struct *p,
                                  struct spoolss_AddPrintProcessor *r)
 {
        /* for now, just indicate success and ignore the add.  We'll
@@ -9130,7 +9470,7 @@ WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
  _spoolss_AddPort
 ****************************************************************/
 
-WERROR _spoolss_AddPort(pipes_struct *p,
+WERROR _spoolss_AddPort(struct pipes_struct *p,
                        struct spoolss_AddPort *r)
 {
        /* do what w2k3 does */
@@ -9142,7 +9482,7 @@ WERROR _spoolss_AddPort(pipes_struct *p,
  _spoolss_GetPrinterDriver
 ****************************************************************/
 
-WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
+WERROR _spoolss_GetPrinterDriver(struct pipes_struct *p,
                                 struct spoolss_GetPrinterDriver *r)
 {
        p->rng_fault_state = true;
@@ -9153,7 +9493,7 @@ WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
  _spoolss_ReadPrinter
 ****************************************************************/
 
-WERROR _spoolss_ReadPrinter(pipes_struct *p,
+WERROR _spoolss_ReadPrinter(struct pipes_struct *p,
                            struct spoolss_ReadPrinter *r)
 {
        p->rng_fault_state = true;
@@ -9164,7 +9504,7 @@ WERROR _spoolss_ReadPrinter(pipes_struct *p,
  _spoolss_WaitForPrinterChange
 ****************************************************************/
 
-WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
+WERROR _spoolss_WaitForPrinterChange(struct pipes_struct *p,
                                     struct spoolss_WaitForPrinterChange *r)
 {
        p->rng_fault_state = true;
@@ -9175,7 +9515,7 @@ WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
  _spoolss_ConfigurePort
 ****************************************************************/
 
-WERROR _spoolss_ConfigurePort(pipes_struct *p,
+WERROR _spoolss_ConfigurePort(struct pipes_struct *p,
                              struct spoolss_ConfigurePort *r)
 {
        p->rng_fault_state = true;
@@ -9186,7 +9526,7 @@ WERROR _spoolss_ConfigurePort(pipes_struct *p,
  _spoolss_DeletePort
 ****************************************************************/
 
-WERROR _spoolss_DeletePort(pipes_struct *p,
+WERROR _spoolss_DeletePort(struct pipes_struct *p,
                           struct spoolss_DeletePort *r)
 {
        p->rng_fault_state = true;
@@ -9197,7 +9537,7 @@ WERROR _spoolss_DeletePort(pipes_struct *p,
  _spoolss_CreatePrinterIC
 ****************************************************************/
 
-WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
+WERROR _spoolss_CreatePrinterIC(struct pipes_struct *p,
                                struct spoolss_CreatePrinterIC *r)
 {
        p->rng_fault_state = true;
@@ -9208,7 +9548,7 @@ WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
  _spoolss_PlayGDIScriptOnPrinterIC
 ****************************************************************/
 
-WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
+WERROR _spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct *p,
                                         struct spoolss_PlayGDIScriptOnPrinterIC *r)
 {
        p->rng_fault_state = true;
@@ -9219,7 +9559,7 @@ WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
  _spoolss_DeletePrinterIC
 ****************************************************************/
 
-WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
+WERROR _spoolss_DeletePrinterIC(struct pipes_struct *p,
                                struct spoolss_DeletePrinterIC *r)
 {
        p->rng_fault_state = true;
@@ -9230,7 +9570,7 @@ WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
  _spoolss_AddPrinterConnection
 ****************************************************************/
 
-WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
+WERROR _spoolss_AddPrinterConnection(struct pipes_struct *p,
                                     struct spoolss_AddPrinterConnection *r)
 {
        p->rng_fault_state = true;
@@ -9241,7 +9581,7 @@ WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
  _spoolss_DeletePrinterConnection
 ****************************************************************/
 
-WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
+WERROR _spoolss_DeletePrinterConnection(struct pipes_struct *p,
                                        struct spoolss_DeletePrinterConnection *r)
 {
        p->rng_fault_state = true;
@@ -9252,7 +9592,7 @@ WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
  _spoolss_PrinterMessageBox
 ****************************************************************/
 
-WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
+WERROR _spoolss_PrinterMessageBox(struct pipes_struct *p,
                                  struct spoolss_PrinterMessageBox *r)
 {
        p->rng_fault_state = true;
@@ -9263,7 +9603,7 @@ WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
  _spoolss_AddMonitor
 ****************************************************************/
 
-WERROR _spoolss_AddMonitor(pipes_struct *p,
+WERROR _spoolss_AddMonitor(struct pipes_struct *p,
                           struct spoolss_AddMonitor *r)
 {
        p->rng_fault_state = true;
@@ -9274,7 +9614,7 @@ WERROR _spoolss_AddMonitor(pipes_struct *p,
  _spoolss_DeleteMonitor
 ****************************************************************/
 
-WERROR _spoolss_DeleteMonitor(pipes_struct *p,
+WERROR _spoolss_DeleteMonitor(struct pipes_struct *p,
                              struct spoolss_DeleteMonitor *r)
 {
        p->rng_fault_state = true;
@@ -9285,7 +9625,7 @@ WERROR _spoolss_DeleteMonitor(pipes_struct *p,
  _spoolss_DeletePrintProcessor
 ****************************************************************/
 
-WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
+WERROR _spoolss_DeletePrintProcessor(struct pipes_struct *p,
                                     struct spoolss_DeletePrintProcessor *r)
 {
        p->rng_fault_state = true;
@@ -9296,7 +9636,7 @@ WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
  _spoolss_AddPrintProvidor
 ****************************************************************/
 
-WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
+WERROR _spoolss_AddPrintProvidor(struct pipes_struct *p,
                                 struct spoolss_AddPrintProvidor *r)
 {
        p->rng_fault_state = true;
@@ -9307,7 +9647,7 @@ WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
  _spoolss_DeletePrintProvidor
 ****************************************************************/
 
-WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
+WERROR _spoolss_DeletePrintProvidor(struct pipes_struct *p,
                                    struct spoolss_DeletePrintProvidor *r)
 {
        p->rng_fault_state = true;
@@ -9318,7 +9658,7 @@ WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
  _spoolss_FindFirstPrinterChangeNotification
 ****************************************************************/
 
-WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
+WERROR _spoolss_FindFirstPrinterChangeNotification(struct pipes_struct *p,
                                                   struct spoolss_FindFirstPrinterChangeNotification *r)
 {
        p->rng_fault_state = true;
@@ -9329,7 +9669,7 @@ WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
  _spoolss_FindNextPrinterChangeNotification
 ****************************************************************/
 
-WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
+WERROR _spoolss_FindNextPrinterChangeNotification(struct pipes_struct *p,
                                                  struct spoolss_FindNextPrinterChangeNotification *r)
 {
        p->rng_fault_state = true;
@@ -9340,7 +9680,7 @@ WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
  _spoolss_RouterFindFirstPrinterChangeNotificationOld
 ****************************************************************/
 
-WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
+WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct *p,
                                                            struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
 {
        p->rng_fault_state = true;
@@ -9351,7 +9691,7 @@ WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
  _spoolss_ReplyOpenPrinter
 ****************************************************************/
 
-WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
+WERROR _spoolss_ReplyOpenPrinter(struct pipes_struct *p,
                                 struct spoolss_ReplyOpenPrinter *r)
 {
        p->rng_fault_state = true;
@@ -9362,7 +9702,7 @@ WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
  _spoolss_RouterReplyPrinter
 ****************************************************************/
 
-WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
+WERROR _spoolss_RouterReplyPrinter(struct pipes_struct *p,
                                   struct spoolss_RouterReplyPrinter *r)
 {
        p->rng_fault_state = true;
@@ -9373,7 +9713,7 @@ WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
  _spoolss_ReplyClosePrinter
 ****************************************************************/
 
-WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
+WERROR _spoolss_ReplyClosePrinter(struct pipes_struct *p,
                                  struct spoolss_ReplyClosePrinter *r)
 {
        p->rng_fault_state = true;
@@ -9384,7 +9724,7 @@ WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
  _spoolss_AddPortEx
 ****************************************************************/
 
-WERROR _spoolss_AddPortEx(pipes_struct *p,
+WERROR _spoolss_AddPortEx(struct pipes_struct *p,
                          struct spoolss_AddPortEx *r)
 {
        p->rng_fault_state = true;
@@ -9395,7 +9735,7 @@ WERROR _spoolss_AddPortEx(pipes_struct *p,
  _spoolss_RouterFindFirstPrinterChangeNotification
 ****************************************************************/
 
-WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
+WERROR _spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct *p,
                                                         struct spoolss_RouterFindFirstPrinterChangeNotification *r)
 {
        p->rng_fault_state = true;
@@ -9406,7 +9746,7 @@ WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
  _spoolss_SpoolerInit
 ****************************************************************/
 
-WERROR _spoolss_SpoolerInit(pipes_struct *p,
+WERROR _spoolss_SpoolerInit(struct pipes_struct *p,
                            struct spoolss_SpoolerInit *r)
 {
        p->rng_fault_state = true;
@@ -9417,7 +9757,7 @@ WERROR _spoolss_SpoolerInit(pipes_struct *p,
  _spoolss_ResetPrinterEx
 ****************************************************************/
 
-WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
+WERROR _spoolss_ResetPrinterEx(struct pipes_struct *p,
                               struct spoolss_ResetPrinterEx *r)
 {
        p->rng_fault_state = true;
@@ -9428,7 +9768,7 @@ WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
  _spoolss_RouterReplyPrinterEx
 ****************************************************************/
 
-WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
+WERROR _spoolss_RouterReplyPrinterEx(struct pipes_struct *p,
                                     struct spoolss_RouterReplyPrinterEx *r)
 {
        p->rng_fault_state = true;
@@ -9439,7 +9779,7 @@ WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
  _spoolss_44
 ****************************************************************/
 
-WERROR _spoolss_44(pipes_struct *p,
+WERROR _spoolss_44(struct pipes_struct *p,
                   struct spoolss_44 *r)
 {
        p->rng_fault_state = true;
@@ -9450,7 +9790,7 @@ WERROR _spoolss_44(pipes_struct *p,
  _spoolss_47
 ****************************************************************/
 
-WERROR _spoolss_47(pipes_struct *p,
+WERROR _spoolss_47(struct pipes_struct *p,
                   struct spoolss_47 *r)
 {
        p->rng_fault_state = true;
@@ -9461,7 +9801,7 @@ WERROR _spoolss_47(pipes_struct *p,
  _spoolss_4a
 ****************************************************************/
 
-WERROR _spoolss_4a(pipes_struct *p,
+WERROR _spoolss_4a(struct pipes_struct *p,
                   struct spoolss_4a *r)
 {
        p->rng_fault_state = true;
@@ -9472,7 +9812,7 @@ WERROR _spoolss_4a(pipes_struct *p,
  _spoolss_4b
 ****************************************************************/
 
-WERROR _spoolss_4b(pipes_struct *p,
+WERROR _spoolss_4b(struct pipes_struct *p,
                   struct spoolss_4b *r)
 {
        p->rng_fault_state = true;
@@ -9483,7 +9823,7 @@ WERROR _spoolss_4b(pipes_struct *p,
  _spoolss_4c
 ****************************************************************/
 
-WERROR _spoolss_4c(pipes_struct *p,
+WERROR _spoolss_4c(struct pipes_struct *p,
                   struct spoolss_4c *r)
 {
        p->rng_fault_state = true;
@@ -9494,7 +9834,7 @@ WERROR _spoolss_4c(pipes_struct *p,
  _spoolss_53
 ****************************************************************/
 
-WERROR _spoolss_53(pipes_struct *p,
+WERROR _spoolss_53(struct pipes_struct *p,
                   struct spoolss_53 *r)
 {
        p->rng_fault_state = true;
@@ -9505,7 +9845,7 @@ WERROR _spoolss_53(pipes_struct *p,
  _spoolss_55
 ****************************************************************/
 
-WERROR _spoolss_55(pipes_struct *p,
+WERROR _spoolss_55(struct pipes_struct *p,
                   struct spoolss_55 *r)
 {
        p->rng_fault_state = true;
@@ -9516,7 +9856,7 @@ WERROR _spoolss_55(pipes_struct *p,
  _spoolss_56
 ****************************************************************/
 
-WERROR _spoolss_56(pipes_struct *p,
+WERROR _spoolss_56(struct pipes_struct *p,
                   struct spoolss_56 *r)
 {
        p->rng_fault_state = true;
@@ -9527,7 +9867,7 @@ WERROR _spoolss_56(pipes_struct *p,
  _spoolss_57
 ****************************************************************/
 
-WERROR _spoolss_57(pipes_struct *p,
+WERROR _spoolss_57(struct pipes_struct *p,
                   struct spoolss_57 *r)
 {
        p->rng_fault_state = true;
@@ -9538,7 +9878,7 @@ WERROR _spoolss_57(pipes_struct *p,
  _spoolss_5a
 ****************************************************************/
 
-WERROR _spoolss_5a(pipes_struct *p,
+WERROR _spoolss_5a(struct pipes_struct *p,
                   struct spoolss_5a *r)
 {
        p->rng_fault_state = true;
@@ -9549,7 +9889,7 @@ WERROR _spoolss_5a(pipes_struct *p,
  _spoolss_5b
 ****************************************************************/
 
-WERROR _spoolss_5b(pipes_struct *p,
+WERROR _spoolss_5b(struct pipes_struct *p,
                   struct spoolss_5b *r)
 {
        p->rng_fault_state = true;
@@ -9560,7 +9900,7 @@ WERROR _spoolss_5b(pipes_struct *p,
  _spoolss_5c
 ****************************************************************/
 
-WERROR _spoolss_5c(pipes_struct *p,
+WERROR _spoolss_5c(struct pipes_struct *p,
                   struct spoolss_5c *r)
 {
        p->rng_fault_state = true;
@@ -9571,7 +9911,7 @@ WERROR _spoolss_5c(pipes_struct *p,
  _spoolss_5d
 ****************************************************************/
 
-WERROR _spoolss_5d(pipes_struct *p,
+WERROR _spoolss_5d(struct pipes_struct *p,
                   struct spoolss_5d *r)
 {
        p->rng_fault_state = true;
@@ -9582,7 +9922,7 @@ WERROR _spoolss_5d(pipes_struct *p,
  _spoolss_5e
 ****************************************************************/
 
-WERROR _spoolss_5e(pipes_struct *p,
+WERROR _spoolss_5e(struct pipes_struct *p,
                   struct spoolss_5e *r)
 {
        p->rng_fault_state = true;
@@ -9593,7 +9933,7 @@ WERROR _spoolss_5e(pipes_struct *p,
  _spoolss_5f
 ****************************************************************/
 
-WERROR _spoolss_5f(pipes_struct *p,
+WERROR _spoolss_5f(struct pipes_struct *p,
                   struct spoolss_5f *r)
 {
        p->rng_fault_state = true;
@@ -9604,7 +9944,7 @@ WERROR _spoolss_5f(pipes_struct *p,
  _spoolss_60
 ****************************************************************/
 
-WERROR _spoolss_60(pipes_struct *p,
+WERROR _spoolss_60(struct pipes_struct *p,
                   struct spoolss_60 *r)
 {
        p->rng_fault_state = true;
@@ -9615,7 +9955,7 @@ WERROR _spoolss_60(pipes_struct *p,
  _spoolss_61
 ****************************************************************/
 
-WERROR _spoolss_61(pipes_struct *p,
+WERROR _spoolss_61(struct pipes_struct *p,
                   struct spoolss_61 *r)
 {
        p->rng_fault_state = true;
@@ -9626,7 +9966,7 @@ WERROR _spoolss_61(pipes_struct *p,
  _spoolss_62
 ****************************************************************/
 
-WERROR _spoolss_62(pipes_struct *p,
+WERROR _spoolss_62(struct pipes_struct *p,
                   struct spoolss_62 *r)
 {
        p->rng_fault_state = true;
@@ -9637,7 +9977,7 @@ WERROR _spoolss_62(pipes_struct *p,
  _spoolss_63
 ****************************************************************/
 
-WERROR _spoolss_63(pipes_struct *p,
+WERROR _spoolss_63(struct pipes_struct *p,
                   struct spoolss_63 *r)
 {
        p->rng_fault_state = true;
@@ -9648,7 +9988,7 @@ WERROR _spoolss_63(pipes_struct *p,
  _spoolss_64
 ****************************************************************/
 
-WERROR _spoolss_64(pipes_struct *p,
+WERROR _spoolss_64(struct pipes_struct *p,
                   struct spoolss_64 *r)
 {
        p->rng_fault_state = true;
@@ -9659,7 +9999,7 @@ WERROR _spoolss_64(pipes_struct *p,
  _spoolss_65
 ****************************************************************/
 
-WERROR _spoolss_65(pipes_struct *p,
+WERROR _spoolss_65(struct pipes_struct *p,
                   struct spoolss_65 *r)
 {
        p->rng_fault_state = true;
@@ -9670,7 +10010,7 @@ WERROR _spoolss_65(pipes_struct *p,
  _spoolss_GetCorePrinterDrivers
 ****************************************************************/
 
-WERROR _spoolss_GetCorePrinterDrivers(pipes_struct *p,
+WERROR _spoolss_GetCorePrinterDrivers(struct pipes_struct *p,
                                      struct spoolss_GetCorePrinterDrivers *r)
 {
        p->rng_fault_state = true;
@@ -9681,7 +10021,7 @@ WERROR _spoolss_GetCorePrinterDrivers(pipes_struct *p,
  _spoolss_67
 ****************************************************************/
 
-WERROR _spoolss_67(pipes_struct *p,
+WERROR _spoolss_67(struct pipes_struct *p,
                   struct spoolss_67 *r)
 {
        p->rng_fault_state = true;
@@ -9692,7 +10032,7 @@ WERROR _spoolss_67(pipes_struct *p,
  _spoolss_GetPrinterDriverPackagePath
 ****************************************************************/
 
-WERROR _spoolss_GetPrinterDriverPackagePath(pipes_struct *p,
+WERROR _spoolss_GetPrinterDriverPackagePath(struct pipes_struct *p,
                                            struct spoolss_GetPrinterDriverPackagePath *r)
 {
        p->rng_fault_state = true;
@@ -9703,7 +10043,7 @@ WERROR _spoolss_GetPrinterDriverPackagePath(pipes_struct *p,
  _spoolss_69
 ****************************************************************/
 
-WERROR _spoolss_69(pipes_struct *p,
+WERROR _spoolss_69(struct pipes_struct *p,
                   struct spoolss_69 *r)
 {
        p->rng_fault_state = true;
@@ -9714,7 +10054,7 @@ WERROR _spoolss_69(pipes_struct *p,
  _spoolss_6a
 ****************************************************************/
 
-WERROR _spoolss_6a(pipes_struct *p,
+WERROR _spoolss_6a(struct pipes_struct *p,
                   struct spoolss_6a *r)
 {
        p->rng_fault_state = true;
@@ -9725,7 +10065,7 @@ WERROR _spoolss_6a(pipes_struct *p,
  _spoolss_6b
 ****************************************************************/
 
-WERROR _spoolss_6b(pipes_struct *p,
+WERROR _spoolss_6b(struct pipes_struct *p,
                   struct spoolss_6b *r)
 {
        p->rng_fault_state = true;
@@ -9736,7 +10076,7 @@ WERROR _spoolss_6b(pipes_struct *p,
  _spoolss_6c
 ****************************************************************/
 
-WERROR _spoolss_6c(pipes_struct *p,
+WERROR _spoolss_6c(struct pipes_struct *p,
                   struct spoolss_6c *r)
 {
        p->rng_fault_state = true;
@@ -9747,7 +10087,7 @@ WERROR _spoolss_6c(pipes_struct *p,
  _spoolss_6d
 ****************************************************************/
 
-WERROR _spoolss_6d(pipes_struct *p,
+WERROR _spoolss_6d(struct pipes_struct *p,
                   struct spoolss_6d *r)
 {
        p->rng_fault_state = true;