Use WERR_FILE_EXISTS which is the equivalent of WERR_ALREADY_EXISTS
[ira/wip.git] / source3 / rpc_server / srv_spoolss_nt.c
index a6f3bfba1783cf9a26a2e7e64b4e4536b6281e14..b0200de20a71bc9f74be365bb0ac7f2ee915fa28 100644 (file)
@@ -72,6 +72,18 @@ struct xcv_api_table {
        WERROR(*fn) (NT_USER_TOKEN *token, RPC_BUFFER *in, RPC_BUFFER *out, uint32 *needed);
 };
 
+/********************************************************************
+ * Canonicalize servername.
+ ********************************************************************/
+
+static const char *canon_servername(const char *servername)
+{
+       const char *pservername = servername;
+       while (*pservername == '\\') {
+               pservername++;
+       }
+       return pservername;
+}
 
 /* translate between internal status numbers and NT status numbers */
 static int nt_printj_status(int v)
@@ -153,7 +165,9 @@ static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle)
                return;
        }
 
-       result = rpccli_spoolss_reply_close_printer(notify_cli_pipe, notify_cli_pipe->cli->mem_ctx, handle);
+       result = rpccli_spoolss_reply_close_printer(notify_cli_pipe,
+                               talloc_tos(),
+                               handle);
 
        if (!W_ERROR_IS_OK(result))
                DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
@@ -162,7 +176,7 @@ static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle)
        /* if it's the last connection, deconnect the IPC$ share */
        if (smb_connections==1) {
 
-               cli_shutdown( notify_cli_pipe->cli );
+               cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
                notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */
 
                messaging_deregister(smbd_messaging_context(),
@@ -284,10 +298,11 @@ static bool close_printer_handle(pipes_struct *p, POLICY_HND *hnd)
 /****************************************************************************
  Delete a printer given a handle.
 ****************************************************************************/
-WERROR delete_printer_hook( NT_USER_TOKEN *token, const char *sharename )
+
+WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename )
 {
        char *cmd = lp_deleteprinter_cmd();
-       pstring command;
+       char *command = NULL;
        int ret;
        SE_PRIV se_printop = SE_PRINT_OPERATOR;
        bool is_print_op = False;
@@ -297,8 +312,12 @@ WERROR delete_printer_hook( NT_USER_TOKEN *token, const char *sharename )
        if ( !*cmd )
                return WERR_OK;
 
-       pstr_sprintf(command, "%s \"%s\"", cmd, sharename);
-
+       command = talloc_asprintf(ctx,
+                       "%s \"%s\"",
+                       cmd, sharename);
+       if (!command) {
+               return WERR_NOMEM;
+       }
        if ( token )
                is_print_op = user_has_privileges( token, &se_printop );
 
@@ -322,6 +341,8 @@ WERROR delete_printer_hook( NT_USER_TOKEN *token, const char *sharename )
 
        DEBUGADD(10,("returned [%d]\n", ret));
 
+       TALLOC_FREE(command);
+
        if (ret != 0)
                return WERR_BADFID; /* What to return here? */
 
@@ -367,7 +388,7 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
                return WERR_BADFID;
        }
 
-       return delete_printer_hook( p->pipe_user.nt_user_token, Printer->sharename );
+       return delete_printer_hook(p->mem_ctx, p->pipe_user.nt_user_token, Printer->sharename );
 }
 
 /****************************************************************************
@@ -446,13 +467,12 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename)
 
        aprinter = handlename;
        if ( *handlename == '\\' ) {
-               servername = handlename + 2;
-               if ( (aprinter = strchr_m( handlename+2, '\\' )) != NULL ) {
+               servername = canon_servername(handlename);
+               if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
                        *aprinter = '\0';
                        aprinter++;
                }
-       }
-       else {
+       } else {
                servername = "";
        }
 
@@ -512,7 +532,13 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename)
                fstrcpy(sname, lp_servicename(snum));
 
                printer = NULL;
-               result = get_a_printer( NULL, &printer, 2, sname );
+
+               /* This call doesn't fill in the location or comment from
+                * a CUPS server for efficiency with large numbers of printers.
+                * JRA.
+                */
+
+               result = get_a_printer_search( NULL, &printer, 2, sname );
                if ( !W_ERROR_IS_OK(result) ) {
                        DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
                                sname, dos_errstr(result)));
@@ -1521,6 +1547,13 @@ WERROR _spoolss_open_printer(pipes_struct *p, SPOOL_Q_OPEN_PRINTER *q_u, SPOOL_R
 
        memcpy(r_u, &r_u_ex, sizeof(*r_u));
 
+       if (W_ERROR_EQUAL(r_u->status, WERR_INVALID_PARAM)) {
+               /* OpenPrinterEx returns this for a bad
+                * printer name. We must return WERR_INVALID_PRINTER_NAME
+                * instead.
+                */
+               r_u->status = WERR_INVALID_PRINTER_NAME;
+       }
        return r_u->status;
 }
 
@@ -1536,8 +1569,9 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
        int snum;
        Printer_entry *Printer=NULL;
 
-       if ( !q_u->printername )
-               return WERR_INVALID_PRINTER_NAME;
+       if (!q_u->printername) {
+               return WERR_INVALID_PARAM;
+       }
 
        /* some sanity check because you can open a printer or a print server */
        /* aka: \\server\printer or \\server */
@@ -1546,15 +1580,16 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
 
        DEBUGADD(3,("checking name: %s\n",name));
 
-       if (!open_printer_hnd(p, handle, name, 0))
-               return WERR_INVALID_PRINTER_NAME;
+       if (!open_printer_hnd(p, handle, name, 0)) {
+               return WERR_INVALID_PARAM;
+       }
 
        Printer=find_printer_index_by_hnd(p, handle);
        if ( !Printer ) {
                DEBUG(0,(" _spoolss_open_printer_ex: logic error.  Can't find printer "
                        "handle we created for printer %s\n", name ));
                close_printer_handle(p,handle);
-               return WERR_INVALID_PRINTER_NAME;
+               return WERR_INVALID_PARAM;
        }
 
        /*
@@ -1625,7 +1660,8 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
                            !user_has_privileges(p->pipe_user.nt_user_token,
                                                 &se_printop ) &&
                            !token_contains_name_in_list(
-                                   uidtoname(p->pipe_user.ut.uid), NULL,
+                                   uidtoname(p->pipe_user.ut.uid),
+                                   NULL, NULL,
                                    p->pipe_user.nt_user_token,
                                    lp_printer_admin(snum))) {
                                close_printer_handle(p, handle);
@@ -1679,9 +1715,9 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
                        return WERR_ACCESS_DENIED;
                }
 
-               if (!user_ok_token(uidtoname(p->pipe_user.ut.uid),
+               if (!user_ok_token(uidtoname(p->pipe_user.ut.uid), NULL,
                                   p->pipe_user.nt_user_token, snum) ||
-                   !print_access_check(&p->pipe_user, snum,
+                   !print_access_check(p->server_info, snum,
                                        printer_default->access_required)) {
                        DEBUG(3, ("access DENIED for printer open\n"));
                        close_printer_handle(p, handle);
@@ -1984,8 +2020,10 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
 
        if ( (p->pipe_user.ut.uid != 0)
                && !user_has_privileges(p->pipe_user.nt_user_token, &se_printop )
-               && !token_contains_name_in_list( uidtoname(p->pipe_user.ut.uid),
-                   NULL, p->pipe_user.nt_user_token, lp_printer_admin(-1)) )
+               && !token_contains_name_in_list(
+                       uidtoname(p->pipe_user.ut.uid), NULL,
+                       NULL, p->pipe_user.nt_user_token,
+                       lp_printer_admin(-1)) )
        {
                return WERR_ACCESS_DENIED;
        }
@@ -2079,8 +2117,9 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV
 
        if ( (p->pipe_user.ut.uid != 0)
                && !user_has_privileges(p->pipe_user.nt_user_token, &se_printop )
-               && !token_contains_name_in_list( uidtoname(p->pipe_user.ut.uid),
-                   NULL, p->pipe_user.nt_user_token, lp_printer_admin(-1)) )
+               && !token_contains_name_in_list(
+                       uidtoname(p->pipe_user.ut.uid), NULL, NULL,
+                       p->pipe_user.nt_user_token, lp_printer_admin(-1)) )
        {
                return WERR_ACCESS_DENIED;
        }
@@ -2578,17 +2617,14 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
         * Now start the NT Domain stuff :-).
         */
 
