r22542: Move over to using the _strict varients of the talloc
[samba.git] / source3 / rpc_server / srv_spoolss_nt.c
index af413b8b70f6eb7306cf8df4abdc02771d0e23a7..beb3b5aef0d2a5da7f7959d5c8b17ee1cdb09d7f 100644 (file)
@@ -40,23 +40,6 @@ extern userdom_struct current_user_info;
 #define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
 #define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
 
-
-/* Table to map the driver version */
-/* to OS */
-static const char * drv_ver_to_os[] = {
-       "WIN9X",   /* driver version/cversion 0 */
-       "",        /* unused ? */
-       "WINNT",   /* driver version/cversion 2 */
-       "WIN2K",   /* driver version/cversion 3 */
-};
-
-static const char *get_drv_ver_to_os(int ver)
-{
-       if (ver < 0 || ver > 3)
-               return "";
-       return drv_ver_to_os[ver];
-}
-
 struct table_node {
        const char    *long_archi;
        const char    *short_archi;
@@ -83,10 +66,6 @@ static uint32 smb_connections=0;
 
 extern STANDARD_MAPPING printer_std_mapping, printserver_std_mapping;
 
-#define OUR_HANDLE(hnd) (((hnd)==NULL)?"NULL":(IVAL((hnd)->data5,4)==(uint32)sys_getpid()?"OURS":"OTHER")), \
-((unsigned int)IVAL((hnd)->data5,4)),((unsigned int)sys_getpid())
-
-
 /* API table for Xcv Monitor functions */
 
 struct xcv_api_table {
@@ -348,7 +327,7 @@ WERROR delete_printer_hook( NT_USER_TOKEN *token, const char *sharename )
        /* go ahead and re-read the services immediately */
        reload_services( False );
        
-       if ( lp_servicenumber( sharename )  < 0 )
+       if ( share_defined( sharename ) )
                return WERR_ACCESS_DENIED;
                
        return WERR_OK;
@@ -394,7 +373,8 @@ static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
  Return the snum of a printer corresponding to an handle.
 ****************************************************************************/
 
-static BOOL get_printer_snum(pipes_struct *p, POLICY_HND *hnd, int *number)
+static BOOL get_printer_snum(pipes_struct *p, POLICY_HND *hnd, int *number,
+                            struct share_params **params)
 {
        Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
                
@@ -407,6 +387,13 @@ static BOOL get_printer_snum(pipes_struct *p, POLICY_HND *hnd, int *number)
                case SPLHND_PRINTER:            
                        DEBUG(4,("short name:%s\n", Printer->sharename));                       
                        *number = print_queue_snum(Printer->sharename);
+                       if ((*number != -1) && (params != NULL)) {
+                               *params = get_share_params(tmp_talloc_ctx(),
+                                                          Printer->sharename);
+                               if (*params == NULL) {
+                                       return False;
+                               }
+                       }
                        return (*number != -1);
                case SPLHND_SERVER:
                        return False;
@@ -458,7 +445,7 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
        const char *servername;
        fstring sname;
        BOOL found=False;
-       NT_PRINTER_INFO_LEVEL *printer;
+       NT_PRINTER_INFO_LEVEL *printer = NULL;
        WERROR result;
        
        DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename)));
@@ -549,6 +536,7 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
                printername++;
                
                if ( strequal(printername, aprinter) ) {
+                       free_a_printer( &printer, 2);
                        found = True;
                        break;
                }
@@ -558,6 +546,8 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
                free_a_printer( &printer, 2);
        }
 
+       free_a_printer( &printer, 2);
+
        if ( !found ) {
                DEBUGADD(4,("Printer not found\n"));
                return False;
@@ -723,14 +713,22 @@ static void notify_system_time(struct spoolss_notify_msg *msg,
 
        if (!make_systemtime(&systime, gmtime((time_t *)msg->notify.data))) {
                DEBUG(5, ("notify_system_time: unable to make systemtime\n"));
+               prs_mem_free(&ps);
                return;
        }
 
-       if (!spoolss_io_system_time("", &ps, 0, &systime))
+       if (!spoolss_io_system_time("", &ps, 0, &systime)) {
+               prs_mem_free(&ps);
                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 = (uint16 *)
+               TALLOC(mem_ctx, prs_offset(&ps));
+       if (!data->notify_data.data.string) {
+               prs_mem_free(&ps);
+               return;
+       }
 
        prs_copy_all_data_out((char *)data->notify_data.data.string, &ps);
 
@@ -918,7 +916,8 @@ 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 = (char *)
+                       TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
        
        return ctr->num_groups;
 }
@@ -977,6 +976,10 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
                /* allocate the max entries possible */
                
                data = TALLOC_ARRAY( mem_ctx, SPOOL_NOTIFY_INFO_DATA, msg_group->num_msgs);
+               if (!data) {
+                       return;
+               }
+
                ZERO_STRUCTP(data);
                
                /* build the array of change notifications */
@@ -1070,18 +1073,18 @@ static BOOL notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, voi
 
        /* Unpack message */
 
-       offset += tdb_unpack((char *)buf + offset, len - offset, "f",
+       offset += tdb_unpack((uint8 *)buf + offset, len - offset, "f",
                             msg->printer);
        
-       offset += tdb_unpack((char *)buf + offset, len - offset, "ddddddd",
+       offset += tdb_unpack((uint8 *)buf + offset, len - offset, "ddddddd",
                                &tv_sec, &tv_usec,
                                &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
 
        if (msg->len == 0)
-               tdb_unpack((char *)buf + offset, len - offset, "dd",
+               tdb_unpack((uint8 *)buf + offset, len - offset, "dd",
                           &msg->notify.value[0], &msg->notify.value[1]);
        else
-               tdb_unpack((char *)buf + offset, len - offset, "B", 
+               tdb_unpack((uint8 *)buf + offset, len - offset, "B", 
                           &msg->len, &msg->notify.data);
 
        DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
@@ -1094,7 +1097,7 @@ static BOOL notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, voi
                DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
                          msg->notify.value[1]));
        else
-               dump_data(3, msg->notify.data, msg->len);
+               dump_data(3, (uint8 *)msg->notify.data, msg->len);
 
        return True;
 }
@@ -1104,7 +1107,8 @@ static BOOL notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, voi
  ********************************************************************/
 
 static void receive_notify2_message_list(int msg_type, struct process_id src,
-                                        void *msg, size_t len)
+                                        void *msg, size_t len,
+                                        void *private_data)
 {
        size_t                  msg_count, i;
        char                    *buf = (char *)msg;
@@ -1216,14 +1220,15 @@ static BOOL srv_spoolss_drv_upgrade_printer(char* drivername)
  over all printers, upgrading ones as necessary 
  **********************************************************************/
  
-void do_drv_upgrade_printer(int msg_type, struct process_id src, void *buf, size_t len)
+void do_drv_upgrade_printer(int msg_type, struct process_id src,
+                           void *buf, size_t len, void *private_data)
 {
        fstring drivername;
        int snum;
        int n_services = lp_numservices();
        
        len = MIN(len,sizeof(drivername)-1);
-       strncpy(drivername, buf, len);
+       strncpy(drivername, (const char *)buf, len);
        
        DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername ));
 
@@ -1314,14 +1319,14 @@ static BOOL srv_spoolss_reset_printerdata(char* drivername)
  **********************************************************************/
  
 void reset_all_printerdata(int msg_type, struct process_id src,
-                          void *buf, size_t len)
+                          void *buf, size_t len, void *private_data)
 {
        fstring drivername;
        int snum;
        int n_services = lp_numservices();
        
        len = MIN( len, sizeof(drivername)-1 );
-       strncpy( drivername, buf, len );
+       strncpy( drivername, (const char *)buf, len );
        
        DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername ));
 
@@ -1384,7 +1389,7 @@ static DEVICEMODE* dup_devicemode(TALLOC_CTX *ctx, DEVICEMODE *devmode)
        
        /* bulk copy first */
        
-       d = TALLOC_MEMDUP(ctx, devmode, sizeof(DEVICEMODE));
+       d = (DEVICEMODE *)TALLOC_MEMDUP(ctx, devmode, sizeof(DEVICEMODE));
        if (!d)
                return NULL;
                
@@ -1393,6 +1398,9 @@ static DEVICEMODE* dup_devicemode(TALLOC_CTX *ctx, DEVICEMODE *devmode)
        len = unistrlen(devmode->devicename.buffer);
        if (len != -1) {
                d->devicename.buffer = TALLOC_ARRAY(ctx, uint16, len);
+               if (!d->devicename.buffer) {
+                       return NULL;
+               }
                if (unistrcpy(d->devicename.buffer, devmode->devicename.buffer) != len)
                        return NULL;
        }
@@ -1401,12 +1409,18 @@ static DEVICEMODE* dup_devicemode(TALLOC_CTX *ctx, DEVICEMODE *devmode)
        len = unistrlen(devmode->formname.buffer);
        if (len != -1) {
                d->devicename.buffer = TALLOC_ARRAY(ctx, uint16, len);
+               if (!d->devicename.buffer) {
+                       return NULL;
+               }
                if (unistrcpy(d->formname.buffer, devmode->formname.buffer) != len)
                        return NULL;
        }
 
-       d->dev_private = TALLOC_MEMDUP(ctx, devmode->dev_private, devmode->driverextra);
-       
+       d->dev_private = (uint8 *)TALLOC_MEMDUP(ctx, devmode->dev_private,
+                                               devmode->driverextra);
+       if (!d->dev_private) {
+               return NULL;
+       }       
        return d;
 }
 
