r8066: * had to modify the printer data storage slightly in ntprinters.tdb
[gd/samba/.git] / source / rpc_server / srv_spoolss_nt.c
index 95237e979f4c85f03e3bda93deadd75432cab336..19ef3700e6dbc3ef938ba2858185916d959f7d71 100644 (file)
@@ -3,9 +3,9 @@
  *  RPC Pipe client / server routines
  *  Copyright (C) Andrew Tridgell              1992-2000,
  *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
- *  Copyright (C) Jean François Micouleau      1998-2000,
+ *  Copyright (C) Jean François Micouleau      1998-2000,
  *  Copyright (C) Jeremy Allison               2001-2002,
- *  Copyright (C) Gerald Carter                       2000-2003,
+ *  Copyright (C) Gerald Carter                       2000-2004,
  *  Copyright (C) Tim Potter                   2001-2002.
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -28,6 +28,8 @@
 
 #include "includes.h"
 
+extern userdom_struct current_user_info;
+
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_RPC_SRV
 
@@ -64,14 +66,14 @@ struct table_node {
 static Printer_entry *printers_list;
 
 typedef struct _counter_printer_0 {
-       ubi_dlNode Next;
-       ubi_dlNode Prev;
+       struct _counter_printer_0 *next;
+       struct _counter_printer_0 *prev;
        
        int snum;
        uint32 counter;
 } counter_printer_0;
 
-static ubi_dlList counter_list;
+static counter_printer_0 *counter_list;
 
 static struct cli_state notify_cli; /* print notify back-channel */
 static uint32 smb_connections=0;
@@ -180,7 +182,7 @@ static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle)
                /* Tell the connections db we're no longer interested in
                 * printer notify messages. */
 
-               register_message_flags( False, FLAG_MSG_PRINTING );
+               register_message_flags( False, FLAG_MSG_PRINT_NOTIFY );
        }
 
        smb_connections--;
@@ -201,7 +203,7 @@ static void free_printer_entry(void *ptr)
                        snum = -1;
                        srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
                } else if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTER) {
-                       snum = print_queue_snum(Printer->dev.handlename);
+                       snum = print_queue_snum(Printer->sharename);
                        if (snum != -1)
                                srv_spoolss_replycloseprinter(snum,
                                                &Printer->notify.client_hnd);
@@ -238,7 +240,7 @@ static SPOOL_NOTIFY_OPTION *dup_spool_notify_option(SPOOL_NOTIFY_OPTION *sp)
        if (!sp)
                return NULL;
 
-       new_sp = (SPOOL_NOTIFY_OPTION *)malloc(sizeof(SPOOL_NOTIFY_OPTION));
+       new_sp = SMB_MALLOC_P(SPOOL_NOTIFY_OPTION);
        if (!new_sp)
                return NULL;
 
@@ -273,7 +275,36 @@ static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd
 }
 
 /****************************************************************************
-  find printer index by handle
+ look for a printer object cached on an open printer handle
+****************************************************************************/
+
+WERROR find_printer_in_print_hnd_cache( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL_2 **info2, 
+                                        const char *servername, const char *printername )
+{
+       Printer_entry *p;
+       
+       DEBUG(10,("find_printer_in_print_hnd_cache: printer [\\\\%s\\%s]\n", 
+               servername, printername));
+
+       for ( p=printers_list; p; p=p->next )
+       {
+               if ( p->printer_type==PRINTER_HANDLE_IS_PRINTER 
+                       && p->printer_info
+                       && strequal( p->sharename, printername )
+                       && strequal( p->servername, servername ) )
+               {
+                       DEBUG(10,("Found printer\n"));
+                       *info2 = dup_printer_2( ctx, p->printer_info->info_2 );
+                       if ( *info2 )
+                               return WERR_OK;
+               }
+       }
+
+       return WERR_INVALID_PRINTER_NAME;
+}
+
+/****************************************************************************
+  destroy any cached printer_info_2 structures on open handles
 ****************************************************************************/
 
 void invalidate_printer_hnd_cache( char *printername )
@@ -285,7 +316,8 @@ void invalidate_printer_hnd_cache( char *printername )
        for ( p=printers_list; p; p=p->next )
        {
                if ( p->printer_type==PRINTER_HANDLE_IS_PRINTER 
-                       && StrCaseCmp(p->dev.handlename, printername)==0)
+                       && p->printer_info
+                       && StrCaseCmp(p->sharename, printername)==0)
                {
                        DEBUG(10,("invalidating printer_info cache for handl:\n"));
                        free_a_printer( &p->printer_info, 2 );
@@ -349,37 +381,55 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
                return WERR_ACCESS_DENIED;
        }
 #endif
-
-       if (del_a_printer(Printer->dev.handlename) != 0) {
-               DEBUG(3,("Error deleting printer %s\n", Printer->dev.handlename));
+       
+       /* this does not need a become root since the access check has been 
+          done on the handle already */
+          
+       if (del_a_printer( Printer->sharename ) != 0) {
+               DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
                return WERR_BADFID;
        }
 
+       /* the delete printer script shoudl be run as root if the user has perms */
+       
        if (*lp_deleteprinter_cmd()) {
 
                char *cmd = lp_deleteprinter_cmd();
                pstring command;
                int ret;
-               int i;
-
-               /* Printer->dev.handlename equals portname equals sharename */
-               slprintf(command, sizeof(command)-1, "%s \"%s\"", cmd,
-                                       Printer->dev.handlename);
+               SE_PRIV se_printop = SE_PRINT_OPERATOR;
+               BOOL is_print_op;
+               
+               pstr_sprintf(command, "%s \"%s\"", cmd, Printer->sharename);
 
+               is_print_op = user_has_privileges( p->pipe_user.nt_user_token, &se_printop );
+       
                DEBUG(10,("Running [%s]\n", command));
-               ret = smbrun(command, NULL);
-               if (ret != 0) {
-                       return WERR_BADFID; /* What to return here? */
+
+               /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
+       
+               if ( is_print_op )
+                       become_root();
+               
+               if ( (ret = smbrun(command, NULL)) == 0 ) {
+                       /* Tell everyone we updated smb.conf. */
+                       message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
                }
+               
+               if ( is_print_op )
+                       unbecome_root();
+
+               /********** END SePrintOperatorPrivlege BLOCK **********/
+
                DEBUGADD(10,("returned [%d]\n", ret));
 
-               /* Send SIGHUP to process group... is there a better way? */
-               kill(0, SIGHUP);
+               if (ret != 0) 
+                       return WERR_BADFID; /* What to return here? */
 
                /* go ahead and re-read the services immediately */
                reload_services( False );
 
-               if ( ( i = lp_servicenumber( Printer->dev.handlename ) ) < 0 )
+               if ( lp_servicenumber( Printer->sharename )  < 0 )
                        return WERR_ACCESS_DENIED;
        }
 
@@ -400,14 +450,14 @@ static BOOL get_printer_snum(pipes_struct *p, POLICY_HND *hnd, int *number)
        }
        
        switch (Printer->printer_type) {
-       case PRINTER_HANDLE_IS_PRINTER:         
-               DEBUG(4,("short name:%s\n", Printer->dev.handlename));                  
-               *number = print_queue_snum(Printer->dev.handlename);
-               return (*number != -1);
-       case PRINTER_HANDLE_IS_PRINTSERVER:
-               return False;
-       default:
-               return False;
+               case PRINTER_HANDLE_IS_PRINTER:         
+                       DEBUG(4,("short name:%s\n", Printer->sharename));                       
+                       *number = print_queue_snum(Printer->sharename);
+                       return (*number != -1);
+               case PRINTER_HANDLE_IS_PRINTSERVER:
+                       return False;
+               default:
+                       return False;
        }
 }
 
@@ -447,66 +497,103 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
 {
        int snum;
        int n_services=lp_numservices();
-       char *aprinter;
+       char *aprinter, *printername;
+       const char *servername;
        fstring sname;
        BOOL found=False;
+       NT_PRINTER_INFO_LEVEL *printer;
+       WERROR result;
        
-       DEBUG(4,("Setting printer name=%s (len=%d)\n", handlename, strlen(handlename)));
+       DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename)));
 
-       if (Printer->printer_type==PRINTER_HANDLE_IS_PRINTSERVER) {
-               ZERO_STRUCT(Printer->dev.printerservername);
-               strncpy(Printer->dev.printerservername, handlename, strlen(handlename));
-               return True;
+       aprinter = handlename;
+       if ( *handlename == '\\' ) {
+               servername = handlename + 2;
+               if ( (aprinter = strchr_m( handlename+2, '\\' )) != NULL ) {
+                       *aprinter = '\0';
+                       aprinter++;
+               }
        }
+       else {
+               servername = "";
+       }
+       
+       /* save the servername to fill in replies on this handle */
+       
+       if ( !is_myname_or_ipaddr( servername ) )
+               return False;
+
+       fstrcpy( Printer->servername, servername );
+       
+       if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER )
+               return True;
 
-       if (Printer->printer_type!=PRINTER_HANDLE_IS_PRINTER)
+       if ( Printer->printer_type != PRINTER_HANDLE_IS_PRINTER )
                return False;
+
+       DEBUGADD(5, ("searching for [%s]\n", aprinter ));
+
+       /* Search all sharenames first as this is easier than pulling 
+          the printer_info_2 off of disk */
        
-       if (*handlename=='\\') {
-               aprinter=strchr_m(handlename+2, '\\');
-               aprinter++;
-       }
-       else {
-               aprinter=handlename;
+       snum = find_service(aprinter);
+       
+       if ( lp_snum_ok(snum) && lp_print_ok(snum) ) {
+               found = True;
+               fstrcpy( sname, aprinter );
        }
 
-       DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter, strlen(aprinter)));
-
-       /*
-        * The original code allowed smbd to store a printer name that
-        * was different from the share name.  This is not possible 
-        * anymore, so I've simplified this loop greatly.  Here
-        * we are just verifying that the printer name is a valid
-        * printer service defined in smb.conf
-        *                          --jerry [Fri Feb 15 11:17:46 CST 2002]
-        */
+       /* do another loop to look for printernames */
+       
+       for (snum=0; !found && snum<n_services; snum++) {
 
-       for (snum=0; snum<n_services; snum++) {
+               /* no point in checking if this is not a printer or 
+                  we aren't allowing printername != sharename */
 
-               if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
+               if ( !(lp_snum_ok(snum) 
+                       && lp_print_ok(snum) 
+                       && !lp_force_printername(snum)) ) 
+               {
                        continue;
+               }
                
                fstrcpy(sname, lp_servicename(snum));
 
-               DEBUGADD(5,("share:%s\n",sname));
+               printer = NULL;
+               result = get_a_printer( 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)));
+                       continue;
+               }
+               
+               /* printername is always returned as \\server\printername */
+               if ( !(printername = strchr_m(&printer->info_2->printername[2], '\\')) ) {
+                       DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
+                               printer->info_2->printername));
+                       free_a_printer( &printer, 2);
+                       continue;
+               }
                
-               if (! StrCaseCmp(sname, aprinter)) {
+               printername++;
+               
+               if ( strequal(printername, aprinter) ) {
                        found = True;
-                       break;
                }
-
+               
+               DEBUGADD(10, ("printername: %s\n", printername));
+               
+               free_a_printer( &printer, 2);
        }
 
-               
-       if (!found) {
+       if ( !found ) {
                DEBUGADD(4,("Printer not found\n"));
                return False;
        }
        
        DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
 
-       ZERO_STRUCT(Printer->dev.handlename);
-       fstrcpy(Printer->dev.handlename, sname);
+       fstrcpy(Printer->sharename, sname);
 
        return True;
 }
@@ -521,7 +608,7 @@ static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint3
 
        DEBUG(10,("open_printer_hnd: name [%s]\n", name));
 
-       if((new_printer=(Printer_entry *)malloc(sizeof(Printer_entry))) == NULL)
+       if((new_printer=SMB_MALLOC_P(Printer_entry)) == NULL)
                return False;
 
        ZERO_STRUCTP(new_printer);
@@ -536,7 +623,7 @@ static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint3
        
        new_printer->notify.option=NULL;
                                
-       if ( !(new_printer->ctx = talloc_init("Printer Entry [0x%x]", (uint32)hnd)) ) {
+       if ( !(new_printer->ctx = talloc_init("Printer Entry [%p]", hnd)) ) {
                DEBUG(0,("open_printer_hnd: talloc_init() failed!\n"));
                close_printer_handle(p, hnd);
                return False;
@@ -559,41 +646,6 @@ static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint3
        return True;
 }
 
-/****************************************************************************
- Allocate more memory for a BUFFER.
-****************************************************************************/
-
-static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
-{
-       prs_struct *ps;
-       uint32 extra_space;
-       uint32 old_offset;
-       
-       ps= &buffer->prs;
-
-       /* damn, I'm doing the reverse operation of prs_grow() :) */
-       if (buffer_size < prs_data_size(ps))
-               extra_space=0;
-       else    
-               extra_space = buffer_size - prs_data_size(ps);
-
-       /*
-        * save the offset and move to the end of the buffer
-        * prs_grow() checks the extra_space against the offset
-        */
-       old_offset=prs_offset(ps);      
-       prs_set_offset(ps, prs_data_size(ps));
-       
-       if (!prs_grow(ps, extra_space))
-               return False;
-
-       prs_set_offset(ps, old_offset);
-
-       buffer->string_at_end=prs_data_size(ps);
-
-       return True;
-}
-
 /***************************************************************************
  check to see if the client motify handle is monitoring the notification
  given by (notify_type, notify_field).
@@ -617,7 +669,11 @@ static BOOL is_monitoring_event(Printer_entry *p, uint16 notify_type,
         * might use the flags though instead of the NOTIFY_OPTION_INFO 
         * --jerry
         */
-        
+
+       if (!option) {
+               return False;
+       }
+
        if (p->notify.flags)
                return is_monitoring_event_flags(
                        p->notify.flags, notify_type, notify_field);
@@ -638,10 +694,8 @@ static BOOL is_monitoring_event(Printer_entry *p, uint16 notify_type,
                }
        }
        
-       DEBUG(10, ("%s is not monitoring 0x%02x/0x%02x\n",
-                  (p->printer_type == PRINTER_HANDLE_IS_PRINTER) ?
-                  p->dev.handlename : p->dev.printerservername,
-                  notify_type, notify_field));
+       DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
+                  p->servername, p->sharename, notify_type, notify_field));
        
        return False;
 }