-       if ( !(*pp_pipe = cli_rpc_pipe_open_noauth(the_cli, PI_SPOOLSS, &ret)) ) {
+       ret = cli_rpc_pipe_open_noauth(the_cli, &syntax_spoolss, pp_pipe);
+       if (!NT_STATUS_IS_OK(ret)) {
                DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
                        remote_machine, nt_errstr(ret)));
                cli_shutdown(the_cli);
                return False;
        }
 
-       /* make sure to save the cli_state pointer.  Keep its own talloc_ctx */
-
-       (*pp_pipe)->cli = the_cli;
-
        return True;
 }
 
@@ -2632,8 +2668,12 @@ static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
 
        smb_connections++;
 
-       result = rpccli_spoolss_reply_open_printer(notify_cli_pipe, notify_cli_pipe->cli->mem_ctx, printer, localprinter,
-                       type, handle);
+       result = rpccli_spoolss_reply_open_printer(notify_cli_pipe,
+                       talloc_tos(),
+                       printer,
+                       localprinter,
+                       type,
+                       handle);
 
        if (!W_ERROR_IS_OK(result))
                DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
@@ -2693,9 +2733,8 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE
                        !get_printer_snum(p, handle, &snum, NULL) )
                return WERR_BADFID;
 
-       if (!interpret_string_addr(&client_ss,
-                               p->conn->client_address,
-                               AI_NUMERICHOST)) {
+       if (!interpret_string_addr(&client_ss, p->client_address,
+                                  AI_NUMERICHOST)) {
                return WERR_SERVER_UNAVAILABLE;
        }
 
@@ -2719,20 +2758,17 @@ void spoolss_notify_server_name(int snum,
                                       NT_PRINTER_INFO_LEVEL *printer,
                                       TALLOC_CTX *mem_ctx)
 {
-       pstring temp;
+       smb_ucs2_t *temp = NULL;
        uint32 len;
 
-       len = rpcstr_push(temp, printer->info_2->servername, sizeof(temp)-2, STR_TERMINATE);
+       len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->servername);
+       if (len == (uint32)-1) {
+               len = 0;
+       }
 
        data->notify_data.data.length = len;
        if (len) {
-               data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
-               if (!data->notify_data.data.string) {
-                       data->notify_data.data.length = 0;
-                       return;
-               }
-
-               memcpy(data->notify_data.data.string, temp, len);
+               data->notify_data.data.string = (uint16 *)temp;
        } else {
                data->notify_data.data.string = NULL;
        }
@@ -2748,7 +2784,7 @@ void spoolss_notify_printer_name(int snum,
                                        NT_PRINTER_INFO_LEVEL *printer,
                                        TALLOC_CTX *mem_ctx)
 {
-       pstring temp;
+       smb_ucs2_t *temp = NULL;
        uint32 len;
 
        /* the notify name should not contain the \\server\ part */
@@ -2760,16 +2796,14 @@ void spoolss_notify_printer_name(int snum,
                p++;
        }
 
-       len = rpcstr_push(temp, p, sizeof(temp)-2, STR_TERMINATE);
+       len = rpcstr_push_talloc(mem_ctx, &temp, p);
+       if (len == (uint32)-1) {
+               len = 0;
+       }
 
        data->notify_data.data.length = len;
        if (len) {
-               data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
-               if (!data->notify_data.data.string) {
-                       data->notify_data.data.length = 0;
-                       return;
-               }
-               memcpy(data->notify_data.data.string, temp, len);
+               data->notify_data.data.string = (uint16 *)temp;
        } else {
                data->notify_data.data.string = NULL;
        }
@@ -2785,19 +2819,17 @@ void spoolss_notify_share_name(int snum,
                                      NT_PRINTER_INFO_LEVEL *printer,
                                      TALLOC_CTX *mem_ctx)
 {
-       pstring temp;
+       smb_ucs2_t *temp = NULL;
        uint32 len;
 
-       len = rpcstr_push(temp, lp_servicename(snum), sizeof(temp)-2, STR_TERMINATE);
+       len = rpcstr_push_talloc(mem_ctx, &temp, lp_servicename(snum));
+       if (len == (uint32)-1) {
+               len = 0;
+       }
 
        data->notify_data.data.length = len;
        if (len) {
-               data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
-               if (!data->notify_data.data.string) {
-                       data->notify_data.data.length = 0;
-                       return;
-               }
-               memcpy(data->notify_data.data.string, temp, len);
+               data->notify_data.data.string = (uint16 *)temp;
        } else {
                data->notify_data.data.string = NULL;
        }
@@ -2814,23 +2846,19 @@ void spoolss_notify_port_name(int snum,
                                     NT_PRINTER_INFO_LEVEL *printer,
                                     TALLOC_CTX *mem_ctx)
 {
-       pstring temp;
+       smb_ucs2_t *temp = NULL;
        uint32 len;
 
        /* even if it's strange, that's consistant in all the code */
 
-       len = rpcstr_push(temp, printer->info_2->portname, sizeof(temp)-2, STR_TERMINATE);
+       len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->portname);
+       if (len == (uint32)-1) {
+               len = 0;
+       }
 
        data->notify_data.data.length = len;
        if (len) {
-               data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
-
-               if (!data->notify_data.data.string) {
-                       data->notify_data.data.length = 0;
-                       return;
-               }
-
-               memcpy(data->notify_data.data.string, temp, len);
+               data->notify_data.data.string = (uint16 *)temp;
        } else {
                data->notify_data.data.string = NULL;
        }
@@ -2847,21 +2875,17 @@ void spoolss_notify_driver_name(int snum,
                                       NT_PRINTER_INFO_LEVEL *printer,
                                       TALLOC_CTX *mem_ctx)
 {
-       pstring temp;
+       smb_ucs2_t *temp = NULL;
        uint32 len;
 
-       len = rpcstr_push(temp, printer->info_2->drivername, sizeof(temp)-2, STR_TERMINATE);
+       len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->drivername);
+       if (len == (uint32)-1) {
+               len = 0;
+       }
 
        data->notify_data.data.length = len;
        if (len) {
-               data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
-
-               if (!data->notify_data.data.string) {
-                       data->notify_data.data.length = 0;
-                       return;
-               }
-
-               memcpy(data->notify_data.data.string, temp, len);
+               data->notify_data.data.string = (uint16 *)temp;
        } else {
                data->notify_data.data.string = NULL;
        }
@@ -2877,24 +2901,20 @@ void spoolss_notify_comment(int snum,
                                   NT_PRINTER_INFO_LEVEL *printer,
                                   TALLOC_CTX *mem_ctx)
 {
-       pstring temp;
+       smb_ucs2_t *temp = NULL;
        uint32 len;
 
        if (*printer->info_2->comment == '\0')
-               len = rpcstr_push(temp, lp_comment(snum), sizeof(temp)-2, STR_TERMINATE);
+               len = rpcstr_push_talloc(mem_ctx, &temp, lp_comment(snum));
        else
-               len = rpcstr_push(temp, printer->info_2->comment, sizeof(temp)-2, STR_TERMINATE);
+               len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->comment);
 
+       if (len == (uint32)-1) {
+               len = 0;
+       }
        data->notify_data.data.length = len;
        if (len) {
-               data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
-
-               if (!data->notify_data.data.string) {
-                       data->notify_data.data.length = 0;
-                       return;
-               }
-
-               memcpy(data->notify_data.data.string, temp, len);
+               data->notify_data.data.string = (uint16 *)temp;
        } else {
                data->notify_data.data.string = NULL;
        }
@@ -2911,21 +2931,17 @@ void spoolss_notify_location(int snum,
                                    NT_PRINTER_INFO_LEVEL *printer,
                                    TALLOC_CTX *mem_ctx)
 {
-       pstring temp;
+       smb_ucs2_t *temp = NULL;
        uint32 len;
 
-       len = rpcstr_push(temp, printer->info_2->location,sizeof(temp)-2, STR_TERMINATE);
+       len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->location);
+       if (len == (uint32)-1) {
+               len = 0;
+       }
 
        data->notify_data.data.length = len;
        if (len) {
-               data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
-
-               if (!data->notify_data.data.string) {
-                       data->notify_data.data.length = 0;
-                       return;
-               }
-
-               memcpy(data->notify_data.data.string, temp, len);
+               data->notify_data.data.string = (uint16 *)temp;
        } else {
                data->notify_data.data.string = NULL;
        }
@@ -2957,21 +2973,17 @@ void spoolss_notify_sepfile(int snum,
                                   NT_PRINTER_INFO_LEVEL *printer,
                                   TALLOC_CTX *mem_ctx)
 {
-       pstring temp;
+       smb_ucs2_t *temp = NULL;
        uint32 len;
 
-       len = rpcstr_push(temp, printer->info_2->sepfile, sizeof(temp)-2, STR_TERMINATE);
+       len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->sepfile);
+       if (len == (uint32)-1) {
+               len = 0;
+       }
 
        data->notify_data.data.length = len;
        if (len) {
-               data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
-
-               if (!data->notify_data.data.string) {
-                       data->notify_data.data.length = 0;
-                       return;
-               }
-
-               memcpy(data->notify_data.data.string, temp, len);
+               data->notify_data.data.string = (uint16 *)temp;
        } else {
                data->notify_data.data.string = NULL;
        }
@@ -2988,21 +3000,17 @@ void spoolss_notify_print_processor(int snum,
                                           NT_PRINTER_INFO_LEVEL *printer,
                                           TALLOC_CTX *mem_ctx)
 {
-       pstring temp;
+       smb_ucs2_t *temp = NULL;
        uint32 len;
 
-       len = rpcstr_push(temp,  printer->info_2->printprocessor, sizeof(temp)-2, STR_TERMINATE);
+       len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->printprocessor);
+       if (len == (uint32)-1) {
+               len = 0;
+       }
 
        data->notify_data.data.length = len;
        if (len) {
-               data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
-
-               if (!data->notify_data.data.string) {
-                       data->notify_data.data.length = 0;
-                       return;
-               }
-
-               memcpy(data->notify_data.data.string, temp, len);
+               data->notify_data.data.string = (uint16 *)temp;
        } else {
                data->notify_data.data.string = NULL;
        }
@@ -3019,21 +3027,17 @@ void spoolss_notify_parameters(int snum,
                                      NT_PRINTER_INFO_LEVEL *printer,
                                      TALLOC_CTX *mem_ctx)
 {
-       pstring temp;
+       smb_ucs2_t *temp = NULL;
        uint32 len;
 
-       len = rpcstr_push(temp,  printer->info_2->parameters, sizeof(temp)-2, STR_TERMINATE);
+       len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->parameters);
+       if (len == (uint32)-1) {
+               len = 0;
+       }
 
        data->notify_data.data.length = len;
        if (len) {
-               data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
-
-               if (!data->notify_data.data.string) {
-                       data->notify_data.data.length = 0;
-                       return;
-               }
-
-               memcpy(data->notify_data.data.string, temp, len);
+               data->notify_data.data.string = (uint16 *)temp;
        } else {
                data->notify_data.data.string = NULL;
        }
@@ -3050,21 +3054,17 @@ void spoolss_notify_datatype(int snum,
                                    NT_PRINTER_INFO_LEVEL *printer,
                                    TALLOC_CTX *mem_ctx)
 {
-       pstring temp;
+       smb_ucs2_t *temp = NULL;
        uint32 len;
 
-       len = rpcstr_push(temp, printer->info_2->datatype, sizeof(pstring)-2, STR_TERMINATE);
+       len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->datatype);
+       if (len == (uint32)-1) {
+               len = 0;
+       }
 
        data->notify_data.data.length = len;
        if (len) {
-               data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
-
-               if (!data->notify_data.data.string) {
-                       data->notify_data.data.length = 0;
-                       return;
-               }
-
-               memcpy(data->notify_data.data.string, temp, len);
+               data->notify_data.data.string = (uint16 *)temp;
        } else {
                data->notify_data.data.string = NULL;
        }
@@ -3214,21 +3214,17 @@ static void spoolss_notify_username(int snum,
                                    NT_PRINTER_INFO_LEVEL *printer,
                                    TALLOC_CTX *mem_ctx)
 {
-       pstring temp;
+       smb_ucs2_t *temp = NULL;
        uint32 len;
 
-       len = rpcstr_push(temp, queue->fs_user, sizeof(temp)-2, STR_TERMINATE);
+       len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_user);
+       if (len == (uint32)-1) {
+               len = 0;
+       }
 
        data->notify_data.data.length = len;
        if (len) {
-               data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
-
-               if (!data->notify_data.data.string) {
-                       data->notify_data.data.length = 0;
-                       return;
-               }
-
-               memcpy(data->notify_data.data.string, temp, len);
+               data->notify_data.data.string = (uint16 *)temp;
        } else {
                data->notify_data.data.string = NULL;
        }
@@ -3258,21 +3254,17 @@ static void spoolss_notify_job_name(int snum,
                                    NT_PRINTER_INFO_LEVEL *printer,
                                    TALLOC_CTX *mem_ctx)
 {
-       pstring temp;
+       smb_ucs2_t *temp = NULL;
        uint32 len;
 
-       len = rpcstr_push(temp, queue->fs_file, sizeof(temp)-2, STR_TERMINATE);
+       len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_file);
+       if (len == (uint32)-1) {
+               len = 0;
+       }
 
        data->notify_data.data.length = len;
        if (len) {
-               data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
-
-               if (!data->notify_data.data.string) {
-                       data->notify_data.data.length = 0;
-                       return;
-               }
-
-               memcpy(data->notify_data.data.string, temp, len);
+               data->notify_data.data.string = (uint16 *)temp;
        } else {
                data->notify_data.data.string = NULL;
        }
@@ -3293,7 +3285,7 @@ static void spoolss_notify_job_status_string(int snum,
         */
 
        const char *p = "";
-       pstring temp;
+       smb_ucs2_t *temp = NULL;
        uint32 len;
 
 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
@@ -3315,18 +3307,14 @@ static void spoolss_notify_job_status_string(int snum,
        }
 #endif /* NO LONGER NEEDED. */
 
-       len = rpcstr_push(temp, p, sizeof(temp) - 2, STR_TERMINATE);
+       len = rpcstr_push_talloc(mem_ctx, &temp, p);
+       if (len == (uint32)-1) {
+               len = 0;
+       }
 
        data->notify_data.data.length = len;
        if (len) {
-               data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
-
-               if (!data->notify_data.data.string) {
-                       data->notify_data.data.length = 0;
-                       return;
-               }
-
-               memcpy(data->notify_data.data.string, temp, len);
+               data->notify_data.data.string = (uint16 *)temp;
        } else {
                data->notify_data.data.string = NULL;
        }
@@ -3954,7 +3942,7 @@ done:
 
 static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum)
 {
-       pstring chaine;
+       char *chaine = NULL;
        int count;
        NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
        counter_printer_0 *session_counter;
@@ -3962,10 +3950,19 @@ static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *p
        struct tm *t;
        time_t setuptime;
        print_status_struct status;
+       TALLOC_CTX *ctx = talloc_tos();
 
        if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
                return False;
 
+       init_unistr(&printer->printername, ntprinter->info_2->printername);
+
+       chaine = talloc_asprintf(ctx, "\\\\%s", get_server_name(print_hnd));
+       if (!chaine) {
+               free_a_printer(&ntprinter,2);
+               return false;
+       }
+
        count = print_queue_length(snum, &status);
 
        /* check if we already have a counter for this printer */
@@ -3974,6 +3971,8 @@ static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *p
                        break;
        }
 
+       init_unistr(&printer->servername, chaine);
+
        /* it's the first time, add it to the list */
        if (session_counter==NULL) {
                if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) {
@@ -3994,14 +3993,6 @@ static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *p
         * and should be zeroed on samba startup
         */
        global_counter=session_counter->counter;
-
-       pstrcpy(chaine,ntprinter->info_2->printername);
-
-       init_unistr(&printer->printername, chaine);
-
-       slprintf(chaine,sizeof(chaine)-1,"\\\\%s", get_server_name(print_hnd));
-       init_unistr(&printer->servername, chaine);
-
        printer->cjobs = count;
        printer->total_jobs = 0;
        printer->total_bytes = 0;
@@ -4059,30 +4050,35 @@ static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *p
  ********************************************************************/
 static bool construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum)
 {
-       pstring chaine;
-       pstring chaine2;
+       char *chaine = NULL;
        NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
+       TALLOC_CTX *ctx = talloc_tos();
 
        if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
-               return False;
+               return false;
 
        printer->flags=flags;
 
        if (*ntprinter->info_2->comment == '\0') {
                init_unistr(&printer->comment, lp_comment(snum));
-               slprintf(chaine,sizeof(chaine)-1,"%s,%s,%s", ntprinter->info_2->printername,
-                       ntprinter->info_2->drivername, lp_comment(snum));
+               chaine = talloc_asprintf(ctx,
+                               "%s,%s,%s", ntprinter->info_2->printername,
+                               ntprinter->info_2->drivername, lp_comment(snum));
        }
        else {
                init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
-               slprintf(chaine,sizeof(chaine)-1,"%s,%s,%s", ntprinter->info_2->printername,
-                       ntprinter->info_2->drivername, ntprinter->info_2->comment);
+               chaine = talloc_asprintf(ctx,
+                               "%s,%s,%s", ntprinter->info_2->printername,
+                               ntprinter->info_2->drivername, ntprinter->info_2->comment);
        }
 
-       slprintf(chaine2,sizeof(chaine)-1,"%s", ntprinter->info_2->printername);
+       if (!chaine) {
+               free_a_printer(&ntprinter,2);
+               return false;
+       }
 
        init_unistr(&printer->description, chaine);
-       init_unistr(&printer->name, chaine2);
+       init_unistr(&printer->name, ntprinter->info_2->printername);
 
        free_a_printer(&ntprinter,2);
 
@@ -4376,10 +4372,13 @@ static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *p
        struct GUID guid;
 
        if (is_printer_published(print_hnd, snum, &guid)) {
-               asprintf(&guid_str, "{%s}",
-                        smb_uuid_string(talloc_tos(), guid));
+               if (asprintf(&guid_str, "{%s}",
+                            GUID_string(talloc_tos(), &guid)) == -1) {
+                       return false;
+               }
                strupper_m(guid_str);
                init_unistr(&printer->guid, guid_str);
+               SAFE_FREE(guid_str);
                printer->action = SPOOL_DS_PUBLISH;
        } else {
                init_unistr(&printer->guid, "");
@@ -4673,20 +4672,16 @@ static WERROR enumprinters_level1( uint32 flags, fstring name,
  * handle enumeration of printers at level 2
  ********************************************************************/
 
-static WERROR enumprinters_level2( uint32 flags, fstring servername,
+static WERROR enumprinters_level2( uint32 flags, const char *servername,
                                 RPC_BUFFER *buffer, uint32 offered,
                                 uint32 *needed, uint32 *returned)
 {
-       char *s = servername;
-
        if (flags & PRINTER_ENUM_LOCAL) {
                        return enum_all_printers_info_2(buffer, offered, needed, returned);
        }
 
        if (flags & PRINTER_ENUM_NAME) {
-               if ((servername[0] == '\\') && (servername[1] == '\\'))
-                       s = servername + 2;
-               if (is_myname_or_ipaddr(s))
+               if (is_myname_or_ipaddr(canon_servername(servername)))
                        return enum_all_printers_info_2(buffer, offered, needed, returned);
                else
                        return WERR_INVALID_NAME;
@@ -4702,7 +4697,7 @@ static WERROR enumprinters_level2( uint32 flags, fstring servername,
  * handle enumeration of printers at level 5
  ********************************************************************/
 
-static WERROR enumprinters_level5( uint32 flags, fstring servername,
+static WERROR enumprinters_level5( uint32 flags, const char *servername,
                                 RPC_BUFFER *buffer, uint32 offered,
                                 uint32 *needed, uint32 *returned)
 {
@@ -5042,8 +5037,10 @@ static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER
        if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
                return WERR_NOMEM;
 
-       if (!construct_printer_info_7(print_hnd, printer, snum))
-               return WERR_NOMEM;
+       if (!construct_printer_info_7(print_hnd, printer, snum)) {
+               result = WERR_NOMEM;
+               goto out;
+       }
 
        /* check the required size. */
        *needed += spoolss_size_printer_info_7(printer);
@@ -5122,7 +5119,7 @@ WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET
  * fill a DRIVER_INFO_1 struct
  ********************************************************************/
 
-static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername, fstring architecture)
+static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername, fstring architecture)
 {
        init_unistr( &info->name, driver.info_3->name);
 }
@@ -5131,7 +5128,7 @@ static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_IN
  * construct_printer_driver_info_1
  ********************************************************************/
 
-static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fstring servername, fstring architecture, uint32 version)
+static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, const char *servername, fstring architecture, uint32 version)
 {
        NT_PRINTER_INFO_LEVEL *printer = NULL;
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
@@ -5158,30 +5155,43 @@ static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fst
  * fill a printer_info_2 struct
  ********************************************************************/
 
-static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
+static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
 {
-       pstring temp;
+       TALLOC_CTX *ctx = talloc_tos();
+       char *temp = NULL;
+       const char *cservername = canon_servername(servername);
 
        info->version=driver.info_3->cversion;
 
        init_unistr( &info->name, driver.info_3->name );
        init_unistr( &info->architecture, driver.info_3->environment );
 
-
-    if (strlen(driver.info_3->driverpath)) {
-               slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
+       if (strlen(driver.info_3->driverpath)) {
+               temp = talloc_asprintf(ctx,
+                               "\\\\%s%s",
+                               cservername,
+                               driver.info_3->driverpath);
                init_unistr( &info->driverpath, temp );
-    } else
-        init_unistr( &info->driverpath, "" );
+       } else {
+               init_unistr( &info->driverpath, "" );
+       }
 
+       TALLOC_FREE(temp);
        if (strlen(driver.info_3->datafile)) {
-               slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile);
+               temp = talloc_asprintf(ctx,
+                               "\\\\%s%s",
+                               cservername,
+                               driver.info_3->datafile);
                init_unistr( &info->datafile, temp );
        } else
                init_unistr( &info->datafile, "" );
 
+       TALLOC_FREE(temp);
        if (strlen(driver.info_3->configfile)) {
-               slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile);
+               temp = talloc_asprintf(ctx,
+                               "\\\\%s%s",
+                               cservername,
+                               driver.info_3->configfile);
                init_unistr( &info->configfile, temp );
        } else
                init_unistr( &info->configfile, "" );
@@ -5192,7 +5202,7 @@ static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_IN
  * fill a printer_info_2 struct
  ********************************************************************/
 
-static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstring servername, fstring architecture, uint32 version)
+static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, const char *servername, fstring architecture, uint32 version)
 {
        NT_PRINTER_INFO_LEVEL *printer = NULL;
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
@@ -5226,17 +5236,16 @@ static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const c
        int i=0;
        int j=0;
        const char *v;
-       pstring line;
+       char *line = NULL;
+       TALLOC_CTX *ctx = talloc_tos();
 
        DEBUG(6,("init_unistr_array\n"));
        *uni_array=NULL;
 
-       while (True)
-       {
-               if ( !char_array )
+       while (true) {
+               if ( !char_array ) {
                        v = "";
-               else
-               {
+               } else {
                        v = char_array[i];
                        if (!v)
                                v = ""; /* hack to handle null lists */
@@ -5244,12 +5253,21 @@ static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const c
 
                /* hack to allow this to be used in places other than when generating
                   the list of dependent files */
-               
-               if ( servername )
-                       slprintf( line, sizeof(line)-1, "\\\\%s%s", servername, v );
-               else
-                       pstrcpy( line, v );
 
+               TALLOC_FREE(line);
+               if ( servername ) {
+                       line = talloc_asprintf(ctx,
+                                       "\\\\%s%s",
+                                       canon_servername(servername),
+                                       v);
+               } else {
+                       line = talloc_strdup(ctx, v);
+               }
+
+               if (!line) {
+                       SAFE_FREE(*uni_array);
+                       return 0;
+               }
                DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line)));
 
                /* add one extra unit16 for the second terminating NULL */
@@ -5285,9 +5303,11 @@ static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const c
  * fill a printer_info_3 struct
  ********************************************************************/
 
-static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
+static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
 {
-       pstring temp;
+       char *temp = NULL;
+       TALLOC_CTX *ctx = talloc_tos();
+       const char *cservername = canon_servername(servername);
 
        ZERO_STRUCTP(info);
 
@@ -5297,34 +5317,50 @@ static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_IN
        init_unistr( &info->architecture, driver.info_3->environment );
 
        if (strlen(driver.info_3->driverpath)) {
-               slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
+               temp = talloc_asprintf(ctx,
+                               "\\\\%s%s",
+                               cservername,
+                               driver.info_3->driverpath);
                init_unistr( &info->driverpath, temp );
        } else
                init_unistr( &info->driverpath, "" );
 
+       TALLOC_FREE(temp);
        if (strlen(driver.info_3->datafile)) {
-               slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile);
+               temp = talloc_asprintf(ctx,
+                               "\\\\%s%s",
+                               cservername,
+                               driver.info_3->datafile);
                init_unistr( &info->datafile, temp );
        } else
                init_unistr( &info->datafile, "" );
 
+       TALLOC_FREE(temp);
        if (strlen(driver.info_3->configfile)) {
-               slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile);
+               temp = talloc_asprintf(ctx,
+                               "\\\\%s%s",
+                               cservername,
+                               driver.info_3->configfile);
                init_unistr( &info->configfile, temp );
        } else
                init_unistr( &info->configfile, "" );
 
+       TALLOC_FREE(temp);
        if (strlen(driver.info_3->helpfile)) {
-               slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
+               temp = talloc_asprintf(ctx,
+                               "\\\\%s%s",
+                               cservername,
+                               driver.info_3->helpfile);
                init_unistr( &info->helpfile, temp );
        } else
                init_unistr( &info->helpfile, "" );
 
+       TALLOC_FREE(temp);
        init_unistr( &info->monitorname, driver.info_3->monitorname );
        init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
 
        info->dependentfiles=NULL;
-       init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, servername);
+       init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, cservername);
 }
 
 /********************************************************************
@@ -5332,7 +5368,7 @@ static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_IN
  * fill a printer_info_3 struct
  ********************************************************************/
 
-static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fstring servername, fstring architecture, uint32 version)
+static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, const char *servername, fstring architecture, uint32 version)
 {
        NT_PRINTER_INFO_LEVEL *printer = NULL;
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
@@ -5391,10 +5427,12 @@ static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fst
  * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
  ********************************************************************/
 
-static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
+static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
 {
-       pstring temp;
+       char *temp = NULL;
        fstring nullstr;
+       TALLOC_CTX *ctx = talloc_tos();
+       const char *cservername = canon_servername(servername);
 
        ZERO_STRUCTP(info);
        memset(&nullstr, '\0', sizeof(fstring));
@@ -5405,29 +5443,45 @@ static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_IN
        init_unistr( &info->architecture, driver.info_3->environment );
 
        if (strlen(driver.info_3->driverpath)) {
-               slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
+               temp = talloc_asprintf(ctx,
+                               "\\\\%s%s",
+                               cservername,
+                               driver.info_3->driverpath);
                init_unistr( &info->driverpath, temp );
        } else
                init_unistr( &info->driverpath, "" );
 
+       TALLOC_FREE(temp);
        if (strlen(driver.info_3->datafile)) {
-               slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile);
+               temp = talloc_asprintf(ctx,
+                               "\\\\%s%s",
+                               cservername,
+                               driver.info_3->datafile);
                init_unistr( &info->datafile, temp );
        } else
                init_unistr( &info->datafile, "" );
 
+       TALLOC_FREE(temp);
        if (strlen(driver.info_3->configfile)) {
-               slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile);
+               temp = talloc_asprintf(ctx,
+                               "\\\\%s%s",
+                               cservername,
+                               driver.info_3->configfile);
                init_unistr( &info->configfile, temp );
        } else
                init_unistr( &info->configfile, "" );
 
+       TALLOC_FREE(temp);
        if (strlen(driver.info_3->helpfile)) {
-               slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
+               temp = talloc_asprintf(ctx,
+                               "\\\\%s%s",
+                               cservername,
+                               driver.info_3->helpfile);
                init_unistr( &info->helpfile, temp );
        } else
                init_unistr( &info->helpfile, "" );
 
+       TALLOC_FREE(temp);
        init_unistr( &info->monitorname, driver.info_3->monitorname );
        init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
 
@@ -5455,7 +5509,7 @@ static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_IN
  ********************************************************************/
 
 static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
-              fstring servername, fstring architecture, uint32 version)
+              const char *servername, fstring architecture, uint32 version)
 {
        NT_PRINTER_INFO_LEVEL           *printer = NULL;
        NT_PRINTER_DRIVER_INFO_LEVEL    driver;
@@ -5522,7 +5576,7 @@ static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level1(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        DRIVER_INFO_1 *info=NULL;
        WERROR result;
@@ -5560,7 +5614,7 @@ out:
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level2(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        DRIVER_INFO_2 *info=NULL;
        WERROR result;
@@ -5598,7 +5652,7 @@ out:
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level3(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        DRIVER_INFO_3 info;
        WERROR result;
@@ -5634,7 +5688,7 @@ out:
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinterdriver2_level6(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        DRIVER_INFO_6 info;
        WERROR result;
@@ -5786,10 +5840,10 @@ WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, S
        POLICY_HND *handle = &q_u->handle;
        DOC_INFO *docinfo = &q_u->doc_info_container.docinfo;
        uint32 *jobid = &r_u->jobid;
-
+       TALLOC_CTX *ctx = p->mem_ctx;
        DOC_INFO_1 *info_1 = &docinfo->doc_info_1;
        int snum;
-       pstring jobname;
+       char *jobname = NULL;
        fstring datatype;
        Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
 
@@ -5819,9 +5873,10 @@ WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, S
                return WERR_BADFID;
        }
 
-       unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname));
+       jobname = unistr2_to_ascii_talloc(ctx, &info_1->docname);
 
-       Printer->jobid = print_job_start(&p->pipe_user, snum, jobname, Printer->nt_devmode);
+       Printer->jobid = print_job_start(p->server_info, snum, jobname,
+                                        Printer->nt_devmode);
 
        /* An error occured in print_job_start() so return an appropriate
           NT error code. */
@@ -5908,18 +5963,18 @@ static WERROR control_printer(POLICY_HND *handle, uint32 command,
 
        switch (command) {
        case PRINTER_CONTROL_PAUSE:
-               if (print_queue_pause(&p->pipe_user, snum, &errcode)) {
+               if (print_queue_pause(p->server_info, snum, &errcode)) {
                        errcode = WERR_OK;
                }
                break;
        case PRINTER_CONTROL_RESUME:
        case PRINTER_CONTROL_UNPAUSE:
-               if (print_queue_resume(&p->pipe_user, snum, &errcode)) {
+               if (print_queue_resume(p->server_info, snum, &errcode)) {
                        errcode = WERR_OK;
                }
                break;
        case PRINTER_CONTROL_PURGE:
-               if (print_queue_purge(&p->pipe_user, snum, &errcode)) {
+               if (print_queue_purge(p->server_info, snum, &errcode)) {
                        errcode = WERR_OK;
                }
                break;
@@ -5951,7 +6006,7 @@ WERROR _spoolss_abortprinter(pipes_struct *p, SPOOL_Q_ABORTPRINTER *q_u, SPOOL_R
        if (!get_printer_snum(p, handle, &snum, NULL))
                return WERR_BADFID;
 
-       print_job_delete( &p->pipe_user, snum, Printer->jobid, &errcode );
+       print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
 
        return errcode;
 }
@@ -5999,7 +6054,11 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
        /* NT seems to like setting the security descriptor even though
           nothing may have actually changed. */
 
-       nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr);
+       if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) {
+               DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
+               result = WERR_BADFID;
+               goto done;
+       }
 
        if (DEBUGLEVEL >= 10) {
                SEC_ACL *the_acl;
@@ -6010,11 +6069,8 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
                           PRINTERNAME(snum), the_acl->num_aces));
 
                for (i = 0; i < the_acl->num_aces; i++) {
-                       fstring sid_str;
-
-                       sid_to_string(sid_str, &the_acl->aces[i].trustee);
-
-                       DEBUG(10, ("%s 0x%08x\n", sid_str,
+                       DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
+                                          &the_acl->aces[i].trustee),
                                  the_acl->aces[i].access_mask));
                }
 
@@ -6025,11 +6081,8 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
                                   PRINTERNAME(snum), the_acl->num_aces));
 
                        for (i = 0; i < the_acl->num_aces; i++) {
-                               fstring sid_str;
-
-                               sid_to_string(sid_str, &the_acl->aces[i].trustee);
-
-                               DEBUG(10, ("%s 0x%08x\n", sid_str,
+                               DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
+                                                  &the_acl->aces[i].trustee),
                                           the_acl->aces[i].access_mask));
                        }
                } else {
@@ -6109,12 +6162,11 @@ static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
 /****************************************************************************
 ****************************************************************************/
 
-WERROR add_port_hook(NT_USER_TOKEN *token, const char *portname, const char *uri )
+WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri )
 {
        char *cmd = lp_addport_cmd();
-       pstring command;
+       char *command = NULL;
        int ret;
-       int fd;
        SE_PRIV se_printop = SE_PRINT_OPERATOR;
        bool is_print_op = False;
 
@@ -6122,7 +6174,11 @@ WERROR add_port_hook(NT_USER_TOKEN *token, const char *portname, const char *uri
                return WERR_ACCESS_DENIED;
        }
 
-       slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"", cmd, portname, uri );
+       command = talloc_asprintf(ctx,
+                       "%s \"%s\" \"%s\"", cmd, portname, uri );
+       if (!command) {
+               return WERR_NOMEM;
+       }
 
        if ( token )
                is_print_op = user_has_privileges( token, &se_printop );