@@ -1507,7 +1521,6 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
 
        fstring name;
        int snum;
-       struct current_user user;
        Printer_entry *Printer=NULL;
 
        if ( !q_u->printername )
@@ -1531,8 +1544,6 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
                return WERR_INVALID_PRINTER_NAME;
        }
 
-       get_current_user(&user, p);
-
        /*
         * First case: the user is opening the print server:
         *
@@ -1597,12 +1608,12 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
                        /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
                           and not a printer admin, then fail */
                        
-                       if ((user.ut.uid != 0) &&
-                           !user_has_privileges(user.nt_user_token,
+                       if ((p->pipe_user.ut.uid != 0) &&
+                           !user_has_privileges(p->pipe_user.nt_user_token,
                                                 &se_printop ) &&
                            !token_contains_name_in_list(
-                                   uidtoname(user.ut.uid), NULL,
-                                   user.nt_user_token,
+                                   uidtoname(p->pipe_user.ut.uid), NULL,
+                                   p->pipe_user.nt_user_token,
                                    lp_printer_admin(snum))) {
                                close_printer_handle(p, handle);
                                return WERR_ACCESS_DENIED;
@@ -1625,7 +1636,7 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
                /* NT doesn't let us connect to a printer if the connecting user
                   doesn't have print permission.  */
 
-               if (!get_printer_snum(p, handle, &snum)) {
+               if (!get_printer_snum(p, handle, &snum, NULL)) {
                        close_printer_handle(p, handle);
                        return WERR_BADFID;
                }
@@ -1655,9 +1666,9 @@ WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u,
                        return WERR_ACCESS_DENIED;
                }
 
-               if (!user_ok_token(uidtoname(user.ut.uid), user.nt_user_token,
-                                  snum) ||
-                   !print_access_check(&user, snum,
+               if (!user_ok_token(uidtoname(p->pipe_user.ut.uid),
+                                  p->pipe_user.nt_user_token, snum) ||
+                   !print_access_check(&p->pipe_user, snum,
                                        printer_default->access_required)) {
                        DEBUG(3, ("access DENIED for printer open\n"));
                        close_printer_handle(p, handle);
@@ -1852,7 +1863,7 @@ static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handl
                return WERR_BADFID;
        }
        
-       if (!get_printer_snum(p, handle, &snum))
+       if (!get_printer_snum(p, handle, &snum, NULL))
                return WERR_BADFID;
 
        Printer->document_started=False;
@@ -1951,20 +1962,17 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
        NT_PRINTER_DRIVER_INFO_LEVEL    info;
        NT_PRINTER_DRIVER_INFO_LEVEL    info_win2k;
        int                             version;
-       struct current_user             user;
        WERROR                          status;
        WERROR                          status_win2k = WERR_ACCESS_DENIED;
        SE_PRIV                         se_printop = SE_PRINT_OPERATOR; 
        
-       get_current_user(&user, p);
-        
        /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
           and not a printer admin, then fail */
                        
-       if ( (user.ut.uid != 0) 
-               && !user_has_privileges(user.nt_user_token, &se_printop ) 
-               && !token_contains_name_in_list( uidtoname(user.ut.uid), 
-                   NULL, user.nt_user_token, lp_printer_admin(-1)) ) 
+       if ( (p->pipe_user.ut.uid != 0) 
+               && !user_has_privileges(p->pipe_user.nt_user_token, &se_printop ) 
+               && !token_contains_name_in_list( uidtoname(p->pipe_user.ut.uid), 
+                   NULL, p->pipe_user.nt_user_token, lp_printer_admin(-1)) ) 
        {
                return WERR_ACCESS_DENIED;
        }
@@ -2011,7 +2019,7 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
                        /* if we get to here, we now have 2 driver info structures to remove */
                        /* remove the Win2k driver first*/
                
-                       status_win2k = delete_printer_driver(info_win2k.info_3, &user, 3, False );
+                       status_win2k = delete_printer_driver(info_win2k.info_3, &p->pipe_user, 3, False );
                        free_a_printer_driver( info_win2k, 3 );
                
                        /* this should not have failed---if it did, report to client */
@@ -2023,7 +2031,7 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
                }
        }
        
-       status = delete_printer_driver(info.info_3, &user, version, False);
+       status = delete_printer_driver(info.info_3, &p->pipe_user, version, False);
        
        /* if at least one of the deletes succeeded return OK */
        
@@ -2049,20 +2057,17 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV
        int                             version;
        uint32                          flags = q_u->delete_flags;
        BOOL                            delete_files;
-       struct current_user             user;
        WERROR                          status;
        WERROR                          status_win2k = WERR_ACCESS_DENIED;
        SE_PRIV                         se_printop = SE_PRINT_OPERATOR; 
        
-       get_current_user(&user, p);
-       
        /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
           and not a printer admin, then fail */
                        
-       if ( (user.ut.uid != 0) 
-               && !user_has_privileges(user.nt_user_token, &se_printop ) 
-               && !token_contains_name_in_list( uidtoname(user.ut.uid), 
-                   NULL, user.nt_user_token, lp_printer_admin(-1)) ) 
+       if ( (p->pipe_user.ut.uid != 0) 
+               && !user_has_privileges(p->pipe_user.nt_user_token, &se_printop ) 
+               && !token_contains_name_in_list( uidtoname(p->pipe_user.ut.uid), 
+                   NULL, p->pipe_user.nt_user_token, lp_printer_admin(-1)) ) 
        {
                return WERR_ACCESS_DENIED;
        }
@@ -2148,7 +2153,7 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV
                        /* if we get to here, we now have 2 driver info structures to remove */
                        /* remove the Win2k driver first*/
                
-                       status_win2k = delete_printer_driver(info_win2k.info_3, &user, 3, delete_files);
+                       status_win2k = delete_printer_driver(info_win2k.info_3, &p->pipe_user, 3, delete_files);
                        free_a_printer_driver( info_win2k, 3 );
                                
                        /* this should not have failed---if it did, report to client */
@@ -2158,7 +2163,7 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV
                }
        }
 
-       status = delete_printer_driver(info.info_3, &user, version, delete_files);
+       status = delete_printer_driver(info.info_3, &p->pipe_user, version, delete_files);
 
        if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
                status = WERR_OK;
@@ -2450,7 +2455,7 @@ WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO
                status = getprinterdata_printer_server( p->mem_ctx, value, type, data, needed, *out_size );
        else
        {
-               if ( !get_printer_snum(p,handle, &snum) ) {
+               if ( !get_printer_snum(p,handle, &snum, NULL) ) {
                        status = WERR_BADFID;
                        goto done;
                }
@@ -2594,7 +2599,8 @@ static BOOL srv_spoolss_replyopenprinter(int snum, const char *printer,
                if ( !spoolss_connect_to_client( &notify_cli_pipe, client_ip, unix_printer ))
                        return False;
                        
-               message_register(MSG_PRINTER_NOTIFY2, receive_notify2_message_list);
+               message_register(MSG_PRINTER_NOTIFY2,
+                                receive_notify2_message_list, NULL);
                /* Tell the connections db we're now interested in printer
                 * notify messages. */
                register_message_flags( True, FLAG_MSG_PRINT_NOTIFY );
@@ -2668,7 +2674,7 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE
        if ( Printer->printer_type == SPLHND_SERVER)
                snum = -1;
        else if ( (Printer->printer_type == SPLHND_PRINTER) &&
-                       !get_printer_snum(p, handle, &snum) )
+                       !get_printer_snum(p, handle, &snum, NULL) )
                return WERR_BADFID;
                
        client_ip.s_addr = inet_addr(p->conn->client_address);
@@ -2892,6 +2898,9 @@ static void spoolss_notify_devmode(int snum,
                                   NT_PRINTER_INFO_LEVEL *printer,
                                   TALLOC_CTX *mem_ctx)
 {
+       /* for a dummy implementation we have to zero the fields */
+       data->notify_data.data.length = 0;
+       data->notify_data.data.string = NULL;
 }
 
 /*******************************************************************
@@ -3013,8 +3022,8 @@ static void spoolss_notify_security_desc(int snum,
                                         NT_PRINTER_INFO_LEVEL *printer,
                                         TALLOC_CTX *mem_ctx)
 {
-       data->notify_data.sd.size = printer->info_2->secdesc_buf->len;
-       data->notify_data.sd.desc = dup_sec_desc( mem_ctx, printer->info_2->secdesc_buf->sec ) ;
+       data->notify_data.sd.size = printer->info_2->secdesc_buf->sd_size;
+       data->notify_data.sd.desc = dup_sec_desc( mem_ctx, printer->info_2->secdesc_buf->sd ) ;
 }
 
 /*******************************************************************
@@ -3441,25 +3450,22 @@ static uint32 size_of_notify_info_data(uint16 type, uint16 field)
 {
        int i=0;
 
-       for (i = 0; i < sizeof(notify_info_data_table); i++) 
-       {
+       for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) {
                if ( (notify_info_data_table[i].type == type)
-                       && (notify_info_data_table[i].field == field) ) 
-               {
-                       switch(notify_info_data_table[i].size) 
-                       {
-                       case NOTIFY_ONE_VALUE:
-                       case NOTIFY_TWO_VALUE:
-                               return 1;
-                       case NOTIFY_STRING:
-                               return 2;
-
-                       /* The only pointer notify data I have seen on
-                          the wire is the submitted time and this has
-                          the notify size set to 4. -tpot */
-
-                       case NOTIFY_POINTER:
-                               return 4;
+                       && (notify_info_data_table[i].field == field) ) {
+                       switch(notify_info_data_table[i].size) {
+                               case NOTIFY_ONE_VALUE:
+                               case NOTIFY_TWO_VALUE:
+                                       return 1;
+                               case NOTIFY_STRING:
+                                       return 2;
+
+                               /* The only pointer notify data I have seen on
+                                  the wire is the submitted time and this has
+                                  the notify size set to 4. -tpot */
+
+                               case NOTIFY_POINTER:
+                                       return 4;
                                        
                                case NOTIFY_SECDESC:
                                        return 5;
@@ -3476,23 +3482,23 @@ static uint32 size_of_notify_info_data(uint16 type, uint16 field)
  Return the type of notify_info_data.
 ********************************************************************/
 
-static int type_of_notify_info_data(uint16 type, uint16 field)
+static uint32 type_of_notify_info_data(uint16 type, uint16 field)
 {
-       int i=0;
+       uint32 i=0;
 
-       for (i = 0; i < sizeof(notify_info_data_table); i++) {
+       for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) {
                if (notify_info_data_table[i].type == type &&
                    notify_info_data_table[i].field == field)
                        return notify_info_data_table[i].size;
        }
 
-       return False;
+       return 0;
 }
 
 /****************************************************************************
 ****************************************************************************/
 
-static int search_notify(uint16 type, uint16 field, int *value)
+static BOOL search_notify(uint16 type, uint16 field, int *value)
 {      
        int i;
 
@@ -3521,10 +3527,8 @@ void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16
        info_data->enc_type = type_of_notify_info_data(type, field);
 
        info_data->id = id;
-
 }
 
-
 /*******************************************************************
  *
  * fill a notify_info struct with info asked
@@ -3563,6 +3567,7 @@ static BOOL construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY
 
                if((info->data=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"));
+                       free_a_printer(&printer, 2);
                        return False;
                }
 
@@ -3757,7 +3762,7 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY
        if ( !option )
                return WERR_BADFID;
 
-       get_printer_snum(p, hnd, &snum);
+       get_printer_snum(p, hnd, &snum, NULL);
 
        for (i=0; i<option->count; i++) {
                option_type=&option->ctr.type[i];
@@ -3875,7 +3880,9 @@ done:
  * fill a printer_info_0 struct
  ********************************************************************/
 
-static BOOL construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum)
+static BOOL construct_printer_info_0(Printer_entry *print_hnd,
+                                    PRINTER_INFO_0 *printer,
+                                    const struct share_params *params)
 {
        pstring chaine;
        int count;
@@ -3886,14 +3893,15 @@ static BOOL construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *p
        time_t setuptime;
        print_status_struct status;
        
-       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
+       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
+                                        lp_const_servicename(params->service))))
                return False;
 
-       count = print_queue_length(snum, &status);
+       count = print_queue_length(params->service, &status);
 
        /* check if we already have a counter for this printer */       
        for(session_counter = counter_list; session_counter; session_counter = session_counter->next) {
-               if (session_counter->snum == snum)
+               if (session_counter->snum == params->service)
                        break;
        }
 
@@ -3904,7 +3912,7 @@ static BOOL construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *p
                        return False;
                }
                ZERO_STRUCTP(session_counter);
