s3-spoolss: make it possible to have and announce a [prnproc$] share on the printserver.
[mat/samba.git] / source3 / rpc_server / srv_spoolss_nt.c
index 573faaf979e4c9455929b3629ae8e3b81501ec1f..c05ba66e427d354f11bf51e079fca1f68acc550e 100644 (file)
@@ -73,7 +73,7 @@ struct printer_handle {
        bool page_started;
        uint32 jobid; /* jobid in printing backend */
        int printer_type;
-       fstring servername;
+       const char *servername;
        fstring sharename;
        uint32 type;
        uint32 access_granted;
@@ -150,7 +150,7 @@ const struct standard_mapping printserver_std_mapping = {
 
 struct xcv_api_table {
        const char *name;
-       WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
+       WERROR(*fn) (TALLOC_CTX *mem_ctx, struct security_token *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
 };
 
 static void prune_printername_cache(void);
@@ -357,14 +357,13 @@ static bool close_printer_handle(struct pipes_struct *p, struct policy_handle *h
  Delete a printer given a handle.
 ****************************************************************************/
 
-static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
+static WERROR delete_printer_hook(TALLOC_CTX *ctx, struct security_token *token,
                                  const char *sharename,
                                  struct messaging_context *msg_ctx)
 {
        char *cmd = lp_deleteprinter_cmd();
        char *command = NULL;
        int ret;
-       SE_PRIV se_printop = SE_PRINT_OPERATOR;
        bool is_print_op = false;
 
        /* can't fail if we don't try */
@@ -379,7 +378,7 @@ static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
                return WERR_NOMEM;
        }
        if ( token )
-               is_print_op = user_has_privileges( token, &se_printop );
+               is_print_op = security_token_has_privilege(token, SEC_PRIV_PRINT_OPERATOR);
 
        DEBUG(10,("Running [%s]\n", command));
 
@@ -410,7 +409,7 @@ static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
        reload_services(msg_ctx, -1, false);
        unbecome_root();
 
-       if ( lp_servicenumber( sharename )  > 0 )
+       if ( lp_servicenumber( sharename ) >= 0 )
                return WERR_ACCESS_DENIED;
 
        return WERR_OK;
@@ -548,6 +547,7 @@ static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
        bool found = false;
        struct spoolss_PrinterInfo2 *info2 = NULL;
        WERROR result;
+       char *p;
 
        /*
         * Hopefully nobody names his printers like this. Maybe \ or ,
@@ -570,8 +570,10 @@ static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
                if (!is_myname_or_ipaddr(servername)) {
                        return false;
                }
-
-               fstrcpy(Printer->servername, servername);
+               Printer->servername = talloc_asprintf(Printer, "\\\\%s", servername);
+               if (Printer->servername == NULL) {
+                       return false;
+               }
        }
 
        if (Printer->printer_type == SPLHND_SERVER) {
@@ -584,6 +586,18 @@ static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
 
        DEBUGADD(5, ("searching for [%s]\n", aprinter));
 
+       if ((p = strchr(aprinter, ',')) != NULL) {
+               if (*p == ' ')
+                       p++;
+               if (strnequal(p+1, "DrvConvert", strlen("DrvConvert")) ||
+                   strnequal(p+1, " DrvConvert", strlen(" DrvConvert"))) {
+                       *p = '\0';
+               } else if (strnequal(p+1, "LocalOnly", strlen("LocalOnly")) ||
+                          strnequal(p+1, " LocalOnly", strlen(" LocalOnly"))) {
+                       *p = '\0';
+               }
+       }
+
        /* check for the Port Monitor Interface */
        if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
                Printer->printer_type = SPLHND_PORTMON_TCP;
@@ -650,7 +664,6 @@ static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
                result = winreg_get_printer(mem_ctx,
                                            server_info,
                                            msg_ctx,
-                                           servername,
                                            sname,
                                            &info2);
                if ( !W_ERROR_IS_OK(result) ) {
@@ -1462,6 +1475,18 @@ static bool srv_spoolss_drv_upgrade_printer(const char *drivername,
        return true;
 }
 
+void srv_spoolss_cleanup(void)
+{
+       struct printer_session_counter *session_counter;
+
+       for (session_counter = counter_list;
+            session_counter != NULL;
+            session_counter = counter_list) {
+               DLIST_REMOVE(counter_list, session_counter);
+               TALLOC_FREE(session_counter);
+       }
+}
+
 /**********************************************************************
  callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
  over all printers, upgrading ones as necessary
@@ -1481,7 +1506,6 @@ void do_drv_upgrade_printer(struct messaging_context *msg,
        const char *drivername;
        int snum;
        int n_services = lp_numservices();
-       size_t len;
 
        tmp_ctx = talloc_new(NULL);
        if (!tmp_ctx) return;
@@ -1493,8 +1517,7 @@ void do_drv_upgrade_printer(struct messaging_context *msg,
                goto done;
        }
 
-       len = MIN(data->length,sizeof(drivername)-1);
-       drivername = talloc_strndup(tmp_ctx, (const char *)data->data, len);
+       drivername = talloc_strndup(tmp_ctx, (const char *)data->data, data->length);
        if (!drivername) {
                DEBUG(0, ("do_drv_upgrade_printer: Out of memoery ?!\n"));
                goto done;
@@ -1510,8 +1533,12 @@ void do_drv_upgrade_printer(struct messaging_context *msg,
                        continue;
                }
 
+               /* ignore [printers] share */
+               if (strequal(lp_const_servicename(snum), "printers")) {
+                       continue;
+               }
+
                result = winreg_get_printer(tmp_ctx, server_info, msg,
-                                           NULL,
                                            lp_const_servicename(snum),
                                            &pinfo2);
 
@@ -1731,8 +1758,6 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
 
                if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
                {
-                       SE_PRIV se_printop = SE_PRINT_OPERATOR;
-
                        if (!lp_ms_add_printer_wizard()) {
                                close_printer_handle(p, r->out.handle);
                                ZERO_STRUCTP(r->out.handle);
@@ -1743,8 +1768,7 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
                           and not a printer admin, then fail */
 
                        if ((p->server_info->utok.uid != sec_initial_uid()) &&
-                           !user_has_privileges(p->server_info->ptok,
-                                                &se_printop ) &&
+                           !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,
@@ -1812,7 +1836,7 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
 
                if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
                                   p->server_info->ptok, snum) ||
-                   !print_access_check(get_server_info_system(),
+                   !print_access_check(p->server_info,
                                        p->msg_ctx,
                                        snum,
                                        r->in.access_mask)) {
@@ -1840,7 +1864,6 @@ WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
                winreg_create_printer(p->mem_ctx,
                                      get_server_info_system(),
                                      p->msg_ctx,
-                                     Printer->servername,
                                      lp_const_servicename(snum));
 
                break;
@@ -1983,13 +2006,12 @@ WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
        struct spoolss_DriverInfo8 *info_win2k = NULL;
        int                             version;
        WERROR                          status;
-       SE_PRIV                         se_printop = SE_PRINT_OPERATOR;
 
        /* 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())
-               && !user_has_privileges(p->server_info->ptok, &se_printop )
+            && !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,
@@ -2089,13 +2111,12 @@ WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
        int                             version;
        bool                            delete_files;
        WERROR                          status;
-       SE_PRIV                         se_printop = SE_PRINT_OPERATOR;
 
        /* 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())
-               && !user_has_privileges(p->server_info->ptok, &se_printop )
+               && !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,
@@ -3499,7 +3520,6 @@ static WERROR printserver_notify_info(struct pipes_struct *p,
                        result = winreg_get_printer(mem_ctx,
                                                    get_server_info_system(),
                                                    p->msg_ctx,
-                                                   Printer->servername,
                                                    lp_servicename(snum),
                                                    &pinfo2);
                        if (!W_ERROR_IS_OK(result)) {
@@ -3586,7 +3606,6 @@ static WERROR printer_notify_info(struct pipes_struct *p,
        result = winreg_get_printer(mem_ctx,
                                    get_server_info_system(),
                                    p->msg_ctx,
-                                   Printer->servername,
                                    lp_servicename(snum), &pinfo2);
        if (!W_ERROR_IS_OK(result)) {
                return WERR_BADFID;
@@ -3714,6 +3733,46 @@ done:
        return result;
 }
 
+/********************************************************************
+ ********************************************************************/
+
+static WERROR create_printername(TALLOC_CTX *mem_ctx,
+                                const char *servername,
+                                const char *printername,
+                                const char **printername_p)
+{
+       /* FIXME: add lp_force_printername() */
+
+       if (servername == NULL) {
+               *printername_p = talloc_strdup(mem_ctx, printername);
+               W_ERROR_HAVE_NO_MEMORY(*printername_p);
+               return WERR_OK;
+       }
+
+       if (servername[0] == '\\' && servername[1] == '\\') {
+               servername += 2;
+       }
+
+       *printername_p = talloc_asprintf(mem_ctx, "\\\\%s\\%s", servername, printername);
+       W_ERROR_HAVE_NO_MEMORY(*printername_p);
+
+       return WERR_OK;
+}
+
+/********************************************************************
+ ********************************************************************/
+
+static void compose_devicemode_devicename(struct spoolss_DeviceMode *dm,
+                                         const char *printername)
+{
+       if (dm == NULL) {
+               return;
+       }
+
+       dm->devicename = talloc_strndup(dm, printername,
+                                       MIN(strlen(printername), 31));
+}
+
 /********************************************************************
  * construct_printer_info_0
  * fill a printer_info_0 struct
@@ -3723,6 +3782,7 @@ static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
                                      const struct auth_serversupplied_info *server_info,
                                      struct messaging_context *msg_ctx,
                                      struct spoolss_PrinterInfo2 *info2,
+                                     const char *servername,
                                      struct spoolss_PrinterInfo0 *r,
                                      int snum)
 {
@@ -3730,12 +3790,19 @@ static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
        struct printer_session_counter *session_counter;
        struct timeval setuptime;
        print_status_struct status;
+       WERROR result;
 
-       r->printername          = talloc_strdup(mem_ctx, info2->printername);
-       W_ERROR_HAVE_NO_MEMORY(r->printername);
+       result = create_printername(mem_ctx, servername, info2->printername, &r->printername);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
 
-       r->servername           = talloc_strdup(mem_ctx, info2->servername);
-       W_ERROR_HAVE_NO_MEMORY(r->servername);
+       if (servername) {
+               r->servername = talloc_strdup(mem_ctx, servername);
+               W_ERROR_HAVE_NO_MEMORY(r->servername);
+       } else {
+               r->servername = NULL;
+       }
 
        count = print_queue_length(msg_ctx, snum, &status);
 
@@ -3810,16 +3877,13 @@ static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
 static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
                                      const struct spoolss_PrinterInfo2 *info2,
                                      uint32_t flags,
+                                     const char *servername,
                                      struct spoolss_PrinterInfo1 *r,
                                      int snum)
 {
-       r->flags                = flags;
+       WERROR result;
 
-       r->description          = talloc_asprintf(mem_ctx, "%s,%s,%s",
-                                                 info2->printername,
-                                                 info2->drivername,
-                                                 info2->location);
-       W_ERROR_HAVE_NO_MEMORY(r->description);
+       r->flags                = flags;
 
        if (info2->comment == NULL || info2->comment[0] == '\0') {
                r->comment      = talloc_strdup(mem_ctx, lp_comment(snum));
@@ -3828,8 +3892,16 @@ static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
        }
        W_ERROR_HAVE_NO_MEMORY(r->comment);
 
-       r->name                 = talloc_strdup(mem_ctx, info2->printername);
-       W_ERROR_HAVE_NO_MEMORY(r->name);
+       result = create_printername(mem_ctx, servername, info2->printername, &r->name);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
+       r->description          = talloc_asprintf(mem_ctx, "%s,%s,%s",
+                                                 r->name,
+                                                 info2->drivername,
+                                                 r->comment);
+       W_ERROR_HAVE_NO_MEMORY(r->description);
 
        return WERR_OK;
 }
@@ -3842,18 +3914,28 @@ static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
 static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
                                      struct messaging_context *msg_ctx,
                                      const struct spoolss_PrinterInfo2 *info2,
+                                     const char *servername,
                                      struct spoolss_PrinterInfo2 *r,
                                      int snum)
 {
        int count;
        print_status_struct status;
+       WERROR result;
 
        count = print_queue_length(msg_ctx, snum, &status);
 
-       r->servername           = talloc_strdup(mem_ctx, info2->servername);
-       W_ERROR_HAVE_NO_MEMORY(r->servername);
-       r->printername          = talloc_strdup(mem_ctx, info2->printername);
-       W_ERROR_HAVE_NO_MEMORY(r->printername);
+       if (servername) {
+               r->servername           = talloc_strdup(mem_ctx, servername);
+               W_ERROR_HAVE_NO_MEMORY(r->servername);
+       } else {
+               r->servername           = NULL;
+       }
+
+       result = create_printername(mem_ctx, servername, info2->printername, &r->printername);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
        r->sharename            = talloc_strdup(mem_ctx, lp_servicename(snum));
        W_ERROR_HAVE_NO_MEMORY(r->sharename);
        r->portname             = talloc_strdup(mem_ctx, info2->portname);
@@ -3894,6 +3976,8 @@ static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
                DEBUG(8,("Returning NULL Devicemode!\n"));
        }
 
+       compose_devicemode_devicename(r->devmode, r->printername);
+
        r->secdesc = NULL;
 
        if (info2->secdesc != NULL) {
@@ -3913,6 +3997,7 @@ static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
 
 static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
                                      const struct spoolss_PrinterInfo2 *info2,
+                                     const char *servername,
                                      struct spoolss_PrinterInfo3 *r,
                                      int snum)
 {
@@ -3936,13 +4021,23 @@ static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
 
 static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
                                      const struct spoolss_PrinterInfo2 *info2,
+                                     const char *servername,
                                      struct spoolss_PrinterInfo4 *r,
                                      int snum)
 {
-       r->printername  = talloc_strdup(mem_ctx, info2->printername);
-       W_ERROR_HAVE_NO_MEMORY(r->printername);
-       r->servername   = talloc_strdup(mem_ctx, info2->servername);
-       W_ERROR_HAVE_NO_MEMORY(r->servername);
+       WERROR result;
+
+       result = create_printername(mem_ctx, servername, info2->printername, &r->printername);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
+       if (servername) {
+               r->servername   = talloc_strdup(mem_ctx, servername);
+               W_ERROR_HAVE_NO_MEMORY(r->servername);
+       } else {
+               r->servername = NULL;
+       }
 
        r->attributes   = info2->attributes;
 
@@ -3956,11 +4051,17 @@ static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
 
 static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
                                      const struct spoolss_PrinterInfo2 *info2,
+                                     const char *servername,
                                      struct spoolss_PrinterInfo5 *r,
                                      int snum)
 {
-       r->printername  = talloc_strdup(mem_ctx, info2->printername);
-       W_ERROR_HAVE_NO_MEMORY(r->printername);
+       WERROR result;
+
+       result = create_printername(mem_ctx, servername, info2->printername, &r->printername);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
        r->portname     = talloc_strdup(mem_ctx, info2->portname);
        W_ERROR_HAVE_NO_MEMORY(r->portname);
 
@@ -3981,6 +4082,7 @@ static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
 static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
                                      struct messaging_context *msg_ctx,
                                      const struct spoolss_PrinterInfo2 *info2,
+                                     const char *servername,
                                      struct spoolss_PrinterInfo6 *r,
                                      int snum)
 {
@@ -4001,7 +4103,7 @@ static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
 
 static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
                                      struct messaging_context *msg_ctx,
-                                     struct printer_handle *print_hnd,
+                                     const char *servername,
                                      struct spoolss_PrinterInfo7 *r,
                                      int snum)
 {
@@ -4017,7 +4119,7 @@ static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
        }
 
        if (is_printer_published(mem_ctx, server_info, msg_ctx,
-                                print_hnd->servername,
+                                servername,
                                 lp_servicename(snum), &guid, NULL)) {
                r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
                r->action = DSPRINT_PUBLISH;
@@ -4038,14 +4140,25 @@ static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
 
 static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
                                      const struct spoolss_PrinterInfo2 *info2,
+                                     const char *servername,
                                      struct spoolss_DeviceModeInfo *r,
                                      int snum)
 {
+       WERROR result;
+       const char *printername;
+
+       result = create_printername(mem_ctx, servername, info2->printername, &printername);
+       if (!W_ERROR_IS_OK(result)) {
+               return result;
+       }
+
        copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
        if (!r->devmode) {
                DEBUG(8,("Returning NULL Devicemode!\n"));
        }
 
+       compose_devicemode_devicename(r->devmode, printername);
+
        return WERR_OK;
 }
 
@@ -4065,6 +4178,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,
                                           struct messaging_context *msg_ctx,
+                                          const char *servername,
                                           uint32_t level,
                                           uint32_t flags,
                                           union spoolss_PrinterInfo **info_p,
@@ -4096,7 +4210,6 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
                result = winreg_create_printer(mem_ctx,
                                               server_info,
                                               msg_ctx,
-                                              NULL,
                                               printer);
                if (!W_ERROR_IS_OK(result)) {
                        goto out;
@@ -4111,7 +4224,7 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
                }
 
                result = winreg_get_printer(mem_ctx, server_info, msg_ctx,
-                                           NULL, printer, &info2);
+                                           printer, &info2);
                if (!W_ERROR_IS_OK(result)) {
                        goto out;
                }
@@ -4120,22 +4233,27 @@ static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
                case 0:
                        result = construct_printer_info0(info, server_info,
                                                         msg_ctx, info2,
+                                                        servername,
                                                         &info[count].info0, snum);
                        break;
                case 1:
                        result = construct_printer_info1(info, info2, flags,
+                                                        servername,
                                                         &info[count].info1, snum);
                        break;
                case 2:
                        result = construct_printer_info2(info, msg_ctx, info2,
+                                                        servername,
                                                         &info[count].info2, snum);
                        break;
                case 4:
                        result = construct_printer_info4(info, info2,
+                                                        servername,
                                                         &info[count].info4, snum);
                        break;
                case 5:
                        result = construct_printer_info5(info, info2,
+                                                        servername,
                                                         &info[count].info5, snum);
                        break;
 
@@ -4180,7 +4298,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,
-                                           0, flags, info, count);
+                                           servername, 0, flags, info, count);
 }
 
 
@@ -4190,6 +4308,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,
                                       struct messaging_context *msg_ctx,
+                                      const char *servername,
                                       uint32_t flags,
                                       union spoolss_PrinterInfo **info,
                                       uint32_t *count)
@@ -4197,7 +4316,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,
-                                           1, flags, info, count);
+                                           servername, 1, flags, info, count);
 }
 
 /********************************************************************
@@ -4207,13 +4326,14 @@ 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,
                                             struct messaging_context *msg_ctx,
+                                            const char *servername,
                                             union spoolss_PrinterInfo **info,
                                             uint32_t *count)
 {
        DEBUG(4,("enum_all_printers_info_1_local\n"));
 
        return enum_all_printers_info_1(mem_ctx, server_info, msg_ctx,
-                                       PRINTER_ENUM_ICON8, info, count);
+                                       servername, PRINTER_ENUM_ICON8, info, count);
 }
 
 /********************************************************************
@@ -4223,16 +4343,16 @@ 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,
                                            struct messaging_context *msg_ctx,
-                                           const char *name,
+                                           const char *servername,
                                            union spoolss_PrinterInfo **info,
                                            uint32_t *count)
 {
-       const char *s = name;
+       const char *s = servername;
 
        DEBUG(4,("enum_all_printers_info_1_name\n"));
 
-       if ((name[0] == '\\') && (name[1] == '\\')) {
-               s = name + 2;
+       if ((servername[0] == '\\') && (servername[1] == '\\')) {
+               s = servername + 2;
        }
 
        if (!is_myname_or_ipaddr(s)) {
@@ -4240,7 +4360,7 @@ static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
        }
 
        return enum_all_printers_info_1(mem_ctx, server_info, msg_ctx,
-                                       PRINTER_ENUM_ICON8, info, count);
+                                       servername, PRINTER_ENUM_ICON8, info, count);
 }
 
 /********************************************************************
@@ -4250,11 +4370,11 @@ 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,
                                               struct messaging_context *msg_ctx,
-                                              const char *name,
+                                              const char *servername,
                                               union spoolss_PrinterInfo **info,
                                               uint32_t *count)
 {
-       const char *s = name;
+       const char *s = servername;
 
        DEBUG(4,("enum_all_printers_info_1_network\n"));
 
@@ -4266,8 +4386,8 @@ static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
           listed. Windows responds to this call with a
           WERR_CAN_NOT_COMPLETE so we should do the same. */
 
-       if (name[0] == '\\' && name[1] == '\\') {
-                s = name + 2;
+       if (servername[0] == '\\' && servername[1] == '\\') {
+                s = servername + 2;
        }
 
        if (is_myname_or_ipaddr(s)) {
@@ -4275,7 +4395,7 @@ static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
        }
 
        return enum_all_printers_info_1(mem_ctx, server_info, msg_ctx,
-                                       PRINTER_ENUM_NAME, info, count);
+                                       servername, PRINTER_ENUM_NAME, info, count);
 }
 
 /********************************************************************
@@ -4287,13 +4407,14 @@ 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,
                                       struct messaging_context *msg_ctx,
+                                      const char *servername,
                                       union spoolss_PrinterInfo **info,
                                       uint32_t *count)
 {
        DEBUG(4,("enum_all_printers_info_2\n"));
 
        return enum_all_printers_info_level(mem_ctx, server_info, msg_ctx,
-                                           2, 0, info, count);
+                                           servername, 2, 0, info, count);
 }
 
 /********************************************************************
@@ -4304,7 +4425,7 @@ static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
                                  const struct auth_serversupplied_info *server_info,
                                  struct messaging_context *msg_ctx,
                                  uint32_t flags,
-                                 const char *name,
+                                 const char *servername,
                                  union spoolss_PrinterInfo **info,
                                  uint32_t *count)
 {
@@ -4312,18 +4433,18 @@ static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
 
        if (flags & PRINTER_ENUM_LOCAL) {
                return enum_all_printers_info_1_local(mem_ctx, server_info,
-                                                     msg_ctx, info, count);
+                                                     msg_ctx, servername, info, count);
        }
 
        if (flags & PRINTER_ENUM_NAME) {
                return enum_all_printers_info_1_name(mem_ctx, server_info,
-                                                    msg_ctx, name, info,
+                                                    msg_ctx, servername, info,
                                                     count);
        }
 
        if (flags & PRINTER_ENUM_NETWORK) {
                return enum_all_printers_info_1_network(mem_ctx, server_info,
-                                                       msg_ctx, name, info,
+                                                       msg_ctx, servername, info,
                                                        count);
        }
 
@@ -4343,16 +4464,19 @@ static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
                                  uint32_t *count)
 {
        if (flags & PRINTER_ENUM_LOCAL) {
+
                return enum_all_printers_info_2(mem_ctx, server_info, msg_ctx,
+                                               servername,
                                                info, count);
        }
 
        if (flags & PRINTER_ENUM_NAME) {
-               if (!is_myname_or_ipaddr(canon_servername(servername))) {
+               if (servername && !is_myname_or_ipaddr(canon_servername(servername))) {
                        return WERR_INVALID_NAME;
                }
 
                return enum_all_printers_info_2(mem_ctx, server_info, msg_ctx,
+                                               servername,
                                                info, count);
        }
 
@@ -4378,7 +4502,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,
-                                           4, flags, info, count);
+                                           servername, 4, flags, info, count);
 }
 
 
@@ -4397,7 +4521,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,
-                                           5, flags, info, count);
+                                           servername, 5, flags, info, count);
 }
 
 /****************************************************************
@@ -4408,7 +4532,6 @@ WERROR _spoolss_EnumPrinters(struct pipes_struct *p,
                             struct spoolss_EnumPrinters *r)
 {
        const struct auth_serversupplied_info *server_info = get_server_info_system();
-       const char *name = NULL;
        WERROR result;
 
        /* that's an [in out] buffer */
@@ -4436,35 +4559,39 @@ WERROR _spoolss_EnumPrinters(struct pipes_struct *p,
         * Level 5: same as Level 2
         */
 
-       if (r->in.server) {
-               name = talloc_strdup_upper(p->mem_ctx, r->in.server);
-               W_ERROR_HAVE_NO_MEMORY(name);
+       if (r->in.server && r->in.server[0] == '\0') {
+               r->in.server = NULL;
        }
 
        switch (r->in.level) {
        case 0:
                result = enumprinters_level0(p->mem_ctx, server_info,
-                                            p->msg_ctx, r->in.flags, name,
+                                            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,
-                                            p->msg_ctx, r->in.flags, name,
+                                            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,
-                                            p->msg_ctx, r->in.flags, name,
+                                            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,
-                                            p->msg_ctx, r->in.flags, name,
+                                            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,
-                                            p->msg_ctx, r->in.flags, name,
+                                            p->msg_ctx, r->in.flags,
+                                            r->in.server,
                                             r->out.info, r->out.count);
                break;
        default:
@@ -4495,7 +4622,6 @@ WERROR _spoolss_GetPrinter(struct pipes_struct *p,
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
        struct spoolss_PrinterInfo2 *info2 = NULL;
        WERROR result = WERR_OK;
-       const char *servername = NULL;
        int snum;
 
        /* that's an [in out] buffer */
@@ -4506,22 +4632,21 @@ WERROR _spoolss_GetPrinter(struct pipes_struct *p,
 
        *r->out.needed = 0;
 
-       if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
+       if (Printer == NULL) {
                return WERR_BADFID;
        }
 
-       if (Printer != NULL || Printer->servername != NULL) {
-               servername = Printer->servername;
+       if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
+               return WERR_BADFID;
        }
 
        result = winreg_get_printer(p->mem_ctx,
                                    get_server_info_system(),
                                    p->msg_ctx,
-                                   servername,
                                    lp_const_servicename(snum),
                                    &info2);
        if (!W_ERROR_IS_OK(result)) {
-               return result;
+               goto out;
        }
 
        switch (r->in.level) {
@@ -4530,41 +4655,49 @@ WERROR _spoolss_GetPrinter(struct pipes_struct *p,
                                                 get_server_info_system(),
                                                 p->msg_ctx,
                                                 info2,
+                                                Printer->servername,
                                                 &r->out.info->info0,
                                                 snum);
                break;
        case 1:
                result = construct_printer_info1(p->mem_ctx, info2,
                                                 PRINTER_ENUM_ICON8,
+                                                Printer->servername,
                                                 &r->out.info->info1, snum);
                break;
        case 2:
                result = construct_printer_info2(p->mem_ctx, p->msg_ctx, info2,
+                                                Printer->servername,
                                                 &r->out.info->info2, snum);
                break;
        case 3:
                result = construct_printer_info3(p->mem_ctx, info2,
+                                                Printer->servername,
                                                 &r->out.info->info3, snum);
                break;
        case 4:
                result = construct_printer_info4(p->mem_ctx, info2,
+                                                Printer->servername,
                                                 &r->out.info->info4, snum);
                break;
        case 5:
                result = construct_printer_info5(p->mem_ctx, info2,
+                                                Printer->servername,
                                                 &r->out.info->info5, snum);
                break;
        case 6:
                result = construct_printer_info6(p->mem_ctx, p->msg_ctx, info2,
+                                                Printer->servername,
                                                 &r->out.info->info6, snum);
                break;
        case 7:
                result = construct_printer_info7(p->mem_ctx, p->msg_ctx,
-                                                Printer,
+                                                Printer->servername,
                                                 &r->out.info->info7, snum);
                break;
        case 8:
                result = construct_printer_info8(p->mem_ctx, info2,
+                                                Printer->servername,
                                                 &r->out.info->info8, snum);
                break;
        default:
@@ -4572,6 +4705,7 @@ WERROR _spoolss_GetPrinter(struct pipes_struct *p,
                break;
        }
 
+ out:
        if (!W_ERROR_IS_OK(result)) {
                DEBUG(0, ("_spoolss_GetPrinter: failed to construct printer info level %d - %s\n",
                          r->in.level, win_errstr(result)));
@@ -5280,10 +5414,13 @@ static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
        struct spoolss_DriverInfo8 *driver;
        WERROR result;
 
+       if (level == 101) {
+               return WERR_UNKNOWN_LEVEL;
+       }
+
        result = winreg_get_printer(mem_ctx,
                                    server_info,
                                    msg_ctx,
-                                   servername,
                                    lp_const_servicename(snum),
                                    &pinfo2);
 
@@ -5513,7 +5650,7 @@ WERROR _spoolss_StartDocPrinter(struct pipes_struct *p,
                return WERR_BADFID;
        }
 
-       werr = print_job_start(get_server_info_system(),
+       werr = print_job_start(p->server_info,
                               p->msg_ctx,
                               p->client_id->name,
                               snum,
@@ -5616,7 +5753,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 = get_server_info_system();
+       const struct auth_serversupplied_info *server_info = p->server_info;
        int snum;
        WERROR errcode = WERR_BADFUNC;
        struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
@@ -5675,7 +5812,7 @@ WERROR _spoolss_AbortPrinter(struct pipes_struct *p,
                return WERR_SPL_NO_STARTDOC;
        }
 
-       errcode = print_job_delete(get_server_info_system(),
+       errcode = print_job_delete(p->server_info,
                                   p->msg_ctx,
                                   snum,
                                   Printer->jobid);
@@ -5846,12 +5983,11 @@ static bool check_printer_ok(TALLOC_CTX *mem_ctx,
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
+static WERROR add_port_hook(TALLOC_CTX *ctx, struct security_token *token, const char *portname, const char *uri)
 {
        char *cmd = lp_addport_cmd();
        char *command = NULL;
        int ret;
-       SE_PRIV se_printop = SE_PRINT_OPERATOR;
        bool is_print_op = false;
 
        if ( !*cmd ) {
@@ -5865,7 +6001,7 @@ static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *p
        }
 
        if ( token )
-               is_print_op = user_has_privileges( token, &se_printop );
+               is_print_op = security_token_has_privilege(token, SEC_PRIV_PRINT_OPERATOR);
 
        DEBUG(10,("Running [%s]\n", command));
 
@@ -5895,7 +6031,7 @@ static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *p
 /****************************************************************************
 ****************************************************************************/
 
-static bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
+static bool add_printer_hook(TALLOC_CTX *ctx, struct security_token *token,
                             struct spoolss_SetPrinterInfo2 *info2,
                             const char *remote_machine,
                             struct messaging_context *msg_ctx)
@@ -5906,7 +6042,6 @@ static bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
        int numlines;
        int ret;
        int fd;
-       SE_PRIV se_printop = SE_PRINT_OPERATOR;
        bool is_print_op = false;
 
        if (!remote_machine) {
@@ -5923,7 +6058,7 @@ static bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
        }
 
        if ( token )
-               is_print_op = user_has_privileges( token, &se_printop );
+               is_print_op = security_token_has_privilege(token, SEC_PRIV_PRINT_OPERATOR);
 
        DEBUG(10,("Running [%s]\n", command));
 
@@ -6008,7 +6143,8 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
                                printer->drivername));
 
                        notify_printer_driver(server_event_context(), msg_ctx,
-                                             snum, printer->drivername);
+                                             snum, printer->drivername ?
+                                             printer->drivername : "");
                }
        }
 
@@ -6026,7 +6162,8 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
 
                if (!force_update) {
                        notify_printer_comment(server_event_context(), msg_ctx,
-                                              snum, printer->comment);
+                                              snum, printer->comment ?
+                                              printer->comment : "");
                }
        }
 
@@ -6045,7 +6182,8 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
                if (!force_update) {
                        notify_printer_sharename(server_event_context(),
                                                 msg_ctx,
-                                                snum, printer->sharename);
+                                                snum, printer->sharename ?
+                                                printer->sharename : "");
                }
        }
 
@@ -6072,7 +6210,7 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
 
                if (!force_update) {
                        notify_printer_printername(server_event_context(),
-                                                  msg_ctx, snum, p);
+                                                  msg_ctx, snum, p ? p : "");
                }
        }
 
@@ -6090,7 +6228,8 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
 
                if (!force_update) {
                        notify_printer_port(server_event_context(),
-                                           msg_ctx, snum, printer->portname);
+                                           msg_ctx, snum, printer->portname ?
+                                           printer->portname : "");
                }
        }
 
@@ -6109,7 +6248,8 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
                if (!force_update) {
                        notify_printer_location(server_event_context(),
                                                msg_ctx, snum,
-                                               printer->location);
+                                               printer->location ?
+                                               printer->location : "");
                }
        }
 
@@ -6126,9 +6266,10 @@ static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
                                          buffer.length);
 
                if (!force_update) {
-                       notify_printer_location(server_event_context(),
-                                               msg_ctx, snum,
-                                               printer->location);
+                       notify_printer_sepfile(server_event_context(),
+                                              msg_ctx, snum,
+                                              printer->sepfile ?
+                                              printer->sepfile : "");
                }
        }
 
@@ -6277,7 +6418,6 @@ static WERROR update_printer(struct pipes_struct *p,
        struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
        struct spoolss_PrinterInfo2 *old_printer;
        struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
-       const char *servername = NULL;
        int snum;
        WERROR result = WERR_OK;
        TALLOC_CTX *tmp_ctx;
@@ -6299,14 +6439,9 @@ static WERROR update_printer(struct pipes_struct *p,
                goto done;
        }
 
-       if (Printer != NULL || Printer->servername != NULL) {
-               servername = Printer->servername;
-       }
-
        result = winreg_get_printer(tmp_ctx,
                                    get_server_info_system(),
                                    p->msg_ctx,
-                                   servername,
                                    lp_const_servicename(snum),
                                    &old_printer);
        if (!W_ERROR_IS_OK(result)) {
@@ -6404,7 +6539,6 @@ static WERROR publish_or_unpublish_printer(struct pipes_struct *p,
        result = winreg_get_printer(p->mem_ctx,
                                    get_server_info_system(),
                                    p->msg_ctx,
-                                   Printer->servername,
                                    lp_servicename(snum),
                                    &pinfo2);
        if (!W_ERROR_IS_OK(result)) {
@@ -6868,7 +7002,6 @@ WERROR _spoolss_EnumJobs(struct pipes_struct *p,
        result = winreg_get_printer(p->mem_ctx,
                                    get_server_info_system(),
                                    p->msg_ctx,
-                                   NULL,
                                    lp_const_servicename(snum),
                                    &pinfo2);
        if (!W_ERROR_IS_OK(result)) {
@@ -6964,7 +7097,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 = get_server_info_system();
+       const struct auth_serversupplied_info *server_info = p->server_info;
        int snum;
        WERROR errcode = WERR_BADFUNC;
 
@@ -7676,7 +7809,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(get_server_info_system(),
+       if (!print_access_check(p->server_info,
                                p->msg_ctx,
                                snum,
                                PRINTER_ACCESS_ADMINISTER)) {
@@ -8235,7 +8368,6 @@ WERROR _spoolss_AddForm(struct pipes_struct *p,
        struct spoolss_AddFormInfo1 *form = r->in.info.info1;
        int snum = -1;
        WERROR status = WERR_OK;
-       SE_PRIV se_printop = SE_PRINT_OPERATOR;
 
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
@@ -8251,8 +8383,8 @@ WERROR _spoolss_AddForm(struct pipes_struct *p,
           and not a printer admin, then fail */
 
        if ((p->server_info->utok.uid != sec_initial_uid()) &&
-            !user_has_privileges(p->server_info->ptok, &se_printop) &&
-            !token_contains_name_in_list(uidtoname(p->server_info->utok.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,
                                          NULL,
                                          p->server_info->ptok,
@@ -8309,7 +8441,6 @@ 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;
-       SE_PRIV se_printop = SE_PRINT_OPERATOR;
 
        DEBUG(5,("_spoolss_DeleteForm\n"));
 
@@ -8320,8 +8451,8 @@ WERROR _spoolss_DeleteForm(struct pipes_struct *p,
        }
 
        if ((p->server_info->utok.uid != sec_initial_uid()) &&
-            !user_has_privileges(p->server_info->ptok, &se_printop) &&
-            !token_contains_name_in_list(uidtoname(p->server_info->utok.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,
                                          NULL,
                                          p->server_info->ptok,
@@ -8369,7 +8500,6 @@ WERROR _spoolss_SetForm(struct pipes_struct *p,
        const char *form_name = r->in.form_name;
        int snum = -1;
        WERROR status = WERR_OK;
-       SE_PRIV se_printop = SE_PRINT_OPERATOR;
 
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
@@ -8385,7 +8515,7 @@ WERROR _spoolss_SetForm(struct pipes_struct *p,
           and not a printer admin, then fail */
 
        if ((p->server_info->utok.uid != sec_initial_uid()) &&
-            !user_has_privileges(p->server_info->ptok, &se_printop) &&
+            !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,
                                          NULL,
@@ -8499,6 +8629,10 @@ WERROR _spoolss_EnumPrintProcessors(struct pipes_struct *p,
        *r->out.needed = 0;
        *r->out.info = NULL;
 
+       if (!get_short_archi(r->in.environment)) {
+               return WERR_INVALID_ENVIRONMENT;
+       }
+
        switch (r->in.level) {
        case 1:
                result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
@@ -8590,6 +8724,11 @@ WERROR _spoolss_EnumPrintProcDataTypes(struct pipes_struct *p,
        *r->out.needed = 0;
        *r->out.info = NULL;
 
+       if (r->in.print_processor_name == NULL ||
+           !strequal(r->in.print_processor_name, "winprint")) {
+               return WERR_UNKNOWN_PRINTPROCESSOR;
+       }
+
        switch (r->in.level) {
        case 1:
                result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
@@ -8900,7 +9039,6 @@ WERROR _spoolss_GetJob(struct pipes_struct *p,
        result = winreg_get_printer(p->mem_ctx,
                                    get_server_info_system(),
                                    p->msg_ctx,
-                                   NULL,
                                    lp_const_servicename(snum),
                                    &pinfo2);
        if (!W_ERROR_IS_OK(result)) {
@@ -9118,7 +9256,6 @@ WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
        result = winreg_get_printer(Printer,
                                    get_server_info_system(),
                                    p->msg_ctx,
-                                   Printer->servername,
                                    lp_servicename(snum),
                                    &pinfo2);
        if (!W_ERROR_IS_OK(result)) {
@@ -9469,6 +9606,9 @@ WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p,
                                           struct spoolss_GetPrintProcessorDirectory *r)
 {
        WERROR result;
+       fstring prnproc_share;
+       bool prnproc_share_exists = false;
+       int snum;
 
        /* that's an [in out] buffer */
 
@@ -9485,10 +9625,17 @@ WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p,
 
        /* We always should reply with a local print processor directory so that
         * users are not forced to have a [prnproc$] share on the Samba spoolss
-        * server - Guenther */
+        * server, if users decide to do so, lets announce it though - Guenther */
+
+       fstrcpy(prnproc_share, "prnproc$");
+
+       snum = find_service(prnproc_share);
+       if (snum != -1) {
+               prnproc_share_exists = true;
+       }
 
        result = getprintprocessordirectory_level_1(p->mem_ctx,
-                                                   NULL, /* r->in.server */
+                                                   prnproc_share_exists ? r->in.server : NULL,
                                                    r->in.environment,
                                                    &r->out.info->info1);
        if (!W_ERROR_IS_OK(result)) {
@@ -9527,7 +9674,7 @@ static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
 *******************************************************************/
 
 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
-                              NT_USER_TOKEN *token, DATA_BLOB *in,
+                              struct security_token *token, DATA_BLOB *in,
                               DATA_BLOB *out, uint32_t *needed)
 {
        const char *dllname = "tcpmonui.dll";
@@ -9582,7 +9729,7 @@ static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
 *******************************************************************/
 
 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
-                            NT_USER_TOKEN *token, DATA_BLOB *in,
+                            struct security_token *token, DATA_BLOB *in,
                             DATA_BLOB *out, uint32_t *needed)
 {
        struct spoolss_PortData1 port1;
@@ -9674,7 +9821,7 @@ struct xcv_api_table xcvtcp_cmds[] = {
 };
 
 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
-                                    NT_USER_TOKEN *token, const char *command,
+                                    struct security_token *token, const char *command,
                                     DATA_BLOB *inbuf,
                                     DATA_BLOB *outbuf,
                                     uint32_t *needed )
@@ -9696,7 +9843,7 @@ static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
 #if 0  /* don't support management using the "Local Port" monitor */
 
 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
-                                NT_USER_TOKEN *token, DATA_BLOB *in,
+                                struct security_token *token, DATA_BLOB *in,
                                 DATA_BLOB *out, uint32_t *needed)
 {
        const char *dllname = "localui.dll";
@@ -9733,7 +9880,7 @@ struct xcv_api_table xcvlocal_cmds[] = {
 *******************************************************************/
 
 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
-                                      NT_USER_TOKEN *token, const char *command,
+                                      struct security_token *token, const char *command,
                                       DATA_BLOB *inbuf, DATA_BLOB *outbuf,
                                       uint32_t *needed)
 {
@@ -10157,11 +10304,11 @@ WERROR _spoolss_44(struct pipes_struct *p,
 }
 
 /****************************************************************
- _spoolss_47
+ _spoolss_SetPort
 ****************************************************************/
 
-WERROR _spoolss_47(struct pipes_struct *p,
-                  struct spoolss_47 *r)
+WERROR _spoolss_SetPort(struct pipes_struct *p,
+                       struct spoolss_SetPort *r)
 {
        p->rng_fault_state = true;
        return WERR_NOT_SUPPORTED;