s3-printing: pass a talloc ctx to unpack_pjob
[ddiss/samba.git] / source3 / rpc_server / spoolss / srv_spoolss_nt.c
index 2b05d5f5f37d287f452578f5b9ec384e11596a10..8868a9894e666e6e1f120f91097d0c269db5aebf 100644 (file)
    up, all the errors returned are DOS errors, not NT status codes. */
 
 #include "includes.h"
+#include "ntdomain.h"
 #include "nt_printing.h"
 #include "srv_spoolss_util.h"
 #include "../librpc/gen_ndr/srv_spoolss.h"
 #include "../librpc/gen_ndr/ndr_spoolss_c.h"
 #include "rpc_client/init_spoolss.h"
-#include "librpc/gen_ndr/messaging.h"
+#include "rpc_client/cli_pipe.h"
 #include "../libcli/security/security.h"
 #include "librpc/gen_ndr/ndr_security.h"
 #include "registry.h"
 #include "secrets.h"
 #include "../librpc/gen_ndr/netlogon.h"
 #include "rpc_misc.h"
+#include "printing/notify.h"
+#include "serverid.h"
+#include "../libcli/registry/util_reg.h"
+#include "smbd/smbd.h"
+#include "auth.h"
+#include "messages.h"
+#include "rpc_server/spoolss/srv_spoolss_nt.h"
+#include "util_tdb.h"
+#include "libsmb/libsmb.h"
+#include "printing/printer_list.h"
+#include "rpc_client/cli_winreg_spoolss.h"
 
 /* macros stolen from s4 spoolss server */
 #define SPOOLSS_BUFFER_UNION(fn,info,level) \
@@ -283,6 +295,7 @@ static void srv_spoolss_replycloseprinter(int snum,
 
        if (prn_hnd->notify.cli_chan) {
                prn_hnd->notify.cli_chan->active_connections--;
+               prn_hnd->notify.cli_chan = NULL;
        }
 }
 