-               session_counter->snum=snum;
+               session_counter->snum=params->service;
                session_counter->counter=0;
                DLIST_ADD(counter_list, session_counter);
        }
@@ -3980,21 +3988,25 @@ static BOOL construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *p
  * construct_printer_info_1
  * fill a printer_info_1 struct
  ********************************************************************/
-static BOOL construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum)
+static BOOL construct_printer_info_1(Printer_entry *print_hnd, uint32 flags,
+                                    PRINTER_INFO_1 *printer,
+                                    const struct share_params *params)
 {
        pstring chaine;
        pstring chaine2;
        NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
 
-       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
+       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
+                                        lp_const_servicename(params->service))))
                return False;
 
        printer->flags=flags;
 
        if (*ntprinter->info_2->comment == '\0') {
-               init_unistr(&printer->comment, lp_comment(snum));
+               init_unistr(&printer->comment, lp_comment(params->service));
                slprintf(chaine,sizeof(chaine)-1,"%s,%s,%s", ntprinter->info_2->printername,
-                       ntprinter->info_2->drivername, lp_comment(snum));
+                       ntprinter->info_2->drivername,
+                        lp_comment(params->service));
        }
        else {
                init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
@@ -4076,7 +4088,7 @@ static BOOL convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode
  Create a DEVMODE struct. Returns malloced memory.
 ****************************************************************************/
 
-DEVICEMODE *construct_dev_mode(int snum)
+DEVICEMODE *construct_dev_mode(const char *servicename)
 {
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
        DEVICEMODE              *devmode = NULL;
@@ -4085,7 +4097,7 @@ DEVICEMODE *construct_dev_mode(int snum)
        
        DEBUGADD(8,("getting printer characteristics\n"));
 
-       if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum)))) 
+       if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
                return NULL;
 
        if ( !printer->info_2->devmode ) {
@@ -4118,26 +4130,29 @@ done:
  * fill a printer_info_2 struct
  ********************************************************************/
 
-static BOOL construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum)
+static BOOL construct_printer_info_2(Printer_entry *print_hnd,
+                                    PRINTER_INFO_2 *printer,
+                                    const struct share_params *params)
 {
        int count;
        NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
 
        print_status_struct status;
 
-       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
+       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
+                                        lp_const_servicename(params->service))))
                return False;
                
-       count = print_queue_length(snum, &status);
+       count = print_queue_length(params->service, &status);
 
        init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
        init_unistr(&printer->printername, ntprinter->info_2->printername);                             /* printername*/
-       init_unistr(&printer->sharename, lp_servicename(snum));                 /* sharename */
+       init_unistr(&printer->sharename, lp_servicename(params->service));                      /* sharename */
        init_unistr(&printer->portname, ntprinter->info_2->portname);                   /* port */      
        init_unistr(&printer->drivername, ntprinter->info_2->drivername);       /* drivername */
 
        if (*ntprinter->info_2->comment == '\0')
-               init_unistr(&printer->comment, lp_comment(snum));                       /* comment */   
+               init_unistr(&printer->comment, lp_comment(params->service));                    /* comment */   
        else
                init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
 
@@ -4157,19 +4172,20 @@ static BOOL construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *p
        printer->cjobs = count;                                                 /* jobs */
        printer->averageppm = ntprinter->info_2->averageppm;                    /* average pages per minute */
                        
-       if ( !(printer->devmode = construct_dev_mode(snum)) )
+       if ( !(printer->devmode = construct_dev_mode(
+                      lp_const_servicename(params->service))) )
                DEBUG(8, ("Returning NULL Devicemode!\n"));
 
        printer->secdesc = NULL;
 
        if ( ntprinter->info_2->secdesc_buf 
-               && ntprinter->info_2->secdesc_buf->len != 0 ) 
+               && ntprinter->info_2->secdesc_buf->sd_size != 0 ) 
        {
                /* don't use talloc_steal() here unless you do a deep steal of all 
                   the SEC_DESC members */
 
                printer->secdesc = dup_sec_desc( get_talloc_ctx(), 
-                       ntprinter->info_2->secdesc_buf->sec );
+                       ntprinter->info_2->secdesc_buf->sd );
        }
 
        free_a_printer(&ntprinter, 2);
@@ -4182,17 +4198,21 @@ static BOOL construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *p
  * fill a printer_info_3 struct
  ********************************************************************/
 
-static BOOL construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum)
+static BOOL construct_printer_info_3(Printer_entry *print_hnd,
+                                    PRINTER_INFO_3 **pp_printer,
+                                    const struct share_params *params)
 {
        NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
        PRINTER_INFO_3 *printer = NULL;
 
-       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
+       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
+                                        lp_const_servicename(params->service))))
                return False;
 
        *pp_printer = NULL;
        if ((printer = SMB_MALLOC_P(PRINTER_INFO_3)) == NULL) {
                DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
+               free_a_printer(&ntprinter, 2);
                return False;
        }
 
@@ -4200,14 +4220,12 @@ static BOOL construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **
        
        /* These are the components of the SD we are returning. */
 