@@ -664,10 +718,10 @@ static void notify_string(struct spoolss_notify_msg *msg,
        
        /* The length of the message includes the trailing \0 */
 
-       init_unistr2(&unistr, msg->notify.data, msg->len);
+       init_unistr2(&unistr, msg->notify.data, UNI_STR_TERMINATE);
 
        data->notify_data.data.length = msg->len * 2;
-       data->notify_data.data.string = (uint16 *)talloc(mem_ctx, msg->len * 2);
+       data->notify_data.data.string = TALLOC_ARRAY(mem_ctx, uint16, msg->len);
 
        if (!data->notify_data.data.string) {
                data->notify_data.data.length = 0;
@@ -704,7 +758,7 @@ static void notify_system_time(struct spoolss_notify_msg *msg,
                return;
 
        data->notify_data.data.length = prs_offset(&ps);
-       data->notify_data.data.string = talloc(mem_ctx, prs_offset(&ps));
+       data->notify_data.data.string = TALLOC(mem_ctx, prs_offset(&ps));
 
        prs_copy_all_data_out((char *)data->notify_data.data.string, &ps);
 
@@ -862,7 +916,7 @@ static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MS
        if ( i == ctr->num_groups ) {
                ctr->num_groups++;
 
-               if ( !(groups = talloc_realloc( ctr->ctx, ctr->msg_groups, sizeof(SPOOLSS_NOTIFY_MSG_GROUP)*ctr->num_groups)) ) {
+               if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
                        DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
                        return 0;
                }
@@ -880,7 +934,7 @@ static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MS
        
        msg_grp->num_msgs++;
        
-       if ( !(msg_list =  talloc_realloc( ctr->ctx, msg_grp->msgs, sizeof(SPOOLSS_NOTIFY_MSG)*msg_grp->num_msgs )) ) {
+       if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
                DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
                return 0;
        }
@@ -892,7 +946,7 @@ static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MS
        /* need to allocate own copy of data */
        
        if ( msg->len != 0 ) 
-               msg_grp->msgs[new_slot].notify.data = talloc_memdup( ctr->ctx, msg->notify.data, msg->len );
+               msg_grp->msgs[new_slot].notify.data = TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
        
        return ctr->num_groups;
 }
@@ -930,31 +984,29 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
                SPOOL_NOTIFY_INFO_DATA *data;
                uint32  data_len = 0;
                uint32  id;
-               int     i, event_index;
+               int     i;
 
                /* Is there notification on this handle? */
 
                if ( !p->notify.client_connected )
                        continue;
 
-               DEBUG(10,("Client connected! [%s]\n", p->dev.handlename));
+               DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
 
                /* For this printer?  Print servers always receive 
                    notifications. */
 
                if ( ( p->printer_type == PRINTER_HANDLE_IS_PRINTER )  &&
-                   ( !strequal(msg_group->printername, p->dev.handlename) ) )
+                   ( !strequal(msg_group->printername, p->sharename) ) )
                        continue;
 
                DEBUG(10,("Our printer\n"));
                
                /* allocate the max entries possible */
                
-               data = talloc( mem_ctx, msg_group->num_msgs*sizeof(SPOOL_NOTIFY_INFO_DATA) );
+               data = TALLOC_ARRAY( mem_ctx, SPOOL_NOTIFY_INFO_DATA, msg_group->num_msgs);
                ZERO_STRUCTP(data);
                
-               event_index = 0;
-               
                /* build the array of change notifications */
                
                sending_msg_count = 0;
@@ -970,8 +1022,8 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
                        sending_msg_count++;
                        
                        
-                       DEBUG(10,("process_notify2_message: Sending message type [%x] field [%x] for printer [%s]\n",
-                               msg->type, msg->field, p->dev.handlename));
+                       DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
+                               msg->type, msg->field, p->sharename));
 
                        /* 
                         * if the is a printer notification handle and not a job notification 
@@ -1075,58 +1127,6 @@ static BOOL notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, voi
        return True;
 }
 
-/* ENUMJOB last timestamp list. */
-struct ejts_list {
-       struct ejts_list *next, *prev;
-       char *printer_name;
-       struct timeval tv;
-};
-
-static struct ejts_list *ejts_head;
-
-static struct ejts_list *find_enumjobs_timestamp(const char *printer_name)
-{
-       struct ejts_list *ejtsl;
-
-       for( ejtsl = ejts_head; ejtsl; ejtsl = ejtsl->next)
-               if (strequal(ejtsl->printer_name, printer_name))
-                       return ejtsl;
-       return NULL;
-}
-
-static void set_enumjobs_timestamp(int snum)
-{
-       const char *printer_name = lp_const_servicename(snum);
-       struct ejts_list *ejtsl = find_enumjobs_timestamp(printer_name);
-
-       if (!ejtsl) {
-               ejtsl = (struct ejts_list *)malloc(sizeof(struct ejts_list));
-               if (!ejtsl)
-                       return;
-               ejtsl->printer_name = strdup(printer_name);
-               if (!ejtsl->printer_name) {
-                       SAFE_FREE(ejtsl);
-                       return;
-               }
-               DLIST_ADD(ejts_head, ejtsl);
-       }
-
-       gettimeofday(&ejtsl->tv, NULL);
-}
-
-static int timeval_diff(struct timeval *tv1, struct timeval *tv2)
-{
-       if (tv1->tv_sec > tv2->tv_sec)
-               return 1;
-       if (tv1->tv_sec < tv2->tv_sec)
-               return -1;
-       if (tv1->tv_usec > tv2->tv_usec)
-               return 1;
-       if (tv1->tv_usec < tv2->tv_usec)
-               return -1;
-       return 0;
-}
-
 /********************************************************************
  Receive a notify2 message list
  ********************************************************************/
@@ -1149,7 +1149,7 @@ static void receive_notify2_message_list(int msg_type, pid_t src, void *msg, siz
        msg_count = IVAL(buf, 0);
        msg_ptr = buf + 4;
 
-       DEBUG(5, ("receive_notify2_message_list: got %d messages in list\n", msg_count));
+       DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
 
        if (msg_count == 0) {
                DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
@@ -1189,30 +1189,7 @@ static void receive_notify2_message_list(int msg_type, pid_t src, void *msg, siz
                ZERO_STRUCT( notify );
                notify2_unpack_msg( &notify, &msg_tv, msg_ptr, msg_len );
                msg_ptr += msg_len;
-               
-               /* See if it is still relevent. */
-               if (notify.type == JOB_NOTIFY_TYPE) {
-                       BOOL status_is_deleting = False;
 
-                       if (notify.field == JOB_NOTIFY_STATUS && (notify.notify.value[0] & (JOB_STATUS_DELETING|JOB_STATUS_DELETED)))
-                               status_is_deleting = True;
-
-                       if (!status_is_deleting) {
-                               struct ejts_list *ejtsl = find_enumjobs_timestamp(notify.printer);
-
-                               if (ejtsl && (timeval_diff(&ejtsl->tv, &msg_tv) > 0)) {
-
-                                       DEBUG(10, ("receive_notify2_message_list: enumjobs ts = %u, %u, msg ts = %u, %u discarding\n",
-                                               (unsigned int)ejtsl->tv.tv_sec, (unsigned int)ejtsl->tv.tv_usec,
-                                               (unsigned int)msg_tv.tv_sec, (unsigned int)msg_tv.tv_usec ));
-
-                                       /* Message no longer relevent. Ignore it. */
-                                       if ( notify.len != 0 )
-                                               SAFE_FREE( notify.notify.data );
-                                       continue;
-                               }
-                       }
-               }
                /* add to correct list in container */
                
                notify_msg_ctr_addmsg( &messages, &notify );
@@ -1239,6 +1216,22 @@ static void receive_notify2_message_list(int msg_type, pid_t src, void *msg, siz
        return;
 }
 
+/********************************************************************
+ callback to MSG_PRINTER_CHANGED.  When a printer is changed by 
+ one smbd, all of processes must clear their printer cache immediately.
+ ********************************************************************/
+
+void receive_printer_mod_msg(int msg_type, pid_t src, void *buf, size_t len)
+{
+       fstring printername;
+       
+       fstrcpy( printername, buf );
+       
+       DEBUG(10,("receive_printer_mod_msg: Printer change [%s]\n", printername ));
+       
+       invalidate_printer_hnd_cache( printername );
+}
+
 /********************************************************************
  Send a message to ourself about new driver being installed
  so we can upgrade the information for each printer bound to this
@@ -1295,7 +1288,7 @@ void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len)
                                
                                /* all we care about currently is the change_id */
                                
-                               result = mod_a_printer(*printer, 2);
+                               result = mod_a_printer(printer, 2);
                                if (!W_ERROR_IS_OK(result)) {
                                        DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n", 
                                                dos_errstr(result)));
@@ -1326,7 +1319,7 @@ void update_monitored_printq_cache( void )
                if ( (printer->printer_type == PRINTER_HANDLE_IS_PRINTER) 
                        && printer->notify.client_connected ) 
                {
-                       snum = print_queue_snum(printer->dev.handlename);
+                       snum = print_queue_snum(printer->sharename);
                        print_queue_status( snum, NULL, NULL );
                }
                
@@ -1399,7 +1392,7 @@ void reset_all_printerdata(int msg_type, pid_t src, void *buf, size_t len)
                                                printer->info_2->printername, printer->info_2->drivername));
                                }       
                                
-                               result = mod_a_printer( *printer, 2 );
+                               result = mod_a_printer( printer, 2 );
                                if ( !W_ERROR_IS_OK(result) ) {
                                        DEBUG(3,("reset_all_printerdata: mod_a_printer() failed!  (%s)\n", 
                                                get_dos_error_msg(result)));
@@ -1431,7 +1424,7 @@ static DEVICEMODE* dup_devicemode(TALLOC_CTX *ctx, DEVICEMODE *devmode)
        
        /* bulk copy first */
        
-       d = talloc_memdup(ctx, devmode, sizeof(DEVICEMODE));
+       d = TALLOC_MEMDUP(ctx, devmode, sizeof(DEVICEMODE));
        if (!d)
                return NULL;
                
@@ -1439,7 +1432,7 @@ static DEVICEMODE* dup_devicemode(TALLOC_CTX *ctx, DEVICEMODE *devmode)
        
        len = unistrlen(devmode->devicename.buffer);
        if (len != -1) {
-               d->devicename.buffer = talloc(ctx, len*2);
+               d->devicename.buffer = TALLOC_ARRAY(ctx, uint16, len);
                if (unistrcpy(d->devicename.buffer, devmode->devicename.buffer) != len)
                        return NULL;
        }
@@ -1447,12 +1440,12 @@ static DEVICEMODE* dup_devicemode(TALLOC_CTX *ctx, DEVICEMODE *devmode)
 
        len = unistrlen(devmode->formname.buffer);
        if (len != -1) {
-               d->devicename.buffer = talloc(ctx, len*2);
+               d->devicename.buffer = TALLOC_ARRAY(ctx, uint16, len);
                if (unistrcpy(d->formname.buffer, devmode->formname.buffer) != len)
                        return NULL;
        }
 
-       d->private = talloc_memdup(ctx, devmode->private, devmode->driverextra);
+       d->dev_private = TALLOC_MEMDUP(ctx, devmode->dev_private, devmode->driverextra);
        
        return d;
 }
@@ -1500,10 +1493,10 @@ static void convert_to_openprinterex(TALLOC_CTX *ctx, SPOOL_Q_OPEN_PRINTER_EX *q
 
        DEBUG(8,("convert_to_openprinterex\n"));
                                
-       q_u_ex->printername_ptr = q_u->printername_ptr;
-       
-       if (q_u->printername_ptr)
-               copy_unistr2(&q_u_ex->printername, &q_u->printername);
+       if ( q_u->printername ) {
+               q_u_ex->printername = TALLOC_P( ctx, UNISTR2 );
+               copy_unistr2(q_u_ex->printername, q_u->printername);
+       }
        
        copy_printer_default(ctx, &q_u_ex->printer_default, &q_u->printer_default);
 }
@@ -1597,7 +1590,6 @@ WERROR _spoolss_open_printer(pipes_struct *p, SPOOL_Q_OPEN_PRINTER *q_u, SPOOL_R
 
 WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u)
 {
-       UNISTR2                 *printername = NULL;
        PRINTER_DEFAULT         *printer_default = &q_u->printer_default;
        POLICY_HND              *handle = &r_u->handle;
 
@@ -1606,15 +1598,13 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
        struct current_user user;
        Printer_entry *Printer=NULL;
 
-       if (q_u->printername_ptr != 0)
-               printername = &q_u->printername;
-
-       if (printername == NULL)
+       if ( !q_u->printername )
                return WERR_INVALID_PRINTER_NAME;
 
        /* some sanity check because you can open a printer or a print server */
        /* aka: \\server\printer or \\server */
-       unistr2_to_ascii(name, printername, sizeof(name)-1);
+
+       unistr2_to_ascii(name, q_u->printername, sizeof(name)-1);
 
        DEBUGADD(3,("checking name: %s\n",name));
 
@@ -1622,9 +1612,9 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
                return WERR_INVALID_PRINTER_NAME;
        
        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 ));
+       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;
        }