@@ -452,8 +465,8 @@ static WERROR delete_printer_handle(struct pipes_struct *p, struct policy_handle
        /* this does not need a become root since the access check has been
           done on the handle already */
 
-       result = winreg_delete_printer_key(p->mem_ctx,
-                                          get_server_info_system(),
+       result = winreg_delete_printer_key_internal(p->mem_ctx,
+                                          get_session_info_system(),
                                           p->msg_ctx,
                                           Printer->sharename,
                                           "");
@@ -462,7 +475,7 @@ static WERROR delete_printer_handle(struct pipes_struct *p, struct policy_handle
                return WERR_BADFID;
        }
 
-       result = delete_printer_hook(p->mem_ctx, p->server_info->ptok,
+       result = delete_printer_hook(p->mem_ctx, p->session_info->security_token,
                                     Printer->sharename, p->msg_ctx);
        if (!W_ERROR_IS_OK(result)) {
                return result;
@@ -540,7 +553,7 @@ static void prune_printername_cache(void)
 ****************************************************************************/
 
 static WERROR set_printer_hnd_name(TALLOC_CTX *mem_ctx,
-                                  const struct auth_serversupplied_info *server_info,
+                                  const struct auth_serversupplied_info *session_info,
                                   struct messaging_context *msg_ctx,
                                   struct printer_handle *Printer,
                                   const char *handlename)
@@ -674,8 +687,8 @@ static WERROR set_printer_hnd_name(TALLOC_CTX *mem_ctx,
                        continue;
                }
 
-               result = winreg_get_printer(mem_ctx,
-                                           server_info,
+               result = winreg_get_printer_internal(mem_ctx,
+                                           session_info,
                                            msg_ctx,
                                            sname,
                                            &info2);
@@ -761,7 +774,7 @@ static WERROR open_printer_hnd(struct pipes_struct *p,
        }
 
        result = set_printer_hnd_name(p->mem_ctx,
-                                     get_server_info_system(),
+                                     get_session_info_system(),
                                      p->msg_ctx,
                                      new_printer, name);
        if (!W_ERROR_IS_OK(result)) {
@@ -1522,21 +1535,22 @@ void do_drv_upgrade_printer(struct messaging_context *msg,
                            DATA_BLOB *data)
 {
        TALLOC_CTX *tmp_ctx;
-       struct auth_serversupplied_info *server_info = NULL;
+       struct auth_serversupplied_info *session_info = NULL;
        struct spoolss_PrinterInfo2 *pinfo2;
        NTSTATUS status;
        WERROR result;
        const char *drivername;
        int snum;
        int n_services = lp_numservices();
+       struct dcerpc_binding_handle *b = NULL;
 
        tmp_ctx = talloc_new(NULL);
        if (!tmp_ctx) return;
 
-       status = make_server_info_system(tmp_ctx, &server_info);
+       status = make_session_info_system(tmp_ctx, &session_info);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("do_drv_upgrade_printer: "
-                         "Could not create system server_info\n"));
+                         "Could not create system session_info\n"));
                goto done;
        }
 
@@ -1561,7 +1575,17 @@ void do_drv_upgrade_printer(struct messaging_context *msg,
                        continue;
                }
 
-               result = winreg_get_printer(tmp_ctx, server_info, msg,
+               if (b == NULL) {
+                       result = winreg_printer_binding_handle(tmp_ctx,
+                                                              session_info,
+                                                              msg,
+                                                              &b);
+                       if (!W_ERROR_IS_OK(result)) {
+                               break;
+                       }
+               }
+
+               result = winreg_get_printer(tmp_ctx, b,
                                            lp_const_servicename(snum),
                                            &pinfo2);
 
@@ -1580,9 +1604,7 @@ void do_drv_upgrade_printer(struct messaging_context *msg,
                DEBUG(6,("Updating printer [%s]\n", pinfo2->printername));
 
                /* all we care about currently is the change_id */
-               result = winreg_printer_update_changeid(tmp_ctx,
-                                                       server_info,
-                                                       msg,
+               result = winreg_printer_update_changeid(tmp_ctx, b,
                                                        pinfo2->printername);
 
                if (!W_ERROR_IS_OK(result)) {
@@ -1706,7 +1728,7 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
                return WERR_INVALID_PARAM;
        }
 
-       if (r->in.level < 0 || r->in.level > 3) {
+       if (r->in.level > 3) {
                return WERR_INVALID_PARAM;
        }
        if ((r->in.level == 1 && !r->in.userlevel.level1) ||
@@ -1801,14 +1823,14 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
                        /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
                           and not a printer admin, then fail */
 
-                       if ((p->server_info->utok.uid != sec_initial_uid()) &&
-                           !security_token_has_privilege(p->server_info->ptok, SEC_PRIV_PRINT_OPERATOR) &&
-                           !nt_token_check_sid(&global_sid_Builtin_Print_Operators, p->server_info->ptok) &&
+                       if ((p->session_info->utok.uid != sec_initial_uid()) &&
+                           !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_PRINT_OPERATOR) &&
+                           !nt_token_check_sid(&global_sid_Builtin_Print_Operators, p->session_info->security_token) &&
                            !token_contains_name_in_list(
-                                   uidtoname(p->server_info->utok.uid),
-                                   p->server_info->info3->base.domain.string,
+                                   uidtoname(p->session_info->utok.uid),
+                                   p->session_info->info3->base.domain.string,
                                    NULL,
-                                   p->server_info->ptok,
+                                   p->session_info->security_token,
                                    lp_printer_admin(snum))) {
                                close_printer_handle(p, r->out.handle);
                                ZERO_STRUCTP(r->out.handle);
@@ -1873,9 +1895,9 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
                        return WERR_ACCESS_DENIED;
                }
 
-               if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
-                                  p->server_info->ptok, snum) ||
-                   !print_access_check(p->server_info,
+               if (!user_ok_token(uidtoname(p->session_info->utok.uid), NULL,
+                                  p->session_info->security_token, snum) ||
+                   !print_access_check(p->session_info,
                                        p->msg_ctx,
                                        snum,
                                        r->in.access_mask)) {
@@ -1900,8 +1922,8 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
                DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
                        ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
 
-               winreg_create_printer(p->mem_ctx,
-                                     get_server_info_system(),
+               winreg_create_printer_internal(p->mem_ctx,
+                                     get_session_info_system(),
                                      p->msg_ctx,
                                      lp_const_servicename(snum));
 
@@ -1991,8 +2013,8 @@ WERROR _spoolss_DeletePrinter(struct pipes_struct *p,
        }
 
        if (get_printer_snum(p, r->in.handle, &snum, NULL)) {
-               winreg_delete_printer_key(p->mem_ctx,
-                                         get_server_info_system(),
+               winreg_delete_printer_key_internal(p->mem_ctx,
+                                         get_session_info_system(),
                                          p->msg_ctx,
                                          lp_const_servicename(snum),
                                          "");
@@ -2020,6 +2042,12 @@ static const struct print_architecture_table_node archi_table[]= {
        {NULL,                   "",            -1 }
 };
 
+static const int drv_cversion[] = {SPOOLSS_DRIVER_VERSION_9X,
+                                  SPOOLSS_DRIVER_VERSION_NT35,
+                                  SPOOLSS_DRIVER_VERSION_NT4,
+                                  SPOOLSS_DRIVER_VERSION_200X,
+                                  -1};
+
 static int get_version_id(const char *arch)
 {
        int i;
@@ -2042,20 +2070,23 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
 {
 
        struct spoolss_DriverInfo8 *info = NULL;
-       struct spoolss_DriverInfo8 *info_win2k = NULL;
        int                             version;
        WERROR                          status;
+       struct dcerpc_binding_handle *b;
+       TALLOC_CTX *tmp_ctx = NULL;
+       int i;
+       bool found;
 
        /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
           and not a printer admin, then fail */
 
-       if ( (p->server_info->utok.uid != sec_initial_uid())
-            && !security_token_has_privilege(p->server_info->ptok, SEC_PRIV_PRINT_OPERATOR)
+       if ( (p->session_info->utok.uid != sec_initial_uid())
+            && !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_PRINT_OPERATOR)
                && !token_contains_name_in_list(
-                       uidtoname(p->server_info->utok.uid),
-                       p->server_info->info3->base.domain.string,
+                       uidtoname(p->session_info->utok.uid),
+                       p->session_info->info3->base.domain.string,
                        NULL,
-                       p->server_info->ptok,
+                       p->session_info->security_token,
                        lp_printer_admin(-1)) )
        {
                return WERR_ACCESS_DENIED;
@@ -2066,75 +2097,115 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
        if ((version = get_version_id(r->in.architecture)) == -1)
                return WERR_INVALID_ENVIRONMENT;
 
-       status = winreg_get_driver(p->mem_ctx,
-                                  get_server_info_system(),
-                                  p->msg_ctx,
-                                  r->in.architecture, r->in.driver,
-                                  version, &info);
-       if (!W_ERROR_IS_OK(status)) {
-               /* try for Win2k driver if "Windows NT x86" */
+       tmp_ctx = talloc_new(p->mem_ctx);
+       if (!tmp_ctx) {
+               return WERR_NOMEM;
+       }
 
-               if ( version == 2 ) {
-                       version = 3;
+       status = winreg_printer_binding_handle(tmp_ctx,
+                                              get_session_info_system(),
+                                              p->msg_ctx,
+                                              &b);
+       if (!W_ERROR_IS_OK(status)) {
+               goto done;
+       }
 
-                       status = winreg_get_driver(p->mem_ctx,
-                                                  get_server_info_system(),
-                                                  p->msg_ctx,
-                                                  r->in.architecture,
-                                                  r->in.driver,
-                                                  version, &info);
-                       if (!W_ERROR_IS_OK(status)) {
-                               status = WERR_UNKNOWN_PRINTER_DRIVER;
-                               goto done;
-                       }
+       for (found = false, i = 0; drv_cversion[i] >= 0; i++) {
+               status = winreg_get_driver(tmp_ctx, b,
+                                          r->in.architecture, r->in.driver,
+                                          drv_cversion[i], &info);
+               if (!W_ERROR_IS_OK(status)) {
+                       DEBUG(5, ("skipping del of driver with version %d\n",
+                                 drv_cversion[i]));
+                       continue;
                }
-               /* otherwise it was a failure */
-               else {
-                       status = WERR_UNKNOWN_PRINTER_DRIVER;
+               found = true;
+
+               if (printer_driver_in_use(tmp_ctx, get_session_info_system(),
+                                         p->msg_ctx, info)) {
+                       status = WERR_PRINTER_DRIVER_IN_USE;
                        goto done;
                }
 
+               status = winreg_del_driver(tmp_ctx, b, info, drv_cversion[i]);
+               if (!W_ERROR_IS_OK(status)) {
+                       DEBUG(0, ("failed del of driver with version %d\n",
+                                 drv_cversion[i]));
+                       goto done;
+               }
        }
+       if (found == false) {
+               DEBUG(0, ("driver %s not found for deletion\n", r->in.driver));
+               status = WERR_UNKNOWN_PRINTER_DRIVER;
+       } else {
+               status = WERR_OK;
+       }
+
+done:
+       talloc_free(tmp_ctx);
+       return status;
+}
 
-       if (printer_driver_in_use(p->mem_ctx,
-                                 get_server_info_system(),
-                                 p->msg_ctx,
-                                 info)) {
+static WERROR spoolss_dpd_version(TALLOC_CTX *mem_ctx,
+                                 struct pipes_struct *p,
+                                 struct spoolss_DeletePrinterDriverEx *r,
+                                 struct dcerpc_binding_handle *b,
+                                 struct spoolss_DriverInfo8 *info)
+{
+       WERROR status;
+       bool delete_files;
+
+       if (printer_driver_in_use(mem_ctx, get_session_info_system(),
+                                 p->msg_ctx, info)) {
                status = WERR_PRINTER_DRIVER_IN_USE;
                goto done;
        }
 
-       if (version == 2) {
-               status = winreg_get_driver(p->mem_ctx,
-                                          get_server_info_system(),
-                                          p->msg_ctx,
-                                          r->in.architecture,
-                                          r->in.driver, 3, &info_win2k);
-               if (W_ERROR_IS_OK(status)) {
-                       /* if we get to here, we now have 2 driver info structures to remove */
-                       /* remove the Win2k driver first*/
-
-                       status = winreg_del_driver(p->mem_ctx,
-                                                  get_server_info_system(),
-                                                  p->msg_ctx,
-                                                  info_win2k, 3);
-                       talloc_free(info_win2k);
+       /*
+        * we have a couple of cases to consider.
+        * (1) Are any files in use?  If so and DPD_DELETE_ALL_FILES is set,
+        *     then the delete should fail if **any** files overlap with
+        *     other drivers
+        * (2) If DPD_DELETE_UNUSED_FILES is set, then delete all
+        *     non-overlapping files
+        * (3) If neither DPD_DELETE_ALL_FILES nor DPD_DELETE_UNUSED_FILES
+        *     is set, then do not delete any files
+        * Refer to MSDN docs on DeletePrinterDriverEx() for details.
+        */
 
-                       /* this should not have failed---if it did, report to client */
-                       if (!W_ERROR_IS_OK(status)) {
-                               goto done;
-                       }
+       delete_files = r->in.delete_flags
+                       & (DPD_DELETE_ALL_FILES | DPD_DELETE_UNUSED_FILES);
+
+       if (delete_files) {
+               bool in_use = printer_driver_files_in_use(mem_ctx,
+                                               get_session_info_system(),
+                                                         p->msg_ctx,
+                                                         info);
+               if (in_use && (r->in.delete_flags & DPD_DELETE_ALL_FILES)) {
+                       status = WERR_PRINTER_DRIVER_IN_USE;
+                       goto done;
                }
+               /*
+                * printer_driver_files_in_use() has trimmed overlapping files
+                * from info so they are not removed on DPD_DELETE_UNUSED_FILES
+                */
        }
 
-       status = winreg_del_driver(p->mem_ctx,
-                                  get_server_info_system(),
-                                  p->msg_ctx,
-                                  info, version);
+       status = winreg_del_driver(mem_ctx, b, info, info->version);
+       if (!W_ERROR_IS_OK(status)) {
+               goto done;
+       }
 
-done:
-       talloc_free(info);
+       /*
+        * now delete any associated files if delete_files is
+        * true. Even if this part failes, we return succes
+        * because the driver doesn not exist any more
+        */
+       if (delete_files) {
+               delete_driver_files(get_session_info_system(), info);
+       }
 
+done:
        return status;
 }
 
@@ -2145,174 +2216,79 @@ done:
 WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
                                      struct spoolss_DeletePrinterDriverEx *r)
 {
-       struct spoolss_DriverInfo8      *info = NULL;
-       struct spoolss_DriverInfo8      *info_win2k = NULL;
-       int                             version;
-       bool                            delete_files;
+       struct spoolss_DriverInfo8 *info = NULL;
        WERROR                          status;
+       struct dcerpc_binding_handle *b;
+       TALLOC_CTX *tmp_ctx = NULL;
+       int i;
+       bool found;
 
        /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
           and not a printer admin, then fail */
 
-       if ( (p->server_info->utok.uid != sec_initial_uid())
-               && !security_token_has_privilege(p->server_info->ptok, SEC_PRIV_PRINT_OPERATOR)
+       if ( (p->session_info->utok.uid != sec_initial_uid())
+               && !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_PRINT_OPERATOR)
                && !token_contains_name_in_list(
-                       uidtoname(p->server_info->utok.uid),
-                       p->server_info->info3->base.domain.string,
+                       uidtoname(p->session_info->utok.uid),
+                       p->session_info->info3->base.domain.string,
                        NULL,
-                       p->server_info->ptok, lp_printer_admin(-1)) )
+                       p->session_info->security_token, lp_printer_admin(-1)) )
        {
                return WERR_ACCESS_DENIED;
        }
 
        /* check that we have a valid driver name first */
-       if ((version = get_version_id(r->in.architecture)) == -1) {
+       if (get_version_id(r->in.architecture) == -1) {
                /* this is what NT returns */
                return WERR_INVALID_ENVIRONMENT;
        }
 
-       if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
-               version = r->in.version;
-
-       status = winreg_get_driver(p->mem_ctx,
-                                  get_server_info_system(),
-                                  p->msg_ctx,
-                                  r->in.architecture,
-                                  r->in.driver,
-                                  version,
-                                  &info);
-       if (!W_ERROR_IS_OK(status)) {
-               status = WERR_UNKNOWN_PRINTER_DRIVER;
-
-               /*
-                * if the client asked for a specific version,
-                * or this is something other than Windows NT x86,
-                * then we've failed
-                */
-
-               if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
-                       goto done;
-
-               /* try for Win2k driver if "Windows NT x86" */
-
-               version = 3;
-               status = winreg_get_driver(info,
-                                          get_server_info_system(),
-                                          p->msg_ctx,
-                                          r->in.architecture,
-                                          r->in.driver,
-                                          version, &info);
-               if (!W_ERROR_IS_OK(status)) {
-                       status = WERR_UNKNOWN_PRINTER_DRIVER;
-                       goto done;
-               }
-       }
-
-       if (printer_driver_in_use(info,
-                                 get_server_info_system(),
-                                 p->msg_ctx,
-                                 info)) {
-               status = WERR_PRINTER_DRIVER_IN_USE;
-               goto done;
+       tmp_ctx = talloc_new(p->mem_ctx);
+       if (!tmp_ctx) {
+               return WERR_NOMEM;
        }
 
-       /*
-        * we have a couple of cases to consider.
-        * (1) Are any files in use?  If so and DPD_DELTE_ALL_FILE is set,
-        *     then the delete should fail if **any** files overlap with
-        *     other drivers
-        * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
-        *     non-overlapping files
-        * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
-        *     is set, the do not delete any files
-        * Refer to MSDN docs on DeletePrinterDriverEx() for details.
-        */
-
-       delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
-
-       /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
-
-       if (delete_files &&
-           (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
-           printer_driver_files_in_use(info,
-                                       get_server_info_system(),
-                                       p->msg_ctx,
-                                       info)) {
-               /* no idea of the correct error here */
-               status = WERR_ACCESS_DENIED;
+       status = winreg_printer_binding_handle(tmp_ctx,
+                                              get_session_info_system(),
+                                              p->msg_ctx,
+                                              &b);
+       if (!W_ERROR_IS_OK(status)) {
                goto done;
        }
 
+       for (found = false, i = 0; drv_cversion[i] >= 0; i++) {
+               if ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
+                && (drv_cversion[i] != r->in.version)) {
+                       continue;
+               }
 
-       /* also check for W32X86/3 if necessary; maybe we already have? */
-
-       if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION)  ) {
-               status = winreg_get_driver(info,
-                                          get_server_info_system(),
-                                          p->msg_ctx,
-                                          r->in.architecture,
-                                          r->in.driver, 3, &info_win2k);
-               if (W_ERROR_IS_OK(status)) {
-
-                       if (delete_files &&
-                           (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
-                           printer_driver_files_in_use(info,
-                                                       get_server_info_system(),
-                                                       p->msg_ctx,
-                                                       info_win2k)) {
-                               /* no idea of the correct error here */
-                               talloc_free(info_win2k);
-                               status = WERR_ACCESS_DENIED;
-                               goto done;
-                       }
-
-                       /* if we get to here, we now have 2 driver info structures to remove */
-                       /* remove the Win2k driver first*/
-
-                       status = winreg_del_driver(info,
-                                                  get_server_info_system(),
-                                                  p->msg_ctx,
-                                                  info_win2k,
-                                                  3);
-
-                       /* this should not have failed---if it did, report to client */
-
-                       if (!W_ERROR_IS_OK(status)) {
-                               goto done;
-                       }
-
-                       /*
-                        * now delete any associated files if delete_files is
-                        * true. Even if this part failes, we return succes
-                        * because the driver doesn not exist any more
-                        */
-                       if (delete_files) {
-                               delete_driver_files(get_server_info_system(),
-                                                   info_win2k);
-                       }
+               /* check if a driver with this version exists before delete */
+               status = winreg_get_driver(tmp_ctx, b,
+                                          r->in.architecture, r->in.driver,
+                                          drv_cversion[i], &info);
+               if (!W_ERROR_IS_OK(status)) {
+                       DEBUG(5, ("skipping del of driver with version %d\n",
+                                 drv_cversion[i]));
+                       continue;
                }
-       }
+               found = true;
 
-       status = winreg_del_driver(info,
-                                  get_server_info_system(),
-                                  p->msg_ctx,
-                                  info,
-                                  version);
-       if (!W_ERROR_IS_OK(status)) {
-               goto done;
+               status = spoolss_dpd_version(tmp_ctx, p, r, b, info);
+               if (!W_ERROR_IS_OK(status)) {
+                       DEBUG(0, ("failed to delete driver with version %d\n",
+                                 drv_cversion[i]));
+                       goto done;
+               }
        }
-
-       /*
-        * now delete any associated files if delete_files is
-        * true. Even if this part failes, we return succes
-        * because the driver doesn not exist any more
-        */
-       if (delete_files) {
-               delete_driver_files(get_server_info_system(), info);
+       if (found == false) {
+               DEBUG(0, ("driver %s not found for deletion\n", r->in.driver));
+               status = WERR_UNKNOWN_PRINTER_DRIVER;
+       } else {
+               status = WERR_OK;
        }
 
 done:
-       talloc_free(info);
+       talloc_free(tmp_ctx);
        return status;
 }
 
@@ -2733,6 +2709,12 @@ WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct pipes_struct *p,
        DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
                "client_address is %s\n", p->client_id->addr));
 
+       if (!lp_print_notify_backchannel(snum)) {
+               DEBUG(10, ("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
+                       "backchannel disabled\n"));
+               return WERR_SERVER_UNAVAILABLE;
+       }
+
        if (!interpret_string_addr(&client_ss, p->client_id->addr,
                                   AI_NUMERICHOST)) {
                return WERR_SERVER_UNAVAILABLE;
@@ -2863,7 +2845,21 @@ static void spoolss_notify_location(struct messaging_context *msg_ctx,
                                    struct spoolss_PrinterInfo2 *pinfo2,
                                    TALLOC_CTX *mem_ctx)
 {
-       SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->location);
+       const char *loc = pinfo2->location;
+       NTSTATUS status;
+
+       status = printer_list_get_printer(mem_ctx,
+                                         pinfo2->sharename,
+                                         NULL,
+                                         &loc,
+                                         NULL);
+       if (NT_STATUS_IS_OK(status)) {
+               if (loc == NULL) {
+                       loc = pinfo2->location;
+               }
+       }
+
+       SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, loc);
 }
 
 /*******************************************************************
@@ -3223,7 +3219,7 @@ static void spoolss_notify_job_position(struct messaging_context *msg_ctx,
                                        struct spoolss_PrinterInfo2 *pinfo2,
                                        TALLOC_CTX *mem_ctx)
 {
-       SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
+       SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->sysjob);
 }
 
 /*******************************************************************
@@ -3391,7 +3387,6 @@ static bool construct_notify_printer_info(struct messaging_context *msg_ctx,
        uint16_t field;
 
        struct spoolss_Notify *current_data;
-       print_queue_struct *queue=NULL;
 
        type = option_type->type;
 
@@ -3425,7 +3420,7 @@ static bool construct_notify_printer_info(struct messaging_context *msg_ctx,
                           pinfo2->printername));
 
                notify_info_data_table[j].fn(msg_ctx, snum, current_data,
-                                            queue, pinfo2, mem_ctx);
+                                            NULL, pinfo2, mem_ctx);
 
                info->count++;
        }
@@ -3560,9 +3555,9 @@ static WERROR printserver_notify_info(struct pipes_struct *p,
                                continue; /* skip */
                        }
 
-                       /* Maybe we should use the SYSTEM server_info here... */
-                       result = winreg_get_printer(mem_ctx,
-                                                   get_server_info_system(),
+                       /* Maybe we should use the SYSTEM session_info here... */
+                       result = winreg_get_printer_internal(mem_ctx,
+                                                   get_session_info_system(),
                                                    p->msg_ctx,
                                                    lp_servicename(snum),
                                                    &pinfo2);
@@ -3644,17 +3639,28 @@ static WERROR printer_notify_info(struct pipes_struct *p,
        if ( !option )
                return WERR_BADFID;
 
-       get_printer_snum(p, hnd, &snum, NULL);
+       if (!get_printer_snum(p, hnd, &snum, NULL)) {
+               return WERR_BADFID;
+       }
 
-       /* Maybe we should use the SYSTEM server_info here... */
-       result = winreg_get_printer(mem_ctx,
-                                   get_server_info_system(),
+       /* Maybe we should use the SYSTEM session_info here... */
+       result = winreg_get_printer_internal(mem_ctx,
+                                   get_session_info_system(),
                                    p->msg_ctx,
                                    lp_servicename(snum), &pinfo2);
        if (!W_ERROR_IS_OK(result)) {
                return WERR_BADFID;
        }
 
+       /*
+        * When sending a PRINTER_NOTIFY_FIELD_SERVER_NAME we should send the
+        * correct servername.
+        */
+       pinfo2->servername = talloc_strdup(pinfo2, Printer->servername);
+       if (pinfo2->servername == NULL) {
+               return WERR_NOMEM;
+       }
+
        for (i=0; i<option->count; i++) {
                option_type = option->types[i];
 
@@ -3679,7 +3685,7 @@ static WERROR printer_notify_info(struct pipes_struct *p,
                                                           &queue[j], info,
                                                           pinfo2, snum,
                                                           &option_type,
-                                                          queue[j].job,
+                                                          queue[j].sysjob,
                                                           mem_ctx);
                        }
 
@@ -3741,7 +3747,7 @@ WERROR _spoolss_RouterRefreshPrinterChangeNotify(struct pipes_struct *p,
         *      We are now using the change value, and
         *      I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
         *      I don't have a global notification system, I'm sending back all the
-        *      informations even when _NOTHING_ has changed.
+        *      information even when _NOTHING_ has changed.
         */
 
        /* We need to keep track of the change value to send back in
@@ -3823,7 +3829,7 @@ static void compose_devicemode_devicename(struct spoolss_DeviceMode *dm,
  ********************************************************************/
 
 static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
-                                     const struct auth_serversupplied_info *server_info,
+                                     const struct auth_serversupplied_info *session_info,
                                      struct messaging_context *msg_ctx,
                                      struct spoolss_PrinterInfo2 *info2,
                                      const char *servername,
@@ -3896,7 +3902,7 @@ static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
        r->high_part_total_bytes        = 0x0;
 
        /* ChangeID in milliseconds*/
-       winreg_printer_get_changeid(mem_ctx, server_info, msg_ctx,
+       winreg_printer_get_changeid_internal(mem_ctx, session_info, msg_ctx,
                                    info2->sharename, &r->change_id);
 
        r->last_error                   = WERR_OK;
@@ -3994,8 +4000,24 @@ static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
        }
        W_ERROR_HAVE_NO_MEMORY(r->comment);
 
-       r->location             = talloc_strdup(mem_ctx, info2->location);
+       r->location     = talloc_strdup(mem_ctx, info2->location);
+       if (info2->location[0] == '\0') {
+               const char *loc = NULL;
+               NTSTATUS nt_status;
+
+               nt_status = printer_list_get_printer(mem_ctx,
+                                                    info2->sharename,
+                                                    NULL,
+                                                    &loc,
+                                                    NULL);
+               if (NT_STATUS_IS_OK(nt_status)) {
+                       if (loc != NULL) {
+                               r->location = talloc_strdup(mem_ctx, loc);
+                       }
+               }
+       }
        W_ERROR_HAVE_NO_MEMORY(r->location);
+
        r->sepfile              = talloc_strdup(mem_ctx, info2->sepfile);
        W_ERROR_HAVE_NO_MEMORY(r->sepfile);
        r->printprocessor       = talloc_strdup(mem_ctx, info2->printprocessor);
@@ -4151,18 +4173,18 @@ static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
                                      struct spoolss_PrinterInfo7 *r,
                                      int snum)
 {
-       struct auth_serversupplied_info *server_info;
+       struct auth_serversupplied_info *session_info;
        struct GUID guid;
        NTSTATUS status;
 
-       status = make_server_info_system(mem_ctx, &server_info);
+       status = make_session_info_system(mem_ctx, &session_info);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("construct_printer_info7: "
-                         "Could not create system server_info\n"));
+                         "Could not create system session_info\n"));
                return WERR_NOMEM;
        }
 
-       if (is_printer_published(mem_ctx, server_info, msg_ctx,
+       if (is_printer_published(mem_ctx, session_info, msg_ctx,
                                 servername,
                                 lp_servicename(snum), &guid, NULL)) {
                r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
@@ -4173,7 +4195,7 @@ static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
        }
        W_ERROR_HAVE_NO_MEMORY(r->guid);
 
-       TALLOC_FREE(server_info);
+       TALLOC_FREE(session_info);
        return WERR_OK;
 }
 
@@ -4220,7 +4242,7 @@ static bool snum_is_shared_printer(int snum)
 ********************************************************************/
 
 static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
-                                          const struct auth_serversupplied_info *server_info,
+                                          const struct auth_serversupplied_info *session_info,
                                           struct messaging_context *msg_ctx,
                                           const char *servername,
                                           uint32_t level,
@@ -4233,6 +4255,7 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
        union spoolss_PrinterInfo *info = NULL;
        uint32_t count = 0;
        WERROR result = WERR_OK;
+       struct dcerpc_binding_handle *b = NULL;
 
        *count_p = 0;
        *info_p = NULL;
@@ -4251,9 +4274,17 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
                DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
                        printer, snum));
 
-               result = winreg_create_printer(mem_ctx,
-                                              server_info,
-                                              msg_ctx,
+               if (b == NULL) {
+                       result = winreg_printer_binding_handle(mem_ctx,
+                                                              session_info,
+                                                              msg_ctx,
+                                                              &b);
+                       if (!W_ERROR_IS_OK(result)) {
+                               goto out;
+                       }
+               }
+
+               result = winreg_create_printer(mem_ctx, b,
                                               printer);
                if (!W_ERROR_IS_OK(result)) {
                        goto out;
@@ -4267,7 +4298,7 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
                        goto out;
                }
 
-               result = winreg_get_printer(mem_ctx, server_info, msg_ctx,
+               result = winreg_get_printer(mem_ctx, b,
                                            printer, &info2);
                if (!W_ERROR_IS_OK(result)) {
                        goto out;
@@ -4275,7 +4306,7 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
 
                switch (level) {
                case 0:
-                       result = construct_printer_info0(info, server_info,
+                       result = construct_printer_info0(info, session_info,
                                                         msg_ctx, info2,
                                                         servername,
                                                         &info[count].info0, snum);
@@ -4332,7 +4363,7 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
  ********************************************************************/
 
 static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
-                                 const struct auth_serversupplied_info *server_info,
+                                 const struct auth_serversupplied_info *session_info,
                                  struct messaging_context *msg_ctx,
                                  uint32_t flags,
                                  const char *servername,
@@ -4341,7 +4372,7 @@ static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
 {
        DEBUG(4,("enum_all_printers_info_0\n"));
 
-       return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
+       return enum_all_printers_info_level(mem_ctx, session_info, msg_ctx,
                                            servername, 0, flags, info, count);
 }
 
@@ -4350,7 +4381,7 @@ static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
 ********************************************************************/
 
 static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
-                                      const struct auth_serversupplied_info *server_info,
+                                      const struct auth_serversupplied_info *session_info,
                                       struct messaging_context *msg_ctx,
                                       const char *servername,
                                       uint32_t flags,
@@ -4359,7 +4390,7 @@ static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
 {
        DEBUG(4,("enum_all_printers_info_1\n"));
 
-       return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
+       return enum_all_printers_info_level(mem_ctx, session_info, msg_ctx,
                                            servername, 1, flags, info, count);
 }
 
@@ -4368,7 +4399,7 @@ static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
 *********************************************************************/
 
 static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
-                                            const struct auth_serversupplied_info *server_info,
+                                            const struct auth_serversupplied_info *session_info,
                                             struct messaging_context *msg_ctx,
                                             const char *servername,
                                             union spoolss_PrinterInfo **info,
@@ -4376,7 +4407,7 @@ static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
 {
        DEBUG(4,("enum_all_printers_info_1_local\n"));
 
-       return enum_all_printers_info_1(mem_ctx, server_info, msg_ctx,
+       return enum_all_printers_info_1(mem_ctx, session_info, msg_ctx,
                                        servername, PRINTER_ENUM_ICON8, info, count);
 }
 
@@ -4385,7 +4416,7 @@ static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
 *********************************************************************/
 
 static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
-                                           const struct auth_serversupplied_info *server_info,
+                                           const struct auth_serversupplied_info *session_info,
                                            struct messaging_context *msg_ctx,
                                            const char *servername,
                                            union spoolss_PrinterInfo **info,
@@ -4403,7 +4434,7 @@ static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
                return WERR_INVALID_NAME;
        }
 
-       return enum_all_printers_info_1(mem_ctx, server_info, msg_ctx,
+       return enum_all_printers_info_1(mem_ctx, session_info, msg_ctx,
                                        servername, PRINTER_ENUM_ICON8, info, count);
 }
 
@@ -4412,7 +4443,7 @@ static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
 *********************************************************************/
 
 static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
-                                              const struct auth_serversupplied_info *server_info,
+                                              const struct auth_serversupplied_info *session_info,
                                               struct messaging_context *msg_ctx,
                                               const char *servername,
                                               union spoolss_PrinterInfo **info,
@@ -4438,7 +4469,7 @@ static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
                 return WERR_CAN_NOT_COMPLETE;
        }
 
-       return enum_all_printers_info_1(mem_ctx, server_info, msg_ctx,
+       return enum_all_printers_info_1(mem_ctx, session_info, msg_ctx,
                                        servername, PRINTER_ENUM_NAME, info, count);
 }
 
@@ -4449,7 +4480,7 @@ static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
  ********************************************************************/
 
 static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
-                                      const struct auth_serversupplied_info *server_info,
+                                      const struct auth_serversupplied_info *session_info,
                                       struct messaging_context *msg_ctx,
                                       const char *servername,
                                       union spoolss_PrinterInfo **info,
@@ -4457,7 +4488,7 @@ static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
 {
        DEBUG(4,("enum_all_printers_info_2\n"));
 
-       return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
+       return enum_all_printers_info_level(mem_ctx, session_info, msg_ctx,
                                            servername, 2, 0, info, count);
 }
 
@@ -4466,7 +4497,7 @@ static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
  ********************************************************************/
 
 static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
-                                 const struct auth_serversupplied_info *server_info,
+                                 const struct auth_serversupplied_info *session_info,
                                  struct messaging_context *msg_ctx,
                                  uint32_t flags,
                                  const char *servername,
@@ -4476,18 +4507,18 @@ static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
        /* Not all the flags are equals */
 
        if (flags & PRINTER_ENUM_LOCAL) {
-               return enum_all_printers_info_1_local(mem_ctx, server_info,
+               return enum_all_printers_info_1_local(mem_ctx, session_info,
                                                      msg_ctx, servername, info, count);
        }
 
        if (flags & PRINTER_ENUM_NAME) {
-               return enum_all_printers_info_1_name(mem_ctx, server_info,
+               return enum_all_printers_info_1_name(mem_ctx, session_info,
                                                     msg_ctx, servername, info,
                                                     count);
        }
 
        if (flags & PRINTER_ENUM_NETWORK) {
-               return enum_all_printers_info_1_network(mem_ctx, server_info,
+               return enum_all_printers_info_1_network(mem_ctx, session_info,
                                                        msg_ctx, servername, info,
                                                        count);
        }
@@ -4500,7 +4531,7 @@ static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
  ********************************************************************/
 
 static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
-                                 const struct auth_serversupplied_info *server_info,
+                                 const struct auth_serversupplied_info *session_info,
                                  struct messaging_context *msg_ctx,
                                  uint32_t flags,
                                  const char *servername,
@@ -4509,7 +4540,7 @@ static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
 {
        if (flags & PRINTER_ENUM_LOCAL) {
 
-               return enum_all_printers_info_2(mem_ctx, server_info, msg_ctx,
+               return enum_all_printers_info_2(mem_ctx, session_info, msg_ctx,
                                                servername,
                                                info, count);
        }
@@ -4519,7 +4550,7 @@ static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
                        return WERR_INVALID_NAME;
                }
 
-               return enum_all_printers_info_2(mem_ctx, server_info, msg_ctx,
+               return enum_all_printers_info_2(mem_ctx, session_info, msg_ctx,
                                                servername,
                                                info, count);
        }
@@ -4536,7 +4567,7 @@ static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
  ********************************************************************/
 
 static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
-                                 const struct auth_serversupplied_info *server_info,
+                                 const struct auth_serversupplied_info *session_info,
                                  struct messaging_context *msg_ctx,
                                  uint32_t flags,
                                  const char *servername,
@@ -4545,7 +4576,7 @@ static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
 {
        DEBUG(4,("enum_all_printers_info_4\n"));
 
-       return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
+       return enum_all_printers_info_level(mem_ctx, session_info, msg_ctx,
                                            servername, 4, flags, info, count);
 }
 
@@ -4555,7 +4586,7 @@ static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
  ********************************************************************/
 
 static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
-                                 const struct auth_serversupplied_info *server_info,
+                                 const struct auth_serversupplied_info *session_info,
                                  struct messaging_context *msg_ctx,
                                  uint32_t flags,
                                  const char *servername,
@@ -4564,7 +4595,7 @@ static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
 {
        DEBUG(4,("enum_all_printers_info_5\n"));
 
-       return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
+       return enum_all_printers_info_level(mem_ctx, session_info, msg_ctx,
                                            servername, 5, flags, info, count);
 }
 
@@ -4575,7 +4606,7 @@ static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
 WERROR _spoolss_EnumPrinters(struct pipes_struct *p,
                             struct spoolss_EnumPrinters *r)
 {
-       const struct auth_serversupplied_info *server_info = get_server_info_system();
+       const struct auth_serversupplied_info *session_info = get_session_info_system();
        WERROR result;
 
        /* that's an [in out] buffer */
@@ -4609,31 +4640,31 @@ WERROR _spoolss_EnumPrinters(struct pipes_struct *p,
 
        switch (r->in.level) {
        case 0:
-               result = enumprinters_level0(p->mem_ctx, server_info,
+               result = enumprinters_level0(p->mem_ctx, session_info,
                                             p->msg_ctx, r->in.flags,
                                             r->in.server,
                                             r->out.info, r->out.count);
                break;
        case 1:
-               result = enumprinters_level1(p->mem_ctx, server_info,
+               result = enumprinters_level1(p->mem_ctx, session_info,
                                             p->msg_ctx, r->in.flags,
                                             r->in.server,
                                             r->out.info, r->out.count);
                break;
        case 2:
-               result = enumprinters_level2(p->mem_ctx, server_info,
+               result = enumprinters_level2(p->mem_ctx, session_info,
                                             p->msg_ctx, r->in.flags,
                                             r->in.server,
                                             r->out.info, r->out.count);
                break;
        case 4:
-               result = enumprinters_level4(p->mem_ctx, server_info,
+               result = enumprinters_level4(p->mem_ctx, session_info,
                                             p->msg_ctx, r->in.flags,
                                             r->in.server,
                                             r->out.info, r->out.count);
                break;
        case 5:
-               result = enumprinters_level5(p->mem_ctx, server_info,
+               result = enumprinters_level5(p->mem_ctx, session_info,
                                             p->msg_ctx, r->in.flags,
                                             r->in.server,
                                             r->out.info, r->out.count);
@@ -4684,8 +4715,8 @@ WERROR _spoolss_GetPrinter(struct pipes_struct *p,
                return WERR_BADFID;
        }
 
-       result = winreg_get_printer(p->mem_ctx,
-                                   get_server_info_system(),
+       result = winreg_get_printer_internal(p->mem_ctx,
+                                   get_session_info_system(),
                                    p->msg_ctx,
                                    lp_const_servicename(snum),
                                    &info2);
@@ -4696,7 +4727,7 @@ WERROR _spoolss_GetPrinter(struct pipes_struct *p,
        switch (r->in.level) {
        case 0:
                result = construct_printer_info0(p->mem_ctx,
-                                                get_server_info_system(),
+                                                get_session_info_system(),
                                                 p->msg_ctx,
                                                 info2,
                                                 Printer->servername,
@@ -5445,7 +5476,7 @@ static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
  ********************************************************************/
 
 static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
-                                                 const struct auth_serversupplied_info *server_info,
+                                                 const struct auth_serversupplied_info *session_info,
                                                  struct messaging_context *msg_ctx,
                                                  uint32_t level,
                                                  union spoolss_DriverInfo *r,
@@ -5457,14 +5488,21 @@ static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
        struct spoolss_PrinterInfo2 *pinfo2 = NULL;
        struct spoolss_DriverInfo8 *driver;
        WERROR result;
+       struct dcerpc_binding_handle *b;
 
        if (level == 101) {
                return WERR_UNKNOWN_LEVEL;
        }
 
-       result = winreg_get_printer(mem_ctx,
-                                   server_info,
-                                   msg_ctx,
+       result = winreg_printer_binding_handle(mem_ctx,
+                                              session_info,
+                                              msg_ctx,
+                                              &b);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
+       result = winreg_get_printer(mem_ctx, b,
                                    lp_const_servicename(snum),
                                    &pinfo2);
 
@@ -5475,7 +5513,7 @@ static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
                return WERR_INVALID_PRINTER_NAME;
        }
 
-       result = winreg_get_driver(mem_ctx, server_info, msg_ctx,
+       result = winreg_get_driver(mem_ctx, b,
                                   architecture,
                                   pinfo2->drivername, version, &driver);
 
@@ -5494,7 +5532,7 @@ static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
 
                /* Yes - try again with a WinNT driver. */
                version = 2;
-               result = winreg_get_driver(mem_ctx, server_info, msg_ctx,
+               result = winreg_get_driver(mem_ctx, b,
                                           architecture,
                                           pinfo2->drivername,
                                           version, &driver);
@@ -5578,7 +5616,7 @@ WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p,
        }
 
        result = construct_printer_driver_info_level(p->mem_ctx,
-                                                    get_server_info_system(),
+                                                    get_session_info_system(),
                                                     p->msg_ctx,
                                                     r->in.level, r->out.info,
                                                     snum, printer->servername,
@@ -5694,7 +5732,7 @@ WERROR _spoolss_StartDocPrinter(struct pipes_struct *p,
                return WERR_BADFID;
        }
 
-       werr = print_job_start(p->server_info,
+       werr = print_job_start(p->session_info,
                               p->msg_ctx,
                               p->client_id->name,
                               snum,
@@ -5797,7 +5835,7 @@ WERROR _spoolss_WritePrinter(struct pipes_struct *p,
 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
                              struct pipes_struct *p)
 {
-       const struct auth_serversupplied_info *server_info = p->server_info;
+       const struct auth_serversupplied_info *session_info = p->session_info;
        int snum;
        WERROR errcode = WERR_BADFUNC;
        struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
@@ -5813,14 +5851,14 @@ static WERROR control_printer(struct policy_handle *handle, uint32_t command,
 
        switch (command) {
        case SPOOLSS_PRINTER_CONTROL_PAUSE:
-               errcode = print_queue_pause(server_info, p->msg_ctx, snum);
+               errcode = print_queue_pause(session_info, p->msg_ctx, snum);
                break;
        case SPOOLSS_PRINTER_CONTROL_RESUME:
        case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
-               errcode = print_queue_resume(server_info, p->msg_ctx, snum);
+               errcode = print_queue_resume(session_info, p->msg_ctx, snum);
                break;
        case SPOOLSS_PRINTER_CONTROL_PURGE:
-               errcode = print_queue_purge(server_info, p->msg_ctx, snum);
+               errcode = print_queue_purge(session_info, p->msg_ctx, snum);
                break;
        default:
                return WERR_UNKNOWN_LEVEL;
@@ -5856,7 +5894,7 @@ WERROR _spoolss_AbortPrinter(struct pipes_struct *p,
                return WERR_SPL_NO_STARTDOC;
        }
 
-       errcode = print_job_delete(p->server_info,
+       errcode = print_job_delete(p->session_info,
                                   p->msg_ctx,
                                   snum,
                                   Printer->jobid);
@@ -5878,8 +5916,8 @@ static WERROR update_printer_sec(struct policy_handle *handle,
        const char *printer;
        WERROR result;
        int snum;
-
        struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
+       struct dcerpc_binding_handle *b;
 
        if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
                DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
@@ -5907,15 +5945,21 @@ static WERROR update_printer_sec(struct policy_handle *handle,
                goto done;
        }
 
+       result = winreg_printer_binding_handle(p->mem_ctx,
+                                              get_session_info_system(),
+                                              p->msg_ctx,
+                                              &b);
+       if (!W_ERROR_IS_OK(result)) {
+               goto done;
+       }
+
        /* NT seems to like setting the security descriptor even though
           nothing may have actually changed. */
-       result = winreg_get_printer_secdesc(p->mem_ctx,
-                                           get_server_info_system(),
-                                           p->msg_ctx,
+       result = winreg_get_printer_secdesc(p->mem_ctx, b,
                                            printer,
                                            &old_secdesc);
        if (!W_ERROR_IS_OK(result)) {
-               DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n"));
+               DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc_internal() failed\n"));
                result = WERR_BADFID;
                goto done;
        }
@@ -5961,9 +6005,7 @@ static WERROR update_printer_sec(struct policy_handle *handle,
                goto done;
        }
 
-       result = winreg_set_printer_secdesc(p->mem_ctx,
-                                           get_server_info_system(),
-                                           p->msg_ctx,
+       result = winreg_set_printer_secdesc(p->mem_ctx, b,
                                            printer,
                                            new_secdesc);
 
@@ -6156,7 +6198,7 @@ static bool add_printer_hook(TALLOC_CTX *ctx, struct security_token *token,
 }
 
 static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
-                              const struct auth_serversupplied_info *server_info,
+                              const struct auth_serversupplied_info *session_info,
                               struct messaging_context *msg_ctx,
                               int snum,
                               struct spoolss_SetPrinterInfo2 *printer,
@@ -6169,12 +6211,19 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
        const char *spooling;
        DATA_BLOB buffer;
        WERROR result = WERR_OK;
+       struct dcerpc_binding_handle *b;
+
+       result = winreg_printer_binding_handle(mem_ctx,
+                                              session_info,
+                                              msg_ctx,
+                                              &b);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
 
        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,
-                                         msg_ctx,
+               winreg_set_printer_dataex(mem_ctx, b,
                                          printer->sharename,
                                          SPOOL_DSSPOOLER_KEY,
                                          SPOOL_REG_DRIVERNAME,
@@ -6194,9 +6243,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
 
        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,
-                                         msg_ctx,
+               winreg_set_printer_dataex(mem_ctx, b,
                                          printer->sharename,
                                          SPOOL_DSSPOOLER_KEY,
                                          SPOOL_REG_DESCRIPTION,
@@ -6213,9 +6260,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
 
        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,
-                                         msg_ctx,
+               winreg_set_printer_dataex(mem_ctx, b,
                                          printer->sharename,
                                          SPOOL_DSSPOOLER_KEY,
                                          SPOOL_REG_PRINTSHARENAME,
@@ -6242,9 +6287,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
                }
 
                push_reg_sz(mem_ctx, &buffer, p);
-               winreg_set_printer_dataex(mem_ctx,
-                                         server_info,
-                                         msg_ctx,
+               winreg_set_printer_dataex(mem_ctx, b,
                                          printer->sharename,
                                          SPOOL_DSSPOOLER_KEY,
                                          SPOOL_REG_PRINTERNAME,
@@ -6260,9 +6303,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
 
        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,
-                                         msg_ctx,
+               winreg_set_printer_dataex(mem_ctx, b,
                                          printer->sharename,
                                          SPOOL_DSSPOOLER_KEY,
                                          SPOOL_REG_PORTNAME,
@@ -6279,9 +6320,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
 
        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,
-                                         msg_ctx,
+               winreg_set_printer_dataex(mem_ctx, b,
                                          printer->sharename,
                                          SPOOL_DSSPOOLER_KEY,
                                          SPOOL_REG_LOCATION,
@@ -6299,9 +6338,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
 
        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,
-                                         msg_ctx,
+               winreg_set_printer_dataex(mem_ctx, b,
                                          printer->sharename,
                                          SPOOL_DSSPOOLER_KEY,
                                          SPOOL_REG_PRINTSEPARATORFILE,
@@ -6320,9 +6357,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
        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,
-                                         msg_ctx,
+               winreg_set_printer_dataex(mem_ctx, b,
                                          printer->sharename,
                                          SPOOL_DSSPOOLER_KEY,
                                          SPOOL_REG_PRINTSTARTTIME,
@@ -6334,9 +6369,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
        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,
-                                         msg_ctx,
+               winreg_set_printer_dataex(mem_ctx, b,
                                          printer->sharename,
                                          SPOOL_DSSPOOLER_KEY,
                                          SPOOL_REG_PRINTENDTIME,
@@ -6348,9 +6381,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
        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,
-                                         msg_ctx,
+               winreg_set_printer_dataex(mem_ctx, b,
                                          printer->sharename,
                                          SPOOL_DSSPOOLER_KEY,
                                          SPOOL_REG_PRIORITY,
@@ -6363,9 +6394,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
                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,
-                                         msg_ctx,
+               winreg_set_printer_dataex(mem_ctx, b,
                                          printer->sharename,
                                          SPOOL_DSSPOOLER_KEY,
                                          SPOOL_REG_PRINTKEEPPRINTEDJOBS,
@@ -6387,9 +6416,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
                                spooling = "unknown";
                }
                push_reg_sz(mem_ctx, &buffer, spooling);
-               winreg_set_printer_dataex(mem_ctx,
-                                         server_info,
-                                         msg_ctx,
+               winreg_set_printer_dataex(mem_ctx, b,
                                          printer->sharename,
                                          SPOOL_DSSPOOLER_KEY,
                                          SPOOL_REG_PRINTSPOOLING,
@@ -6399,9 +6426,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
        }
 
        push_reg_sz(mem_ctx, &buffer, global_myname());
-       winreg_set_printer_dataex(mem_ctx,
-                                 server_info,
-                                 msg_ctx,
+       winreg_set_printer_dataex(mem_ctx, b,
                                  printer->sharename,
                                  SPOOL_DSSPOOLER_KEY,
                                  SPOOL_REG_SHORTSERVERNAME,
@@ -6421,9 +6446,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
        }
 
        push_reg_sz(mem_ctx, &buffer, longname);
-       winreg_set_printer_dataex(mem_ctx,
-                                 server_info,
-                                 msg_ctx,
+       winreg_set_printer_dataex(mem_ctx, b,
                                  printer->sharename,
                                  SPOOL_DSSPOOLER_KEY,
                                  SPOOL_REG_SERVERNAME,
@@ -6434,9 +6457,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
        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,
-                                 msg_ctx,
+       winreg_set_printer_dataex(mem_ctx, b,
                                  printer->sharename,
                                  SPOOL_DSSPOOLER_KEY,
                                  SPOOL_REG_UNCNAME,
@@ -6465,6 +6486,7 @@ static WERROR update_printer(struct pipes_struct *p,
        int snum;
        WERROR result = WERR_OK;
        TALLOC_CTX *tmp_ctx;
+       struct dcerpc_binding_handle *b;
 
        DEBUG(8,("update_printer\n"));
 
@@ -6483,9 +6505,15 @@ static WERROR update_printer(struct pipes_struct *p,
                goto done;
        }
 
-       result = winreg_get_printer(tmp_ctx,
-                                   get_server_info_system(),
-                                   p->msg_ctx,
+       result = winreg_printer_binding_handle(tmp_ctx,
+                                              get_session_info_system(),
+                                              p->msg_ctx,
+                                              &b);
+       if (!W_ERROR_IS_OK(result)) {
+               goto done;
+       }
+
+       result = winreg_get_printer(tmp_ctx, b,
                                    lp_const_servicename(snum),
                                    &old_printer);
        if (!W_ERROR_IS_OK(result)) {
@@ -6519,7 +6547,7 @@ static WERROR update_printer(struct pipes_struct *p,
                         !strequal(printer->location, old_printer->location)) )
        {
                /* add_printer_hook() will call reload_services() */
-               if (!add_printer_hook(tmp_ctx, p->server_info->ptok,
+               if (!add_printer_hook(tmp_ctx, p->session_info->security_token,
                                      printer, p->client_id->addr,
                                      p->msg_ctx)) {
                        result = WERR_ACCESS_DENIED;
@@ -6528,7 +6556,7 @@ static WERROR update_printer(struct pipes_struct *p,
        }
 
        update_dsspooler(tmp_ctx,
-                        get_server_info_system(),
+                        get_session_info_system(),
                         p->msg_ctx,
                         snum,
                         printer,
@@ -6539,9 +6567,7 @@ static WERROR update_printer(struct pipes_struct *p,
        if (devmode == NULL) {
                printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
        }
-       result = winreg_update_printer(tmp_ctx,
-                                      get_server_info_system(),
-                                      p->msg_ctx,
+       result = winreg_update_printer(tmp_ctx, b,
                                       printer->sharename,
                                       printer_mask,
                                       printer,
@@ -6580,8 +6606,8 @@ static WERROR publish_or_unpublish_printer(struct pipes_struct *p,
        if (!get_printer_snum(p, handle, &snum, NULL))
                return WERR_BADFID;
 
-       result = winreg_get_printer(p->mem_ctx,
-                                   get_server_info_system(),
+       result = winreg_get_printer_internal(p->mem_ctx,
+                                   get_session_info_system(),
                                    p->msg_ctx,
                                    lp_servicename(snum),
                                    &pinfo2);
@@ -6590,7 +6616,7 @@ static WERROR publish_or_unpublish_printer(struct pipes_struct *p,
        }
 
        nt_printer_publish(pinfo2,
-                          get_server_info_system(),
+                          get_session_info_system(),
                           p->msg_ctx,
                           pinfo2,
                           info7->action);
@@ -6629,8 +6655,8 @@ static WERROR update_printer_devmode(struct pipes_struct *p,
                return WERR_ACCESS_DENIED;
        }
 
-       return winreg_update_printer(p->mem_ctx,
-                                    get_server_info_system(),
+       return winreg_update_printer_internal(p->mem_ctx,
+                                    get_session_info_system(),
                                     p->msg_ctx,
                                     lp_const_servicename(snum),
                                     info2_mask,
@@ -6757,7 +6783,7 @@ static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
 
        t = gmtime(&queue->time);
 
-       r->job_id               = queue->job;
+       r->job_id               = queue->sysjob;
 
        r->printer_name         = talloc_strdup(mem_ctx, lp_servicename(snum));
        W_ERROR_HAVE_NO_MEMORY(r->printer_name);
@@ -6798,7 +6824,7 @@ static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
 
        t = gmtime(&queue->time);
 
-       r->job_id               = queue->job;
+       r->job_id               = queue->sysjob;
 
        r->printer_name         = talloc_strdup(mem_ctx, lp_servicename(snum));
        W_ERROR_HAVE_NO_MEMORY(r->printer_name);
@@ -6851,10 +6877,10 @@ static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
                             int position, int snum,
                             struct spoolss_PrinterInfo2 *pinfo2)
 {
-       r->job_id               = queue->job;
+       r->job_id               = queue->sysjob;
        r->next_job_id          = 0;
        if (next_queue) {
-               r->next_job_id  = next_queue->job;
+               r->next_job_id  = next_queue->sysjob;
        }
        r->reserved             = 0;
 
@@ -7043,8 +7069,8 @@ WERROR _spoolss_EnumJobs(struct pipes_struct *p,
                return WERR_BADFID;
        }
 
-       result = winreg_get_printer(p->mem_ctx,
-                                   get_server_info_system(),
+       result = winreg_get_printer_internal(p->mem_ctx,
+                                   get_session_info_system(),
                                    p->msg_ctx,
                                    lp_const_servicename(snum),
                                    &pinfo2);
@@ -7141,7 +7167,7 @@ static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
 WERROR _spoolss_SetJob(struct pipes_struct *p,
                       struct spoolss_SetJob *r)
 {
-       const struct auth_serversupplied_info *server_info = p->server_info;
+       const struct auth_serversupplied_info *session_info = p->session_info;
        int snum;
        WERROR errcode = WERR_BADFUNC;
 
@@ -7156,24 +7182,20 @@ WERROR _spoolss_SetJob(struct pipes_struct *p,
        switch (r->in.command) {
        case SPOOLSS_JOB_CONTROL_CANCEL:
        case SPOOLSS_JOB_CONTROL_DELETE:
-               errcode = print_job_delete(server_info, p->msg_ctx,
+               errcode = print_job_delete(session_info, p->msg_ctx,
                                           snum, r->in.job_id);
                if (W_ERROR_EQUAL(errcode, WERR_PRINTER_HAS_JOBS_QUEUED)) {
                        errcode = WERR_OK;
                }
                break;
        case SPOOLSS_JOB_CONTROL_PAUSE:
-               if (print_job_pause(server_info, p->msg_ctx,
-                                   snum, r->in.job_id, &errcode)) {
-                       errcode = WERR_OK;
-               }
+               errcode = print_job_pause(session_info, p->msg_ctx,
+                                         snum, r->in.job_id);
                break;
        case SPOOLSS_JOB_CONTROL_RESTART:
        case SPOOLSS_JOB_CONTROL_RESUME:
-               if (print_job_resume(server_info, p->msg_ctx,
-                                    snum, r->in.job_id, &errcode)) {
-                       errcode = WERR_OK;
-               }
+               errcode = print_job_resume(session_info, p->msg_ctx,
+                                          snum, r->in.job_id);
                break;
        case 0:
                errcode = WERR_OK;
@@ -7212,7 +7234,7 @@ WERROR _spoolss_SetJob(struct pipes_struct *p,
 ****************************************************************************/
 
 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
-                                                      const struct auth_serversupplied_info *server_info,
+                                                      const struct auth_serversupplied_info *session_info,
                                                       struct messaging_context *msg_ctx,
                                                       const char *servername,
                                                       const char *architecture,
@@ -7228,12 +7250,21 @@ static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
        WERROR result = WERR_OK;
        uint32_t num_drivers;
        const char **drivers;
+       struct dcerpc_binding_handle *b;
 
        *count_p = 0;
        *info_p = NULL;
 
+       result = winreg_printer_binding_handle(mem_ctx,
+                                              session_info,
+                                              msg_ctx,
+                                              &b);
+       if (!W_ERROR_IS_OK(result)) {
+               goto out;
+       }
+
        for (version=0; version<DRIVER_MAX_VERSION; version++) {
-               result = winreg_get_driver_list(mem_ctx, server_info, msg_ctx,
+               result = winreg_get_driver_list(mem_ctx, b,
                                                architecture, version,
                                                &num_drivers, &drivers);
                if (!W_ERROR_IS_OK(result)) {
@@ -7258,8 +7289,7 @@ static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
                for (i = 0; i < num_drivers; i++) {
                        DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
 
-                       result = winreg_get_driver(mem_ctx, server_info,
-                                                  msg_ctx,
+                       result = winreg_get_driver(mem_ctx, b,
                                                   architecture, drivers[i],
                                                   version, &driver);
                        if (!W_ERROR_IS_OK(result)) {
@@ -7330,7 +7360,7 @@ static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
 ****************************************************************************/
 
 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
-                                      const struct auth_serversupplied_info *server_info,
+                                      const struct auth_serversupplied_info *session_info,
                                       struct messaging_context *msg_ctx,
                                       const char *servername,
                                       const char *architecture,
@@ -7349,7 +7379,7 @@ static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
                        uint32_t count = 0;
 
                        result = enumprinterdrivers_level_by_architecture(mem_ctx,
-                                                                         server_info,
+                                                                         session_info,
                                                                          msg_ctx,
                                                                          servername,
                                                                          archi_table[a].long_archi,
@@ -7370,7 +7400,7 @@ static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
        }
 
        return enumprinterdrivers_level_by_architecture(mem_ctx,
-                                                       server_info,
+                                                       session_info,
                                                        msg_ctx,
                                                        servername,
                                                        architecture,
@@ -7408,7 +7438,7 @@ WERROR _spoolss_EnumPrinterDrivers(struct pipes_struct *p,
        }
 
        result = enumprinterdrivers_level(p->mem_ctx,
-                                         get_server_info_system(),
+                                         get_session_info_system(),
                                          p->msg_ctx,
                                          cservername,
                                          r->in.environment,
@@ -7454,8 +7484,8 @@ WERROR _spoolss_EnumForms(struct pipes_struct *p,
 
        switch (r->in.level) {
        case 1:
-               result = winreg_printer_enumforms1(p->mem_ctx,
-                                                  get_server_info_system(),
+               result = winreg_printer_enumforms1_internal(p->mem_ctx,
+                                                  get_session_info_system(),
                                                   p->msg_ctx,
                                                   r->out.count,
                                                   r->out.info);
@@ -7504,8 +7534,8 @@ WERROR _spoolss_GetForm(struct pipes_struct *p,
 
        switch (r->in.level) {
        case 1:
-               result = winreg_printer_getform1(p->mem_ctx,
-                                                get_server_info_system(),
+               result = winreg_printer_getform1_internal(p->mem_ctx,
+                                                get_session_info_system(),
                                                 p->msg_ctx,
                                                 r->in.form_name,
                                                 &r->out.info->info1);
@@ -7836,14 +7866,14 @@ static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p,
           trying to add a printer like this  --jerry */
 
        if (*lp_addprinter_cmd() ) {
-               if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
+               if ( !add_printer_hook(p->mem_ctx, p->session_info->security_token,
                                       info2, p->client_id->addr,
                                       p->msg_ctx) ) {
                        return WERR_ACCESS_DENIED;
                }
        } else {
-               DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
-                       "smb.conf parameter \"addprinter command\" is defined. This"
+               DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no "
+                       "smb.conf parameter \"addprinter command\" is defined. This "
                        "parameter must exist for this call to succeed\n",
                        info2->sharename ));
        }
@@ -7853,7 +7883,7 @@ static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p,
        }
 
        /* you must be a printer admin to add a new printer */
-       if (!print_access_check(p->server_info,
+       if (!print_access_check(p->session_info,
                                p->msg_ctx,
                                snum,
                                PRINTER_ACCESS_ADMINISTER)) {
@@ -7873,14 +7903,14 @@ static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p,
        }
 
        update_dsspooler(p->mem_ctx,
-                        get_server_info_system(),
+                        get_session_info_system(),
                         p->msg_ctx,
                         0,
                         info2,
                         NULL);
 
-       err = winreg_update_printer(p->mem_ctx,
-                                   get_server_info_system(),
+       err = winreg_update_printer_internal(p->mem_ctx,
+                                   get_session_info_system(),
                                    p->msg_ctx,
                                    info2->sharename,
                                    info2_mask,
@@ -7996,18 +8026,18 @@ WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
        }
 
        DEBUG(5,("Cleaning driver's information\n"));
-       err = clean_up_driver_struct(p->mem_ctx, p, r->in.info_ctr);
+       err = clean_up_driver_struct(p->mem_ctx, p->session_info, r->in.info_ctr);
        if (!W_ERROR_IS_OK(err))
                goto done;
 
        DEBUG(5,("Moving driver to final destination\n"));
-       if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
-                                                             &err)) ) {
+       err = move_driver_to_download_area(p->session_info, r->in.info_ctr);
+       if (!W_ERROR_IS_OK(err)) {
                goto done;
        }
 
-       err = winreg_add_driver(p->mem_ctx,
-                               get_server_info_system(),
+       err = winreg_add_driver_internal(p->mem_ctx,
+                               get_session_info_system(),
                                p->msg_ctx,
                                r->in.info_ctr,
                                &driver_name,
@@ -8413,8 +8443,8 @@ WERROR _spoolss_AddForm(struct pipes_struct *p,
        struct spoolss_AddFormInfo1 *form = r->in.info.info1;
        int snum = -1;
        WERROR status = WERR_OK;
-
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
+       struct dcerpc_binding_handle *b;
 
        DEBUG(5,("_spoolss_AddForm\n"));
 
@@ -8427,12 +8457,12 @@ WERROR _spoolss_AddForm(struct pipes_struct *p,
        /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
           and not a printer admin, then fail */
 
-       if ((p->server_info->utok.uid != sec_initial_uid()) &&
-           !security_token_has_privilege(p->server_info->ptok, SEC_PRIV_PRINT_OPERATOR) &&
-           !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
-                                         p->server_info->info3->base.domain.string,
+       if ((p->session_info->utok.uid != sec_initial_uid()) &&
+           !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_PRINT_OPERATOR) &&
+           !token_contains_name_in_list(uidtoname(p->session_info->utok.uid),
+                                         p->session_info->info3->base.domain.string,
                                          NULL,
-                                         p->server_info->ptok,
+                                         p->session_info->security_token,
                                          lp_printer_admin(snum))) {
                DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
                return WERR_ACCESS_DENIED;
@@ -8447,9 +8477,15 @@ WERROR _spoolss_AddForm(struct pipes_struct *p,
                return WERR_INVALID_PARAM;
        }
 
-       status = winreg_printer_addform1(p->mem_ctx,
-                                        get_server_info_system(),
-                                        p->msg_ctx,
+       status = winreg_printer_binding_handle(p->mem_ctx,
+                                              get_session_info_system(),
+                                              p->msg_ctx,
+                                              &b);
+       if (!W_ERROR_IS_OK(status)) {
+               return status;
+       }
+
+       status = winreg_printer_addform1(p->mem_ctx, b,
                                         form);
        if (!W_ERROR_IS_OK(status)) {
                return status;
@@ -8463,9 +8499,7 @@ WERROR _spoolss_AddForm(struct pipes_struct *p,
                        return WERR_BADFID;
                }
 
-               status = winreg_printer_update_changeid(p->mem_ctx,
-                                                       get_server_info_system(),
-                                                       p->msg_ctx,
+               status = winreg_printer_update_changeid(p->mem_ctx, b,
                                                        lp_const_servicename(snum));
                if (!W_ERROR_IS_OK(status)) {
                        return status;
@@ -8486,6 +8520,7 @@ WERROR _spoolss_DeleteForm(struct pipes_struct *p,
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
        int snum = -1;
        WERROR status = WERR_OK;
+       struct dcerpc_binding_handle *b;
 
        DEBUG(5,("_spoolss_DeleteForm\n"));
 
@@ -8495,20 +8530,26 @@ WERROR _spoolss_DeleteForm(struct pipes_struct *p,
                return WERR_BADFID;
        }
 
-       if ((p->server_info->utok.uid != sec_initial_uid()) &&
-           !security_token_has_privilege(p->server_info->ptok, SEC_PRIV_PRINT_OPERATOR) &&
-           !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
-                                         p->server_info->info3->base.domain.string,
+       if ((p->session_info->utok.uid != sec_initial_uid()) &&
+           !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_PRINT_OPERATOR) &&
+           !token_contains_name_in_list(uidtoname(p->session_info->utok.uid),
+                                         p->session_info->info3->base.domain.string,
                                          NULL,
-                                         p->server_info->ptok,
+                                         p->session_info->security_token,
                                          lp_printer_admin(snum))) {
                DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
                return WERR_ACCESS_DENIED;
        }
 
-       status = winreg_printer_deleteform1(p->mem_ctx,
-                                           get_server_info_system(),
-                                           p->msg_ctx,
+       status = winreg_printer_binding_handle(p->mem_ctx,
+                                              get_session_info_system(),
+                                              p->msg_ctx,
+                                              &b);
+       if (!W_ERROR_IS_OK(status)) {
+               return status;
+       }
+
+       status = winreg_printer_deleteform1(p->mem_ctx, b,
                                            form_name);
        if (!W_ERROR_IS_OK(status)) {
                return status;
@@ -8522,9 +8563,7 @@ WERROR _spoolss_DeleteForm(struct pipes_struct *p,
                        return WERR_BADFID;
                }
 
-               status = winreg_printer_update_changeid(p->mem_ctx,
-                                                       get_server_info_system(),
-                                                       p->msg_ctx,
+               status = winreg_printer_update_changeid(p->mem_ctx, b,
                                                        lp_const_servicename(snum));
                if (!W_ERROR_IS_OK(status)) {
                        return status;
@@ -8545,6 +8584,7 @@ WERROR _spoolss_SetForm(struct pipes_struct *p,
        const char *form_name = r->in.form_name;
        int snum = -1;
        WERROR status = WERR_OK;
+       struct dcerpc_binding_handle *b;
 
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
@@ -8559,20 +8599,26 @@ WERROR _spoolss_SetForm(struct pipes_struct *p,
        /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
           and not a printer admin, then fail */
 
-       if ((p->server_info->utok.uid != sec_initial_uid()) &&
-            !security_token_has_privilege(p->server_info->ptok, SEC_PRIV_PRINT_OPERATOR) &&
-            !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
-                                         p->server_info->info3->base.domain.string,
+       if ((p->session_info->utok.uid != sec_initial_uid()) &&
+            !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_PRINT_OPERATOR) &&
+            !token_contains_name_in_list(uidtoname(p->session_info->utok.uid),
+                                         p->session_info->info3->base.domain.string,
                                          NULL,
-                                         p->server_info->ptok,
+                                         p->session_info->security_token,
                                          lp_printer_admin(snum))) {
                DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
                return WERR_ACCESS_DENIED;
        }
 
-       status = winreg_printer_setform1(p->mem_ctx,
-                                        get_server_info_system(),
-                                        p->msg_ctx,
+       status = winreg_printer_binding_handle(p->mem_ctx,
+                                              get_session_info_system(),
+                                              p->msg_ctx,
+                                              &b);
+       if (!W_ERROR_IS_OK(status)) {
+               return status;
+       }
+
+       status = winreg_printer_setform1(p->mem_ctx, b,
                                         form_name,
                                         form);
        if (!W_ERROR_IS_OK(status)) {
@@ -8587,9 +8633,7 @@ WERROR _spoolss_SetForm(struct pipes_struct *p,
                        return WERR_BADFID;
                }
 
-               status = winreg_printer_update_changeid(p->mem_ctx,
-                                                       get_server_info_system(),
-                                                       p->msg_ctx,
+               status = winreg_printer_update_changeid(p->mem_ctx, b,
                                                        lp_const_servicename(snum));
                if (!W_ERROR_IS_OK(status)) {
                        return status;
@@ -8980,7 +9024,7 @@ static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
        bool found = false;
 
        for (i=0; i<count; i++) {
-               if (queue[i].job == (int)jobid) {
+               if (queue[i].sysjob == (int)jobid) {
                        found = true;
                        break;
                }
@@ -9015,7 +9059,7 @@ static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
        WERROR result;
 
        for (i=0; i<count; i++) {
-               if (queue[i].job == (int)jobid) {
+               if (queue[i].sysjob == (int)jobid) {
                        found = true;
                        break;
                }
@@ -9033,7 +9077,7 @@ static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
         *  a failure condition
         */
 
-       devmode = print_job_devmode(lp_const_servicename(snum), jobid);
+       devmode = print_job_devmode(mem_ctx, lp_const_servicename(snum), jobid);
        if (!devmode) {
                result = spoolss_create_default_devmode(mem_ctx,
                                                pinfo2->printername,
@@ -9081,8 +9125,8 @@ WERROR _spoolss_GetJob(struct pipes_struct *p,
                return WERR_BADFID;
        }
 
-       result = winreg_get_printer(p->mem_ctx,
-                                   get_server_info_system(),
+       result = winreg_get_printer_internal(p->mem_ctx,
+                                   get_session_info_system(),
                                    p->msg_ctx,
                                    lp_const_servicename(snum),
                                    &pinfo2);
@@ -9139,10 +9183,10 @@ WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
        int                     snum = 0;
        WERROR result = WERR_OK;
        DATA_BLOB blob;
-       enum winreg_Type val_type;
-       uint8_t *val_data;
-       uint32_t val_size;
-
+       enum winreg_Type val_type = REG_NONE;
+       uint8_t *val_data = NULL;
+       uint32_t val_size = 0;
+       struct dcerpc_binding_handle *b;
 
        DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
 
@@ -9200,6 +9244,14 @@ WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
                return WERR_INVALID_PARAM;
        }
 
+       result = winreg_printer_binding_handle(p->mem_ctx,
+                                              get_session_info_system(),
+                                              p->msg_ctx,
+                                              &b);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
        /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
        if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
            strequal(r->in.value_name, "ChangeId")) {
@@ -9208,9 +9260,7 @@ WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
                if (r->in.offered >= *r->out.needed) {
                        uint32_t changeid = 0;
 
-                       result = winreg_printer_get_changeid(p->mem_ctx,
-                                                            get_server_info_system(),
-                                                            p->msg_ctx,
+                       result = winreg_printer_get_changeid(p->mem_ctx, b,
                                                             printer,
                                                             &changeid);
                        if (!W_ERROR_IS_OK(result)) {
@@ -9223,9 +9273,7 @@ WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
                goto done;
        }
 
-       result = winreg_get_printer_dataex(p->mem_ctx,
-                                          get_server_info_system(),
-                                          p->msg_ctx,
+       result = winreg_get_printer_dataex(p->mem_ctx, b,
                                           printer,
                                           r->in.key_name,
                                           r->in.value_name,
@@ -9262,6 +9310,7 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
        WERROR                  result = WERR_OK;
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
        char                    *oid_string;
+       struct dcerpc_binding_handle *b;
 
        DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
 
@@ -9298,9 +9347,15 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
                return WERR_ACCESS_DENIED;
        }
 
-       result = winreg_get_printer(Printer,
-                                   get_server_info_system(),
-                                   p->msg_ctx,
+       result = winreg_printer_binding_handle(p->mem_ctx,
+                                              get_session_info_system(),
+                                              p->msg_ctx,
+                                              &b);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
+       result = winreg_get_printer(Printer, b,
                                    lp_servicename(snum),
                                    &pinfo2);
        if (!W_ERROR_IS_OK(result)) {
@@ -9317,9 +9372,7 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
 
        /* save the registry data */
 
-       result = winreg_set_printer_dataex(p->mem_ctx,
-                                          get_server_info_system(),
-                                          p->msg_ctx,
+       result = winreg_set_printer_dataex(p->mem_ctx, b,
                                           pinfo2->sharename,
                                           r->in.key_name,
                                           r->in.value_name,
@@ -9343,9 +9396,7 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
                         * previous set_printer_dataex() call.  I have no idea if
                         * this is right.    --jerry
                         */
-                       winreg_set_printer_dataex(p->mem_ctx,
-                                                 get_server_info_system(),
-                                                 p->msg_ctx,
+                       winreg_set_printer_dataex(p->mem_ctx, b,
                                                  pinfo2->sharename,
                                                  str,
                                                  r->in.value_name,
@@ -9354,9 +9405,7 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
                                                  strlen(oid_string) + 1);
                }
 
-               result = winreg_printer_update_changeid(p->mem_ctx,
-                                                       get_server_info_system(),
-                                                       p->msg_ctx,
+               result = winreg_printer_update_changeid(p->mem_ctx, b,
                                                        lp_const_servicename(snum));
 
        }
@@ -9402,15 +9451,15 @@ WERROR _spoolss_DeletePrinterDataEx(struct pipes_struct *p,
        }
        printer = lp_const_servicename(snum);
 
-       status = winreg_delete_printer_dataex(p->mem_ctx,
-                                             get_server_info_system(),
+       status = winreg_delete_printer_dataex_internal(p->mem_ctx,
+                                             get_session_info_system(),
                                              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,
-                                                       get_server_info_system(),
+               status = winreg_printer_update_changeid_internal(p->mem_ctx,
+                                                       get_session_info_system(),
                                                        p->msg_ctx,
                                                        printer);
        }
@@ -9444,8 +9493,8 @@ WERROR _spoolss_EnumPrinterKey(struct pipes_struct *p,
                return WERR_BADFID;
        }
 
-       result = winreg_enum_printer_key(p->mem_ctx,
-                                        get_server_info_system(),
+       result = winreg_enum_printer_key_internal(p->mem_ctx,
+                                        get_session_info_system(),
                                         p->msg_ctx,
                                         lp_const_servicename(snum),
                                         r->in.key_name,
@@ -9492,6 +9541,7 @@ WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
        int                     snum=0;
        WERROR                  status;
        const char *printer;
+       struct dcerpc_binding_handle *b;
 
        DEBUG(5,("_spoolss_DeletePrinterKey\n"));
 
@@ -9517,16 +9567,20 @@ WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
 
        printer = lp_const_servicename(snum);
 
+       status = winreg_printer_binding_handle(p->mem_ctx,
+                                              get_session_info_system(),
+                                              p->msg_ctx,
+                                              &b);
+       if (!W_ERROR_IS_OK(status)) {
+               return status;
+       }
+
        /* delete the key and all subkeys */
-       status = winreg_delete_printer_key(p->mem_ctx,
-                                          get_server_info_system(),
-                                          p->msg_ctx,
+       status = winreg_delete_printer_key(p->mem_ctx, b,
                                           printer,
                                           r->in.key_name);
        if (W_ERROR_IS_OK(status)) {
-               status = winreg_printer_update_changeid(p->mem_ctx,
-                                                       get_server_info_system(),
-                                                       p->msg_ctx,
+               status = winreg_printer_update_changeid(p->mem_ctx, b,
                                                        printer);
        }
 
@@ -9575,8 +9629,8 @@ WERROR _spoolss_EnumPrinterDataEx(struct pipes_struct *p,
        }
 
        /* now look for a match on the key name */
-       result = winreg_enum_printer_dataex(p->mem_ctx,
-                                           get_server_info_system(),
+       result = winreg_enum_printer_dataex_internal(p->mem_ctx,
+                                           get_session_info_system(),
                                            p->msg_ctx,
                                            lp_const_servicename(snum),
                                            r->in.key_name,
@@ -9984,14 +10038,14 @@ WERROR _spoolss_XcvData(struct pipes_struct *p,
        switch ( Printer->printer_type ) {
        case SPLHND_PORTMON_TCP:
                werror = process_xcvtcp_command(p->mem_ctx,
-                                               p->server_info->ptok,
+                                               p->session_info->security_token,
                                                r->in.function_name,
                                                &r->in.in_data, &out_data,
                                                r->out.needed);
                break;
        case SPLHND_PORTMON_LOCAL:
                werror = process_xcvlocal_command(p->mem_ctx,
-                                                 p->server_info->ptok,
+                                                 p->session_info->security_token,
                                                  r->in.function_name,
                                                  &r->in.in_data, &out_data,
                                                  r->out.needed);