-       printer->flags = 0x4; 
-
-       if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) {
+       if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
                /* don't use talloc_steal() here unless you do a deep steal of all 
                   the SEC_DESC members */
 
                printer->secdesc = dup_sec_desc( get_talloc_ctx(), 
-                       ntprinter->info_2->secdesc_buf->sec );
+                       ntprinter->info_2->secdesc_buf->sd );
        }
 
        free_a_printer(&ntprinter, 2);
@@ -4221,11 +4239,14 @@ static BOOL construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **
  * fill a printer_info_4 struct
  ********************************************************************/
 
-static BOOL construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum)
+static BOOL construct_printer_info_4(Printer_entry *print_hnd,
+                                    PRINTER_INFO_4 *printer,
+                                    const struct share_params *params)
 {
        NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
 
-       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
+       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
+                                        lp_const_servicename(params->service))))
                return False;
                
        init_unistr(&printer->printername, ntprinter->info_2->printername);                             /* printername*/
@@ -4241,11 +4262,14 @@ static BOOL construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *p
  * fill a printer_info_5 struct
  ********************************************************************/
 
-static BOOL construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum)
+static BOOL construct_printer_info_5(Printer_entry *print_hnd,
+                                    PRINTER_INFO_5 *printer,
+                                    const struct share_params *params)
 {
        NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
 
-       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
+       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
+                                        lp_const_servicename(params->service))))
                return False;
                
        init_unistr(&printer->printername, ntprinter->info_2->printername);
@@ -4262,17 +4286,45 @@ static BOOL construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *p
        return True;
 }
 
+/********************************************************************
+ * construct_printer_info_6
+ * fill a printer_info_6 struct
+ ********************************************************************/
+
+static BOOL construct_printer_info_6(Printer_entry *print_hnd,
+                                    PRINTER_INFO_6 *printer,
+                                    const struct share_params *params)
+{
+       NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
+       int count;
+       print_status_struct status;
+
+       if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
+                                        lp_const_servicename(params->service))))
+               return False;
+
+       count = print_queue_length(params->service, &status);
+
+       printer->status = nt_printq_status(status.status);
+               
+       free_a_printer(&ntprinter, 2);
+
+       return True;
+}
+
 /********************************************************************
  * construct_printer_info_7
  * fill a printer_info_7 struct
  ********************************************************************/
 
-static BOOL construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
+static BOOL construct_printer_info_7(Printer_entry *print_hnd,
+                                    PRINTER_INFO_7 *printer,
+                                    const struct share_params *params)
 {
        char *guid_str = NULL;
-       struct uuid guid; 
+       struct GUID guid; 
        
-       if (is_printer_published(print_hnd, snum, &guid)) {
+       if (is_printer_published(print_hnd, params->service, &guid)) {
                asprintf(&guid_str, "{%s}", smb_uuid_string_static(guid));
                strupper_m(guid_str);
                init_unistr(&printer->guid, guid_str);
@@ -4291,31 +4343,45 @@ static BOOL construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *p
 
 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();
+       struct share_iterator *shares;
+       struct share_params *printer;
        PRINTER_INFO_1 *printers=NULL;
-       PRINTER_INFO_1 current_prt;
        WERROR result = WERR_OK;
        
        DEBUG(4,("enum_all_printers_info_1\n"));        
 
-       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 (!(shares = share_list_all(NULL))) {
+               DEBUG(5, ("Could not list printers\n"));
+               return WERR_ACCESS_DENIED;
+       }
 
-                       if (construct_printer_info_1(NULL, flags, &current_prt, snum)) {
-                               if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) {
-                                       DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
-                                       *returned=0;
-                                       return WERR_NOMEM;
-                               }
-                               DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));             
+       while ((printer = next_printer(shares)) != NULL) {
+               PRINTER_INFO_1 current_prt;
 
-                               memcpy(&printers[*returned], &current_prt, sizeof(PRINTER_INFO_1));
-                               (*returned)++;
-                       }
+               DEBUG(4,("Found a printer in smb.conf: %s\n",
+                        lp_servicename(printer->service)));
+
+               if (!construct_printer_info_1(NULL, flags, &current_prt,
+                                             printer)) {
+                       continue;
+               }
+
+               if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1,
+                                              *returned +1)) == NULL) {
+                       DEBUG(2,("enum_all_printers_info_1: failed to enlarge "
+                                "printers buffer!\n"));
+                       *returned=0;
+                       TALLOC_FREE(shares);
+                       return WERR_NOMEM;
                }
+               DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n",
+                        *returned));
+
+               memcpy(&printers[*returned], &current_prt,
+                      sizeof(PRINTER_INFO_1));
+               (*returned)++;
+               TALLOC_FREE(printer);
        }
                
        /* check the required size. */  
@@ -4340,6 +4406,7 @@ out:
        /* clear memory */
 
        SAFE_FREE(printers);
+       TALLOC_FREE(shares);
 
        if ( !W_ERROR_IS_OK(result) )
                *returned = 0;
@@ -4477,33 +4544,45 @@ static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer,
 
 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();
+       struct share_iterator *shares;
+       struct share_params *printer;
        PRINTER_INFO_2 *printers=NULL;
-       PRINTER_INFO_2 current_prt;
        WERROR result = WERR_OK;
 
        *returned = 0;
 
-       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 ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) {
-                                       DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
-                                       *returned = 0;
-                                       return WERR_NOMEM;
-                               }
+       if (!(shares = share_list_all(NULL))) {
+               DEBUG(5, ("Could not list printers\n"));
+               return WERR_ACCESS_DENIED;
+       }
 
-                               DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1));         
+       while ((printer = next_printer(shares)) != NULL) {
+               PRINTER_INFO_2 current_prt;
 
-                               memcpy(&printers[*returned], &current_prt, sizeof(PRINTER_INFO_2));
+               DEBUG(4,("Found a printer in smb.conf: %s\n",
+                        lp_servicename(printer->service)));
 
-                               (*returned)++;
-                       }
+               if (!construct_printer_info_2(NULL, &current_prt,
+                                             printer)) {
+                       continue;
                }
+               if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2,
+                                                 *returned +1)) ) {
+                       DEBUG(2,("enum_all_printers_info_2: failed to enlarge "
+                                "printers buffer!\n"));
+                       *returned = 0;
+                       TALLOC_FREE(shares);
+                       return WERR_NOMEM;
+               }
+
+               DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n",
+                        *returned + 1));
+
+               memcpy(&printers[*returned], &current_prt,
+                      sizeof(PRINTER_INFO_2));
+               (*returned)++;
+               TALLOC_FREE(printer);
        }
        
        /* check the required size. */  
@@ -4531,6 +4610,7 @@ out:
                free_devmode(printers[i].devmode);
 
        SAFE_FREE(printers);
+       TALLOC_FREE(shares);
 
        if ( !W_ERROR_IS_OK(result) )
                *returned = 0;