@@ -1679,15 +1669,19 @@ Can't find printer handle we created for printer %s\n", name ));
 
                if ( printer_default->access_required & SERVER_ACCESS_ADMINISTER ) 
                {
+                       SE_PRIV se_printop = SE_PRINT_OPERATOR;
+
                        if (!lp_ms_add_printer_wizard()) {
                                close_printer_handle(p, handle);
                                return WERR_ACCESS_DENIED;
                        }
 
-                       /* if the user is not root and not a printer admin, then fail */
+                       /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
+                          and not a printer admin, then fail */
                        
                        if ( user.uid != 0
-                            && !user_in_list(uidtoname(user.uid), lp_printer_admin(snum), user.groups, user.ngroups) )
+                               && !user_has_privileges( user.nt_user_token, &se_printop )
+                               && !user_in_list(uidtoname(user.uid), lp_printer_admin(snum), user.groups, user.ngroups) )
                        {
                                close_printer_handle(p, handle);
                                return WERR_ACCESS_DENIED;
@@ -1736,6 +1730,11 @@ Can't find printer handle we created for printer %s\n", name ));
 
                /* check smb.conf parameters and the the sec_desc */
                
+               if ( !check_access(smbd_server_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {    
+                       DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
+                       return WERR_ACCESS_DENIED;
+               }
+
                if (!user_ok(uidtoname(user.uid), snum, user.groups, user.ngroups) || !print_access_check(&user, snum, printer_default->access_required)) {
                        DEBUG(3, ("access DENIED for printer open\n"));
                        close_printer_handle(p, handle);
@@ -1768,18 +1767,21 @@ Can't find printer handle we created for printer %s\n", name ));
         if ( (Printer->printer_type != PRINTER_HANDLE_IS_PRINTSERVER)
                && q_u->printer_default.devmode_cont.devmode_ptr )
         { 
-               convert_devicemode( Printer->dev.handlename, q_u->printer_default.devmode_cont.devmode,
+               convert_devicemode( Printer->sharename, q_u->printer_default.devmode_cont.devmode,
                        &Printer->nt_devmode );
         }
 
+#if 0  /* JERRY -- I'm doubtful this is really effective */
        /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN 
           optimization in Windows 2000 clients  --jerry */
 
        if ( (printer_default->access_required == PRINTER_ACCESS_ADMINISTER) 
                && (RA_WIN2K == get_remote_arch()) )
        {
-               usleep( 500000 );
+               DEBUG(10,("_spoolss_open_printer_ex: Enabling LAN/WAN hack for Win2k clients.\n"));
+               sys_usleep( 500000 );
        }
+#endif
 
        return WERR_OK;
 }
@@ -1883,12 +1885,12 @@ BOOL convert_devicemode(const char *printername, const DEVICEMODE *devmode,
         * has a new one. JRA.
         */
 
-       if ((devmode->driverextra != 0) && (devmode->private != NULL)) {
-               SAFE_FREE(nt_devmode->private);
+       if ((devmode->driverextra != 0) && (devmode->dev_private != NULL)) {
+               SAFE_FREE(nt_devmode->nt_dev_private);
                nt_devmode->driverextra=devmode->driverextra;
-               if((nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8))) == NULL)
+               if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
                        return False;
-               memcpy(nt_devmode->private, devmode->private, nt_devmode->driverextra);
+               memcpy(nt_devmode->nt_dev_private, devmode->dev_private, nt_devmode->driverextra);
        }
 
        *pp_nt_devmode = nt_devmode;
@@ -1984,6 +1986,8 @@ static int get_version_id (char * arch)
                {"Windows NT R4000",     "W32MIPS",     2 },    
                {"Windows NT Alpha_AXP", "W32ALPHA",    2 },
                {"Windows NT PowerPC",   "W32PPC",      2 },
+               {"Windows IA64",         "IA64",        3 },
+               {"Windows x64",          "x64",         3 },
                {NULL,                   "",            -1 }
        };
  
@@ -2207,7 +2211,8 @@ static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printe
                                  uint32 *needed, uint32 in_size  )
 {
        REGISTRY_VALUE          *val;
-       int                     size, data_len;
+       uint32                  size;
+       int                     data_len;
        
        if ( !(val = get_printer_data( printer->info_2, key, value)) )
                return WERR_BADFILE;
@@ -2225,11 +2230,11 @@ static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printe
                
                /* special case for 0 length values */
                if ( data_len ) {
-                       if ( (*data  = (uint8 *)talloc_memdup(ctx, regval_data_p(val), data_len)) == NULL )
+                       if ( (*data  = (uint8 *)TALLOC_MEMDUP(ctx, regval_data_p(val), data_len)) == NULL )
                                return WERR_NOMEM;
                }
                else {
-                       if ( (*data  = (uint8 *)talloc_zero(ctx, in_size)) == NULL )
+                       if ( (*data  = (uint8 *)TALLOC_ZERO(ctx, in_size)) == NULL )
                                return WERR_NOMEM;
                }
        }
@@ -2275,16 +2280,16 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
        DEBUG(8,("getprinterdata_printer_server:%s\n", value));
                
        if (!StrCaseCmp(value, "W3SvcInstalled")) {
-               *type = 0x4;
-               if((*data = (uint8 *)talloc_zero(ctx, 4*sizeof(uint8) )) == NULL)
+               *type = REG_DWORD;
+               if((*data = (uint8 *)TALLOC_ZERO(ctx, 4*sizeof(uint8) )) == NULL)
                        return WERR_NOMEM;
                *needed = 0x4;
                return WERR_OK;
        }
 
        if (!StrCaseCmp(value, "BeepEnabled")) {
-               *type = 0x4;
-               if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
+               *type = REG_DWORD;
+               if((*data = (uint8 *)TALLOC(ctx, 4*sizeof(uint8) )) == NULL)
                        return WERR_NOMEM;
                SIVAL(*data, 0, 0x00);
                *needed = 0x4;                  
@@ -2292,8 +2297,8 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
        }
 
        if (!StrCaseCmp(value, "EventLog")) {
-               *type = 0x4;
-               if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
+               *type = REG_DWORD;
+               if((*data = (uint8 *)TALLOC(ctx, 4 )) == NULL)
                        return WERR_NOMEM;
                /* formally was 0x1b */
                SIVAL(*data, 0, 0x0);
@@ -2302,8 +2307,8 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
        }
 
        if (!StrCaseCmp(value, "NetPopup")) {
-               *type = 0x4;
-               if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
+               *type = REG_DWORD;
+               if((*data = (uint8 *)TALLOC(ctx, 4 )) == NULL)
                        return WERR_NOMEM;
                SIVAL(*data, 0, 0x00);
                *needed = 0x4;
@@ -2311,8 +2316,8 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
        }
 
        if (!StrCaseCmp(value, "MajorVersion")) {
-               *type = 0x4;
-               if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
+               *type = REG_DWORD;
+               if((*data = (uint8 *)TALLOC(ctx, 4 )) == NULL)
                        return WERR_NOMEM;
 
                /* Windows NT 4.0 seems to not allow uploading of drivers
@@ -2330,15 +2335,14 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
        }
 
        if (!StrCaseCmp(value, "MinorVersion")) {
-               *type = 0x4;
-               if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
+               *type = REG_DWORD;
+               if((*data = (uint8 *)TALLOC(ctx, 4 )) == NULL)
                        return WERR_NOMEM;
                SIVAL(*data, 0, 0);
                *needed = 0x4;
                return WERR_OK;
        }
 
-#if 0  /* JERRY */     
        /* REG_BINARY
         *  uint32 size          = 0x114
         *  uint32 major         = 5
@@ -2347,22 +2351,28 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
         *  extra unicode string = e.g. "Service Pack 3"
         */
        if (!StrCaseCmp(value, "OSVersion")) {
-               *type = 0x4;
-               if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
+               *type = REG_BINARY;
+               *needed = 0x114;
+
+               if ( !(*data = TALLOC_ZERO_ARRAY(ctx, uint8, *needed)) )
                        return WERR_NOMEM;
-               SIVAL(*data, 0, 2);
-               *needed = 0x4;
+
+               SIVAL(*data, 0, *needed);       /* size */
+               SIVAL(*data, 4, 5);             /* Windows 2000 == 5.0 */
+               SIVAL(*data, 8, 0);
+               SIVAL(*data, 12, 2195);         /* build */
+               
+               /* leave extra string empty */
+               
                return WERR_OK;
        }
-#endif
 
-       if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
-               fstring string;
 
-               fstrcpy(string, string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH));
-               *type = 0x1;                    
+       if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
+               const char *string="C:\\PRINTERS";
+               *type = REG_SZ;
                *needed = 2*(strlen(string)+1);         
-               if((*data  = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
+               if((*data  = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
                        return WERR_NOMEM;
                memset(*data, 0, (*needed > in_size) ? *needed:in_size);
                
@@ -2375,10 +2385,10 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
        }
 
        if (!StrCaseCmp(value, "Architecture")) {                       
-               pstring string="Windows NT x86";
-               *type = 0x1;                    
+               const char *string="Windows NT x86";
+               *type = REG_SZ;
                *needed = 2*(strlen(string)+1); 
-               if((*data  = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
+               if((*data  = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
                        return WERR_NOMEM;
                memset(*data, 0, (*needed > in_size) ? *needed:in_size);
                for (i=0; i<strlen(string); i++) {
@@ -2389,10 +2399,18 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
        }
 
        if (!StrCaseCmp(value, "DsPresent")) {
-               *type = 0x4;
-               if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
+               *type = REG_DWORD;
+               if((*data = (uint8 *)TALLOC(ctx, 4 )) == NULL)
                        return WERR_NOMEM;
-               SIVAL(*data, 0, 0x01);
+
+               /* only show the publish check box if we are a 
+                  memeber of a AD domain */
+
+               if ( lp_security() == SEC_ADS )
+                       SIVAL(*data, 0, 0x01);
+               else
+                       SIVAL(*data, 0, 0x00);
+
                *needed = 0x4;
                return WERR_OK;
        }
@@ -2400,11 +2418,11 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint
        if (!StrCaseCmp(value, "DNSMachineName")) {                     
                pstring hostname;
                
-               if (!get_myfullname(hostname))
+               if (!get_mydnsfullname(hostname))
                        return WERR_BADFILE;
-               *type = 0x1;                    
+               *type = REG_SZ;
                *needed = 2*(strlen(hostname)+1);       
-               if((*data  = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
+               if((*data  = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
                        return WERR_NOMEM;
                memset(*data, 0, (*needed > in_size) ? *needed:in_size);
                for (i=0; i<strlen(hostname); i++) {
@@ -2479,7 +2497,7 @@ WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO
                if ( strequal(value, "ChangeId") ) {
                        *type = REG_DWORD;
                        *needed = sizeof(uint32);
-                       if ( (*data = (uint8*)talloc(p->mem_ctx, sizeof(uint32))) == NULL) {
+                       if ( (*data = (uint8*)TALLOC(p->mem_ctx, sizeof(uint32))) == NULL) {
                                status = WERR_NOMEM;
                                goto done;
                        }
@@ -2501,7 +2519,7 @@ done:
                /* reply this param doesn't exist */
                
                if ( *out_size ) {
-                       if((*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL) {
+                       if((*data=(uint8 *)TALLOC_ZERO_ARRAY(p->mem_ctx, uint8, *out_size)) == NULL) {
                                if ( printer ) 
                                        free_a_printer( &printer, 2 );
                                return WERR_NOMEM;
@@ -2567,7 +2585,8 @@ static BOOL spoolss_connect_to_client(struct cli_state *the_cli,
        }
 
        the_cli->protocol = PROTOCOL_NT1;
-    
+       cli_setup_signing_state(the_cli, lp_client_signing());
+  
        if (!cli_negprot(the_cli)) {
                DEBUG(0,("spoolss_connect_to_client: machine %s rejected the negotiate protocol. Error was : %s.\n", remote_machine, cli_errstr(the_cli) ));
                cli_shutdown(the_cli);
@@ -2637,13 +2656,15 @@ static BOOL srv_spoolss_replyopenprinter(int snum, const char *printer,
 
                fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
 
+               ZERO_STRUCT(notify_cli);
+
                if(!spoolss_connect_to_client(&notify_cli, client_ip, unix_printer))
                        return False;
                        
                message_register(MSG_PRINTER_NOTIFY2, receive_notify2_message_list);
                /* Tell the connections db we're now interested in printer
                 * notify messages. */
-               register_message_flags( True, FLAG_MSG_PRINTING );
+               register_message_flags( True, FLAG_MSG_PRINT_NOTIFY );
        }
 
        /* 
@@ -2739,15 +2760,13 @@ void spoolss_notify_server_name(int snum,
                                       NT_PRINTER_INFO_LEVEL *printer,
                                       TALLOC_CTX *mem_ctx) 
 {
-       pstring temp_name, temp;
+       pstring temp;
        uint32 len;
 
-       slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name());
-
-       len = rpcstr_push(temp, temp_name, sizeof(temp)-2, STR_TERMINATE);
+       len = rpcstr_push(temp, printer->info_2->servername, sizeof(temp)-2, STR_TERMINATE);
 
        data->notify_data.data.length = len;
-       data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+       data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
 
        if (!data->notify_data.data.string) {
                data->notify_data.data.length = 0;
@@ -2782,7 +2801,7 @@ void spoolss_notify_printer_name(int snum,
        len = rpcstr_push(temp, p, sizeof(temp)-2, STR_TERMINATE);
 
        data->notify_data.data.length = len;
-       data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+       data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
        
        if (!data->notify_data.data.string) {
                data->notify_data.data.length = 0;
@@ -2808,7 +2827,7 @@ void spoolss_notify_share_name(int snum,
        len = rpcstr_push(temp, lp_servicename(snum), sizeof(temp)-2, STR_TERMINATE);
 
        data->notify_data.data.length = len;
-       data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+       data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
        
        if (!data->notify_data.data.string) {
                data->notify_data.data.length = 0;
@@ -2836,7 +2855,7 @@ void spoolss_notify_port_name(int snum,
        len = rpcstr_push(temp, printer->info_2->portname, sizeof(temp)-2, STR_TERMINATE);
 
        data->notify_data.data.length = len;
-       data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+       data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
        
        if (!data->notify_data.data.string) {
                data->notify_data.data.length = 0;
@@ -2863,7 +2882,7 @@ void spoolss_notify_driver_name(int snum,
        len = rpcstr_push(temp, printer->info_2->drivername, sizeof(temp)-2, STR_TERMINATE);
 
        data->notify_data.data.length = len;
-       data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+       data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
        
        if (!data->notify_data.data.string) {
                data->notify_data.data.length = 0;
@@ -2892,7 +2911,7 @@ void spoolss_notify_comment(int snum,
                len = rpcstr_push(temp, printer->info_2->comment, sizeof(temp)-2, STR_TERMINATE);
 
        data->notify_data.data.length = len;
-       data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+       data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
        
        if (!data->notify_data.data.string) {
                data->notify_data.data.length = 0;
@@ -2919,7 +2938,7 @@ void spoolss_notify_location(int snum,
        len = rpcstr_push(temp, printer->info_2->location,sizeof(temp)-2, STR_TERMINATE);
 
        data->notify_data.data.length = len;
-       data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+       data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
        
        if (!data->notify_data.data.string) {
                data->notify_data.data.length = 0;
@@ -2958,7 +2977,7 @@ void spoolss_notify_sepfile(int snum,
        len = rpcstr_push(temp, printer->info_2->sepfile, sizeof(temp)-2, STR_TERMINATE);
 
        data->notify_data.data.length = len;
-       data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+       data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
        
        if (!data->notify_data.data.string) {
                data->notify_data.data.length = 0;
@@ -2985,7 +3004,7 @@ void spoolss_notify_print_processor(int snum,
        len = rpcstr_push(temp,  printer->info_2->printprocessor, sizeof(temp)-2, STR_TERMINATE);
 
        data->notify_data.data.length = len;
-       data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+       data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
        
        if (!data->notify_data.data.string) {
                data->notify_data.data.length = 0;
@@ -3012,7 +3031,7 @@ void spoolss_notify_parameters(int snum,
        len = rpcstr_push(temp,  printer->info_2->parameters, sizeof(temp)-2, STR_TERMINATE);
 
        data->notify_data.data.length = len;
-       data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+       data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
        
        if (!data->notify_data.data.string) {
                data->notify_data.data.length = 0;
@@ -3039,7 +3058,7 @@ void spoolss_notify_datatype(int snum,
        len = rpcstr_push(temp, printer->info_2->datatype, sizeof(pstring)-2, STR_TERMINATE);
 
        data->notify_data.data.length = len;
-       data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+       data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
        
        if (!data->notify_data.data.string) {
                data->notify_data.data.length = 0;
@@ -3199,7 +3218,7 @@ static void spoolss_notify_username(int snum,
        len = rpcstr_push(temp, queue->fs_user, sizeof(temp)-2, STR_TERMINATE);
 
        data->notify_data.data.length = len;
-       data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+       data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
        
        if (!data->notify_data.data.string) {
                data->notify_data.data.length = 0;
@@ -3239,7 +3258,7 @@ static void spoolss_notify_job_name(int snum,
        len = rpcstr_push(temp, queue->fs_file, sizeof(temp)-2, STR_TERMINATE);
 
        data->notify_data.data.length = len;
-       data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+       data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
        
        if (!data->notify_data.data.string) {
                data->notify_data.data.length = 0;
@@ -3289,7 +3308,7 @@ static void spoolss_notify_job_status_string(int snum,
        len = rpcstr_push(temp, p, sizeof(temp) - 2, STR_TERMINATE);
 
        data->notify_data.data.length = len;
-       data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+       data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
        
        if (!data->notify_data.data.string) {
                data->notify_data.data.length = 0;
@@ -3387,7 +3406,7 @@ static void spoolss_notify_submitted_time(int snum,
        len = sizeof(SYSTEMTIME);
 
        data->notify_data.data.length = len;
-       data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
+       data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
 
        if (!data->notify_data.data.string) {
                data->notify_data.data.length = 0;
@@ -3478,6 +3497,7 @@ static const struct s_notify_info_data_table notify_info_data_table[] =
 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_TOTAL_PAGES,             "JOB_NOTIFY_TOTAL_PAGES",             NOTIFY_ONE_VALUE, spoolss_notify_total_pages },
 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_PAGES_PRINTED,           "JOB_NOTIFY_PAGES_PRINTED",           NOTIFY_ONE_VALUE, spoolss_notify_pages_printed },
 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_TOTAL_BYTES,             "JOB_NOTIFY_TOTAL_BYTES",             NOTIFY_ONE_VALUE, spoolss_notify_job_size },
+{ PRINT_TABLE_END, 0x0, NULL, 0x0, NULL },
 };
 
 /*******************************************************************
@@ -3543,7 +3563,7 @@ static int search_notify(uint16 type, uint16 field, int *value)
 {      
        int i;
 
-       for (i = 0; i < sizeof(notify_info_data_table); i++) {
+       for (i = 0; notify_info_data_table[i].type != PRINT_TABLE_END; i++) {
                if (notify_info_data_table[i].type == type &&
                    notify_info_data_table[i].field == field &&
                    notify_info_data_table[i].fn != NULL) {
@@ -3608,7 +3628,7 @@ static BOOL construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY
                if (!search_notify(type, field, &j) )
                        continue;
 
-               if((tid=(SPOOL_NOTIFY_INFO_DATA *)Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
+               if((tid=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
                        DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
                        return False;
                } else 
@@ -3664,7 +3684,7 @@ static BOOL construct_notify_jobs_info(print_queue_struct *queue,
                if (!search_notify(type, field, &j) )
                        continue;
 
-               if((tid=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) {
+               if((tid=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
                        DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
                        return False;
                }
@@ -3719,7 +3739,6 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
        Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
        int n_services=lp_numservices();
        int i;
-       uint32 id;
        SPOOL_NOTIFY_OPTION *option;
        SPOOL_NOTIFY_OPTION_TYPE *option_type;
 
@@ -3729,11 +3748,16 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
                return WERR_BADFID;
 
        option=Printer->notify.option;
-       id=1;
        info->version=2;
        info->data=NULL;
        info->count=0;
 
+       /* a bug in xp sp2 rc2 causes it to send a fnpcn request without 
+          sending a ffpcn() request first */
+
+       if ( !option )
+               return WERR_BADFID;
+
        for (i=0; i<option->count; i++) {
                option_type=&(option->ctr.type[i]);
                
@@ -3796,6 +3820,12 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY
        info->data=NULL;
        info->count=0;
 
+       /* a bug in xp sp2 rc2 causes it to send a fnpcn request without 
+          sending a ffpcn() request first */
+
+       if ( !option )
+               return WERR_BADFID;
+
        get_printer_snum(p, hnd, &snum);
 
        for (i=0; i<option->count; i++) {
@@ -3931,23 +3961,21 @@ static BOOL construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *p
        count = print_queue_length(snum, &status);
 
        /* check if we already have a counter for this printer */       
-       session_counter = (counter_printer_0 *)ubi_dlFirst(&counter_list);
-
-       for(; session_counter; session_counter = (counter_printer_0 *)ubi_dlNext(session_counter)) {
+       for(session_counter = counter_list; session_counter; session_counter = session_counter->next) {
                if (session_counter->snum == snum)
                        break;
        }
 
        /* it's the first time, add it to the list */
        if (session_counter==NULL) {
-               if((session_counter=(counter_printer_0 *)malloc(sizeof(counter_printer_0))) == NULL) {
+               if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) {
                        free_a_printer(&ntprinter, 2);
                        return False;
                }
                ZERO_STRUCTP(session_counter);
                session_counter->snum=snum;
                session_counter->counter=0;
-               ubi_dlAddHead( &counter_list, (ubi_dlNode *)session_counter);
+               DLIST_ADD(counter_list, session_counter);
        }
        
        /* increment it */
@@ -3963,7 +3991,7 @@ static BOOL construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *p
 
        init_unistr(&printer->printername, chaine);
        
-       slprintf(chaine,sizeof(chaine)-1,"\\\\%s", get_called_name());
+       slprintf(chaine,sizeof(chaine)-1,"\\\\%s", get_server_name(print_hnd));
        init_unistr(&printer->servername, chaine);
        
        printer->cjobs = count;
@@ -4062,7 +4090,7 @@ static void free_dev_mode(DEVICEMODE *dev)
        if (dev == NULL)
                return;
 
-               SAFE_FREE(dev->private);
+       SAFE_FREE(dev->dev_private);
        SAFE_FREE(dev); 
 }
 
@@ -4105,8 +4133,8 @@ static BOOL convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode
        devmode->mediatype        = ntdevmode->mediatype;
        devmode->dithertype       = ntdevmode->dithertype;
 
-       if (ntdevmode->private != NULL) {
-               if ((devmode->private=(uint8 *)memdup(ntdevmode->private, ntdevmode->driverextra)) == NULL)
+       if (ntdevmode->nt_dev_private != NULL) {
+               if ((devmode->dev_private=(uint8 *)memdup(ntdevmode->nt_dev_private, ntdevmode->driverextra)) == NULL)
                        return False;
        }
        
@@ -4134,7 +4162,7 @@ DEVICEMODE *construct_dev_mode(int snum)
                goto done;
        }
 
-       if ((devmode = (DEVICEMODE *)malloc(sizeof(DEVICEMODE))) == NULL) {
+       if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) {
                DEBUG(2,("construct_dev_mode: malloc fail.\n"));
                goto done;
        }
@@ -4231,7 +4259,7 @@ static BOOL construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **
                return False;
 
        *pp_printer = NULL;
-       if ((printer = (PRINTER_INFO_3 *)malloc(sizeof(PRINTER_INFO_3))) == NULL) {
+       if ((printer = SMB_MALLOC_P(PRINTER_INFO_3)) == NULL) {
                DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
                return False;
        }
@@ -4326,11 +4354,11 @@ static BOOL construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *p
 static BOOL construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
 {
        char *guid_str = NULL;
-       GUID guid;
+       struct uuid guid; 
        
        if (is_printer_published(print_hnd, snum, &guid)) {
-               asprintf(&guid_str, "{%s}", uuid_string_static(guid));
-               strupper(guid_str);
+               asprintf(&guid_str, "{%s}", smb_uuid_string_static(guid));
+               strupper_m(guid_str);
                init_unistr(&printer->guid, guid_str);
                printer->action = SPOOL_DS_PUBLISH;
        } else {
@@ -4345,13 +4373,14 @@ static BOOL construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *p
  Spoolss_enumprinters.
 ********************************************************************/
 
-static WERROR enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        int snum;
        int i;
        int n_services=lp_numservices();
        PRINTER_INFO_1 *tp, *printers=NULL;
        PRINTER_INFO_1 current_prt;
+       WERROR result = WERR_OK;
        
        DEBUG(4,("enum_all_printers_info_1\n"));        
 
@@ -4360,7 +4389,7 @@ static WERROR enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32
                        DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
 
                        if (construct_printer_info_1(NULL, flags, &current_prt, snum)) {
-                               if((tp=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1))) == NULL) {
+                               if((tp=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) {
                                        DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
                                        SAFE_FREE(printers);
                                        *returned=0;
@@ -4379,29 +4408,36 @@ static WERROR enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32
        for (i=0; i<*returned; i++)
                (*needed) += spoolss_size_printer_info_1(&printers[i]);
 
-       if (!alloc_buffer_size(buffer, *needed))
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
+       }
 
        /* fill the buffer with the structures */
        for (i=0; i<*returned; i++)
                smb_io_printer_info_1("", buffer, &printers[i], 0);     
 
+out:
        /* clear memory */
+
        SAFE_FREE(printers);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-       else
-               return WERR_OK;
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
+
+       return result;
 }
 
 /********************************************************************
  enum_all_printers_info_1_local.
 *********************************************************************/
 
-static WERROR enum_all_printers_info_1_local(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        DEBUG(4,("enum_all_printers_info_1_local\n"));  
        
@@ -4412,7 +4448,7 @@ static WERROR enum_all_printers_info_1_local(NEW_BUFFER *buffer, uint32 offered,
  enum_all_printers_info_1_name.
 *********************************************************************/
 
-static WERROR enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        char *s = name;
        
@@ -4428,32 +4464,35 @@ static WERROR enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, ui
                return WERR_INVALID_NAME;
 }
 
+#if 0  /* JERRY -- disabled for now.  Don't think this is used, tested, or correct */
 /********************************************************************
  enum_all_printers_info_1_remote.
 *********************************************************************/
 
-static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        PRINTER_INFO_1 *printer;
        fstring printername;
        fstring desc;
        fstring comment;
        DEBUG(4,("enum_all_printers_info_1_remote\n")); 
+       WERROR result = WERR_OK;
 
        /* JFM: currently it's more a place holder than anything else.
         * In the spooler world there is a notion of server registration.
-        * the print servers are registring (sp ?) on the PDC (in the same domain)
+        * the print servers are registered on the PDC (in the same domain)
         *
-        * We should have a TDB here. The registration is done thru an undocumented RPC call.
+        * We should have a TDB here. The registration is done thru an 
+        * undocumented RPC call.
         */
        
-       if((printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1))) == NULL)
+       if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
                return WERR_NOMEM;
 
        *returned=1;
        
-       slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", get_called_name());           
-       slprintf(desc, sizeof(desc)-1,"%s", get_called_name());
+       slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", name);                
+       slprintf(desc, sizeof(desc)-1,"%s", name);
        slprintf(comment, sizeof(comment)-1, "Logged on Domain");
 
        init_unistr(&printer->description, desc);
@@ -4464,30 +4503,36 @@ static WERROR enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer,
        /* check the required size. */  
        *needed += spoolss_size_printer_info_1(printer);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(printer);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_info_1("", buffer, printer, 0);  
 
+out:
        /* clear memory */
        SAFE_FREE(printer);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-       else
-               return WERR_OK;
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
+
+       return result;
 }
 
+#endif
+
 /********************************************************************
  enum_all_printers_info_1_network.
 *********************************************************************/
 
-static WERROR enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        char *s = name;
 
@@ -4516,20 +4561,21 @@ static WERROR enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer,
  * called from api_spoolss_enumprinters (see this to understand)
  ********************************************************************/
 
-static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        int snum;
        int i;
        int n_services=lp_numservices();
        PRINTER_INFO_2 *tp, *printers=NULL;
        PRINTER_INFO_2 current_prt;
+       WERROR result = WERR_OK;
 
        for (snum=0; snum<n_services; snum++) {
                if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
                        DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
                                
                        if (construct_printer_info_2(NULL, &current_prt, snum)) {
-                               if((tp=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2))) == NULL) {
+                               if((tp=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) == NULL) {
                                        DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
                                        SAFE_FREE(printers);
                                        *returned = 0;
@@ -4547,30 +4593,31 @@ static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint3
        for (i=0; i<*returned; i++) 
                (*needed) += spoolss_size_printer_info_2(&printers[i]);
        
-       if (!alloc_buffer_size(buffer, *needed)) {
-               for (i=0; i<*returned; i++) {
-                       free_devmode(printers[i].devmode);
-               }
-               SAFE_FREE(printers);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        for (i=0; i<*returned; i++)
                smb_io_printer_info_2("", buffer, &(printers[i]), 0);   
        
+out:
        /* clear memory */
        for (i=0; i<*returned; i++) {
                free_devmode(printers[i].devmode);
        }
        SAFE_FREE(printers);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-       else
-               return WERR_OK;
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
+
+       return result;
 }
 
 /********************************************************************
@@ -4578,7 +4625,7 @@ static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint3
  ********************************************************************/
 
 static WERROR enumprinters_level1( uint32 flags, fstring name,
-                                NEW_BUFFER *buffer, uint32 offered,
+                                RPC_BUFFER *buffer, uint32 offered,
                                 uint32 *needed, uint32 *returned)
 {
        /* Not all the flags are equals */
@@ -4589,8 +4636,10 @@ static WERROR enumprinters_level1( uint32 flags, fstring name,
        if (flags & PRINTER_ENUM_NAME)
                return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
 
+#if 0  /* JERRY - disabled for now */
        if (flags & PRINTER_ENUM_REMOTE)
                return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
+#endif
 
        if (flags & PRINTER_ENUM_NETWORK)
                return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
@@ -4603,7 +4652,7 @@ static WERROR enumprinters_level1( uint32 flags, fstring name,
  ********************************************************************/
 
 static WERROR enumprinters_level2( uint32 flags, fstring servername,
-                                NEW_BUFFER *buffer, uint32 offered,
+                                RPC_BUFFER *buffer, uint32 offered,
                                 uint32 *needed, uint32 *returned)
 {
        char *s = servername;
@@ -4632,7 +4681,7 @@ static WERROR enumprinters_level2( uint32 flags, fstring servername,
  ********************************************************************/
 
 static WERROR enumprinters_level5( uint32 flags, fstring servername,
-                                NEW_BUFFER *buffer, uint32 offered,
+                                RPC_BUFFER *buffer, uint32 offered,
                                 uint32 *needed, uint32 *returned)
 {
 /*     return enum_all_printers_info_5(buffer, offered, needed, returned);*/
@@ -4650,7 +4699,7 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_
        uint32 flags = q_u->flags;
        UNISTR2 *servername = &q_u->servername;
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        uint32 *returned = &r_u->returned;
@@ -4658,8 +4707,11 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_
        fstring name;
        
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(4,("_spoolss_enumprinters\n"));
 
@@ -4680,7 +4732,7 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_
         */
 
        unistr2_to_ascii(name, servername, sizeof(name)-1);
-       strupper(name);
+       strupper_m(name);
 
        switch (level) {
        case 1:
@@ -4699,11 +4751,12 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        PRINTER_INFO_0 *printer=NULL;
+       WERROR result = WERR_OK;
 
-       if((printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0))) == NULL)
+       if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
                return WERR_NOMEM;
 
        construct_printer_info_0(print_hnd, printer, snum);
@@ -4711,32 +4764,36 @@ static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, NEW_BUFFER
        /* check the required size. */  
        *needed += spoolss_size_printer_info_0(printer);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(printer);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_info_0("", buffer, printer, 0);  
        
+out:
        /* clear memory */
-       SAFE_FREE(printer);
 
-       if (*needed > offered) {
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       SAFE_FREE(printer);
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        PRINTER_INFO_1 *printer=NULL;
+       WERROR result = WERR_OK;
 
-       if((printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1))) == NULL)
+       if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
                return WERR_NOMEM;
 
        construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
@@ -4744,32 +4801,35 @@ static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, NEW_BUFFER
        /* check the required size. */  
        *needed += spoolss_size_printer_info_1(printer);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(printer);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_info_1("", buffer, printer, 0);  
        
+out:
        /* clear memory */
        SAFE_FREE(printer);
 
-       if (*needed > offered) {
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-
-       return WERR_OK; 
+       return result;  
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        PRINTER_INFO_2 *printer=NULL;
+       WERROR result = WERR_OK;
 
-       if((printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)))==NULL)
+       if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
                return WERR_NOMEM;
        
        construct_printer_info_2(print_hnd, printer, snum);
@@ -4777,33 +4837,34 @@ static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, NEW_BUFFER
        /* check the required size. */  
        *needed += spoolss_size_printer_info_2(printer);
        
-       if (!alloc_buffer_size(buffer, *needed)) {
-               free_printer_info_2(printer);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
        }
 
-       /* fill the buffer with the structures */
-       if (!smb_io_printer_info_2("", buffer, printer, 0)) {
-               free_printer_info_2(printer);
-               return WERR_NOMEM;
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
+
+       /* fill the buffer with the structures */
+       if (!smb_io_printer_info_2("", buffer, printer, 0)) 
+               result = WERR_NOMEM;
        
+out:
        /* clear memory */
        free_printer_info_2(printer);
 
-       if (*needed > offered) {
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-
-       return WERR_OK; 
+       return result;  
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        PRINTER_INFO_3 *printer=NULL;
+       WERROR result = WERR_OK;
 
        if (!construct_printer_info_3(print_hnd, &printer, snum))
                return WERR_NOMEM;
@@ -4811,32 +4872,35 @@ static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, NEW_BUFFER
        /* check the required size. */  
        *needed += spoolss_size_printer_info_3(printer);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               free_printer_info_3(printer);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_info_3("", buffer, printer, 0);  
        
+out:
        /* clear memory */
        free_printer_info_3(printer);
        
-       if (*needed > offered) {
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-
-       return WERR_OK; 
+       return result;  
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        PRINTER_INFO_4 *printer=NULL;
+       WERROR result = WERR_OK;
 
-       if((printer=(PRINTER_INFO_4*)malloc(sizeof(PRINTER_INFO_4)))==NULL)
+       if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
                return WERR_NOMEM;
 
        if (!construct_printer_info_4(print_hnd, printer, snum))
@@ -4845,32 +4909,35 @@ static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, NEW_BUFFER
        /* check the required size. */  
        *needed += spoolss_size_printer_info_4(printer);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               free_printer_info_4(printer);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_info_4("", buffer, printer, 0);  
        
+out:
        /* clear memory */
        free_printer_info_4(printer);
        
-       if (*needed > offered) {
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-
-       return WERR_OK; 
+       return result;  
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        PRINTER_INFO_5 *printer=NULL;
+       WERROR result = WERR_OK;
 
-       if((printer=(PRINTER_INFO_5*)malloc(sizeof(PRINTER_INFO_5)))==NULL)
+       if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
                return WERR_NOMEM;
 
        if (!construct_printer_info_5(print_hnd, printer, snum))
@@ -4879,29 +4946,32 @@ static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, NEW_BUFFER
        /* check the required size. */  
        *needed += spoolss_size_printer_info_5(printer);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               free_printer_info_5(printer);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_info_5("", buffer, printer, 0);  
        
+out:
        /* clear memory */
        free_printer_info_5(printer);
        
-       if (*needed > offered) {
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-
-       return WERR_OK; 
+       return result;  
 }
 
-static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        PRINTER_INFO_7 *printer=NULL;
+       WERROR result = WERR_OK;
 
-       if((printer=(PRINTER_INFO_7*)malloc(sizeof(PRINTER_INFO_7)))==NULL)
+       if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
                return WERR_NOMEM;
 
        if (!construct_printer_info_7(print_hnd, printer, snum))
@@ -4910,22 +4980,25 @@ static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, NEW_BUFFER
        /* check the required size. */  
        *needed += spoolss_size_printer_info_7(printer);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               free_printer_info_7(printer);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
+
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_info_7("", buffer, printer, 0);  
        
+out:
        /* clear memory */
        free_printer_info_7(printer);
        
-       if (*needed > offered) {
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-
-       return WERR_OK; 
+       return result;  
 }
 
 /****************************************************************************
@@ -4935,7 +5008,7 @@ WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET
 {
        POLICY_HND *handle = &q_u->handle;
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
@@ -4943,8 +5016,11 @@ WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET
        int snum;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        *needed=0;
 
@@ -5099,11 +5175,11 @@ static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const c
                else
                        pstrcpy( line, v );
                        
-               DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line)));
+               DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line)));
 
                /* add one extra unit16 for the second terminating NULL */
                
-               if ( (tuary=Realloc(*uni_array, (j+1+strlen(line)+2)*sizeof(uint16))) == NULL ) {
+               if ( (tuary=SMB_REALLOC_ARRAY(*uni_array, uint16, j+1+strlen(line)+2)) == NULL ) {
                        DEBUG(2,("init_unistr_array: Realloc error\n" ));
                        return 0;
                } else
@@ -5368,149 +5444,154 @@ static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
 static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
 {
        SAFE_FREE(info->dependentfiles);
-       
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        DRIVER_INFO_1 *info=NULL;
-       WERROR status;
+       WERROR result;
        
-       if((info=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1))) == NULL)
+       if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL)
                return WERR_NOMEM;
        
-       status=construct_printer_driver_info_1(info, snum, servername, architecture, version);
-       if (!W_ERROR_IS_OK(status)) {
-               SAFE_FREE(info);
-               return status;
-       }
+       result = construct_printer_driver_info_1(info, snum, servername, architecture, version);
+       if (!W_ERROR_IS_OK(result)) 
+               goto out;
 
        /* check the required size. */  
        *needed += spoolss_size_printer_driver_info_1(info);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(info);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_driver_info_1("", buffer, info, 0);      
 
+out:
        /* clear memory */
        SAFE_FREE(info);
 
-       if (*needed > offered)
-               return WERR_INSUFFICIENT_BUFFER;
-
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        DRIVER_INFO_2 *info=NULL;
-       WERROR status;
+       WERROR result;
        
-       if((info=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2))) == NULL)
+       if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL)
                return WERR_NOMEM;
        
-       status=construct_printer_driver_info_2(info, snum, servername, architecture, version);
-       if (!W_ERROR_IS_OK(status)) {
-               SAFE_FREE(info);
-               return status;
-       }
+       result = construct_printer_driver_info_2(info, snum, servername, architecture, version);
+       if (!W_ERROR_IS_OK(result)) 
+               goto out;
 
        /* check the required size. */  
        *needed += spoolss_size_printer_driver_info_2(info);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(info);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+       
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_driver_info_2("", buffer, info, 0);      
 
+out:
        /* clear memory */
        SAFE_FREE(info);
 
-       if (*needed > offered)
-               return WERR_INSUFFICIENT_BUFFER;
-       
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        DRIVER_INFO_3 info;
-       WERROR status;
+       WERROR result;
 
        ZERO_STRUCT(info);
 
-       status=construct_printer_driver_info_3(&info, snum, servername, architecture, version);
-       if (!W_ERROR_IS_OK(status)) {
-               return status;
-       }
+       result = construct_printer_driver_info_3(&info, snum, servername, architecture, version);
+       if (!W_ERROR_IS_OK(result))
+               goto out;
 
        /* check the required size. */  
        *needed += spoolss_size_printer_driver_info_3(&info);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               free_printer_driver_info_3(&info);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_driver_info_3("", buffer, &info, 0);
 
+out:
        free_printer_driver_info_3(&info);
 
-       if (*needed > offered)
-               return WERR_INSUFFICIENT_BUFFER;
-
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinterdriver2_level6(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinterdriver2_level6(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
 {
        DRIVER_INFO_6 info;
-       WERROR status;
+       WERROR result;
 
        ZERO_STRUCT(info);
 
-       status=construct_printer_driver_info_6(&info, snum, servername, architecture, version);
-       if (!W_ERROR_IS_OK(status)) {
-               return status;
-       }
+       result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
+       if (!W_ERROR_IS_OK(result)) 
+               goto out;
 
        /* check the required size. */  
        *needed += spoolss_size_printer_driver_info_6(&info);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               free_printer_driver_info_6(&info);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+       
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        smb_io_printer_driver_info_6("", buffer, &info, 0);
 
+out:
        free_printer_driver_info_6(&info);
 
-       if (*needed > offered)
-               return WERR_INSUFFICIENT_BUFFER;
-       
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
@@ -5522,27 +5603,36 @@ WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_
        UNISTR2 *uni_arch = &q_u->architecture;
        uint32 level = q_u->level;
        uint32 clientmajorversion = q_u->clientmajorversion;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        uint32 *servermajorversion = &r_u->servermajorversion;
        uint32 *serverminorversion = &r_u->serverminorversion;
+       Printer_entry *printer;
 
        fstring servername;
        fstring architecture;
        int snum;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(4,("_spoolss_getprinterdriver2\n"));
 
+       if ( !(printer = find_printer_index_by_hnd( p, handle )) ) {
+               DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
+               return WERR_INVALID_PRINTER_NAME;
+       }
+
        *needed = 0;
        *servermajorversion = 0;
        *serverminorversion = 0;
 
-       fstrcpy(servername, get_called_name());
+       fstrcpy(servername, get_server_name( printer ));
        unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
 
        if (!get_printer_snum(p, handle, &snum))
@@ -5557,6 +5647,12 @@ WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_
                return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
        case 6:
                return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
+#if 0  /* JERRY */
+       case 101: 
+               /* apparently this call is the equivalent of 
+                  EnumPrinterDataEx() for the DsDriver key */
+               break;
+#endif
        }
 
        return WERR_UNKNOWN_LEVEL;
@@ -5702,8 +5798,9 @@ WERROR _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R
        if (!get_printer_snum(p, handle, &snum))
                return WERR_BADFID;
 
-       (*buffer_written) = print_job_write(snum, Printer->jobid, (char *)buffer, buffer_size);
-       if (*buffer_written == -1) {
+       (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer,
+                                       (SMB_OFF_T)-1, (size_t)buffer_size);
+       if (*buffer_written == (uint32)-1) {
                r_u->buffer_written = 0;
                if (errno == ENOSPC)
                        return WERR_NO_SPOOL_SPACE;
@@ -5803,7 +5900,6 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
                                 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
 {
        SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
-       struct current_user user;
        WERROR result;
        int snum;
 
@@ -5816,13 +5912,22 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
                result = WERR_BADFID;
                goto done;
        }
+       
+       /* Check the user has permissions to change the security
+          descriptor.  By experimentation with two NT machines, the user
+          requires Full Access to the printer to change security
+          information. */
+
+       if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
+               DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
+               result = WERR_ACCESS_DENIED;
+               goto done;
+       }
 
        /* NT seems to like setting the security descriptor even though
-          nothing may have actually changed.  This causes annoying
-          dialog boxes when the user doesn't have permission to change
-          the security descriptor. */
+          nothing may have actually changed. */
 
-       nt_printing_getsec(p->mem_ctx, Printer->dev.handlename, &old_secdesc_ctr);
+       nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr);
 
        if (DEBUGLEVEL >= 10) {
                SEC_ACL *the_acl;
@@ -5867,21 +5972,7 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
                goto done;
        }
 
-       /* Work out which user is performing the operation */
-
-       get_current_user(&user, p);
-
-       /* Check the user has permissions to change the security
-          descriptor.  By experimentation with two NT machines, the user
-          requires Full Access to the printer to change security
-          information. */
-
-       if (!print_access_check(&user, snum, PRINTER_ACCESS_ADMINISTER)) {
-               result = WERR_ACCESS_DENIED;
-               goto done;
-       }
-
-       result = nt_printing_setsec(Printer->dev.handlename, new_secdesc_ctr);
+       result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
 
  done:
 
@@ -5889,22 +5980,51 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
 }
 
 /********************************************************************
- Do Samba sanity checks on a printer info struct.
- this has changed purpose: it now "canonicalises" printer
- info from a client rather than just checking it is correct
+ Canonicalize printer info from a client
+
+ ATTN: It does not matter what we set the servername to hear 
+ since we do the necessary work in get_a_printer() to set it to 
+ the correct value based on what the client sent in the 
+ _spoolss_open_printer_ex().
  ********************************************************************/
 
 static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
 {
-       DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s portname=%s drivername=%s comment=%s location=%s\n",
-                info->servername, info->printername, info->sharename, info->portname, info->drivername, info->comment, info->location));
+       fstring printername;
+       const char *p;
+       
+       DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
+               "portname=%s drivername=%s comment=%s location=%s\n",
+               info->servername, info->printername, info->sharename, 
+               info->portname, info->drivername, info->comment, info->location));
 
        /* we force some elements to "correct" values */
-       slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", get_called_name());
+       slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
        fstrcpy(info->sharename, lp_servicename(snum));
-       slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
-                get_called_name(), info->sharename);
-       info->attributes = PRINTER_ATTRIBUTE_SAMBA;
+       
+       /* check to see if we allow printername != sharename */
+
+       if ( lp_force_printername(snum) ) {
+               slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
+                       global_myname(), info->sharename );
+       } else {
+
+               /* make sure printername is in \\server\printername format */
+       
+               fstrcpy( printername, info->printername );
+               p = printername;
+               if ( printername[0] == '\\' && printername[1] == '\\' ) {
+                       if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
+                               p++;
+               }
+               
+               slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
+                        global_myname(), p );
+       }
+
+       info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
+       info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
+       
        
        
        return True;
@@ -5913,9 +6033,8 @@ static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
 /****************************************************************************
 ****************************************************************************/
 
-static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
+static BOOL add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
 {
-       extern userdom_struct current_user_info;
        char *cmd = lp_addprinter_cmd();
        char **qlines;
        pstring command;
@@ -5923,6 +6042,8 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
        int ret;
        int fd;
        fstring remote_machine = "%m";
+       SE_PRIV se_printop = SE_PRINT_OPERATOR;
+       BOOL is_print_op;
 
        standard_sub_basic(current_user_info.smb_name, remote_machine,sizeof(remote_machine));
        
@@ -5931,8 +6052,25 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
                        printer->info_2->portname, printer->info_2->drivername,
                        printer->info_2->location, printer->info_2->comment, remote_machine);
 
+       is_print_op = user_has_privileges( token, &se_printop );
+
        DEBUG(10,("Running [%s]\n", command));
-       ret = smbrun(command, &fd);
+
+       /********* BEGIN SePrintOperatorPrivilege **********/
+
+       if ( is_print_op )
+               become_root();
+       
+       if ( (ret = smbrun(command, &fd)) == 0 ) {
+               /* Tell everyone we updated smb.conf. */
+               message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL);
+       }
+
+       if ( is_print_op )
+               unbecome_root();
+
+       /********* END SePrintOperatorPrivilege **********/
+
        DEBUGADD(10,("returned [%d]\n", ret));
 
        if ( ret != 0 ) {
@@ -5941,22 +6079,22 @@ static BOOL add_printer_hook(NT_PRINTER_INFO_LEVEL *printer)
                return False;
        }
 
+       /* reload our services immediately */
+       reload_services( False );
+
        numlines = 0;
        /* Get lines and convert them back to dos-codepage */
        qlines = fd_lines_load(fd, &numlines);
        DEBUGADD(10,("Lines returned = [%d]\n", numlines));
        close(fd);
 
-       if(numlines) {
+       /* Set the portname to what the script says the portname should be. */
+       /* but don't require anything to be return from the script exit a good error code */
+
+       if (numlines) {
                /* Set the portname to what the script says the portname should be. */
                strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
                DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
-
-               /* Send SIGHUP to process group... is there a better way? */
-               kill(0, SIGHUP);
-               
-               /* reload our services immediately */
-               reload_services( False );
        }
 
        file_lines_free(qlines);
@@ -6051,7 +6189,7 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
                        || !strequal(printer->info_2->portname, old_printer->info_2->portname)
                        || !strequal(printer->info_2->location, old_printer->info_2->location)) )
        {
-               if ( !add_printer_hook(printer) ) {
+               if ( !add_printer_hook(p->pipe_user.nt_user_token, printer) ) {
                        result = WERR_ACCESS_DENIED;
                        goto done;
                }
@@ -6090,7 +6228,7 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
         */
 
        if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
-               init_unistr2( &buffer, printer->info_2->comment, strlen(printer->info_2->comment)+1 );
+               init_unistr2( &buffer, printer->info_2->comment, UNI_STR_TERMINATE);
                set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
                        REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
 
@@ -6098,17 +6236,31 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
        }
 
        if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
-               init_unistr2( &buffer, printer->info_2->sharename, strlen(printer->info_2->sharename)+1 );
-               set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
-                       REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
+               init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE);
                set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
                        REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
 
                notify_printer_sharename(snum, printer->info_2->sharename);
        }
 
+       if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
+               char *pname;
+               
+               if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
+                       pname++;
+               else
+                       pname = printer->info_2->printername;
+                       
+
+               init_unistr2( &buffer, pname, UNI_STR_TERMINATE);
+               set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
+                       REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
+
+               notify_printer_printername( snum, pname );
+       }
+       
        if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
-               init_unistr2( &buffer, printer->info_2->portname, strlen(printer->info_2->portname)+1 );
+               init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE);
                set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
                        REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
 
@@ -6116,7 +6268,7 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
        }
 
        if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
-               init_unistr2( &buffer, printer->info_2->location, strlen(printer->info_2->location)+1 );
+               init_unistr2( &buffer, printer->info_2->location, UNI_STR_TERMINATE);
                set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
                        REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
 
@@ -6126,7 +6278,7 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
        /* here we need to update some more DsSpooler keys */
        /* uNCName, serverName, shortServerName */
        
-       init_unistr2( &buffer, global_myname(), strlen(global_myname())+1 );
+       init_unistr2( &buffer, global_myname(), UNI_STR_TERMINATE);
        set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
                REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
        set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
@@ -6134,12 +6286,12 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
 
        slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
                  global_myname(), printer->info_2->sharename );
-       init_unistr2( &buffer, asc_buffer, strlen(asc_buffer)+1 );
+       init_unistr2( &buffer, asc_buffer, UNI_STR_TERMINATE);
        set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
                REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
 
        /* Update printer info */
-       result = mod_a_printer(*printer, 2);
+       result = mod_a_printer(printer, 2);
 
 done:
        free_a_printer(&printer, 2);
@@ -6158,12 +6310,9 @@ static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
        SPOOL_PRINTER_INFO_LEVEL_7 *info7 = info->info_7;
        int snum;
        Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
-       WERROR result;
 
        DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
 
-       result = WERR_OK;
-
        if (!Printer)
                return WERR_BADFID;
 
@@ -6188,6 +6337,7 @@ WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SET
        DEVMODE_CTR devmode_ctr = q_u->devmode_ctr;
        SEC_DESC_BUF *secdesc_ctr = q_u->secdesc_ctr;
        uint32 command = q_u->command;
+       WERROR result;
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
        
@@ -6201,7 +6351,12 @@ WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SET
                case 0:
                        return control_printer(handle, command, p);
                case 2:
-                       return update_printer(p, handle, level, info, devmode_ctr.devmode);
+                       result = update_printer(p, handle, level, info, devmode_ctr.devmode);
+                       if (!W_ERROR_IS_OK(result)) 
+                               return result;
+                       if (secdesc_ctr)
+                               result = update_printer_sec(handle, level, info, p, secdesc_ctr);
+                       return result;
                case 3:
                        return update_printer_sec(handle, level, info, p,
                                                  secdesc_ctr);
@@ -6253,8 +6408,10 @@ WERROR _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u)
 
 WERROR _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u)
 {
-       /* that's an [in out] buffer (despite appearences to the contrary) */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
+       /* that's an [in out] buffer */
+
+       if ( q_u->buffer ) 
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
 
        r_u->needed = 0;
        return WERR_INVALID_PARAM; /* this is what a NT server
@@ -6267,18 +6424,16 @@ WERROR _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u
 ****************************************************************************/
 
 static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
-                            int position, int snum)
+                            int position, int snum, 
+                            NT_PRINTER_INFO_LEVEL *ntprinter)
 {
-       pstring temp_name;
-       
        struct tm *t;
        
        t=gmtime(&queue->time);
-       slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name());
 
        job_info->jobid=queue->job;     
        init_unistr(&job_info->printername, lp_servicename(snum));
-       init_unistr(&job_info->machinename, temp_name);
+       init_unistr(&job_info->machinename, ntprinter->info_2->servername);
        init_unistr(&job_info->username, queue->fs_user);
        init_unistr(&job_info->document, queue->fs_file);
        init_unistr(&job_info->datatype, "RAW");
@@ -6300,17 +6455,15 @@ static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
                            NT_PRINTER_INFO_LEVEL *ntprinter,
                            DEVICEMODE *devmode)
 {
-       pstring temp_name;
        struct tm *t;
 
        t=gmtime(&queue->time);
-       slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name());
 
        job_info->jobid=queue->job;
        
        init_unistr(&job_info->printername, ntprinter->info_2->printername);
        
-       init_unistr(&job_info->machinename, temp_name);
+       init_unistr(&job_info->machinename, ntprinter->info_2->servername);
        init_unistr(&job_info->username, queue->fs_user);
        init_unistr(&job_info->document, queue->fs_file);
        init_unistr(&job_info->notifyname, queue->fs_user);
@@ -6343,13 +6496,15 @@ static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
 ****************************************************************************/
 
 static WERROR enumjobs_level1(print_queue_struct *queue, int snum,
-                             NEW_BUFFER *buffer, uint32 offered,
+                              NT_PRINTER_INFO_LEVEL *ntprinter,
+                             RPC_BUFFER *buffer, uint32 offered,
                              uint32 *needed, uint32 *returned)
 {
        JOB_INFO_1 *info;
        int i;
+       WERROR result = WERR_OK;
        
-       info=(JOB_INFO_1 *)malloc(*returned*sizeof(JOB_INFO_1));
+       info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
        if (info==NULL) {
                SAFE_FREE(queue);
                *returned=0;
@@ -6357,7 +6512,7 @@ static WERROR enumjobs_level1(print_queue_struct *queue, int snum,
        }
        
        for (i=0; i<*returned; i++)
-               fill_job_info_1(&info[i], &queue[i], i, snum);
+               fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter );
 
        SAFE_FREE(queue);
 
@@ -6365,24 +6520,28 @@ static WERROR enumjobs_level1(print_queue_struct *queue, int snum,
        for (i=0; i<*returned; i++)
                (*needed) += spoolss_size_job_info_1(&info[i]);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(info);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        for (i=0; i<*returned; i++)
                smb_io_job_info_1("", buffer, &info[i], 0);     
 
+out:
        /* clear memory */
        SAFE_FREE(info);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
@@ -6390,26 +6549,18 @@ static WERROR enumjobs_level1(print_queue_struct *queue, int snum,
 ****************************************************************************/
 
 static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
-                             NEW_BUFFER *buffer, uint32 offered,
+                              NT_PRINTER_INFO_LEVEL *ntprinter,
+                             RPC_BUFFER *buffer, uint32 offered,
                              uint32 *needed, uint32 *returned)
 {
-       NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
        JOB_INFO_2 *info = NULL;
        int i;
-       WERROR result;
+       WERROR result = WERR_OK;
        DEVICEMODE *devmode = NULL;
        
-       info=(JOB_INFO_2 *)malloc(*returned*sizeof(JOB_INFO_2));
-       if (info==NULL) {
+       if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) {
                *returned=0;
-               result = WERR_NOMEM;
-               goto done;
-       }
-
-       result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
-       if (!W_ERROR_IS_OK(result)) {
-               *returned = 0;
-               goto done;
+               return WERR_NOMEM;
        }
                
        /* this should not be a failure condition if the devmode is NULL */
@@ -6417,8 +6568,7 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
        devmode = construct_dev_mode(snum);
 
        for (i=0; i<*returned; i++)
-               fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter,
-                               devmode);
+               fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
 
        free_a_printer(&ntprinter, 2);
        SAFE_FREE(queue);
@@ -6428,29 +6578,26 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
                (*needed) += spoolss_size_job_info_2(&info[i]);
 
        if (*needed > offered) {
-               *returned=0;
                result = WERR_INSUFFICIENT_BUFFER;
-               goto done;
+               goto out;
        }
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(info);
-               result = WERR_INSUFFICIENT_BUFFER;
-               goto done;
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the structures */
        for (i=0; i<*returned; i++)
                smb_io_job_info_2("", buffer, &info[i], 0);     
 
-       result = WERR_OK;
-
- done:
-       free_a_printer(&ntprinter, 2);
+out:
        free_devmode(devmode);
-       SAFE_FREE(queue);
        SAFE_FREE(info);
 
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
+
        return result;
 
 }
@@ -6463,51 +6610,60 @@ WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO
 {      
        POLICY_HND *handle = &q_u->handle;
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        uint32 *returned = &r_u->returned;
        WERROR wret;
-
+       NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
        int snum;
        print_status_struct prt_status;
        print_queue_struct *queue=NULL;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(4,("_spoolss_enumjobs\n"));
 
        *needed=0;
        *returned=0;
 
+       /* lookup the printer snum and tdb entry */
+       
        if (!get_printer_snum(p, handle, &snum))
                return WERR_BADFID;
 
+       wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
+       if ( !W_ERROR_IS_OK(wret) )
+               return wret;
+       
        *returned = print_queue_status(snum, &queue, &prt_status);
        DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
 
        if (*returned == 0) {
-               set_enumjobs_timestamp(snum);
                SAFE_FREE(queue);
                return WERR_OK;
        }
 
        switch (level) {
        case 1:
-               wret = enumjobs_level1(queue, snum, buffer, offered, needed, returned);
-               set_enumjobs_timestamp(snum);
+               wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned);
                return wret;
        case 2:
-               wret = enumjobs_level2(queue, snum, buffer, offered, needed, returned);
-               set_enumjobs_timestamp(snum);
+               wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned);
                return wret;
        default:
                SAFE_FREE(queue);
                *returned=0;
-               return WERR_UNKNOWN_LEVEL;
+               wret = WERR_UNKNOWN_LEVEL;
        }
+       
+       free_a_printer( &ntprinter, 2 );
+       return wret;
 }
 
 /****************************************************************************
@@ -6535,7 +6691,7 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u
                return WERR_BADFID;
        }
 
-       if (!print_job_exists(snum, jobid)) {
+       if (!print_job_exists(lp_const_servicename(snum), jobid)) {
                return WERR_INVALID_PRINTER_NAME;
        }
 
@@ -6570,15 +6726,15 @@ 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, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        int i;
        int ndrivers;
        uint32 version;
        fstring *list = NULL;
-
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
        DRIVER_INFO_1 *tdi1, *driver_info_1=NULL;
+       WERROR result = WERR_OK;
 
        *returned=0;
 
@@ -6591,7 +6747,7 @@ static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture
                        return WERR_NOMEM;
 
                if(ndrivers != 0) {
-                       if((tdi1=(DRIVER_INFO_1 *)Realloc(driver_info_1, (*returned+ndrivers) * sizeof(DRIVER_INFO_1))) == NULL) {
+                       if((tdi1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) {
                                DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
                                SAFE_FREE(driver_info_1);
                                SAFE_FREE(list);
@@ -6624,9 +6780,14 @@ static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture
                *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
        }
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(driver_info_1);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;    
+               goto out;
        }
 
        /* fill the buffer with the driver structures */
@@ -6635,29 +6796,28 @@ static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture
                smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
        }
 
+out:
        SAFE_FREE(driver_info_1);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
  Enumerates all printer drivers at level 2.
 ****************************************************************************/
 
-static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        int i;
        int ndrivers;
        uint32 version;
        fstring *list = NULL;
-
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
        DRIVER_INFO_2 *tdi2, *driver_info_2=NULL;
+       WERROR result = WERR_OK;
 
        *returned=0;
 
@@ -6670,7 +6830,7 @@ static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture
                        return WERR_NOMEM;
 
                if(ndrivers != 0) {
-                       if((tdi2=(DRIVER_INFO_2 *)Realloc(driver_info_2, (*returned+ndrivers) * sizeof(DRIVER_INFO_2))) == NULL) {
+                       if((tdi2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) {
                                DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
                                SAFE_FREE(driver_info_2);
                                SAFE_FREE(list);
@@ -6704,9 +6864,14 @@ static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture
                *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
        }
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(driver_info_2);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;    
+               goto out;
        }
 
        /* fill the buffer with the form structures */
@@ -6715,29 +6880,28 @@ static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture
                smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
        }
 
+out:
        SAFE_FREE(driver_info_2);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
  Enumerates all printer drivers at level 3.
 ****************************************************************************/
 
-static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        int i;
        int ndrivers;
        uint32 version;
        fstring *list = NULL;
-
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
        DRIVER_INFO_3 *tdi3, *driver_info_3=NULL;
+       WERROR result = WERR_OK;
 
        *returned=0;
 
@@ -6750,7 +6914,7 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture
                        return WERR_NOMEM;
 
                if(ndrivers != 0) {
-                       if((tdi3=(DRIVER_INFO_3 *)Realloc(driver_info_3, (*returned+ndrivers) * sizeof(DRIVER_INFO_3))) == NULL) {
+                       if((tdi3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) {
                                DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
                                SAFE_FREE(driver_info_3);
                                SAFE_FREE(list);
@@ -6784,28 +6948,32 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture
                *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
        }
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(driver_info_3);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;    
+               goto out;
        }
-       
+
        /* fill the buffer with the driver structures */
        for (i=0; i<*returned; i++) {
                DEBUGADD(6,("adding driver [%d] to buffer\n",i));
                smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
        }
 
+out:
        for (i=0; i<*returned; i++)
                SAFE_FREE(driver_info_3[i].dependentfiles);
-       
+
        SAFE_FREE(driver_info_3);
        
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
@@ -6814,27 +6982,32 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture
 
 WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
 {
-       UNISTR2 *environment = &q_u->environment;
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        uint32 *returned = &r_u->returned;
 
-       fstring *list = NULL;
        fstring servername;
        fstring architecture;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(4,("_spoolss_enumprinterdrivers\n"));
-       fstrcpy(servername, get_called_name());
-       *needed=0;
-       *returned=0;
+       
+       *needed   = 0;
+       *returned = 0;
+
+       unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture)-1);
+       unistr2_to_ascii(servername, &q_u->name, sizeof(servername)-1);
 
-       unistr2_to_ascii(architecture, environment, sizeof(architecture)-1);
+       if ( !is_myname_or_ipaddr( servername ) )
+               return WERR_UNKNOWN_PRINTER_DRIVER;
 
        switch (level) {
        case 1:
@@ -6844,8 +7017,6 @@ WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS
        case 3:
                return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned);
        default:
-               *returned=0;
-               SAFE_FREE(list);
                return WERR_UNKNOWN_LEVEL;
        }
 }
@@ -6871,7 +7042,7 @@ static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
 WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
 {
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        uint32 *numofforms = &r_u->numofforms;
@@ -6884,8 +7055,11 @@ WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
        int i;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(4,("_spoolss_enumforms\n"));
        DEBUGADD(5,("Offered buffer size [%d]\n", offered));
@@ -6897,11 +7071,12 @@ WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
        DEBUGADD(5,("Number of user forms [%d]\n",     *numofforms));
        *numofforms += numbuiltinforms;
 
-       if (*numofforms == 0) return WERR_NO_MORE_ITEMS;
+       if (*numofforms == 0) 
+               return WERR_NO_MORE_ITEMS;
 
        switch (level) {
        case 1:
-               if ((forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1))) == NULL) {
+               if ((forms_1=SMB_MALLOC_ARRAY(FORM_1, *numofforms)) == NULL) {
                        *numofforms=0;
                        return WERR_NOMEM;
                }
@@ -6933,10 +7108,17 @@ WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
 
                *needed=buffer_size;            
                
-               if (!alloc_buffer_size(buffer, buffer_size)){
+               if (*needed > offered) {
                        SAFE_FREE(forms_1);
+                       *numofforms=0;
                        return WERR_INSUFFICIENT_BUFFER;
                }
+       
+               if (!rpcbuf_alloc_size(buffer, buffer_size)){
+                       SAFE_FREE(forms_1);
+                       *numofforms=0;
+                       return WERR_NOMEM;
+               }
 
                /* fill the buffer with the form structures */
                for (i=0; i<numbuiltinforms; i++) {
@@ -6947,15 +7129,10 @@ WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
                        DEBUGADD(6,("adding form [%d] to buffer\n",i));
                        smb_io_form_1("", buffer, &forms_1[i], 0);
                }
-
-               SAFE_FREE(forms_1);
-
-               if (*needed > offered) {
-                       *numofforms=0;
-                       return WERR_INSUFFICIENT_BUFFER;
-               }
-               else
-                       return WERR_OK;
+
+               SAFE_FREE(forms_1);
+
+               return WERR_OK;
                        
        default:
                SAFE_FREE(list);
@@ -6972,7 +7149,7 @@ WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *
 {
        uint32 level = q_u->level;
        UNISTR2 *uni_formname = &q_u->formname;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
 
@@ -6985,8 +7162,11 @@ WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *
        int numofforms=0, i=0;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
 
@@ -7030,13 +7210,11 @@ WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *
 
                *needed=spoolss_size_form_1(&form_1);
                
-               if (!alloc_buffer_size(buffer, buffer_size)){
+               if (*needed > offered) 
                        return WERR_INSUFFICIENT_BUFFER;
-               }
 
-               if (*needed > offered) {
-                       return WERR_INSUFFICIENT_BUFFER;
-               }
+               if (!rpcbuf_alloc_size(buffer, buffer_size))
+                       return WERR_NOMEM;
 
                /* fill the buffer with the form structures */
                DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name, i));
@@ -7066,28 +7244,36 @@ static void fill_port_2(PORT_INFO_2 *port, const char *name)
        init_unistr(&port->port_name, name);
        init_unistr(&port->monitor_name, "Local Monitor");
        init_unistr(&port->description, "Local Port");
-#define PORT_TYPE_WRITE 1
        port->port_type=PORT_TYPE_WRITE;
        port->reserved=0x0;     
 }
 
+
 /****************************************************************************
- enumports level 1.
+ wrapper around the enumer ports command
 ****************************************************************************/
 
-static WERROR enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+WERROR enumports_hook( int *count, char ***lines )
 {
-       PORT_INFO_1 *ports=NULL;
-       int i=0;
+       char *cmd = lp_enumports_cmd();
+       char **qlines;
+       pstring command;
+       int numlines;
+       int ret;
+       int fd;
 
-       if (*lp_enumports_cmd()) {
-               char *cmd = lp_enumports_cmd();
-               char **qlines;
-               pstring command;
-               int numlines;
-               int ret;
-               int fd;
 
+       /* if no hook then just fill in the default port */
+       
+       if ( !*cmd ) {
+               qlines = SMB_MALLOC_ARRAY( char*, 2 );
+               qlines[0] = SMB_STRDUP( SAMBA_PRINTER_PORT_NAME );
+               qlines[1] = NULL;
+               numlines = 1;
+       }
+       else {
+               /* we have a valid enumport command */
+               
                slprintf(command, sizeof(command)-1, "%s \"%d\"", cmd, 1);
 
                DEBUG(10,("Running [%s]\n", command));
@@ -7096,7 +7282,7 @@ static WERROR enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
                if (ret != 0) {
                        if (fd != -1)
                                close(fd);
-                       /* Is this the best error to return here? */
+                       
                        return WERR_ACCESS_DENIED;
                }
 
@@ -7104,45 +7290,61 @@ static WERROR enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
                qlines = fd_lines_load(fd, &numlines);
                DEBUGADD(10,("Lines returned = [%d]\n", numlines));
                close(fd);
+       }
+       
+       *count = numlines;
+       *lines = qlines;
 
-               if(numlines) {
-                       if((ports=(PORT_INFO_1 *)malloc( numlines * sizeof(PORT_INFO_1) )) == NULL) {
-                               DEBUG(10,("Returning WERR_NOMEM [%s]\n", 
-                                         dos_errstr(WERR_NOMEM)));
-                               file_lines_free(qlines);
-                               return WERR_NOMEM;
-                       }
+       return WERR_OK;
+}
 
-                       for (i=0; i<numlines; i++) {
-                               DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
-                               fill_port_1(&ports[i], qlines[i]);
-                       }
+/****************************************************************************
+ enumports level 1.
+****************************************************************************/
+
+static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+{
+       PORT_INFO_1 *ports=NULL;
+       int i=0;
+       WERROR result = WERR_OK;
+       char **qlines;
+       int numlines;
 
+       if ( !W_ERROR_IS_OK(result = enumports_hook( &numlines, &qlines )) ) 
+               return result;
+       
+       if(numlines) {
+               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);
+                       return WERR_NOMEM;
                }
 
-               *returned = numlines;
-
-       } else {
-               *returned = 1; /* Sole Samba port returned. */
-
-               if((ports=(PORT_INFO_1 *)malloc( sizeof(PORT_INFO_1) )) == NULL)
-                       return WERR_NOMEM;
-       
-               DEBUG(10,("enumports_level_1: port name %s\n", SAMBA_PRINTER_PORT_NAME));
+               for (i=0; i<numlines; i++) {
+                       DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
+                       fill_port_1(&ports[i], qlines[i]);
+               }
 
-               fill_port_1(&ports[0], SAMBA_PRINTER_PORT_NAME);
+               file_lines_free(qlines);
        }
 
+       *returned = numlines;
+
        /* check the required size. */
        for (i=0; i<*returned; i++) {
                DEBUGADD(6,("adding port [%d]'s size\n", i));
                *needed += spoolss_size_port_info_1(&ports[i]);
        }
                
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(ports);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the ports structures */
@@ -7151,96 +7353,61 @@ static WERROR enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need
                smb_io_port_1("", buffer, &ports[i], 0);
        }
 
+out:
        SAFE_FREE(ports);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
  enumports level 2.
 ****************************************************************************/
 
-static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        PORT_INFO_2 *ports=NULL;
        int i=0;
+       WERROR result = WERR_OK;
+       char **qlines;
+       int numlines;
 
-       if (*lp_enumports_cmd()) {
-               char *cmd = lp_enumports_cmd();
-               char *path;
-               char **qlines;
-               pstring tmp_file;
-               pstring command;
-               int numlines;
-               int ret;
-               int fd;
-
-               if (*lp_pathname(lp_servicenumber(PRINTERS_NAME)))
-                       path = lp_pathname(lp_servicenumber(PRINTERS_NAME));
-               else
-                       path = lp_lockdir();
-
-               slprintf(tmp_file, sizeof(tmp_file)-1, "%s/smbcmd.%u.", path, (unsigned int)sys_getpid());
-               slprintf(command, sizeof(command)-1, "%s \"%d\"", cmd, 2);
-
-               unlink(tmp_file);
-               DEBUG(10,("Running [%s > %s]\n", command,tmp_file));
-               ret = smbrun(command, &fd);
-               DEBUGADD(10,("returned [%d]\n", ret));
-               if (ret != 0) {
-                       if (fd != -1)
-                               close(fd);
-                       /* Is this the best error to return here? */
-                       return WERR_ACCESS_DENIED;
-               }
-
-               numlines = 0;
-               qlines = fd_lines_load(fd, &numlines);
-               DEBUGADD(10,("Lines returned = [%d]\n", numlines));
-               close(fd);
-
-               if(numlines) {
-                       if((ports=(PORT_INFO_2 *)malloc( numlines * sizeof(PORT_INFO_2) )) == NULL) {
-                               file_lines_free(qlines);
-                               return WERR_NOMEM;
-                       }
-
-                       for (i=0; i<numlines; i++) {
-                               DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
-                               fill_port_2(&(ports[i]), qlines[i]);
-                       }
-
+       if ( !W_ERROR_IS_OK(result = enumports_hook( &numlines, &qlines )) ) 
+               return result;
+       
+       
+       if(numlines) {
+               if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) {
                        file_lines_free(qlines);
+                       return WERR_NOMEM;
                }
 
-               *returned = numlines;
-
-       } else {
-
-               *returned = 1;
-
-               if((ports=(PORT_INFO_2 *)malloc( sizeof(PORT_INFO_2) )) == NULL)
-                       return WERR_NOMEM;
-       
-               DEBUG(10,("enumports_level_2: port name %s\n", SAMBA_PRINTER_PORT_NAME));
+               for (i=0; i<numlines; i++) {
+                       DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
+                       fill_port_2(&(ports[i]), qlines[i]);
+               }
 
-               fill_port_2(&ports[0], SAMBA_PRINTER_PORT_NAME);
+               file_lines_free(qlines);
        }
 
+       *returned = numlines;
+
        /* check the required size. */
        for (i=0; i<*returned; i++) {
                DEBUGADD(6,("adding port [%d]'s size\n", i));
                *needed += spoolss_size_port_info_2(&ports[i]);
        }
                
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(ports);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        /* fill the buffer with the ports structures */
@@ -7249,14 +7416,13 @@ static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
                smb_io_port_2("", buffer, &ports[i], 0);
        }
 
+out:
        SAFE_FREE(ports);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
@@ -7266,14 +7432,17 @@ static WERROR enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need
 WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
 {
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        uint32 *returned = &r_u->returned;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(4,("_spoolss_enumports\n"));
        
@@ -7304,7 +7473,7 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
        int     snum;
        WERROR err = WERR_OK;
 
-       if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
+       if ((printer = SMB_MALLOC_P(NT_PRINTER_INFO_LEVEL)) == NULL) {
                DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
                return WERR_NOMEM;
        }
@@ -7330,13 +7499,16 @@ 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(printer) ) {
+               if ( !add_printer_hook(p->pipe_user.nt_user_token, printer) ) {
                        free_a_printer(&printer,2);
                        return WERR_ACCESS_DENIED;
        }
        }
 
-       slprintf(name, sizeof(name)-1, "\\\\%s\\%s", get_called_name(),
+       /* use our primary netbios name since get_a_printer() will convert 
+          it to what the client expects on a case by case basis */
+
+       slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
              printer->info_2->sharename);
 
        
@@ -7382,7 +7554,7 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
        }
 
        /* write the ASCII on disk */
-       err = mod_a_printer(*printer, 2);
+       err = mod_a_printer(printer, 2);
        if (!W_ERROR_IS_OK(err)) {
                free_a_printer(&printer,2);
                return err;
@@ -7406,7 +7578,7 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_
 
 WERROR _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_R_ADDPRINTEREX *r_u)
 {
-       UNISTR2 *uni_srv_name = &q_u->server_name;
+       UNISTR2 *uni_srv_name = q_u->server_name;
        uint32 level = q_u->level;
        SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
        DEVICEMODE *devmode = q_u->devmode_ctr.devmode;
@@ -7457,9 +7629,7 @@ WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u,
                goto done;
 
        DEBUG(5,("Moving driver to final destination\n"));
-       if(!move_driver_to_download_area(driver, level, &user, &err)) {
-               if (W_ERROR_IS_OK(err))
-                       err = WERR_ACCESS_DENIED;
+       if( !W_ERROR_IS_OK(err = move_driver_to_download_area(driver, level, &user, &err)) ) {
                goto done;
        }
 
@@ -7604,22 +7774,37 @@ static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+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; 
        const char *short_archi;
        DRIVER_DIRECTORY_1 *info=NULL;
+       WERROR result = WERR_OK;
 
+       unistr2_to_ascii(servername, name, sizeof(servername)-1);
        unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
 
+       /* check for beginning double '\'s and that the server
+          long enough */
+
+       pservername = servername;
+       if ( *pservername == '\\' && strlen(servername)>2 ) {
+               pservername += 2;
+       } 
+       
+       if ( !is_myname_or_ipaddr( pservername ) )
+               return WERR_INVALID_PARAM;
+
        if (!(short_archi = get_short_archi(long_archi)))
                return WERR_INVALID_ENVIRONMENT;
 
-       if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL)
+       if((info=SMB_MALLOC_P(DRIVER_DIRECTORY_1)) == NULL)
                return WERR_NOMEM;
 
-       slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", get_called_name(), short_archi);
+       slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", pservername, short_archi);
 
        DEBUG(4,("printer driver directory: [%s]\n", path));
 
@@ -7627,19 +7812,22 @@ static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen
        
        *needed += spoolss_size_driverdir_info_1(info);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(info);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        smb_io_driverdir_1("", buffer, info, 0);
 
+out:
        SAFE_FREE(info);
        
-       if (*needed > offered)
-               return WERR_INSUFFICIENT_BUFFER;
-
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
@@ -7650,13 +7838,16 @@ WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRI
        UNISTR2 *name = &q_u->name;
        UNISTR2 *uni_environment = &q_u->environment;
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
 
@@ -7689,7 +7880,6 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
 
        NT_PRINTER_INFO_LEVEL *printer = NULL;
        
-       uint32          param_index;
        uint32          biggest_valuesize;
        uint32          biggest_datasize;
        uint32          data_len;
@@ -7738,7 +7928,6 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
        {
                DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
 
-               param_index       = 0;
                biggest_valuesize = 0;
                biggest_datasize  = 0;
                                
@@ -7786,7 +7975,7 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
 
                *out_max_value_len=(in_value_len/sizeof(uint16));
                
-               if((*out_value=(uint16 *)talloc_zero(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
+               if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
                {
                        result = WERR_NOMEM;
                        goto done;
@@ -7801,7 +7990,7 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
                
                /* only allocate when given a non-zero data_len */
                
-               if ( in_data_len && ((*data_out=(uint8 *)talloc_zero(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
+               if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
                {
                        result = WERR_NOMEM;
                        goto done;
@@ -7822,7 +8011,7 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
        
                /* name */
                *out_max_value_len=(in_value_len/sizeof(uint16));
-               if ( (*out_value = (uint16 *)talloc_zero(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL ) 
+               if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL ) 
                {
                        result = WERR_NOMEM;
                        goto done;
@@ -7837,12 +8026,12 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
                /* data - counted in bytes */
 
                *out_max_data_len = in_data_len;
-               if ( (*data_out = (uint8 *)talloc_zero(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) 
+               if ( (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) 
                {
                        result = WERR_NOMEM;
                        goto done;
                }
-               data_len = (size_t)regval_size(val);
+               data_len = regval_size(val);
                memcpy( *data_out, regval_data_p(val), data_len );
                *out_data_len = data_len;
        }
@@ -7876,6 +8065,11 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
                return WERR_BADFID;
        }
 
+       if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER ) {
+               DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
+               return WERR_INVALID_PARAM;
+       }
+
        if (!get_printer_snum(p,handle, &snum))
                return WERR_BADFID;
 
@@ -7917,7 +8111,7 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
        status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename, 
                                        type, data, real_len );
                if ( W_ERROR_IS_OK(status) )
-                       status = mod_a_printer(*printer, 2);
+                       status = mod_a_printer(printer, 2);
        }
 
 done:
@@ -7993,6 +8187,9 @@ WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_
        unistr2_to_ascii( valuename, value, sizeof(valuename)-1 );
 
        status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename );
+       
+       if ( W_ERROR_IS_OK(status) )
+               mod_a_printer( printer, 2 );
 
        free_a_printer(&printer, 2);
 
@@ -8062,7 +8259,7 @@ WERROR _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM
         */
         
        if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTER )
-               status = mod_a_printer(*printer, 2);
+               status = mod_a_printer(printer, 2);
        
 done:
        if ( printer )
@@ -8129,7 +8326,7 @@ WERROR _spoolss_deleteform( pipes_struct *p, SPOOL_Q_DELETEFORM *q_u, SPOOL_R_DE
         */
         
        if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTER )
-               status = mod_a_printer(*printer, 2);
+               status = mod_a_printer(printer, 2);
        
 done:
        if ( printer )
@@ -8195,7 +8392,7 @@ WERROR _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM *
         */
         
        if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTER )
-               status = mod_a_printer(*printer, 2);
+               status = mod_a_printer(printer, 2);
        
        
 done:
@@ -8210,11 +8407,12 @@ done:
  enumprintprocessors level 1.
 ****************************************************************************/
 
-static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        PRINTPROCESSOR_1 *info_1=NULL;
+       WERROR result = WERR_OK;
        
-       if((info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1))) == NULL)
+       if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL)
                return WERR_NOMEM;
 
        (*returned) = 0x1;
@@ -8223,19 +8421,25 @@ static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, ui
 
        *needed += spoolss_size_printprocessor_info_1(info_1);
 
-       if (!alloc_buffer_size(buffer, *needed))
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
+       }
 
        smb_io_printprocessor_info_1("", buffer, info_1, 0);
 
+out:
        SAFE_FREE(info_1);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
@@ -8244,14 +8448,17 @@ static WERROR enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, ui
 WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
 {
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        uint32 *returned = &r_u->returned;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(5,("spoolss_enumprintprocessors\n"));
 
@@ -8277,11 +8484,12 @@ WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS
  enumprintprocdatatypes level 1.
 ****************************************************************************/
 
-static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        PRINTPROCDATATYPE_1 *info_1=NULL;
+       WERROR result = WERR_NOMEM;
        
-       if((info_1 = (PRINTPROCDATATYPE_1 *)malloc(sizeof(PRINTPROCDATATYPE_1))) == NULL)
+       if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
                return WERR_NOMEM;
 
        (*returned) = 0x1;
@@ -8290,19 +8498,25 @@ static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered,
 
        *needed += spoolss_size_printprocdatatype_info_1(info_1);
 
-       if (!alloc_buffer_size(buffer, *needed))
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
+       }
 
        smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
 
+out:
        SAFE_FREE(info_1);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
@@ -8311,14 +8525,17 @@ static WERROR enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered,
 WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
 {
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        uint32 *returned = &r_u->returned;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
        
@@ -8337,11 +8554,12 @@ WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDAT
  enumprintmonitors level 1.
 ****************************************************************************/
 
-static WERROR enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        PRINTMONITOR_1 *info_1=NULL;
+       WERROR result = WERR_OK;
        
-       if((info_1 = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1))) == NULL)
+       if((info_1 = SMB_MALLOC_P(PRINTMONITOR_1)) == NULL)
                return WERR_NOMEM;
 
        (*returned) = 0x1;
@@ -8350,30 +8568,37 @@ static WERROR enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint
 
        *needed += spoolss_size_printmonitor_info_1(info_1);
 
-       if (!alloc_buffer_size(buffer, *needed))
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
+       }
 
        smb_io_printmonitor_info_1("", buffer, info_1, 0);
 
+out:
        SAFE_FREE(info_1);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
 
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
  enumprintmonitors level 2.
 ****************************************************************************/
 
-static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
+static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        PRINTMONITOR_2 *info_2=NULL;
+       WERROR result = WERR_OK;
        
-       if((info_2 = (PRINTMONITOR_2 *)malloc(sizeof(PRINTMONITOR_2))) == NULL)
+       if((info_2 = SMB_MALLOC_P(PRINTMONITOR_2)) == NULL)
                return WERR_NOMEM;
 
        (*returned) = 0x1;
@@ -8384,19 +8609,25 @@ static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint
 
        *needed += spoolss_size_printmonitor_info_2(info_2);
 
-       if (!alloc_buffer_size(buffer, *needed))
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
+       }
 
        smb_io_printmonitor_info_2("", buffer, info_2, 0);
 
+out:
        SAFE_FREE(info_2);
 
-       if (*needed > offered) {
-               *returned=0;
-               return WERR_INSUFFICIENT_BUFFER;
-       }
-
-       return WERR_OK;
+       if ( !W_ERROR_IS_OK(result) )
+               *returned = 0;
+       
+       return result;
 }
 
 /****************************************************************************
@@ -8405,14 +8636,17 @@ static WERROR enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint
 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
 {
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        uint32 *returned = &r_u->returned;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(5,("spoolss_enumprintmonitors\n"));
 
@@ -8439,13 +8673,17 @@ WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
+                             NT_PRINTER_INFO_LEVEL *ntprinter,
+                             uint32 jobid, RPC_BUFFER *buffer, uint32 offered, 
+                            uint32 *needed)
 {
        int i=0;
        BOOL found=False;
        JOB_INFO_1 *info_1=NULL;
+       WERROR result = WERR_OK;
 
-       info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1));
+       info_1=SMB_MALLOC_P(JOB_INFO_1);
 
        if (info_1 == NULL) {
                return WERR_NOMEM;
@@ -8462,75 +8700,71 @@ static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum, ui
                return WERR_INVALID_PARAM;
        }
        
-       fill_job_info_1(info_1, &((*queue)[i-1]), i, snum);
+       fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
        
        *needed += spoolss_size_job_info_1(info_1);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               SAFE_FREE(info_1);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
+               goto out;
        }
 
        smb_io_job_info_1("", buffer, info_1, 0);
 
+out:
        SAFE_FREE(info_1);
 
-       if (*needed > offered)
-               return WERR_INSUFFICIENT_BUFFER;
-
-       return WERR_OK;
+       return result;
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum, 
+                             NT_PRINTER_INFO_LEVEL *ntprinter,
+                             uint32 jobid, RPC_BUFFER *buffer, uint32 offered, 
+                            uint32 *needed)
 {
        int             i = 0;
        BOOL            found = False;
        JOB_INFO_2      *info_2;
-       NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
-       WERROR          ret;
+       WERROR          result;
        DEVICEMODE      *devmode = NULL;
        NT_DEVICEMODE   *nt_devmode = NULL;
 
-       info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2));
+       if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
+               return WERR_NOMEM;
 
        ZERO_STRUCTP(info_2);
 
-       if (info_2 == NULL) {
-               ret = WERR_NOMEM;
-               goto done;
-       }
-
        for ( i=0; i<count && found==False; i++ ) 
        {
                if ((*queue)[i].job == (int)jobid)
                        found = True;
        }
        
-       if ( !found ) 
-       {
+       if ( !found ) {
                /* NT treats not found as bad param... yet another bad
                   choice */
-               ret = WERR_INVALID_PARAM;
+               result = WERR_INVALID_PARAM;
                goto done;
        }
        
-       ret = get_a_printer(NULL, &ntprinter, 2, lp_const_servicename(snum));
-       if (!W_ERROR_IS_OK(ret))
-               goto done;
-       
        /* 
         * if the print job does not have a DEVMODE associated with it, 
         * just use the one for the printer. A NULL devicemode is not
         *  a failure condition
         */
         
-       if ( !(nt_devmode=print_job_devmode( snum, jobid )) )
+       if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
                devmode = construct_dev_mode(snum);
        else {
-               if ((devmode = (DEVICEMODE *)malloc(sizeof(DEVICEMODE))) != NULL) {
+               if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
                        ZERO_STRUCTP( devmode );
                        convert_nt_devicemode( devmode, nt_devmode );
                }
@@ -8540,28 +8774,27 @@ static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum, ui
        
        *needed += spoolss_size_job_info_2(info_2);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               ret = WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
                goto done;
        }
 
-       smb_io_job_info_2("", buffer, info_2, 0);
-
-       if (*needed > offered) {
-               ret = WERR_INSUFFICIENT_BUFFER;
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_NOMEM;
                goto done;
        }
 
-       ret = WERR_OK;
+       smb_io_job_info_2("", buffer, info_2, 0);
+
+       result = WERR_OK;
        
  done:
        /* Cleanup allocated memory */
 
        free_job_info_2(info_2);        /* Also frees devmode */
        SAFE_FREE(info_2);
-       free_a_printer(&ntprinter, 2);
 
-       return ret;
+       return result;
 }
 
 /****************************************************************************
@@ -8572,19 +8805,22 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
        POLICY_HND *handle = &q_u->handle;
        uint32 jobid = q_u->jobid;
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        WERROR          wstatus = WERR_OK;
-
+       NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
        int snum;
        int count;
        print_queue_struct      *queue = NULL;
        print_status_struct prt_status;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(5,("spoolss_getjob\n"));
        
@@ -8593,6 +8829,10 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
        if (!get_printer_snum(p, handle, &snum))
                return WERR_BADFID;
        
+       wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
+       if ( !W_ERROR_IS_OK(wstatus) )
+               return wstatus;
+               
        count = print_queue_status(snum, &queue, &prt_status);
        
        DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
@@ -8600,11 +8840,11 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
                
        switch ( level ) {
        case 1:
-                       wstatus = getjob_level_1(&queue, count, snum, jobid, 
+                       wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid, 
                                buffer, offered, needed);
                        break;
        case 2:
-                       wstatus = getjob_level_2(&queue, count, snum, jobid, 
+                       wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid, 
                                buffer, offered, needed);
                        break;
        default:
@@ -8613,6 +8853,8 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
        }
        
        SAFE_FREE(queue);
+       free_a_printer( &ntprinter, 2 );
+       
        return wstatus;
 }
 
@@ -8662,7 +8904,7 @@ WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u,
        /* Is the handle to a printer or to the server? */
 
        if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) {
-               DEBUG(10,("_spoolss_getprinterdatex: Not implemented for server handles yet\n"));
+               DEBUG(10,("_spoolss_getprinterdataex: Not implemented for server handles yet\n"));
                status = WERR_INVALID_PARAM;
                goto done;
        }
@@ -8703,7 +8945,7 @@ done:
                
                if ( *out_size ) 
                {
-                       if( (*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL ) {
+                       if( (*data=(uint8 *)TALLOC_ZERO(p->mem_ctx, *out_size*sizeof(uint8))) == NULL ) {
                                status = WERR_NOMEM;
                                goto done;
                        }
@@ -8744,10 +8986,15 @@ WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u,
            SetPrinterData if key is "PrinterDriverData" */
 
        if (!Printer) {
-               DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
+               DEBUG(2,("_spoolss_setprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
                return WERR_BADFID;
        }
 
+       if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER ) {
+               DEBUG(10,("_spoolss_setprinterdataex: Not implemented for server handles yet\n"));
+               return WERR_INVALID_PARAM;
+       }
+
        if ( !get_printer_snum(p,handle, &snum) )
                return WERR_BADFID;
 
@@ -8788,21 +9035,21 @@ WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u,
        {
                /* save the OID if one was specified */
                if ( oid_string ) {
-               fstrcat( keyname, "\\" );
-               fstrcat( keyname, SPOOL_OID_KEY );
+                       fstrcat( keyname, "\\" );
+                       fstrcat( keyname, SPOOL_OID_KEY );
                
-               /* 
-                * I'm not checking the status here on purpose.  Don't know 
-                * if this is right, but I'm returning the status from the 
-                * previous set_printer_dataex() call.  I have no idea if 
-                * this is right.    --jerry
-                */
+                       /* 
+                        * I'm not checking the status here on purpose.  Don't know 
+                        * if this is right, but I'm returning the status from the 
+                        * previous set_printer_dataex() call.  I have no idea if 
+                        * this is right.    --jerry
+                        */
                 
-               set_printer_dataex( printer, keyname, valuename, 
-                                   REG_SZ, (void*)oid_string, strlen(oid_string)+1 );          
-       }
+                       set_printer_dataex( printer, keyname, valuename, 
+                                           REG_SZ, (void*)oid_string, strlen(oid_string)+1 );          
+               }
        
-               status = mod_a_printer(*printer, 2);
+               status = mod_a_printer(printer, 2);
        }
                
        free_a_printer(&printer, 2);
@@ -8851,6 +9098,9 @@ WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX
 
        status = delete_printer_dataex( printer, keyname, valuename );
 
+       if ( W_ERROR_IS_OK(status) )
+               mod_a_printer( printer, 2 );
+               
        free_a_printer(&printer, 2);
 
        return status;
@@ -8972,7 +9222,7 @@ WERROR _spoolss_deleteprinterkey(pipes_struct *p, SPOOL_Q_DELETEPRINTERKEY *q_u,
        status = delete_all_printer_data( printer->info_2, key );       
 
        if ( W_ERROR_IS_OK(status) )
-               status = mod_a_printer(*printer, 2);
+               status = mod_a_printer(printer, 2);
        
        free_a_printer( &printer, 2 );
        
@@ -9001,7 +9251,7 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
        int             i;
        REGISTRY_VALUE  *val;
        char            *value_name;
-       int             data_len;
+       uint32          data_len;
        
 
        DEBUG(4,("_spoolss_enumprinterdataex\n"));
@@ -9054,10 +9304,10 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
        num_entries = regval_ctr_numvals( &p_data->keys[key_index].values );
        if ( num_entries )
        {
-               if ( (enum_values=talloc(p->mem_ctx, num_entries*sizeof(PRINTER_ENUM_VALUES))) == NULL )
+               if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
                {
-                       DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%d] bytes!\n",
-                               num_entries*sizeof(PRINTER_ENUM_VALUES)));
+                       DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
+                               (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
                        result = WERR_NOMEM;
                        goto done;
                }
@@ -9086,7 +9336,7 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
                
                data_len = regval_size( val );
                if ( data_len ) {
-                       if ( !(enum_values[i].data = talloc_memdup(p->mem_ctx, regval_data_p(val), data_len)) ) 
+                       if ( !(enum_values[i].data = TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) ) 
                        {
                                DEBUG(0,("talloc_memdup failed to allocate memory [data_len=%d] for data!\n", 
                                        data_len ));
@@ -9136,21 +9386,21 @@ static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, cha
 
 static WERROR getprintprocessordirectory_level_1(UNISTR2 *name, 
                                                 UNISTR2 *environment, 
-                                                NEW_BUFFER *buffer, 
+                                                RPC_BUFFER *buffer, 
                                                 uint32 offered, 
                                                 uint32 *needed)
 {
        pstring path;
        pstring long_archi;
-        const char *short_archi;
        PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
+       WERROR result = WERR_OK;
 
        unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1);
 
-       if (!(short_archi = get_short_archi(long_archi)))
+       if (!get_short_archi(long_archi))
                return WERR_INVALID_ENVIRONMENT;
 
-       if((info=(PRINTPROCESSOR_DIRECTORY_1 *)malloc(sizeof(PRINTPROCESSOR_DIRECTORY_1))) == NULL)
+       if((info=SMB_MALLOC_P(PRINTPROCESSOR_DIRECTORY_1)) == NULL)
                return WERR_NOMEM;
 
        pstrcpy(path, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
@@ -9159,32 +9409,38 @@ static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
        
        *needed += spoolss_size_printprocessordirectory_info_1(info);
 
-       if (!alloc_buffer_size(buffer, *needed)) {
-               safe_free(info);
-               return WERR_INSUFFICIENT_BUFFER;
+       if (*needed > offered) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
+       }
+
+       if (!rpcbuf_alloc_size(buffer, *needed)) {
+               result = WERR_INSUFFICIENT_BUFFER;
+               goto out;
        }
 
        smb_io_printprocessordirectory_1("", buffer, info, 0);
 
-       safe_free(info);
+out:
+       SAFE_FREE(info);
        
-       if (*needed > offered)
-               return WERR_INSUFFICIENT_BUFFER;
-       else
-               return WERR_OK;
+       return result;
 }
 
 WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u)
 {
        uint32 level = q_u->level;
-       NEW_BUFFER *buffer = NULL;
+       RPC_BUFFER *buffer = NULL;
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        WERROR result;
 
        /* that's an [in out] buffer */
-       spoolss_move_buffer(q_u->buffer, &r_u->buffer);
-       buffer = r_u->buffer;
+
+       if ( q_u->buffer ) {
+               rpcbuf_move(q_u->buffer, &r_u->buffer);
+               buffer = r_u->buffer;
+       }
 
        DEBUG(5,("_spoolss_getprintprocessordirectory\n"));