@@ -6134,7 +6190,7 @@ WERROR add_port_hook(NT_USER_TOKEN *token, const char *portname, const char *uri
        if ( is_print_op )
                become_root();
 
-       ret = smbrun(command, &fd);
+       ret = smbrun(command, NULL);
 
        if ( is_print_op )
                unbecome_root();
@@ -6143,9 +6199,9 @@ WERROR add_port_hook(NT_USER_TOKEN *token, const char *portname, const char *uri
 
        DEBUGADD(10,("returned [%d]\n", ret));
 
+       TALLOC_FREE(command);
+
        if ( ret != 0 ) {
-               if (fd != -1)
-                       close(fd);
                return WERR_ACCESS_DENIED;
        }
 
@@ -6155,26 +6211,37 @@ WERROR add_port_hook(NT_USER_TOKEN *token, const char *portname, const char *uri
 /****************************************************************************
 ****************************************************************************/
 
-bool add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
+bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
 {
        char *cmd = lp_addprinter_cmd();
        char **qlines;
-       pstring command;
+       char *command = NULL;
        int numlines;
        int ret;
        int fd;
-       fstring remote_machine = "%m";
        SE_PRIV se_printop = SE_PRINT_OPERATOR;
        bool is_print_op = False;
+       char *remote_machine = talloc_strdup(ctx, "%m");
 
-       standard_sub_basic(current_user_info.smb_name,
-                          current_user_info.domain,
-                          remote_machine,sizeof(remote_machine));
+       if (!remote_machine) {
+               return false;
+       }
+       remote_machine = talloc_sub_basic(ctx,
+                               current_user_info.smb_name,
+                               current_user_info.domain,
+                               remote_machine);
+       if (!remote_machine) {
+               return false;
+       }
 
-       slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
+       command = talloc_asprintf(ctx,
+                       "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
                        cmd, printer->info_2->printername, printer->info_2->sharename,
                        printer->info_2->portname, printer->info_2->drivername,
                        printer->info_2->location, printer->info_2->comment, remote_machine);
+       if (!command) {
+               return false;
+       }
 
        if ( token )
                is_print_op = user_has_privileges( token, &se_printop );
@@ -6199,6 +6266,9 @@ bool add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
 
        DEBUGADD(10,("returned [%d]\n", ret));
 
+       TALLOC_FREE(command);
+       TALLOC_FREE(remote_machine);
+
        if ( ret != 0 ) {
                if (fd != -1)
                        close(fd);
@@ -6210,7 +6280,7 @@ bool add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
 
        numlines = 0;
        /* Get lines and convert them back to dos-codepage */
-       qlines = fd_lines_load(fd, &numlines, 0);
+       qlines = fd_lines_load(fd, &numlines, 0, NULL);
        DEBUGADD(10,("Lines returned = [%d]\n", numlines));
        close(fd);
 
@@ -6223,7 +6293,7 @@ bool add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
                DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
        }
 
-       file_lines_free(qlines);
+       TALLOC_FREE(qlines);
        return True;
 }
 
@@ -6318,7 +6388,7 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
        {
                /* add_printer_hook() will call reload_services() */
 
-               if ( !add_printer_hook(p->pipe_user.nt_user_token, printer) ) {
+               if ( !add_printer_hook(p->mem_ctx, p->pipe_user.nt_user_token, printer) ) {
                        result = WERR_ACCESS_DENIED;
                        goto done;
                }
@@ -6826,18 +6896,18 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u
        switch (command) {
        case JOB_CONTROL_CANCEL:
        case JOB_CONTROL_DELETE:
-               if (print_job_delete(&p->pipe_user, snum, jobid, &errcode)) {
+               if (print_job_delete(p->server_info, snum, jobid, &errcode)) {
                        errcode = WERR_OK;
                }
                break;
        case JOB_CONTROL_PAUSE:
-               if (print_job_pause(&p->pipe_user, snum, jobid, &errcode)) {
+               if (print_job_pause(p->server_info, snum, jobid, &errcode)) {
                        errcode = WERR_OK;
                }
                break;
        case JOB_CONTROL_RESTART:
        case JOB_CONTROL_RESUME:
-               if (print_job_resume(&p->pipe_user, snum, jobid, &errcode)) {
+               if (print_job_resume(p->server_info, snum, jobid, &errcode)) {
                        errcode = WERR_OK;
                }
                break;
@@ -6852,7 +6922,7 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u
  Enumerates all printer drivers at level 1.
 ****************************************************************************/
 
-static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level1(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        int i;
        int ndrivers;
@@ -6936,7 +7006,7 @@ out:
  Enumerates all printer drivers at level 2.
 ****************************************************************************/
 
-static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level2(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        int i;
        int ndrivers;
@@ -7021,7 +7091,7 @@ out:
  Enumerates all printer drivers at level 3.
 ****************************************************************************/
 
-static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level3(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        int i;
        int ndrivers;
@@ -7117,7 +7187,7 @@ WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        uint32 *returned = &r_u->returned;
-
+       const char *cservername;
        fstring servername;
        fstring architecture;
 
@@ -7138,16 +7208,18 @@ WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS
        unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture));
        unistr2_to_ascii(servername, &q_u->name, sizeof(servername));
 
-       if ( !is_myname_or_ipaddr( servername ) )
+       cservername = canon_servername(servername);
+
+       if (!is_myname_or_ipaddr(cservername))
                return WERR_UNKNOWN_PRINTER_DRIVER;
 
        switch (level) {
        case 1:
-               return enumprinterdrivers_level1(servername, architecture, buffer, offered, needed, returned);
+               return enumprinterdrivers_level1(cservername, architecture, buffer, offered, needed, returned);
        case 2:
-               return enumprinterdrivers_level2(servername, architecture, buffer, offered, needed, returned);
+               return enumprinterdrivers_level2(cservername, architecture, buffer, offered, needed, returned);
        case 3:
-               return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned);
+               return enumprinterdrivers_level3(cservername, architecture, buffer, offered, needed, returned);
        default:
                return WERR_UNKNOWN_LEVEL;
        }
@@ -7395,11 +7467,11 @@ static void fill_port_2(PORT_INFO_2 *port, const char *name)
  wrapper around the enumer ports command
 ****************************************************************************/
 
-WERROR enumports_hook( int *count, char ***lines )
+WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
 {
        char *cmd = lp_enumports_cmd();
-       char **qlines;
-       pstring command;
+       char **qlines = NULL;
+       char *command = NULL;
        int numlines;
        int ret;
        int fd;
@@ -7423,11 +7495,15 @@ WERROR enumports_hook( int *count, char ***lines )
        else {
                /* we have a valid enumport command */
 
-               slprintf(command, sizeof(command)-1, "%s \"%d\"", cmd, 1);
+               command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
+               if (!command) {
+                       return WERR_NOMEM;
+               }
 
                DEBUG(10,("Running [%s]\n", command));
                ret = smbrun(command, &fd);
                DEBUG(10,("Returned [%d]\n", ret));
+               TALLOC_FREE(command);
                if (ret != 0) {
                        if (fd != -1) {
                                close(fd);
@@ -7436,7 +7512,7 @@ WERROR enumports_hook( int *count, char ***lines )
                }
 
                numlines = 0;
-               qlines = fd_lines_load(fd, &numlines, 0);
+               qlines = fd_lines_load(fd, &numlines, 0, NULL);
                DEBUGADD(10,("Lines returned = [%d]\n", numlines));
                close(fd);
        }
@@ -7459,9 +7535,9 @@ static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *need
        char **qlines = NULL;
        int numlines = 0;
 
-       result = enumports_hook( &numlines, &qlines );
+       result = enumports_hook(talloc_tos(), &numlines, &qlines );
        if (!W_ERROR_IS_OK(result)) {
-               file_lines_free(qlines);
+               TALLOC_FREE(qlines);
                return result;
        }
 
@@ -7469,7 +7545,7 @@ static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *need
                if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) {
                        DEBUG(10,("Returning WERR_NOMEM [%s]\n",
                                  dos_errstr(WERR_NOMEM)));
-                       file_lines_free(qlines);
+                       TALLOC_FREE(qlines);
                        return WERR_NOMEM;
                }
 
@@ -7478,7 +7554,7 @@ static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *need
                        fill_port_1(&ports[i], qlines[i]);
                }
        }
-       file_lines_free(qlines);
+       TALLOC_FREE(qlines);
 
        *returned = numlines;
 
@@ -7525,15 +7601,15 @@ static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *need
        char **qlines = NULL;
        int numlines = 0;
 
-       result = enumports_hook( &numlines, &qlines );
+       result = enumports_hook(talloc_tos(), &numlines, &qlines );
        if ( !W_ERROR_IS_OK(result)) {
-               file_lines_free(qlines);
+               TALLOC_FREE(qlines);
                return result;
        }
 
        if(numlines) {
                if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) {
-                       file_lines_free(qlines);
+                       TALLOC_FREE(qlines);
                        return WERR_NOMEM;
                }
 
@@ -7543,7 +7619,7 @@ static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *need
                }
        }
 
-       file_lines_free(qlines);
+       TALLOC_FREE(qlines);
 
        *returned = numlines;
 
@@ -7652,7 +7728,7 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
           trying to add a printer like this  --jerry */
 
        if (*lp_addprinter_cmd() ) {
-               if ( !add_printer_hook(p->pipe_user.nt_user_token, printer) ) {
+               if ( !add_printer_hook(p->mem_ctx, p->pipe_user.nt_user_token, printer) ) {
                        free_a_printer(&printer,2);
                        return WERR_ACCESS_DENIED;
                }
@@ -7793,6 +7869,17 @@ WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u,
                goto done;
        }
 
+        switch(level) {
+       case 3:
+               fstrcpy(driver_name,
+                       driver.info_3->name ? driver.info_3->name : "");
+               break;
+       case 6:
+               fstrcpy(driver_name,
+                       driver.info_6->name ?  driver.info_6->name : "");
+               break;
+        }
+
        /*
         * I think this is where he DrvUpgradePrinter() hook would be
         * be called in a driver's interface DLL on a Windows NT 4.0/2k
@@ -7916,26 +8003,27 @@ static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
 
 static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
-       pstring path;
-       pstring long_archi;
-       fstring servername;
-       char *pservername;
+       char *path = NULL;
+       char *long_archi = NULL;
+       char *servername = NULL;
+       const char *pservername = NULL;
        const char *short_archi;
        DRIVER_DIRECTORY_1 *info=NULL;
        WERROR result = WERR_OK;
+       TALLOC_CTX *ctx = talloc_tos();
 
-       unistr2_to_ascii(servername, name, sizeof(servername));
-       unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi));
-
-       /* check for beginning double '\'s and that the server
-          long enough */
-
-       pservername = servername;
-       if ( *pservername == '\\' && strlen(servername)>2 ) {
-               pservername += 2;
+       servername = unistr2_to_ascii_talloc(ctx, name);
+       if (!servername) {
+               return WERR_NOMEM;
+       }
+       long_archi = unistr2_to_ascii_talloc(ctx, uni_environment);
+       if (!long_archi) {
+               return WERR_NOMEM;
        }
 
-       if ( !is_myname_or_ipaddr( pservername ) )
+       pservername = canon_servername(servername);
+
+       if ( !is_myname_or_ipaddr(pservername))
                return WERR_INVALID_PARAM;
 
        if (!(short_archi = get_short_archi(long_archi)))
@@ -7944,7 +8032,12 @@ static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen
        if((info=SMB_MALLOC_P(DRIVER_DIRECTORY_1)) == NULL)
                return WERR_NOMEM;
 
-       slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", pservername, short_archi);
+       path = talloc_asprintf(ctx,
+                       "\\\\%s\\print$\\%s", pservername, short_archi);
+       if (!path) {
+               result = WERR_NOMEM;
+               goto out;
+       }
 
        DEBUG(4,("printer driver directory: [%s]\n", path));
 
@@ -8313,7 +8406,8 @@ WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_
        int             snum=0;
        WERROR          status = WERR_OK;
        Printer_entry   *Printer=find_printer_index_by_hnd(p, handle);
-       pstring         valuename;
+       char *valuename = NULL;
+       TALLOC_CTX *ctx = p->mem_ctx;
 
        DEBUG(5,("spoolss_deleteprinterdata\n"));
 
@@ -8334,7 +8428,11 @@ WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_
        if (!W_ERROR_IS_OK(status))
                return status;
 
-       unistr2_to_ascii(valuename, value, sizeof(valuename));
+       valuename = unistr2_to_ascii_talloc(ctx, value);
+       if (!valuename) {
+               free_a_printer(&printer, 2);
+               return WERR_NOMEM;
+       }
 
        status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename );
 
@@ -8342,6 +8440,7 @@ WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_
                mod_a_printer( printer, 2 );
 
        free_a_printer(&printer, 2);
+       TALLOC_FREE(valuename);
 
        return status;
 }
@@ -8391,7 +8490,7 @@ WERROR _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM
        /* can't add if builtin */
 
        if (get_a_builtin_ntform(&form->name,&tmpForm)) {
-               status = WERR_ALREADY_EXISTS;
+               status = WERR_FILE_EXISTS;
                goto done;
        }
 
@@ -9245,7 +9344,9 @@ WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX
        int             snum=0;
        WERROR          status = WERR_OK;
        Printer_entry   *Printer=find_printer_index_by_hnd(p, handle);
-       pstring         valuename, keyname;
+       char *valuename = NULL;
+       char *keyname = NULL;
+       TALLOC_CTX *ctx = p->mem_ctx;
 
        DEBUG(5,("spoolss_deleteprinterdataex\n"));
 
@@ -9262,13 +9363,16 @@ WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX
                return WERR_ACCESS_DENIED;
        }
 
+       valuename = unistr2_to_ascii_talloc(ctx, value);
+       keyname = unistr2_to_ascii_talloc(ctx, key);
+       if (!valuename || !keyname) {
+               return WERR_NOMEM;
+       }
+
        status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
        if (!W_ERROR_IS_OK(status))
                return status;
 
-       unistr2_to_ascii(valuename, value, sizeof(valuename));
-       unistr2_to_ascii(keyname, key, sizeof(keyname));
-
        status = delete_printer_dataex( printer, keyname, valuename );
 
        if ( W_ERROR_IS_OK(status) )
@@ -9545,13 +9649,16 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
 
        /* copy data into the reply */
 
-       r_u->ctr.size           = r_u->needed;
+       /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
+          response buffer size is != the offered buffer size
+
+               r_u->ctr.size           = r_u->needed;
+       */
+       r_u->ctr.size           = in_size;
 
        r_u->ctr.size_of_array  = r_u->returned;
        r_u->ctr.values         = enum_values;
 
-
-
 done:
        if ( printer )
        free_a_printer(&printer, 2);
@@ -9562,7 +9669,7 @@ done:
 /****************************************************************************
 ****************************************************************************/
 
-static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, char *name)
+static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, const char *name)
 {
        init_unistr(&info->name, name);
 }
@@ -9573,12 +9680,15 @@ static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
                                                 uint32 offered,
                                                 uint32 *needed)
 {
-       pstring path;
-       pstring long_archi;
+       char *long_archi = NULL;
        PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
        WERROR result = WERR_OK;
+       TALLOC_CTX *ctx = talloc_tos();
 
-       unistr2_to_ascii(long_archi, environment, sizeof(long_archi));
+       long_archi = unistr2_to_ascii_talloc(ctx, environment);
+       if (!long_archi) {
+               return WERR_NOMEM;
+       }
 
        if (!get_short_archi(long_archi))
                return WERR_INVALID_ENVIRONMENT;
@@ -9586,9 +9696,7 @@ static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
        if((info=SMB_MALLOC_P(PRINTPROCESSOR_DIRECTORY_1)) == NULL)
                return WERR_NOMEM;
 
-       pstrcpy(path, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
-
-       fill_printprocessordirectory_1(info, path);
+       fill_printprocessordirectory_1(info, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
 
        *needed += spoolss_size_printprocessordirectory_info_1(info);
 
@@ -9673,7 +9781,8 @@ static WERROR xcvtcp_addport( NT_USER_TOKEN *token, RPC_BUFFER *in,
                               RPC_BUFFER *out, uint32 *needed )
 {
        NT_PORT_DATA_1 port1;
-       pstring device_uri;
+       TALLOC_CTX *ctx = talloc_tos();
+       char *device_uri = NULL;
 
        ZERO_STRUCT( port1 );
 
@@ -9687,18 +9796,24 @@ static WERROR xcvtcp_addport( NT_USER_TOKEN *token, RPC_BUFFER *in,
 
        switch ( port1.protocol ) {
        case PORT_PROTOCOL_DIRECT:
-               pstr_sprintf( device_uri, "socket://%s:%d/", port1.hostaddr, port1.port );
+               device_uri = talloc_asprintf(ctx,
+                               "socket://%s:%d/", port1.hostaddr, port1.port );
                break;
 
        case PORT_PROTOCOL_LPR:
-               pstr_sprintf( device_uri, "lpr://%s/%s", port1.hostaddr, port1.queue );
+               device_uri = talloc_asprintf(ctx,
+                       "lpr://%s/%s", port1.hostaddr, port1.queue );
                break;
 
        default:
                return WERR_UNKNOWN_PORT;
        }
 
-       return add_port_hook( token, port1.name, device_uri );
+       if (!device_uri) {
+               return WERR_NOMEM;
+       }
+
+       return add_port_hook(ctx, token, port1.name, device_uri );
 }
 
 /*******************************************************************