@@ -4626,7 +4706,7 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_
        
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer) {
+       if (!q_u->buffer && (offered!=0)) {
                return WERR_INVALID_PARAM;
        }
 
@@ -4671,7 +4751,10 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_0(Printer_entry *print_hnd,
+                                const struct share_params *params,
+                                RPC_BUFFER *buffer, uint32 offered,
+                                uint32 *needed)
 {
        PRINTER_INFO_0 *printer=NULL;
        WERROR result = WERR_OK;
@@ -4679,7 +4762,7 @@ static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER
        if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
                return WERR_NOMEM;
 
-       construct_printer_info_0(print_hnd, printer, snum);
+       construct_printer_info_0(print_hnd, printer, params);
        
        /* check the required size. */  
        *needed += spoolss_size_printer_info_0(printer);
@@ -4708,7 +4791,10 @@ out:
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_1(Printer_entry *print_hnd,
+                                const struct share_params *params,
+                                RPC_BUFFER *buffer, uint32 offered,
+                                uint32 *needed)
 {
        PRINTER_INFO_1 *printer=NULL;
        WERROR result = WERR_OK;
@@ -4716,7 +4802,8 @@ static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER
        if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
                return WERR_NOMEM;
 
-       construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
+       construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer,
+                                params);
        
        /* check the required size. */  
        *needed += spoolss_size_printer_info_1(printer);
@@ -4744,7 +4831,10 @@ out:
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_2(Printer_entry *print_hnd,
+                                const struct share_params *params,
+                                RPC_BUFFER *buffer, uint32 offered,
+                                uint32 *needed)
 {
        PRINTER_INFO_2 *printer=NULL;
        WERROR result = WERR_OK;
@@ -4752,7 +4842,7 @@ static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER
        if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
                return WERR_NOMEM;
        
-       construct_printer_info_2(print_hnd, printer, snum);
+       construct_printer_info_2(print_hnd, printer, params);
        
        /* check the required size. */  
        *needed += spoolss_size_printer_info_2(printer);
@@ -4781,12 +4871,15 @@ out:
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_3(Printer_entry *print_hnd,
+                                const struct share_params *params,
+                                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))
+       if (!construct_printer_info_3(print_hnd, &printer, params))
                return WERR_NOMEM;
        
        /* check the required size. */  
@@ -4815,7 +4908,10 @@ out:
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_4(Printer_entry *print_hnd,
+                                const struct share_params *params,
+                                RPC_BUFFER *buffer, uint32 offered,
+                                uint32 *needed)
 {
        PRINTER_INFO_4 *printer=NULL;
        WERROR result = WERR_OK;
@@ -4823,8 +4919,10 @@ static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER
        if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
                return WERR_NOMEM;
 
-       if (!construct_printer_info_4(print_hnd, printer, snum))
+       if (!construct_printer_info_4(print_hnd, printer, params)) {
+               SAFE_FREE(printer);
                return WERR_NOMEM;
+       }
        
        /* check the required size. */  
        *needed += spoolss_size_printer_info_4(printer);
@@ -4852,7 +4950,10 @@ out:
 /****************************************************************************
 ****************************************************************************/
 
-static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_5(Printer_entry *print_hnd,
+                                const struct share_params *params,
+                                RPC_BUFFER *buffer, uint32 offered,
+                                uint32 *needed)
 {
        PRINTER_INFO_5 *printer=NULL;
        WERROR result = WERR_OK;
@@ -4860,8 +4961,10 @@ static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER
        if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
                return WERR_NOMEM;
 
-       if (!construct_printer_info_5(print_hnd, printer, snum))
+       if (!construct_printer_info_5(print_hnd, printer, params)) {
+               free_printer_info_5(printer);
                return WERR_NOMEM;
+       }
        
        /* check the required size. */  
        *needed += spoolss_size_printer_info_5(printer);
@@ -4886,7 +4989,50 @@ out:
        return result;  
 }
 
-static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
+static WERROR getprinter_level_6(Printer_entry *print_hnd,
+                                const struct share_params *params,
+                                RPC_BUFFER *buffer, uint32 offered,
+                                uint32 *needed)
+{
+       PRINTER_INFO_6 *printer;
+       WERROR result = WERR_OK;
+
+       if ((printer = SMB_MALLOC_P(PRINTER_INFO_6)) == NULL) {
+               return WERR_NOMEM;
+       }
+
+       if (!construct_printer_info_6(print_hnd, printer, params)) {
+               free_printer_info_6(printer);
+               return WERR_NOMEM;
+       }
+
+       /* check the required size. */
+       *needed += spoolss_size_printer_info_6(printer);
+
+       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_6("", buffer, printer, 0);  
+       
+out:
+       /* clear memory */
+       free_printer_info_6(printer);
+       
+       return result;  
+}
+
+static WERROR getprinter_level_7(Printer_entry *print_hnd,
+                                const struct share_params *params,
+                                RPC_BUFFER *buffer, uint32 offered,
+                                uint32 *needed)
 {
        PRINTER_INFO_7 *printer=NULL;
        WERROR result = WERR_OK;
@@ -4894,7 +5040,7 @@ static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER
        if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
                return WERR_NOMEM;
 
-       if (!construct_printer_info_7(print_hnd, printer, snum))
+       if (!construct_printer_info_7(print_hnd, printer, params))
                return WERR_NOMEM;
        
        /* check the required size. */  
@@ -4932,12 +5078,13 @@ WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET
        uint32 offered = q_u->offered;
        uint32 *needed = &r_u->needed;
        Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
+       struct share_params *params;
 
        int snum;
 
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer) {
+       if (!q_u->buffer && (offered!=0)) {
                return WERR_INVALID_PARAM;
        }
 
@@ -4946,24 +5093,34 @@ WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET
 
        *needed=0;
 
-       if (!get_printer_snum(p, handle, &snum))
+       if (!get_printer_snum(p, handle, &snum, &params))
                return WERR_BADFID;
 
        switch (level) {
        case 0:
-               return getprinter_level_0(Printer, snum, buffer, offered, needed);
+               return getprinter_level_0(Printer, params, buffer, offered,
+                                         needed);
        case 1:
-               return getprinter_level_1(Printer, snum, buffer, offered, needed);
+               return getprinter_level_1(Printer, params, buffer, offered,
+                                         needed);
        case 2:         
-               return getprinter_level_2(Printer, snum, buffer, offered, needed);
+               return getprinter_level_2(Printer, params, buffer, offered,
+                                         needed);
        case 3:         
-               return getprinter_level_3(Printer, snum, buffer, offered, needed);
+               return getprinter_level_3(Printer, params, buffer, offered,
+                                         needed);
        case 4:         
-               return getprinter_level_4(Printer, snum, buffer, offered, needed);
+               return getprinter_level_4(Printer, params, buffer, offered,
+                                         needed);
        case 5:         
-               return getprinter_level_5(Printer, snum, buffer, offered, needed);
+               return getprinter_level_5(Printer, params, buffer, offered,
+                                         needed);
+       case 6:
+               return getprinter_level_6(Printer, params, buffer, offered,
+                                         needed);
        case 7:
-               return getprinter_level_7(Printer, snum, buffer, offered, needed);
+               return getprinter_level_7(Printer, params, buffer, offered,
+                                         needed);
        }
        return WERR_UNKNOWN_LEVEL;
 }      
@@ -4991,8 +5148,10 @@ static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fst
        if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
                return WERR_INVALID_PRINTER_NAME;
 
-       if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version)))
+       if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
+               free_a_printer(&printer, 2);
                return WERR_UNKNOWN_PRINTER_DRIVER;
+       }
 
        fill_printer_driver_info_1(info, driver, servername, architecture);
 
@@ -5051,8 +5210,10 @@ static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fst
        if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
                return WERR_INVALID_PRINTER_NAME;
 
-       if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version)))
+       if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
+               free_a_printer(&printer, 2);
                return WERR_UNKNOWN_PRINTER_DRIVER;
+       }
 
        fill_printer_driver_info_2(info, driver, servername);
 
@@ -5283,8 +5444,7 @@ static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_IN
        info->previousdrivernames=NULL;
        init_unistr_array(&info->previousdrivernames, &nullstr, servername);
 
-       info->driver_date.low=0;
-       info->driver_date.high=0;
+       info->driver_date=0;
 
        info->padding=0;
        info->driver_version_low=0;
@@ -5536,7 +5696,7 @@ WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_
 
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer) {
+       if (!q_u->buffer && (offered!=0)) {
                return WERR_INVALID_PARAM;
        }
 
@@ -5557,7 +5717,7 @@ WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_
        fstrcpy(servername, get_server_name( printer ));
        unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1);
 
