diff options
author | Luke Leighton <lkcl@samba.org> | 2000-04-03 11:31:17 +0000 |
---|---|---|
committer | Luke Leighton <lkcl@samba.org> | 2000-04-03 11:31:17 +0000 |
commit | 7879877518b9ca0e14286128a48ccea87ca0d252 (patch) | |
tree | a7d1d475ec754b7a5d174d157839e5ee847af9c0 | |
parent | 70eedfacb2efa41aaaadbff355e11ee7f2f7c1bd (diff) | |
download | samba-7879877518b9ca0e14286128a48ccea87ca0d252.tar.gz |
merge from cvs main of jean-francois' spoolss work.
-rw-r--r-- | source/include/lib_smb_proto.h | 1 | ||||
-rw-r--r-- | source/include/nt_printing.h | 30 | ||||
-rw-r--r-- | source/include/proto.h | 19 | ||||
-rw-r--r-- | source/include/rpc_parse_proto.h | 9 | ||||
-rwxr-xr-x | source/include/rpc_spoolss.h | 107 | ||||
-rw-r--r-- | source/printing/nt_printing.c | 215 | ||||
-rw-r--r-- | source/rpc_parse/parse_prs.c | 8 | ||||
-rw-r--r-- | source/rpc_parse/parse_spoolss.c | 937 | ||||
-rwxr-xr-x | source/rpc_server/srv_spoolss.c | 19 | ||||
-rwxr-xr-x | source/spoolssd/srv_spoolss_nt.c | 753 |
10 files changed, 1352 insertions, 746 deletions
diff --git a/source/include/lib_smb_proto.h b/source/include/lib_smb_proto.h index 4cc87907056..c384f4098f2 100644 --- a/source/include/lib_smb_proto.h +++ b/source/include/lib_smb_proto.h @@ -632,6 +632,7 @@ BOOL prs_append_data(prs_struct * ps, const char *data, int len); BOOL prs_add_data(prs_struct * ps, const char *data, int len); void prs_switch_type(prs_struct *ps, BOOL io); void prs_force_dynamic(prs_struct *ps); +uint32 prs_data_size(prs_struct *ps); uint32 prs_offset(prs_struct *ps); BOOL prs_set_offset(prs_struct *ps, uint32 offset); void prs_mem_free(prs_struct *ps); diff --git a/source/include/nt_printing.h b/source/include/nt_printing.h index 22c837c7481..7d4c4e9dd55 100644 --- a/source/include/nt_printing.h +++ b/source/include/nt_printing.h @@ -1,3 +1,28 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB parameters and setup + Copyright (C) Andrew Tridgell 1992-2000, + Copyright (C) Jean Francois Micouleau 1998-2000. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef NT_PRINTING_H_ +#define NT_PRINTING_H_ + #define ORIENTATION 0x00000001L #define PAPERSIZE 0x00000002L #define PAPERLENGTH 0x00000004L @@ -192,7 +217,6 @@ typedef struct nt_printer_info_level_2 fstring sharename; fstring portname; fstring drivername; - fstring comment; fstring location; NT_DEVICEMODE *devmode; fstring sepfile; @@ -202,6 +226,9 @@ typedef struct nt_printer_info_level_2 NT_PRINTER_PARAM *specific; /* SEC_DESC_BUF *secdesc; */ /* not used but ... and how ??? */ + uint32 changeid; + uint32 c_setprinter; + time_t setuptime; } NT_PRINTER_INFO_LEVEL_2; typedef struct nt_printer_info_level @@ -235,3 +262,4 @@ typedef struct _form UNISTR2 name; } FORM; */ +#endif /* NT_PRINTING_H_ */ diff --git a/source/include/proto.h b/source/include/proto.h index 146e964c8b1..9b25b9b55cc 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -930,6 +930,11 @@ const char *get_sid_name_use_str(uint32 sid_name_use); BOOL do_file_lock(int fd, int waitsecs, int type); BOOL file_lock(int fd, int type, int secs, int *plock_depth); BOOL file_unlock(int fd, int *plock_depth); +uint32 map_lock_offset(uint32 high, uint32 low); +SMB_OFF_T get_lock_count(char *data, int data_offset, BOOL large_file_format, + BOOL *err); +SMB_OFF_T get_lock_offset(char *data, int data_offset, BOOL large_file_format, + BOOL *err); BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type); void *startfileent(char *pfile, char *s_readbuf, int bufsize, int *file_lock_depth, BOOL update); @@ -3784,6 +3789,7 @@ BOOL prs_append_data(prs_struct * ps, const char *data, int len); BOOL prs_add_data(prs_struct * ps, const char *data, int len); void prs_switch_type(prs_struct *ps, BOOL io); void prs_force_dynamic(prs_struct *ps); +uint32 prs_data_size(prs_struct *ps); uint32 prs_offset(prs_struct *ps); BOOL prs_set_offset(prs_struct *ps, uint32 offset); void prs_mem_free(prs_struct *ps); @@ -4752,10 +4758,6 @@ int reply_copy(connection_struct * conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize); int reply_setdir(connection_struct * conn, char *inbuf, char *outbuf, int dum_size, int dum_buffsize); -SMB_OFF_T get_lock_count(char *data, int data_offset, BOOL large_file_format, - BOOL *err); -SMB_OFF_T get_lock_offset(char *data, int data_offset, BOOL large_file_format, - BOOL *err); int reply_lockingX(connection_struct * conn, char *inbuf, char *outbuf, int length, int bufsize); int reply_readbmpx(connection_struct * conn, char *inbuf, char *outbuf, @@ -4956,9 +4958,10 @@ uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 le uint32 *needed, uint32 *returned); uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level, NEW_BUFFER *buffer, uint32 offered, uint32 *needed); -uint32 _spoolss_getprinterdriver2(const POLICY_HND *handle, const UNISTR2 *uni_arch, uint32 level, uint32 unknown, +uint32 _spoolss_getprinterdriver2(const POLICY_HND *handle, const UNISTR2 *uni_arch, uint32 level, + uint32 clientmajorversion, uint32 clientminorversion, NEW_BUFFER *buffer, uint32 offered, - uint32 *needed, uint32 *unknown0, uint32 *unknown1); + uint32 *needed, uint32 *servermajorversion, uint32 *serverminorversion); uint32 _spoolss_startpageprinter(const POLICY_HND *handle); uint32 _spoolss_endpageprinter(const POLICY_HND *handle); uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level, @@ -4996,7 +4999,7 @@ uint32 _spoolss_enumports( UNISTR2 *name, uint32 level, uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level, const SPOOL_PRINTER_INFO_LEVEL *info, uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3, - uint32 user_switch, const SPOOL_USER_CTR *user, + uint32 user_switch, const SPOOL_USER_CTR *user, POLICY_HND *handle); uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name, uint32 level, @@ -5008,7 +5011,7 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 idx, uint32 in_value_len, uint32 in_data_len, uint32 *out_max_value_len, uint16 **out_value, uint32 *out_value_len, uint32 *out_type, - uint32 *out_max_data_len, uint8 **out_pdata, uint32 *out_data_len); + uint32 *out_max_data_len, uint8 **data_out, uint32 *out_data_len); uint32 _spoolss_setprinterdata( const POLICY_HND *handle, const UNISTR2 *value, uint32 type, diff --git a/source/include/rpc_parse_proto.h b/source/include/rpc_parse_proto.h index cd1f0a44fbc..ab36786297b 100644 --- a/source/include/rpc_parse_proto.h +++ b/source/include/rpc_parse_proto.h @@ -937,7 +937,7 @@ BOOL make_systemtime(SYSTEMTIME *systime, struct tm *unixtime); BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth); BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u, fstring printername, fstring datatype, - uint32 access_required, fstring cli_name, fstring user_name); + uint32 access_required, fstring clientname, fstring user_name); BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth); BOOL spoolss_io_r_open_printer_ex(char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth); BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u, @@ -999,6 +999,10 @@ uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info); uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info); uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info); uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info); +BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, + const POLICY_HND *hnd, fstring architecture, + uint32 level, uint32 clientmajor, uint32 clientminor, + NEW_BUFFER *buffer, uint32 offered); BOOL spoolss_io_q_getprinterdriver2(char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth); BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth); BOOL make_spoolss_q_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u, uint32 flags, @@ -1008,6 +1012,8 @@ BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct BOOL new_spoolss_io_r_enumprinters(char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth); BOOL spoolss_io_r_getprinter(char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth); +BOOL make_spoolss_q_getprinter(SPOOL_Q_GETPRINTER *q_u, const POLICY_HND *hnd, uint32 level, + NEW_BUFFER *buffer, uint32 offered); BOOL spoolss_io_r_setprinter(char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth); BOOL spoolss_io_r_fcpn(char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth); @@ -1032,6 +1038,7 @@ BOOL spoolss_io_q_enumforms(char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, BOOL new_spoolss_io_r_enumforms(char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth); BOOL new_spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_enumports(char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth); +BOOL spool_io_printer_info_level_1(char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth); BOOL spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth); BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth); BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth); diff --git a/source/include/rpc_spoolss.h b/source/include/rpc_spoolss.h index e25eabe4412..0100fb007ef 100755 --- a/source/include/rpc_spoolss.h +++ b/source/include/rpc_spoolss.h @@ -332,6 +332,7 @@ #define PRINTER_ENUM_NETWORK 0x00000040 /* the flags of each printers */ +#define PRINTER_ENUM_UNKNOWN_8 0x00000008 #define PRINTER_ENUM_EXPAND 0x00004000 #define PRINTER_ENUM_CONTAINER 0x00008000 #define PRINTER_ENUM_ICONMASK 0x00ff0000 @@ -711,35 +712,49 @@ typedef struct printer_info_0 UNISTR printername; UNISTR servername; uint32 cjobs; - uint32 attributes; - uint32 unknown0; - uint32 unknown1; - uint32 unknown2; - uint32 unknown3; - uint32 unknown4; - uint32 unknown5; - uint32 unknown6; - uint16 majorversion; - uint16 buildversion; + uint32 total_jobs; + uint32 total_bytes; + + uint16 year; + uint16 month; + uint16 dayofweek; + uint16 day; + uint16 hour; + uint16 minute; + uint16 second; + uint16 milliseconds; + + uint32 global_counter; + uint32 total_pages; + + uint16 major_version; + uint16 build_version; + uint32 unknown7; uint32 unknown8; uint32 unknown9; - uint32 unknown10; + uint32 session_counter; uint32 unknown11; - uint32 unknown12; + uint32 printer_errors; uint32 unknown13; uint32 unknown14; uint32 unknown15; uint32 unknown16; - uint32 unknown17; + uint32 change_id; uint32 unknown18; uint32 status; uint32 unknown20; - uint32 unknown21; + uint32 c_setprinter; + uint16 unknown22; - uint32 unknown23; -} -PRINTER_INFO_0; + uint16 unknown23; + uint16 unknown24; + uint16 unknown25; + uint16 unknown26; + uint16 unknown27; + uint16 unknown28; + uint16 unknown29; +} PRINTER_INFO_0; typedef struct printer_info_1 { @@ -789,6 +804,7 @@ SPOOL_Q_ENUMPRINTERS; typedef struct printer_info_ctr_info { + PRINTER_INFO_0 *printers_0; PRINTER_INFO_1 *printers_1; PRINTER_INFO_2 *printers_2; } @@ -829,9 +845,7 @@ typedef struct spool_r_getprinter NEW_BUFFER *buffer; uint32 needed; uint32 status; - -} -SPOOL_R_GETPRINTER; +} SPOOL_R_GETPRINTER; struct s_notify_info_data_table { @@ -839,16 +853,15 @@ struct s_notify_info_data_table uint16 field; char *name; uint32 size; - void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA * data, - print_queue_struct * queue, - NT_PRINTER_INFO_LEVEL * printer); + void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data, + print_queue_struct *queue, + NT_PRINTER_INFO_LEVEL *printer); }; typedef struct driver_info_1 { UNISTR name; -} -DRIVER_INFO_1; +} DRIVER_INFO_1; typedef struct driver_info_2 { @@ -858,8 +871,7 @@ typedef struct driver_info_2 UNISTR driverpath; UNISTR datafile; UNISTR configfile; -} -DRIVER_INFO_2; +} DRIVER_INFO_2; typedef struct driver_info_3 { @@ -870,7 +882,7 @@ typedef struct driver_info_3 UNISTR datafile; UNISTR configfile; UNISTR helpfile; - UNISTR **dependentfiles; + uint16 *dependentfiles; UNISTR monitorname; UNISTR defaultdatatype; } @@ -878,16 +890,11 @@ DRIVER_INFO_3; typedef struct driver_info_info { - union - { - DRIVER_INFO_1 *info1; - DRIVER_INFO_2 *info2; - DRIVER_INFO_3 *info3; - } - driver; - + DRIVER_INFO_1 *info1; + DRIVER_INFO_2 *info2; + DRIVER_INFO_3 *info3; } -DRIVER_INFO; +PRINTER_DRIVER_CTR; typedef struct spool_q_getprinterdriver2 { @@ -897,7 +904,8 @@ typedef struct spool_q_getprinterdriver2 uint32 level; NEW_BUFFER *buffer; uint32 offered; - uint32 unknown; + uint32 clientmajorversion; + uint32 clientminorversion; } SPOOL_Q_GETPRINTERDRIVER2; @@ -905,8 +913,8 @@ typedef struct spool_r_getprinterdriver2 { NEW_BUFFER *buffer; uint32 needed; - uint32 unknown0; - uint32 unknown1; + uint32 servermajorversion; + uint32 serverminorversion; uint32 status; } SPOOL_R_GETPRINTERDRIVER2; @@ -1180,6 +1188,17 @@ typedef struct spool_r_enumforms SPOOL_R_ENUMFORMS; +typedef struct spool_printer_info_level_1 +{ + uint32 flags; + uint32 description_ptr; + uint32 name_ptr; + uint32 comment_ptr; + UNISTR2 description; + UNISTR2 name; + UNISTR2 comment; +} SPOOL_PRINTER_INFO_LEVEL_1; + typedef struct spool_printer_info_level_2 { uint32 servername_ptr; @@ -1222,6 +1241,7 @@ typedef struct spool_printer_info_level { uint32 level; uint32 info_ptr; + SPOOL_PRINTER_INFO_LEVEL_1 *info_1; SPOOL_PRINTER_INFO_LEVEL_2 *info_2; } SPOOL_PRINTER_INFO_LEVEL; @@ -1525,7 +1545,6 @@ typedef struct spool_q_setprinterdata uint8 *data; uint32 real_len; uint32 numeric_data; - } SPOOL_Q_SETPRINTERDATA; @@ -1597,9 +1616,11 @@ typedef struct pjob_info_info JOB_INFO_1 *job_info_1; JOB_INFO_2 *job_info_2; void *info; - } job; + } + job; -} PJOB_INFO; +} +PJOB_INFO; typedef struct spool_r_getjob { diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c index 88efba6563d..a2a8d728d9d 100644 --- a/source/printing/nt_printing.c +++ b/source/printing/nt_printing.c @@ -1,3 +1,25 @@ +/* + * Unix SMB/Netbios implementation. + * Version 1.9. + * RPC Pipe client / server routines + * Copyright (C) Andrew Tridgell 1992-2000, + * Copyright (C) Jean François Micouleau 1998-2000. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + #include "includes.h" #include "nterr.h" @@ -31,7 +53,7 @@ static BOOL parse_form_entry(char *line, nt_forms_struct *buf) count++; } - DEBUG(6,("Found [%d] tokens\n", count)); + DEBUG(106,("Found [%d] tokens\n", count)); StrnCpy(buf->name,tok[NAMETOK],sizeof(buf->name)-1); buf->flag=atoi(tok[FLAGTOK]); @@ -65,7 +87,7 @@ int get_ntforms(nt_forms_struct **list) while ( fgets(line, sizeof(pstring), f) ) { - DEBUG(5,("%s\n",line)); + DEBUG(105,("%s\n",line)); *list = Realloc(*list, sizeof(nt_forms_struct)*(total+1)); if (! *list) @@ -73,7 +95,7 @@ int get_ntforms(nt_forms_struct **list) total = 0; break; } - memset( (char *)&(*list)[total], 0, sizeof(nt_forms_struct) ); + memset( (char *)&(*list)[total], '\0', sizeof(nt_forms_struct) ); if ( parse_form_entry(line, &(*list)[total] ) ) { total++; @@ -82,7 +104,7 @@ int get_ntforms(nt_forms_struct **list) } fclose(f); - DEBUG(4,("%d info lines on %d\n",total, grandtotal)); + DEBUG(104,("%d info lines on %d\n",total, grandtotal)); return(total); } @@ -100,7 +122,7 @@ int write_ntforms(nt_forms_struct **list, int number) *line=0; - DEBUG(6,("write_ntforms\n")); + DEBUG(106,("write_ntforms\n")); if((f = sys_fopen(file, "w")) == NULL) { @@ -115,11 +137,11 @@ int write_ntforms(nt_forms_struct **list, int number) (*list)[i].flag, (*list)[i].width, (*list)[i].length, (*list)[i].left, (*list)[i].top, (*list)[i].right, (*list)[i].bottom); - DEBUGADD(7,("adding entry [%s]\n", (*list)[i].name)); + DEBUGADD(107,("adding entry [%s]\n", (*list)[i].name)); } fclose(f); - DEBUGADD(6,("closing file\n")); + DEBUGADD(106,("closing file\n")); return(total); } @@ -145,7 +167,7 @@ void add_a_form(nt_forms_struct **list, const FORM *form, int *count) { if (!strncmp((*list)[n].name, form_name, strlen(form_name))) { - DEBUG(3, ("NT workaround, [%s] already exists\n", form_name)); + DEBUG(103, ("NT workaround, [%s] already exists\n", form_name)); update=True; } } @@ -175,10 +197,10 @@ void update_a_form(nt_forms_struct **list, const FORM *form, int count) fstring form_name; unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1); - DEBUG(6, ("[%s]\n", form_name)); + DEBUG(106, ("[%s]\n", form_name)); for (n=0; n<count; n++) { - DEBUGADD(6, ("n [%d]:[%s]\n", n, (*list)[n].name)); + DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name)); if (!strncmp((*list)[n].name, form_name, strlen(form_name))) break; } @@ -209,7 +231,7 @@ int get_ntdrivers(fstring **list, char *architecture) int match_len; int total=0; - DEBUG(5,("Getting the driver list from directory: [%s]\n", lp_nt_drivers_file())); + DEBUG(105,("Getting the driver list from directory: [%s]\n", lp_nt_drivers_file())); *list=NULL; dirp = opendir(lp_nt_drivers_file()); @@ -228,13 +250,13 @@ int get_ntdrivers(fstring **list, char *architecture) { if (strncmp(dpname, name_match, match_len)==0) { - DEBUGADD(7,("Found: [%s]\n", dpname)); + DEBUGADD(107,("Found: [%s]\n", dpname)); fstrcpy(driver_name, dpname+match_len); all_string_sub(driver_name, "#", "/", 0); *list = Realloc(*list, sizeof(fstring)*(total+1)); StrnCpy((*list)[total], driver_name, strlen(driver_name)); - DEBUGADD(6,("Added: [%s]\n", driver_name)); + DEBUGADD(106,("Added: [%s]\n", driver_name)); total++; } } @@ -266,20 +288,20 @@ void get_short_archi(char *short_archi, char *long_archi) int i=-1; - DEBUG(7,("Getting architecture dependant directory\n")); + DEBUG(107,("Getting architecture dependant directory\n")); do { i++; } while ( (archi_table[i].long_archi!=NULL ) && strncmp(long_archi, archi_table[i].long_archi, strlen(long_archi)) ); if (archi_table[i].long_archi==NULL) { - DEBUGADD(7,("Unknown architecture [%s] !\n", long_archi)); + DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi)); } StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi)); - DEBUGADD(8,("index: [%d]\n", i)); - DEBUGADD(8,("long architecture: [%s]\n", long_archi)); - DEBUGADD(8,("short architecture: [%s]\n", short_archi)); + DEBUGADD(108,("index: [%d]\n", i)); + DEBUGADD(108,("long architecture: [%s]\n", long_archi)); + DEBUGADD(108,("short architecture: [%s]\n", short_archi)); } /**************************************************************************** @@ -397,7 +419,7 @@ static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, v=strncpyn(p, line, sizeof(p), ':'); if (v==NULL) { - DEBUG(1, ("malformed printer entry (no :)\n")); + DEBUG(1, ("malformed printer driver entry (no :)\n")); continue; } @@ -444,7 +466,6 @@ static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, StrnCpy(dependentfiles[i], v, strlen(v) ); i++; } - } free(line); @@ -471,36 +492,32 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3; char **dependentfiles; - DEBUG(6,("Dumping printer driver at level [%d]\n", level)); + DEBUG(106,("Dumping printer driver at level [%d]\n", level)); switch (level) { case 3: { if (driver.info_3 == NULL) - { - DEBUGADD(3,("NULL pointer, memory not alloced ?\n")); success=5; - } - else - { + else { info3=driver.info_3; - DEBUGADD(6,("version:[%d]\n", info3->cversion)); - DEBUGADD(6,("name:[%s]\n", info3->name)); - DEBUGADD(6,("environment:[%s]\n", info3->environment)); - DEBUGADD(6,("driverpath:[%s]\n", info3->driverpath)); - DEBUGADD(6,("datafile:[%s]\n", info3->datafile)); - DEBUGADD(6,("configfile:[%s]\n", info3->configfile)); - DEBUGADD(6,("helpfile:[%s]\n", info3->helpfile)); - DEBUGADD(6,("monitorname:[%s]\n", info3->monitorname)); - DEBUGADD(6,("defaultdatatype:[%s]\n", info3->defaultdatatype)); + DEBUGADD(106,("version:[%d]\n", info3->cversion)); + DEBUGADD(106,("name:[%s]\n", info3->name)); + DEBUGADD(106,("environment:[%s]\n", info3->environment)); + DEBUGADD(106,("driverpath:[%s]\n", info3->driverpath)); + DEBUGADD(106,("datafile:[%s]\n", info3->datafile)); + DEBUGADD(106,("configfile:[%s]\n", info3->configfile)); + DEBUGADD(106,("helpfile:[%s]\n", info3->helpfile)); + DEBUGADD(106,("monitorname:[%s]\n", info3->monitorname)); + DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype)); dependentfiles=info3->dependentfiles; while ( **dependentfiles != '\0' ) { - DEBUGADD(6,("dependentfile:[%s]\n", *dependentfiles)); + DEBUGADD(106,("dependentfile:[%s]\n", *dependentfiles)); dependentfiles++; } success=0; @@ -619,6 +636,9 @@ static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info) fprintf(f, "status: %d\n", info->status); fprintf(f, "cjobs: %d\n", info->cjobs); fprintf(f, "averageppm: %d\n", info->averageppm); + fprintf(f, "changeid: %d\n", info->changeid); + fprintf(f, "c_setprinter: %d\n", info->c_setprinter); + fprintf(f, "setuptime: %d\n", (int)info->setuptime); /* * in addprinter: no servername and the printer is the name @@ -641,7 +661,6 @@ static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info) fprintf(f, "sharename: %s\n", info->sharename); fprintf(f, "portname: %s\n", info->portname); fprintf(f, "drivername: %s\n", info->drivername); - fprintf(f, "comment: %s\n", info->comment); fprintf(f, "location: %s\n", info->location); fprintf(f, "sepfile: %s\n", info->sepfile); fprintf(f, "printprocessor: %s\n", info->printprocessor); @@ -676,7 +695,7 @@ static void dissect_and_fill_a_param(NT_PRINTER_PARAM *param, char *v) char *tok[5]; int count = 0; - DEBUG(5,("dissect_and_fill_a_param\n")); + DEBUG(105,("dissect_and_fill_a_param\n")); tok[count] = strtok(v,"#"); count++; @@ -693,7 +712,7 @@ static void dissect_and_fill_a_param(NT_PRINTER_PARAM *param, char *v) strhex_to_str(param->data, 2*(param->data_len), tok[3]); param->next=NULL; - DEBUGADD(5,("value:[%s], len:[%d]\n", param->value, param->data_len)); + DEBUGADD(105,("value:[%s], len:[%d]\n", param->value, param->data_len)); } /**************************************************************************** @@ -703,10 +722,10 @@ used when reading from disk. ****************************************************************************/ void dump_a_param(NT_PRINTER_PARAM *param) { - DEBUG(5,("dump_a_param\n")); - DEBUGADD(6,("value [%s]\n", param->value)); - DEBUGADD(6,("type [%d]\n", param->type)); - DEBUGADD(6,("data len [%d]\n", param->data_len)); + DEBUG(105,("dump_a_param\n")); + DEBUGADD(106,("value [%s]\n", param->value)); + DEBUGADD(106,("type [%d]\n", param->type)); + DEBUGADD(106,("data len [%d]\n", param->data_len)); } /**************************************************************************** @@ -715,7 +734,7 @@ BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *par { NT_PRINTER_PARAM *current; - DEBUG(8,("add_a_specific_param\n")); + DEBUG(108,("add_a_specific_param\n")); param->next=NULL; @@ -749,10 +768,10 @@ BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_ if ( !strcmp(current->value, param->value) && (strlen(current->value)==strlen(param->value)) ) { - DEBUG(9,("deleting first value\n")); + DEBUG(109,("deleting first value\n")); info_2->specific=current->next; free(current); - DEBUG(9,("deleted first value\n")); + DEBUG(109,("deleted first value\n")); return (True); } @@ -763,10 +782,10 @@ BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_ if (!strcmp(current->value, param->value) && strlen(current->value)==strlen(param->value) ) { - DEBUG(9,("deleting current value\n")); + DEBUG(109,("deleting current value\n")); previous->next=current->next; free(current); - DEBUG(9,("deleted current value\n")); + DEBUG(109,("deleted current value\n")); return(True); } @@ -835,7 +854,7 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen /* don't check if v==NULL as an empty arg is valid */ - DEBUGADD(15, ("[%s]:[%s]\n", p, v)); + DEBUGADD(115, ("[%s]:[%s]\n", p, v)); /* * The PRINTER_INFO_2 fields @@ -865,6 +884,15 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen if (!strncmp(p, "averageppm", strlen("averageppm"))) info->averageppm=atoi(v); + if (!strncmp(p, "changeid", strlen("changeid"))) + info->changeid=atoi(v); + + if (!strncmp(p, "c_setprinter", strlen("c_setprinter"))) + info->c_setprinter=atoi(v); + + if (!strncmp(p, "setuptime", strlen("setuptime"))) + info->setuptime=atoi(v); + if (!strncmp(p, "servername", strlen("servername"))) StrnCpy(info->servername, v, strlen(v)); @@ -880,9 +908,6 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen if (!strncmp(p, "drivername", strlen("drivername"))) StrnCpy(info->drivername, v, strlen(v)); - if (!strncmp(p, "comment", strlen("comment"))) - StrnCpy(info->comment, v, strlen(v)); - if (!strncmp(p, "location", strlen("location"))) StrnCpy(info->location, v, strlen(v)); @@ -1008,41 +1033,40 @@ static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level) uint32 success; NT_PRINTER_INFO_LEVEL_2 *info2; - DEBUG(6,("Dumping printer at level [%d]\n", level)); + DEBUG(106,("Dumping printer at level [%d]\n", level)); switch (level) { case 2: { if (printer.info_2 == NULL) - { - DEBUGADD(3,("NULL pointer, memory not alloced ?\n")); success=5; - } else { info2=printer.info_2; - DEBUGADD(6,("attributes:[%d]\n", info2->attributes)); - DEBUGADD(6,("priority:[%d]\n", info2->priority)); - DEBUGADD(6,("default_priority:[%d]\n", info2->default_priority)); - DEBUGADD(6,("starttime:[%d]\n", info2->starttime)); - DEBUGADD(6,("untiltime:[%d]\n", info2->untiltime)); - DEBUGADD(6,("status:[%d]\n", info2->status)); - DEBUGADD(6,("cjobs:[%d]\n", info2->cjobs)); - DEBUGADD(6,("averageppm:[%d]\n", info2->averageppm)); - - DEBUGADD(6,("servername:[%s]\n", info2->servername)); - DEBUGADD(6,("printername:[%s]\n", info2->printername)); - DEBUGADD(6,("sharename:[%s]\n", info2->sharename)); - DEBUGADD(6,("portname:[%s]\n", info2->portname)); - DEBUGADD(6,("drivername:[%s]\n", info2->drivername)); - DEBUGADD(6,("comment:[%s]\n", info2->comment)); - DEBUGADD(6,("location:[%s]\n", info2->location)); - DEBUGADD(6,("sepfile:[%s]\n", info2->sepfile)); - DEBUGADD(6,("printprocessor:[%s]\n", info2->printprocessor)); - DEBUGADD(6,("datatype:[%s]\n", info2->datatype)); - DEBUGADD(6,("parameters:[%s]\n", info2->parameters)); + DEBUGADD(106,("attributes:[%d]\n", info2->attributes)); + DEBUGADD(106,("priority:[%d]\n", info2->priority)); + DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority)); + DEBUGADD(106,("starttime:[%d]\n", info2->starttime)); + DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime)); + DEBUGADD(106,("status:[%d]\n", info2->status)); + DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs)); + DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm)); + DEBUGADD(106,("changeid:[%d]\n", info2->changeid)); + DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter)); + DEBUGADD(106,("setuptime:[%d]\n", (int)info2->setuptime)); + + DEBUGADD(106,("servername:[%s]\n", info2->servername)); + DEBUGADD(106,("printername:[%s]\n", info2->printername)); + DEBUGADD(106,("sharename:[%s]\n", info2->sharename)); + DEBUGADD(106,("portname:[%s]\n", info2->portname)); + DEBUGADD(106,("drivername:[%s]\n", info2->drivername)); + DEBUGADD(106,("location:[%s]\n", info2->location)); + DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile)); + DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor)); + DEBUGADD(106,("datatype:[%s]\n", info2->datatype)); + DEBUGADD(106,("parameters:[%s]\n", info2->parameters)); success=0; } break; @@ -1114,7 +1138,7 @@ uint32 get_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level, fstring share uint32 free_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level) { uint32 success; - DEBUG(4,("freeing a printer at level [%d]\n", level)); + DEBUG(104,("freeing a printer at level [%d]\n", level)); switch (level) { @@ -1124,7 +1148,7 @@ uint32 free_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level) { if ((printer.info_2)->devmode != NULL) { - DEBUG(6,("deleting DEVMODE\n")); + DEBUG(106,("deleting DEVMODE\n")); if ((printer.info_2)->devmode->private !=NULL ) free((printer.info_2)->devmode->private); free((printer.info_2)->devmode); @@ -1140,7 +1164,7 @@ uint32 free_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level) while ( param != NULL) { next_param=param->next; - DEBUG(6,("deleting param [%s]\n", param->value)); + DEBUG(106,("deleting param [%s]\n", param->value)); free(param->data); free(param); param=next_param; @@ -1168,7 +1192,7 @@ uint32 free_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level) uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level) { uint32 success; - DEBUG(4,("adding a printer at level [%d]\n", level)); + DEBUG(104,("adding a printer at level [%d]\n", level)); dump_a_printer_driver(driver, level); switch (level) @@ -1272,17 +1296,16 @@ BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, ui i++; } - if (param != NULL) - { - /* exited because it exist */ - *type=param->type; - StrnCpy(value, param->value, sizeof(value)-1); - *data=(uint8 *)malloc(param->data_len*sizeof(uint8)); - memcpy(*data, param->data, param->data_len); - *len=param->data_len; - return (True); - } - return (False); + if (param == NULL) + return False; + + /* exited because it exist */ + *type=param->type; + StrnCpy(value, param->value, sizeof(fstring)-1); + *data=(uint8 *)malloc(param->data_len*sizeof(uint8)); + memcpy(*data, param->data, param->data_len); + *len=param->data_len; + return True; } /**************************************************************************** @@ -1293,7 +1316,7 @@ BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level, /* right now that's enough ! */ NT_PRINTER_PARAM *param; - DEBUG(5, ("get_specific_param\n")); + DEBUG(105, ("get_specific_param\n")); param=printer.info_2->specific; @@ -1306,7 +1329,7 @@ BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level, param=param->next; } - DEBUG(6, ("found one param\n")); + DEBUG(106, ("found one param\n")); if (param != NULL) { /* exited because it exist */ @@ -1316,10 +1339,10 @@ BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level, memcpy(*data, param->data, param->data_len); *len=param->data_len; - DEBUG(6, ("exit of get_specific_param:true\n")); + DEBUG(106, ("exit of get_specific_param:true\n")); return (True); } - DEBUG(6, ("exit of get_specific_param:false\n")); + DEBUG(106, ("exit of get_specific_param:false\n")); return (False); } @@ -1331,7 +1354,7 @@ void init_devicemode(NT_DEVICEMODE *nt_devmode) * should I init this ones ??? nt_devmode->devicename */ - safe_strcpy(nt_devmode->formname, "A4", sizeof(nt_devmode->formname)-1); + fstrcpy(nt_devmode->formname, "A4"); nt_devmode->specversion = 0x0401; nt_devmode->driverversion = 0x0400; diff --git a/source/rpc_parse/parse_prs.c b/source/rpc_parse/parse_prs.c index 214fc2d73c6..56c835b4bf5 100644 --- a/source/rpc_parse/parse_prs.c +++ b/source/rpc_parse/parse_prs.c @@ -576,7 +576,14 @@ void prs_force_dynamic(prs_struct *ps) /******************************************************************* Fetch the current offset (external interface). ********************************************************************/ +uint32 prs_data_size(prs_struct *ps) +{ + return ps->data_size; +} +/******************************************************************* + Fetch the current offset (external interface). + ********************************************************************/ uint32 prs_offset(prs_struct *ps) { return ps->offset; @@ -585,7 +592,6 @@ uint32 prs_offset(prs_struct *ps) /******************************************************************* Set the current offset (external interface). ********************************************************************/ - BOOL prs_set_offset(prs_struct *ps, uint32 offset) { if(offset <= ps->offset) { diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c index e930014b245..57853d6c152 100644 --- a/source/rpc_parse/parse_spoolss.c +++ b/source/rpc_parse/parse_spoolss.c @@ -26,17 +26,24 @@ #include "nterr.h" #include "rpc_parse.h" -#undef prs_uint16 -#undef prs_uint32 -#undef prs_uint8s -#undef prs_uint16s -#undef prs_unistr -#define prs_uint16 _prs_uint16 -#define prs_uint32 _prs_uint32 -#define prs_uint8s _prs_uint8s -#define prs_uint16s _prs_uint16s -#define prs_unistr _prs_unistr -#define init_unistr2 make_unistr2 +#define TNG + +#ifdef TNG + #undef prs_uint16 + #undef prs_uint32 + #undef prs_uint8s + #undef prs_uint16s + #undef prs_unistr + #undef prs_unistr2 + #define prs_uint16 _prs_uint16 + #define prs_uint32 _prs_uint32 + #define prs_uint8s _prs_uint8s + #define prs_uint16s _prs_uint16s + #define prs_unistr _prs_unistr + #define prs_unistr2 _prs_unistr2 + #define init_unistr2 make_unistr2 + #define init_buf_unistr2 make_buf_unistr2 +#endif extern int DEBUGLEVEL; @@ -59,14 +66,22 @@ This should be moved in a more generic lib. ********************************************************************/ static BOOL spoolss_io_system_time(char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime) { - prs_uint16("year", ps, depth, &(systime->year)); - prs_uint16("month", ps, depth, &(systime->month)); - prs_uint16("dayofweek", ps, depth, &(systime->dayofweek)); - prs_uint16("day", ps, depth, &(systime->day)); - prs_uint16("hour", ps, depth, &(systime->hour)); - prs_uint16("minute", ps, depth, &(systime->minute)); - prs_uint16("second", ps, depth, &(systime->second)); - prs_uint16("milliseconds", ps, depth, &(systime->milliseconds)); + if(!prs_uint16("year", ps, depth, &(systime->year))) + return False; + if(!prs_uint16("month", ps, depth, &(systime->month))) + return False; + if(!prs_uint16("dayofweek", ps, depth, &(systime->dayofweek))) + return False; + if(!prs_uint16("day", ps, depth, &(systime->day))) + return False; + if(!prs_uint16("hour", ps, depth, &(systime->hour))) + return False; + if(!prs_uint16("minute", ps, depth, &(systime->minute))) + return False; + if(!prs_uint16("second", ps, depth, &(systime->second))) + return False; + if(!prs_uint16("milliseconds", ps, depth, &(systime->milliseconds))) + return False; return True; } @@ -97,15 +112,22 @@ static BOOL smb_io_doc_info_1(char *desc, DOC_INFO_1 *info_1, prs_struct *ps, in prs_debug(ps, depth, desc, "smb_io_doc_info_1"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; - prs_uint32("p_docname", ps, depth, &(info_1->p_docname)); - prs_uint32("p_outputfile", ps, depth, &(info_1->p_outputfile)); - prs_uint32("p_datatype", ps, depth, &(info_1->p_datatype)); + if(!prs_uint32("p_docname", ps, depth, &(info_1->p_docname))) + return False; + if(!prs_uint32("p_outputfile", ps, depth, &(info_1->p_outputfile))) + return False; + if(!prs_uint32("p_datatype", ps, depth, &(info_1->p_datatype))) + return False; - smb_io_unistr2("", &(info_1->docname), info_1->p_docname, ps, depth); - smb_io_unistr2("", &(info_1->outputfile), info_1->p_outputfile, ps, depth); - smb_io_unistr2("", &(info_1->datatype), info_1->p_datatype, ps, depth); + if(!smb_io_unistr2("", &(info_1->docname), info_1->p_docname, ps, depth)) + return False; + if(!smb_io_unistr2("", &(info_1->outputfile), info_1->p_outputfile, ps, depth)) + return False; + if(!smb_io_unistr2("", &(info_1->datatype), info_1->p_datatype, ps, depth)) + return False; return True; } @@ -122,16 +144,20 @@ static BOOL smb_io_doc_info(char *desc, DOC_INFO *info, prs_struct *ps, int dept prs_debug(ps, depth, desc, "smb_io_doc_info"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; - prs_uint32("switch_value", ps, depth, &(info->switch_value)); + if(!prs_uint32("switch_value", ps, depth, &(info->switch_value))) + return False; - prs_uint32("doc_info_X ptr", ps, depth, &(useless_ptr)); + if(!prs_uint32("doc_info_X ptr", ps, depth, &(useless_ptr))) + return False; switch (info->switch_value) { case 1: - smb_io_doc_info_1("",&(info->doc_info_1), ps, depth); + if(!smb_io_doc_info_1("",&(info->doc_info_1), ps, depth)) + return False; break; case 2: /* @@ -164,11 +190,14 @@ static BOOL smb_io_doc_info_container(char *desc, DOC_INFO_CONTAINER *cont, prs_ prs_debug(ps, depth, desc, "smb_io_doc_info_container"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; - prs_uint32("level", ps, depth, &(cont->level)); + if(!prs_uint32("level", ps, depth, &(cont->level))) + return False; - smb_io_doc_info("",&(cont->docinfo), ps, depth); + if(!smb_io_doc_info("",&(cont->docinfo), ps, depth)) + return False; return True; } @@ -312,20 +341,28 @@ static BOOL smb_io_notify_info_data(char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs isvalue=data->enc_type; - prs_align(ps); - prs_uint16("type", ps, depth, &(data->type)); - prs_uint16("field", ps, depth, &(data->field)); + if(!prs_align(ps)) + return False; + if(!prs_uint16("type", ps, depth, &(data->type))) + return False; + if(!prs_uint16("field", ps, depth, &(data->field))) + return False; /*prs_align(ps);*/ - prs_uint32("how many words", ps, depth, &how_many_words); - prs_uint32("id", ps, depth, &(data->id)); - prs_uint32("how many words", ps, depth, &how_many_words); + if(!prs_uint32("how many words", ps, depth, &how_many_words)) + return False; + if(!prs_uint32("id", ps, depth, &(data->id))) + return False; + if(!prs_uint32("how many words", ps, depth, &how_many_words)) + return False; /*prs_align(ps);*/ if (isvalue==True) { - prs_uint32("value[0]", ps, depth, &(data->notify_data.value[0])); - prs_uint32("value[1]", ps, depth, &(data->notify_data.value[1])); + if(!prs_uint32("value[0]", ps, depth, &(data->notify_data.value[0]))) + return False; + if(!prs_uint32("value[1]", ps, depth, &(data->notify_data.value[1]))) + return False; /*prs_align(ps);*/ } else @@ -333,8 +370,10 @@ static BOOL smb_io_notify_info_data(char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs /* it's a string */ /* length in ascii including \0 */ x=2*(data->notify_data.data.length+1); - prs_uint32("string length", ps, depth, &x ); - prs_uint32("pointer", ps, depth, &useless_ptr); + if(!prs_uint32("string length", ps, depth, &x )) + return False; + if(!prs_uint32("pointer", ps, depth, &useless_ptr)) + return False; /*prs_align(ps);*/ } @@ -353,17 +392,22 @@ BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_debug(ps, depth, desc, "smb_io_notify_info_data"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; + isvalue=data->enc_type; if (isvalue==False) { /* length of string in unicode include \0 */ x=data->notify_data.data.length+1; - prs_uint32("string length", ps, depth, &x ); - prs_uint16s(True,"string",ps,depth,data->notify_data.data.string,x); + if(!prs_uint32("string length", ps, depth, &x )) + return False; + if(!prs_uint16s(True,"string",ps,depth,data->notify_data.data.string,x)) + return False; } - prs_align(ps); + if(!prs_align(ps)) + return False; return True; } @@ -381,20 +425,26 @@ static BOOL smb_io_notify_info(char *desc, SPOOL_NOTIFY_INFO *info, prs_struct * if(!prs_align(ps)) return False; - prs_uint32("count", ps, depth, &(info->count)); - prs_uint32("version", ps, depth, &(info->version)); - prs_uint32("flags", ps, depth, &(info->flags)); - prs_uint32("count", ps, depth, &(info->count)); + if(!prs_uint32("count", ps, depth, &(info->count))) + return False; + if(!prs_uint32("version", ps, depth, &(info->version))) + return False; + if(!prs_uint32("flags", ps, depth, &(info->flags))) + return False; + if(!prs_uint32("count", ps, depth, &(info->count))) + return False; for (i=0;i<info->count;i++) { - smb_io_notify_info_data(desc, &(info->data[i]), ps, depth); + if(!smb_io_notify_info_data(desc, &(info->data[i]), ps, depth)) + return False; } /* now do the strings at the end of the stream */ for (i=0;i<info->count;i++) { - smb_io_notify_info_data_strings(desc, &(info->data[i]), ps, depth); + if(!smb_io_notify_info_data_strings(desc, &(info->data[i]), ps, depth)) + return False; } return True; @@ -550,6 +600,8 @@ static BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE { if (UNMARSHALLING(ps)) { devmode->private=(uint8 *)malloc(devmode->driverextra*sizeof(uint8)); + if(devmode->private == NULL) + return False; DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for private\n",devmode->driverextra)); } @@ -592,6 +644,8 @@ static BOOL spoolss_io_devmode_cont(char *desc, DEVMODE_CTR *dm_c, prs_struct *p if (UNMARSHALLING(ps)) { DEBUG(9,("Allocating memory for spoolss_io_devmode\n")); dm_c->devmode=(DEVICEMODE *)malloc(sizeof(DEVICEMODE)); + if(dm_c->devmode == NULL) + return False; ZERO_STRUCTP(dm_c->devmode); } @@ -637,7 +691,7 @@ static BOOL spoolss_io_printer_default(char *desc, PRINTER_DEFAULT *pd, prs_stru * init a structure. ********************************************************************/ BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u, fstring printername, fstring datatype, - uint32 access_required, fstring cli_name, fstring user_name) + uint32 access_required, fstring clientname, fstring user_name) { DEBUG(5,("make_spoolss_q_open_printer_ex\n")); q_u->printername_ptr = (printername!=NULL)?1:0; @@ -655,14 +709,14 @@ BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u, fstring printe q_u->user_switch=1; q_u->user_ctr.level=1; q_u->user_ctr.ptr=1; - q_u->user_ctr.user1.size=strlen(cli_name)+strlen(user_name)+8; - q_u->user_ctr.user1.client_name_ptr = (cli_name!=NULL)?1:0; + q_u->user_ctr.user1.size=strlen(clientname)+strlen(user_name)+8; + q_u->user_ctr.user1.client_name_ptr = (clientname!=NULL)?1:0; q_u->user_ctr.user1.user_name_ptr = (user_name!=NULL)?1:0; q_u->user_ctr.user1.build=1381; q_u->user_ctr.user1.major=2; q_u->user_ctr.user1.minor=0; q_u->user_ctr.user1.processor=0; - init_unistr2(&(q_u->user_ctr.user1.client_name), cli_name, strlen(cli_name)); + init_unistr2(&(q_u->user_ctr.user1.client_name), clientname, strlen(clientname)); init_unistr2(&(q_u->user_ctr.user1.user_name), user_name, strlen(user_name)); return True; @@ -873,11 +927,14 @@ BOOL spoolss_io_q_startdocprinter(char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_ prs_debug(ps, depth, desc, "spoolss_io_q_startdocprinter"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; - smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth); + if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth)) + return False; - smb_io_doc_info_container("",&(q_u->doc_info_container), ps, depth); + if(!smb_io_doc_info_container("",&(q_u->doc_info_container), ps, depth)) + return False; return True; } @@ -890,8 +947,10 @@ BOOL spoolss_io_r_startdocprinter(char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_ { prs_debug(ps, depth, desc, "spoolss_io_r_startdocprinter"); depth++; - prs_uint32("jobid", ps, depth, &(r_u->jobid)); - prs_uint32("status", ps, depth, &(r_u->status)); + if(!prs_uint32("jobid", ps, depth, &(r_u->jobid))) + return False; + if(!prs_uint32("status", ps, depth, &(r_u->status))) + return False; return True; } @@ -907,9 +966,11 @@ BOOL spoolss_io_q_enddocprinter(char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_stru prs_debug(ps, depth, desc, "spoolss_io_q_enddocprinter"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; - smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth); + if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth)) + return False; return True; } @@ -922,7 +983,8 @@ BOOL spoolss_io_r_enddocprinter(char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_stru { prs_debug(ps, depth, desc, "spoolss_io_r_enddocprinter"); depth++; - prs_uint32("status", ps, depth, &(r_u->status)); + if(!prs_uint32("status", ps, depth, &(r_u->status))) + return False; return True; } @@ -938,9 +1000,11 @@ BOOL spoolss_io_q_startpageprinter(char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, pr prs_debug(ps, depth, desc, "spoolss_io_q_startpageprinter"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; - smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth); + if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth)) + return False; return True; } @@ -953,7 +1017,8 @@ BOOL spoolss_io_r_startpageprinter(char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, pr { prs_debug(ps, depth, desc, "spoolss_io_r_startpageprinter"); depth++; - prs_uint32("status", ps, depth, &(r_u->status)); + if(!prs_uint32("status", ps, depth, &(r_u->status))) + return False; return True; } @@ -969,9 +1034,11 @@ BOOL spoolss_io_q_endpageprinter(char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_st prs_debug(ps, depth, desc, "spoolss_io_q_endpageprinter"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; - smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth); + if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth)) + return False; return True; } @@ -984,7 +1051,8 @@ BOOL spoolss_io_r_endpageprinter(char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_st { prs_debug(ps, depth, desc, "spoolss_io_r_endpageprinter"); depth++; - prs_uint32("status", ps, depth, &(r_u->status)); + if(!prs_uint32("status", ps, depth, &(r_u->status))) + return False; return True; } @@ -1000,18 +1068,26 @@ BOOL spoolss_io_q_writeprinter(char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct prs_debug(ps, depth, desc, "spoolss_io_q_writeprinter"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; - smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth); - prs_uint32("buffer_size", ps, depth, &(q_u->buffer_size)); + if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth)) + return False; + if(!prs_uint32("buffer_size", ps, depth, &(q_u->buffer_size))) + return False; if (q_u->buffer_size!=0) { q_u->buffer=(uint8 *)malloc(q_u->buffer_size*sizeof(uint8)); - prs_uint8s(True, "buffer", ps, depth, q_u->buffer, q_u->buffer_size); + if(q_u->buffer == NULL) + return False; + if(!prs_uint8s(True, "buffer", ps, depth, q_u->buffer, q_u->buffer_size)) + return False; } - prs_align(ps); - prs_uint32("buffer_size2", ps, depth, &(q_u->buffer_size2)); + if(!prs_align(ps)) + return False; + if(!prs_uint32("buffer_size2", ps, depth, &(q_u->buffer_size2))) + return False; return True; } @@ -1024,8 +1100,10 @@ BOOL spoolss_io_r_writeprinter(char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct { prs_debug(ps, depth, desc, "spoolss_io_r_writeprinter"); depth++; - prs_uint32("buffer_written", ps, depth, &(r_u->buffer_written)); - prs_uint32("status", ps, depth, &(r_u->status)); + if(!prs_uint32("buffer_written", ps, depth, &(r_u->buffer_written))) + return False; + if(!prs_uint32("status", ps, depth, &(r_u->status))) + return False; return True; } @@ -1149,13 +1227,20 @@ BOOL spoolss_io_r_rfnpcnex(char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, in } /******************************************************************* + * return the length of a uint16 (obvious, but the code is clean) + ********************************************************************/ +static uint32 size_of_uint16(uint16 *value) +{ + return (sizeof(*value)); +} + +/******************************************************************* * return the length of a uint32 (obvious, but the code is clean) ********************************************************************/ static uint32 size_of_uint32(uint32 *value) { return (sizeof(*value)); } - /******************************************************************* * return the length of a UNICODE string in number of char, includes: * - the leading zero @@ -1181,7 +1266,7 @@ static uint32 size_of_device_mode(DEVICEMODE *devmode) if (devmode==NULL) return (4); else - return (0xDC+4); + return (4+devmode->size+devmode->driverextra); } /******************************************************************* @@ -1275,39 +1360,49 @@ static BOOL new_smb_io_relstr(char *desc, NEW_BUFFER *buffer, int depth, UNISTR /******************************************************************* - * write a array UNICODE strings and its relative pointer. + * write a array of UNICODE strings and its relative pointer. * used by 2 RPC structs ********************************************************************/ -static BOOL new_smb_io_relarraystr(char *desc, NEW_BUFFER *buffer, int depth, UNISTR ***string) +static BOOL new_smb_io_relarraystr(char *desc, NEW_BUFFER *buffer, int depth, uint16 **string) { + UNISTR chaine; + prs_struct *ps=&(buffer->prs); if (MARSHALLING(ps)) { uint32 struct_offset = prs_offset(ps); uint32 relative_offset; - int i=0; - - while ( (*string)[i]!=0x0000 ) - i++; - i--; - - /* count the ending NULL of the array */ + uint16 *p; + uint16 *q; + uint16 zero=0; + p=*string; + q=*string; + + /* first write the last 0 */ buffer->string_at_end -= 2; + prs_set_offset(ps, buffer->string_at_end); + + if(!prs_uint16("leading zero", ps, depth, &zero)) + return False; - /* jfm: FIXME: write a (uint16) 0 for the ending NULL */ - do - { - buffer->string_at_end -= 2*(str_len_uni((*string)[i])+1); + { + while (*q!=0) + q++; + + memcpy(chaine.buffer, p, (q-p+1)*sizeof(uint16)); + + buffer->string_at_end -= (q-p+1)*sizeof(uint16); + prs_set_offset(ps, buffer->string_at_end); /* write the string */ - if (!spoolss_smb_io_unistr(desc, (*string)[i], ps, depth)) + if (!spoolss_smb_io_unistr(desc, &chaine, ps, depth)) return False; - - i--; - } - while (i>=0); + q++; + p=q; + + } while (*p!=0); /* end on the last leading 0 */ prs_set_offset(ps, struct_offset); @@ -1318,22 +1413,32 @@ static BOOL new_smb_io_relarraystr(char *desc, NEW_BUFFER *buffer, int depth, UN } else { uint32 old_offset; + uint16 *chaine2=NULL; + int l_chaine=0; + int l_chaine2=0; + *string=NULL; + /* read the offset */ if (!prs_uint32("offset", ps, depth, &(buffer->string_at_end))) return False; old_offset = prs_offset(ps); - prs_set_offset(ps, buffer->string_at_end); - - /* read the string */ - - /* jfm: FIXME: alloc memory and read all the strings until the string is NULL */ + prs_set_offset(ps, buffer->string_at_end + buffer->struct_start); + + do { + if (!spoolss_smb_io_unistr(desc, &chaine, ps, depth)) + return False; + + l_chaine=str_len_uni(&chaine); + chaine2=(uint16 *)Realloc(chaine2, (l_chaine2+l_chaine+1)*sizeof(uint16)); + memcpy(chaine2+l_chaine2, chaine.buffer, (l_chaine+1)*sizeof(uint16)); + l_chaine2+=l_chaine+1; + + } while(l_chaine!=0); + + *string=chaine2; -/* - if (!spoolss_smb_io_unistr(desc, string, ps, depth)) - return False; -*/ prs_set_offset(ps, old_offset); } return True; @@ -1409,26 +1514,36 @@ BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *i if(!prs_uint32("cjobs", ps, depth, &info->cjobs)) return False; - if(!prs_uint32("attributes", ps, depth, &info->attributes)) + if(!prs_uint32("total_jobs", ps, depth, &info->total_jobs)) + return False; + if(!prs_uint32("total_bytes", ps, depth, &info->total_bytes)) return False; - if(!prs_uint32("unknown0", ps, depth, &info->unknown0)) + if(!prs_uint16("year", ps, depth, &info->year)) + return False; + if(!prs_uint16("month", ps, depth, &info->month)) + return False; + if(!prs_uint16("dayofweek", ps, depth, &info->dayofweek)) + return False; + if(!prs_uint16("day", ps, depth, &info->day)) return False; - if(!prs_uint32("unknown1", ps, depth, &info->unknown1)) + if(!prs_uint16("hour", ps, depth, &info->hour)) return False; - if(!prs_uint32("unknown2", ps, depth, &info->unknown2)) + if(!prs_uint16("minute", ps, depth, &info->minute)) return False; - if(!prs_uint32("unknown3", ps, depth, &info->unknown3)) + if(!prs_uint16("second", ps, depth, &info->second)) return False; - if(!prs_uint32("unknown4", ps, depth, &info->unknown4)) + if(!prs_uint16("milliseconds", ps, depth, &info->milliseconds)) return False; - if(!prs_uint32("unknown5", ps, depth, &info->unknown5)) + + if(!prs_uint32("global_counter", ps, depth, &info->global_counter)) return False; - if(!prs_uint32("unknown6", ps, depth, &info->unknown6)) + if(!prs_uint32("total_pages", ps, depth, &info->total_pages)) return False; - if(!prs_uint16("majorversion", ps, depth, &info->majorversion)) + + if(!prs_uint16("major_version", ps, depth, &info->major_version)) return False; - if(!prs_uint16("buildversion", ps, depth, &info->buildversion)) + if(!prs_uint16("build_version", ps, depth, &info->build_version)) return False; if(!prs_uint32("unknown7", ps, depth, &info->unknown7)) return False; @@ -1436,11 +1551,11 @@ BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *i return False; if(!prs_uint32("unknown9", ps, depth, &info->unknown9)) return False; - if(!prs_uint32("unknown10", ps, depth, &info->unknown10)) + if(!prs_uint32("session_counter", ps, depth, &info->session_counter)) return False; if(!prs_uint32("unknown11", ps, depth, &info->unknown11)) return False; - if(!prs_uint32("unknown12", ps, depth, &info->unknown12)) + if(!prs_uint32("printer_errors", ps, depth, &info->printer_errors)) return False; if(!prs_uint32("unknown13", ps, depth, &info->unknown13)) return False; @@ -1450,7 +1565,7 @@ BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *i return False; if(!prs_uint32("unknown16", ps, depth, &info->unknown16)) return False; - if(!prs_uint32("unknown17", ps, depth, &info->unknown17)) + if(!prs_uint32("change_id", ps, depth, &info->change_id)) return False; if(!prs_uint32("unknown18", ps, depth, &info->unknown18)) return False; @@ -1458,11 +1573,23 @@ BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *i return False; if(!prs_uint32("unknown20", ps, depth, &info->unknown20)) return False; - if(!prs_uint32("unknown21", ps, depth, &info->unknown21)) + if(!prs_uint32("c_setprinter", ps, depth, &info->c_setprinter)) return False; if(!prs_uint16("unknown22", ps, depth, &info->unknown22)) return False; - if(!prs_uint32("unknown23", ps, depth, &info->unknown23)) + if(!prs_uint16("unknown23", ps, depth, &info->unknown23)) + return False; + if(!prs_uint16("unknown24", ps, depth, &info->unknown24)) + return False; + if(!prs_uint16("unknown25", ps, depth, &info->unknown25)) + return False; + if(!prs_uint16("unknown26", ps, depth, &info->unknown26)) + return False; + if(!prs_uint16("unknown27", ps, depth, &info->unknown27)) + return False; + if(!prs_uint16("unknown28", ps, depth, &info->unknown28)) + return False; + if(!prs_uint16("unknown29", ps, depth, &info->unknown29)) return False; return True; @@ -1908,7 +2035,7 @@ BOOL new_smb_io_driverdir_1(char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 * buffer->struct_start=prs_offset(ps); - if(!new_smb_io_relstr("name", buffer, depth, &info->name)) + if (!spoolss_smb_io_unistr(desc, &info->name, ps, depth)) return False; return True; @@ -2038,13 +2165,53 @@ uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info) { int size=0; - size+=24*4; - size+=6; + size+=size_of_relative_string( &info->printername ); + size+=size_of_relative_string( &info->servername ); + + size+=size_of_uint32( &info->cjobs); + size+=size_of_uint32( &info->total_jobs); + size+=size_of_uint32( &info->total_bytes); + + size+=size_of_uint16( &info->year); + size+=size_of_uint16( &info->month); + size+=size_of_uint16( &info->dayofweek); + size+=size_of_uint16( &info->day); + size+=size_of_uint16( &info->hour); + size+=size_of_uint16( &info->minute); + size+=size_of_uint16( &info->second); + size+=size_of_uint16( &info->milliseconds); + + size+=size_of_uint32( &info->global_counter); + size+=size_of_uint32( &info->total_pages); + + size+=size_of_uint16( &info->major_version); + size+=size_of_uint16( &info->build_version); + + size+=size_of_uint32( &info->unknown7); + size+=size_of_uint32( &info->unknown8); + size+=size_of_uint32( &info->unknown9); + size+=size_of_uint32( &info->session_counter); + size+=size_of_uint32( &info->unknown11); + size+=size_of_uint32( &info->printer_errors); + size+=size_of_uint32( &info->unknown13); + size+=size_of_uint32( &info->unknown14); + size+=size_of_uint32( &info->unknown15); + size+=size_of_uint32( &info->unknown16); + size+=size_of_uint32( &info->change_id); + size+=size_of_uint32( &info->unknown18); + size+=size_of_uint32( &info->status); + size+=size_of_uint32( &info->unknown20); + size+=size_of_uint32( &info->c_setprinter); + + size+=size_of_uint16( &info->unknown22); + size+=size_of_uint16( &info->unknown23); + size+=size_of_uint16( &info->unknown24); + size+=size_of_uint16( &info->unknown25); + size+=size_of_uint16( &info->unknown26); + size+=size_of_uint16( &info->unknown27); + size+=size_of_uint16( &info->unknown28); + size+=size_of_uint16( &info->unknown29); - size+=size_of_uint32( &(info->attributes) ); - size+=size_of_relative_string( &(info->printername) ); - size+=size_of_relative_string( &(info->servername) ); - return size; } @@ -2071,30 +2238,30 @@ uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info) int size=0; size+=4; /* the security descriptor */ - size+=info->devmode->size+4; /* size of the devmode and the ptr */ - size+=info->devmode->driverextra; /* if a devmode->private section exists, add its size */ - size+=size_of_relative_string( &(info->servername) ); - size+=size_of_relative_string( &(info->printername) ); - size+=size_of_relative_string( &(info->sharename) ); - size+=size_of_relative_string( &(info->portname) ); - size+=size_of_relative_string( &(info->drivername) ); - size+=size_of_relative_string( &(info->comment) ); - size+=size_of_relative_string( &(info->location) ); + size+=size_of_device_mode( info->devmode ); - size+=size_of_relative_string( &(info->sepfile) ); - size+=size_of_relative_string( &(info->printprocessor) ); - size+=size_of_relative_string( &(info->datatype) ); - size+=size_of_relative_string( &(info->parameters) ); - - size+=size_of_uint32( &(info->attributes) ); - size+=size_of_uint32( &(info->priority) ); - size+=size_of_uint32( &(info->defaultpriority) ); - size+=size_of_uint32( &(info->starttime) ); - size+=size_of_uint32( &(info->untiltime) ); - size+=size_of_uint32( &(info->status) ); - size+=size_of_uint32( &(info->cjobs) ); - size+=size_of_uint32( &(info->averageppm) ); + size+=size_of_relative_string( &info->servername ); + size+=size_of_relative_string( &info->printername ); + size+=size_of_relative_string( &info->sharename ); + size+=size_of_relative_string( &info->portname ); + size+=size_of_relative_string( &info->drivername ); + size+=size_of_relative_string( &info->comment ); + size+=size_of_relative_string( &info->location ); + + size+=size_of_relative_string( &info->sepfile ); + size+=size_of_relative_string( &info->printprocessor ); + size+=size_of_relative_string( &info->datatype ); + size+=size_of_relative_string( &info->parameters ); + + size+=size_of_uint32( &info->attributes ); + size+=size_of_uint32( &info->priority ); + size+=size_of_uint32( &info->defaultpriority ); + size+=size_of_uint32( &info->starttime ); + size+=size_of_uint32( &info->untiltime ); + size+=size_of_uint32( &info->status ); + size+=size_of_uint32( &info->cjobs ); + size+=size_of_uint32( &info->averageppm ); return size; } @@ -2104,7 +2271,7 @@ return the size required by a struct in the stream uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info) { int size=0; - size+=size_of_relative_string( &(info->name) ); + size+=size_of_relative_string( &info->name ); return size; } @@ -2115,12 +2282,12 @@ return the size required by a struct in the stream uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info) { int size=0; - size+=size_of_uint32( &(info->version) ); - size+=size_of_relative_string( &(info->name) ); - size+=size_of_relative_string( &(info->architecture) ); - size+=size_of_relative_string( &(info->driverpath) ); - size+=size_of_relative_string( &(info->datafile) ); - size+=size_of_relative_string( &(info->configfile) ); + size+=size_of_uint32( &info->version ); + size+=size_of_relative_string( &info->name ); + size+=size_of_relative_string( &info->architecture ); + size+=size_of_relative_string( &info->driverpath ); + size+=size_of_relative_string( &info->datafile ); + size+=size_of_relative_string( &info->configfile ); return size; } @@ -2131,26 +2298,24 @@ return the size required by a struct in the stream uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info) { int size=0; - UNISTR **string; + uint16 *string; int i=0; - size+=size_of_uint32( &(info->version) ); - size+=size_of_relative_string( &(info->name) ); - size+=size_of_relative_string( &(info->architecture) ); - size+=size_of_relative_string( &(info->driverpath) ); - size+=size_of_relative_string( &(info->datafile) ); - size+=size_of_relative_string( &(info->configfile) ); - size+=size_of_relative_string( &(info->helpfile) ); - size+=size_of_relative_string( &(info->monitorname) ); - size+=size_of_relative_string( &(info->defaultdatatype) ); + size+=size_of_uint32( &info->version ); + size+=size_of_relative_string( &info->name ); + size+=size_of_relative_string( &info->architecture ); + size+=size_of_relative_string( &info->driverpath ); + size+=size_of_relative_string( &info->datafile ); + size+=size_of_relative_string( &info->configfile ); + size+=size_of_relative_string( &info->helpfile ); + size+=size_of_relative_string( &info->monitorname ); + size+=size_of_relative_string( &info->defaultdatatype ); string=info->dependentfiles; - while ( (string)[i]!=0x0000 ) - { - size+=2*(1+ str_len_uni( string[i] ) ); - i++; - } + for (i=0; (string[i]!=0x0000) || (string[i+1]!=0x0000); i++); + + size+=2*i; size+=6; return size; @@ -2162,19 +2327,19 @@ return the size required by a struct in the stream uint32 spoolss_size_job_info_1(JOB_INFO_1 *info) { int size=0; - size+=size_of_uint32( &(info->jobid) ); - size+=size_of_relative_string( &(info->printername) ); - size+=size_of_relative_string( &(info->machinename) ); - size+=size_of_relative_string( &(info->username) ); - size+=size_of_relative_string( &(info->document) ); - size+=size_of_relative_string( &(info->datatype) ); - size+=size_of_relative_string( &(info->text_status) ); - size+=size_of_uint32( &(info->status) ); - size+=size_of_uint32( &(info->priority) ); - size+=size_of_uint32( &(info->position) ); - size+=size_of_uint32( &(info->totalpages) ); - size+=size_of_uint32( &(info->pagesprinted) ); - size+=size_of_systemtime( &(info->submitted) ); + size+=size_of_uint32( &info->jobid ); + size+=size_of_relative_string( &info->printername ); + size+=size_of_relative_string( &info->machinename ); + size+=size_of_relative_string( &info->username ); + size+=size_of_relative_string( &info->document ); + size+=size_of_relative_string( &info->datatype ); + size+=size_of_relative_string( &info->text_status ); + size+=size_of_uint32( &info->status ); + size+=size_of_uint32( &info->priority ); + size+=size_of_uint32( &info->position ); + size+=size_of_uint32( &info->totalpages ); + size+=size_of_uint32( &info->pagesprinted ); + size+=size_of_systemtime( &info->submitted ); return size; } @@ -2188,29 +2353,29 @@ uint32 spoolss_size_job_info_2(JOB_INFO_2 *info) size+=4; /* size of sec desc ptr */ - size+=size_of_uint32( &(info->jobid) ); - size+=size_of_relative_string( &(info->printername) ); - size+=size_of_relative_string( &(info->machinename) ); - size+=size_of_relative_string( &(info->username) ); - size+=size_of_relative_string( &(info->document) ); - size+=size_of_relative_string( &(info->notifyname) ); - size+=size_of_relative_string( &(info->datatype) ); - size+=size_of_relative_string( &(info->printprocessor) ); - size+=size_of_relative_string( &(info->parameters) ); - size+=size_of_relative_string( &(info->drivername) ); + size+=size_of_uint32( &info->jobid ); + size+=size_of_relative_string( &info->printername ); + size+=size_of_relative_string( &info->machinename ); + size+=size_of_relative_string( &info->username ); + size+=size_of_relative_string( &info->document ); + size+=size_of_relative_string( &info->notifyname ); + size+=size_of_relative_string( &info->datatype ); + size+=size_of_relative_string( &info->printprocessor ); + size+=size_of_relative_string( &info->parameters ); + size+=size_of_relative_string( &info->drivername ); size+=size_of_device_mode( info->devmode ); - size+=size_of_relative_string( &(info->text_status) ); + size+=size_of_relative_string( &info->text_status ); /* SEC_DESC sec_desc;*/ - size+=size_of_uint32( &(info->status) ); - size+=size_of_uint32( &(info->priority) ); - size+=size_of_uint32( &(info->position) ); - size+=size_of_uint32( &(info->starttime) ); - size+=size_of_uint32( &(info->untiltime) ); - size+=size_of_uint32( &(info->totalpages) ); - size+=size_of_uint32( &(info->size) ); - size+=size_of_systemtime( &(info->submitted) ); - size+=size_of_uint32( &(info->timeelapsed) ); - size+=size_of_uint32( &(info->pagesprinted) ); + size+=size_of_uint32( &info->status ); + size+=size_of_uint32( &info->priority ); + size+=size_of_uint32( &info->position ); + size+=size_of_uint32( &info->starttime ); + size+=size_of_uint32( &info->untiltime ); + size+=size_of_uint32( &info->totalpages ); + size+=size_of_uint32( &info->size ); + size+=size_of_systemtime( &info->submitted ); + size+=size_of_uint32( &info->timeelapsed ); + size+=size_of_uint32( &info->pagesprinted ); return size; } @@ -2253,7 +2418,9 @@ uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info) { int size=0; - size+=size_of_relative_string( &info->name ); + size=str_len_uni(&info->name); /* the string length */ + size=size+1; /* add the leading zero */ + size=size*2; /* convert in char */ return size; } @@ -2322,6 +2489,33 @@ uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info) } /******************************************************************* + * init a structure. + ********************************************************************/ +BOOL make_spoolss_q_getprinterdriver2(SPOOL_Q_GETPRINTERDRIVER2 *q_u, + const POLICY_HND *hnd, fstring architecture, + uint32 level, uint32 clientmajor, uint32 clientminor, + NEW_BUFFER *buffer, uint32 offered) +{ + if (q_u == NULL) + { + return False; + } + + memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); + + init_buf_unistr2(&q_u->architecture, &q_u->architecture_ptr, architecture); + + q_u->level=level; + q_u->clientmajorversion=clientmajor; + q_u->clientminorversion=clientminor; + + q_u->buffer=buffer; + q_u->offered=offered; + + return True; +} + +/******************************************************************* * read a structure. * called from spoolss_getprinterdriver2 (srv_spoolss.c) ********************************************************************/ @@ -2354,7 +2548,9 @@ BOOL spoolss_io_q_getprinterdriver2(char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, if(!prs_uint32("offered", ps, depth, &q_u->offered)) return False; - if(!prs_uint32("unknown", ps, depth, &q_u->unknown)) + if(!prs_uint32("clientmajorversion", ps, depth, &q_u->clientmajorversion)) + return False; + if(!prs_uint32("clientminorversion", ps, depth, &q_u->clientminorversion)) return False; return True; @@ -2379,9 +2575,9 @@ BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, return False; if (!prs_uint32("needed", ps, depth, &r_u->needed)) return False; - if (!prs_uint32("unknown0", ps, depth, &r_u->unknown0)) + if (!prs_uint32("servermajorversion", ps, depth, &r_u->servermajorversion)) return False; - if (!prs_uint32("unknown1", ps, depth, &r_u->unknown1)) + if (!prs_uint32("serverminorversion", ps, depth, &r_u->serverminorversion)) return False; if (!prs_uint32("status", ps, depth, &r_u->status)) return False; @@ -2530,15 +2726,36 @@ BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps } /******************************************************************* + * init a structure. + ********************************************************************/ +BOOL make_spoolss_q_getprinter(SPOOL_Q_GETPRINTER *q_u, const POLICY_HND *hnd, uint32 level, + NEW_BUFFER *buffer, uint32 offered) +{ + if (q_u == NULL) + { + return False; + } + memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); + + q_u->level=level; + q_u->buffer=buffer; + q_u->offered=offered; + + return True; +} + +/******************************************************************* ********************************************************************/ BOOL spoolss_io_r_setprinter(char *desc, SPOOL_R_SETPRINTER *r_u, prs_struct *ps, int depth) { prs_debug(ps, depth, desc, "spoolss_io_r_setprinter"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; - prs_uint32("status", ps, depth, &(r_u->status)); + if(!prs_uint32("status", ps, depth, &(r_u->status))) + return False; return True; } @@ -2564,8 +2781,10 @@ BOOL spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth)) return False; - prs_uint32("security.size_of_buffer", ps, depth, &q_u->security.size_of_buffer); - prs_uint32("security.data", ps, depth, &q_u->security.data); + if(!prs_uint32("security.size_of_buffer", ps, depth, &q_u->security.size_of_buffer)) + return False; + if(!prs_uint32("security.data", ps, depth, &q_u->security.data)) + return False; if(!prs_uint32("command", ps, depth, &q_u->command)) return False; @@ -2580,9 +2799,11 @@ BOOL spoolss_io_r_fcpn(char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth) prs_debug(ps, depth, desc, "spoolss_io_r_fcpn"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; - prs_uint32("status", ps, depth, &(r_u->status)); + if(!prs_uint32("status", ps, depth, &(r_u->status))) + return False; return True; } @@ -2595,9 +2816,11 @@ BOOL spoolss_io_q_fcpn(char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth) prs_debug(ps, depth, desc, "spoolss_io_q_fcpn"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; - smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth); + if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth)) + return False; return True; } @@ -2733,9 +2956,11 @@ BOOL spoolss_io_r_schedulejob(char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct * prs_debug(ps, depth, desc, "spoolss_io_r_schedulejob"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; - prs_uint32("status", ps, depth, &(r_u->status)); + if(!prs_uint32("status", ps, depth, &(r_u->status))) + return False; return True; } @@ -2747,10 +2972,13 @@ BOOL spoolss_io_q_schedulejob(char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct * prs_debug(ps, depth, desc, "spoolss_io_q_schedulejob"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; - smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth); - prs_uint32("jobid", ps, depth, &(q_u->jobid)); + if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth)) + return False; + if(!prs_uint32("jobid", ps, depth, &(q_u->jobid))) + return False; return True; } @@ -2762,9 +2990,11 @@ BOOL spoolss_io_r_setjob(char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int de prs_debug(ps, depth, desc, "spoolss_io_r_setjob"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; - prs_uint32("status", ps, depth, &(r_u->status)); + if(!prs_uint32("status", ps, depth, &(r_u->status))) + return False; return True; } @@ -2776,16 +3006,21 @@ BOOL spoolss_io_q_setjob(char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int de prs_debug(ps, depth, desc, "spoolss_io_q_setjob"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; - smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth); - prs_uint32("jobid", ps, depth, &(q_u->jobid)); + if(!smb_io_pol_hnd("printer handle",&(q_u->handle),ps,depth)) + return False; + if(!prs_uint32("jobid", ps, depth, &(q_u->jobid))) + return False; /* * level is usually 0. If (level!=0) then I'm in trouble ! * I will try to generate setjob command with level!=0, one day. */ - prs_uint32("level", ps, depth, &(q_u->level)); - prs_uint32("command", ps, depth, &(q_u->command)); + if(!prs_uint32("level", ps, depth, &(q_u->level))) + return False; + if(!prs_uint32("command", ps, depth, &(q_u->command))) + return False; return True; } @@ -2977,6 +3212,36 @@ BOOL spoolss_io_q_enumports(char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, } /******************************************************************* + Parse a SPOOL_PRINTER_INFO_LEVEL_1 structure. +********************************************************************/ +BOOL spool_io_printer_info_level_1(char *desc, SPOOL_PRINTER_INFO_LEVEL_1 *il, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spool_io_printer_info_level_1"); + depth++; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("flags", ps, depth, &il->flags)) + return False; + if(!prs_uint32("description_ptr", ps, depth, &il->description_ptr)) + return False; + if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr)) + return False; + if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr)) + return False; + + if(!smb_io_unistr2("description", &il->description, il->description_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth)) + return False; + + return True; +} + +/******************************************************************* Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure. ********************************************************************/ BOOL spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 *il, prs_struct *ps, int depth) @@ -3073,8 +3338,10 @@ BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_s /* if no struct inside just return */ if (il->info_ptr==0) { - if (UNMARSHALLING(ps)) + if (UNMARSHALLING(ps)) { + il->info_1=NULL; il->info_2=NULL; + } return True; } @@ -3089,9 +3356,21 @@ BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_s * level 2 is used by addprinter * and by setprinter when updating printer's info */ + case 1: + if (UNMARSHALLING(ps)) { + il->info_1=(SPOOL_PRINTER_INFO_LEVEL_1 *)malloc(sizeof(SPOOL_PRINTER_INFO_LEVEL_1)); + if(il->info_1 == NULL) + return False; + } + if (!spool_io_printer_info_level_1("", il->info_1, ps, depth)) + return False; + break; case 2: - if (UNMARSHALLING(ps)) + if (UNMARSHALLING(ps)) { il->info_2=(SPOOL_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(SPOOL_PRINTER_INFO_LEVEL_2)); + if(il->info_2 == NULL) + return False; + } if (!spool_io_printer_info_level_2("", il->info_2, ps, depth)) return False; break; @@ -3163,9 +3442,11 @@ BOOL spoolss_io_r_addprinterex(char *desc, SPOOL_R_ADDPRINTEREX *r_u, prs_struct prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex"); depth++; - smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth); + if(!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth)) + return False; - prs_uint32("status", ps, depth, &(r_u->status)); + if(!prs_uint32("status", ps, depth, &(r_u->status))) + return False; return True; } @@ -3183,6 +3464,8 @@ BOOL spool_io_printer_driver_info_level_3(char *desc, SPOOL_PRINTER_DRIVER_INFO_ /* reading */ if (UNMARSHALLING(ps)) { il=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *)malloc(sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3)); + if(il == NULL) + return False; ZERO_STRUCTP(il); *q_u=il; } @@ -3274,7 +3557,9 @@ BOOL uniarray_2_ascarray(BUFFER5 *buf5, char ***ar) src=buf5->buffer; string=(char *)malloc(sizeof(char)*buf5->buf_len); - + if(string == NULL) + return False; + destend = string + buf5->buf_len; dest=string; @@ -3285,6 +3570,8 @@ BOOL uniarray_2_ascarray(BUFFER5 *buf5, char ***ar) /* that ugly for the first one but that's working */ array=(char **)Realloc(array, sizeof(char *)*(i+1)); + if(array == NULL) + return False; array[i++]=string; while ( n < buf5->buf_len ) @@ -3292,6 +3579,8 @@ BOOL uniarray_2_ascarray(BUFFER5 *buf5, char ***ar) if ( *(string++) == '\0' ) { array=(char **)Realloc(array, sizeof(char *)*(i+1)); + if(array == NULL) + return False; array[i++]=string; } n++; @@ -3315,10 +3604,11 @@ BOOL smb_io_unibuffer(char *desc, UNISTR2 *buffer, prs_struct *ps, int depth) buffer->undoc=0; buffer->uni_str_len=buffer->uni_max_len; - prs_uint32("buffer_size", ps, depth, &(buffer->uni_max_len)); - - prs_unistr2(True, "buffer ", ps, depth, buffer); + if(!prs_uint32("buffer_size", ps, depth, &(buffer->uni_max_len))) + return False; + if(!prs_unistr2(True, "buffer ", ps, depth, buffer)) + return False; return True; } @@ -3342,7 +3632,8 @@ BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LE switch (il->level) { case 3: - spool_io_printer_driver_info_level_3("", &(il->info_3), ps, depth); + if(!spool_io_printer_driver_info_level_3("", &(il->info_3), ps, depth)) + return False; break; } @@ -3401,6 +3692,8 @@ BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni, if (*asc==NULL) { *asc=(NT_PRINTER_DRIVER_INFO_LEVEL_3 *)malloc(sizeof(NT_PRINTER_DRIVER_INFO_LEVEL_3)); + if(*asc == NULL) + return False; ZERO_STRUCTP(*asc); } @@ -3436,15 +3729,26 @@ BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni, NT_PRINTER_INFO_LEVEL_2 **asc) { NT_PRINTER_INFO_LEVEL_2 *d; + NTTIME time_nt; + time_t time_unix; DEBUG(7,("Converting from UNICODE to ASCII\n")); + time_unix=time(NULL); if (*asc==NULL) { DEBUGADD(8,("allocating memory\n")); *asc=(NT_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(NT_PRINTER_INFO_LEVEL_2)); + if(*asc == NULL) + return False; ZERO_STRUCTP(*asc); + + /* we allocate memory iff called from + * addprinter(ex) so we can do one time stuff here. + */ + (*asc)->setuptime=time_unix; + } DEBUGADD(8,("start converting\n")); @@ -3458,17 +3762,21 @@ BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni, d->status=uni->status; d->cjobs=uni->cjobs; - unistr2_to_ascii(d->servername, &(uni->servername), sizeof(d->servername)-1); - unistr2_to_ascii(d->printername, &(uni->printername), sizeof(d->printername)-1); - unistr2_to_ascii(d->sharename, &(uni->sharename), sizeof(d->sharename)-1); - unistr2_to_ascii(d->portname, &(uni->portname), sizeof(d->portname)-1); - unistr2_to_ascii(d->drivername, &(uni->drivername), sizeof(d->drivername)-1); - unistr2_to_ascii(d->comment, &(uni->comment), sizeof(d->comment)-1); - unistr2_to_ascii(d->location, &(uni->location), sizeof(d->location)-1); - unistr2_to_ascii(d->sepfile, &(uni->sepfile), sizeof(d->sepfile)-1); - unistr2_to_ascii(d->printprocessor, &(uni->printprocessor), sizeof(d->printprocessor)-1); - unistr2_to_ascii(d->datatype, &(uni->datatype), sizeof(d->datatype)-1); - unistr2_to_ascii(d->parameters, &(uni->parameters), sizeof(d->parameters)-1); + unix_to_nt_time(&time_nt, time_unix); + d->changeid=time_nt.low; + + d->c_setprinter++; + + unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername)-1); + unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername)-1); + unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename)-1); + unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname)-1); + unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername)-1); + unistr2_to_ascii(d->location, &uni->location, sizeof(d->location)-1); + unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile)-1); + unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)-1); + unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype)-1); + unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters)-1); return True; } @@ -3811,15 +4119,21 @@ BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_st prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata"); depth++; - prs_align(ps); - smb_io_pol_hnd("printer handle", &(q_u->handle), ps, depth); - smb_io_unistr2("", &(q_u->value), True, ps, depth); + if(!prs_align(ps)) + return False; + if(!smb_io_pol_hnd("printer handle", &(q_u->handle), ps, depth)) + return False; + if(!smb_io_unistr2("", &(q_u->value), True, ps, depth)) + return False; - prs_align(ps); + if(!prs_align(ps)) + return False; - prs_uint32("type", ps, depth, &(q_u->type)); + if(!prs_uint32("type", ps, depth, &(q_u->type))) + return False; - prs_uint32("max_len", ps, depth, &(q_u->max_len)); + if(!prs_uint32("max_len", ps, depth, &(q_u->max_len))) + return False; switch (q_u->type) { @@ -3828,12 +4142,17 @@ BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_st case 0x4: case 0x7: q_u->data=(uint8 *)malloc(q_u->max_len * sizeof(uint8)); - prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len); - prs_align(ps); + if(q_u->data == NULL) + return False; + if(!prs_uint8s(False,"data", ps, depth, q_u->data, q_u->max_len)) + return False; + if(!prs_align(ps)) + return False; break; } - prs_uint32("real_len", ps, depth, &(q_u->real_len)); + if(!prs_uint32("real_len", ps, depth, &(q_u->real_len))) + return False; return True; } @@ -3845,8 +4164,10 @@ BOOL spoolss_io_r_setprinterdata(char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_st prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata"); depth++; - prs_align(ps); - prs_uint32("status", ps, depth, &(r_u->status)); + if(!prs_align(ps)) + return False; + if(!prs_uint32("status", ps, depth, &(r_u->status))) + return False; return True; } @@ -3861,6 +4182,8 @@ BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value, if (*param == NULL) { *param=(NT_PRINTER_PARAM *)malloc(sizeof(NT_PRINTER_PARAM)); + if(*param == NULL) + return False; ZERO_STRUCTP(*param); DEBUGADD(6,("Allocated a new PARAM struct\n")); } @@ -3873,6 +4196,8 @@ BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value, (*param)->data_len=len; (*param)->data=(uint8 *)malloc(len * sizeof(uint8)); + if((*param)->data == NULL) + return False; memcpy((*param)->data, data, len); @@ -3887,20 +4212,30 @@ static BOOL spoolss_io_addform(char *desc, FORM *f, uint32 ptr, prs_struct *ps, { prs_debug(ps, depth, desc, "spoolss_io_addform"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; if (ptr!=0) { - prs_uint32("flags", ps, depth, &(f->flags)); - prs_uint32("name_ptr", ps, depth, &(f->name_ptr)); - prs_uint32("size_x", ps, depth, &(f->size_x)); - prs_uint32("size_y", ps, depth, &(f->size_y)); - prs_uint32("left", ps, depth, &(f->left)); - prs_uint32("top", ps, depth, &(f->top)); - prs_uint32("right", ps, depth, &(f->right)); - prs_uint32("bottom", ps, depth, &(f->bottom)); - - smb_io_unistr2("", &(f->name), f->name_ptr, ps, depth); + if(!prs_uint32("flags", ps, depth, &(f->flags))) + return False; + if(!prs_uint32("name_ptr", ps, depth, &(f->name_ptr))) + return False; + if(!prs_uint32("size_x", ps, depth, &(f->size_x))) + return False; + if(!prs_uint32("size_y", ps, depth, &(f->size_y))) + return False; + if(!prs_uint32("left", ps, depth, &(f->left))) + return False; + if(!prs_uint32("top", ps, depth, &(f->top))) + return False; + if(!prs_uint32("right", ps, depth, &(f->right))) + return False; + if(!prs_uint32("bottom", ps, depth, &(f->bottom))) + return False; + + if(!smb_io_unistr2("", &(f->name), f->name_ptr, ps, depth)) + return False; } return True; @@ -3914,15 +4249,21 @@ BOOL spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int prs_debug(ps, depth, desc, "spoolss_io_q_addform"); depth++; - prs_align(ps); - smb_io_pol_hnd("printer handle", &(q_u->handle), ps, depth); - prs_uint32("level", ps, depth, &(q_u->level)); - prs_uint32("level2", ps, depth, &(q_u->level2)); + if(!prs_align(ps)) + return False; + if(!smb_io_pol_hnd("printer handle", &(q_u->handle), ps, depth)) + return False; + if(!prs_uint32("level", ps, depth, &(q_u->level))) + return False; + if(!prs_uint32("level2", ps, depth, &(q_u->level2))) + return False; if (q_u->level==1) { - prs_uint32("useless_ptr", ps, depth, &(useless_ptr)); - spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth); + if(!prs_uint32("useless_ptr", ps, depth, &(useless_ptr))) + return False; + if(!spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth)) + return False; } return True; @@ -3935,8 +4276,10 @@ BOOL spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int prs_debug(ps, depth, desc, "spoolss_io_r_addform"); depth++; - prs_align(ps); - prs_uint32("status", ps, depth, &(r_u->status)); + if(!prs_align(ps)) + return False; + if(!prs_uint32("status", ps, depth, &(r_u->status))) + return False; return True; } @@ -3949,19 +4292,27 @@ BOOL spoolss_io_q_setform(char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int prs_debug(ps, depth, desc, "spoolss_io_q_setform"); depth++; - prs_align(ps); - smb_io_pol_hnd("printer handle", &(q_u->handle), ps, depth); - smb_io_unistr2("", &(q_u->name), True, ps, depth); + if(!prs_align(ps)) + return False; + if(!smb_io_pol_hnd("printer handle", &(q_u->handle), ps, depth)) + return False; + if(!smb_io_unistr2("", &(q_u->name), True, ps, depth)) + return False; - prs_align(ps); + if(!prs_align(ps)) + return False; - prs_uint32("level", ps, depth, &(q_u->level)); - prs_uint32("level2", ps, depth, &(q_u->level2)); + if(!prs_uint32("level", ps, depth, &(q_u->level))) + return False; + if(!prs_uint32("level2", ps, depth, &(q_u->level2))) + return False; if (q_u->level==1) { - prs_uint32("useless_ptr", ps, depth, &(useless_ptr)); - spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth); + if(!prs_uint32("useless_ptr", ps, depth, &(useless_ptr))) + return False; + if(!spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth)) + return False; } return True; @@ -3974,8 +4325,10 @@ BOOL spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int prs_debug(ps, depth, desc, "spoolss_io_r_setform"); depth++; - prs_align(ps); - prs_uint32("status", ps, depth, &(r_u->status)); + if(!prs_align(ps)) + return False; + if(!prs_uint32("status", ps, depth, &(r_u->status))) + return False; return True; } diff --git a/source/rpc_server/srv_spoolss.c b/source/rpc_server/srv_spoolss.c index 1b19a7b2a36..08925afabff 100755 --- a/source/rpc_server/srv_spoolss.c +++ b/source/rpc_server/srv_spoolss.c @@ -320,9 +320,11 @@ static BOOL api_spoolss_getprinterdriver2(prs_struct *data, prs_struct *rdata) r_u.status = _spoolss_getprinterdriver2(&q_u.handle, &q_u.architecture, - q_u.level, q_u.unknown, r_u.buffer, + q_u.level, q_u.clientmajorversion, + q_u.clientminorversion, r_u.buffer, q_u.offered, &r_u.needed, - &r_u.unknown0, &r_u.unknown1); + &r_u.servermajorversion, + &r_u.serverminorversion); if (!spoolss_io_r_getprinterdriver2("", &r_u, rdata, 0)) { @@ -857,6 +859,19 @@ static BOOL api_spoolss_addprinterex(prs_struct *data, prs_struct *rdata) return False; } + if (q_u.info.info_ptr != 0) + { + switch (q_u.info.level) + { + case 1: + safe_free(q_u.info.info_1); + break; + case 2: + safe_free(q_u.info.info_2); + break; + } + } + return True; } diff --git a/source/spoolssd/srv_spoolss_nt.c b/source/spoolssd/srv_spoolss_nt.c index 5d8c3be6b71..e99c7307625 100755 --- a/source/spoolssd/srv_spoolss_nt.c +++ b/source/spoolssd/srv_spoolss_nt.c @@ -76,7 +76,17 @@ typedef struct _Printer{ } client; } Printer_entry; +typedef struct _counter_printer_0 { + ubi_dlNode Next; + ubi_dlNode Prev; + + int snum; + uint32 counter; +} counter_printer_0; + static ubi_dlList Printer_list; +static ubi_dlList counter_list; + #define OPEN_HANDLE(pnum) ((pnum!=NULL) && (pnum->open!=False)) @@ -86,6 +96,7 @@ static ubi_dlList Printer_list; void init_printer_hnd(void) { ubi_dlInitList(&Printer_list); + ubi_dlInitList(&counter_list); } /**************************************************************************** @@ -396,24 +407,24 @@ static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size) ps=&(buffer->prs); /* damn, I'm doing the reverse operation of prs_grow() :) */ - if (buffer_size < ps->data_size) + if (buffer_size < prs_data_size(ps)) extra_space=0; else - extra_space = buffer_size - ps->data_size; + extra_space = buffer_size - prs_data_size(ps); /* * save the offset and move to the end of the buffer * prs_grow() checks the extra_space against the offset */ old_offset=prs_offset(ps); - prs_set_offset(ps, ps->data_size); + prs_set_offset(ps, prs_data_size(ps)); if (!prs_grow(ps, extra_space)) return False; prs_set_offset(ps, old_offset); - buffer->string_at_end=ps->data_size; + buffer->string_at_end=prs_data_size(ps); return True; } @@ -433,7 +444,7 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername, clear_handle(handle); if (printername == NULL) - return NT_STATUS_ACCESS_DENIED; + return ERROR_INVALID_PRINTER_NAME; /* some sanity check because you can open a printer or a print server */ /* aka: \\server\printer or \\server */ @@ -447,12 +458,12 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername, if (!set_printer_hnd_printertype(handle, name)) { close_printer_handle(handle); - return NT_STATUS_ACCESS_DENIED; + return ERROR_INVALID_PRINTER_NAME; } if (!set_printer_hnd_printername(handle, name)) { close_printer_handle(handle); - return NT_STATUS_ACCESS_DENIED; + return ERROR_INVALID_PRINTER_NAME; } /* @@ -467,7 +478,7 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername, if (!set_printer_hnd_accesstype(handle, printer_default->access_required)) { close_printer_handle(handle); - return NT_STATUS_ACCESS_DENIED; + return ERROR_ACCESS_DENIED; } return NT_STATUS_NO_PROBLEMO; @@ -661,25 +672,32 @@ static BOOL getprinterdata_printer(const POLICY_HND *handle, DEBUG(5,("getprinterdata_printer\n")); - if (OPEN_HANDLE(Printer)) - { + if (!OPEN_HANDLE(Printer)) + return False; + get_printer_snum(handle, &snum); get_a_printer(&printer, 2, lp_servicename(snum)); - if (get_specific_param(printer, 2, value, &idata, type, &len)) - { - *data = (uint8 *)malloc( (len>in_size)?len:in_size *sizeof(uint8) ); - memset(*data, 0, sizeof(uint8)*len); - memcpy(*data, idata, (len>in_size)?len:in_size); + if (!get_specific_param(printer, 2, value, &idata, type, &len)) { + free_a_printer(printer, 2); + return False; + } + + DEBUG(5,("getprinterdata_printer:allocating %d\n", in_size)); + + *data = (uint8 *)malloc( in_size *sizeof(uint8) ); + memset(*data, 0, in_size *sizeof(uint8)); + /* copy the min(in_size, len) */ + memcpy(*data, idata, (len>in_size)?in_size:len *sizeof(uint8)); + *needed = len; - if (idata) free(idata); - return (True); - } + DEBUG(5,("getprinterdata_printer:copy done\n")); + free_a_printer(printer, 2); - } + safe_free(idata); - return (False); + return True; } /******************************************************************** @@ -724,9 +742,10 @@ uint32 _spoolss_getprinterdata(const POLICY_HND *handle, UNISTR2 *valuename, found=getprinterdata_printer(handle, value, type, data, needed, *out_size); if (found==False) { + DEBUG(5, ("value not found, allocating %d\n", *out_size)); /* reply this param doesn't exist */ - *data=(uint8 *)malloc(4*sizeof(uint8)); - memset(*data, 0x0, 4); + *data=(uint8 *)malloc(*out_size*sizeof(uint8)); + memset(*data, 0x0, *out_size*sizeof(uint8)); return ERROR_INVALID_PARAMETER; } @@ -980,7 +999,7 @@ static void spoolss_notify_status(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_ memset(&status, 0, sizeof(status)); count=get_printqueue(snum, NULL, UID_FIELD_INVALID, &q, &status); data->notify_data.value[0]=(uint32) status.status; - if (q) free(q); + safe_free(q); } /******************************************************************* @@ -993,7 +1012,7 @@ static void spoolss_notify_cjobs(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_q memset(&status, 0, sizeof(status)); data->notify_data.value[0]=get_printqueue(snum, NULL, UID_FIELD_INVALID, &q, &status); - if (q) free(q); + safe_free(q); } /******************************************************************* @@ -1497,17 +1516,45 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer,int snum, pstring s pstring chaine; int count; NT_PRINTER_INFO_LEVEL ntprinter; + counter_printer_0 *session_counter; + uint32 global_counter; + struct tm *t; print_queue_struct *queue=NULL; print_status_struct status; + memset(&status, 0, sizeof(status)); if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0) - { - return (False); - } + return False; count=get_printqueue(snum, NULL, UID_FIELD_INVALID, &queue, &status); + + /* check if we already have a counter for this printer */ + session_counter = (counter_printer_0 *)ubi_dlFirst(&counter_list); + + for(; session_counter; session_counter = (counter_printer_0 *)ubi_dlNext(session_counter)) { + if (session_counter->snum == snum) + break; + } + + /* it's the first time, add it to the list */ + if (session_counter==NULL) { + session_counter=(counter_printer_0 *)malloc(sizeof(counter_printer_0)); + ZERO_STRUCTP(session_counter); + session_counter->snum=snum; + session_counter->counter=0; + ubi_dlAddHead( &counter_list, (ubi_dlNode *)session_counter); + } + + /* increment it */ + session_counter->counter++; + + /* JFM: + * the global_counter should be stored in a TDB as it's common to all the clients + * and should be zeroed on samba startup + */ + global_counter=session_counter->counter; /* the description and the name are of the form \\server\share */ slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s",servername, ntprinter.info_2->printername); @@ -1518,35 +1565,47 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer,int snum, pstring s init_unistr(&(printer->servername), chaine); printer->cjobs = count; - printer->attributes = PRINTER_ATTRIBUTE_SHARED \ - | PRINTER_ATTRIBUTE_NETWORK \ - | PRINTER_ATTRIBUTE_RAW_ONLY ; - printer->unknown0 = 0x1; /* pointer */ - printer->unknown1 = 0x000A07CE; /* don't known */ - printer->unknown2 = 0x00020005; - printer->unknown3 = 0x0006000D; - printer->unknown4 = 0x02180026; - printer->unknown5 = 0x09; - printer->unknown6 = 0x36; - printer->majorversion = 0x0004; /* NT 4 */ - printer->buildversion = 0x0565; /* build 1381 */ + printer->total_jobs = 0; + printer->total_bytes = 0; + + t=gmtime(&ntprinter.info_2->setuptime); + + printer->year = t->tm_year+1900; + printer->month = t->tm_mon+1; + printer->dayofweek = t->tm_wday; + printer->day = t->tm_mday; + printer->hour = t->tm_hour; + printer->minute = t->tm_min; + printer->second = t->tm_sec; + printer->milliseconds = 0; + + printer->global_counter = global_counter; + printer->total_pages = 0; + printer->major_version = 0x0004; /* NT 4 */ + printer->build_version = 0x0565; /* build 1381 */ printer->unknown7 = 0x1; printer->unknown8 = 0x0; printer->unknown9 = 0x2; - printer->unknown10 = 0x3; + printer->session_counter = session_counter->counter; printer->unknown11 = 0x0; - printer->unknown12 = 0x0; + printer->printer_errors = 0x0; /* number of print failure */ printer->unknown13 = 0x0; printer->unknown14 = 0x1; printer->unknown15 = 0x024a; /*586 Pentium ? */ printer->unknown16 = 0x0; - printer->unknown17 = 0x423ed444; /* CacheChangeID */ + printer->change_id = ntprinter.info_2->changeid; /* ChangeID in milliseconds*/ printer->unknown18 = 0x0; printer->status = status.status; printer->unknown20 = 0x0; - printer->unknown21 = 0x0648; + printer->c_setprinter = ntprinter.info_2->c_setprinter; /* how many times setprinter has been called */ printer->unknown22 = 0x0; - printer->unknown23 = 0x5; + printer->unknown23 = 0x6; /* 6 ???*/ + printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */ + printer->unknown25 = 0; + printer->unknown26 = 0; + printer->unknown27 = 0; + printer->unknown28 = 0; + printer->unknown29 = 0; safe_free(queue); @@ -1558,35 +1617,29 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer,int snum, pstring s * construct_printer_info_1 * fill a printer_info_1 struct ********************************************************************/ -static BOOL construct_printer_info_1(PRINTER_INFO_1 *printer, int snum, pstring servername) +static BOOL construct_printer_info_1(fstring server, uint32 flags, PRINTER_INFO_1 *printer, int snum) { pstring chaine; pstring chaine2; NT_PRINTER_INFO_LEVEL ntprinter; if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0) - { - return (False); - } - - printer->flags=PRINTER_ENUM_ICON8; + return False; - /* the description and the name are of the form \\server\share */ + printer->flags=flags; - snprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s,%s,%s",servername, - ntprinter.info_2->printername, - ntprinter.info_2->drivername, - lp_comment(snum)); - init_unistr(&(printer->description), chaine); + snprintf(chaine,sizeof(chaine)-1,"%s%s,%s,%s",server, ntprinter.info_2->printername, + ntprinter.info_2->drivername, lp_comment(snum)); - snprintf(chaine2,sizeof(chaine)-1,"\\\\%s\\%s", servername, ntprinter.info_2->printername); - init_unistr(&(printer->name), chaine2); + snprintf(chaine2,sizeof(chaine)-1,"%s%s", server, ntprinter.info_2->printername); - init_unistr(&(printer->comment), lp_comment(snum)); + init_unistr(&printer->description, chaine); + init_unistr(&printer->name, chaine2); + init_unistr(&printer->comment, lp_comment(snum)); free_a_printer(ntprinter, 2); - return (True); + return True; } /**************************************************************************** @@ -1653,9 +1706,11 @@ static void construct_dev_mode(DEVICEMODE *devmode, int snum, char *servername) * construct_printer_info_2 * fill a printer_info_2 struct ********************************************************************/ -static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum, pstring servername) +static BOOL construct_printer_info_2(pstring servername, PRINTER_INFO_2 *printer, int snum) { pstring chaine; + pstring chaine2; + pstring sl; int count; DEVICEMODE *devmode; NT_PRINTER_INFO_LEVEL ntprinter; @@ -1663,33 +1718,36 @@ static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum, pstring print_queue_struct *queue=NULL; print_status_struct status; memset(&status, 0, sizeof(status)); - count=get_printqueue(snum, NULL, UID_FIELD_INVALID, &queue, &status); if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 ) - { - return (False); - } + return False; - snprintf(chaine, sizeof(chaine)-1, "\\\\%s", servername); - init_unistr(&(printer->servername), chaine); /* servername*/ + ZERO_STRUCT(status); + count=get_printqueue(snum, NULL, UID_FIELD_INVALID, &queue, &status); - snprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", servername, ntprinter.info_2->printername); - init_unistr(&(printer->printername), chaine); /* printername*/ + snprintf(chaine, sizeof(chaine)-1, "%s", servername); - init_unistr(&(printer->sharename), lp_servicename(snum)); /* sharename */ + if (strlen(servername)!=0) + fstrcpy(sl, "\\"); + else + fstrcpy(sl, '\0'); - init_unistr(&(printer->portname), lp_servicename(snum)); /* port */ - init_unistr(&(printer->drivername), ntprinter.info_2->drivername); /* drivername */ + snprintf(chaine2, sizeof(chaine)-1, "%s%s%s", servername, sl, ntprinter.info_2->printername); - init_unistr(&(printer->comment), ntprinter.info_2->comment); /* comment */ - init_unistr(&(printer->location), ntprinter.info_2->location); /* location */ - init_unistr(&(printer->sepfile), ntprinter.info_2->sepfile); /* separator file */ - init_unistr(&(printer->printprocessor), ntprinter.info_2->printprocessor);/* print processor */ - init_unistr(&(printer->datatype), ntprinter.info_2->datatype); /* datatype */ - init_unistr(&(printer->parameters), ntprinter.info_2->parameters); /* parameters (of print processor) */ + init_unistr(&printer->servername, chaine); /* servername*/ + init_unistr(&printer->printername, chaine2); /* printername*/ + init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */ + init_unistr(&printer->portname, lp_servicename(snum)); /* port */ + init_unistr(&printer->drivername, ntprinter.info_2->drivername); /* drivername */ + init_unistr(&printer->comment, lp_comment(snum)); /* comment */ + init_unistr(&printer->location, ntprinter.info_2->location); /* location */ + init_unistr(&printer->sepfile, ntprinter.info_2->sepfile); /* separator file */ + init_unistr(&printer->printprocessor, ntprinter.info_2->printprocessor);/* print processor */ + init_unistr(&printer->datatype, ntprinter.info_2->datatype); /* datatype */ + init_unistr(&printer->parameters, ntprinter.info_2->parameters); /* parameters (of print processor) */ printer->attributes = PRINTER_ATTRIBUTE_SHARED \ - | PRINTER_ATTRIBUTE_NETWORK \ + | PRINTER_ATTRIBUTE_LOCAL \ | PRINTER_ATTRIBUTE_RAW_ONLY ; /* attributes */ printer->priority = ntprinter.info_2->priority; /* priority */ @@ -1707,79 +1765,38 @@ static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum, pstring safe_free(queue); free_a_printer(ntprinter, 2); - return (True); -} - -/******************************************************************** - * enum_printer_info_1 - * glue between spoolss_enumprinters and construct_printer_info_1 - ********************************************************************/ -static BOOL get_printer_info_1(PRINTER_INFO_1 **printer, int snum, int number) -{ - pstring servername; - - *printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1)); - DEBUG(4,("Allocated memory for ONE PRINTER_INFO_1 at [%p]\n", *printer)); - pstrcpy(servername, global_myname); - if (!construct_printer_info_1(*printer, snum, servername)) { - free(*printer); - return False; - } - else return True; } /******************************************************************** - * enum_printer_info_2 - * glue between spoolss_enumprinters and construct_printer_info_2 - ********************************************************************/ -static BOOL get_printer_info_2(PRINTER_INFO_2 **printer, int snum, int number) -{ - pstring servername; - - *printer=(PRINTER_INFO_2 *)malloc(sizeof(PRINTER_INFO_2)); - DEBUG(4,("Allocated memory for ONE PRINTER_INFO_2 at [%p]\n", *printer)); - pstrcpy(servername, global_myname); - if (!construct_printer_info_2(*printer, snum, servername)) - { - free(*printer); - return (False); - } - else - { - return (True); - } -} - -/******************************************************************** - * spoolss_enumprinters - * - * called from api_spoolss_enumprinters (see this to understand) + Spoolss_enumprinters. ********************************************************************/ -static BOOL enum_printer_info_1(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static BOOL enum_all_printers_info_1(fstring server, uint32 flags, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int snum; int i; int n_services=lp_numservices(); - PRINTER_INFO_1 *printer=NULL; -DEBUG(1,("enum_printer_info_1\n")); + PRINTER_INFO_1 *printers=NULL; + PRINTER_INFO_1 current_prt; + + 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)); - /* - JFM: here we should check the name - - */ - - if (get_printer_info_1(&printer , snum, *returned) ) + if (construct_printer_info_1(server, flags, ¤t_prt, snum)) { + printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1)); + DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned)); + memcpy(&(printers[*returned]), ¤t_prt, sizeof(PRINTER_INFO_1)); (*returned)++; } } + } /* check the required size. */ for (i=0; i<*returned; i++) - (*needed) += spoolss_size_printer_info_1(printer); + (*needed) += spoolss_size_printer_info_1(&(printers[i])); if (!alloc_buffer_size(buffer, *needed)) return ERROR_INSUFFICIENT_BUFFER; @@ -1787,9 +1804,10 @@ DEBUG(1,("enum_printer_info_1\n")); /* fill the buffer with the structures */ for (i=0; i<*returned; i++) - new_smb_io_printer_info_1("", buffer, printer, 0); + new_smb_io_printer_info_1("", buffer, &(printers[i]), 0); /* clear memory */ + safe_free(printers); if (*needed > offered) { *returned=0; @@ -1800,49 +1818,87 @@ DEBUG(1,("enum_printer_info_1\n")); } /******************************************************************** - Spoolss_enumprinters. -********************************************************************/ -static BOOL enum_all_printers_info_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) + enum_all_printers_info_1_local. +*********************************************************************/ +static BOOL enum_all_printers_info_1_local(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { - int snum; - int i; - int n_services=lp_numservices(); - PRINTER_INFO_1 *printers=NULL; - PRINTER_INFO_1 current_prt; - pstring servername; - - DEBUG(4,("enum_all_printers_info_1\n")); + fstring temp; + DEBUG(4,("enum_all_printers_info_1_local\n")); - pstrcpy(servername, global_myname); + fstrcpy(temp, "\\\\"); + fstrcat(temp, global_myname); - 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 (!strcmp(name, temp)) { + fstrcat(temp, "\\"); + return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned); + } + else + return enum_all_printers_info_1("", PRINTER_ENUM_ICON8, buffer, offered, needed, returned); +} - if (construct_printer_info_1(¤t_prt, snum, servername)) +/******************************************************************** + enum_all_printers_info_1_name. +*********************************************************************/ +static BOOL enum_all_printers_info_1_name(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { - printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1)); - DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned)); - memcpy(&(printers[*returned]), ¤t_prt, sizeof(PRINTER_INFO_1)); - (*returned)++; - } + fstring temp; + DEBUG(4,("enum_all_printers_info_1_name\n")); + + fstrcpy(temp, "\\\\"); + fstrcat(temp, global_myname); + + if (!strcmp(name, temp)) { + fstrcat(temp, "\\"); + return enum_all_printers_info_1(temp, PRINTER_ENUM_ICON8, buffer, offered, needed, returned); } + else + return ERROR_INVALID_NAME; } +/******************************************************************** + enum_all_printers_info_1_remote. +*********************************************************************/ +static BOOL enum_all_printers_info_1_remote(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +{ + PRINTER_INFO_1 *printer; + fstring printername; + fstring desc; + fstring comment; + DEBUG(4,("enum_all_printers_info_1_remote\n")); + + /* JFM: currently it's more a place holder than anything else. + * In the spooler world there is a notion of server registration. + * the print servers are registring (sp ?) on the PDC (in the same domain) + * + * We should have a TDB here. The registration is done thru an undocumented RPC call. + */ + + printer=(PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1)); + + *returned=1; + + snprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", global_myname); + snprintf(desc, sizeof(desc)-1,"%s", global_myname); + snprintf(comment, sizeof(comment)-1, "Logged on Domain"); + + init_unistr(&printer->description, desc); + init_unistr(&printer->name, printername); + init_unistr(&printer->comment, comment); + printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER; + /* check the required size. */ - for (i=0; i<*returned; i++) - (*needed) += spoolss_size_printer_info_1(&(printers[i])); + *needed += spoolss_size_printer_info_1(printer); - if (!alloc_buffer_size(buffer, *needed)) + if (!alloc_buffer_size(buffer, *needed)) { + safe_free(printer); return ERROR_INSUFFICIENT_BUFFER; - + } /* fill the buffer with the structures */ - - for (i=0; i<*returned; i++) - new_smb_io_printer_info_1("", buffer, &(printers[i]), 0); + new_smb_io_printer_info_1("", buffer, printer, 0); /* clear memory */ + safe_free(printer); if (*needed > offered) { *returned=0; @@ -1853,45 +1909,68 @@ static BOOL enum_all_printers_info_1(NEW_BUFFER *buffer, uint32 offered, uint32 } /******************************************************************** + enum_all_printers_info_1_network. +*********************************************************************/ +static BOOL enum_all_printers_info_1_network(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +{ + fstring temp; + DEBUG(4,("enum_all_printers_info_1_network\n")); + + fstrcpy(temp, "\\\\"); + fstrcat(temp, global_myname); + fstrcat(temp, "\\"); + return enum_all_printers_info_1(temp, PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned); +} + +/******************************************************************** * api_spoolss_enumprinters * * called from api_spoolss_enumprinters (see this to understand) ********************************************************************/ -static BOOL enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +static BOOL enum_all_printers_info_2(fstring servername, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int snum; int i; int n_services=lp_numservices(); - PRINTER_INFO_2 **printers=NULL; + PRINTER_INFO_2 *printers=NULL; + PRINTER_INFO_2 current_prt; 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)); - printers=Realloc(printers, ((*returned)+1)*sizeof(PRINTER_INFO_2 *)); - - DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2 pointers\n", (*returned)+1)); - - if (get_printer_info_2( &(printers[*returned]), snum, *returned) ) + if (construct_printer_info_2(servername, ¤t_prt, snum)) { + printers=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2)); + DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned)); + memcpy(&(printers[*returned]), ¤t_prt, sizeof(PRINTER_INFO_2)); (*returned)++; } } + } /* check the required size. */ for (i=0; i<*returned; i++) - (*needed) += spoolss_size_printer_info_2(printers[i]); - - DEBUG(4,("we need [%d] bytes\n", *needed)); + (*needed) += spoolss_size_printer_info_2(&(printers[i])); - if (!alloc_buffer_size(buffer, *needed)) + if (!alloc_buffer_size(buffer, *needed)) { + for (i=0; i<*returned; i++) { + safe_free(printers[i].devmode->private); + safe_free(printers[i].devmode); + } + safe_free(printers); return ERROR_INSUFFICIENT_BUFFER; + } /* fill the buffer with the structures */ for (i=0; i<*returned; i++) - new_smb_io_printer_info_2("", buffer, printers[i], 0); + new_smb_io_printer_info_2("", buffer, &(printers[i]), 0); /* clear memory */ + for (i=0; i<*returned; i++) { + safe_free(printers[i].devmode->private); + safe_free(printers[i].devmode); + } + safe_free(printers); if (*needed > offered) { *returned=0; @@ -1908,20 +1987,21 @@ static uint32 enumprinters_level1( uint32 flags, fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { - if (flags && PRINTER_ENUM_NETWORK) - return enum_all_printers_info_1(buffer, offered, needed, returned); + /* Not all the flags are equals */ - if (flags && PRINTER_ENUM_NAME) { - if (*name=='\0') - return enum_all_printers_info_1(buffer, offered, needed, returned); - else - return enum_printer_info_1(name, buffer, offered, needed, returned); - } + if (flags & PRINTER_ENUM_LOCAL) + return enum_all_printers_info_1_local(name, buffer, offered, needed, returned); - if (flags && PRINTER_ENUM_REMOTE) - return enum_all_printers_info_1(buffer, offered, needed, returned); + if (flags & PRINTER_ENUM_NAME) + return enum_all_printers_info_1_name(name, buffer, offered, needed, returned); - return NT_STATUS_INVALID_LEVEL; + if (flags & PRINTER_ENUM_REMOTE) + return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned); + + if (flags & PRINTER_ENUM_NETWORK) + return enum_all_printers_info_1_network(name, buffer, offered, needed, returned); + + return NT_STATUS_NO_PROBLEMO; /* NT4sp5 does that */ } /******************************************************************** @@ -1931,7 +2011,29 @@ static uint32 enumprinters_level2( uint32 flags, fstring servername, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { - return enum_all_printers_info_2(buffer, offered, needed, returned); + fstring temp; + + fstrcpy(temp, "\\\\"); + fstrcat(temp, global_myname); + + if (flags & PRINTER_ENUM_LOCAL) { + if (!strcmp(servername, temp)) + return enum_all_printers_info_2(temp, buffer, offered, needed, returned); + else + return enum_all_printers_info_2("", buffer, offered, needed, returned); + } + + if (flags & PRINTER_ENUM_NAME) { + if (!strcmp(servername, temp)) + return enum_all_printers_info_2(temp, buffer, offered, needed, returned); + else + return ERROR_INVALID_NAME; + } + + if (flags & PRINTER_ENUM_REMOTE) + return ERROR_INVALID_LEVEL; + + return NT_STATUS_NO_PROBLEMO; } /******************************************************************** @@ -1975,6 +2077,7 @@ uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 le */ unistr2_to_ascii(name, servername, sizeof(name)-1); + strupper(name); switch (level) { case 1: @@ -2006,8 +2109,10 @@ static uint32 getprinter_level_0(pstring servername, int snum, NEW_BUFFER *buffe /* check the required size. */ *needed += spoolss_size_printer_info_0(printer); - if (!alloc_buffer_size(buffer, *needed)) + if (!alloc_buffer_size(buffer, *needed)) { + safe_free(printer); return ERROR_INSUFFICIENT_BUFFER; + } /* fill the buffer with the structures */ new_smb_io_printer_info_0("", buffer, printer, 0); @@ -2029,13 +2134,15 @@ static uint32 getprinter_level_1(pstring servername, int snum, NEW_BUFFER *buffe PRINTER_INFO_1 *printer=NULL; printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1)); - construct_printer_info_1(printer, snum, servername); + construct_printer_info_1(servername, PRINTER_ENUM_ICON8, printer, snum); /* check the required size. */ *needed += spoolss_size_printer_info_1(printer); - if (!alloc_buffer_size(buffer, *needed)) + if (!alloc_buffer_size(buffer, *needed)) { + safe_free(printer); return ERROR_INSUFFICIENT_BUFFER; + } /* fill the buffer with the structures */ new_smb_io_printer_info_1("", buffer, printer, 0); @@ -2055,20 +2162,28 @@ static uint32 getprinter_level_1(pstring servername, int snum, NEW_BUFFER *buffe static uint32 getprinter_level_2(pstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_2 *printer=NULL; + fstring temp; printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)); - construct_printer_info_2(printer, snum, servername); + + fstrcpy(temp, "\\\\"); + fstrcat(temp, servername); + construct_printer_info_2(temp, printer, snum); /* check the required size. */ *needed += spoolss_size_printer_info_2(printer); - if (!alloc_buffer_size(buffer, *needed)) + if (!alloc_buffer_size(buffer, *needed)) { + safe_free(printer); return ERROR_INSUFFICIENT_BUFFER; + } /* fill the buffer with the structures */ new_smb_io_printer_info_2("", buffer, printer, 0); /* clear memory */ + safe_free(printer->devmode->private); + safe_free(printer->devmode); safe_free(printer); if (*needed > offered) { @@ -2091,9 +2206,7 @@ uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level, pstrcpy(servername, global_myname); if (!get_printer_snum(handle, &snum)) - { return NT_STATUS_INVALID_HANDLE; - } switch (level) { case 0: @@ -2106,7 +2219,7 @@ uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level, return getprinter_level_2(servername,snum, buffer, offered, needed); break; default: - return NT_STATUS_INVALID_LEVEL; + return ERROR_INVALID_LEVEL; break; } } @@ -2177,8 +2290,7 @@ static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, * construct_printer_driver_info_2 * fill a printer_info_2 struct ********************************************************************/ -static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, - pstring servername, fstring architecture) +static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, pstring servername, fstring architecture) { NT_PRINTER_INFO_LEVEL printer; NT_PRINTER_DRIVER_INFO_LEVEL driver; @@ -2194,36 +2306,30 @@ static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, /******************************************************************** * copy a strings array and convert to UNICODE + * + * convert an array of ascii string to a UNICODE string ********************************************************************/ -static void init_unistr_array(UNISTR ***uni_array, char **char_array, char *where) +static void init_unistr_array(uint16 **uni_array, char **char_array, char *where) { int i=0; + int j=0; char *v; pstring line; DEBUG(6,("init_unistr_array\n")); + *uni_array=NULL; - for (v=char_array[i]; *v!='\0'; v=char_array[i]) - { - DEBUGADD(6,("i:%d:", i)); - DEBUGADD(6,("%s:%d:", v, strlen(v))); - - *uni_array=(UNISTR **)Realloc(*uni_array, sizeof(UNISTR *)*(i+1)); - DEBUGADD(7,("realloc:[%p],", *uni_array)); - - (*uni_array)[i]=(UNISTR *)malloc( sizeof(UNISTR) ); - DEBUGADD(7,("alloc:[%p],", (*uni_array)[i])); - + for (v=char_array[i]; *v!='\0'; v=char_array[i]) { snprintf(line, sizeof(line)-1, "%s%s", where, v); - init_unistr( (*uni_array)[i], line ); - DEBUGADD(7,("copy\n")); - + DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line))); + *uni_array=Realloc(*uni_array, (j+strlen(line)+2)*sizeof(uint16)); + ascii_to_unistr( *uni_array+j, line , strlen(line)); + j+=strlen(line)+1; i++; } - DEBUGADD(7,("last one\n")); - *uni_array=(UNISTR **)Realloc(*uni_array, sizeof(UNISTR *)*(i+1)); - (*uni_array)[i]=0x0000; + (*uni_array)[j]=0x0000; + DEBUGADD(6,("last one:done\n")); } @@ -2302,8 +2408,10 @@ static uint32 getprinterdriver2_level1(pstring servername, pstring architecture, /* check the required size. */ *needed += spoolss_size_printer_driver_info_1(info); - if (!alloc_buffer_size(buffer, *needed)) + if (!alloc_buffer_size(buffer, *needed)) { + safe_free(info); return ERROR_INSUFFICIENT_BUFFER; + } /* fill the buffer with the structures */ new_smb_io_printer_driver_info_1("", buffer, info, 0); @@ -2311,9 +2419,8 @@ static uint32 getprinterdriver2_level1(pstring servername, pstring architecture, /* clear memory */ safe_free(info); - if (*needed > offered) { + if (*needed > offered) return ERROR_INSUFFICIENT_BUFFER; - } else return NT_STATUS_NO_PROBLEMO; } @@ -2331,8 +2438,10 @@ static uint32 getprinterdriver2_level2(pstring servername, pstring architecture, /* check the required size. */ *needed += spoolss_size_printer_driver_info_2(info); - if (!alloc_buffer_size(buffer, *needed)) + if (!alloc_buffer_size(buffer, *needed)) { + safe_free(info); return ERROR_INSUFFICIENT_BUFFER; + } /* fill the buffer with the structures */ new_smb_io_printer_driver_info_2("", buffer, info, 0); @@ -2340,9 +2449,8 @@ static uint32 getprinterdriver2_level2(pstring servername, pstring architecture, /* clear memory */ safe_free(info); - if (*needed > offered) { + if (*needed > offered) return ERROR_INSUFFICIENT_BUFFER; - } else return NT_STATUS_NO_PROBLEMO; } @@ -2360,27 +2468,30 @@ static uint32 getprinterdriver2_level3(pstring servername, pstring architecture, /* check the required size. */ *needed += spoolss_size_printer_driver_info_3(info); - if (!alloc_buffer_size(buffer, *needed)) + if (!alloc_buffer_size(buffer, *needed)) { + safe_free(info); return ERROR_INSUFFICIENT_BUFFER; + } /* fill the buffer with the structures */ new_smb_io_printer_driver_info_3("", buffer, info, 0); /* clear memory */ + safe_free(info->dependentfiles); safe_free(info); - if (*needed > offered) { + if (*needed > offered) return ERROR_INSUFFICIENT_BUFFER; - } else return NT_STATUS_NO_PROBLEMO; } /**************************************************************************** ****************************************************************************/ -uint32 _spoolss_getprinterdriver2(const POLICY_HND *handle, const UNISTR2 *uni_arch, uint32 level, uint32 unknown, +uint32 _spoolss_getprinterdriver2(const POLICY_HND *handle, const UNISTR2 *uni_arch, uint32 level, + uint32 clientmajorversion, uint32 clientminorversion, NEW_BUFFER *buffer, uint32 offered, - uint32 *needed, uint32 *unknown0, uint32 *unknown1) + uint32 *needed, uint32 *servermajorversion, uint32 *serverminorversion) { pstring servername; fstring architecture; @@ -2389,16 +2500,14 @@ uint32 _spoolss_getprinterdriver2(const POLICY_HND *handle, const UNISTR2 *uni_a DEBUG(4,("_spoolss_getprinterdriver2\n")); *needed=0; - *unknown0=0; - *unknown1=0; + *servermajorversion=0; + *serverminorversion=0; pstrcpy(servername, global_myname); unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1); if (!get_printer_snum(handle, &snum)) - { return NT_STATUS_INVALID_HANDLE; - } switch (level) { case 1: @@ -2490,7 +2599,7 @@ uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level, if (strcmp(datatype, "RAW") != 0) { (*jobid)=0; - return STATUS_1804; + return ERROR_INVALID_DATATYPE; } } @@ -2507,7 +2616,7 @@ uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level, slprintf(tempname,sizeof(tempname)-1, "%s/smb_print.XXXXXX",lp_pathname(snum)); pstrcpy(fname, (char *)mktemp(tempname)); - fd=open(fname, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR ); + fd=open(fname, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, S_IRUSR|S_IWUSR ); DEBUG(4,("Temp spool file created: [%s]\n", fname)); Printer->current_jobid=fd; @@ -2767,9 +2876,10 @@ uint32 _spoolss_setprinter(const POLICY_HND *handle, uint32 level, case 2: return update_printer(handle, level, info, devmode_ctr.devmode); break; + default: + return ERROR_INVALID_LEVEL; + break; } - - return NT_STATUS_INVALID_INFO_CLASS; } /**************************************************************************** @@ -3093,27 +3203,31 @@ static uint32 enumprinterdrivers_level1(fstring *list, fstring servername, fstri free_a_printer_driver(driver, 3); } + safe_free(list); + /* check the required size. */ - for (i=0; i<*returned; i++) - { + for (i=0; i<*returned; i++) { DEBUGADD(6,("adding driver [%d]'s size\n",i)); *needed += spoolss_size_printer_driver_info_1(&(driver_info_1[i])); } - if (!alloc_buffer_size(buffer, *needed)) + if (!alloc_buffer_size(buffer, *needed)) { + safe_free(driver_info_1); return ERROR_INSUFFICIENT_BUFFER; + } /* fill the buffer with the form structures */ - for (i=0; i<*returned; i++) - { + for (i=0; i<*returned; i++) { DEBUGADD(6,("adding driver [%d] to buffer\n",i)); new_smb_io_printer_driver_info_1("", buffer, &(driver_info_1[i]), 0); } - safe_free(list); + safe_free(driver_info_1); - if (*needed > offered) + if (*needed > offered) { + *returned=0; return ERROR_INSUFFICIENT_BUFFER; + } else return NT_STATUS_NO_PROBLEMO; } @@ -3134,27 +3248,31 @@ static uint32 enumprinterdrivers_level2(fstring *list, fstring servername, fstri free_a_printer_driver(driver, 3); } + safe_free(list); + /* check the required size. */ - for (i=0; i<*returned; i++) - { + for (i=0; i<*returned; i++) { DEBUGADD(6,("adding driver [%d]'s size\n",i)); *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i])); } - if (!alloc_buffer_size(buffer, *needed)) + if (!alloc_buffer_size(buffer, *needed)) { + safe_free(driver_info_2); return ERROR_INSUFFICIENT_BUFFER; + } /* fill the buffer with the form structures */ - for (i=0; i<*returned; i++) - { + for (i=0; i<*returned; i++) { DEBUGADD(6,("adding driver [%d] to buffer\n",i)); new_smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0); } - safe_free(list); + safe_free(driver_info_2); - if (*needed > offered) + if (*needed > offered) { + *returned=0; return ERROR_INSUFFICIENT_BUFFER; + } else return NT_STATUS_NO_PROBLEMO; } @@ -3175,27 +3293,34 @@ static uint32 enumprinterdrivers_level3(fstring *list, fstring servername, fstri free_a_printer_driver(driver, 3); } + safe_free(list); + /* check the required size. */ - for (i=0; i<*returned; i++) - { + for (i=0; i<*returned; i++) { DEBUGADD(6,("adding driver [%d]'s size\n",i)); *needed += spoolss_size_printer_driver_info_3(&(driver_info_3[i])); } - if (!alloc_buffer_size(buffer, *needed)) + if (!alloc_buffer_size(buffer, *needed)) { + safe_free(driver_info_3); return ERROR_INSUFFICIENT_BUFFER; + } /* fill the buffer with the form structures */ - for (i=0; i<*returned; i++) - { + for (i=0; i<*returned; i++) { DEBUGADD(6,("adding form [%d] to buffer\n",i)); new_smb_io_printer_driver_info_3("", buffer, &(driver_info_3[i]), 0); } - safe_free(list); + for (i=0; i<*returned; i++) + safe_free(driver_info_3[i].dependentfiles); - if (*needed > offered) + safe_free(driver_info_3); + + if (*needed > offered) { + *returned=0; return ERROR_INSUFFICIENT_BUFFER; + } else return NT_STATUS_NO_PROBLEMO; } @@ -3235,7 +3360,7 @@ uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32 return enumprinterdrivers_level3(list, servername, architecture, buffer, offered, needed, returned); break; default: - return NT_STATUS_INVALID_INFO_CLASS; + return ERROR_INVALID_LEVEL; break; } } @@ -3277,41 +3402,44 @@ uint32 _new_spoolss_enumforms( const POLICY_HND *handle, uint32 level, forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1)); /* construct the list of form structures */ - for (i=0; i<*numofforms; i++) - { + for (i=0; i<*numofforms; i++) { DEBUGADD(6,("Filling form number [%d]\n",i)); fill_form_1(&(forms_1[i]), &(list[i]), i); } + safe_free(list); + /* check the required size. */ - for (i=0; i<*numofforms; i++) - { + for (i=0; i<*numofforms; i++) { DEBUGADD(6,("adding form [%d]'s size\n",i)); buffer_size += spoolss_size_form_1(&(forms_1[i])); } *needed=buffer_size; - if (!alloc_buffer_size(buffer, buffer_size)) + if (!alloc_buffer_size(buffer, buffer_size)){ + safe_free(forms_1); return ERROR_INSUFFICIENT_BUFFER; + } /* fill the buffer with the form structures */ - for (i=0; i<*numofforms; i++) - { + for (i=0; i<*numofforms; i++) { DEBUGADD(6,("adding form [%d] to buffer\n",i)); new_smb_io_form_1("", buffer, &(forms_1[i]), 0); } - safe_free(list); + safe_free(forms_1); - if (*needed > offered) + if (*needed > offered) { + *numofforms=0; return ERROR_INSUFFICIENT_BUFFER; + } else return NT_STATUS_NO_PROBLEMO; default: safe_free(list); - return NT_STATUS_INVALID_INFO_CLASS; + return ERROR_INVALID_LEVEL; } } @@ -3352,8 +3480,7 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need ports=(PORT_INFO_1 *)malloc( (*returned+1) * sizeof(PORT_INFO_1) ); - for (snum=0; snum<n_services; snum++) - { + for (snum=0; snum<n_services; snum++) { if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) { DEBUGADD(6,("Filling port number [%d]\n", i)); fill_port_1(&(ports[i]), lp_servicename(snum)); @@ -3362,18 +3489,18 @@ static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *need } /* check the required size. */ - for (i=0; i<*returned; i++) - { + for (i=0; i<*returned; i++) { DEBUGADD(6,("adding port [%d]'s size\n", i)); *needed += spoolss_size_port_info_1(&(ports[i])); } - if (!alloc_buffer_size(buffer, *needed)) + if (!alloc_buffer_size(buffer, *needed)) { + safe_free(ports); return ERROR_INSUFFICIENT_BUFFER; + } /* fill the buffer with the ports structures */ - for (i=0; i<*returned; i++) - { + for (i=0; i<*returned; i++) { DEBUGADD(6,("adding port [%d] to buffer\n", i)); new_smb_io_port_1("", buffer, &(ports[i]), 0); } @@ -3406,8 +3533,7 @@ static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need ports=(PORT_INFO_2 *)malloc( (*returned+1) * sizeof(PORT_INFO_2) ); - for (snum=0; snum<n_services; snum++) - { + for (snum=0; snum<n_services; snum++) { if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) { DEBUGADD(6,("Filling port number [%d]\n", i)); fill_port_2(&(ports[i]), lp_servicename(snum)); @@ -3416,18 +3542,18 @@ static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *need } /* check the required size. */ - for (i=0; i<*returned; i++) - { + for (i=0; i<*returned; i++) { DEBUGADD(6,("adding port [%d]'s size\n", i)); *needed += spoolss_size_port_info_2(&(ports[i])); } - if (!alloc_buffer_size(buffer, *needed)) + if (!alloc_buffer_size(buffer, *needed)) { + safe_free(ports); return ERROR_INSUFFICIENT_BUFFER; + } /* fill the buffer with the ports structures */ - for (i=0; i<*returned; i++) - { + for (i=0; i<*returned; i++) { DEBUGADD(6,("adding port [%d] to buffer\n", i)); new_smb_io_port_2("", buffer, &(ports[i]), 0); } @@ -3469,7 +3595,7 @@ uint32 _spoolss_enumports( UNISTR2 *name, uint32 level, /**************************************************************************** ****************************************************************************/ -uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level, +static uint32 spoolss_addprinterex_level_2( const UNISTR2 *uni_srv_name, const SPOOL_PRINTER_INFO_LEVEL *info, uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3, uint32 user_switch, const SPOOL_USER_CTR *user, @@ -3481,45 +3607,63 @@ uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level, clear_handle(handle); -/* - * FIX: JFM: we need to check the user here !!!! - * - * as the code is running as root, anybody can add printers to the server - */ /* NULLify info_2 here */ /* don't put it in convert_printer_info as it's used also with non-NULL values */ printer.info_2=NULL; /* convert from UNICODE to ASCII */ - convert_printer_info(info, &printer, level); + convert_printer_info(info, &printer, 2); - unistr2_to_ascii(share_name, &((info->info_2)->portname), sizeof(share_name)-1); + unistr2_to_ascii(share_name, &((info->info_2)->printername), sizeof(share_name)-1); slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname, share_name); + /* write the ASCII on disk */ + if (add_a_printer(printer, 2) != 0x0) + return ERROR_ACCESS_DENIED; + create_printer_hnd(handle); open_printer_hnd(handle); if (!set_printer_hnd_printertype(handle, name)) { close_printer_handle(handle); - return NT_STATUS_ACCESS_DENIED; + return ERROR_ACCESS_DENIED; } if (!set_printer_hnd_printername(handle, name)) { close_printer_handle(handle); - return NT_STATUS_ACCESS_DENIED; + return ERROR_ACCESS_DENIED; } - /* write the ASCII on disk */ - if (add_a_printer(printer, level) != 0x0) { - close_printer_handle(handle); - return NT_STATUS_ACCESS_DENIED; + return NT_STATUS_NO_PROBLEMO; } - return NT_STATUS_NO_PROBLEMO; +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level, + const SPOOL_PRINTER_INFO_LEVEL *info, + uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3, + uint32 user_switch, const SPOOL_USER_CTR *user, + POLICY_HND *handle) +{ + switch (level) { + case 1: + /* we don't handle yet */ + /* but I know what to do ... */ + break; + case 2: + return spoolss_addprinterex_level_2(uni_srv_name, info, + unk0, unk1, unk2, unk3, + user_switch, user, handle); + break; + default: + return ERROR_INVALID_LEVEL; + break; +} } + /**************************************************************************** ****************************************************************************/ uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name, @@ -3565,8 +3709,10 @@ static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen *needed += spoolss_size_driverdir_info_1(info); - if (!alloc_buffer_size(buffer, *needed)) + if (!alloc_buffer_size(buffer, *needed)) { + safe_free(info); return ERROR_INSUFFICIENT_BUFFER; + } new_smb_io_driverdir_1("", buffer, info, 0); @@ -3593,7 +3739,7 @@ uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environmen return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed); break; default: - return NT_STATUS_INVALID_INFO_CLASS; + return ERROR_INVALID_LEVEL; break; } } @@ -3604,7 +3750,7 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 idx, uint32 in_value_len, uint32 in_data_len, uint32 *out_max_value_len, uint16 **out_value, uint32 *out_value_len, uint32 *out_type, - uint32 *out_max_data_len, uint8 **out_pdata, uint32 *out_data_len) + uint32 *out_max_data_len, uint8 **data_out, uint32 *out_data_len) { NT_PRINTER_INFO_LEVEL printer; @@ -3628,7 +3774,7 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 idx, *out_type=0; *out_max_data_len=0; - *out_pdata=NULL; + *data_out=NULL; *out_data_len=0; DEBUG(5,("spoolss_enumprinterdata\n")); @@ -3681,7 +3827,7 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 idx, if (!get_specific_param_by_index(printer, 2, idx, value, &data, &type, &data_len)) { free_a_printer(printer, 2); - return 0x0103; /* ERROR_NO_MORE_ITEMS */ + return ERROR_NO_MORE_ITEMS; } /* @@ -3702,8 +3848,8 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 idx, /* the data is counted in bytes */ *out_max_data_len=in_data_len; - *out_pdata=(uint8 *)malloc(in_data_len*sizeof(uint8)); - memcpy(*out_pdata, data, data_len); + *data_out=(uint8 *)malloc(in_data_len*sizeof(uint8)); + memcpy(*data_out, data, data_len); *out_data_len=data_len; safe_free(data); @@ -4051,6 +4197,8 @@ static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uin /**************************************************************************** ****************************************************************************/ +#if 0 +... Not yet used... static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { int i=0; @@ -4090,6 +4238,7 @@ static uint32 getjob_level_2(print_queue_struct *queue, int count, int snum, uin else return NT_STATUS_NO_PROBLEMO; } +#endif /**************************************************************************** ****************************************************************************/ |