-       if (!get_printer_snum(p, handle, &snum))
+       if (!get_printer_snum(p, handle, &snum, NULL))
                return WERR_BADFID;
 
        switch (level) {
@@ -5613,7 +5773,7 @@ WERROR _spoolss_endpageprinter(pipes_struct *p, SPOOL_Q_ENDPAGEPRINTER *q_u, SPO
                return WERR_BADFID;
        }
        
-       if (!get_printer_snum(p, handle, &snum))
+       if (!get_printer_snum(p, handle, &snum, NULL))
                return WERR_BADFID;
 
        Printer->page_started=False;
@@ -5639,15 +5799,12 @@ WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, S
        pstring jobname;
        fstring datatype;
        Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
-       struct current_user user;
 
        if (!Printer) {
                DEBUG(2,("_spoolss_startdocprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
                return WERR_BADFID;
        }
 
-       get_current_user(&user, p);
-
        /*
         * a nice thing with NT is it doesn't listen to what you tell it.
         * when asked to send _only_ RAW datas, it tries to send datas
@@ -5665,13 +5822,13 @@ WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, S
        }               
        
        /* get the share number of the printer */
-       if (!get_printer_snum(p, handle, &snum)) {
+       if (!get_printer_snum(p, handle, &snum, NULL)) {
                return WERR_BADFID;
        }
 
        unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname));
        
-       Printer->jobid = print_job_start(&user, snum, jobname, Printer->nt_devmode);
+       Printer->jobid = print_job_start(&p->pipe_user, snum, jobname, Printer->nt_devmode);
 
        /* An error occured in print_job_start() so return an appropriate
           NT error code. */
@@ -5717,7 +5874,7 @@ WERROR _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R
                return WERR_BADFID;
        }
 
-       if (!get_printer_snum(p, handle, &snum))
+       if (!get_printer_snum(p, handle, &snum, NULL))
                return WERR_BADFID;
 
        (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer,
@@ -5744,35 +5901,32 @@ WERROR _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R
 static WERROR control_printer(POLICY_HND *handle, uint32 command,
                              pipes_struct *p)
 {
-       struct current_user user;
        int snum;
        WERROR errcode = WERR_BADFUNC;
        Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
 
-       get_current_user(&user, p);
-
        if (!Printer) {
                DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
                return WERR_BADFID;
        }
 
-       if (!get_printer_snum(p, handle, &snum))
+       if (!get_printer_snum(p, handle, &snum, NULL))
                return WERR_BADFID;
 
        switch (command) {
        case PRINTER_CONTROL_PAUSE:
-               if (print_queue_pause(&user, snum, &errcode)) {
+               if (print_queue_pause(&p->pipe_user, snum, &errcode)) {
                        errcode = WERR_OK;
                }
                break;
        case PRINTER_CONTROL_RESUME:
        case PRINTER_CONTROL_UNPAUSE:
-               if (print_queue_resume(&user, snum, &errcode)) {
+               if (print_queue_resume(&p->pipe_user, snum, &errcode)) {
                        errcode = WERR_OK;
                }
                break;
        case PRINTER_CONTROL_PURGE:
-               if (print_queue_purge(&user, snum, &errcode)) {
+               if (print_queue_purge(&p->pipe_user, snum, &errcode)) {
                        errcode = WERR_OK;
                }
                break;
@@ -5794,7 +5948,6 @@ WERROR _spoolss_abortprinter(pipes_struct *p, SPOOL_Q_ABORTPRINTER *q_u, SPOOL_R
        POLICY_HND      *handle = &q_u->handle;
        Printer_entry   *Printer = find_printer_index_by_hnd(p, handle);
        int             snum;
-       struct          current_user user;
        WERROR          errcode = WERR_OK;
        
        if (!Printer) {
@@ -5802,12 +5955,10 @@ WERROR _spoolss_abortprinter(pipes_struct *p, SPOOL_Q_ABORTPRINTER *q_u, SPOOL_R
                return WERR_BADFID;
        }
        
-       if (!get_printer_snum(p, handle, &snum))
+       if (!get_printer_snum(p, handle, &snum, NULL))
                return WERR_BADFID;
        
-       get_current_user( &user, p );   
-       
-       print_job_delete( &user, snum, Printer->jobid, &errcode );      
+       print_job_delete( &p->pipe_user, snum, Printer->jobid, &errcode );      
        
        return errcode;
 }
@@ -5827,7 +5978,7 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
 
-       if (!Printer || !get_printer_snum(p, handle, &snum)) {
+       if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
                DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
                         OUR_HANDLE(handle)));
 
@@ -5835,6 +5986,12 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
                goto done;
        }
        
+       if (!secdesc_ctr) {
+               DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
+               result = WERR_INVALID_PARAM;
+               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
@@ -5855,20 +6012,20 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
                SEC_ACL *the_acl;
                int i;
 
-               the_acl = old_secdesc_ctr->sec->dacl;
+               the_acl = old_secdesc_ctr->sd->dacl;
                DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n", 
                           PRINTERNAME(snum), the_acl->num_aces));
 
                for (i = 0; i < the_acl->num_aces; i++) {
                        fstring sid_str;
 
-                       sid_to_string(sid_str, &the_acl->ace[i].trustee);
+                       sid_to_string(sid_str, &the_acl->aces[i].trustee);
 
                        DEBUG(10, ("%s 0x%08x\n", sid_str, 
-                                 the_acl->ace[i].info.mask));
+                                 the_acl->aces[i].access_mask));
                }
 
-               the_acl = secdesc_ctr->sec->dacl;
+               the_acl = secdesc_ctr->sd->dacl;
 
                if (the_acl) {
                        DEBUG(10, ("secdesc_ctr for %s has %d aces:\n", 
@@ -5877,10 +6034,10 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
                        for (i = 0; i < the_acl->num_aces; i++) {
                                fstring sid_str;
                                
-                               sid_to_string(sid_str, &the_acl->ace[i].trustee);
+                               sid_to_string(sid_str, &the_acl->aces[i].trustee);
                                
                                DEBUG(10, ("%s 0x%08x\n", sid_str, 
-                                          the_acl->ace[i].info.mask));
+                                          the_acl->aces[i].access_mask));
                        }
                } else {
                        DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
@@ -5888,8 +6045,12 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
        }
 
        new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
+       if (!new_secdesc_ctr) {
+               result = WERR_NOMEM;
+               goto done;
+       }
 
-       if (sec_desc_equal(new_secdesc_ctr->sec, old_secdesc_ctr->sec)) {
+       if (sec_desc_equal(new_secdesc_ctr->sd, old_secdesc_ctr->sd)) {
                result = WERR_OK;
                goto done;
        }
@@ -6013,7 +6174,9 @@ BOOL add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
        SE_PRIV se_printop = SE_PRINT_OPERATOR;
        BOOL is_print_op = False;
 
-       standard_sub_basic(current_user_info.smb_name, remote_machine,sizeof(remote_machine));
+       standard_sub_basic(current_user_info.smb_name,
+                          current_user_info.domain,
+                          remote_machine,sizeof(remote_machine));
        
        slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
                        cmd, printer->info_2->printername, printer->info_2->sharename,
@@ -6096,7 +6259,7 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
                goto done;
        }
 
-       if (!get_printer_snum(p, handle, &snum)) {
+       if (!get_printer_snum(p, handle, &snum, NULL)) {
                result = WERR_BADFID;
                goto done;
        }
@@ -6274,14 +6437,20 @@ static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
 #ifdef HAVE_ADS
        SPOOL_PRINTER_INFO_LEVEL_7 *info7 = info->info_7;
        int snum;
-       Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
+       Printer_entry *Printer;
+
+       if ( lp_security() != SEC_ADS ) {
+               return WERR_UNKNOWN_LEVEL;
+       }
+
+       Printer = find_printer_index_by_hnd(p, handle);
 
        DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
 
        if (!Printer)
                return WERR_BADFID;
 
-       if (!get_printer_snum(p, handle, &snum))
+       if (!get_printer_snum(p, handle, &snum, NULL))
                return WERR_BADFID;
        
        nt_printer_publish(Printer, snum, info7->action);
@@ -6351,7 +6520,7 @@ WERROR _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u)
                if ( Printer->printer_type == SPLHND_SERVER)
                        snum = -1;
                else if ( (Printer->printer_type == SPLHND_PRINTER) &&
-                               !get_printer_snum(p, handle, &snum) )
+                               !get_printer_snum(p, handle, &snum, NULL) )
                        return WERR_BADFID;
 
                srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
@@ -6375,7 +6544,7 @@ WERROR _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u
 {
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer) {
+       if (!q_u->buffer && (q_u->offered!=0)) {
                return WERR_INVALID_PARAM;
        }
 
@@ -6391,9 +6560,9 @@ 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,
+static void fill_job_info_1(JOB_INFO_1 *job_info, const print_queue_struct *queue,
                             int position, int snum, 
-                            NT_PRINTER_INFO_LEVEL *ntprinter)
+                            const NT_PRINTER_INFO_LEVEL *ntprinter)
 {
        struct tm *t;
        
@@ -6418,9 +6587,9 @@ static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue,
 /****************************************************************************
 ****************************************************************************/
 
-static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
+static BOOL fill_job_info_2(JOB_INFO_2 *job_info, const print_queue_struct *queue,
                             int position, int snum, 
-                           NT_PRINTER_INFO_LEVEL *ntprinter,
+                           const NT_PRINTER_INFO_LEVEL *ntprinter,
                            DEVICEMODE *devmode)
 {
        struct tm *t;
@@ -6463,8 +6632,8 @@ static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue,
  Enumjobs at level 1.
 ****************************************************************************/
 
-static WERROR enumjobs_level1(print_queue_struct *queue, int snum,
-                              NT_PRINTER_INFO_LEVEL *ntprinter,
+static WERROR enumjobs_level1(const print_queue_struct *queue, int snum,
+                              const NT_PRINTER_INFO_LEVEL *ntprinter,
                              RPC_BUFFER *buffer, uint32 offered,
                              uint32 *needed, uint32 *returned)
 {
@@ -6474,7 +6643,6 @@ static WERROR enumjobs_level1(print_queue_struct *queue, int snum,
        
        info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
        if (info==NULL) {
-               SAFE_FREE(queue);
                *returned=0;
                return WERR_NOMEM;
        }
@@ -6482,8 +6650,6 @@ 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, ntprinter );
 
-       SAFE_FREE(queue);
-
        /* check the required size. */  
        for (i=0; i<*returned; i++)
                (*needed) += spoolss_size_job_info_1(&info[i]);
@@ -6516,8 +6682,8 @@ out:
  Enumjobs at level 2.
 ****************************************************************************/
 
-static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
-                              NT_PRINTER_INFO_LEVEL *ntprinter,
+static WERROR enumjobs_level2(const print_queue_struct *queue, int snum,
+                              const NT_PRINTER_INFO_LEVEL *ntprinter,
                              RPC_BUFFER *buffer, uint32 offered,
                              uint32 *needed, uint32 *returned)
 {
@@ -6533,14 +6699,11 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum,
                
        /* this should not be a failure condition if the devmode is NULL */
        
-       devmode = construct_dev_mode(snum);
+       devmode = construct_dev_mode(lp_const_servicename(snum));
 
        for (i=0; i<*returned; i++)
                fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
 
-       free_a_printer(&ntprinter, 2);
-       SAFE_FREE(queue);
-
        /* check the required size. */  
        for (i=0; i<*returned; i++)
                (*needed) += spoolss_size_job_info_2(&info[i]);
@@ -6590,7 +6753,7 @@ WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO
 
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer) {
+       if (!q_u->buffer && (offered!=0)) {
                return WERR_INVALID_PARAM;
        }
 
@@ -6604,7 +6767,7 @@ WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO
 
        /* lookup the printer snum and tdb entry */
        
-       if (!get_printer_snum(p, handle, &snum))
+       if (!get_printer_snum(p, handle, &snum, NULL))
                return WERR_BADFID;
 
        wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
@@ -6616,22 +6779,24 @@ WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJO
 
        if (*returned == 0) {
                SAFE_FREE(queue);
+               free_a_printer(&ntprinter, 2);
                return WERR_OK;
        }
 
        switch (level) {
        case 1:
                wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned);
-               return wret;
+               break;
        case 2:
                wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned);
-               return wret;
+               break;
        default:
-               SAFE_FREE(queue);
                *returned=0;
                wret = WERR_UNKNOWN_LEVEL;
+               break;
        }
        
+       SAFE_FREE(queue);
        free_a_printer( &ntprinter, 2 );
        return wret;
 }
@@ -6653,11 +6818,10 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u
        uint32 jobid = q_u->jobid;
        uint32 command = q_u->command;
 
-       struct current_user user;
        int snum;
        WERROR errcode = WERR_BADFUNC;
                
-       if (!get_printer_snum(p, handle, &snum)) {
+       if (!get_printer_snum(p, handle, &snum, NULL)) {
                return WERR_BADFID;
        }
 
@@ -6665,23 +6829,21 @@ WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u
                return WERR_INVALID_PRINTER_NAME;
        }
 
-       get_current_user(&user, p);     
-
        switch (command) {
        case JOB_CONTROL_CANCEL:
        case JOB_CONTROL_DELETE:
-               if (print_job_delete(&user, snum, jobid, &errcode)) {
+               if (print_job_delete(&p->pipe_user, snum, jobid, &errcode)) {
                        errcode = WERR_OK;
                }
                break;
        case JOB_CONTROL_PAUSE:
-               if (print_job_pause(&user, snum, jobid, &errcode)) {
+               if (print_job_pause(&p->pipe_user, snum, jobid, &errcode)) {
                        errcode = WERR_OK;
                }               
                break;
        case JOB_CONTROL_RESTART:
        case JOB_CONTROL_RESUME:
-               if (print_job_resume(&user, snum, jobid, &errcode)) {
+               if (print_job_resume(&p->pipe_user, snum, jobid, &errcode)) {
                        errcode = WERR_OK;
                }
                break;
@@ -6713,8 +6875,10 @@ static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture
                ndrivers=get_ntdrivers(&list, architecture, version);
                DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
 
-               if(ndrivers == -1)
+               if(ndrivers == -1) {
+                       SAFE_FREE(driver_info_1);
                        return WERR_NOMEM;
+               }
 
                if(ndrivers != 0) {
                        if((driver_info_1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) {
@@ -6732,6 +6896,7 @@ static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture
                                                      architecture, version);
                        if (!W_ERROR_IS_OK(status)) {
                                SAFE_FREE(list);
+                               SAFE_FREE(driver_info_1);
                                return status;
                        }
                        fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );             
@@ -6794,8 +6959,10 @@ static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture
                ndrivers=get_ntdrivers(&list, architecture, version);
                DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
 
-               if(ndrivers == -1)
+               if(ndrivers == -1) {
+                       SAFE_FREE(driver_info_2);
                        return WERR_NOMEM;
+               }
 
                if(ndrivers != 0) {
                        if((driver_info_2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) {
@@ -6814,6 +6981,7 @@ static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture
                                                      architecture, version);
                        if (!W_ERROR_IS_OK(status)) {
                                SAFE_FREE(list);
+                               SAFE_FREE(driver_info_2);
                                return status;
                        }
                        fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);            
@@ -6865,8 +7033,8 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture
        int ndrivers;
        uint32 version;
        fstring *list = NULL;
-       NT_PRINTER_DRIVER_INFO_LEVEL driver;
        DRIVER_INFO_3 *driver_info_3=NULL;
+       NT_PRINTER_DRIVER_INFO_LEVEL driver;
        WERROR result = WERR_OK;
 
        *returned=0;
@@ -6876,8 +7044,10 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture
                ndrivers=get_ntdrivers(&list, architecture, version);
                DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
 
-               if(ndrivers == -1)
+               if(ndrivers == -1) {
+                       SAFE_FREE(driver_info_3);
                        return WERR_NOMEM;
+               }
 
                if(ndrivers != 0) {
                        if((driver_info_3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) {
@@ -6896,6 +7066,7 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture
                                                      architecture, version);
                        if (!W_ERROR_IS_OK(status)) {
                                SAFE_FREE(list);
+                               SAFE_FREE(driver_info_3);
                                return status;
                        }
                        fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);            
@@ -6929,8 +7100,9 @@ static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture
        }
 
 out:
-       for (i=0; i<*returned; i++)
+       for (i=0; i<*returned; i++) {
                SAFE_FREE(driver_info_3[i].dependentfiles);
+       }
 
        SAFE_FREE(driver_info_3);
        
@@ -6957,7 +7129,7 @@ WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS
 
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer) {
+       if (!q_u->buffer && (offered!=0)) {
                return WERR_INVALID_PARAM;
        }
 
@@ -7022,7 +7194,7 @@ WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
 
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer) {
+       if (!q_u->buffer && (offered!=0) ) {
                return WERR_INVALID_PARAM;
        }
 
@@ -7039,12 +7211,17 @@ 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) 
+       if (*numofforms == 0) {
+               SAFE_FREE(builtinlist);
+               SAFE_FREE(list);
                return WERR_NO_MORE_ITEMS;
+       }
 
        switch (level) {
        case 1:
                if ((forms_1=SMB_MALLOC_ARRAY(FORM_1, *numofforms)) == NULL) {
+                       SAFE_FREE(builtinlist);
+                       SAFE_FREE(list);
                        *numofforms=0;
                        return WERR_NOMEM;
                }
@@ -7107,7 +7284,6 @@ WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMF
                SAFE_FREE(builtinlist);
                return WERR_UNKNOWN_LEVEL;
        }
-
 }
 
 /****************************************************************************
@@ -7131,7 +7307,7 @@ WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *
 
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer) {
+       if (!q_u->buffer && (offered!=0)) {
                return WERR_INVALID_PARAM;
        }
 
@@ -7234,6 +7410,8 @@ WERROR enumports_hook( int *count, char ***lines )
        int ret;
        int fd;
 
+       *count = 0;
+       *lines = NULL;
 
        /* if no hook then just fill in the default port */
        
@@ -7252,9 +7430,9 @@ WERROR enumports_hook( int *count, char ***lines )
                ret = smbrun(command, &fd);
                DEBUG(10,("Returned [%d]\n", ret));
                if (ret != 0) {
-                       if (fd != -1)
+                       if (fd != -1) {
                                close(fd);
-                       
+                       }
                        return WERR_ACCESS_DENIED;
                }
 
@@ -7279,11 +7457,14 @@ static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *need
        PORT_INFO_1 *ports=NULL;
        int i=0;
        WERROR result = WERR_OK;
-       char **qlines;
-       int numlines;
+       char **qlines = NULL;
+       int numlines = 0;
 
-       if ( !W_ERROR_IS_OK(result = enumports_hook( &numlines, &qlines )) ) 
+       result = enumports_hook( &numlines, &qlines );
+       if (!W_ERROR_IS_OK(result)) {
+               file_lines_free(qlines);
                return result;
+       }
        
        if(numlines) {
                if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) {
@@ -7297,9 +7478,8 @@ static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *need
                        DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
                        fill_port_1(&ports[i], qlines[i]);
                }
-
-               file_lines_free(qlines);
        }
+       file_lines_free(qlines);
 
        *returned = numlines;
 
@@ -7343,12 +7523,14 @@ static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *need
        PORT_INFO_2 *ports=NULL;
        int i=0;
        WERROR result = WERR_OK;
-       char **qlines;
-       int numlines;
+       char **qlines = NULL;
+       int numlines = 0;
 
-       if ( !W_ERROR_IS_OK(result = enumports_hook( &numlines, &qlines )) ) 
+       result = enumports_hook( &numlines, &qlines );
+       if ( !W_ERROR_IS_OK(result)) {
+               file_lines_free(qlines);
                return result;
-       
+       }
        
        if(numlines) {
                if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) {
@@ -7360,10 +7542,10 @@ static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *need
                        DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
                        fill_port_2(&(ports[i]), qlines[i]);
                }
-
-               file_lines_free(qlines);
        }
 
+       file_lines_free(qlines);
+
        *returned = numlines;
 
        /* check the required size. */
@@ -7411,7 +7593,7 @@ WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUM
 
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer) {
+       if (!q_u->buffer && (offered!=0)) {
                return WERR_INVALID_PARAM;
        }
 
@@ -7587,26 +7769,23 @@ WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u,
        SPOOL_PRINTER_DRIVER_INFO_LEVEL *info = &q_u->info;
        WERROR err = WERR_OK;
        NT_PRINTER_DRIVER_INFO_LEVEL driver;
-       struct current_user user;
        fstring driver_name;
        uint32 version;
 
        ZERO_STRUCT(driver);
 
-       get_current_user(&user, p);
-       
        if (!convert_printer_driver_info(info, &driver, level)) {
                err = WERR_NOMEM;
                goto done;
        }
 
        DEBUG(5,("Cleaning driver's information\n"));
-       err = clean_up_driver_struct(driver, level, &user);
+       err = clean_up_driver_struct(driver, level, &p->pipe_user);
        if (!W_ERROR_IS_OK(err))
                goto done;
 
        DEBUG(5,("Moving driver to final destination\n"));
-       if( !W_ERROR_IS_OK(err = move_driver_to_download_area(driver, level, &user, &err)) ) {
+       if( !W_ERROR_IS_OK(err = move_driver_to_download_area(driver, level, &p->pipe_user, &err)) ) {
                goto done;
        }
 
@@ -7615,21 +7794,6 @@ WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u,
                goto done;
        }
 
-       /* BEGIN_ADMIN_LOG */
-        switch(level) {
-           case 3:
-               fstrcpy(driver_name, driver.info_3->name ? driver.info_3->name : "");
-               sys_adminlog(LOG_INFO,"Added printer driver. Print driver name: %s. Print driver OS: %s. Administrator name: %s.",
-                       driver_name, get_drv_ver_to_os(driver.info_3->cversion),uidtoname(user.ut.uid));
-               break;
-           case 6:   
-               fstrcpy(driver_name, driver.info_6->name ?  driver.info_6->name : "");
-               sys_adminlog(LOG_INFO,"Added printer driver. Print driver name: %s. Print driver OS: %s. Administrator name: %s.",
-                       driver_name, get_drv_ver_to_os(driver.info_6->version),uidtoname(user.ut.uid));
-               break;
-        }
-       /* END_ADMIN_LOG */
-
        /* 
         * I think this is where he DrvUpgradePrinter() hook would be
         * be called in a driver's interface DLL on a Windows NT 4.0/2k
@@ -7821,7 +7985,7 @@ WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRI
 
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer ) {
+       if (!q_u->buffer && (offered!=0)) {
                return WERR_INVALID_PARAM;
        }
 
@@ -7883,7 +8047,7 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
                return WERR_BADFID;
        }
 
-       if (!get_printer_snum(p,handle, &snum))
+       if (!get_printer_snum(p,handle, &snum, NULL))
                return WERR_BADFID;
        
        result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
@@ -7994,7 +8158,7 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S
                        goto done;
                }
        
-               *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), in_value_len, 0);
+               *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0);
 
                /* type */
                
@@ -8048,7 +8212,7 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP
                return WERR_INVALID_PARAM;
        }
 
-       if (!get_printer_snum(p,handle, &snum))
+       if (!get_printer_snum(p,handle, &snum, NULL))
                return WERR_BADFID;
 
        /* 
@@ -8120,7 +8284,7 @@ WERROR _spoolss_resetprinter(pipes_struct *p, SPOOL_Q_RESETPRINTER *q_u, SPOOL_R
                return WERR_BADFID;
        }
 
-       if (!get_printer_snum(p,handle, &snum))
+       if (!get_printer_snum(p,handle, &snum, NULL))
                return WERR_BADFID;
 
 
@@ -8150,7 +8314,7 @@ WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_
                return WERR_BADFID;
        }
 
-       if (!get_printer_snum(p, handle, &snum))
+       if (!get_printer_snum(p, handle, &snum, NULL))
                return WERR_BADFID;
 
        if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
@@ -8202,7 +8366,7 @@ WERROR _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM
        
        if ( Printer->printer_type == SPLHND_PRINTER )
        {
-               if (!get_printer_snum(p,handle, &snum))
+               if (!get_printer_snum(p,handle, &snum, NULL))
                        return WERR_BADFID;
         
                status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
@@ -8273,7 +8437,7 @@ WERROR _spoolss_deleteform( pipes_struct *p, SPOOL_Q_DELETEFORM *q_u, SPOOL_R_DE
        
        if ( Printer->printer_type == SPLHND_PRINTER )
        {
-               if (!get_printer_snum(p,handle, &snum))
+               if (!get_printer_snum(p,handle, &snum, NULL))
                        return WERR_BADFID;
         
                status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
@@ -8341,7 +8505,7 @@ WERROR _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM *
        
        if ( Printer->printer_type == SPLHND_PRINTER )
        {
-               if (!get_printer_snum(p,handle, &snum))
+               if (!get_printer_snum(p,handle, &snum, NULL))
                        return WERR_BADFID;
         
                status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
@@ -8433,7 +8597,7 @@ WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS
 
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer) {
+       if (!q_u->buffer && (offered!=0)) {
                return WERR_INVALID_PARAM;
        }
 
@@ -8467,7 +8631,7 @@ WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS
 static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
 {
        PRINTPROCDATATYPE_1 *info_1=NULL;
-       WERROR result = WERR_NOMEM;
+       WERROR result = WERR_OK;
        
        if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
                return WERR_NOMEM;
@@ -8512,7 +8676,7 @@ WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDAT
 
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer) {
+       if (!q_u->buffer && (offered!=0)) {
                return WERR_INVALID_PARAM;
        }
 
@@ -8640,7 +8804,7 @@ WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_
 
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer) {
+       if (!q_u->buffer && (offered!=0)) {
                return WERR_INVALID_PARAM;
        }
 
@@ -8761,7 +8925,7 @@ static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
         */
         
        if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
-               devmode = construct_dev_mode(snum);
+               devmode = construct_dev_mode(lp_const_servicename(snum));
        else {
                if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
                        ZERO_STRUCTP( devmode );
@@ -8816,7 +8980,7 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
 
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer) {
+       if (!q_u->buffer && (offered!=0)) {
                return WERR_INVALID_PARAM;
        }
 
@@ -8827,7 +8991,7 @@ WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_
        
        *needed = 0;
        
-       if (!get_printer_snum(p, handle, &snum))
+       if (!get_printer_snum(p, handle, &snum, NULL))
                return WERR_BADFID;
        
        wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
@@ -8910,7 +9074,7 @@ WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u,
                goto done;
        }
        
-       if ( !get_printer_snum(p,handle, &snum) )
+       if ( !get_printer_snum(p,handle, &snum, NULL) )
                return WERR_BADFID;
 
        status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
@@ -8996,7 +9160,7 @@ WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u,
                return WERR_INVALID_PARAM;
        }
 
-       if ( !get_printer_snum(p,handle, &snum) )
+       if ( !get_printer_snum(p,handle, &snum, NULL) )
                return WERR_BADFID;
 
        /* 
@@ -9047,7 +9211,8 @@ WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u,
                         */
                 
                        set_printer_dataex( printer, keyname, valuename, 
-                                           REG_SZ, (void*)oid_string, strlen(oid_string)+1 );          
+                                           REG_SZ, (uint8 *)oid_string,
+                                           strlen(oid_string)+1 );
                }
        
                status = mod_a_printer(printer, 2);
@@ -9082,7 +9247,7 @@ WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX
                return WERR_BADFID;
        }
 
-       if (!get_printer_snum(p, handle, &snum))
+       if (!get_printer_snum(p, handle, &snum, NULL))
                return WERR_BADFID;
 
        if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
@@ -9134,7 +9299,7 @@ WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPO
                return WERR_BADFID;
        }
 
-       if ( !get_printer_snum(p,handle, &snum) )
+       if ( !get_printer_snum(p,handle, &snum, NULL) )
                return WERR_BADFID;
 
        status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
@@ -9204,7 +9369,7 @@ WERROR _spoolss_deleteprinterkey(pipes_struct *p, SPOOL_Q_DELETEPRINTERKEY *q_u,
        if ( !q_u->keyname.buffer )
                return WERR_INVALID_PARAM;
                
-       if (!get_printer_snum(p, handle, &snum))
+       if (!get_printer_snum(p, handle, &snum, NULL))
                return WERR_BADFID;
 
        if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
@@ -9277,7 +9442,7 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
 
        /* get the printer off of disk */
        
-       if (!get_printer_snum(p,handle, &snum))
+       if (!get_printer_snum(p,handle, &snum, NULL))
                return WERR_BADFID;
        
        ZERO_STRUCT(printer);
@@ -9337,9 +9502,9 @@ 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 = (uint8 *)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", 
+                               DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n", 
                                        data_len ));
                                result = WERR_NOMEM;
                                goto done;
@@ -9354,6 +9519,15 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
        
        /* housekeeping information in the reply */
        
+       /* Fix from Martin Zielinski <mz@seh.de> - ensure
+        * the hand marshalled container size is a multiple
+        * of 4 bytes for RPC alignment.
+        */
+
+       if (needed % 4) {
+               needed += 4-(needed % 4);
+       }
+
        r_u->needed     = needed;
        r_u->returned   = num_entries;
 
@@ -9365,6 +9539,7 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_
        /* copy data into the reply */
        
        r_u->ctr.size           = r_u->needed;
+
        r_u->ctr.size_of_array  = r_u->returned;
        r_u->ctr.values         = enum_values;
        
@@ -9438,7 +9613,7 @@ WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROC
 
        /* that's an [in out] buffer */
 
-       if (!q_u->buffer) {
+       if (!q_u->buffer && (offered!=0)) {
                return WERR_INVALID_PARAM;
        }