From bd9d4cdde9193c120c6f4e8cf72f87cd67a9387e Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Mon, 7 Feb 2000 16:17:59 +0000 Subject: First commit of the spoolss code to the HEAD branch. still needs a lot of cleaning/debuging. J.F. --- source/include/nt_printing.h | 237 ++ source/include/rpc_spoolss.h | 1441 +++++++++++ source/printing/nt_printing.c | 1413 +++++++++++ source/rpc_parse/parse_spoolss.c | 4806 ++++++++++++++++++++++++++++++++++++ source/rpc_server/srv_spoolss.c | 793 ++++++ source/rpc_server/srv_spoolss_nt.c | 3434 ++++++++++++++++++++++++++ 6 files changed, 12124 insertions(+) create mode 100644 source/include/nt_printing.h create mode 100755 source/include/rpc_spoolss.h create mode 100644 source/printing/nt_printing.c create mode 100644 source/rpc_parse/parse_spoolss.c create mode 100755 source/rpc_server/srv_spoolss.c create mode 100644 source/rpc_server/srv_spoolss_nt.c diff --git a/source/include/nt_printing.h b/source/include/nt_printing.h new file mode 100644 index 00000000000..22c837c7481 --- /dev/null +++ b/source/include/nt_printing.h @@ -0,0 +1,237 @@ +#define ORIENTATION 0x00000001L +#define PAPERSIZE 0x00000002L +#define PAPERLENGTH 0x00000004L +#define PAPERWIDTH 0x00000008L +#define SCALE 0x00000010L +#define COPIES 0x00000100L +#define DEFAULTSOURCE 0x00000200L +#define PRINTQUALITY 0x00000400L +#define COLOR 0x00000800L +#define DUPLEX 0x00001000L +#define YRESOLUTION 0x00002000L +#define TTOPTION 0x00004000L +#define COLLATE 0x00008000L +#define FORMNAME 0x00010000L +#define LOGPIXELS 0x00020000L +#define BITSPERPEL 0x00040000L +#define PELSWIDTH 0x00080000L +#define PELSHEIGHT 0x00100000L +#define DISPLAYFLAGS 0x00200000L +#define DISPLAYFREQUENCY 0x00400000L +#define PANNINGWIDTH 0x00800000L +#define PANNINGHEIGHT 0x01000000L + +#define ORIENT_PORTRAIT 1 +#define ORIENT_LANDSCAPE 2 + +#define PAPER_FIRST PAPER_LETTER +#define PAPER_LETTER 1 /* Letter 8 1/2 x 11 in */ +#define PAPER_LETTERSMALL 2 /* Letter Small 8 1/2 x 11 in */ +#define PAPER_TABLOID 3 /* Tabloid 11 x 17 in */ +#define PAPER_LEDGER 4 /* Ledger 17 x 11 in */ +#define PAPER_LEGAL 5 /* Legal 8 1/2 x 14 in */ +#define PAPER_STATEMENT 6 /* Statement 5 1/2 x 8 1/2 in */ +#define PAPER_EXECUTIVE 7 /* Executive 7 1/4 x 10 1/2 in */ +#define PAPER_A3 8 /* A3 297 x 420 mm */ +#define PAPER_A4 9 /* A4 210 x 297 mm */ +#define PAPER_A4SMALL 10 /* A4 Small 210 x 297 mm */ +#define PAPER_A5 11 /* A5 148 x 210 mm */ +#define PAPER_B4 12 /* B4 (JIS) 250 x 354 */ +#define PAPER_B5 13 /* B5 (JIS) 182 x 257 mm */ +#define PAPER_FOLIO 14 /* Folio 8 1/2 x 13 in */ +#define PAPER_QUARTO 15 /* Quarto 215 x 275 mm */ +#define PAPER_10X14 16 /* 10x14 in */ +#define PAPER_11X17 17 /* 11x17 in */ +#define PAPER_NOTE 18 /* Note 8 1/2 x 11 in */ +#define PAPER_ENV_9 19 /* Envelope #9 3 7/8 x 8 7/8 */ +#define PAPER_ENV_10 20 /* Envelope #10 4 1/8 x 9 1/2 */ +#define PAPER_ENV_11 21 /* Envelope #11 4 1/2 x 10 3/8 */ +#define PAPER_ENV_12 22 /* Envelope #12 4 \276 x 11 */ +#define PAPER_ENV_14 23 /* Envelope #14 5 x 11 1/2 */ +#define PAPER_CSHEET 24 /* C size sheet */ +#define PAPER_DSHEET 25 /* D size sheet */ +#define PAPER_ESHEET 26 /* E size sheet */ +#define PAPER_ENV_DL 27 /* Envelope DL 110 x 220mm */ +#define PAPER_ENV_C5 28 /* Envelope C5 162 x 229 mm */ +#define PAPER_ENV_C3 29 /* Envelope C3 324 x 458 mm */ +#define PAPER_ENV_C4 30 /* Envelope C4 229 x 324 mm */ +#define PAPER_ENV_C6 31 /* Envelope C6 114 x 162 mm */ +#define PAPER_ENV_C65 32 /* Envelope C65 114 x 229 mm */ +#define PAPER_ENV_B4 33 /* Envelope B4 250 x 353 mm */ +#define PAPER_ENV_B5 34 /* Envelope B5 176 x 250 mm */ +#define PAPER_ENV_B6 35 /* Envelope B6 176 x 125 mm */ +#define PAPER_ENV_ITALY 36 /* Envelope 110 x 230 mm */ +#define PAPER_ENV_MONARCH 37 /* Envelope Monarch 3.875 x 7.5 in */ +#define PAPER_ENV_PERSONAL 38 /* 6 3/4 Envelope 3 5/8 x 6 1/2 in */ +#define PAPER_FANFOLD_US 39 /* US Std Fanfold 14 7/8 x 11 in */ +#define PAPER_FANFOLD_STD_GERMAN 40 /* German Std Fanfold 8 1/2 x 12 in */ +#define PAPER_FANFOLD_LGL_GERMAN 41 /* German Legal Fanfold 8 1/2 x 13 in */ + +#define PAPER_LAST PAPER_FANFOLD_LGL_GERMAN +#define PAPER_USER 256 + +#define BIN_FIRST BIN_UPPER +#define BIN_UPPER 1 +#define BIN_ONLYONE 1 +#define BIN_LOWER 2 +#define BIN_MIDDLE 3 +#define BIN_MANUAL 4 +#define BIN_ENVELOPE 5 +#define BIN_ENVMANUAL 6 +#define BIN_AUTO 7 +#define BIN_TRACTOR 8 +#define BIN_SMALLFMT 9 +#define BIN_LARGEFMT 10 +#define BIN_LARGECAPACITY 11 +#define BIN_CASSETTE 14 +#define BIN_FORMSOURCE 15 +#define BIN_LAST BIN_FORMSOURCE + +#define BIN_USER 256 /* device specific bins start here */ + +#define RES_DRAFT (-1) +#define RES_LOW (-2) +#define RES_MEDIUM (-3) +#define RES_HIGH (-4) + +#define COLOR_MONOCHROME 1 +#define COLOR_COLOR 2 + +#define DUP_SIMPLEX 1 +#define DUP_VERTICAL 2 +#define DUP_HORIZONTAL 3 + +#define TT_BITMAP 1 /* print TT fonts as graphics */ +#define TT_DOWNLOAD 2 /* download TT fonts as soft fonts */ +#define TT_SUBDEV 3 /* substitute device fonts for TT fonts */ + +#define COLLATE_FALSE 0 +#define COLLATE_TRUE 1 + +typedef struct nt_printer_driver_info_level_3 +{ + uint32 cversion; + + fstring name; + fstring environment; + fstring driverpath; + fstring datafile; + fstring configfile; + fstring helpfile; + fstring monitorname; + fstring defaultdatatype; + char **dependentfiles; + +} NT_PRINTER_DRIVER_INFO_LEVEL_3; + +typedef struct nt_printer_driver_info_level +{ + NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3; +} NT_PRINTER_DRIVER_INFO_LEVEL; + +typedef struct nt_printer_param +{ + fstring value; + uint32 type; + uint8 *data; + int data_len; + struct nt_printer_param *next; +} NT_PRINTER_PARAM; + +typedef struct ntdevicemode +{ + fstring devicename; + uint16 specversion; + uint16 driverversion; + uint16 size; + uint16 driverextra; + uint32 fields; + uint16 orientation; + uint16 papersize; + uint16 paperlength; + uint16 paperwidth; + uint16 scale; + uint16 copies; + uint16 defaultsource; + uint16 printquality; + uint16 color; + uint16 duplex; + uint16 yresolution; + uint16 ttoption; + uint16 collate; + fstring formname; + uint16 logpixels; + uint32 bitsperpel; + uint32 pelswidth; + uint32 pelsheight; + uint32 displayflags; + uint32 displayfrequency; + uint32 icmmethod; + uint32 icmintent; + uint32 mediatype; + uint32 dithertype; + uint32 reserved1; + uint32 reserved2; + uint32 panningwidth; + uint32 panningheight; + uint8 *private; +} NT_DEVICEMODE; + +typedef struct nt_printer_info_level_2 +{ + uint32 attributes; + uint32 priority; + uint32 default_priority; + uint32 starttime; + uint32 untiltime; + uint32 status; + uint32 cjobs; + uint32 averageppm; + fstring servername; + fstring printername; + fstring sharename; + fstring portname; + fstring drivername; + fstring comment; + fstring location; + NT_DEVICEMODE *devmode; + fstring sepfile; + fstring printprocessor; + fstring datatype; + fstring parameters; + NT_PRINTER_PARAM *specific; + /* SEC_DESC_BUF *secdesc; */ + /* not used but ... and how ??? */ +} NT_PRINTER_INFO_LEVEL_2; + +typedef struct nt_printer_info_level +{ + NT_PRINTER_INFO_LEVEL_2 *info_2; +} NT_PRINTER_INFO_LEVEL; + +typedef struct +{ + char name[100]; + uint32 flag; + uint32 width; + uint32 length; + uint32 left; + uint32 top; + uint32 right; + uint32 bottom; +} nt_forms_struct; + +/* +typedef struct _form +{ + uint32 flags; + uint32 name_ptr; + uint32 size_x; + uint32 size_y; + uint32 left; + uint32 top; + uint32 right; + uint32 bottom; + UNISTR2 name; +} FORM; +*/ diff --git a/source/include/rpc_spoolss.h b/source/include/rpc_spoolss.h new file mode 100755 index 00000000000..5aef2f3f639 --- /dev/null +++ b/source/include/rpc_spoolss.h @@ -0,0 +1,1441 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB parameters and setup + Copyright (C) Andrew Tridgell 1992-2000, + Copyright (C) Luke Kenneth Casson Leighton 1996-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 _RPC_SPOOLSS_H /* _RPC_SPOOLSS_H */ +#define _RPC_SPOOLSS_H + +#define INTEGER 1 +#define STRING 2 + +/* spoolss pipe: this are the calls which are not implemented ... +#define SPOOLSS_OPENPRINTER 0x01 +#define SPOOLSS_DELETEPRINTER 0x06 +#define SPOOLSS_GETPRINTERDRIVER 0x0b +#define SPOOLSS_DELETEPRINTERDRIVER 0x0d +#define SPOOLSS_ADDPRINTPROCESSOR 0x0e +#define SPOOLSS_GETPRINTPROCESSORDIRECTORY 0x10 +#define SPOOLSS_ABORTPRINTER 0x15 +#define SPOOLSS_READPRINTER 0x16 +#define SPOOLSS_WAITFORPRINTERCHANGE 0x1c +#define SPOOLSS_DELETEFORM 0x1f +#define SPOOLSS_GETFORM 0x20 +#define SPOOLSS_ADDPORT 0x25 +#define SPOOLSS_CONFIGUREPORT 0x26 +#define SPOOLSS_DELETEPORT 0x27 +#define SPOOLSS_CREATEPRINTERIC 0x28 +#define SPOOLSS_PLAYGDISCRIPTONPRINTERIC 0x29 +#define SPOOLSS_DELETEPRINTERIC 0x2a +#define SPOOLSS_ADDPRINTERCONNECTION 0x2b +#define SPOOLSS_DELETEPRINTERCONNECTION 0x2c +#define SPOOLSS_PRINTERMESSAGEBOX 0x2d +#define SPOOLSS_ADDMONITOR 0x2e +#define SPOOLSS_DELETEMONITOR 0x2f +#define SPOOLSS_DELETEPRINTPROCESSOR 0x30 +#define SPOOLSS_ADDPRINTPROVIDOR 0x31 +#define SPOOLSS_DELETEPRINTPROVIDOR 0x32 +#define SPOOLSS_RESETPRINTER 0x34 +#define SPOOLSS_FINDFIRSTPRINTERCHANGENOTIFICATION 0x36 +#define SPOOLSS_FINDNEXTPRINTERCHANGENOTIFICATION 0x37 +#define SPOOLSS_ROUTERFINDFIRSTPRINTERNOTIFICATIONOLD 0x39 +#define SPOOLSS_REPLYOPENPRINTER 0x3a +#define SPOOLSS_ROUTERREPLYPRINTER 0x3b +#define SPOOLSS_REPLYCLOSEPRINTER 0x3c +#define SPOOLSS_ADDPORTEX 0x3d +#define SPOOLSS_REMOTEFINDFIRSTPRINTERCHANGENOTIFICATION0x3e +#define SPOOLSS_SPOOLERINIT 0x3f +#define SPOOLSS_RESETPRINTEREX 0x40 +#define SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFICATION 0x42 +*/ + +/* those are implemented */ +#define SPOOLSS_ENUMPRINTERS 0x00 +#define SPOOLSS_SETJOB 0x02 +#define SPOOLSS_GETJOB 0x03 +#define SPOOLSS_ENUMJOBS 0x04 +#define SPOOLSS_ADDPRINTER 0x05 +#define SPOOLSS_SETPRINTER 0x07 +#define SPOOLSS_GETPRINTER 0x08 +#define SPOOLSS_ADDPRINTERDRIVER 0x09 +#define SPOOLSS_ENUMPRINTERDRIVERS 0x0a +#define SPOOLSS_GETPRINTERDRIVERDIRECTORY 0x0c +#define SPOOLSS_ENUMPRINTPROCESSORS 0x0f +#define SPOOLSS_STARTDOCPRINTER 0x11 +#define SPOOLSS_STARTPAGEPRINTER 0x12 +#define SPOOLSS_WRITEPRINTER 0x13 +#define SPOOLSS_ENDPAGEPRINTER 0x14 +#define SPOOLSS_ENDDOCPRINTER 0x17 +#define SPOOLSS_ADDJOB 0x18 +#define SPOOLSS_SCHEDULEJOB 0x19 +#define SPOOLSS_GETPRINTERDATA 0x1a +#define SPOOLSS_SETPRINTERDATA 0x1b +#define SPOOLSS_CLOSEPRINTER 0x1d +#define SPOOLSS_ADDFORM 0x1e +#define SPOOLSS_SETFORM 0x21 +#define SPOOLSS_ENUMFORMS 0x22 +#define SPOOLSS_ENUMPORTS 0x23 +#define SPOOLSS_ENUMMONITORS 0x24 +#define SPOOLSS_ENUMPRINTPROCESSORDATATYPES 0x33 +#define SPOOLSS_GETPRINTERDRIVER2 0x35 +/* find close printer notification */ +#define SPOOLSS_FCPN 0x38 +/* remote find first printer change notifyEx */ +#define SPOOLSS_RFFPCNEX 0x41 +/* remote find next printer change notifyEx */ +#define SPOOLSS_RFNPCNEX 0x43 +#define SPOOLSS_OPENPRINTEREX 0x45 +#define SPOOLSS_ADDPRINTEREX 0x46 +#define SPOOLSS_ENUMPRINTERDATA 0x48 + +#define SERVER_ACCESS_ADMINISTER 0x00000001 +#define SERVER_ACCESS_ENUMERATE 0x00000002 + +#define PRINTER_ACCESS_ADMINISTER 0x00000004 +#define PRINTER_ACCESS_USE 0x00000008 + +#define PRINTER_CONTROL_UNPAUSE 0x00000000 +#define PRINTER_CONTROL_PAUSE 0x00000001 +#define PRINTER_CONTROL_RESUME 0x00000002 +#define PRINTER_CONTROL_PURGE 0x00000003 +#define PRINTER_CONTROL_SET_STATUS 0x00000004 + +#define PRINTER_STATUS_PAUSED 0x00000001 +#define PRINTER_STATUS_ERROR 0x00000002 +#define PRINTER_STATUS_PENDING_DELETION 0x00000004 +#define PRINTER_STATUS_PAPER_JAM 0x00000008 + +#define PRINTER_STATUS_PAPER_OUT 0x00000010 +#define PRINTER_STATUS_MANUAL_FEED 0x00000020 +#define PRINTER_STATUS_PAPER_PROBLEM 0x00000040 +#define PRINTER_STATUS_OFFLINE 0x00000080 + +#define PRINTER_STATUS_IO_ACTIVE 0x00000100 +#define PRINTER_STATUS_BUSY 0x00000200 +#define PRINTER_STATUS_PRINTING 0x00000400 +#define PRINTER_STATUS_OUTPUT_BIN_FULL 0x00000800 + +#define PRINTER_STATUS_NOT_AVAILABLE 0x00001000 +#define PRINTER_STATUS_WAITING 0x00002000 +#define PRINTER_STATUS_PROCESSING 0x00004000 +#define PRINTER_STATUS_INITIALIZING 0x00008000 + +#define PRINTER_STATUS_WARMING_UP 0x00010000 +#define PRINTER_STATUS_TONER_LOW 0x00020000 +#define PRINTER_STATUS_NO_TONER 0x00040000 +#define PRINTER_STATUS_PAGE_PUNT 0x00080000 + +#define PRINTER_STATUS_USER_INTERVENTION 0x00100000 +#define PRINTER_STATUS_OUT_OF_MEMORY 0x00200000 +#define PRINTER_STATUS_DOOR_OPEN 0x00400000 +#define PRINTER_STATUS_SERVER_UNKNOWN 0x00800000 + +#define PRINTER_STATUS_POWER_SAVE 0x01000000 + +#define JOB_ACCESS_ADMINISTER 0x00000010 + +#define STANDARD_RIGHTS_READ 0x00020000 +#define STANDARD_RIGHTS_WRITE STANDARD_RIGHTS_READ +#define STANDARD_RIGHTS_EXECUTE STANDARD_RIGHTS_READ +#define STANDARD_RIGHTS_REQUIRED 0x000F0000 + +/* Access rights for print servers */ +#define SERVER_ALL_ACCESS STANDARD_RIGHTS_REQUIRED|SERVER_ACCESS_ADMINISTER|SERVER_ACCESS_ENUMERATE +#define SERVER_READ STANDARD_RIGHTS_READ|SERVER_ACCESS_ENUMERATE +#define SERVER_WRITE STANDARD_RIGHTS_WRITE|SERVER_ACCESS_ADMINISTER|SERVER_ACCESS_ENUMERATE +#define SERVER_EXECUTE STANDARD_RIGHTS_EXECUTE|SERVER_ACCESS_ENUMERATE + +/* Access rights for printers */ +#define PRINTER_ALL_ACCESS STANDARD_RIGHTS_REQUIRED|PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE +#define PRINTER_READ STANDARD_RIGHTS_READ|PRINTER_ACCESS_USE +#define PRINTER_WRITE STANDARD_RIGHTS_WRITE|PRINTER_ACCESS_USE +#define PRINTER_EXECUTE STANDARD_RIGHTS_EXECUTE|PRINTER_ACCESS_USE + +/* Access rights for jobs */ +#define JOB_ALL_ACCESS STANDARD_RIGHTS_REQUIRED|JOB_ACCESS_ADMINISTER +#define JOB_READ STANDARD_RIGHTS_READ|JOB_ACCESS_ADMINISTER +#define JOB_WRITE STANDARD_RIGHTS_WRITE|JOB_ACCESS_ADMINISTER +#define JOB_EXECUTE STANDARD_RIGHTS_EXECUTE|JOB_ACCESS_ADMINISTER + +#define POLICY_HND_SIZE 20 + +#define ONE_VALUE 01 +#define TWO_VALUE 02 +#define POINTER 03 + +#define PRINTER_NOTIFY_TYPE 0x00 +#define JOB_NOTIFY_TYPE 0x01 + +#define MAX_PRINTER_NOTIFY 26 + +#define PRINTER_NOTIFY_SERVER_NAME 0x00 +#define PRINTER_NOTIFY_PRINTER_NAME 0x01 +#define PRINTER_NOTIFY_SHARE_NAME 0x02 +#define PRINTER_NOTIFY_PORT_NAME 0x03 +#define PRINTER_NOTIFY_DRIVER_NAME 0x04 +#define PRINTER_NOTIFY_COMMENT 0x05 +#define PRINTER_NOTIFY_LOCATION 0x06 +#define PRINTER_NOTIFY_DEVMODE 0x07 +#define PRINTER_NOTIFY_SEPFILE 0x08 +#define PRINTER_NOTIFY_PRINT_PROCESSOR 0x09 +#define PRINTER_NOTIFY_PARAMETERS 0x0A +#define PRINTER_NOTIFY_DATATYPE 0x0B +#define PRINTER_NOTIFY_SECURITY_DESCRIPTOR 0x0C +#define PRINTER_NOTIFY_ATTRIBUTES 0x0D +#define PRINTER_NOTIFY_PRIORITY 0x0E +#define PRINTER_NOTIFY_DEFAULT_PRIORITY 0x0F +#define PRINTER_NOTIFY_START_TIME 0x10 +#define PRINTER_NOTIFY_UNTIL_TIME 0x11 +#define PRINTER_NOTIFY_STATUS 0x12 +#define PRINTER_NOTIFY_STATUS_STRING 0x13 +#define PRINTER_NOTIFY_CJOBS 0x14 +#define PRINTER_NOTIFY_AVERAGE_PPM 0x15 +#define PRINTER_NOTIFY_TOTAL_PAGES 0x16 +#define PRINTER_NOTIFY_PAGES_PRINTED 0x17 +#define PRINTER_NOTIFY_TOTAL_BYTES 0x18 +#define PRINTER_NOTIFY_BYTES_PRINTED 0x19 + +#define MAX_JOB_NOTIFY 24 + +#define JOB_NOTIFY_PRINTER_NAME 0x00 +#define JOB_NOTIFY_MACHINE_NAME 0x01 +#define JOB_NOTIFY_PORT_NAME 0x02 +#define JOB_NOTIFY_USER_NAME 0x03 +#define JOB_NOTIFY_NOTIFY_NAME 0x04 +#define JOB_NOTIFY_DATATYPE 0x05 +#define JOB_NOTIFY_PRINT_PROCESSOR 0x06 +#define JOB_NOTIFY_PARAMETERS 0x07 +#define JOB_NOTIFY_DRIVER_NAME 0x08 +#define JOB_NOTIFY_DEVMODE 0x09 +#define JOB_NOTIFY_STATUS 0x0A +#define JOB_NOTIFY_STATUS_STRING 0x0B +#define JOB_NOTIFY_SECURITY_DESCRIPTOR 0x0C +#define JOB_NOTIFY_DOCUMENT 0x0D +#define JOB_NOTIFY_PRIORITY 0x0E +#define JOB_NOTIFY_POSITION 0x0F +#define JOB_NOTIFY_SUBMITTED 0x10 +#define JOB_NOTIFY_START_TIME 0x11 +#define JOB_NOTIFY_UNTIL_TIME 0x12 +#define JOB_NOTIFY_TIME 0x13 +#define JOB_NOTIFY_TOTAL_PAGES 0x14 +#define JOB_NOTIFY_PAGES_PRINTED 0x15 +#define JOB_NOTIFY_TOTAL_BYTES 0x16 +#define JOB_NOTIFY_BYTES_PRINTED 0x17 + +/* + * The printer attributes. + * I #defined all of them (grabbed form MSDN) + * I'm only using: + * ( SHARED | NETWORK | RAW_ONLY ) + * RAW_ONLY _MUST_ be present otherwise NT will send an EMF file + */ + +#define PRINTER_ATTRIBUTE_QUEUED 0x00000001 +#define PRINTER_ATTRIBUTE_DIRECT 0x00000002 +#define PRINTER_ATTRIBUTE_DEFAULT 0x00000004 +#define PRINTER_ATTRIBUTE_SHARED 0x00000008 + +#define PRINTER_ATTRIBUTE_NETWORK 0x00000010 +#define PRINTER_ATTRIBUTE_HIDDEN 0x00000020 +#define PRINTER_ATTRIBUTE_LOCAL 0x00000040 +#define PRINTER_ATTRIBUTE_ENABLE_DEVQ 0x00000080 + +#define PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS 0x00000100 +#define PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST 0x00000200 +#define PRINTER_ATTRIBUTE_WORK_OFFLINE 0x00000400 +#define PRINTER_ATTRIBUTE_ENABLE_BIDI 0x00000800 + +#define PRINTER_ATTRIBUTE_RAW_ONLY 0x00001000 + +#define NO_PRIORITY 0 +#define MAX_PRIORITY 99 +#define MIN_PRIORITY 1 +#define DEF_PRIORITY 1 + +#define PRINTER_ENUM_DEFAULT 0x00000001 +#define PRINTER_ENUM_LOCAL 0x00000002 +#define PRINTER_ENUM_CONNECTIONS 0x00000004 +#define PRINTER_ENUM_FAVORITE 0x00000004 +#define PRINTER_ENUM_NAME 0x00000008 +#define PRINTER_ENUM_REMOTE 0x00000010 +#define PRINTER_ENUM_SHARED 0x00000020 +#define PRINTER_ENUM_NETWORK 0x00000040 + +#define PRINTER_ENUM_EXPAND 0x00004000 +#define PRINTER_ENUM_CONTAINER 0x00008000 + +#define PRINTER_ENUM_ICONMASK 0x00ff0000 +#define PRINTER_ENUM_ICON1 0x00010000 +#define PRINTER_ENUM_ICON2 0x00020000 +#define PRINTER_ENUM_ICON3 0x00040000 +#define PRINTER_ENUM_ICON4 0x00080000 +#define PRINTER_ENUM_ICON5 0x00100000 +#define PRINTER_ENUM_ICON6 0x00200000 +#define PRINTER_ENUM_ICON7 0x00400000 +#define PRINTER_ENUM_ICON8 0x00800000 + +#define POLICY_HND_SIZE 20 + +/* this struct is undocumented */ +/* thanks to the ddk ... */ +typedef struct spool_user_1 +{ + uint32 size; + uint32 client_name_ptr; + uint32 user_name_ptr; + uint32 build; + uint32 major; + uint32 minor; + uint32 processor; + UNISTR2 client_name; + UNISTR2 user_name; +} SPOOL_USER_1; + +typedef struct spool_user_ctr_info +{ + uint32 level; + uint32 ptr; + SPOOL_USER_1 user1; +} SPOOL_USER_CTR; + +typedef struct devicemode +{ + UNISTR devicename; + uint16 specversion; + uint16 driverversion; + uint16 size; + uint16 driverextra; + uint32 fields; + uint16 orientation; + uint16 papersize; + uint16 paperlength; + uint16 paperwidth; + uint16 scale; + uint16 copies; + uint16 defaultsource; + uint16 printquality; + uint16 color; + uint16 duplex; + uint16 yresolution; + uint16 ttoption; + uint16 collate; + UNISTR formname; + uint16 logpixels; + uint32 bitsperpel; + uint32 pelswidth; + uint32 pelsheight; + uint32 displayflags; + uint32 displayfrequency; + uint32 icmmethod; + uint32 icmintent; + uint32 mediatype; + uint32 dithertype; + uint32 reserved1; + uint32 reserved2; + uint32 panningwidth; + uint32 panningheight; + uint8 *private; +} DEVICEMODE; + +typedef struct _devmode_cont +{ + uint32 size; + uint32 devmode_ptr; + DEVICEMODE *devmode; +} DEVMODE_CTR; + +typedef struct _printer_default +{ + uint32 datatype_ptr; + UNISTR2 datatype; + DEVMODE_CTR devmode_cont; + uint32 access_required; +} PRINTER_DEFAULT; + +/* SPOOL_Q_OPEN_PRINTER_EX request to open a printer */ +typedef struct spool_q_open_printer_ex +{ + uint32 printername_ptr; + UNISTR2 printername; + PRINTER_DEFAULT printer_default; + uint32 user_switch; + SPOOL_USER_CTR user_ctr; +} SPOOL_Q_OPEN_PRINTER_EX; + +/* SPOOL_Q_OPEN_PRINTER_EX reply to an open printer */ +typedef struct spool_r_open_printer_ex +{ + POLICY_HND handle; /* handle used along all transactions (20*uint8) */ + uint32 status; + +} SPOOL_R_OPEN_PRINTER_EX; + +typedef struct spool_notify_option_type +{ + uint16 type; + uint16 reserved0; + uint32 reserved1; + uint32 reserved2; + uint32 count; + uint16 fields[16]; +} SPOOL_NOTIFY_OPTION_TYPE; + + +typedef struct s_header_type +{ + uint32 type; + union + { + uint32 value; + UNISTR string; + } data; +} HEADER_TYPE; + +typedef struct s_buffer +{ + uint32 ptr; + uint32 size; + uint32 count; + uint8 *data; + HEADER_TYPE *header; +} BUFFER; + +typedef struct new_buffer +{ + uint32 ptr; + uint32 size; + prs_struct prs; + uint32 struct_start; + uint32 string_at_end; +} NEW_BUFFER; + +typedef struct spool_q_getprinterdata +{ + POLICY_HND handle; + UNISTR2 valuename; + uint32 size; +} SPOOL_Q_GETPRINTERDATA; + +typedef struct spool_r_getprinterdata +{ + uint32 type; + uint32 size; + uint8 *data; + uint32 needed; + uint32 status; +} SPOOL_R_GETPRINTERDATA; + +typedef struct spool_q_closeprinter +{ + POLICY_HND handle; +} SPOOL_Q_CLOSEPRINTER; + +typedef struct spool_r_closeprinter +{ + POLICY_HND handle; + uint32 status; +} SPOOL_R_CLOSEPRINTER; + +typedef struct spool_q_startpageprinter +{ + POLICY_HND handle; +} SPOOL_Q_STARTPAGEPRINTER; + +typedef struct spool_r_startpageprinter +{ + uint32 status; +} SPOOL_R_STARTPAGEPRINTER; + +typedef struct spool_q_endpageprinter +{ + POLICY_HND handle; +} SPOOL_Q_ENDPAGEPRINTER; + +typedef struct spool_r_endpageprinter +{ + uint32 status; +} SPOOL_R_ENDPAGEPRINTER; + +typedef struct spool_doc_info_1 +{ + uint32 p_docname; + uint32 p_outputfile; + uint32 p_datatype; + UNISTR2 docname; + UNISTR2 outputfile; + UNISTR2 datatype; +} DOC_INFO_1; + +typedef struct spool_doc_info +{ + uint32 switch_value; + DOC_INFO_1 doc_info_1; +} DOC_INFO; + +typedef struct spool_doc_info_container +{ + uint32 level; + DOC_INFO docinfo; +} DOC_INFO_CONTAINER; + +typedef struct spool_q_startdocprinter +{ + POLICY_HND handle; + DOC_INFO_CONTAINER doc_info_container; +} SPOOL_Q_STARTDOCPRINTER; + +typedef struct spool_r_startdocprinter +{ + uint32 jobid; + uint32 status; +} SPOOL_R_STARTDOCPRINTER; + +typedef struct spool_q_enddocprinter +{ + POLICY_HND handle; +} SPOOL_Q_ENDDOCPRINTER; + +typedef struct spool_r_enddocprinter +{ + uint32 status; +} SPOOL_R_ENDDOCPRINTER; + +typedef struct spool_q_writeprinter +{ + POLICY_HND handle; + uint32 buffer_size; + uint8 *buffer; + uint32 buffer_size2; +} SPOOL_Q_WRITEPRINTER; + +typedef struct spool_r_writeprinter +{ + uint32 buffer_written; + uint32 status; +} SPOOL_R_WRITEPRINTER; + +typedef struct spool_notify_option +{ + uint32 version; + uint32 reserved; + uint32 count; + SPOOL_NOTIFY_OPTION_TYPE type[16]; /* totally arbitrary !!! */ +} SPOOL_NOTIFY_OPTION; + +typedef struct spool_notify_info_data +{ + uint16 type; + uint16 field; + uint32 reserved; + uint32 id; + union + { + uint32 value[2]; + struct + { + uint32 length; + uint16 string[1024]; + } data; + } notify_data; + uint32 size; + BOOL enc_type; +} SPOOL_NOTIFY_INFO_DATA; + +typedef struct spool_notify_info +{ + uint32 version; + uint32 flags; + uint32 count; + SPOOL_NOTIFY_INFO_DATA data[26*16]; + /* 26 differents data types */ + /* so size it for 16 printers at max */ + /* jfmxxxx: Have to make it dynamic !!!*/ +} SPOOL_NOTIFY_INFO; + +/* If the struct name looks obscure, yes it is ! */ +/* RemoteFindFirstPrinterChangeNotificationEx query struct */ +typedef struct spoolss_q_rffpcnex +{ + POLICY_HND handle; + uint32 flags; + uint32 options; + UNISTR2 localmachine; + uint32 printerlocal; + SPOOL_NOTIFY_OPTION option; +} SPOOL_Q_RFFPCNEX; + +typedef struct spool_r_rffpcnex +{ + uint32 status; +} SPOOL_R_RFFPCNEX; + +/* Remote Find Next Printer Change Notify Ex */ +typedef struct spool_q_rfnpcnex +{ + POLICY_HND handle; + uint32 change; + SPOOL_NOTIFY_OPTION option; +} SPOOL_Q_RFNPCNEX; + +typedef struct spool_r_rfnpcnex +{ + uint32 count; + SPOOL_NOTIFY_INFO info; + uint32 status; + +} SPOOL_R_RFNPCNEX; + +/* Find Close Printer Notify */ +typedef struct spool_q_fcpn +{ + POLICY_HND handle; +} SPOOL_Q_FCPN; + +typedef struct spool_r_fcpn +{ + uint32 status; +} SPOOL_R_FCPN; + + +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 unknown7; + uint32 unknown8; + uint32 unknown9; + uint32 unknown10; + uint32 unknown11; + uint32 unknown12; + uint32 unknown13; + uint32 unknown14; + uint32 unknown15; + uint32 unknown16; + uint32 unknown17; + uint32 unknown18; + uint32 status; + uint32 unknown20; + uint32 unknown21; + uint16 unknown22; + uint32 unknown23; +} PRINTER_INFO_0; + +typedef struct printer_info_1 +{ + uint32 flags; + UNISTR description; + UNISTR name; + UNISTR comment; +} PRINTER_INFO_1; + +typedef struct printer_info_2 +{ + UNISTR servername; + UNISTR printername; + UNISTR sharename; + UNISTR portname; + UNISTR drivername; + UNISTR comment; + UNISTR location; + DEVICEMODE *devmode; + UNISTR sepfile; + UNISTR printprocessor; + UNISTR datatype; + UNISTR parameters; + /*SECURITY_DESCRIPTOR securitydescriptor;*/ + uint32 attributes; + uint32 priority; + uint32 defaultpriority; + uint32 starttime; + uint32 untiltime; + uint32 status; + uint32 cjobs; + uint32 averageppm; +} PRINTER_INFO_2; + +typedef struct spool_q_enumprinters +{ + uint32 flags; + UNISTR2 servername; + uint32 level; + BUFFER buffer; + uint32 buf_size; +} SPOOL_Q_ENUMPRINTERS; + +typedef struct printer_info_ctr_info +{ + union { + PRINTER_INFO_1 **printers_1; + PRINTER_INFO_2 **printers_2; + void *info; + } printer; + +} PRINTER_INFO_CTR; + +typedef struct spool_r_enumprinters +{ + uint32 offered; /* number of bytes offered */ + uint32 needed; /* bytes needed */ + uint32 level; + UNISTR servername; + PRINTER_INFO_CTR ctr; + uint32 returned; /* number of printers */ + uint32 status; + +} SPOOL_R_ENUMPRINTERS; + + +typedef struct spool_q_getprinter +{ + POLICY_HND handle; + uint32 level; + uint8* buffer; + uint32 offered; + +} SPOOL_Q_GETPRINTER; + +typedef struct printer_info_info +{ + union { + PRINTER_INFO_0 *info0; + PRINTER_INFO_1 *info1; + PRINTER_INFO_2 *info2; + void *info; + } printer; + +} PRINTER_INFO; + +typedef struct spool_r_getprinter +{ + POLICY_HND handle; + uint32 level; + + PRINTER_INFO ctr; + + uint32 offered; + uint32 needed; + uint32 status; + +} SPOOL_R_GETPRINTER; + +struct s_notify_info_data_table +{ + uint16 type; + uint16 field; + char *name; + uint32 size; + void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer); +}; + +typedef struct spool_q_getprinterdriver2 +{ + POLICY_HND handle; + UNISTR2 architecture; + uint32 level; + BUFFER buffer; + uint32 buf_size; + uint32 unknown; + +} SPOOL_Q_GETPRINTERDRIVER2; + +typedef struct driver_info_1 +{ + UNISTR name; +} DRIVER_INFO_1; + +typedef struct driver_info_2 +{ + uint32 version; + UNISTR name; + UNISTR architecture; + UNISTR driverpath; + UNISTR datafile; + UNISTR configfile; +} DRIVER_INFO_2; + +typedef struct driver_info_3 +{ + uint32 version; + UNISTR name; + UNISTR architecture; + UNISTR driverpath; + UNISTR datafile; + UNISTR configfile; + UNISTR helpfile; + UNISTR **dependentfiles; + UNISTR monitorname; + UNISTR defaultdatatype; +} DRIVER_INFO_3; + +typedef struct driver_info_info +{ + union { + DRIVER_INFO_1 *info1; + DRIVER_INFO_2 *info2; + DRIVER_INFO_3 *info3; + } driver; + +} DRIVER_INFO; + +typedef struct spool_r_getprinterdriver2 +{ + uint32 level; + DRIVER_INFO ctr; + uint32 needed; + uint32 offered; + uint32 returned; + uint32 status; + +} SPOOL_R_GETPRINTERDRIVER2; + +typedef struct add_jobinfo_1 +{ + UNISTR path; + uint32 job_number; +} ADD_JOBINFO_1; + + +typedef struct spool_q_addjob +{ + POLICY_HND handle; + uint32 level; + BUFFER buffer; + uint32 buf_size; +} SPOOL_Q_ADDJOB; + +typedef struct spool_r_addjob +{ + uint32 status; +} SPOOL_R_ADDJOB; + +/* + * I'm really wondering how many different time formats + * I will have to cope with + * + * JFM, 09/13/98 In a mad mood ;-( +*/ +typedef struct systemtime +{ + uint16 year; + uint16 month; + uint16 dayofweek; + uint16 day; + uint16 hour; + uint16 minute; + uint16 second; + uint16 milliseconds; +} SYSTEMTIME; + +typedef struct s_job_info_1 +{ + uint32 jobid; + UNISTR printername; + UNISTR machinename; + UNISTR username; + UNISTR document; + UNISTR datatype; + UNISTR text_status; + uint32 status; + uint32 priority; + uint32 position; + uint32 totalpages; + uint32 pagesprinted; + SYSTEMTIME submitted; +} JOB_INFO_1; + +typedef struct s_job_info_2 +{ + uint32 jobid; + UNISTR printername; + UNISTR machinename; + UNISTR username; + UNISTR document; + UNISTR notifyname; + UNISTR datatype; + UNISTR printprocessor; + UNISTR parameters; + UNISTR drivername; + DEVICEMODE *devmode; + UNISTR text_status; +/* SEC_DESC sec_desc;*/ + uint32 status; + uint32 priority; + uint32 position; + uint32 starttime; + uint32 untiltime; + uint32 totalpages; + uint32 size; + SYSTEMTIME submitted; + uint32 timeelapsed; + uint32 pagesprinted; +} JOB_INFO_2; + +typedef struct spool_q_enumjobs +{ + POLICY_HND handle; + uint32 firstjob; + uint32 numofjobs; + uint32 level; + BUFFER buffer; + uint32 buf_size; + +} SPOOL_Q_ENUMJOBS; + +typedef struct job_info_ctr_info +{ + union { + JOB_INFO_1 **job_info_1; + JOB_INFO_2 **job_info_2; + void *info; + } job; + +} JOB_INFO_CTR; + +typedef struct spool_r_enumjobs +{ + uint32 level; + uint32 offered; + JOB_INFO_CTR ctr; + uint32 numofjobs; + uint32 status; + +} SPOOL_R_ENUMJOBS; + +typedef struct spool_q_schedulejob +{ + POLICY_HND handle; + uint32 jobid; +} SPOOL_Q_SCHEDULEJOB; + +typedef struct spool_r_schedulejob +{ + uint32 status; +} SPOOL_R_SCHEDULEJOB; + +typedef struct s_port_info_1 +{ + UNISTR port_name; +} PORT_INFO_1; + +typedef struct s_port_info_2 +{ + UNISTR port_name; + UNISTR monitor_name; + UNISTR description; + uint32 port_type; + uint32 reserved; +} PORT_INFO_2; + +typedef struct spool_q_enumports +{ + UNISTR2 name; + uint32 level; + BUFFER buffer; + uint32 buf_size; +} SPOOL_Q_ENUMPORTS; + +typedef struct port_info_ctr_info +{ + union { + PORT_INFO_1 *info_1; + PORT_INFO_2 *info_2; + } port; + +} PORT_INFO_CTR; + +typedef struct spool_r_enumports +{ + uint32 level; + PORT_INFO_CTR ctr; + uint32 offered; + uint32 numofports; + uint32 status; + +} SPOOL_R_ENUMPORTS; + +#define JOB_CONTROL_PAUSE 1 +#define JOB_CONTROL_RESUME 2 +#define JOB_CONTROL_CANCEL 3 +#define JOB_CONTROL_RESTART 4 +#define JOB_CONTROL_DELETE 5 + +typedef struct job_info_info +{ + union { + JOB_INFO_1 job_info_1; + JOB_INFO_2 job_info_2; + } job; + +} JOB_INFO; + +typedef struct spool_q_setjob +{ + POLICY_HND handle; + uint32 jobid; + uint32 level; + JOB_INFO ctr; + uint32 command; + +} SPOOL_Q_SETJOB; + +typedef struct spool_r_setjob +{ + uint32 status; + +} SPOOL_R_SETJOB; + +typedef struct spool_q_enumprinterdrivers +{ + UNISTR2 name; + UNISTR2 environment; + uint32 level; + BUFFER buffer; + uint32 buf_size; + +} SPOOL_Q_ENUMPRINTERDRIVERS; + +typedef struct spool_r_enumprinterdrivers +{ + uint32 level; + DRIVER_INFO ctr; + uint32 offered; + uint32 numofdrivers; + uint32 status; + +} SPOOL_R_ENUMPRINTERDRIVERS; + +typedef struct spool_form_1 +{ + uint32 flag; + UNISTR name; + uint32 width; + uint32 length; + uint32 left; + uint32 top; + uint32 right; + uint32 bottom; +} FORM_1; + +typedef struct spool_q_enumforms +{ + POLICY_HND handle; + uint32 level; + NEW_BUFFER *buffer; + uint32 offered; +} SPOOL_Q_ENUMFORMS; + +typedef struct spool_r_enumforms +{ + NEW_BUFFER *buffer; + uint32 needed; + uint32 numofforms; + uint32 status; +} SPOOL_R_ENUMFORMS; + + +typedef struct spool_printer_info_level_2 +{ + uint32 servername_ptr; + uint32 printername_ptr; + uint32 sharename_ptr; + uint32 portname_ptr; + uint32 drivername_ptr; + uint32 comment_ptr; + uint32 location_ptr; + uint32 devmode_ptr; + uint32 sepfile_ptr; + uint32 printprocessor_ptr; + uint32 datatype_ptr; + uint32 parameters_ptr; + uint32 secdesc_ptr; + uint32 attributes; + uint32 priority; + uint32 default_priority; + uint32 starttime; + uint32 untiltime; + uint32 status; + uint32 cjobs; + uint32 averageppm; + UNISTR2 servername; + UNISTR2 printername; + UNISTR2 sharename; + UNISTR2 portname; + UNISTR2 drivername; + UNISTR2 comment; + UNISTR2 location; + UNISTR2 sepfile; + UNISTR2 printprocessor; + UNISTR2 datatype; + UNISTR2 parameters; + SEC_DESC_BUF *secdesc; +} SPOOL_PRINTER_INFO_LEVEL_2; + +typedef struct spool_printer_info_level +{ + SPOOL_PRINTER_INFO_LEVEL_2 *info_2; +} SPOOL_PRINTER_INFO_LEVEL; + +typedef struct spool_printer_driver_info_level_3 +{ + uint32 cversion; + uint32 name_ptr; + uint32 environment_ptr; + uint32 driverpath_ptr; + uint32 datafile_ptr; + uint32 configfile_ptr; + uint32 helpfile_ptr; + uint32 monitorname_ptr; + uint32 defaultdatatype_ptr; + uint32 dependentfilessize; + uint32 dependentfiles_ptr; + + UNISTR2 name; + UNISTR2 environment; + UNISTR2 driverpath; + UNISTR2 datafile; + UNISTR2 configfile; + UNISTR2 helpfile; + UNISTR2 monitorname; + UNISTR2 defaultdatatype; + BUFFER5 dependentfiles; + +} SPOOL_PRINTER_DRIVER_INFO_LEVEL_3; + +typedef struct spool_printer_driver_info_level +{ + SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *info_3; +} SPOOL_PRINTER_DRIVER_INFO_LEVEL; + + +/* this struct is undocumented */ +/* thanks to the ddk ... */ +typedef struct spool_user_level_1 +{ + uint32 size; + uint32 client_name_ptr; + uint32 user_name_ptr; + uint32 build; + uint32 major; + uint32 minor; + uint32 processor; + UNISTR2 client_name; + UNISTR2 user_name; +} SPOOL_USER_LEVEL_1; + +typedef struct spool_user_level +{ + SPOOL_USER_LEVEL_1 *user_level_1; +} SPOOL_USER_LEVEL; + +typedef struct spool_q_setprinter +{ + POLICY_HND handle; + uint32 level; + SPOOL_PRINTER_INFO_LEVEL info; + + DEVICEMODE *devmode; + + /* lkclXXXX jean-francois, see SEC_DESC_BUF code */ + struct + { + uint32 size_of_buffer; + uint32 data; + } security; + + uint32 command; + +} SPOOL_Q_SETPRINTER; + +typedef struct spool_r_setprinter +{ + uint32 status; +} SPOOL_R_SETPRINTER; + +typedef struct spool_q_addprinter +{ + UNISTR2 server_name; + uint32 level; + SPOOL_PRINTER_INFO_LEVEL info; + uint32 unk0; + uint32 unk1; + uint32 unk2; + uint32 unk3; + uint32 user_level; + SPOOL_USER_LEVEL user; +} SPOOL_Q_ADDPRINTER; + +typedef struct spool_r_addprinter +{ + uint32 status; +} SPOOL_R_ADDPRINTER; + +typedef struct spool_q_addprinterex +{ + UNISTR2 server_name; + uint32 level; + SPOOL_PRINTER_INFO_LEVEL info; + uint32 unk0; + uint32 unk1; + uint32 unk2; + uint32 unk3; + uint32 user_level; + SPOOL_USER_LEVEL user; +} SPOOL_Q_ADDPRINTEREX; + + +typedef struct spool_r_addprinterex +{ + POLICY_HND handle; + uint32 status; +} SPOOL_R_ADDPRINTEREX; + +typedef struct spool_q_addprinterdriver +{ + UNISTR2 server_name; + uint32 level; + SPOOL_PRINTER_DRIVER_INFO_LEVEL info; +} SPOOL_Q_ADDPRINTERDRIVER; + +typedef struct spool_r_addprinterdriver +{ + uint32 status; +} SPOOL_R_ADDPRINTERDRIVER; + +typedef struct spool_q_getprinterdriverdirectory +{ + UNISTR2 name; + UNISTR2 environment; + uint32 level; + BUFFER buffer; + uint32 buf_size; +} SPOOL_Q_GETPRINTERDRIVERDIR; + +typedef struct driver_directory_1 +{ + UNISTR name; + +} DRIVER_DIRECTORY_1 ; + +typedef struct driver_info_ctr_info +{ + union { + DRIVER_DIRECTORY_1 info_1; + } driver; + +} DRIVER_DIRECTORY_CTR; + +typedef struct spool_r_getprinterdriverdirectory +{ + uint32 level; + DRIVER_DIRECTORY_CTR ctr; + uint32 offered; + uint32 status; + +} SPOOL_R_GETPRINTERDRIVERDIR; + +typedef struct spool_q_enumprintprocessors +{ + UNISTR2 name; + UNISTR2 environment; + uint32 level; + BUFFER buffer; + uint32 buf_size; +} SPOOL_Q_ENUMPRINTPROCESSORS; + +typedef struct printprocessor_1 +{ + UNISTR name; +} PRINTPROCESSOR_1; + +typedef struct spool_r_enumprintprocessors +{ + uint32 level; + PRINTPROCESSOR_1 *info_1; + uint32 offered; + uint32 numofprintprocessors; + uint32 status; +} SPOOL_R_ENUMPRINTPROCESSORS; + +typedef struct spool_q_enumprintprocessordatatypes +{ + UNISTR2 name; + UNISTR2 printprocessor; + uint32 level; + BUFFER buffer; + uint32 buf_size; +} SPOOL_Q_ENUMPRINTPROCESSORDATATYPES; + +typedef struct ppdatatype_1 +{ + UNISTR name; +} PPDATATYPE_1; + +typedef struct spool_r_enumprintprocessordatatypes +{ + uint32 level; + PPDATATYPE_1 *info_1; + uint32 offered; + uint32 numofppdatatypes; + uint32 status; +} SPOOL_R_ENUMPRINTPROCESSORDATATYPES; + +typedef struct spool_q_enumprintmonitors +{ + UNISTR2 name; + uint32 level; + BUFFER buffer; + uint32 buf_size; +} SPOOL_Q_ENUMPRINTMONITORS; + +typedef struct printmonitor_1 +{ + UNISTR name; +} PRINTMONITOR_1; + +typedef struct spool_r_enumprintmonitors +{ + uint32 level; + PRINTMONITOR_1 *info_1; + uint32 offered; + uint32 numofprintmonitors; + uint32 status; +} SPOOL_R_ENUMPRINTMONITORS; + +typedef struct spool_q_enumprinterdata +{ + POLICY_HND handle; + uint32 index; + uint32 valuesize; + uint32 datasize; +} SPOOL_Q_ENUMPRINTERDATA; + +typedef struct spool_r_enumprinterdata +{ + uint32 valuesize; + UNISTR value; + uint32 realvaluesize; + uint32 type; + uint32 datasize; + uint8 *data; + uint32 realdatasize; + uint32 status; +} SPOOL_R_ENUMPRINTERDATA; + +typedef struct spool_q_setprinterdata +{ + POLICY_HND handle; + UNISTR2 value; + uint32 type; + uint32 max_len; + uint8 *data; + uint32 real_len; + uint32 numeric_data; +} SPOOL_Q_SETPRINTERDATA; + +typedef struct spool_r_setprinterdata +{ + uint32 status; +} SPOOL_R_SETPRINTERDATA; + +typedef struct _form +{ + uint32 flags; + uint32 name_ptr; + uint32 size_x; + uint32 size_y; + uint32 left; + uint32 top; + uint32 right; + uint32 bottom; + UNISTR2 name; +} FORM; + +typedef struct spool_q_addform +{ + POLICY_HND handle; + uint32 level; + uint32 level2; + FORM form; +} SPOOL_Q_ADDFORM; + +typedef struct spool_r_addform +{ + uint32 status; +} SPOOL_R_ADDFORM; + +typedef struct spool_q_setform +{ + POLICY_HND handle; + UNISTR2 name; + uint32 level; + uint32 level2; + FORM form; +} SPOOL_Q_SETFORM; + +typedef struct spool_r_setform +{ + uint32 status; +} SPOOL_R_SETFORM; + +typedef struct spool_q_getjob +{ + POLICY_HND handle; + uint32 jobid; + uint32 level; + BUFFER buffer; + uint32 buf_size; + +} SPOOL_Q_GETJOB; + +typedef struct pjob_info_info +{ + union { + JOB_INFO_1 *job_info_1; + JOB_INFO_2 *job_info_2; + void *info; + } job; + +} PJOB_INFO; + +typedef struct spool_r_getjob +{ + uint32 level; + PJOB_INFO ctr; + uint32 offered; + uint32 status; +} SPOOL_R_GETJOB; + +#define PRINTER_DRIVER_VERSION 2 +#define PRINTER_DRIVER_ARCHITECTURE "Windows NT x86" + + +#endif /* _RPC_SPOOLSS_H */ diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c new file mode 100644 index 00000000000..00e052772e6 --- /dev/null +++ b/source/printing/nt_printing.c @@ -0,0 +1,1413 @@ +#include "includes.h" +#include "nterr.h" + +extern int DEBUGLEVEL; + +/**************************************************************************** +parse a form line. +****************************************************************************/ +static BOOL parse_form_entry(char *line, nt_forms_struct *buf) +{ +#define NAMETOK 0 +#define FLAGTOK 1 +#define WIDTHTOK 2 +#define LENGTHTOK 3 +#define LEFTTOK 4 +#define TOPTOK 5 +#define RIGHTTOK 6 +#define BOTTOMTOK 7 +#define MAXTOK 8 + char *tok[MAXTOK]; + int count = 0; + + tok[count] = strtok(line,":"); + + /* strip the comment lines */ + if (tok[0][0]=='#') return (False); + count++; + + while ( ((tok[count] = strtok(NULL,":")) != NULL ) && countname,tok[NAMETOK],sizeof(buf->name)-1); + buf->flag=atoi(tok[FLAGTOK]); + buf->width=atoi(tok[WIDTHTOK]); + buf->length=atoi(tok[LENGTHTOK]); + buf->left=atoi(tok[LEFTTOK]); + buf->top=atoi(tok[TOPTOK]); + buf->right=atoi(tok[RIGHTTOK]); + buf->bottom=atoi(tok[BOTTOMTOK]); + + return(True); +} + +/**************************************************************************** +get a form struct list +****************************************************************************/ +int get_ntforms(nt_forms_struct **list) +{ + FILE *f; + pstring line; + char *lp_forms = lp_nt_forms(); + int total=0; + int grandtotal=0; + *line=0; + + f = sys_fopen(lp_forms,"r"); + if (!f) + { + return(0); + } + + while ( fgets(line, sizeof(pstring), f) ) + { + DEBUG(5,("%s\n",line)); + + *list = Realloc(*list, sizeof(nt_forms_struct)*(total+1)); + if (! *list) + { + total = 0; + break; + } + bzero( (char *)&(*list)[total], sizeof(nt_forms_struct) ); + if ( parse_form_entry(line, &(*list)[total] ) ) + { + total++; + } + grandtotal++; + } + fclose(f); + + DEBUG(4,("%d info lines on %d\n",total, grandtotal)); + + return(total); +} + +/**************************************************************************** +write a form struct list +****************************************************************************/ +int write_ntforms(nt_forms_struct **list, int number) +{ + FILE *f; + pstring line; + char *file = lp_nt_forms(); + int total=0; + int i; + + *line=0; + + DEBUG(6,("write_ntforms\n")); + + if((f = sys_fopen(file, "w")) == NULL) + { + DEBUG(1, ("cannot create forms file [%s]\n", file)); + return(0); + } + + for (i=0; iname), sizeof(form_name)-1); + for (n=0; n<*count && update==False; n++) + { + if (!strncmp((*list)[n].name, form_name, strlen(form_name))) + { + DEBUG(3, ("NT workaround, [%s] already exists\n", form_name)); + update=True; + } + } + + if (update==False) + { + *list=Realloc(*list, (n+1)*sizeof(nt_forms_struct)); + unistr2_to_ascii((*list)[n].name, &(form->name), sizeof((*list)[n].name)-1); + (*count)++; + } + + (*list)[n].flag=form->flags; + (*list)[n].width=form->size_x; + (*list)[n].length=form->size_y; + (*list)[n].left=form->left; + (*list)[n].top=form->top; + (*list)[n].right=form->right; + (*list)[n].bottom=form->bottom; +} + +/**************************************************************************** +update a form struct +****************************************************************************/ +void update_a_form(nt_forms_struct **list, const FORM *form, int count) +{ + int n=0; + fstring form_name; + unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1); + + DEBUG(6, ("[%s]\n", form_name)); + for (n=0; nflags; + (*list)[n].width=form->size_x; + (*list)[n].length=form->size_y; + (*list)[n].left=form->left; + (*list)[n].top=form->top; + (*list)[n].right=form->right; + (*list)[n].bottom=form->bottom; +} + +/**************************************************************************** +get the nt drivers list + +open the directory and look-up the matching names +****************************************************************************/ +int get_ntdrivers(fstring **list, char *architecture) +{ + DIR *dirp; + char *dpname; + fstring name_match; + fstring short_archi; + fstring driver_name; + int match_len; + int total=0; + + DEBUG(5,("Getting the driver list from directory: [%s]\n", lp_nt_drivers_file())); + + *list=NULL; + dirp = opendir(lp_nt_drivers_file()); + + if (dirp == NULL) + { + DEBUG(0,("Error opening driver directory [%s]\n",lp_nt_drivers_file())); + return(-1); + } + + get_short_archi(short_archi, architecture); + slprintf(name_match, sizeof(name_match)-1, "NTdriver_%s_", short_archi); + match_len=strlen(name_match); + + while ((dpname = readdirname(dirp)) != NULL) + { + if (strncmp(dpname, name_match, match_len)==0) + { + DEBUGADD(7,("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)); + total++; + } + } + + closedir(dirp); + return(total); +} + +/**************************************************************************** +function to do the mapping between the long architecture name and +the short one. +****************************************************************************/ +void get_short_archi(char *short_archi, char *long_archi) +{ + struct table { + char *long_archi; + char *short_archi; + }; + + struct table archi_table[]= + { + {"Windows 4.0", "" }, + {"Windows NT x86", "W32X86" }, + {"Windows NT R4000", "" }, + {"Windows NT Alpha_AXP", "" }, + {"Windows NT PowerPC", "" }, + {NULL, "" } + }; + + int i=-1; + + DEBUG(7,("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)); + } + 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)); +} + +/**************************************************************************** +****************************************************************************/ +static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver) +{ + FILE *f; + pstring file; + fstring architecture; + fstring driver_name; + char **dependentfiles; + + /* create a file in the dir lp_nt_driver_file */ + /* with the full printer DRIVER name */ + /* eg: "/usr/local/samba/lib/NTdriver_HP LaserJet 6MP" */ + /* each name is really defining an *unique* printer model */ + /* I don't want to mangle the name to find it back when enumerating */ + + /* il faut substituer les / par 1 autre caractere d'abord */ + /* dans le nom de l'imprimante par un # ???*/ + + StrnCpy(driver_name, driver->name, sizeof(driver_name)-1); + + all_string_sub(driver_name, "/", "#", 0); + + get_short_archi(architecture, driver->environment); + + slprintf(file, sizeof(file)-1, "%s/NTdriver_%s_%s", + lp_nt_drivers_file(), architecture, driver_name); + + if((f = sys_fopen(file, "w")) == NULL) + { + DEBUG(1, ("cannot create driver file [%s]\n", file)); + return(2); + } + + /* + * cversion must be 2. + * when adding a printer ON the SERVER + * rpcAddPrinterDriver defines it to zero + * which is wrong !!! + * + * JFM, 4/14/99 + */ + driver->cversion=2; + + fprintf(f, "version: %d\n", driver->cversion); + fprintf(f, "name: %s\n", driver->name); + fprintf(f, "environment: %s\n", driver->environment); + fprintf(f, "driverpath: %s\n", driver->driverpath); + fprintf(f, "datafile: %s\n", driver->datafile); + fprintf(f, "configfile: %s\n", driver->configfile); + fprintf(f, "helpfile: %s\n", driver->helpfile); + fprintf(f, "monitorname: %s\n", driver->monitorname); + fprintf(f, "defaultdatatype: %s\n", driver->defaultdatatype); + + /* and the dependants files */ + + dependentfiles=driver->dependentfiles; + + while ( **dependentfiles != '\0' ) + { + fprintf(f, "dependentfile: %s\n", *dependentfiles); + dependentfiles++; + } + + fclose(f); + return(0); +} + +/**************************************************************************** +****************************************************************************/ +static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch) +{ + FILE *f; + pstring file; + fstring driver_name; + fstring architecture; + NT_PRINTER_DRIVER_INFO_LEVEL_3 *info; + char *line; + fstring p; + char *v; + int i=0; + char **dependentfiles=NULL; + + /* + * replace all the / by # in the driver name + * get the short architecture name + * construct the driver file name + */ + StrnCpy(driver_name, in_prt, sizeof(driver_name)-1); + all_string_sub(driver_name, "/", "#", 0); + + get_short_archi(architecture, in_arch); + + slprintf(file, sizeof(file)-1, "%s/NTdriver_%s_%s", + lp_nt_drivers_file(), architecture, driver_name); + + if((f = sys_fopen(file, "r")) == NULL) + { + DEBUG(2, ("cannot open printer driver file [%s]\n", file)); + return(2); + } + + /* the file exists, allocate some memory */ + info=(NT_PRINTER_DRIVER_INFO_LEVEL_3 *)malloc(sizeof(NT_PRINTER_DRIVER_INFO_LEVEL_3)); + ZERO_STRUCTP(info); + + /* allocate a 4Kbytes buffer for parsing lines */ + line=(char *)malloc(4096*sizeof(char)); + + while ( fgets(line, 4095, f) ) + { + + v=strncpyn(p, line, sizeof(p), ':'); + if (v==NULL) + { + DEBUG(1, ("malformed printer entry (no :)\n")); + continue; + } + + v++; + + trim_string(v, " ", NULL); + trim_string(v, NULL, " "); + trim_string(v, NULL, "\n"); + /* don't check if v==NULL as an empty arg is valid */ + + if (!strncmp(p, "version", strlen("version"))) + info->cversion=atoi(v); + + if (!strncmp(p, "name", strlen("name"))) + StrnCpy(info->name, v, strlen(v)); + + if (!strncmp(p, "environment", strlen("environment"))) + StrnCpy(info->environment, v, strlen(v)); + + if (!strncmp(p, "driverpath", strlen("driverpath"))) + StrnCpy(info->driverpath, v, strlen(v)); + + if (!strncmp(p, "datafile", strlen("datafile"))) + StrnCpy(info->datafile, v, strlen(v)); + + if (!strncmp(p, "configfile", strlen("configfile"))) + StrnCpy(info->configfile, v, strlen(v)); + + if (!strncmp(p, "helpfile", strlen("helpfile"))) + StrnCpy(info->helpfile, v, strlen(v)); + + if (!strncmp(p, "monitorname", strlen("monitorname"))) + StrnCpy(info->monitorname, v, strlen(v)); + + if (!strncmp(p, "defaultdatatype", strlen("defaultdatatype"))) + StrnCpy(info->defaultdatatype, v, strlen(v)); + + if (!strncmp(p, "dependentfile", strlen("dependentfile"))) + { + dependentfiles=(char **)Realloc(dependentfiles, sizeof(char *)*(i+1)); + + dependentfiles[i]=(char *)malloc( sizeof(char)* (strlen(v)+1) ); + + StrnCpy(dependentfiles[i], v, strlen(v) ); + i++; + } + + } + + free(line); + + fclose(f); + + dependentfiles=(char **)Realloc(dependentfiles, sizeof(char *)*(i+1)); + dependentfiles[i]=(char *)malloc( sizeof(char) ); + *dependentfiles[i]='\0'; + + info->dependentfiles=dependentfiles; + + *info_ptr=info; + + return (0); +} + +/**************************************************************************** +debugging function, dump at level 6 the struct in the logs +****************************************************************************/ +static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level) +{ + uint32 success; + NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3; + char **dependentfiles; + + DEBUG(6,("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 + { + 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)); + + dependentfiles=info3->dependentfiles; + + while ( **dependentfiles != '\0' ) + { + DEBUGADD(6,("dependentfile:[%s]\n", *dependentfiles)); + dependentfiles++; + } + success=0; + } + break; + } + default: + DEBUGADD(1,("Level not implemented\n")); + success=1; + break; + } + + return (success); +} + +/**************************************************************************** +****************************************************************************/ +static void add_a_devicemode(NT_DEVICEMODE *nt_devmode, FILE *f) +{ + int i; + + fprintf(f, "formname: %s\n", nt_devmode->formname); + fprintf(f, "specversion: %d\n", nt_devmode->specversion); + fprintf(f, "driverversion: %d\n", nt_devmode->driverversion); + fprintf(f, "size: %d\n", nt_devmode->size); + fprintf(f, "driverextra: %d\n", nt_devmode->driverextra); + fprintf(f, "fields: %d\n", nt_devmode->fields); + fprintf(f, "orientation: %d\n", nt_devmode->orientation); + fprintf(f, "papersize: %d\n", nt_devmode->papersize); + fprintf(f, "paperlength: %d\n", nt_devmode->paperlength); + fprintf(f, "paperwidth: %d\n", nt_devmode->paperwidth); + fprintf(f, "scale: %d\n", nt_devmode->scale); + fprintf(f, "copies: %d\n", nt_devmode->copies); + fprintf(f, "defaultsource: %d\n", nt_devmode->defaultsource); + fprintf(f, "printquality: %d\n", nt_devmode->printquality); + fprintf(f, "color: %d\n", nt_devmode->color); + fprintf(f, "duplex: %d\n", nt_devmode->duplex); + fprintf(f, "yresolution: %d\n", nt_devmode->yresolution); + fprintf(f, "ttoption: %d\n", nt_devmode->ttoption); + fprintf(f, "collate: %d\n", nt_devmode->collate); + fprintf(f, "icmmethod: %d\n", nt_devmode->icmmethod); + fprintf(f, "icmintent: %d\n", nt_devmode->icmintent); + fprintf(f, "mediatype: %d\n", nt_devmode->mediatype); + fprintf(f, "dithertype: %d\n", nt_devmode->dithertype); + + if (nt_devmode->private != NULL) + { + fprintf(f, "private: "); + for (i=0; idriverextra; i++) + fprintf(f, "%02X", nt_devmode->private[i]); + fprintf(f, "\n"); + } +} + +/**************************************************************************** +****************************************************************************/ +static void save_specifics(NT_PRINTER_PARAM *param, FILE *f) +{ + int i; + + while (param != NULL) + { + fprintf(f, "specific: %s#%d#%d#", param->value, param->type, param->data_len); + + for (i=0; idata_len; i++) + fprintf(f, "%02X", param->data[i]); + + fprintf(f, "\n"); + + param=param->next; + } +} + +/**************************************************************************** +****************************************************************************/ +static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info) +{ + FILE *f; + pstring file; + fstring printer_name; + NT_DEVICEMODE *nt_devmode; + + /* + * JFM: one day I'll forget. + * below that's info->portname because that's the SAMBA sharename + * and I made NT 'thinks' it's the portname + * the info->sharename is the thing you can name when you add a printer + * that's the short-name when you create shared printer for 95/98 + * So I've made a limitation in SAMBA: you can only have 1 printer model + * behind a SAMBA share. + */ + + + StrnCpy(printer_name, info->portname, sizeof(printer_name)-1); + + slprintf(file, sizeof(file)-1, "%s/NTprinter_%s", + lp_nt_drivers_file(), printer_name); + + /* create a file in the dir lp_nt_driver_file */ + /* with the full printer name */ + /* eg: "/usr/local/samba/lib/NTprinter_HP LaserJet 6MP" */ + /* each name is really defining an *unique* printer model */ + /* I don't want to mangle the name to find it back when enumerating */ + + if((f = sys_fopen(file, "w")) == NULL) + { + DEBUG(1, ("cannot create printer file [%s]\n", file)); + return(2); + } + + fprintf(f, "attributes: %d\n", info->attributes); + fprintf(f, "priority: %d\n", info->priority); + fprintf(f, "default_priority: %d\n", info->default_priority); + fprintf(f, "starttime: %d\n", info->starttime); + fprintf(f, "untiltime: %d\n", info->untiltime); + fprintf(f, "status: %d\n", info->status); + fprintf(f, "cjobs: %d\n", info->cjobs); + fprintf(f, "averageppm: %d\n", info->averageppm); + + /* + * in addprinter: no servername and the printer is the name + * in setprinter: servername is \\server + * and printer is \\server\\printer + * + * Samba manages only local printers. + * we currently don't support things like path=\\other_server\printer + */ + + if (info->servername[0]!='\0') + { + trim_string(info->printername, info->servername, NULL); + trim_string(info->printername, "\\", NULL); + info->servername[0]='\0'; + } + + fprintf(f, "servername: %s\n", info->servername); + fprintf(f, "printername: %s\n", info->printername); + 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); + fprintf(f, "datatype: %s\n", info->datatype); + fprintf(f, "parameters: %s\n", info->parameters); + + /* store the devmode and the private part if it exist */ + nt_devmode=info->devmode; + if (nt_devmode!=NULL) + { + add_a_devicemode(nt_devmode, f); + } + + /* and store the specific parameters */ + if (info->specific != NULL) + { + save_specifics(info->specific, f); + } + + fclose(f); + + return (0); +} + +/**************************************************************************** +fill a NT_PRINTER_PARAM from a text file + +used when reading from disk. +****************************************************************************/ +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")); + + tok[count] = strtok(v,"#"); + count++; + + while ( ((tok[count] = strtok(NULL,"#")) != NULL ) && count<4) + { + count++; + } + + StrnCpy(param->value, tok[0], sizeof(param->value)-1); + param->type=atoi(tok[1]); + param->data_len=atoi(tok[2]); + param->data=(uint8 *)malloc(param->data_len * sizeof(uint8)); + 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)); +} + +/**************************************************************************** +fill a NT_PRINTER_PARAM from a text file + +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)); +} + +/**************************************************************************** +****************************************************************************/ +BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param) +{ + NT_PRINTER_PARAM *current; + + DEBUG(8,("add_a_specific_param\n")); + + param->next=NULL; + + if (info_2->specific == NULL) + { + info_2->specific=param; + } + else + { + current=info_2->specific; + while (current->next != NULL) { + current=current->next; + } + current->next=param; + } + return (True); +} + +/**************************************************************************** +****************************************************************************/ +BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param) +{ + NT_PRINTER_PARAM *current; + NT_PRINTER_PARAM *previous; + + current=info_2->specific; + previous=current; + + if (current==NULL) return (False); + + if ( !strcmp(current->value, param->value) && + (strlen(current->value)==strlen(param->value)) ) + { + DEBUG(9,("deleting first value\n")); + info_2->specific=current->next; + free(current); + DEBUG(9,("deleted first value\n")); + return (True); + } + + current=previous->next; + + while ( current!=NULL ) + { + if (!strcmp(current->value, param->value) && + strlen(current->value)==strlen(param->value) ) + { + DEBUG(9,("deleting current value\n")); + previous->next=current->next; + free(current); + DEBUG(9,("deleted current value\n")); + return(True); + } + + previous=previous->next; + current=current->next; + } + return (False); +} + +/**************************************************************************** +****************************************************************************/ +static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename) +{ + FILE *f; + pstring file; + fstring printer_name; + NT_PRINTER_INFO_LEVEL_2 *info; + NT_DEVICEMODE *nt_devmode; + NT_PRINTER_PARAM *param; + char *line; + fstring p; + char *v; + + /* + * the sharename argument is the SAMBA sharename + */ + StrnCpy(printer_name, sharename, sizeof(printer_name)-1); + + slprintf(file, sizeof(file)-1, "%s/NTprinter_%s", + lp_nt_drivers_file(), printer_name); + + if((f = sys_fopen(file, "r")) == NULL) + { + DEBUG(2, ("cannot open printer file [%s]\n", file)); + return(2); + } + + /* the file exists, allocate some memory */ + info=(NT_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(NT_PRINTER_INFO_LEVEL_2)); + ZERO_STRUCTP(info); + + nt_devmode=(NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE)); + ZERO_STRUCTP(nt_devmode); + init_devicemode(nt_devmode); + + info->devmode=nt_devmode; + + line=(char *)malloc(4096*sizeof(char)); + + while ( fgets(line, 4095, f) ) + { + + v=strncpyn(p, line, sizeof(p), ':'); + if (v==NULL) + { + DEBUG(1, ("malformed printer entry (no `:')\n")); + DEBUGADD(2, ("line [%s]\n", line)); + continue; + } + + v++; + + trim_string(v, " ", NULL); + trim_string(v, NULL, " "); + trim_string(v, NULL, "\n"); + + /* don't check if v==NULL as an empty arg is valid */ + + DEBUGADD(15, ("[%s]:[%s]\n", p, v)); + + /* + * The PRINTER_INFO_2 fields + */ + + if (!strncmp(p, "attributes", strlen("attributes"))) + info->attributes=atoi(v); + + if (!strncmp(p, "priority", strlen("priority"))) + info->priority=atoi(v); + + if (!strncmp(p, "default_priority", strlen("default_priority"))) + info->default_priority=atoi(v); + + if (!strncmp(p, "starttime", strlen("starttime"))) + info->starttime=atoi(v); + + if (!strncmp(p, "untiltime", strlen("untiltime"))) + info->untiltime=atoi(v); + + if (!strncmp(p, "status", strlen("status"))) + info->status=atoi(v); + + if (!strncmp(p, "cjobs", strlen("cjobs"))) + info->cjobs=atoi(v); + + if (!strncmp(p, "averageppm", strlen("averageppm"))) + info->averageppm=atoi(v); + + if (!strncmp(p, "servername", strlen("servername"))) + StrnCpy(info->servername, v, strlen(v)); + + if (!strncmp(p, "printername", strlen("printername"))) + StrnCpy(info->printername, v, strlen(v)); + + if (!strncmp(p, "sharename", strlen("sharename"))) + StrnCpy(info->sharename, v, strlen(v)); + + if (!strncmp(p, "portname", strlen("portname"))) + StrnCpy(info->portname, v, strlen(v)); + + 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)); + + if (!strncmp(p, "sepfile", strlen("sepfile"))) + StrnCpy(info->sepfile, v, strlen(v)); + + if (!strncmp(p, "printprocessor", strlen("printprocessor"))) + StrnCpy(info->printprocessor, v, strlen(v)); + + if (!strncmp(p, "datatype", strlen("datatype"))) + StrnCpy(info->datatype, v, strlen(v)); + + if (!strncmp(p, "parameters", strlen("parameters"))) + StrnCpy(info->parameters, v, strlen(v)); + + /* + * The DEVICEMODE fields + */ + + if (!strncmp(p, "formname", strlen("formname"))) + StrnCpy(nt_devmode->formname, v, strlen(v)); + + if (!strncmp(p, "specversion", strlen("specversion"))) + nt_devmode->specversion=atoi(v); + + if (!strncmp(p, "driverversion", strlen("driverversion"))) + nt_devmode->driverversion=atoi(v); + + if (!strncmp(p, "size", strlen("size"))) + nt_devmode->size=atoi(v); + + if (!strncmp(p, "driverextra", strlen("driverextra"))) + nt_devmode->driverextra=atoi(v); + + if (!strncmp(p, "fields", strlen("fields"))) + nt_devmode->fields=atoi(v); + + if (!strncmp(p, "orientation", strlen("orientation"))) + nt_devmode->orientation=atoi(v); + + if (!strncmp(p, "papersize", strlen("papersize"))) + nt_devmode->papersize=atoi(v); + + if (!strncmp(p, "paperlength", strlen("paperlength"))) + nt_devmode->paperlength=atoi(v); + + if (!strncmp(p, "paperwidth", strlen("paperwidth"))) + nt_devmode->paperwidth=atoi(v); + + if (!strncmp(p, "scale", strlen("scale"))) + nt_devmode->scale=atoi(v); + + if (!strncmp(p, "copies", strlen("copies"))) + nt_devmode->copies=atoi(v); + + if (!strncmp(p, "defaultsource", strlen("defaultsource"))) + nt_devmode->defaultsource=atoi(v); + + if (!strncmp(p, "printquality", strlen("printquality"))) + nt_devmode->printquality=atoi(v); + + if (!strncmp(p, "color", strlen("color"))) + nt_devmode->color=atoi(v); + + if (!strncmp(p, "duplex", strlen("duplex"))) + nt_devmode->duplex=atoi(v); + + if (!strncmp(p, "yresolution", strlen("yresolution"))) + nt_devmode->yresolution=atoi(v); + + if (!strncmp(p, "ttoption", strlen("ttoption"))) + nt_devmode->ttoption=atoi(v); + + if (!strncmp(p, "collate", strlen("collate"))) + nt_devmode->collate=atoi(v); + + if (!strncmp(p, "icmmethod", strlen("icmmethod"))) + nt_devmode->icmmethod=atoi(v); + + if (!strncmp(p, "icmintent", strlen("icmintent"))) + nt_devmode->icmintent=atoi(v); + + if (!strncmp(p, "mediatype", strlen("mediatype"))) + nt_devmode->mediatype=atoi(v); + + if (!strncmp(p, "dithertype", strlen("dithertype"))) + nt_devmode->dithertype=atoi(v); + + if (!strncmp(p, "private", strlen("private"))) + { + nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra*sizeof(uint8)); + strhex_to_str(nt_devmode->private, 2*nt_devmode->driverextra, v); + } + + /* the specific */ + + if (!strncmp(p, "specific", strlen("specific"))) + { + param=(NT_PRINTER_PARAM *)malloc(sizeof(NT_PRINTER_PARAM)); + ZERO_STRUCTP(param); + + dissect_and_fill_a_param(param, v); + + dump_a_param(param); + + add_a_specific_param(info, param); + } + + } + fclose(f); + free(line); + + *info_ptr=info; + + return (0); +} + +/**************************************************************************** +debugging function, dump at level 6 the struct in the logs +****************************************************************************/ +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)); + + 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)); + success=0; + } + break; + } + default: + DEBUGADD(1,("Level not implemented\n")); + success=1; + break; + } + + return (success); +} + +/* + * The function below are the high level ones. + * only those ones must be called from the spoolss code. + * JFM. + */ + + +/**************************************************************************** +****************************************************************************/ +uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level) +{ + uint32 success; + + dump_a_printer(printer, level); + + switch (level) + { + case 2: + { + success=add_a_printer_2(printer.info_2); + break; + } + default: + success=1; + break; + } + + return (success); +} + +/**************************************************************************** +****************************************************************************/ +uint32 get_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level, fstring sharename) +{ + uint32 success; + + switch (level) + { + case 2: + { + printer->info_2=NULL; + success=get_a_printer_2(&(printer->info_2), sharename); + break; + } + default: + success=1; + break; + } + + dump_a_printer(*printer, level); + return (success); +} + +/**************************************************************************** +****************************************************************************/ +uint32 free_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level) +{ + uint32 success; + DEBUG(4,("freeing a printer at level [%d]\n", level)); + + switch (level) + { + case 2: + { + if (printer.info_2 != NULL) + { + if ((printer.info_2)->devmode != NULL) + { + DEBUG(6,("deleting DEVMODE\n")); + if ((printer.info_2)->devmode->private !=NULL ) + free((printer.info_2)->devmode->private); + free((printer.info_2)->devmode); + } + + if ((printer.info_2)->specific != NULL) + { + NT_PRINTER_PARAM *param; + NT_PRINTER_PARAM *next_param; + + param=(printer.info_2)->specific; + + while ( param != NULL) + { + next_param=param->next; + DEBUG(6,("deleting param [%s]\n", param->value)); + free(param->data); + free(param); + param=next_param; + } + } + + free(printer.info_2); + success=0; + } + else + { + success=4; + } + break; + } + default: + success=1; + break; + } + return (success); +} + +/**************************************************************************** +****************************************************************************/ +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)); + dump_a_printer_driver(driver, level); + + switch (level) + { + case 3: + { + success=add_a_printer_driver_3(driver.info_3); + break; + } + default: + success=1; + break; + } + + return (success); +} +/**************************************************************************** +****************************************************************************/ +uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, + fstring printername, fstring architecture) +{ + uint32 success; + + switch (level) + { + case 3: + { + success=get_a_printer_driver_3(&(driver->info_3), + printername, + architecture); + break; + } + default: + success=1; + break; + } + + dump_a_printer_driver(*driver, level); + return (success); +} + +/**************************************************************************** +****************************************************************************/ +uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level) +{ + uint32 success; + NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3; + char **dependentfiles; + + switch (level) + { + case 3: + { + if (driver.info_3 != NULL) + { + info3=driver.info_3; + dependentfiles=info3->dependentfiles; + + while ( **dependentfiles != '\0' ) + { + free (*dependentfiles); + dependentfiles++; + } + + /* the last one (1 char !) */ + free (*dependentfiles); + + dependentfiles=info3->dependentfiles; + free (dependentfiles); + + free(info3); + success=0; + } + else + { + success=4; + } + break; + } + default: + success=1; + break; + } + return (success); +} + +/**************************************************************************** +****************************************************************************/ +BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index, + fstring value, uint8 **data, uint32 *type, uint32 *len) +{ + /* right now that's enough ! */ + NT_PRINTER_PARAM *param; + int i=0; + + param=printer.info_2->specific; + + while (param != NULL && i < param_index) + { + param=param->next; + 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); +} + +/**************************************************************************** +****************************************************************************/ +BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level, + fstring value, uint8 **data, uint32 *type, uint32 *len) +{ + /* right now that's enough ! */ + NT_PRINTER_PARAM *param; + + DEBUG(5, ("get_specific_param\n")); + + param=printer.info_2->specific; + + while (param != NULL) + { + if ( !strcmp(value, param->value) + && strlen(value)==strlen(param->value)) + break; + + param=param->next; + } + + DEBUG(6, ("found one param\n")); + if (param != NULL) + { + /* exited because it exist */ + *type=param->type; + + *data=(uint8 *)malloc(param->data_len*sizeof(uint8)); + memcpy(*data, param->data, param->data_len); + *len=param->data_len; + + DEBUG(6, ("exit of get_specific_param:true\n")); + return (True); + } + DEBUG(6, ("exit of get_specific_param:false\n")); + return (False); +} + +/**************************************************************************** +****************************************************************************/ +void init_devicemode(NT_DEVICEMODE *nt_devmode) +{ +/* + * should I init this ones ??? + nt_devmode->devicename +*/ + fstrcpy(nt_devmode->formname, "A4"); + + nt_devmode->specversion = 0x0401; + nt_devmode->driverversion = 0x0400; + nt_devmode->size = 0x00DC; + nt_devmode->driverextra = 0x0000; + nt_devmode->fields = FORMNAME | TTOPTION | PRINTQUALITY | + DEFAULTSOURCE | COPIES | SCALE | + PAPERSIZE | ORIENTATION; + nt_devmode->orientation = 1; + nt_devmode->papersize = PAPER_A4; + nt_devmode->paperlength = 0; + nt_devmode->paperwidth = 0; + nt_devmode->scale = 0x64; + nt_devmode->copies = 01; + nt_devmode->defaultsource = BIN_FORMSOURCE; + nt_devmode->printquality = 0x0258; + nt_devmode->color = COLOR_MONOCHROME; + nt_devmode->duplex = DUP_SIMPLEX; + nt_devmode->yresolution = 0; + nt_devmode->ttoption = TT_SUBDEV; + nt_devmode->collate = COLLATE_FALSE; + nt_devmode->icmmethod = 0; + nt_devmode->icmintent = 0; + nt_devmode->mediatype = 0; + nt_devmode->dithertype = 0; + + /* non utilisés par un driver d'imprimante */ + nt_devmode->logpixels = 0; + nt_devmode->bitsperpel = 0; + nt_devmode->pelswidth = 0; + nt_devmode->pelsheight = 0; + nt_devmode->displayflags = 0; + nt_devmode->displayfrequency = 0; + nt_devmode->reserved1 = 0; + nt_devmode->reserved2 = 0; + nt_devmode->panningwidth = 0; + nt_devmode->panningheight = 0; + + nt_devmode->private=NULL; +} + + +/* error code: + 0: everything OK + 1: level not implemented + 2: file doesn't exist + 3: can't allocate memory + 4: can't free memory + 5: non existant struct +*/ + +/* + A printer and a printer driver are 2 different things. + NT manages them separatelly, Samba does the same. + Why ? Simply because it's easier and it makes sense ! + + Now explanation: You have 3 printers behind your samba server, + 2 of them are the same make and model (laser A and B). But laser B + has an 3000 sheet feeder and laser A doesn't such an option. + Your third printer is an old dot-matrix model for the accounting :-). + + If the /usr/local/samba/lib directory (default dir), you will have + 5 files to describe all of this. + + 3 files for the printers (1 by printer): + NTprinter_laser A + NTprinter_laser B + NTprinter_accounting + 2 files for the drivers (1 for the laser and 1 for the dot matrix) + NTdriver_printer model X + NTdriver_printer model Y + +jfm: I should use this comment for the text file to explain + same thing for the forms BTW. + Je devrais mettre mes commentaires en francais, ca serait mieux :-) + +*/ + + diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c new file mode 100644 index 00000000000..a6f72a3181e --- /dev/null +++ b/source/rpc_parse/parse_spoolss.c @@ -0,0 +1,4806 @@ +/* + * Unix SMB/Netbios implementation. + * Version 1.9. + * RPC Pipe client / server routines + * Copyright (C) Andrew Tridgell 1992-2000, + * Copyright (C) Luke Kenneth Casson Leighton 1996-2000, + * Copyright (C) Jean François Micouleau 1998-2000. + * + * 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" + +extern int DEBUGLEVEL; +/******************************************************************* +return the length of a UNISTR string. +********************************************************************/ +static uint32 str_len_uni(UNISTR *source) +{ + uint32 i=0; + + while (source->buffer[i]!=0x0000) + { + i++; + } + return i; +} + +/******************************************************************* +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)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL make_systemtime(SYSTEMTIME *systime, struct tm *unixtime) +{ + systime->year=unixtime->tm_year+1900; + systime->month=unixtime->tm_mon+1; + systime->dayofweek=unixtime->tm_wday; + systime->day=unixtime->tm_mday; + systime->hour=unixtime->tm_hour; + systime->minute=unixtime->tm_min; + systime->second=unixtime->tm_sec; + systime->milliseconds=0; + + return True; +} + +/******************************************************************* +reads or writes an POLICY_HND structure. +********************************************************************/ +static BOOL smb_io_prt_hnd(char *desc, POLICY_HND *hnd, prs_struct *ps, int depth) +{ + if (hnd == NULL) return False; + + prs_debug(ps, depth, desc, "smb_io_prt_hnd"); + depth++; + + prs_align(ps); + + prs_uint8s (False, "data", ps, depth, hnd->data, POLICY_HND_SIZE); + + return True; +} + +/******************************************************************* +reads or writes an DOC_INFO structure. +********************************************************************/ +static BOOL smb_io_doc_info_1(char *desc, DOC_INFO_1 *info_1, prs_struct *ps, int depth) +{ + if (info_1 == NULL) return False; + + prs_debug(ps, depth, desc, "smb_io_doc_info_1"); + depth++; + + prs_align(ps); + + 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)); + + 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); + + return True; +} + +/******************************************************************* +reads or writes an DOC_INFO structure. +********************************************************************/ +static BOOL smb_io_doc_info(char *desc, DOC_INFO *info, prs_struct *ps, int depth) +{ + uint32 useless_ptr=0; + + if (info == NULL) return False; + + prs_debug(ps, depth, desc, "smb_io_doc_info"); + depth++; + + prs_align(ps); + + prs_uint32("switch_value", ps, depth, &(info->switch_value)); + + prs_uint32("doc_info_X ptr", ps, depth, &(useless_ptr)); + + switch (info->switch_value) + { + case 1: + smb_io_doc_info_1("",&(info->doc_info_1), ps, depth); + break; + case 2: + /* + this is just a placeholder + + MSDN July 1998 says doc_info_2 is only on + Windows 95, and as Win95 doesn't do RPC to print + this case is nearly impossible + + Maybe one day with Windows for dishwasher 2037 ... + + */ + /* smb_io_doc_info_2("",&(info->doc_info_2), ps, depth); */ + break; + default: + DEBUG(0,("Something is obviously wrong somewhere !\n")); + break; + } + + return True; +} + +/******************************************************************* +reads or writes an DOC_INFO_CONTAINER structure. +********************************************************************/ +static BOOL smb_io_doc_info_container(char *desc, DOC_INFO_CONTAINER *cont, prs_struct *ps, int depth) +{ + if (cont == NULL) return False; + + prs_debug(ps, depth, desc, "smb_io_doc_info_container"); + depth++; + + prs_align(ps); + + prs_uint32("level", ps, depth, &(cont->level)); + + smb_io_doc_info("",&(cont->docinfo), ps, depth); + + return True; +} + +/******************************************************************* +reads or writes an NOTIFY OPTION TYPE structure. +********************************************************************/ +static BOOL smb_io_notify_option_type(char *desc, + SPOOL_NOTIFY_OPTION_TYPE *type, + prs_struct *ps, int depth) +{ + uint32 useless_ptr; + + prs_debug(ps, depth, desc, "smb_io_notify_option_type"); + depth++; + + prs_align(ps); + + prs_uint16("type", ps, depth, &(type->type)); + prs_uint16("reserved0", ps, depth, &(type->reserved0)); + prs_uint32("reserved1", ps, depth, &(type->reserved1)); + prs_uint32("reserved2", ps, depth, &(type->reserved2)); + prs_uint32("count", ps, depth, &(type->count)); + prs_uint32("useless ptr", ps, depth, &useless_ptr); + + + return True; +} + +/******************************************************************* +reads or writes an NOTIFY OPTION TYPE DATA. +********************************************************************/ +static BOOL smb_io_notify_option_type_data(char *desc, + SPOOL_NOTIFY_OPTION_TYPE *type, + prs_struct *ps, int depth) +{ + uint32 count; + int i; + + prs_debug(ps, depth, desc, "smb_io_notify_option_type_data"); + depth++; + + prs_align(ps); + + prs_uint32("count", ps, depth, &count); + + if (count != type->count) + { + DEBUG(4,("What a mess, count was %x now is %x !\n",type->count,count)); + type->count=count; + } + for(i=0;ifields[i])); + } + + return True; +} + +/******************************************************************* +reads or writes an NOTIFY OPTION structure. +********************************************************************/ +static BOOL smb_io_notify_option(char *desc, SPOOL_NOTIFY_OPTION *option, + prs_struct *ps, int depth) +{ + uint32 useless_ptr; + int i; + + prs_debug(ps, depth, desc, "smb_io_notify_option"); + depth++; + + prs_align(ps); + + /* memory pointer to the struct */ + prs_uint32("useless ptr", ps, depth, &useless_ptr); + + prs_uint32("version", ps, depth, &(option->version)); + prs_uint32("reserved", ps, depth, &(option->reserved)); + prs_uint32("count", ps, depth, &(option->count)); + prs_uint32("useless ptr", ps, depth, &useless_ptr); + prs_uint32("count", ps, depth, &(option->count)); + + /* read the option type struct */ + for(i=0;icount;i++) + { + smb_io_notify_option_type("",&(option->type[i]) ,ps, depth); + } + + /* now read the type associated with the option type struct */ + for(i=0;icount;i++) + { + smb_io_notify_option_type_data("",&(option->type[i]) ,ps, depth); + } + + + return True; +} + + +/******************************************************************* +reads or writes an NOTIFY INFO DATA structure. +********************************************************************/ +static BOOL smb_io_notify_info_data(char *desc,SPOOL_NOTIFY_INFO_DATA *data, + prs_struct *ps, int depth) +{ + uint32 useless_ptr=0xADDE0FF0; + + uint32 how_many_words; + BOOL isvalue; + uint32 x; + + prs_debug(ps, depth, desc, "smb_io_notify_info_data"); + depth++; + + how_many_words=data->size; + if (how_many_words==POINTER) + { + how_many_words=TWO_VALUE; + } + + isvalue=data->enc_type; + + prs_align(ps); + prs_uint16("type", ps, depth, &(data->type)); + prs_uint16("field", ps, depth, &(data->field)); + /*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); + /*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])); + /*prs_align(ps);*/ + } + else + { + /* 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); + /*prs_align(ps);*/ + } + + return True; +} + +/******************************************************************* +reads or writes an NOTIFY INFO DATA structure. +********************************************************************/ +BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data, + prs_struct *ps, int depth) +{ + uint32 x; + BOOL isvalue; + + prs_debug(ps, depth, desc, "smb_io_notify_info_data"); + depth++; + + prs_align(ps); + 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); + } + prs_align(ps); + + return True; +} + +/******************************************************************* +reads or writes an NOTIFY INFO structure. +********************************************************************/ +static BOOL smb_io_notify_info(char *desc, SPOOL_NOTIFY_INFO *info, + prs_struct *ps, int depth) +{ + uint32 useless_ptr=0x0001; + int i; + + info->version=0x02; + prs_debug(ps, depth, desc, "smb_io_notify_info"); + depth++; + + prs_align(ps); + + prs_uint32("pointer", ps, depth, &useless_ptr); + 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)); + + for (i=0;icount;i++) + { + smb_io_notify_info_data(desc, &(info->data[i]), ps, depth); + } + + /* now do the strings at the end of the stream */ + for (i=0;icount;i++) + { + smb_io_notify_info_data_strings(desc, &(info->data[i]), + ps, depth); + } + + return True; +} + + +/******************************************************************* +********************************************************************/ +static BOOL spool_io_user_level_1(char *desc, SPOOL_USER_1 *q_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, ""); + depth++; + + /* reading */ + if (ps->io) + ZERO_STRUCTP(q_u); + + if (!prs_align(ps)) + return False; + if (!prs_uint32("size", ps, depth, &(q_u->size))) + return False; + if (!prs_uint32("client_name_ptr", ps, depth, &(q_u->client_name_ptr))) + return False; + if (!prs_uint32("user_name_ptr", ps, depth, &(q_u->user_name_ptr))) + return False; + if (!prs_uint32("build", ps, depth, &(q_u->build))) + return False; + if (!prs_uint32("major", ps, depth, &(q_u->major))) + return False; + if (!prs_uint32("minor", ps, depth, &(q_u->minor))) + return False; + if (!prs_uint32("processor", ps, depth, &(q_u->processor))) + return False; + + if (!smb_io_unistr2("", &(q_u->client_name), q_u->client_name_ptr, ps, depth)) + return False; + if (!prs_align(ps)) + return False; + if (!smb_io_unistr2("", &(q_u->user_name), q_u->user_name_ptr, ps, depth)) + return False; + + return True; +} + +/******************************************************************* +********************************************************************/ +static BOOL spool_io_user_level(char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps, int depth) +{ + if (q_u==NULL) + return False; + + prs_debug(ps, depth, desc, "spool_io_user_level"); + depth++; + + if (!prs_align(ps)) + return False; + if (!prs_uint32("level", ps, depth, &q_u->level)) + return False; + if (!prs_uint32("ptr", ps, depth, &q_u->ptr)) + return False; + + switch (q_u->level) { + case 1: + if (!spool_io_user_level_1("", &(q_u->user1), ps, depth)) + return False; + break; + default: + return False; + } + + return True; +} + +/******************************************************************* + * read or write a DEVICEMODE struct. + * on reading allocate memory for the private member + ********************************************************************/ +static BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode) +{ + prs_debug(ps, depth, desc, "spoolss_io_devmode"); + depth++; + + if (!prs_uint16s(True,"devicename", ps, depth, devmode->devicename.buffer, 32)) + return False; + if (!prs_uint16("specversion", ps, depth, &(devmode->specversion))) + return False; + if (!prs_uint16("driverversion", ps, depth, &(devmode->driverversion))) + return False; + if (!prs_uint16("size", ps, depth, &(devmode->size))) + return False; + if (!prs_uint16("driverextra", ps, depth, &(devmode->driverextra))) + return False; + if (!prs_uint32("fields", ps, depth, &(devmode->fields))) + return False; + if (!prs_uint16("orientation", ps, depth, &(devmode->orientation))) + return False; + if (!prs_uint16("papersize", ps, depth, &(devmode->papersize))) + return False; + if (!prs_uint16("paperlength", ps, depth, &(devmode->paperlength))) + return False; + if (!prs_uint16("paperwidth", ps, depth, &(devmode->paperwidth))) + return False; + if (!prs_uint16("scale", ps, depth, &(devmode->scale))) + return False; + if (!prs_uint16("copies", ps, depth, &(devmode->copies))) + return False; + if (!prs_uint16("defaultsource", ps, depth, &(devmode->defaultsource))) + return False; + if (!prs_uint16("printquality", ps, depth, &(devmode->printquality))) + return False; + if (!prs_uint16("color", ps, depth, &(devmode->color))) + return False; + if (!prs_uint16("duplex", ps, depth, &(devmode->duplex))) + return False; + if (!prs_uint16("yresolution", ps, depth, &(devmode->yresolution))) + return False; + if (!prs_uint16("ttoption", ps, depth, &(devmode->ttoption))) + return False; + if (!prs_uint16("collate", ps, depth, &(devmode->collate))) + return False; + if (!prs_uint16s(True, "formname", ps, depth, devmode->formname.buffer, 32)) + return False; + if (!prs_uint16("logpixels", ps, depth, &(devmode->logpixels))) + return False; + if (!prs_uint32("bitsperpel", ps, depth, &(devmode->bitsperpel))) + return False; + if (!prs_uint32("pelswidth", ps, depth, &(devmode->pelswidth))) + return False; + if (!prs_uint32("pelsheight", ps, depth, &(devmode->pelsheight))) + return False; + if (!prs_uint32("displayflags", ps, depth, &(devmode->displayflags))) + return False; + if (!prs_uint32("displayfrequency", ps, depth, &(devmode->displayfrequency))) + return False; + if (!prs_uint32("icmmethod", ps, depth, &(devmode->icmmethod))) + return False; + if (!prs_uint32("icmintent", ps, depth, &(devmode->icmintent))) + return False; + if (!prs_uint32("mediatype", ps, depth, &(devmode->mediatype))) + return False; + if (!prs_uint32("dithertype", ps, depth, &(devmode->dithertype))) + return False; + if (!prs_uint32("reserved1", ps, depth, &(devmode->reserved1))) + return False; + if (!prs_uint32("reserved2", ps, depth, &(devmode->reserved2))) + return False; + if (!prs_uint32("panningwidth", ps, depth, &(devmode->panningwidth))) + return False; + if (!prs_uint32("panningheight", ps, depth, &(devmode->panningheight))) + return False; + + if (devmode->driverextra!=0) + { + if (UNMARSHALLING(ps)) { + devmode->private=(uint8 *)malloc(devmode->driverextra*sizeof(uint8)); + DEBUG(7,("spoolss_io_devmode: allocated memory [%d] for private\n",devmode->driverextra)); + } + + DEBUG(7,("spoolss_io_devmode: parsing [%d] bytes of private\n",devmode->driverextra)); + if (!prs_uint8s(True, "private", ps, depth, devmode->private, devmode->driverextra)) + return False; + } + + return True; +} + +/******************************************************************* + Read or write a DEVICEMODE container +********************************************************************/ +static BOOL spoolss_io_devmode_cont(char *desc, DEVMODE_CTR *dm_c, prs_struct *ps, int depth) +{ + if (dm_c==NULL) + return False; + + prs_debug(ps, depth, desc, "spoolss_io_devmode_cont"); + depth++; + + if (!prs_uint32("size", ps, depth, &dm_c->size)) + return False; + + if (!prs_uint32("devmode_ptr", ps, depth, &dm_c->devmode_ptr)) + return False; + + if (dm_c->size==0 || dm_c->devmode_ptr==0) { + if (UNMARSHALLING(ps)) + /* if while reading there is no DEVMODE ... */ + dm_c->devmode=NULL; + return True; + } + + /* so we have a DEVICEMODE to follow */ + if (UNMARSHALLING(ps)) { + DEBUG(9,("Allocating memory for spoolss_io_devmode\n")); + dm_c->devmode=(DEVICEMODE *)malloc(sizeof(DEVICEMODE)); + ZERO_STRUCTP(dm_c->devmode); + } + + /* this is bad code, shouldn't be there */ + if (!prs_uint32("size", ps, depth, &dm_c->size)) + return False; + + if (!spoolss_io_devmode(desc, ps, depth, dm_c->devmode)) + return False; + + return True; +} + +/******************************************************************* +********************************************************************/ +static BOOL spoolss_io_printer_default(char *desc, PRINTER_DEFAULT *pd, prs_struct *ps, int depth) +{ + if (pd==NULL) + return False; + + prs_debug(ps, depth, desc, "spoolss_io_printer_default"); + depth++; + + if (!prs_uint32("datatype_ptr", ps, depth, &pd->datatype_ptr)) + return False; + + if (!smb_io_unistr2("datatype", &(pd->datatype), pd->datatype_ptr, ps,depth)) + return False; + + if (!prs_align(ps)) + return False; + + if (!spoolss_io_devmode_cont("", &(pd->devmode_cont), ps, depth)) + return False; + + if (!prs_uint32("access_required", ps, depth, &pd->access_required)) + return False; + + return True; +} + +/******************************************************************* + * make a structure. + ********************************************************************/ +BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u, + const char *printername, + uint32 cbbuf, uint32 devmod, uint32 des_access, + const char *station, + const char *username) +{ + int len_name = printername != NULL ? strlen(printername) : 0; + int len_sta = station != NULL ? strlen(station ) : 0; + int len_user = username != NULL ? strlen(username ) : 0; + + if (q_u == NULL) return False; + + DEBUG(5,("make_spoolss_io_q_open_printer_ex\n")); + + q_u->printername_ptr = 1; + init_unistr2(&(q_u->printername), printername, len_name); + +/* + q_u->unknown0 = 0x0; + q_u->cbbuf = cbbuf; + q_u->devmod = devmod; + q_u->access_required = des_access; +*/ +/* q_u->unknown1 = 0x1; + q_u->unknown2 = 0x1; + q_u->unknown3 = 0x149f7d8; + q_u->unknown4 = 0x1c; + q_u->unknown5 = 0x00b94dd0; + q_u->unknown6 = 0x0149f5cc; + q_u->unknown7 = 0x00000565; + q_u->unknown8 = 0x2; + q_u->unknown9 = 0x0; + q_u->unknown10 = 0x0; + + init_unistr2(&(q_u->station), station, len_sta); + init_unistr2(&(q_u->username), username, len_user); +*/ + return True; +} + +/******************************************************************* + * read a structure. + * called from spoolss_q_open_printer_ex (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) + return False; + + prs_debug(ps, depth, desc, "spoolss_io_q_open_printer_ex"); + depth++; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("printername_ptr", ps, depth, &(q_u->printername_ptr))) + return False; + if (!smb_io_unistr2("", &(q_u->printername), q_u->printername_ptr, ps,depth)) + return False; + + if (!prs_align(ps)) + return False; + + if (!spoolss_io_printer_default("", &(q_u->printer_default), ps, depth)) + return False; + + if (!prs_uint32("user_switch", ps, depth, &(q_u->user_switch))) + return False; + + if (!spool_io_user_level("", &(q_u->user_ctr), ps, depth)) + return False; + + return True; +} + +/******************************************************************* + * write a structure. + * called from static spoolss_r_open_printer_ex (srv_spoolss.c) + * called from spoolss_open_printer_ex (cli_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_r_open_printer_ex(char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_struct *ps, int depth) +{ + if (r_u == NULL) return False; + + prs_debug(ps, depth, desc, "spoolss_io_r_open_printer_ex"); + depth++; + + if (!prs_align(ps)) + return False; + + if (!smb_io_prt_hnd("printer handle",&(r_u->handle),ps,depth)) + return False; + + if (!prs_uint32("status code", ps, depth, &(r_u->status))) + return False; + + return True; +} +/******************************************************************* + * make a structure. + ********************************************************************/ +BOOL make_spoolss_q_getprinterdata(SPOOL_Q_GETPRINTERDATA *q_u, + POLICY_HND *handle, + char *valuename, + uint32 size) +{ + int len_name = valuename != NULL ? strlen(valuename) : 0; + + if (q_u == NULL) return False; + + DEBUG(5,("make_spoolss_q_getprinterdata\n")); + + memcpy(&(q_u->handle), handle, sizeof(q_u->handle)); + init_unistr2(&(q_u->valuename), valuename, len_name); + q_u->size = size; + + return True; +} + +/******************************************************************* + * read a structure. + * called from spoolss_q_getprinterdata (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_q_getprinterdata(char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) return False; + + prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdata"); + depth++; + + if (!prs_align(ps)) + return False; + if (!smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth)) + return False; + if (!prs_align(ps)) + return False; + if (!smb_io_unistr2("valuename", &(q_u->valuename),True,ps,depth)) + return False; + if (!prs_align(ps)) + return False; + if (!prs_uint32("size", ps, depth, &(q_u->size))) + return False; + + return True; +} + +/******************************************************************* + * write a structure. + * called from spoolss_r_getprinterdata (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_r_getprinterdata(char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth) +{ + if (r_u == NULL) return False; + + prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata"); + depth++; + + prs_align(ps); + prs_uint32("type", ps, depth, &(r_u->type)); + prs_uint32("size", ps, depth, &(r_u->size)); + + prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size); + prs_align(ps); + + prs_uint32("needed", ps, depth, &(r_u->needed)); + prs_uint32("status", ps, depth, &(r_u->status)); + prs_align(ps); + + return True; +} + +/******************************************************************* + * make a structure. + ********************************************************************/ +BOOL make_spoolss_q_closeprinter(SPOOL_Q_CLOSEPRINTER *q_u, POLICY_HND *hnd) +{ + if (q_u == NULL) return False; + + DEBUG(5,("make_spoolss_q_closeprinter\n")); + + memcpy(&(q_u->handle), hnd, sizeof(q_u->handle)); + + return True; +} + +/******************************************************************* + * read a structure. + * called from static spoolss_q_closeprinter (srv_spoolss.c) + * called from spoolss_closeprinter (cli_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_q_closeprinter(char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) return False; + + prs_debug(ps, depth, desc, "spoolss_io_q_closeprinter"); + depth++; + + prs_align(ps); + + smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); + + return True; +} + +/******************************************************************* + * write a structure. + * called from static spoolss_r_closeprinter (srv_spoolss.c) + * called from spoolss_closeprinter (cli_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_r_closeprinter(char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_closeprinter"); + depth++; + prs_align(ps); + + smb_io_prt_hnd("printer handle",&(r_u->handle),ps,depth); + prs_uint32("status", ps, depth, &(r_u->status)); + + + return True; +} + +/******************************************************************* + * read a structure. + * called from spoolss_q_startdocprinter (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_q_startdocprinter(char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) return False; + + prs_debug(ps, depth, desc, "spoolss_io_q_startdocprinter"); + depth++; + + prs_align(ps); + + smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); + + smb_io_doc_info_container("",&(q_u->doc_info_container), ps, depth); + + return True; +} + +/******************************************************************* + * write a structure. + * called from spoolss_r_startdocprinter (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_r_startdocprinter(char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_struct *ps, int depth) +{ + 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)); + + return True; +} + +/******************************************************************* + * read a structure. + * called from spoolss_q_enddocprinter (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_q_enddocprinter(char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) return False; + + prs_debug(ps, depth, desc, "spoolss_io_q_enddocprinter"); + depth++; + + prs_align(ps); + + smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); + + return True; +} + +/******************************************************************* + * write a structure. + * called from spoolss_r_enddocprinter (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_r_enddocprinter(char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_enddocprinter"); + depth++; + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/******************************************************************* + * read a structure. + * called from spoolss_q_startpageprinter (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_q_startpageprinter(char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) return False; + + prs_debug(ps, depth, desc, "spoolss_io_q_startpageprinter"); + depth++; + + prs_align(ps); + + smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); + + return True; +} + +/******************************************************************* + * write a structure. + * called from spoolss_r_startpageprinter (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_r_startpageprinter(char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_startpageprinter"); + depth++; + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/******************************************************************* + * read a structure. + * called from spoolss_q_endpageprinter (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_q_endpageprinter(char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) return False; + + prs_debug(ps, depth, desc, "spoolss_io_q_endpageprinter"); + depth++; + + prs_align(ps); + + smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); + + return True; +} + +/******************************************************************* + * write a structure. + * called from spoolss_r_endpageprinter (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_r_endpageprinter(char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_endpageprinter"); + depth++; + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/******************************************************************* + * read a structure. + * called from spoolss_q_writeprinter (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_q_writeprinter(char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct *ps, int depth) +{ + if (q_u == NULL) return False; + + prs_debug(ps, depth, desc, "spoolss_io_q_writeprinter"); + depth++; + + prs_align(ps); + + smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); + prs_uint32("buffer_size", ps, depth, &(q_u->buffer_size)); + + 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); + } + prs_align(ps); + prs_uint32("buffer_size2", ps, depth, &(q_u->buffer_size2)); + + return True; +} + +/******************************************************************* + * write a structure. + * called from spoolss_r_writeprinter (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_r_writeprinter(char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct *ps, int depth) +{ + 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)); + + return True; +} + +/******************************************************************* + * read a structure. + * called from spoolss_q_rffpcnex (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_q_rffpcnex(char *desc, SPOOL_Q_RFFPCNEX *q_u, + prs_struct *ps, int depth) +{ + uint32 useless_ptr; + + prs_debug(ps, depth, desc, "spoolss_io_q_rffpcnex"); + depth++; + prs_align(ps); + + smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); + prs_uint32("flags", ps, depth, &(q_u->flags)); + prs_uint32("options", ps, depth, &(q_u->options)); + prs_uint32("useless ptr", ps, depth, &useless_ptr); + /*prs_align(ps);*/ + + smb_io_unistr2("", &(q_u->localmachine), True, ps, depth); + + prs_align(ps); + prs_uint32("printerlocal", ps, depth, &(q_u->printerlocal)); + + smb_io_notify_option("notify option", &(q_u->option), ps, depth); + + + return True; +} + +/******************************************************************* + * write a structure. + * called from spoolss_r_rffpcnex (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_r_rffpcnex(char *desc, SPOOL_R_RFFPCNEX *r_u, + prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_rffpcnex"); + depth++; + + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/******************************************************************* + * read a structure. + * called from spoolss_q_rfnpcnex (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u, + prs_struct *ps, int depth) +{ + + prs_debug(ps, depth, desc, "spoolss_io_q_rfnpcnex"); + depth++; + + prs_align(ps); + + smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); + + prs_uint32("change", ps, depth, &(q_u->change)); + + smb_io_notify_option("notify option",&(q_u->option),ps,depth); + + return True; +} + +/******************************************************************* + * write a structure. + * called from spoolss_r_rfnpcnex (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_r_rfnpcnex(char *desc, + SPOOL_R_RFNPCNEX *r_u, + prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_rfnpcnex"); + depth++; + + prs_align(ps); + + smb_io_notify_info("notify info",&(r_u->info),ps,depth); + prs_align(ps); + prs_uint32("status", ps, depth, &r_u->status); + + return True; +} + +/******************************************************************* + * return the length of a uint32 (obvious, but the code is clean) + ********************************************************************/ +static uint32 size_of_uint32(uint32 *value) +{ + return (sizeof(*value)); + + return True; +} + +/******************************************************************* + * return the length of a UNICODE string in number of char, includes: + * - the leading zero + * - the relative pointer size + ********************************************************************/ +static uint32 size_of_relative_string(UNISTR *string) +{ + uint32 size=0; + + size=str_len_uni(string); /* the string length */ + size=size+1; /* add the leading zero */ + size=size*2; /* convert in char */ + size=size+4; /* add the size of the ptr */ + return (size); + + return True; +} + +/******************************************************************* + * return the length of a uint32 (obvious, but the code is clean) + ********************************************************************/ +static uint32 size_of_device_mode(DEVICEMODE *devmode) +{ + if (devmode==NULL) + return (4); + else + return (0xDC+4); + + return True; +} + +/******************************************************************* + * return the length of a uint32 (obvious, but the code is clean) + ********************************************************************/ +static uint32 size_of_systemtime(SYSTEMTIME *systime) +{ + if (systime==NULL) + return (4); + else + return (sizeof(SYSTEMTIME) +4); + + return True; +} + +/******************************************************************* + * write a UNICODE string. + * used by all the RPC structs passing a buffer + ********************************************************************/ +static BOOL spoolss_smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth) +{ + if (uni == NULL) + return False; + + prs_debug(ps, depth, desc, "spoolss_smb_io_unistr"); + depth++; + if (!prs_unistr("unistr", ps, depth, uni)) + return False; + + return True; +} + + +/******************************************************************* + * write a UNICODE string and its relative pointer. + * used by all the RPC structs passing a buffer + ********************************************************************/ +static BOOL smb_io_relstr(char *desc, prs_struct *ps, int depth, UNISTR *buffer, + uint32 *start_offset, uint32 *end_offset) +{ + if (!ps->io) + { + uint32 struct_offset = prs_offset(ps); + uint32 relative_offset; + + /* writing */ + *end_offset -= 2*(str_len_uni(buffer)+1); + prs_set_offset(ps, *end_offset); + spoolss_smb_io_unistr(desc, buffer, ps, depth); + + prs_set_offset(ps,struct_offset); + relative_offset=*end_offset-*start_offset; + + prs_uint32("offset", ps, depth, &(relative_offset)); + } + else + { + uint32 old_offset; + uint32 relative_offset; + + prs_uint32("offset", ps, depth, &(relative_offset)); + + old_offset = prs_offset(ps); + prs_set_offset(ps, (*start_offset) + relative_offset); + + spoolss_smb_io_unistr(desc, buffer, ps, depth); + + *end_offset = prs_offset(ps); + prs_set_offset(ps, old_offset); + } + return True; +} + +/******************************************************************* + * write a UNICODE string and its relative pointer. + * used by all the RPC structs passing a buffer + * + * As I'm a nice guy, I'm forcing myself to explain this code. + * MS did a good job in the overall spoolss code except in some + * functions where they are passing the API buffer directly in the + * RPC request/reply. That's to maintain compatiility at the API level. + * They could have done it the good way the first time. + * + * So what happen is: the strings are written at the buffer's end, + * in the reverse order of the original structure. Some pointers to + * the strings are also in the buffer. Those are relative to the + * buffer's start. + * + * If you don't understand or want to change that function, + * first get in touch with me: jfm@samba.org + * + ********************************************************************/ +static BOOL new_smb_io_relstr(char *desc, NEW_BUFFER *buffer, int depth, UNISTR *string) +{ + prs_struct *ps=&(buffer->prs); + + if (MARSHALLING(ps)) + { + uint32 struct_offset = prs_offset(ps); + uint32 relative_offset; + + buffer->string_at_end -= 2*(str_len_uni(string)+1); + prs_set_offset(ps, buffer->string_at_end); + + /* write the string */ + if (!spoolss_smb_io_unistr(desc, string, ps, depth)) + return False; + + prs_set_offset(ps, struct_offset); + + relative_offset=buffer->string_at_end-buffer->struct_start; + /* write its offset */ + if (!prs_uint32("offset", ps, depth, &relative_offset)) + return False; + } + else + { + uint32 old_offset; + + /* 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 */ + if (!spoolss_smb_io_unistr(desc, string, ps, depth)) + return False; + + prs_set_offset(ps, old_offset); + } + return True; +} + + +/******************************************************************* + * write a array UNICODE strings and its relative pointer. + * used by 2 RPC structs + ********************************************************************/ +static BOOL smb_io_relarraystr(char *desc, prs_struct *ps, int depth, UNISTR ***buffer, + uint32 *start_offset, uint32 *end_offset) +{ + int i=0; + uint32 struct_offset; + uint32 relative_offset; + struct_offset=prs_offset(ps); + + while ( (*buffer)[i]!=0x0000 ) + { + i++; + } + + i--; + + /* that's for the ending NULL */ + *end_offset-=2; + + do + { + *end_offset-= 2*(str_len_uni((*buffer)[i])+1); + prs_set_offset(ps, *end_offset); + spoolss_smb_io_unistr(desc, (*buffer)[i], ps, depth); + + i--; + } + while (i>=0); + + prs_set_offset(ps, struct_offset); + relative_offset=*end_offset-*start_offset; + + prs_uint32("offset", ps, depth, &(relative_offset)); + + return True; +} + +/******************************************************************* + * write a DEVMODE struct and its relative pointer. + * used by all the RPC structs passing a buffer + ********************************************************************/ +static BOOL smb_io_reldevmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode, + uint32 *start_offset, uint32 *end_offset) +{ + uint32 struct_offset; + uint32 relative_offset; + + prs_debug(ps, depth, desc, "smb_io_reldevmode"); + depth++; + + struct_offset=prs_offset(ps); + *end_offset-= (devmode->size+devmode->driverextra); + prs_set_offset(ps, *end_offset); + + spoolss_io_devmode(desc, ps, depth, devmode); + + prs_set_offset(ps, struct_offset); + relative_offset=*end_offset-*start_offset; + + prs_uint32("offset", ps, depth, &(relative_offset)); + + return True; +} + +/******************************************************************* +********************************************************************/ +static BOOL smb_io_printer_info_0(char *desc, PRINTER_INFO_0 *info, prs_struct *ps, int depth, + uint32 *start_offset, uint32 *end_offset) +{ + prs_debug(ps, depth, desc, "smb_io_printer_info_0"); + depth++; + *start_offset=prs_offset(ps); + + smb_io_relstr("printername",ps, depth, &(info->printername), start_offset, end_offset); + smb_io_relstr("servername",ps, depth, &(info->servername), start_offset, end_offset); + prs_uint32("cjobs", ps, depth, &(info->cjobs)); + prs_uint32("attributes", ps, depth, &(info->attributes)); + + prs_uint32("unknown0", ps, depth, &(info->unknown0)); + prs_uint32("unknown1", ps, depth, &(info->unknown1)); + prs_uint32("unknown2", ps, depth, &(info->unknown2)); + prs_uint32("unknown3", ps, depth, &(info->unknown3)); + prs_uint32("unknown4", ps, depth, &(info->unknown4)); + prs_uint32("unknown5", ps, depth, &(info->unknown5)); + prs_uint32("unknown6", ps, depth, &(info->unknown6)); + prs_uint16("majorversion", ps, depth, &(info->majorversion)); + prs_uint16("buildversion", ps, depth, &(info->buildversion)); + prs_uint32("unknown7", ps, depth, &(info->unknown7)); + prs_uint32("unknown8", ps, depth, &(info->unknown8)); + prs_uint32("unknown9", ps, depth, &(info->unknown9)); + prs_uint32("unknown10", ps, depth, &(info->unknown10)); + prs_uint32("unknown11", ps, depth, &(info->unknown11)); + prs_uint32("unknown12", ps, depth, &(info->unknown12)); + prs_uint32("unknown13", ps, depth, &(info->unknown13)); + prs_uint32("unknown14", ps, depth, &(info->unknown14)); + prs_uint32("unknown15", ps, depth, &(info->unknown15)); + prs_uint32("unknown16", ps, depth, &(info->unknown16)); + prs_uint32("unknown17", ps, depth, &(info->unknown17)); + prs_uint32("unknown18", ps, depth, &(info->unknown18)); + prs_uint32("status" , ps, depth, &(info->status)); + prs_uint32("unknown20", ps, depth, &(info->unknown20)); + prs_uint32("unknown21", ps, depth, &(info->unknown21)); + prs_uint16("unknown22", ps, depth, &(info->unknown22)); + prs_uint32("unknown23", ps, depth, &(info->unknown23)); + + return True; +} + +/******************************************************************* +********************************************************************/ +static BOOL smb_io_printer_info_1(char *desc, PRINTER_INFO_1 *info, prs_struct *ps, int depth, + uint32 *start_offset, uint32 *end_offset) +{ + prs_debug(ps, depth, desc, "smb_io_printer_info_1"); + depth++; + *start_offset=prs_offset(ps); + + prs_uint32("flags", ps, depth, &(info->flags)); + smb_io_relstr("description",ps, depth, &(info->description), start_offset, end_offset); + smb_io_relstr("name",ps, depth, &(info->name), start_offset, end_offset); + smb_io_relstr("comment",ps, depth, &(info->comment), start_offset, end_offset); + + return True; +} + +/******************************************************************* +********************************************************************/ +static BOOL smb_io_printer_info_2(char *desc, PRINTER_INFO_2 *info, prs_struct *ps, int depth, + uint32 *start_offset, uint32 *end_offset) +{ + uint32 pipo=0; + uint32 devmode_offset; + uint32 backup_offset; + + prs_debug(ps, depth, desc, "smb_io_printer_info_2"); + depth++; + *start_offset=prs_offset(ps); + + smb_io_relstr("servername", ps, depth, &(info->servername), start_offset, end_offset); + smb_io_relstr("printername", ps, depth, &(info->printername), start_offset, end_offset); + smb_io_relstr("sharename", ps, depth, &(info->sharename), start_offset, end_offset); + smb_io_relstr("portname", ps, depth, &(info->portname), start_offset, end_offset); + smb_io_relstr("drivername", ps, depth, &(info->drivername), start_offset, end_offset); + smb_io_relstr("comment", ps, depth, &(info->comment), start_offset, end_offset); + smb_io_relstr("location", ps, depth, &(info->location), start_offset, end_offset); + + devmode_offset=prs_offset(ps); + prs_set_offset(ps, prs_offset(ps)+4); + + smb_io_relstr("sepfile", ps, depth, &(info->sepfile), start_offset, end_offset); + smb_io_relstr("printprocessor",ps, depth, &(info->printprocessor), start_offset, end_offset); + smb_io_relstr("datatype", ps, depth, &(info->datatype), start_offset, end_offset); + smb_io_relstr("parameters", ps, depth, &(info->parameters), start_offset, end_offset); + + prs_uint32("security descriptor", ps, depth, &(pipo)); + + prs_uint32("attributes", ps, depth, &(info->attributes)); + prs_uint32("priority", ps, depth, &(info->priority)); + prs_uint32("defpriority", ps, depth, &(info->defaultpriority)); + prs_uint32("starttime", ps, depth, &(info->starttime)); + prs_uint32("untiltime", ps, depth, &(info->untiltime)); + prs_uint32("status", ps, depth, &(info->status)); + prs_uint32("jobs", ps, depth, &(info->cjobs)); + prs_uint32("averageppm", ps, depth, &(info->averageppm)); + + /* + I'm not sure if putting the devmode at the end the struct is worth it + but NT does it + */ + backup_offset=prs_offset(ps); + prs_set_offset(ps, devmode_offset); + smb_io_reldevmode("devmode", ps, depth, info->devmode, start_offset, end_offset); + prs_set_offset(ps, backup_offset); + + return True; +} + +/******************************************************************* +********************************************************************/ +static BOOL smb_io_printer_driver_info_1(char *desc, DRIVER_INFO_1 *info, prs_struct *ps, int depth, + uint32 *start_offset, uint32 *end_offset) +{ + prs_debug(ps, depth, desc, "smb_io_printer_driver_info_1"); + depth++; + *start_offset=prs_offset(ps); + + smb_io_relstr("name", ps, depth, &(info->name), start_offset, end_offset); + + return True; +} + +/******************************************************************* +********************************************************************/ +static BOOL smb_io_printer_driver_info_2(char *desc, DRIVER_INFO_2 *info,prs_struct *ps, int depth, + uint32 *start_offset, uint32 *end_offset) +{ + prs_debug(ps, depth, desc, "smb_io_printer_xxx"); + depth++; + *start_offset=prs_offset(ps); + + prs_uint32("version", ps, depth, &(info->version)); + smb_io_relstr("name", ps, depth, &(info->name), start_offset, end_offset); + smb_io_relstr("architecture", ps, depth, &(info->architecture), start_offset, end_offset); + smb_io_relstr("driverpath", ps, depth, &(info->driverpath), start_offset, end_offset); + smb_io_relstr("datafile", ps, depth, &(info->datafile), start_offset, end_offset); + smb_io_relstr("configfile", ps, depth, &(info->configfile), start_offset, end_offset); + + return True; +} + +/******************************************************************* +********************************************************************/ +static BOOL smb_io_printer_driver_info_3(char *desc, DRIVER_INFO_3 *info,prs_struct *ps, int depth, + uint32 *start_offset, uint32 *end_offset) +{ + prs_debug(ps, depth, desc, "smb_io_printer_driver_info_3"); + depth++; + *start_offset=prs_offset(ps); + + prs_uint32("version", ps, depth, &(info->version)); + smb_io_relstr("name", ps, depth, &(info->name), start_offset, end_offset); + smb_io_relstr("architecture", ps, depth, &(info->architecture), start_offset, end_offset); + smb_io_relstr("driverpath", ps, depth, &(info->driverpath), start_offset, end_offset); + smb_io_relstr("datafile", ps, depth, &(info->datafile), start_offset, end_offset); + smb_io_relstr("configfile", ps, depth, &(info->configfile), start_offset, end_offset); + smb_io_relstr("helpfile", ps, depth, &(info->helpfile), start_offset, end_offset); + + smb_io_relarraystr("dependentfiles", ps, depth, &(info->dependentfiles), start_offset, end_offset); + + smb_io_relstr("monitorname", ps, depth, &(info->monitorname), start_offset, end_offset); + smb_io_relstr("defaultdatatype", ps, depth, &(info->defaultdatatype), start_offset, end_offset); + + return True; +} + +/******************************************************************* +********************************************************************/ +static BOOL smb_io_job_info_1(char *desc, JOB_INFO_1 *info, prs_struct *ps, int depth, + uint32 *start_offset, uint32 *end_offset) +{ + prs_debug(ps, depth, desc, "smb_io_job_info_1"); + depth++; + *start_offset=prs_offset(ps); + + prs_uint32("jobid", ps, depth, &(info->jobid)); + smb_io_relstr("printername", ps, depth, &(info->printername), start_offset, end_offset); + smb_io_relstr("machinename", ps, depth, &(info->machinename), start_offset, end_offset); + smb_io_relstr("username", ps, depth, &(info->username), start_offset, end_offset); + smb_io_relstr("document", ps, depth, &(info->document), start_offset, end_offset); + smb_io_relstr("datatype", ps, depth, &(info->datatype), start_offset, end_offset); + smb_io_relstr("text_status", ps, depth, &(info->text_status), start_offset, end_offset); + prs_uint32("status", ps, depth, &(info->status)); + prs_uint32("priority", ps, depth, &(info->priority)); + prs_uint32("position", ps, depth, &(info->position)); + prs_uint32("totalpages", ps, depth, &(info->totalpages)); + prs_uint32("pagesprinted", ps, depth, &(info->pagesprinted)); + spoolss_io_system_time("submitted", ps, depth, &(info->submitted) ); + + return True; +} + +/******************************************************************* +********************************************************************/ +static BOOL smb_io_job_info_2(char *desc, JOB_INFO_2 *info, prs_struct *ps, int depth, + uint32 *start_offset, uint32 *end_offset) +{ + int pipo=0; + prs_debug(ps, depth, desc, "smb_io_job_info_2"); + depth++; + *start_offset=prs_offset(ps); + + prs_uint32("jobid", ps, depth, &(info->jobid)); + smb_io_relstr("printername", ps, depth, &(info->printername), start_offset, end_offset); + smb_io_relstr("machinename", ps, depth, &(info->machinename), start_offset, end_offset); + smb_io_relstr("username", ps, depth, &(info->username), start_offset, end_offset); + smb_io_relstr("document", ps, depth, &(info->document), start_offset, end_offset); + smb_io_relstr("notifyname", ps, depth, &(info->notifyname), start_offset, end_offset); + smb_io_relstr("datatype", ps, depth, &(info->datatype), start_offset, end_offset); + + smb_io_relstr("printprocessor", ps, depth, &(info->printprocessor), start_offset, end_offset); + smb_io_relstr("parameters", ps, depth, &(info->parameters), start_offset, end_offset); + smb_io_relstr("drivername", ps, depth, &(info->drivername), start_offset, end_offset); + smb_io_reldevmode("devmode", ps, depth, info->devmode, start_offset, end_offset); + smb_io_relstr("text_status", ps, depth, &(info->text_status), start_offset, end_offset); + +/* SEC_DESC sec_desc;*/ + prs_uint32("Hack! sec desc", ps, depth, &pipo); + + prs_uint32("status", ps, depth, &(info->status)); + prs_uint32("priority", ps, depth, &(info->priority)); + prs_uint32("position", ps, depth, &(info->position)); + prs_uint32("starttime", ps, depth, &(info->starttime)); + prs_uint32("untiltime", ps, depth, &(info->untiltime)); + prs_uint32("totalpages", ps, depth, &(info->totalpages)); + prs_uint32("size", ps, depth, &(info->size)); + spoolss_io_system_time("submitted", ps, depth, &(info->submitted) ); + prs_uint32("timeelapsed", ps, depth, &(info->timeelapsed)); + prs_uint32("pagesprinted", ps, depth, &(info->pagesprinted)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL new_smb_io_form_1(char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth) +{ + prs_struct *ps=&(buffer->prs); + + prs_debug(ps, depth, desc, "new_smb_io_form_1"); + depth++; + + buffer->struct_start=prs_offset(ps); + + if (!prs_uint32("flag", ps, depth, &(info->flag))) + return False; + + if (!new_smb_io_relstr("name", buffer, depth, &(info->name))) + return False; + + if (!prs_uint32("width", ps, depth, &(info->width))) + return False; + if (!prs_uint32("length", ps, depth, &(info->length))) + return False; + if (!prs_uint32("left", ps, depth, &(info->left))) + return False; + if (!prs_uint32("top", ps, depth, &(info->top))) + return False; + if (!prs_uint32("right", ps, depth, &(info->right))) + return False; + if (!prs_uint32("bottom", ps, depth, &(info->bottom))) + return False; + + return True; +} + +/******************************************************************* + Read/write a BUFFER struct. +********************************************************************/ +static BOOL new_spoolss_io_buffer(char *desc, prs_struct *ps, int depth, NEW_BUFFER *buffer) +{ + if (buffer == NULL) + return False; + + prs_debug(ps, depth, desc, "new_spoolss_io_buffer"); + depth++; + + if (!prs_uint32("ptr", ps, depth, &(buffer->ptr))) + return False; + + /* reading */ + if (UNMARSHALLING(ps)) { + buffer->size=0; + buffer->string_at_end=0; + + if (buffer->ptr==0) { + if (!prs_init(&(buffer->prs), 0, 4, UNMARSHALL)) + return False; + return True; + } + + if (!prs_uint32("size", ps, depth, &(buffer->size))) + return False; + + if (!prs_init(&(buffer->prs), buffer->size, 4, UNMARSHALL)) + return False; + + if (!prs_append_some_prs_data(&(buffer->prs), ps, buffer->size)) + return False; + + prs_set_offset(&(buffer->prs),0); + + prs_set_offset(ps, buffer->size+prs_offset(ps)); + + buffer->string_at_end=buffer->size; + + return True; + } + else { + /* writing */ + if (buffer->ptr==0) + return True; + + if (!prs_uint32("size", ps, depth, &(buffer->size))) + return False; + + if (!prs_append_some_prs_data(ps, &(buffer->prs), buffer->size)) + return False; + } + + return True; +} + +/******************************************************************* + move a BUFFER from the query to the reply. +********************************************************************/ +void new_spoolss_move_buffer(NEW_BUFFER *src, NEW_BUFFER **dest) +{ + prs_switch_type(&(src->prs), MARSHALL); + prs_set_offset(&(src->prs), 0); + prs_force_dynamic(&(src->prs)); + + *dest=src; +} + +/******************************************************************* + create a BUFFER struct. +********************************************************************/ +void new_spoolss_allocate_buffer(NEW_BUFFER **buffer) +{ + if (buffer==NULL) + return; + + *buffer=(NEW_BUFFER *)malloc(sizeof(NEW_BUFFER)); + + (*buffer)->ptr=0x0; + (*buffer)->size=0; + (*buffer)->string_at_end=0; +} + +/******************************************************************* + Destroy a BUFFER struct. +********************************************************************/ +void new_spoolss_free_buffer(NEW_BUFFER *buffer) +{ + if (buffer==NULL) + return; + + prs_mem_free(&(buffer->prs)); + buffer->ptr=0x0; + buffer->size=0; + buffer->string_at_end=0; + + free(buffer); +} + +/******************************************************************* + Get the size of a BUFFER struct. +********************************************************************/ +uint32 new_get_buffer_size(NEW_BUFFER *buffer) +{ + return (buffer->size); +} + +/******************************************************************* +********************************************************************/ +static BOOL smb_io_form_1(char *desc, FORM_1 *info, prs_struct *ps, int depth, + uint32 *start_offset, uint32 *end_offset) +{ + prs_debug(ps, depth, desc, "smb_io_form_1"); + depth++; + *start_offset=prs_offset(ps); + + prs_uint32("flag", ps, depth, &(info->flag)); + smb_io_relstr("name",ps, depth, &(info->name), start_offset, end_offset); + prs_uint32("width", ps, depth, &(info->width)); + prs_uint32("length", ps, depth, &(info->length)); + prs_uint32("left", ps, depth, &(info->left)); + prs_uint32("top", ps, depth, &(info->top)); + prs_uint32("right", ps, depth, &(info->right)); + prs_uint32("bottom", ps, depth, &(info->bottom)); + + return True; +} + +/******************************************************************* +********************************************************************/ +static BOOL smb_io_port_2(char *desc, PORT_INFO_2 *info, prs_struct *ps, int depth, + uint32 *start_offset, uint32 *end_offset) +{ + prs_debug(ps, depth, desc, "smb_io_port_2"); + depth++; + *start_offset=prs_offset(ps); + + smb_io_relstr("port_name",ps, depth, &(info->port_name), start_offset, end_offset); + smb_io_relstr("monitor_name",ps, depth, &(info->monitor_name), start_offset, end_offset); + smb_io_relstr("description",ps, depth, &(info->description), start_offset, end_offset); + prs_uint32("port_type", ps, depth, &(info->port_type)); + prs_uint32("reserved", ps, depth, &(info->reserved)); + + return True; +} + +/******************************************************************* +********************************************************************/ +static BOOL smb_io_processor_info_1(char *desc, PRINTPROCESSOR_1 *info, prs_struct *ps, int depth, + uint32 *start_offset, uint32 *end_offset) +{ + prs_debug(ps, depth, desc, "smb_io_processor_info_1"); + depth++; + *start_offset=prs_offset(ps); + + smb_io_relstr("name",ps, depth, &(info->name), start_offset, end_offset); + + return True; +} + +/******************************************************************* +********************************************************************/ +static BOOL smb_io_monitor_info_1(char *desc, PRINTMONITOR_1 *info, prs_struct *ps, int depth, + uint32 *start_offset, uint32 *end_offset) +{ + prs_debug(ps, depth, desc, "smb_io_monitor_info_1"); + depth++; + *start_offset=prs_offset(ps); + + smb_io_relstr("name",ps, depth, &(info->name), start_offset, end_offset); + + return True; +} + +/******************************************************************* +return the size required by a struct in the stream +********************************************************************/ +static uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info) +{ + int size=0; + + size+=size_of_uint32( &(info->attributes) ); + size+=size_of_relative_string( &(info->printername) ); + size+=size_of_relative_string( &(info->servername) ); + return (size); + + return True; +} + +/******************************************************************* +return the size required by a struct in the stream +********************************************************************/ +static uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info) +{ + int size=0; + + size+=size_of_uint32( &(info->flags) ); + size+=size_of_relative_string( &(info->description) ); + size+=size_of_relative_string( &(info->name) ); + size+=size_of_relative_string( &(info->comment) ); + return (size); + + return True; +} + +/******************************************************************* +return the size required by a struct in the stream +********************************************************************/ +static 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_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); + + return True; +} + +/******************************************************************* +return the size required by a struct in the stream +********************************************************************/ +static uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info) +{ + int size=0; + DEBUG(9,("Sizing driver info_1\n")); + size+=size_of_relative_string( &(info->name) ); + + DEBUGADD(9,("size: [%d]\n", size)); + return (size); + + return True; +} + +/******************************************************************* +return the size required by a struct in the stream +********************************************************************/ +static uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info) +{ + int size=0; + DEBUG(9,("Sizing driver info_2\n")); + 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) ); + + DEBUGADD(9,("size: [%d]\n", size)); + return (size); + + return True; +} + +/******************************************************************* +return the size required by a struct in the stream +********************************************************************/ +static uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info) +{ + int size=0; + UNISTR **string; + int i=0; + + DEBUG(9,("Sizing driver info_3\n")); + 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++; + } + size+=6; + + DEBUGADD(9,("size: [%d]\n", size)); + return (size); + + return True; +} + +/******************************************************************* +return the size required by a struct in the stream +********************************************************************/ +static 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) ); + return (size); + + return True; +} + +/******************************************************************* +return the size required by a struct in the stream +********************************************************************/ +static uint32 spoolss_size_job_info_2(JOB_INFO_2 *info) +{ + int size=0; + + 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_device_mode( info->devmode ); + 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) ); + return (size); + + return True; +} + +/******************************************************************* +return the size required by a struct in the stream +********************************************************************/ +uint32 spoolss_size_form_1(FORM_1 *info) +{ + int size=0; + + size+=size_of_uint32( &(info->flag) ); + size+=size_of_relative_string( &(info->name) ); + size+=size_of_uint32( &(info->width) ); + size+=size_of_uint32( &(info->length) ); + size+=size_of_uint32( &(info->left) ); + size+=size_of_uint32( &(info->top) ); + size+=size_of_uint32( &(info->right) ); + size+=size_of_uint32( &(info->bottom) ); + + return (size); + + return True; +} + +/******************************************************************* +return the size required by a struct in the stream +********************************************************************/ +static uint32 spoolss_size_port_info_2(PORT_INFO_2 *info) +{ + int size=0; + + size+=size_of_relative_string( &(info->port_name) ); + size+=size_of_relative_string( &(info->monitor_name) ); + size+=size_of_relative_string( &(info->description) ); + + size+=size_of_uint32( &(info->port_type) ); + size+=size_of_uint32( &(info->reserved) ); + + return (size); + + return True; +} + +/******************************************************************* +return the size required by a struct in the stream +********************************************************************/ +static uint32 spoolss_size_processor_info_1(PRINTPROCESSOR_1 *info) +{ + int size=0; + size+=size_of_relative_string( &(info->name) ); + + return (size); + + return True; +} + +/******************************************************************* +return the size required by a struct in the stream +********************************************************************/ +static uint32 spoolss_size_monitor_info_1(PRINTMONITOR_1 *info) +{ + int size=0; + size+=size_of_relative_string( &(info->name) ); + + return (size); + + return True; +} + +/******************************************************************* + * make a structure. + ********************************************************************/ +static BOOL make_spoolss_buffer(BUFFER* buffer, uint32 size) +{ + buffer->ptr = (size != 0) ? 1 : 0; + buffer->size = size; + buffer->data = (uint8 *)Realloc( NULL, (buffer->size) * sizeof(uint8) ); + + return (buffer->data != NULL || size == 0); +} + +/******************************************************************* + * read a uint8 buffer of size *size. + * allocate memory for it + * return a pointer to the allocated memory and the size + * return NULL and a size of 0 if the buffer is empty + * + * jfmxxxx: fix it to also write a buffer + ********************************************************************/ +static BOOL spoolss_io_read_buffer(char *desc, prs_struct *ps, int depth, BUFFER *buffer) +{ + prs_debug(ps, depth, desc, "spoolss_io_read_buffer"); + depth++; + + prs_align(ps); + + prs_uint32("pointer", ps, depth, &(buffer->ptr)); + + if (buffer->ptr != 0x0000) + { + prs_uint32("size", ps, depth, &(buffer->size)); + if (ps->io) + { + /* reading */ + buffer->data=(uint8 *)Realloc(NULL, buffer->size * sizeof(uint8) ); + } + if (buffer->data == NULL) + { + return False; + } + prs_uint8s(True, "buffer", ps, depth, buffer->data, buffer->size); + prs_align(ps); + + } + else + { + if (ps->io) + { + /* reading */ + buffer->data=0x0000; + buffer->size=0x0000; + } + } + + if (!ps->io) + { + /* writing */ + if (buffer->data != NULL) + { + free(buffer->data); + } + buffer->data = NULL; + } + return True; +} + +/******************************************************************* + * read a uint8 buffer of size *size. + * allocate memory for it + * return a pointer to the allocated memory and the size + * return NULL and a size of 0 if the buffer is empty + * + * jfmxxxx: fix it to also write a buffer + ********************************************************************/ +BOOL spoolss_io_free_buffer(BUFFER *buffer) +{ + DEBUG(8,("spoolss_io_free_buffer\n")); + + if (buffer->ptr != 0x0000) + { + free(buffer->data); + } + + return True; +} + +/******************************************************************* + * read a structure. + * called from spoolss_getprinterdriver2 (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_q_getprinterdriver2(char *desc, + SPOOL_Q_GETPRINTERDRIVER2 *q_u, + prs_struct *ps, int depth) +{ + uint32 useless_ptr; + prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2"); + depth++; + + prs_align(ps); + + smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); + prs_uint32("pointer", ps, depth, &useless_ptr); + smb_io_unistr2("architecture", &(q_u->architecture),True,ps,depth); + + prs_align(ps); + + prs_uint32("level", ps, depth, &(q_u->level)); + spoolss_io_read_buffer("", ps, depth, &(q_u->buffer)); + + prs_align(ps); + + prs_uint32("buffer size", ps, depth, &(q_u->buf_size)); + DEBUG(0,("spoolss_io_q_getprinterdriver2: renamed status - unknown\n")); + prs_uint32("unknown", ps, depth, &(q_u->unknown)); + + return True; +} + +/******************************************************************* + * read a structure. + * called from spoolss_getprinterdriver2 (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, + prs_struct *ps, int depth) +{ + uint32 useless_ptr=0xADDE0FF0; + uint32 start_offset, end_offset, beginning; + uint32 bufsize_required=0; + uint32 pipo=0; + DRIVER_INFO_1 *info1; + DRIVER_INFO_2 *info2; + DRIVER_INFO_3 *info3; + + prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2"); + depth++; + + prs_align(ps); + prs_uint32("pointer", ps, depth, &useless_ptr); + + info1 = r_u->ctr.driver.info1; + info2 = r_u->ctr.driver.info2; + info3 = r_u->ctr.driver.info3; + + switch (r_u->level) + { + case 1: + { + bufsize_required += spoolss_size_printer_driver_info_1(info1); + break; + } + case 2: + { + bufsize_required += spoolss_size_printer_driver_info_2(info2); + break; + } + case 3: + { + bufsize_required += spoolss_size_printer_driver_info_3(info3); + break; + } + } + + if (ps->io) + { + /* reading */ + r_u->offered = bufsize_required; + } + + DEBUG(4,("spoolss_io_r_getprinterdriver2, size needed: %d\n",bufsize_required)); + DEBUG(4,("spoolss_io_r_getprinterdriver2, size offered: %d\n",r_u->offered)); + + /* check if the buffer is big enough for the datas */ + if (r_u->offered < bufsize_required) + { + /* it's too small */ + r_u->status=ERROR_INSUFFICIENT_BUFFER; /* say so */ + r_u->offered=0; /* don't send back the buffer */ + + DEBUG(4,("spoolss_io_r_getprinterdriver2, buffer too small\n")); + + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + } + else + { + DEBUG(4,("spoolss_io_r_getprinterdriver2, buffer large enough\n")); + + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + + beginning=prs_offset(ps); + start_offset=prs_offset(ps); + end_offset=start_offset+r_u->offered; + + switch (r_u->level) + { + case 1: + { + smb_io_printer_driver_info_1(desc, + info1, + ps, + depth, + &start_offset, + &end_offset); + break; + } + case 2: + { + smb_io_printer_driver_info_2(desc, + info2, + ps, + depth, + &start_offset, + &end_offset); + break; + } + case 3: + { + smb_io_printer_driver_info_3(desc, + info3, + ps, + depth, + &start_offset, + &end_offset); + break; + } + + } + + prs_set_offset(ps, beginning+r_u->offered); + prs_align(ps); + } + + if (!ps->io) + { + /* writing */ + switch (r_u->level) + { + case 1: + { + safe_free(info1); + break; + } + case 2: + { + safe_free(info2); + break; + } + case 3: + { + if (info3!=NULL) + { + UNISTR **dependentfiles; + int j=0; + dependentfiles=info3->dependentfiles; + while ( dependentfiles[j] != NULL ) + { + free(dependentfiles[j]); + j++; + } + free(dependentfiles); + + free(info3); + } + break; + } + + } + } + + /* + * if the buffer was too small, send the minimum required size + * if it was too large, send the real needed size + */ + + prs_uint32("size of buffer needed", ps, depth, &(bufsize_required)); + prs_uint32("pipo", ps, depth, &pipo); + prs_uint32("pipo", ps, depth, &pipo); + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/******************************************************************* + * make a structure. + ********************************************************************/ +BOOL make_spoolss_q_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u, + uint32 flags, + const char* servername, + uint32 level, + uint32 size) +{ + size_t len_name = servername != NULL ? strlen(servername) : 0; + + DEBUG(5,("make_spoolss_q_enumprinters. size: %d\n", size)); + + q_u->flags = flags; + + init_unistr2(&q_u->servername, servername, len_name); + + q_u->level = level; + make_spoolss_buffer(&q_u->buffer, size); + q_u->buf_size = size; + + return True; +} + +/******************************************************************* + * read a structure. + * called from spoolss_enumprinters (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, + prs_struct *ps, int depth) +{ + uint32 useless_ptr = 0x01; + prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters"); + depth++; + + prs_align(ps); + + prs_uint32("flags", ps, depth, &(q_u->flags)); + prs_uint32("useless ptr", ps, depth, &useless_ptr); + + smb_io_unistr2("", &q_u->servername,True,ps,depth); + prs_align(ps); + + prs_uint32("level", ps, depth, &(q_u->level)); + + spoolss_io_read_buffer("buffer", ps, depth, &(q_u->buffer)); + + prs_uint32("buf_size", ps, depth, &q_u->buf_size); + + return True; +} + +/**************************************************************************** +****************************************************************************/ +void free_r_enumprinters(SPOOL_R_ENUMPRINTERS *r_u) +{ + DEBUG(4,("free_enum_printers_info: [%d] structs to free at level [%d]\n", r_u->returned, r_u->level)); + switch (r_u->level) + { + case 1: + { + free_print1_array(r_u->returned, r_u->ctr.printer.printers_1); + break; + } + case 2: + { + free_print2_array(r_u->returned, r_u->ctr.printer.printers_2); + break; + } + } +} + +/******************************************************************* + * write a structure. + * called from spoolss_r_enum_printers (srv_spoolss.c) + * + ********************************************************************/ +BOOL spoolss_io_r_enumprinters(char *desc, + SPOOL_R_ENUMPRINTERS *r_u, + prs_struct *ps, int depth) +{ + uint32 useless_ptr=0xADDE0FF0; + int i; + uint32 start_offset, end_offset, beginning; + uint32 bufsize_required=0; + uint32 tmp_ct = 0; + + PRINTER_INFO_1 *info1; + PRINTER_INFO_2 *info2; + fstring tmp; + + slprintf(tmp, sizeof(tmp)-1, "spoolss_io_r_enumprinters %d", r_u->level); + + prs_debug(ps, depth, desc, tmp); + depth++; + prs_align(ps); + prs_uint32("pointer", ps, depth, &useless_ptr); + + if (!ps->io) + { + /* writing */ + for(i=0;ireturned;i++) + { + switch (r_u->level) + { + case 1: + info1 = r_u->ctr.printer.printers_1[i]; + bufsize_required += spoolss_size_printer_info_1(info1); + break; + case 2: + info2 = r_u->ctr.printer.printers_2[i]; + bufsize_required += spoolss_size_printer_info_2(info2); + break; + } + } + + DEBUG(4,("spoolss_io_r_enumprinters, size needed: %d\n",bufsize_required)); + DEBUG(4,("spoolss_io_r_enumprinters, size offered: %d\n",r_u->offered)); + + if (r_u->offeredstatus=ERROR_INSUFFICIENT_BUFFER; + r_u->offered=0; + /*r_u->returned=0;*/ + + DEBUG(4,("spoolss_io_r_enumprinters, buffer too small\n")); + + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + prs_uint32("size of buffer needed", ps, depth, &(bufsize_required)); + prs_uint32("count", ps, depth, &(r_u->returned)); + prs_uint32("status", ps, depth, &(r_u->status)); + return False; + } + + DEBUG(4,("spoolss_io_r_enumprinters, buffer large enough\n")); + } + + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + + /* have to skip to end of buffer when reading, and have to record + * size of buffer when writing. *shudder*. + */ + + beginning = prs_offset(ps); + start_offset = prs_offset(ps); + end_offset = start_offset + r_u->offered; + + if (ps->io) + { + /* reading */ + prs_set_offset(ps, beginning + r_u->offered); + + prs_align(ps); + prs_uint32("buffer size", ps, depth, &(bufsize_required)); + prs_uint32("count", ps, depth, &(r_u->returned)); + + prs_set_offset(ps, beginning); + } + + for(i=0;ireturned;i++) + { + + switch (r_u->level) + { + case 1: + { + if (ps->io) + { + /* reading */ +/* r_u->ctr.printer.printers_1[i] = add_print1_to_array(&tmp_ct, &r_u->ctr.printer.printers_1, NULL);*/ + } + info1 = r_u->ctr.printer.printers_1[i]; + if (info1 == NULL) + { + return False; + } + smb_io_printer_info_1(desc, info1, ps, depth, + &start_offset, &end_offset); + break; + } + case 2: + { + if (ps->io) + { + /* reading */ +/* + r_u->ctr.printer.printers_2[i] = add_print2_to_array(&tmp_ct, &r_u->ctr.printer.printers_2, NULL); +*/ } + info2 = r_u->ctr.printer.printers_2[i]; + if (info2 == NULL) + { + return False; + } + smb_io_printer_info_2(desc, info2, ps, depth, + &start_offset, &end_offset); + break; + } + } + } + + prs_set_offset(ps, beginning + r_u->offered); + prs_align(ps); + + prs_uint32("buffer size", ps, depth, &(bufsize_required)); + prs_uint32("count", ps, depth, &(r_u->returned)); + prs_uint32("status", ps, depth, &(r_u->status)); + + if (!ps->io) + { + /* writing */ + free_r_enumprinters(r_u); + } + + return True; +} + +/******************************************************************* + * write a structure. + * called from spoolss_r_enum_printers (srv_spoolss.c) + * + ********************************************************************/ +BOOL spoolss_io_r_getprinter(char *desc, + SPOOL_R_GETPRINTER *r_u, + prs_struct *ps, int depth) +{ + uint32 useless_ptr=0xADDE0FF0; + uint32 start_offset, end_offset, beginning; + uint32 bufsize_required=0; + + prs_debug(ps, depth, desc, "spoolss_io_r_getprinter"); + depth++; + + prs_align(ps); + + prs_uint32("pointer", ps, depth, &useless_ptr); + + switch (r_u->level) + { + case 0: + { + PRINTER_INFO_0 *info; + info = r_u->ctr.printer.info0; + bufsize_required += spoolss_size_printer_info_0(info); + break; + } + case 1: + { + PRINTER_INFO_1 *info; + info = r_u->ctr.printer.info1; + bufsize_required += spoolss_size_printer_info_1(info); + break; + } + case 2: + { + PRINTER_INFO_2 *info; + info = r_u->ctr.printer.info2; + bufsize_required += spoolss_size_printer_info_2(info); + break; + } + } + + DEBUG(4,("spoolss_io_r_getprinter, size needed: %d\n",bufsize_required)); + DEBUG(4,("spoolss_io_r_getprinter, size offered: %d\n",r_u->offered)); + + /* check if the buffer is big enough for the datas */ + if (r_u->offered < bufsize_required) + { + /* it's too small */ + r_u->status = ERROR_INSUFFICIENT_BUFFER; /* say so */ + r_u->offered = 0; /* don't send back the buffer */ + + DEBUG(4,("spoolss_io_r_getprinter, buffer too small\n")); + + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + } + else + { + DEBUG(4,("spoolss_io_r_getprinter, buffer large enough\n")); + + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + } + + if (ps->io) + { + /* reading */ + r_u->ctr.printer.info = Realloc(NULL, r_u->offered); + } + + if (bufsize_required <= r_u->offered) + { + beginning=prs_offset(ps); + start_offset=prs_offset(ps); + end_offset=start_offset+r_u->offered; + + switch (r_u->level) + { + case 0: + { + PRINTER_INFO_0 *info; + info = r_u->ctr.printer.info0; + smb_io_printer_info_0(desc, + info, + ps, + depth, + &start_offset, + &end_offset); + if (!ps->io) + { + /* writing */ + free(info); + } + break; + } + case 1: + { + PRINTER_INFO_1 *info; + info = r_u->ctr.printer.info1; + smb_io_printer_info_1(desc, + info, + ps, + depth, + &start_offset, + &end_offset); + if (!ps->io) + { + /* writing */ + free(info); + } + break; + } + case 2: + { + PRINTER_INFO_2 *info; + info = r_u->ctr.printer.info2; + smb_io_printer_info_2(desc, + info, + ps, + depth, + &start_offset, + &end_offset); + if (!ps->io) + { + /* writing */ + free_printer_info_2(info); + } + break; + } + + } + + prs_set_offset(ps, beginning+r_u->offered); + prs_align(ps); + } + + /* + * if the buffer was too small, send the minimum required size + * if it was too large, send the real needed size + */ + + prs_uint32("size of buffer needed", ps, depth, &(bufsize_required)); + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/******************************************************************* + * read a uint8 buffer of size *size. + * allocate memory for it + * return a pointer to the allocated memory and the size + * return NULL and a size of 0 if the buffer is empty + * + * jfmxxxx: fix it to also write a buffer + ********************************************************************/ +static BOOL spoolss_io_read_buffer8(char *desc, prs_struct *ps, uint8 **buffer, uint32 *size,int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_read_buffer8"); + depth++; + + prs_align(ps); + + prs_uint32("buffer size", ps, depth, size); + *buffer = (uint8 *)Realloc(NULL, (*size) * sizeof(uint8) ); + prs_uint8s(True,"buffer",ps,depth,*buffer,*size); + prs_align(ps); + + return True; +} + +/******************************************************************* + * make a structure. + * called from spoolss_getprinter (srv_spoolss.c) + ********************************************************************/ +BOOL make_spoolss_q_getprinter(SPOOL_Q_GETPRINTER *q_u, + POLICY_HND *hnd, + uint32 level, + uint32 buf_size) +{ + if (q_u == NULL) return False; + + memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); + + q_u->level = level; + q_u->buffer = (uint8 *)Realloc(NULL, (buf_size) * sizeof(uint8) ); + q_u->offered = buf_size; + + return True; +} + +/******************************************************************* + * read a structure. + * called from spoolss_getprinter (srv_spoolss.c) + ********************************************************************/ +BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, + prs_struct *ps, int depth) +{ + uint32 count = 0; + uint32 buf_ptr = q_u->buffer != NULL ? 1 : 0; + prs_debug(ps, depth, desc, "spoolss_io_q_getprinter"); + depth++; + + prs_align(ps); + + smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); + + prs_uint32("level", ps, depth, &(q_u->level)); + + if (!ps->io) + { + /* writing */ + buf_ptr = q_u->buffer != NULL ? 1 : 0; + } + prs_uint32("buffer pointer", ps, depth, &buf_ptr); + + if (buf_ptr != 0) + { + spoolss_io_read_buffer8("",ps, &q_u->buffer, &count,depth); + } + if (q_u->buffer != NULL) + { + free(q_u->buffer); + } + prs_uint32("buffer size", ps, depth, &(q_u->offered)); + + return count == q_u->offered; +} + +/******************************************************************* +********************************************************************/ +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); + + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_q_setprinter"); + depth++; + + prs_align(ps); + + smb_io_prt_hnd("printer handle", &(q_u->handle),ps,depth); + prs_uint32("level", ps, depth, &(q_u->level)); + + /* again a designed mess */ + /* sometimes I'm wondering how all of this work ! */ + + /* To be correct it need to be split in 3 functions */ + + spool_io_printer_info_level("", &(q_u->info), ps, depth); + + spoolss_io_devmode(desc, ps, depth, q_u->devmode); + + prs_uint32("security.size_of_buffer", ps, depth, &(q_u->security.size_of_buffer)); + prs_uint32("security.data", ps, depth, &(q_u->security.data)); + + prs_uint32("command", ps, depth, &(q_u->command)); + + return True; +} + +/******************************************************************* +********************************************************************/ +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); + + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/******************************************************************* +********************************************************************/ +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); + + smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); + + return True; +} + + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, ""); + depth++; + + prs_align(ps); + + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_q_addjob(char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth) +{ + + prs_debug(ps, depth, desc, ""); + depth++; + + prs_align(ps); + + smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); + prs_uint32("level", ps, depth, &(q_u->level)); + + spoolss_io_read_buffer("", ps, depth, &(q_u->buffer)); + + prs_align(ps); + + prs_uint32("buf_size", ps, depth, &(q_u->buf_size)); + + return True; +} + +/**************************************************************************** +****************************************************************************/ +void free_job_info_ctr(JOB_INFO_CTR *ctr, uint32 level, uint32 numofjobs) +{ + DEBUG(4,("free_enum_jobs_info: [%d] structs to free at level [%d]\n", + numofjobs, level)); + switch (level) + { + case 1: + { + free_job1_array(numofjobs, + ctr->job.job_info_1); + break; + } + case 2: + { + free_job2_array(numofjobs, + ctr->job.job_info_2); + break; + } + } +} + +/**************************************************************************** +****************************************************************************/ +void free_r_enumjobs(SPOOL_R_ENUMJOBS *r_u) +{ + free_job_info_ctr(&r_u->ctr, r_u->level, r_u->numofjobs); +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth) +{ + uint32 useless_ptr = 0; + uint32 start_offset, end_offset, beginning; + uint32 bufsize_required=0; + uint32 tmp_ct = 0; + int i; + + prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs"); + depth++; + + prs_align(ps); + + if (!ps->io) + { + /* writing */ + switch (r_u->level) + { + case 1: + { + for (i=0; inumofjobs; i++) + { + JOB_INFO_1 *info; + info=r_u->ctr.job.job_info_1[i]; + bufsize_required += spoolss_size_job_info_1(&(info[i])); + } + break; + } + case 2: + { + for (i=0; inumofjobs; i++) + { + JOB_INFO_2 *info; + info=r_u->ctr.job.job_info_2[i]; + + bufsize_required += spoolss_size_job_info_2(&(info[i])); + } + break; + } + } + + DEBUG(4,("spoolss_io_r_enumjobs, size needed: %d\n", + bufsize_required)); + DEBUG(4,("spoolss_io_r_enumjobs, size offered: %d\n", + r_u->offered)); + + /* check if the buffer is big enough for the datas */ + if (r_u->offeredstatus = ERROR_INSUFFICIENT_BUFFER; /* say so */ + r_u->offered = bufsize_required; + useless_ptr = 0; + + DEBUG(4,("spoolss_io_r_enumjobs, buffer too small\n")); + + } + else + { + useless_ptr = 1; + } + } + + prs_uint32("pointer", ps, depth, &useless_ptr); + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + + if (useless_ptr != 0) + { + beginning=prs_offset(ps); + start_offset=prs_offset(ps); + end_offset=start_offset+r_u->offered; + + tmp_ct = 0; + + if (ps->io) + { + /* reading */ + prs_set_offset(ps, beginning + r_u->offered); + + prs_align(ps); + prs_uint32("buffer size", ps, depth, &(bufsize_required)); + prs_uint32("numofjobs", ps, depth, &(r_u->numofjobs)); + + prs_set_offset(ps, beginning); + } + + switch (r_u->level) + { + case 1: + { + JOB_INFO_1 *info; + for (i=0; inumofjobs; i++) + { + if (ps->io) + { + /* reading */ +/* r_u->ctr.job.job_info_1[i] = add_job1_to_array(&tmp_ct, &r_u->ctr.job.job_info_1, NULL);*/ + } + info = r_u->ctr.job.job_info_1[i]; + smb_io_job_info_1(desc, + info, + ps, + depth, + &start_offset, + &end_offset); + } + break; + } + case 2: + { + JOB_INFO_2 *info; + for (i=0; inumofjobs; i++) + { + if (ps->io) + { + /* reading */ +/* r_u->ctr.job.job_info_2[i] = add_job2_to_array(&tmp_ct, &r_u->ctr.job.job_info_2, NULL);*/ + } + info = r_u->ctr.job.job_info_2[i]; + smb_io_job_info_2(desc, + info, + ps, + depth, + &start_offset, + &end_offset); + } + break; + } + + } + prs_set_offset(ps, beginning+r_u->offered); + prs_align(ps); + + /* + * if the buffer was too small, send the minimum required size + * if it was too large, send the real needed size + */ + + prs_uint32("buffer size", ps, depth, &(bufsize_required)); + } + + prs_uint32("numofjobs", ps, depth, &(r_u->numofjobs)); + prs_uint32("status", ps, depth, &(r_u->status)); + + if (!ps->io) + { + /* writing */ + free_r_enumjobs(r_u); + } + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd, + uint32 firstjob, + uint32 numofjobs, + uint32 level, + uint32 buf_size) +{ + if (q_u == NULL) + { + return False; + } + memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); + q_u->firstjob = firstjob; + q_u->numofjobs = numofjobs; + q_u->level = level; + + if (!make_spoolss_buffer(&q_u->buffer, buf_size)) + { + return False; + } + q_u->buf_size = buf_size; + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_q_enumjobs(char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs"); + depth++; + + prs_align(ps); + + smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); + prs_uint32("firstjob", ps, depth, &(q_u->firstjob)); + prs_uint32("numofjobs", ps, depth, &(q_u->numofjobs)); + prs_uint32("level", ps, depth, &(q_u->level)); + + spoolss_io_read_buffer("", ps, depth, &(q_u->buffer)); + + prs_uint32("buf_size", ps, depth, &(q_u->buf_size)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_r_schedulejob(char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_schedulejob"); + depth++; + + prs_align(ps); + + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_q_schedulejob(char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_q_schedulejob"); + depth++; + + prs_align(ps); + + smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); + prs_uint32("jobid", ps, depth, &(q_u->jobid)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_r_setjob(char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_setjob"); + depth++; + + prs_align(ps); + + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_q_setjob(char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_q_setjob"); + depth++; + + prs_align(ps); + + smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); + prs_uint32("jobid", ps, depth, &(q_u->jobid)); + /* + * 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)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_r_enumdrivers(char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth) +{ + uint32 useless_ptr=0xADDE0FF0; + uint32 start_offset, end_offset, beginning; + uint32 bufsize_required=0; + int i; + + prs_debug(ps, depth, desc, "spoolss_io_r_enumdrivers"); + depth++; + + prs_align(ps); + prs_uint32("pointer", ps, depth, &useless_ptr); + + DEBUG(7,("Level [%d], number [%d]\n", r_u->level, r_u->numofdrivers)); + switch (r_u->level) + { + case 1: + { + DRIVER_INFO_1 *driver_info_1; + driver_info_1=r_u->ctr.driver.info1; + + for (i=0; inumofdrivers; i++) + { + bufsize_required += spoolss_size_printer_driver_info_1(&(driver_info_1[i])); + } + break; + } + case 2: + { + DRIVER_INFO_2 *driver_info_2; + driver_info_2=r_u->ctr.driver.info2; + + for (i=0; inumofdrivers; i++) + { + bufsize_required += spoolss_size_printer_driver_info_2(&(driver_info_2[i])); + } + break; + } + case 3: + { + DRIVER_INFO_3 *driver_info_3; + driver_info_3=r_u->ctr.driver.info3; + + for (i=0; inumofdrivers; i++) + { + bufsize_required += spoolss_size_printer_driver_info_3(&(driver_info_3[i])); + } + break; + } + } + + DEBUGADD(7,("size needed: %d\n",bufsize_required)); + DEBUGADD(7,("size offered: %d\n",r_u->offered)); + + /* check if the buffer is big enough for the datas */ + + if (r_u->offeredstatus=ERROR_INSUFFICIENT_BUFFER; /* say so */ + r_u->offered=0; /* don't send back the buffer */ + DEBUGADD(8,("buffer too small\n")); + + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + } + else + { + DEBUGADD(8,("buffer large enough\n")); + + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + beginning=prs_offset(ps); + start_offset=prs_offset(ps); + end_offset=start_offset+r_u->offered; + + switch (r_u->level) + { + case 1: + { + DRIVER_INFO_1 *info; + for (i=0; inumofdrivers; i++) + { + info = &(r_u->ctr.driver.info1[i]); + smb_io_printer_driver_info_1(desc, info, ps, depth, &start_offset, &end_offset); + } + break; + } + case 2: + { + DRIVER_INFO_2 *info; + for (i=0; inumofdrivers; i++) + { + info = &(r_u->ctr.driver.info2[i]); + smb_io_printer_driver_info_2(desc, info, ps, depth, &start_offset, &end_offset); + } + break; + } + case 3: + { + DRIVER_INFO_3 *info; + for (i=0; inumofdrivers; i++) + { + info = &(r_u->ctr.driver.info3[i]); + smb_io_printer_driver_info_3(desc, info, ps, depth, &start_offset, &end_offset); + } + break; + } + } + prs_set_offset(ps, beginning+r_u->offered); + prs_align(ps); + } + + /* + * if the buffer was too small, send the minimum required size + * if it was too large, send the real needed size + */ + + prs_uint32("size of buffer needed", ps, depth, &(bufsize_required)); + prs_uint32("numofdrivers", ps, depth, &(r_u->numofdrivers)); + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + + +void free_spoolss_r_enumdrivers(SPOOL_R_ENUMPRINTERDRIVERS *r_u) +{ + switch (r_u->level) + { + case 1: + { + DRIVER_INFO_1 *driver_info_1; + driver_info_1=r_u->ctr.driver.info1; + + free(driver_info_1); + break; + } + case 2: + { + DRIVER_INFO_2 *driver_info_2; + driver_info_2=r_u->ctr.driver.info2; + + free(driver_info_2); + break; + } + case 3: + { + DRIVER_INFO_3 *driver_info_3; + + UNISTR **dependentfiles; + int i; + + driver_info_3=r_u->ctr.driver.info3; + + for (i=0; inumofdrivers; i++) + { + int j=0; + dependentfiles=(driver_info_3[i]).dependentfiles; + while ( dependentfiles[j] != NULL ) + { + free(dependentfiles[j]); + j++; + } + + free(dependentfiles); + } + free(driver_info_3); + break; + } + } +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_q_enumprinterdrivers(char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth) +{ + + uint32 useless_ptr=0xADDE0FF0; + prs_debug(ps, depth, desc, ""); + depth++; + + prs_align(ps); + prs_uint32("pointer", ps, depth, &useless_ptr); + smb_io_unistr2("", &(q_u->name),True,ps,depth); + prs_align(ps); + prs_uint32("pointer", ps, depth, &useless_ptr); + smb_io_unistr2("", &(q_u->environment),True,ps,depth); + prs_align(ps); + prs_uint32("level", ps, depth, &(q_u->level)); + spoolss_io_read_buffer("", ps, depth, &(q_u->buffer)); + prs_align(ps); + prs_uint32("buf_size", ps, depth, &(q_u->buf_size)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_q_enumforms(char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth) +{ + + prs_debug(ps, depth, desc, "spoolss_io_q_enumforms"); + depth++; + + if (!prs_align(ps)) + return False; + if (!smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth)) + return False; + if (!prs_uint32("level", ps, depth, &(q_u->level))) + return False; + + if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer)) + return False; + + if (!prs_align(ps)) + return False; + if (!prs_uint32("offered", ps, depth, &(q_u->offered))) + return False; + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL new_spoolss_io_r_enumforms(char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "new_spoolss_io_r_enumforms"); + depth++; + + if (!prs_align(ps)) + return False; + + if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("size of buffer needed", ps, depth, &(r_u->needed))) + return False; + + if (!prs_uint32("numofforms", ps, depth, &(r_u->numofforms))) + return False; + + if (!prs_uint32("status", ps, depth, &(r_u->status))) + return False; + + return True; + +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth) +{ + uint32 useless_ptr=0xADDE0FF0; + uint32 start_offset, end_offset, beginning; + uint32 bufsize_required=0; + int i; + + prs_debug(ps, depth, desc, "spoolss_io_r_enumports"); + depth++; + + prs_align(ps); + prs_uint32("pointer", ps, depth, &useless_ptr); + switch (r_u->level) + { + case 2: + { + PORT_INFO_2 *port_2; + port_2=r_u->ctr.port.info_2; + + for (i=0; inumofports; i++) + { + bufsize_required += spoolss_size_port_info_2(&(port_2[i])); + } + break; + } + } + + DEBUG(4,("size needed: %d\n",bufsize_required)); + DEBUG(4,("size offered: %d\n",r_u->offered)); + + /* check if the buffer is big enough for the datas */ + if (r_u->offeredstatus=ERROR_INSUFFICIENT_BUFFER; /* say so */ + r_u->offered=0; /* don't send back the buffer */ + + DEBUG(4,("buffer too small\n")); + + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + } + else + { + DEBUG(4,("buffer large enough\n")); + + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + beginning=prs_offset(ps); + start_offset=prs_offset(ps); + end_offset=start_offset+r_u->offered; + + switch (r_u->level) + { + case 2: + { + PORT_INFO_2 *info; + for (i=0; inumofports; i++) + { + info = &(r_u->ctr.port.info_2[i]); + smb_io_port_2(desc, info, ps, depth, &start_offset, &end_offset); + } + break; + } + } + prs_set_offset(ps, beginning+r_u->offered); + prs_align(ps); + } + + /* + * if the buffer was too small, send the minimum required size + * if it was too large, send the real needed size + */ + + prs_uint32("size of buffer needed", ps, depth, &(bufsize_required)); + prs_uint32("numofports", ps, depth, &(r_u->numofports)); + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +void spoolss_free_r_enumports(SPOOL_R_ENUMPORTS *r_u) +{ + switch (r_u->level) + { + case 2: + { + safe_free(r_u->ctr.port.info_2); + break; + } + } +} +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_q_enumports(char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth) +{ + uint32 useless; + prs_debug(ps, depth, desc, ""); + depth++; + + prs_align(ps); + prs_uint32("useless", ps, depth, &useless); + smb_io_unistr2("", &(q_u->name),True,ps,depth); + prs_align(ps); + prs_uint32("level", ps, depth, &(q_u->level)); + spoolss_io_read_buffer("", ps, depth, &(q_u->buffer)); + prs_align(ps); + prs_uint32("buf_size", ps, depth, &(q_u->buf_size)); + + return True; +} + + +/******************************************************************* +********************************************************************/ +BOOL spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 **q_u, prs_struct *ps, int depth) +{ + SPOOL_PRINTER_INFO_LEVEL_2 *il; + + prs_debug(ps, depth, desc, ""); + depth++; + + /* reading */ + if (ps->io) + { + il=(SPOOL_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(SPOOL_PRINTER_INFO_LEVEL_2)); + ZERO_STRUCTP(il); + *q_u=il; + DEBUG(7,("lecture: memoire ok\n")); + } + else + { + il=*q_u; + } + + prs_align(ps); + + prs_uint32("servername_ptr", ps, depth, &(il->servername_ptr)); + prs_uint32("printername_ptr", ps, depth, &(il->printername_ptr)); + prs_uint32("sharename_ptr", ps, depth, &(il->sharename_ptr)); + prs_uint32("portname_ptr", ps, depth, &(il->portname_ptr)); + prs_uint32("drivername_ptr", ps, depth, &(il->drivername_ptr)); + prs_uint32("comment_ptr", ps, depth, &(il->comment_ptr)); + prs_uint32("location_ptr", ps, depth, &(il->location_ptr)); + prs_uint32("devmode_ptr", ps, depth, &(il->devmode_ptr)); + prs_uint32("sepfile_ptr", ps, depth, &(il->sepfile_ptr)); + prs_uint32("printprocessor_ptr", ps, depth, &(il->printprocessor_ptr)); + prs_uint32("datatype_ptr", ps, depth, &(il->datatype_ptr)); + prs_uint32("parameters_ptr", ps, depth, &(il->parameters_ptr)); + prs_uint32("secdesc_ptr", ps, depth, &(il->secdesc_ptr)); + + prs_uint32("attributes", ps, depth, &(il->attributes)); + prs_uint32("priority", ps, depth, &(il->priority)); + prs_uint32("default_priority", ps, depth, &(il->default_priority)); + prs_uint32("starttime", ps, depth, &(il->starttime)); + prs_uint32("untiltime", ps, depth, &(il->untiltime)); + prs_uint32("status", ps, depth, &(il->status)); + prs_uint32("cjobs", ps, depth, &(il->cjobs)); + prs_uint32("averageppm", ps, depth, &(il->averageppm)); + + smb_io_unistr2("", &(il->servername), il->servername_ptr, ps, depth); + smb_io_unistr2("", &(il->printername), il->printername_ptr, ps, depth); + smb_io_unistr2("", &(il->sharename), il->sharename_ptr, ps, depth); + smb_io_unistr2("", &(il->portname), il->portname_ptr, ps, depth); + smb_io_unistr2("", &(il->drivername), il->drivername_ptr, ps, depth); + smb_io_unistr2("", &(il->comment), il->comment_ptr, ps, depth); + smb_io_unistr2("", &(il->location), il->location_ptr, ps, depth); + smb_io_unistr2("", &(il->sepfile), il->sepfile_ptr, ps, depth); + smb_io_unistr2("", &(il->printprocessor), il->printprocessor_ptr, ps, depth); + smb_io_unistr2("", &(il->datatype), il->datatype_ptr, ps, depth); + smb_io_unistr2("", &(il->parameters), il->parameters_ptr, ps, depth); + + prs_align(ps); + + /* this code as nothing to do here !!! + + if (il->secdesc_ptr) + { + il->secdesc=NULL; + sec_io_desc_buf("", &(il->secdesc), ps, depth); + } + + */ + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth) +{ + uint32 useless; + uint32 level; + prs_debug(ps, depth, desc, ""); + depth++; + + prs_align(ps); + prs_uint32("info level", ps, depth, &level); + prs_uint32("useless", ps, depth, &useless); + + switch (level) + { + /* + * level 0 is used by setprinter when managing the queue + * (hold, stop, start a queue) + */ + case 0: + break; + /* + * level 2 is used by addprinter + * and by setprinter when updating printer's info + */ + case 2: + spool_io_printer_info_level_2("", &(il->info_2), ps, depth); + break; + } + + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth) +{ + uint32 useless; + prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex"); + depth++; + + /* + * I think that's one of the few well written functions. + * the sub-structures are correctly parsed and analysed + * the info level are handled in a nice way. + */ + + prs_align(ps); + prs_uint32("useless", ps, depth, &useless); + smb_io_unistr2("", &(q_u->server_name),True,ps,depth); + prs_align(ps); + + prs_uint32("info_level", ps, depth, &(q_u->level)); + + spool_io_printer_info_level("", &(q_u->info), ps, depth); + + /* the 4 unknown are all 0 */ + + /* + * en fait ils sont pas inconnu + * par recoupement avec rpcSetPrinter + * c'est le devicemode + * et le security descriptor. + */ + + prs_uint32("unk0", ps, depth, &(q_u->unk0)); + prs_uint32("unk1", ps, depth, &(q_u->unk1)); + prs_uint32("unk2", ps, depth, &(q_u->unk2)); + prs_uint32("unk3", ps, depth, &(q_u->unk3)); + + prs_uint32("info_level", ps, depth, &(q_u->user_level)); + + spool_io_user_level("", &(q_u->user), ps, depth); + + return True; +} + + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_r_addprinterex(char *desc, SPOOL_R_ADDPRINTEREX *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex"); + depth++; + + smb_io_prt_hnd("printer handle",&(r_u->handle),ps,depth); + + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spool_io_printer_driver_info_level_3(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, + prs_struct *ps, int depth) +{ + SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il; + + prs_debug(ps, depth, desc, ""); + depth++; + + /* reading */ + if (ps->io) + { + il=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *)malloc(sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3)); + ZERO_STRUCTP(il); + *q_u=il; + DEBUG(1,("lecture: memoire ok\n")); + } + else + { + il=*q_u; + } + + prs_align(ps); + + prs_uint32("cversion", ps, depth, &(il->cversion)); + prs_uint32("name", ps, depth, &(il->name_ptr)); + prs_uint32("environment", ps, depth, &(il->environment_ptr)); + prs_uint32("driverpath", ps, depth, &(il->driverpath_ptr)); + prs_uint32("datafile", ps, depth, &(il->datafile_ptr)); + prs_uint32("configfile", ps, depth, &(il->configfile_ptr)); + prs_uint32("helpfile", ps, depth, &(il->helpfile_ptr)); + prs_uint32("monitorname", ps, depth, &(il->monitorname_ptr)); + prs_uint32("defaultdatatype", ps, depth, &(il->defaultdatatype_ptr)); + prs_uint32("dependentfilessize", ps, depth, &(il->dependentfilessize)); + prs_uint32("dependentfiles", ps, depth, &(il->dependentfiles_ptr)); + + prs_align(ps); + + smb_io_unistr2("", &(il->name), il->name_ptr, ps, depth); + smb_io_unistr2("", &(il->environment), il->environment_ptr, ps, depth); + smb_io_unistr2("", &(il->driverpath), il->driverpath_ptr, ps, depth); + smb_io_unistr2("", &(il->datafile), il->datafile_ptr, ps, depth); + smb_io_unistr2("", &(il->configfile), il->configfile_ptr, ps, depth); + smb_io_unistr2("", &(il->helpfile), il->helpfile_ptr, ps, depth); + smb_io_unistr2("", &(il->monitorname), il->monitorname_ptr, ps, depth); + smb_io_unistr2("", &(il->defaultdatatype), il->defaultdatatype_ptr, ps, depth); + + prs_align(ps); + if (il->dependentfiles_ptr) + smb_io_buffer5("", &(il->dependentfiles), ps, depth); + + + return True; +} + + +/******************************************************************* + convert a buffer of UNICODE strings null terminated + the buffer is terminated by a NULL + + convert to an ascii array (null terminated) + + dynamically allocate memory + +********************************************************************/ +BOOL uniarray_2_ascarray(BUFFER5 *buf5, char ***ar) +{ + char **array; + char *string; + char *destend; + char *dest; + uint32 n; + uint32 i; + + uint16 *src; + + if (buf5==NULL) return False; + + array=NULL; + n=0; + i=0; + src=buf5->buffer; + + string=(char *)malloc(sizeof(char)*buf5->buf_len); + + destend = string + buf5->buf_len; + dest=string; + + while (dest < destend) + { + *(dest++) = (char)*(src++); + } + + /* that ugly for the first one but that's working */ + array=(char **)Realloc(array, sizeof(char *)*(i+1)); + array[i++]=string; + + while ( n < buf5->buf_len ) + { + if ( *(string++) == '\0' ) + { + array=(char **)Realloc(array, sizeof(char *)*(i+1)); + array[i++]=string; + } + n++; + } + *ar=array; + + DEBUG(10,("Number of dependent files: [%d]\n", i-1)); + + return True; +} + +/******************************************************************* + read a UNICODE array with null terminated strings + and null terminated array + and size of array at beginning +********************************************************************/ +BOOL smb_io_unibuffer(char *desc, UNISTR2 *buffer, prs_struct *ps, int depth) +{ + if (buffer==NULL) return False; + + 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); + + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth) +{ + uint32 useless; + uint32 level; + prs_debug(ps, depth, desc, ""); + depth++; + + prs_align(ps); + prs_uint32("info level", ps, depth, &level); + prs_uint32("useless", ps, depth, &useless); + + switch (level) + { + case 3: + spool_io_printer_driver_info_level_3("", &(il->info_3), ps, depth); + break; + } + + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth) +{ + uint32 useless; + prs_debug(ps, depth, desc, ""); + depth++; + + prs_align(ps); + prs_uint32("useless", ps, depth, &useless); + smb_io_unistr2("", &(q_u->server_name),True,ps,depth); + prs_align(ps); + prs_uint32("info_level", ps, depth, &(q_u->level)); + + spool_io_printer_driver_info_level("", &(q_u->info), ps, depth); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_r_addprinterdriver(char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, ""); + depth++; + + prs_uint32("status", ps, depth, &(q_u->status)); + + return True; +} + + +/******************************************************************* +********************************************************************/ +BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni, + NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc) +{ + NT_PRINTER_DRIVER_INFO_LEVEL_3 *d; + + DEBUG(7,("uni_2_asc_printer_driver_3: Converting from UNICODE to ASCII\n")); + + if (*asc==NULL) + { + *asc=(NT_PRINTER_DRIVER_INFO_LEVEL_3 *)malloc(sizeof(NT_PRINTER_DRIVER_INFO_LEVEL_3)); + ZERO_STRUCTP(*asc); + } + + d=*asc; + + d->cversion=uni->cversion; + + unistr2_to_ascii(d->name, &(uni->name), sizeof(d->name)-1); + unistr2_to_ascii(d->environment, &(uni->environment), sizeof(d->environment)-1); + unistr2_to_ascii(d->driverpath, &(uni->driverpath), sizeof(d->driverpath)-1); + unistr2_to_ascii(d->datafile, &(uni->datafile), sizeof(d->datafile)-1); + unistr2_to_ascii(d->configfile, &(uni->configfile), sizeof(d->configfile)-1); + unistr2_to_ascii(d->helpfile, &(uni->helpfile), sizeof(d->helpfile)-1); + unistr2_to_ascii(d->monitorname, &(uni->monitorname), sizeof(d->monitorname)-1); + unistr2_to_ascii(d->defaultdatatype, &(uni->defaultdatatype), sizeof(d->defaultdatatype)-1); + + DEBUGADD(8,( "version: %d\n", d->cversion)); + DEBUGADD(8,( "name: %s\n", d->name)); + DEBUGADD(8,( "environment: %s\n", d->environment)); + DEBUGADD(8,( "driverpath: %s\n", d->driverpath)); + DEBUGADD(8,( "datafile: %s\n", d->datafile)); + DEBUGADD(8,( "configfile: %s\n", d->configfile)); + DEBUGADD(8,( "helpfile: %s\n", d->helpfile)); + DEBUGADD(8,( "monitorname: %s\n", d->monitorname)); + DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype)); + + uniarray_2_ascarray(&(uni->dependentfiles), &(d->dependentfiles) ); + + return True; +} + +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; + + DEBUG(7,("Converting from UNICODE to ASCII\n")); + + if (*asc==NULL) + { + DEBUGADD(8,("allocating memory\n")); + + *asc=(NT_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(NT_PRINTER_INFO_LEVEL_2)); + ZERO_STRUCTP(*asc); + } + DEBUGADD(8,("start converting\n")); + + d=*asc; + + d->attributes=uni->attributes; + d->priority=uni->priority; + d->default_priority=uni->default_priority; + d->starttime=uni->starttime; + d->untiltime=uni->untiltime; + 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); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth) +{ + uint32 useless_ptr=0xADDE0FF0; + uint32 start_offset, end_offset, beginning; + uint32 bufsize_required=0; + + prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriverdir"); + depth++; + + prs_align(ps); + + prs_uint32("pointer", ps, depth, &useless_ptr); + + switch (r_u->level) + { + case 1: + { + DRIVER_DIRECTORY_1 *driver_info_1; + driver_info_1=&(r_u->ctr.driver.info_1); + + bufsize_required = size_of_relative_string(&(driver_info_1->name)); + break; + } + } + + DEBUG(4,("spoolss_io_r_getprinterdriverdir, size needed: %d\n",bufsize_required)); + DEBUG(4,("spoolss_io_r_getprinterdriverdir, size offered: %d\n",r_u->offered)); + + /* check if the buffer is big enough for the datas */ + + if (r_u->offeredstatus=ERROR_INSUFFICIENT_BUFFER; /* say so */ + r_u->offered=0; /* don't send back the buffer */ + DEBUG(4,("spoolss_io_r_getprinterdriverdir, buffer too small\n")); + + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + } + else + { + DEBUG(4,("spoolss_io_r_getprinterdriverdir, buffer large enough\n")); + + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + beginning=prs_offset(ps); + start_offset=prs_offset(ps); + end_offset=start_offset+r_u->offered; + + switch (r_u->level) + { + case 1: + { + DRIVER_DIRECTORY_1 *info; + info = &(r_u->ctr.driver.info_1); + prs_unistr("name", ps, depth, &(info->name)); + /*smb_io_printer_driver_dir_1(desc, info, ps, depth, &start_offset, &end_offset);*/ + break; + } + } + prs_set_offset(ps, beginning+r_u->offered); + prs_align(ps); + } + + /* + * if the buffer was too small, send the minimum required size + * if it was too large, send the real needed size + */ + + prs_uint32("size of buffer needed", ps, depth, &(bufsize_required)); + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth) +{ + + uint32 useless_ptr=0xADDE0FF0; + prs_debug(ps, depth, desc, ""); + depth++; + + prs_align(ps); + prs_uint32("pointer", ps, depth, &useless_ptr); + smb_io_unistr2("", &(q_u->name),True,ps,depth); + prs_align(ps); + prs_uint32("pointer", ps, depth, &useless_ptr); + smb_io_unistr2("", &(q_u->environment),True,ps,depth); + prs_align(ps); + prs_uint32("level", ps, depth, &(q_u->level)); + spoolss_io_read_buffer("", ps, depth, &(q_u->buffer)); + prs_align(ps); + prs_uint32("buf_size", ps, depth, &(q_u->buf_size)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth) +{ + uint32 useless_ptr=0xADDE0FF0; + uint32 start_offset, end_offset, beginning; + uint32 bufsize_required=0; + int i; + + prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors"); + depth++; + + prs_align(ps); + prs_uint32("pointer", ps, depth, &useless_ptr); + switch (r_u->level) + { + case 1: + { + PRINTPROCESSOR_1 *info_1; + info_1=r_u->info_1; + + for (i=0; inumofprintprocessors; i++) + { + bufsize_required += spoolss_size_processor_info_1(&(info_1[i])); + } + break; + } + } + + DEBUG(4,("size needed: %d\n",bufsize_required)); + DEBUG(4,("size offered: %d\n",r_u->offered)); + + /* check if the buffer is big enough for the datas */ + if (r_u->offeredstatus=ERROR_INSUFFICIENT_BUFFER; /* say so */ + r_u->offered=0; /* don't send back the buffer */ + + DEBUG(4,("buffer too small\n")); + + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + } + else + { + DEBUG(4,("buffer large enough\n")); + + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + beginning=prs_offset(ps); + start_offset=prs_offset(ps); + end_offset=start_offset+r_u->offered; + + switch (r_u->level) + { + case 1: + { + PRINTPROCESSOR_1 *info_1; + for (i=0; inumofprintprocessors; i++) + { + info_1 = &(r_u->info_1[i]); + smb_io_processor_info_1(desc, info_1, ps, depth, &start_offset, &end_offset); + } + break; + } + } + prs_set_offset(ps, beginning+r_u->offered); + prs_align(ps); + } + + /* + * if the buffer was too small, send the minimum required size + * if it was too large, send the real needed size + */ + + prs_uint32("size of buffer needed", ps, depth, &(bufsize_required)); + prs_uint32("numofprintprocessors", ps, depth, &(r_u->numofprintprocessors)); + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth) +{ + uint32 useless; + prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors"); + depth++; + + prs_align(ps); + prs_uint32("useless", ps, depth, &useless); + smb_io_unistr2("", &(q_u->name),True,ps,depth); + prs_align(ps); + prs_uint32("useless", ps, depth, &useless); + smb_io_unistr2("", &(q_u->environment),True,ps,depth); + prs_align(ps); + prs_uint32("level", ps, depth, &(q_u->level)); + spoolss_io_read_buffer("", ps, depth, &(q_u->buffer)); + prs_align(ps); + prs_uint32("buf_size", ps, depth, &(q_u->buf_size)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth) +{ + uint32 useless_ptr=0xADDE0FF0; + uint32 start_offset, end_offset, beginning; + uint32 bufsize_required=0; + int i; + + prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors"); + depth++; + + prs_align(ps); + prs_uint32("pointer", ps, depth, &useless_ptr); + switch (r_u->level) + { + case 1: + { + PRINTMONITOR_1 *info_1; + info_1=r_u->info_1; + + for (i=0; inumofprintmonitors; i++) + { + bufsize_required += spoolss_size_monitor_info_1(&(info_1[i])); + } + break; + } + } + + DEBUG(4,("size needed: %d\n",bufsize_required)); + DEBUG(4,("size offered: %d\n",r_u->offered)); + + /* check if the buffer is big enough for the datas */ + if (r_u->offeredstatus=ERROR_INSUFFICIENT_BUFFER; /* say so */ + r_u->offered=0; /* don't send back the buffer */ + + DEBUG(4,("buffer too small\n")); + + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + } + else + { + DEBUG(4,("buffer large enough\n")); + + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + beginning=prs_offset(ps); + start_offset=prs_offset(ps); + end_offset=start_offset+r_u->offered; + + switch (r_u->level) + { + case 1: + { + PRINTMONITOR_1 *info_1; + for (i=0; inumofprintmonitors; i++) + { + info_1 = &(r_u->info_1[i]); + smb_io_monitor_info_1(desc, info_1, ps, depth, &start_offset, &end_offset); + } + break; + } + } + prs_set_offset(ps, beginning+r_u->offered); + prs_align(ps); + } + + /* + * if the buffer was too small, send the minimum required size + * if it was too large, send the real needed size + */ + + prs_uint32("size of buffer needed", ps, depth, &(bufsize_required)); + prs_uint32("numofprintmonitors", ps, depth, &(r_u->numofprintmonitors)); + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth) +{ + uint32 useless; + prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors"); + depth++; + + prs_align(ps); + prs_uint32("useless", ps, depth, &useless); + smb_io_unistr2("", &(q_u->name),True,ps,depth); + prs_align(ps); + prs_uint32("level", ps, depth, &(q_u->level)); + spoolss_io_read_buffer("", ps, depth, &(q_u->buffer)); + prs_align(ps); + prs_uint32("buf_size", ps, depth, &(q_u->buf_size)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata"); + depth++; + + prs_align(ps); + prs_uint32("valuesize", ps, depth, &(r_u->valuesize)); + prs_unistr("value", ps, depth, &(r_u->value)); + prs_uint32("realvaluesize", ps, depth, &(r_u->realvaluesize)); + + prs_uint32("type", ps, depth, &(r_u->type)); + + prs_uint32("datasize", ps, depth, &(r_u->datasize)); + prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize); + prs_uint32("realdatasize", ps, depth, &(r_u->realdatasize)); + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_q_enumprinterdata(char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata"); + depth++; + + prs_align(ps); + smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); + prs_uint32("index", ps, depth, &(q_u->index)); + prs_uint32("valuesize", ps, depth, &(q_u->valuesize)); + prs_uint32("datasize", ps, depth, &(q_u->datasize)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_q_setprinterdata"); + depth++; + + prs_align(ps); + smb_io_prt_hnd("printer handle", &(q_u->handle), ps, depth); + smb_io_unistr2("", &(q_u->value), True, ps, depth); + + prs_align(ps); + + prs_uint32("type", ps, depth, &(q_u->type)); + + prs_uint32("max_len", ps, depth, &(q_u->max_len)); + + switch (q_u->type) + { + case 0x1: + case 0x3: + 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); + break; + } + + prs_uint32("real_len", ps, depth, &(q_u->real_len)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_r_setprinterdata(char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_setprinterdata"); + depth++; + + prs_align(ps); + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value, + uint32 type, const uint8 *data, uint32 len) +{ + DEBUG(5,("converting a specific param struct\n")); + + if (*param == NULL) + { + *param=(NT_PRINTER_PARAM *)malloc(sizeof(NT_PRINTER_PARAM)); + ZERO_STRUCTP(*param); + DEBUGADD(6,("Allocated a new PARAM struct\n")); + } + unistr2_to_ascii((*param)->value, value, sizeof((*param)->value)-1); + (*param)->type = type; + + /* le champ data n'est pas NULL termine */ + /* on stocke donc la longueur */ + + (*param)->data_len=len; + + (*param)->data=(uint8 *)malloc(len * sizeof(uint8)); + + memcpy((*param)->data, data, len); + + DEBUGADD(6,("\tvalue:[%s], len:[%d]\n",(*param)->value, (*param)->data_len)); + + return True; +} + +/******************************************************************* +********************************************************************/ +static BOOL spoolss_io_addform(char *desc, FORM *f, uint32 ptr, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_addform"); + depth++; + prs_align(ps); + + 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); + } + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth) +{ + uint32 useless_ptr=0; + prs_debug(ps, depth, desc, "spoolss_io_q_addform"); + depth++; + + prs_align(ps); + smb_io_prt_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 (q_u->level==1) + { + prs_uint32("useless_ptr", ps, depth, &(useless_ptr)); + spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth); + } + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_addform"); + depth++; + + prs_align(ps); + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_q_setform(char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth) +{ + uint32 useless_ptr=0; + prs_debug(ps, depth, desc, "spoolss_io_q_setform"); + depth++; + + prs_align(ps); + smb_io_prt_hnd("printer handle", &(q_u->handle), ps, depth); + smb_io_unistr2("", &(q_u->name), True, ps, depth); + + prs_align(ps); + + prs_uint32("level", ps, depth, &(q_u->level)); + prs_uint32("level2", ps, depth, &(q_u->level2)); + + if (q_u->level==1) + { + prs_uint32("useless_ptr", ps, depth, &(useless_ptr)); + spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth); + } + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_setform"); + depth++; + + prs_align(ps); + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_r_getjob(char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth) +{ + uint32 useless_ptr=0xADDE0FF0; + uint32 start_offset, end_offset, beginning; + uint32 bufsize_required=0; + + prs_debug(ps, depth, desc, "spoolss_io_r_getjob"); + depth++; + + prs_align(ps); + + prs_uint32("pointer", ps, depth, &useless_ptr); + + switch (r_u->level) + { + case 1: + { + JOB_INFO_1 *info; + info=r_u->ctr.job.job_info_1; + + bufsize_required += spoolss_size_job_info_1(info); + break; + } + case 2: + { + JOB_INFO_2 *info; + info=r_u->ctr.job.job_info_2; + + bufsize_required += spoolss_size_job_info_2(info); + break; + } + } + + DEBUG(4,("spoolss_io_r_getjob, size needed: %d\n",bufsize_required)); + DEBUG(4,("spoolss_io_r_getjob, size offered: %d\n",r_u->offered)); + + /* check if the buffer is big enough for the datas */ + if (r_u->offeredstatus=ERROR_INSUFFICIENT_BUFFER; /* say so */ + r_u->offered=0; /* don't send back the buffer */ + + DEBUG(4,("spoolss_io_r_getjob, buffer too small\n")); + + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + } + else + { + DEBUG(4,("spoolss_io_r_enumjobs, buffer large enough\n")); + + prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + beginning=prs_offset(ps); + start_offset=prs_offset(ps); + end_offset=start_offset+r_u->offered; + + switch (r_u->level) + { + case 1: + { + JOB_INFO_1 *info; + info = r_u->ctr.job.job_info_1; + smb_io_job_info_1(desc, info, ps, depth, &start_offset, &end_offset); + break; + } + case 2: + { + JOB_INFO_2 *info; + info = r_u->ctr.job.job_info_2; + smb_io_job_info_2(desc, info, ps, depth, &start_offset, &end_offset); + break; + } + + } + prs_set_offset(ps, beginning+r_u->offered); + prs_align(ps); + } + + /* + * if the buffer was too small, send the minimum required size + * if it was too large, send the real needed size + */ + + prs_uint32("size of buffer needed", ps, depth, &(bufsize_required)); + prs_uint32("status", ps, depth, &(r_u->status)); + + return True; +} + +/**************************************************************************** +****************************************************************************/ +void free_spoolss_r_getjob(SPOOL_R_GETJOB *r_u) +{ + switch (r_u->level) + { + case 1: + { + free(r_u->ctr.job.job_info_1); + break; + } + case 2: + { + free_job_info_2(r_u->ctr.job.job_info_2); + break; + } + } +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_q_getjob(char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth) +{ + + prs_debug(ps, depth, desc, ""); + depth++; + + prs_align(ps); + + smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); + prs_uint32("jobid", ps, depth, &(q_u->jobid)); + prs_uint32("level", ps, depth, &(q_u->level)); + + spoolss_io_read_buffer("", ps, depth, &(q_u->buffer)); + + prs_align(ps); + + prs_uint32("buf_size", ps, depth, &(q_u->buf_size)); + + return True; +} + +void free_devmode(DEVICEMODE *devmode) +{ + if (devmode!=NULL) + { + if (devmode->private!=NULL) + free(devmode->private); + free(devmode); + } +} + +void free_printer_info_2(PRINTER_INFO_2 *printer) +{ + if (printer!=NULL) + { + free_devmode(printer->devmode); + free(printer); + } +} + +static PRINTER_INFO_2 *prt2_dup(const PRINTER_INFO_2* from) +{ + PRINTER_INFO_2 *copy = (PRINTER_INFO_2 *)malloc(sizeof(PRINTER_INFO_2)); + if (copy != NULL) + { + if (from != NULL) + { + memcpy(copy, from, sizeof(*copy)); + } + else + { + ZERO_STRUCTP(copy); + } + } + return copy; +} + +void free_print2_array(uint32 num_entries, PRINTER_INFO_2 **entries) +{ + void(*fn)(void*) = (void(*)(void*))&free_printer_info_2; + free_void_array(num_entries, (void**)entries, *fn); +} + +PRINTER_INFO_2 *add_print2_to_array(uint32 *len, PRINTER_INFO_2 ***array, + const PRINTER_INFO_2 *prt) +{ + void*(*fn)(const void*) = (void*(*)(const void*))&prt2_dup; + return (PRINTER_INFO_2*)add_copy_to_array(len, + (void***)array, (const void*)prt, *fn, True); +} + +static PRINTER_INFO_1 *prt1_dup(const PRINTER_INFO_1* from) +{ + PRINTER_INFO_1 *copy = (PRINTER_INFO_1 *)malloc(sizeof(PRINTER_INFO_1)); + if (copy != NULL) + { + if (from != NULL) + { + memcpy(copy, from, sizeof(*copy)); + } + else + { + ZERO_STRUCTP(copy); + } + } + return copy; +} + +void free_print1_array(uint32 num_entries, PRINTER_INFO_1 **entries) +{ + void(*fn)(void*) = (void(*)(void*))&free; + free_void_array(num_entries, (void**)entries, *fn); +} + +PRINTER_INFO_1 *add_print1_to_array(uint32 *len, PRINTER_INFO_1 ***array, + const PRINTER_INFO_1 *prt) +{ + void*(*fn)(const void*) = (void*(*)(const void*))&prt1_dup; + return (PRINTER_INFO_1*)add_copy_to_array(len, + (void***)array, (const void*)prt, *fn, True); +} + +static JOB_INFO_1 *job1_dup(const JOB_INFO_1* from) +{ + JOB_INFO_1 *copy = (JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1)); + if (copy != NULL) + { + if (from != NULL) + { + memcpy(copy, from, sizeof(*copy)); + } + else + { + ZERO_STRUCTP(copy); + } + } + return copy; +} + +void free_job1_array(uint32 num_entries, JOB_INFO_1 **entries) +{ + void(*fn)(void*) = (void(*)(void*))&free; + free_void_array(num_entries, (void**)entries, *fn); +} + +JOB_INFO_1 *add_job1_to_array(uint32 *len, JOB_INFO_1 ***array, + const JOB_INFO_1 *job) +{ + void*(*fn)(const void*) = (void*(*)(const void*))&job1_dup; + return (JOB_INFO_1*)add_copy_to_array(len, + (void***)array, (const void*)job, *fn, True); +} + +static JOB_INFO_2 *job2_dup(const JOB_INFO_2* from) +{ + JOB_INFO_2 *copy = (JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2)); + if (copy != NULL) + { + if (from != NULL) + { + memcpy(copy, from, sizeof(*copy)); + } + else + { + ZERO_STRUCTP(copy); + } + } + return copy; +} + +void free_job_info_2(JOB_INFO_2 *job) +{ + if (job!=NULL) + { + free_devmode(job->devmode); + free(job); + } +} + +void free_job2_array(uint32 num_entries, JOB_INFO_2 **entries) +{ + void(*fn)(void*) = (void(*)(void*))&free_job_info_2; + free_void_array(num_entries, (void**)entries, *fn); +} + +JOB_INFO_2 *add_job2_to_array(uint32 *len, JOB_INFO_2 ***array, + const JOB_INFO_2 *job) +{ + void*(*fn)(const void*) = (void*(*)(const void*))&job2_dup; + return (JOB_INFO_2*)add_copy_to_array(len, + (void***)array, (const void*)job, *fn, True); +} + diff --git a/source/rpc_server/srv_spoolss.c b/source/rpc_server/srv_spoolss.c new file mode 100755 index 00000000000..60333e1f3b4 --- /dev/null +++ b/source/rpc_server/srv_spoolss.c @@ -0,0 +1,793 @@ +/* + * Unix SMB/Netbios implementation. + * Version 1.9. + * RPC Pipe client / server routines + * Copyright (C) Andrew Tridgell 1992-2000, + * Copyright (C) Luke Kenneth Casson Leighton 1996-2000, + * Copyright (C) Jean François Micouleau 1998-2000. + * + * 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" + +extern int DEBUGLEVEL; + +/******************************************************************** + * api_spoolss_open_printer_ex + ********************************************************************/ +static BOOL api_spoolss_open_printer_ex(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_OPEN_PRINTER_EX q_u; + SPOOL_R_OPEN_PRINTER_EX r_u; + UNISTR2 *printername = NULL; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if (!spoolss_io_q_open_printer_ex("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_open_printer_ex: unable to unmarshall SPOOL_Q_OPEN_PRINTER_EX.\n")); + return False; + } + + if (q_u.printername_ptr != 0) + { + printername = &q_u.printername; + } + + r_u.status = _spoolss_open_printer_ex( printername, + &q_u.printer_default, + q_u.user_switch, q_u.user_ctr, + &r_u.handle); + + if (!spoolss_io_r_open_printer_ex("",&r_u,rdata,0)){ + DEBUG(0,("spoolss_io_r_open_printer_ex: unable to marshall SPOOL_R_OPEN_PRINTER_EX.\n")); + return False; + } + + return True; +} + +/******************************************************************** + * api_spoolss_getprinterdata + * + * called from the spoolss dispatcher + ********************************************************************/ +static BOOL api_spoolss_getprinterdata(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_GETPRINTERDATA q_u; + SPOOL_R_GETPRINTERDATA r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + /* read the stream and fill the struct */ + if (!spoolss_io_q_getprinterdata("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_getprinterdata: unable to unmarshall SPOOL_Q_GETPRINTERDATA.\n")); + return False; + } + + r_u.status = _spoolss_getprinterdata( &q_u.handle, &q_u.valuename, + q_u.size, &r_u.type, &r_u.size, + &r_u.data, &r_u.needed); + + if (!spoolss_io_r_getprinterdata("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_getprinterdata: unable to marshall SPOOL_R_GETPRINTERDATA.\n")); + return False; + } + + safe_free(r_u.data); + + return True; +} + +/******************************************************************** + * api_spoolss_closeprinter + * + * called from the spoolss dispatcher + ********************************************************************/ +static BOOL api_spoolss_closeprinter(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_CLOSEPRINTER q_u; + SPOOL_R_CLOSEPRINTER r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_closeprinter("", &q_u, data, 0); + r_u.status = _spoolss_closeprinter(&q_u.handle); + memcpy(&r_u.handle, &q_u.handle, sizeof(r_u.handle)); + spoolss_io_r_closeprinter("",&r_u,rdata,0); +} + +/******************************************************************** + * api_spoolss_rffpcnex + * ReplyFindFirstPrinterChangeNotifyEx + ********************************************************************/ +static BOOL api_spoolss_rffpcnex(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_RFFPCNEX q_u; + SPOOL_R_RFFPCNEX r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_rffpcnex("", &q_u, data, 0); + + r_u.status = _spoolss_rffpcnex(&q_u.handle, q_u.flags, + q_u.options, &q_u.localmachine, + q_u.printerlocal, &q_u.option); + spoolss_io_r_rffpcnex("",&r_u,rdata,0); +} + + +/******************************************************************** + * api_spoolss_rfnpcnex + * ReplyFindNextPrinterChangeNotifyEx + * called from the spoolss dispatcher + * + ********************************************************************/ +static BOOL api_spoolss_rfnpcnex(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_RFNPCNEX q_u; + SPOOL_R_RFNPCNEX r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_rfnpcnex("", &q_u, data, 0); + + r_u.status = _spoolss_rfnpcnex(&q_u.handle, q_u.change, + &q_u.option, &r_u.count, &r_u.info); + spoolss_io_r_rfnpcnex("", &r_u, rdata, 0); +} + + +/******************************************************************** + * api_spoolss_enumprinters + * called from the spoolss dispatcher + * + ********************************************************************/ +static BOOL api_spoolss_enumprinters(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_ENUMPRINTERS q_u; + SPOOL_R_ENUMPRINTERS r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_enumprinters("", &q_u, data, 0); + + /* lkclXXX DAMN DAMN DAMN! MICROSOFT @#$%S IT UP, AGAIN, AND WE + HAVE TO DEAL WITH IT! AGH! + */ + r_u.level = q_u.level; + r_u.status = _spoolss_enumprinters( + q_u.flags, + &q_u.servername, + q_u.level, + &q_u.buffer, + q_u.buf_size, + &r_u.offered, + &r_u.needed, + &r_u.ctr, + &r_u.returned); + + memcpy(r_u.servername.buffer,q_u.servername.buffer, + 2*q_u.servername.uni_str_len); + r_u.servername.buffer[q_u.servername.uni_str_len] = 0; + + spoolss_io_free_buffer(&(q_u.buffer)); + spoolss_io_r_enumprinters("",&r_u,rdata,0); +} + + +/******************************************************************** + * api_spoolss_getprinter + * called from the spoolss dispatcher + * + ********************************************************************/ +static BOOL api_spoolss_getprinter(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_GETPRINTER q_u; + SPOOL_R_GETPRINTER r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_getprinter("", &q_u, data, 0); + + r_u.status = _spoolss_getprinter(&q_u.handle, q_u.level, + &r_u.ctr, &q_u.offered, &r_u.needed); + + memcpy(&r_u.handle, &q_u.handle, sizeof(&r_u.handle)); + r_u.offered = q_u.offered; + r_u.level = q_u.level; + safe_free(q_u.buffer); + + spoolss_io_r_getprinter("",&r_u,rdata,0); +} + + +/******************************************************************** + * api_spoolss_getprinter + * called from the spoolss dispatcher + * + ********************************************************************/ +static BOOL api_spoolss_getprinterdriver2(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_GETPRINTERDRIVER2 q_u; + SPOOL_R_GETPRINTERDRIVER2 r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_getprinterdriver2("", &q_u, data, 0); + + r_u.status = _spoolss_getprinterdriver2(&q_u.handle, + &q_u.architecture, q_u.level, + &r_u.ctr, &q_u.buf_size, + &r_u.needed); + + r_u.offered = q_u.buf_size; + r_u.level = q_u.level; + spoolss_io_free_buffer(&(q_u.buffer)); + + spoolss_io_r_getprinterdriver2("",&r_u,rdata,0); +} + +/******************************************************************** + * api_spoolss_getprinter + * called from the spoolss dispatcher + * + ********************************************************************/ +static BOOL api_spoolss_startpageprinter(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_STARTPAGEPRINTER q_u; + SPOOL_R_STARTPAGEPRINTER r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_startpageprinter("", &q_u, data, 0); + r_u.status = _spoolss_startpageprinter(&q_u.handle); + spoolss_io_r_startpageprinter("",&r_u,rdata,0); +} + + +/******************************************************************** + * api_spoolss_getprinter + * called from the spoolss dispatcher + * + ********************************************************************/ +static BOOL api_spoolss_endpageprinter(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_ENDPAGEPRINTER q_u; + SPOOL_R_ENDPAGEPRINTER r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_endpageprinter("", &q_u, data, 0); + r_u.status = _spoolss_endpageprinter(&q_u.handle); + spoolss_io_r_endpageprinter("",&r_u,rdata,0); +} + +/******************************************************************** + * api_spoolss_getprinter + * called from the spoolss dispatcher + * + ********************************************************************/ +static BOOL api_spoolss_startdocprinter(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_STARTDOCPRINTER q_u; + SPOOL_R_STARTDOCPRINTER r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_startdocprinter("", &q_u, data, 0); + r_u.status = _spoolss_startdocprinter(&q_u.handle, + q_u.doc_info_container.level, + &q_u.doc_info_container.docinfo, + &r_u.jobid); + spoolss_io_r_startdocprinter("",&r_u,rdata,0); +} + +/******************************************************************** + * api_spoolss_getprinter + * called from the spoolss dispatcher + * + ********************************************************************/ +static BOOL api_spoolss_enddocprinter(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_ENDDOCPRINTER q_u; + SPOOL_R_ENDDOCPRINTER r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_enddocprinter("", &q_u, data, 0); + r_u.status = _spoolss_enddocprinter(&q_u.handle); + spoolss_io_r_enddocprinter("",&r_u,rdata,0); +} + + +/******************************************************************** + * api_spoolss_getprinter + * called from the spoolss dispatcher + * + ********************************************************************/ +static BOOL api_spoolss_writeprinter(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_WRITEPRINTER q_u; + SPOOL_R_WRITEPRINTER r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_writeprinter("", &q_u, data, 0); + r_u.status = _spoolss_writeprinter(&q_u.handle, + q_u.buffer_size, + q_u.buffer, + &q_u.buffer_size2); + r_u.buffer_written = q_u.buffer_size2; + safe_free(q_u.buffer); + spoolss_io_r_writeprinter("",&r_u,rdata,0); +} + +/**************************************************************************** +****************************************************************************/ +static BOOL api_spoolss_setprinter(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_SETPRINTER q_u; + SPOOL_R_SETPRINTER r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_setprinter("", &q_u, data, 0); + DEBUG(0,("api_spoolss_setprinter: typecast sec_des to uint8*!\n")); + r_u.status = _spoolss_setprinter(&q_u.handle, + q_u.level, &q_u.info, + q_u.devmode, + q_u.security.size_of_buffer, + (const uint8*)q_u.security.data, + q_u.command); + spoolss_io_r_setprinter("",&r_u,rdata,0); +} + +/**************************************************************************** +****************************************************************************/ +static BOOL api_spoolss_fcpn(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_FCPN q_u; + SPOOL_R_FCPN r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_fcpn("", &q_u, data, 0); + r_u.status = _spoolss_fcpn(&q_u.handle); + spoolss_io_r_fcpn("",&r_u,rdata,0); +} + + +/**************************************************************************** +****************************************************************************/ +static BOOL api_spoolss_addjob(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_ADDJOB q_u; + SPOOL_R_ADDJOB r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_addjob("", &q_u, data, 0); + + r_u.status = _spoolss_addjob(&q_u.handle, q_u.level, + &q_u.buffer, q_u.buf_size); + + spoolss_io_free_buffer(&(q_u.buffer)); + spoolss_io_r_addjob("",&r_u,rdata,0); +} + + +/**************************************************************************** +****************************************************************************/ +static BOOL api_spoolss_enumjobs(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_ENUMJOBS q_u; + SPOOL_R_ENUMJOBS r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_enumjobs("", &q_u, data, 0); + r_u.offered = q_u.buf_size; + r_u.level = q_u.level; + r_u.status = _spoolss_enumjobs(&q_u.handle, + q_u.firstjob, q_u.numofjobs, q_u.level, + &r_u.ctr, &r_u.offered, &r_u.numofjobs); + spoolss_io_free_buffer(&(q_u.buffer)); + spoolss_io_r_enumjobs("",&r_u,rdata,0); +} + + +/**************************************************************************** +****************************************************************************/ +static BOOL api_spoolss_schedulejob(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_SCHEDULEJOB q_u; + SPOOL_R_SCHEDULEJOB r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_schedulejob("", &q_u, data, 0); + r_u.status = _spoolss_schedulejob(&q_u.handle, q_u.jobid); + spoolss_io_r_schedulejob("",&r_u,rdata,0); +} + +/**************************************************************************** +****************************************************************************/ +static BOOL api_spoolss_setjob(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_SETJOB q_u; + SPOOL_R_SETJOB r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_setjob("", &q_u, data, 0); + r_u.status = _spoolss_setjob(&q_u.handle, q_u.jobid, + q_u.level, &q_u.ctr, q_u.command); + spoolss_io_r_setjob("",&r_u,rdata,0); +} + +/**************************************************************************** +****************************************************************************/ + +static BOOL api_spoolss_enumprinterdrivers(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_ENUMPRINTERDRIVERS q_u; + SPOOL_R_ENUMPRINTERDRIVERS r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_enumprinterdrivers("", &q_u, data, 0); + + r_u.offered = q_u.buf_size; + r_u.level = q_u.level; + r_u.status = _spoolss_enumprinterdrivers(&q_u.name, + &q_u.environment, q_u. level, + &r_u.ctr, &r_u.offered, &r_u.numofdrivers); + + spoolss_io_free_buffer(&q_u.buffer); + spoolss_io_r_enumdrivers("",&r_u,rdata,0); + free_spoolss_r_enumdrivers(&r_u); +} + + +/**************************************************************************** +****************************************************************************/ +static BOOL api_spoolss_enumforms(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_ENUMFORMS q_u; + SPOOL_R_ENUMFORMS r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + DEBUG(5,("spoolss_io_q_enumforms\n")); + + new_spoolss_allocate_buffer(&q_u.buffer); + + if (!spoolss_io_q_enumforms("", &q_u, data, 0)) + return False; + + /* that's an [in out] buffer */ + new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); + + r_u.status = _new_spoolss_enumforms(&q_u.handle, q_u.level, + r_u.buffer, q_u.offered, + &r_u.needed, &r_u.numofforms); + + if (!new_spoolss_io_r_enumforms("",&r_u,rdata,0)) { + new_spoolss_free_buffer(q_u.buffer); + return False; + } + + new_spoolss_free_buffer(q_u.buffer); + + return True; +} + + +/**************************************************************************** +****************************************************************************/ +static BOOL api_spoolss_enumports(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_ENUMPORTS q_u; + SPOOL_R_ENUMPORTS r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_enumports("", &q_u, data, 0); + + r_u.offered = q_u.buf_size; + r_u.level = q_u.level; + r_u.status = _spoolss_enumports(&q_u.name, + q_u.level, + &r_u.ctr, + &r_u.offered, + &r_u.numofports); + + spoolss_io_free_buffer(&(q_u.buffer)); + spoolss_io_r_enumports("",&r_u,rdata,0); + spoolss_free_r_enumports(&r_u); +} + + +/**************************************************************************** +****************************************************************************/ +static BOOL api_spoolss_addprinterex(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_ADDPRINTEREX q_u; + SPOOL_R_ADDPRINTEREX r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_addprinterex("", &q_u, data, 0); + r_u.status = _spoolss_addprinterex(&q_u.server_name, + q_u.level, &q_u.info, + q_u.unk0, q_u.unk1, q_u.unk2, q_u.unk3, + q_u.user_level, &q_u.user, + &r_u.handle); + spoolss_io_r_addprinterex("", &r_u, rdata, 0); +} + +/**************************************************************************** +****************************************************************************/ +static BOOL api_spoolss_addprinterdriver(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_ADDPRINTERDRIVER q_u; + SPOOL_R_ADDPRINTERDRIVER r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_addprinterdriver("", &q_u, data, 0); + r_u.status = _spoolss_addprinterdriver(&q_u.server_name, + q_u.level, &q_u.info); + spoolss_io_r_addprinterdriver("", &r_u, rdata, 0); +} + +/**************************************************************************** +****************************************************************************/ +static BOOL api_spoolss_getprinterdriverdirectory(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_GETPRINTERDRIVERDIR q_u; + SPOOL_R_GETPRINTERDRIVERDIR r_u; + + spoolss_io_q_getprinterdriverdir("", &q_u, data, 0); + + r_u.offered = q_u.buf_size; + r_u.level = q_u.level; + r_u.status = _spoolss_getprinterdriverdirectory(&q_u.name, + &q_u.environment, + q_u.level, + &r_u.ctr, + &r_u.offered); + spoolss_io_free_buffer(&q_u.buffer); + spoolss_io_r_getprinterdriverdir("", &r_u, rdata, 0); +} + +/**************************************************************************** +****************************************************************************/ +static BOOL api_spoolss_enumprinterdata(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_ENUMPRINTERDATA q_u; + SPOOL_R_ENUMPRINTERDATA r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_enumprinterdata("", &q_u, data, 0); + r_u.valuesize = q_u.valuesize; + r_u.datasize = q_u.datasize; + + r_u.status = _spoolss_enumprinterdata(&q_u.handle, + q_u.index,/* in */ + &r_u.valuesize,/* in out */ + &r_u.value,/* out */ + &r_u.realvaluesize,/* out */ + &r_u.type,/* out */ + &r_u.datasize,/* in out */ + &r_u.data,/* out */ + &r_u.realdatasize);/* out */ + spoolss_io_r_enumprinterdata("", &r_u, rdata, 0); + safe_free(r_u.data); +} + +/**************************************************************************** +****************************************************************************/ +static BOOL api_spoolss_setprinterdata(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_SETPRINTERDATA q_u; + SPOOL_R_SETPRINTERDATA r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_setprinterdata("", &q_u, data, 0); + r_u.status = _spoolss_setprinterdata(&q_u.handle, + &q_u.value, q_u.type, q_u.max_len, + q_u.data, q_u.real_len, q_u.numeric_data); + spoolss_io_r_setprinterdata("", &r_u, rdata, 0); + safe_free(q_u.data); +} + +/**************************************************************************** +****************************************************************************/ +static BOOL api_spoolss_addform(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_ADDFORM q_u; + SPOOL_R_ADDFORM r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_addform("", &q_u, data, 0); + r_u.status = _spoolss_addform(&q_u.handle, q_u.level, &q_u.form); + spoolss_io_r_addform("", &r_u, rdata, 0); +} + +/**************************************************************************** +****************************************************************************/ +static BOOL api_spoolss_setform(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_SETFORM q_u; + SPOOL_R_SETFORM r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_setform("", &q_u, data, 0); + r_u.status = _spoolss_setform(&q_u.handle, + &q_u.name, q_u.level, &q_u.form); + spoolss_io_r_setform("", &r_u, rdata, 0); +} + +/**************************************************************************** +****************************************************************************/ +static BOOL api_spoolss_enumprintprocessors(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_ENUMPRINTPROCESSORS q_u; + SPOOL_R_ENUMPRINTPROCESSORS r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_enumprintprocessors("", &q_u, data, 0); + r_u.offered = q_u.buf_size; + r_u.level = q_u.level; + r_u.status = _spoolss_enumprintprocessors(&q_u.name, + &q_u.environment, + q_u.level, + &r_u.info_1, + &r_u.offered, + &r_u.numofprintprocessors); + spoolss_io_free_buffer(&q_u.buffer); + spoolss_io_r_enumprintprocessors("", &r_u, rdata, 0); + safe_free(r_u.info_1); +} + +/**************************************************************************** +****************************************************************************/ +static BOOL api_spoolss_enumprintmonitors(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_ENUMPRINTMONITORS q_u; + SPOOL_R_ENUMPRINTMONITORS r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + spoolss_io_q_enumprintmonitors("", &q_u, data, 0); + r_u.offered = q_u.buf_size; + r_u.level = q_u.level; + r_u.status = _spoolss_enumprintmonitors(&q_u.name, + q_u.level, + &r_u.info_1, + &r_u.offered, + &r_u.numofprintmonitors); + spoolss_io_free_buffer(&q_u.buffer); + spoolss_io_r_enumprintmonitors("", &r_u, rdata, 0); + safe_free(r_u.info_1); +} + +/**************************************************************************** +****************************************************************************/ +static BOOL api_spoolss_getjob(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_GETJOB q_u; + SPOOL_R_GETJOB r_u; + + spoolss_io_q_getjob("", &q_u, data, 0); + + r_u.offered = q_u.buf_size; + r_u.level = q_u.level; + r_u.status = _spoolss_getjob(&q_u.handle, + q_u.jobid, + q_u.level, + &r_u.ctr, + &r_u.offered); + spoolss_io_free_buffer(&(q_u.buffer)); + spoolss_io_r_getjob("",&r_u,rdata,0); + free_spoolss_r_getjob(&r_u); +} + +/******************************************************************* +\pipe\spoolss commands +********************************************************************/ +struct api_struct api_spoolss_cmds[] = +{ + {"SPOOLSS_OPENPRINTEREX", SPOOLSS_OPENPRINTEREX, api_spoolss_open_printer_ex }, + {"SPOOLSS_GETPRINTERDATA", SPOOLSS_GETPRINTERDATA, api_spoolss_getprinterdata }, + {"SPOOLSS_CLOSEPRINTER", SPOOLSS_CLOSEPRINTER, api_spoolss_closeprinter }, + {"SPOOLSS_RFFPCNEX", SPOOLSS_RFFPCNEX, api_spoolss_rffpcnex }, + {"SPOOLSS_RFNPCNEX", SPOOLSS_RFNPCNEX, api_spoolss_rfnpcnex }, + {"SPOOLSS_ENUMPRINTERS", SPOOLSS_ENUMPRINTERS, api_spoolss_enumprinters }, + {"SPOOLSS_GETPRINTER", SPOOLSS_GETPRINTER, api_spoolss_getprinter }, + {"SPOOLSS_GETPRINTERDRIVER2", SPOOLSS_GETPRINTERDRIVER2, api_spoolss_getprinterdriver2 }, + {"SPOOLSS_STARTPAGEPRINTER", SPOOLSS_STARTPAGEPRINTER, api_spoolss_startpageprinter }, + {"SPOOLSS_ENDPAGEPRINTER", SPOOLSS_ENDPAGEPRINTER, api_spoolss_endpageprinter }, + {"SPOOLSS_STARTDOCPRINTER", SPOOLSS_STARTDOCPRINTER, api_spoolss_startdocprinter }, + {"SPOOLSS_ENDDOCPRINTER", SPOOLSS_ENDDOCPRINTER, api_spoolss_enddocprinter }, + {"SPOOLSS_WRITEPRINTER", SPOOLSS_WRITEPRINTER, api_spoolss_writeprinter }, + {"SPOOLSS_SETPRINTER", SPOOLSS_SETPRINTER, api_spoolss_setprinter }, + {"SPOOLSS_FCPN", SPOOLSS_FCPN, api_spoolss_fcpn }, + {"SPOOLSS_ADDJOB", SPOOLSS_ADDJOB, api_spoolss_addjob }, + {"SPOOLSS_ENUMJOBS", SPOOLSS_ENUMJOBS, api_spoolss_enumjobs }, + {"SPOOLSS_SCHEDULEJOB", SPOOLSS_SCHEDULEJOB, api_spoolss_schedulejob }, + {"SPOOLSS_SETJOB", SPOOLSS_SETJOB, api_spoolss_setjob }, + {"SPOOLSS_ENUMFORMS", SPOOLSS_ENUMFORMS, api_spoolss_enumforms }, + {"SPOOLSS_ENUMPORTS", SPOOLSS_ENUMPORTS, api_spoolss_enumports }, + {"SPOOLSS_ENUMPRINTERDRIVERS", SPOOLSS_ENUMPRINTERDRIVERS, api_spoolss_enumprinterdrivers }, + {"SPOOLSS_ADDPRINTEREX", SPOOLSS_ADDPRINTEREX, api_spoolss_addprinterex }, + {"SPOOLSS_ADDPRINTERDRIVER", SPOOLSS_ADDPRINTERDRIVER, api_spoolss_addprinterdriver }, + {"SPOOLSS_GETPRINTERDRIVERDIRECTORY", SPOOLSS_GETPRINTERDRIVERDIRECTORY, api_spoolss_getprinterdriverdirectory }, + {"SPOOLSS_ENUMPRINTERDATA", SPOOLSS_ENUMPRINTERDATA, api_spoolss_enumprinterdata }, + {"SPOOLSS_SETPRINTERDATA", SPOOLSS_SETPRINTERDATA, api_spoolss_setprinterdata }, + {"SPOOLSS_ADDFORM", SPOOLSS_ADDFORM, api_spoolss_addform }, + {"SPOOLSS_SETFORM", SPOOLSS_SETFORM, api_spoolss_setform }, + {"SPOOLSS_ENUMPRINTPROCESSORS", SPOOLSS_ENUMPRINTPROCESSORS, api_spoolss_enumprintprocessors }, + {"SPOOLSS_ENUMMONITORS", SPOOLSS_ENUMMONITORS, api_spoolss_enumprintmonitors }, + {"SPOOLSS_GETJOB", SPOOLSS_GETJOB, api_spoolss_getjob }, + { NULL, 0, NULL } +}; + +/******************************************************************* +receives a spoolss pipe and responds. +********************************************************************/ +BOOL api_spoolss_rpc(pipes_struct *p, prs_struct *data) +{ + return api_rpcTNP(p, "api_spoolss_rpc", api_spoolss_cmds, data); +} + diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c new file mode 100644 index 00000000000..db48fa42ff4 --- /dev/null +++ b/source/rpc_server/srv_spoolss_nt.c @@ -0,0 +1,3434 @@ +/* + * Unix SMB/Netbios implementation. + * Version 1.9. + * RPC Pipe client / server routines + * Copyright (C) Andrew Tridgell 1992-2000, + * Copyright (C) Luke Kenneth Casson Leighton 1996-2000, + * Copyright (C) Jean François Micouleau 1998-2000. + * + * 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" + +extern int DEBUGLEVEL; +extern pstring global_myname; + +#ifndef MAX_OPEN_PRINTER_EXS +#define MAX_OPEN_PRINTER_EXS 50 +#endif + +#define PRINTER_HANDLE_IS_PRINTER 0 +#define PRINTER_HANDLE_IS_PRINTSERVER 1 + +/* structure to store the printer handles */ +/* and a reference to what it's pointing to */ +/* and the notify info asked about */ +/* that's the central struct */ +static struct +{ + BOOL open; + BOOL ok; + BOOL document_started; + BOOL page_started; + uint32 current_jobid; + uint32 document_fd; + uint32 document_lastwritten; + pstring document_name; + pstring job_name; + POLICY_HND printer_hnd; + BOOL printer_type; + union + { + fstring printername; + fstring printerservername; + } dev; + uint32 type; + uint32 access; + uint32 number_of_notify; + SPOOL_NOTIFY_OPTION_TYPE notify_info[MAX_PRINTER_NOTIFY+MAX_JOB_NOTIFY]; +} Printer[MAX_OPEN_PRINTER_EXS]; + +#define VALID_HANDLE(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_PRINTER_EXS)) +#define OPEN_HANDLE(pnum) (VALID_HANDLE(pnum) && Printer[pnum].open) + +/**************************************************************************** + initialise printer handle states... +****************************************************************************/ +void init_printer_hnd(void) +{ + int i; + for (i = 0; i < MAX_OPEN_PRINTER_EXS; i++) + { + Printer[i].open = False; + } +} + +/**************************************************************************** + create a unique printer handle +****************************************************************************/ +static void create_printer_hnd(POLICY_HND *hnd) +{ + static uint32 prt_hnd_low = 0; + static uint32 prt_hnd_high = 0; + + if (hnd == NULL) return; + + /* i severely doubt that prt_hnd_high will ever be non-zero... */ + prt_hnd_low++; + if (prt_hnd_low == 0) prt_hnd_high++; + + SIVAL(hnd->data, 0 , 0x0); /* first bit must be null */ + SIVAL(hnd->data, 4 , prt_hnd_low ); /* second bit is incrementing */ + SIVAL(hnd->data, 8 , prt_hnd_high); /* second bit is incrementing */ + SIVAL(hnd->data, 12, time(NULL)); /* something random */ + SIVAL(hnd->data, 16, getpid()); /* something more random */ +} + +/**************************************************************************** + find printer index by handle +****************************************************************************/ +static int find_printer_index_by_hnd(const POLICY_HND *hnd) +{ + int i; + + for (i = 0; i < MAX_OPEN_PRINTER_EXS; i++) + { + if (memcmp(&(Printer[i].printer_hnd), hnd, sizeof(*hnd)) == 0) + { + DEBUG(4,("Found printer handle[%x] ", i)); + dump_data(4, hnd->data, sizeof(hnd->data)); + return i; + } + } + DEBUG(3,("Whoops, Printer handle not found: ")); + dump_data(4, hnd->data, sizeof(hnd->data)); + return -1; +} + +/**************************************************************************** + clear an handle +****************************************************************************/ +static void clear_handle(POLICY_HND *hnd) +{ + bzero(hnd->data, POLICY_HND_SIZE); +} + +/**************************************************************************** + close printer index by handle +****************************************************************************/ +static BOOL close_printer_handle(POLICY_HND *hnd) +{ + int pnum = find_printer_index_by_hnd(hnd); + + if (pnum == -1) + { + DEBUG(3,("Error closing printer handle (pnum=%x)\n", pnum)); + return False; + } + + Printer[pnum].open=False; + clear_handle(hnd); + + return True; +} + +/**************************************************************************** + return the snum of a printer corresponding to an handle +****************************************************************************/ +static BOOL get_printer_snum(const POLICY_HND *hnd, int *number) +{ + int snum; + int pnum = find_printer_index_by_hnd(hnd); + int n_services=lp_numservices(); + + if (!OPEN_HANDLE(pnum)) { + DEBUG(3,("Error getting printer - take a nap quickly !\n")); + return False; + } + + switch (Printer[pnum].printer_type) { + case PRINTER_HANDLE_IS_PRINTER: + DEBUG(4,("short name:%s\n", Printer[pnum].dev.printername)); + for (snum=0;snumdata, sizeof(hnd->data)); + return True; + } + } + DEBUG(1,("ERROR - open_printer_hnd: out of Printers Handles!\n")); + return False; +} + +/**************************************************************************** + set printer handle type. +****************************************************************************/ +static BOOL set_printer_hnd_accesstype(POLICY_HND *hnd, uint32 access_required) +{ + int pnum = find_printer_index_by_hnd(hnd); + + if (OPEN_HANDLE(pnum)) { + DEBUG(4,("Setting printer access=%x (pnum=%x)\n", access_required, pnum)); + Printer[pnum].access = access_required; + return True; + } + else { + DEBUG(4,("Error setting printer type=%x (pnum=%x)", access_required, pnum)); + return False; + } + return False; +} + +/**************************************************************************** + . +****************************************************************************/ +static BOOL printer_entry_is_valid(POLICY_HND *hnd) +{ + int pnum = find_printer_index_by_hnd(hnd); + + if (!OPEN_HANDLE(pnum)) + return False; + + if (Printer[pnum].ok == False) + return False; + + return True; +} + +/**************************************************************************** + set printer handle type. + check if it's \\server or \\server\printer +****************************************************************************/ +static BOOL set_printer_hnd_printertype(POLICY_HND *hnd, char *printername) +{ + int pnum = find_printer_index_by_hnd(hnd); + + if (!OPEN_HANDLE(pnum)) { + DEBUGADD(4,("Error setting printer name %s (pnum=%x)", printername, pnum)); + return False; + } + + DEBUG(3,("Setting printer type=%s (pnum=%x)\n", printername, pnum)); + + if ( strlen(printername) < 3 ) { + DEBUGADD(4,("A print server must have at least 1 char ! %s\n", printername)); + Printer[pnum].ok=False; + return False; + } + + /* it's a print server */ + if (!strchr(printername+2, '\\')) { + DEBUGADD(4,("Printer is a print server\n")); + Printer[pnum].printer_type = PRINTER_HANDLE_IS_PRINTSERVER; + Printer[pnum].ok=True; + + return True; + } + /* it's a printer */ + else { + DEBUGADD(4,("Printer is a printer\n")); + Printer[pnum].printer_type = PRINTER_HANDLE_IS_PRINTER; + Printer[pnum].ok=True; + return True; + } + + return False; +} + +/**************************************************************************** + set printer handle printername. +****************************************************************************/ +static BOOL set_printer_hnd_printername(POLICY_HND *hnd, char *printername) +{ + int pnum = find_printer_index_by_hnd(hnd); + char *back; + NT_PRINTER_INFO_LEVEL printer; + int snum; + int n_services=lp_numservices(); + uint32 marche; + + if (!OPEN_HANDLE(pnum)) + { + DEBUG(0,("Error setting printer name=%s (pnum=%x)\n", printername, pnum)); + return False; + } + + DEBUG(4,("Setting printer name=%s (len=%d) (pnum=%x)\n", printername, strlen(printername), pnum)); + + switch (Printer[pnum].printer_type) { + case PRINTER_HANDLE_IS_PRINTSERVER: + ZERO_STRUCT(Printer[pnum].dev.printerservername); + strncpy(Printer[pnum].dev.printerservername, printername, strlen(printername)); + return True; + break; + + case PRINTER_HANDLE_IS_PRINTER: + back=strchr(printername+2, '\\'); + back=back+1; + DEBUGADD(5,("searching for %s (len=%d)\n", back,strlen(back))); + /* + * store the Samba share name in it + * in back we have the long printer name + * need to iterate all the snum and do a + * get_a_printer each time to find the printer + * faster to do it here than later. + */ + for (snum=0;snumprintername) == strlen(back) ) + && ( !strncasecmp(printer.info_2->printername, back, strlen(back))) + ) { + DEBUGADD(4,("Printer found: %s[%x]\n",lp_servicename(snum),snum)); + ZERO_STRUCT(Printer[pnum].dev.printername); + strncpy(Printer[pnum].dev.printername, lp_servicename(snum), strlen(lp_servicename(snum))); + free_a_printer(printer, 2); + return True; + break; + } + free_a_printer(printer, 2); + } + } + return False; + break; + + default: + return False; + break; + } +} + +/******************************************************************** + ********************************************************************/ +static BOOL handle_is_printserver(const POLICY_HND *handle) +{ + int pnum=find_printer_index_by_hnd(handle); + + if (!OPEN_HANDLE(pnum)) + return False; + + if (Printer[pnum].printer_type != PRINTER_HANDLE_IS_PRINTSERVER) + return False; + + return True; +} + +/******************************************************************** + * spoolss_open_printer + * + * called from the spoolss dispatcher + ********************************************************************/ +uint32 _spoolss_open_printer_ex( const UNISTR2 *printername, + const PRINTER_DEFAULT *printer_default, + uint32 user_switch, SPOOL_USER_CTR user_ctr, + POLICY_HND *handle) +{ + BOOL printer_open = False; + fstring name; + fstring datatype; + + clear_handle(handle); + + if (printername == NULL) + return NT_STATUS_ACCESS_DENIED; + + /* some sanity check because you can open a printer or a print server */ + /* aka: \\server\printer or \\server */ + unistr2_to_ascii(name, printername, sizeof(name)-1); + + DEBUGADD(3,("checking name: %s\n",name)); + + create_printer_hnd(handle); + + open_printer_hnd(handle); + + set_printer_hnd_printertype(handle, name); + + set_printer_hnd_printername(handle, name); + +/* + if (printer_default->datatype_ptr != NULL) + { + unistr2_to_ascii(datatype, printer_default->datatype, sizeof(datatype)-1); + set_printer_hnd_datatype(handle, datatype); + } + else + set_printer_hnd_datatype(handle, ""); +*/ + + set_printer_hnd_accesstype(handle, printer_default->access_required); + + if (!printer_entry_is_valid(handle)) + { + close_printer_handle(handle); + return NT_STATUS_ACCESS_DENIED; + } + + return NT_STATUS_NO_PROBLEMO; +} + +static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni, + NT_PRINTER_INFO_LEVEL *printer, + uint32 level) +{ + switch (level) + { + case 2: + { + uni_2_asc_printer_info_2(uni->info_2, + &(printer->info_2)); + break; + } + default: + break; + } + + + + return True; +} + +static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni, + NT_PRINTER_DRIVER_INFO_LEVEL *printer, + uint32 level) +{ + switch (level) + { + case 3: + { + printer->info_3=NULL; + uni_2_asc_printer_driver_3(uni->info_3, &(printer->info_3)); + break; + } + default: + break; + } + + + + return True; +} + +static BOOL convert_devicemode(DEVICEMODE devmode, NT_DEVICEMODE *nt_devmode) +{ + unistr_to_ascii(nt_devmode->devicename, + devmode.devicename.buffer, + 31); + + unistr_to_ascii(nt_devmode->formname, + devmode.formname.buffer, + 31); + + nt_devmode->specversion=devmode.specversion; + nt_devmode->driverversion=devmode.driverversion; + nt_devmode->size=devmode.size; + nt_devmode->driverextra=devmode.driverextra; + nt_devmode->fields=devmode.fields; + nt_devmode->orientation=devmode.orientation; + nt_devmode->papersize=devmode.papersize; + nt_devmode->paperlength=devmode.paperlength; + nt_devmode->paperwidth=devmode.paperwidth; + nt_devmode->scale=devmode.scale; + nt_devmode->copies=devmode.copies; + nt_devmode->defaultsource=devmode.defaultsource; + nt_devmode->printquality=devmode.printquality; + nt_devmode->color=devmode.color; + nt_devmode->duplex=devmode.duplex; + nt_devmode->yresolution=devmode.yresolution; + nt_devmode->ttoption=devmode.ttoption; + nt_devmode->collate=devmode.collate; + + nt_devmode->logpixels=devmode.logpixels; + nt_devmode->bitsperpel=devmode.bitsperpel; + nt_devmode->pelswidth=devmode.pelswidth; + nt_devmode->pelsheight=devmode.pelsheight; + nt_devmode->displayflags=devmode.displayflags; + nt_devmode->displayfrequency=devmode.displayfrequency; + nt_devmode->icmmethod=devmode.icmmethod; + nt_devmode->icmintent=devmode.icmintent; + nt_devmode->mediatype=devmode.mediatype; + nt_devmode->dithertype=devmode.dithertype; + nt_devmode->reserved1=devmode.reserved1; + nt_devmode->reserved2=devmode.reserved2; + nt_devmode->panningwidth=devmode.panningwidth; + nt_devmode->panningheight=devmode.panningheight; + + if (nt_devmode->driverextra != 0) + { + /* if we had a previous private delete it and make a new one */ + if (nt_devmode->private != NULL) + free(nt_devmode->private); + nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8)); + memcpy(nt_devmode->private, devmode.private, nt_devmode->driverextra); + } + + + return True; +} + +/******************************************************************** + * api_spoolss_closeprinter + ********************************************************************/ +uint32 _spoolss_closeprinter(POLICY_HND *handle) +{ + if (!close_printer_handle(handle)) + return NT_STATUS_INVALID_HANDLE; + + return NT_STATUS_NO_PROBLEMO; +} + +/******************************************************************** + ********************************************************************/ +static BOOL getprinterdata_printer_server(fstring value, uint32 *type, uint8 **data, uint32 *needed) +{ + int i; + + if (!strcmp(value, "BeepEnabled")) + { + *type = 0x4; + *data = (uint8 *)malloc( 4*sizeof(uint8) ); + SIVAL(data, 0, 0x01); + *needed = 0x4; + return True; + } + + if (!strcmp(value, "EventLog")) + { + *type = 0x4; + *data = (uint8 *)malloc( 4*sizeof(uint8) ); + SIVAL(data, 0, 0x1B); + *needed = 0x4; + return True; + } + + if (!strcmp(value, "NetPopup")) + { + *type = 0x4; + *data = (uint8 *)malloc( 4*sizeof(uint8) ); + SIVAL(data, 0, 0x01); + *needed = 0x4; + return True; + } + + if (!strcmp(value, "MajorVersion")) + { + *type = 0x4; + *data = (uint8 *)malloc( 4*sizeof(uint8) ); + SIVAL(data, 0, 0x02); + *needed = 0x4; + return True; + } + + if (!strcmp(value, "DefaultSpoolDirectory")) + { + pstring directory="You are using a Samba server"; + *type = 0x1; + *needed = 2*(strlen(directory)+1); + *data = (uint8 *)malloc(*needed *sizeof(uint8)); + ZERO_STRUCTP(*data); + + /* it's done by hand ready to go on the wire */ + for (i=0; i *out_size) + return ERROR_INSUFFICIENT_BUFFER; + else + return NT_STATUS_NO_PROBLEMO; +} + +/******************************************************************** + * _spoolss_rffpcnex + * ReplyFindFirstPrinterChangeNotifyEx + * + * jfmxxxx: before replying OK: status=0 + * should do a rpc call to the workstation asking ReplyOpenPrinter + * have to code it, later. + * + * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe + * called from api_spoolss_rffpcnex + ********************************************************************/ +uint32 _spoolss_rffpcnex(const POLICY_HND *handle, + uint32 flags, uint32 options, + const UNISTR2 *localmachine, + uint32 printerlocal, + SPOOL_NOTIFY_OPTION *option) +{ + int i,j,k; + + /* store the notify value in the printer struct */ + + i=find_printer_index_by_hnd(handle); + + if (i == -1) + { + return NT_STATUS_INVALID_HANDLE; + } + + Printer[i].number_of_notify=option->count; + + DEBUG(3,("Copying %x notify option info\n",Printer[i].number_of_notify)); + + for (j=0;jtype[j].count; + Printer[i].notify_info[j].type=option->type[j].type ; + + DEBUG(4,("Copying %x info fields of type %x\n", + Printer[i].notify_info[j].count, + Printer[i].notify_info[j].type)); + for(k=0;ktype[j].fields[k]; + } + } + + return 0x0; +} + +/******************************************************************* + * fill a notify_info_data with the servername + ********************************************************************/ +static void spoolss_notify_server_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + pstring temp_name; + + snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname); + + data->notify_data.data.length=strlen(temp_name); + ascii_to_unistr(data->notify_data.data.string, temp_name, sizeof(data->notify_data.data.string)-1); +} + +/******************************************************************* + * fill a notify_info_data with the servicename + * jfmxxxx: it's incorrect should be long_printername + ********************************************************************/ +static void spoolss_notify_printer_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ +/* + data->notify_data.data.length=strlen(lp_servicename(snum)); + ascii_to_unistr(data->notify_data.data.string, lp_servicename(snum), sizeof(data->notify_data.data.string)-1); +*/ + data->notify_data.data.length=strlen(printer->info_2->printername); + ascii_to_unistr(data->notify_data.data.string, + printer->info_2->printername, + sizeof(data->notify_data.data.string)-1); +} + +/******************************************************************* + * fill a notify_info_data with the servicename + ********************************************************************/ +static void spoolss_notify_share_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.data.length=strlen(lp_servicename(snum)); + ascii_to_unistr(data->notify_data.data.string, + lp_servicename(snum), + sizeof(data->notify_data.data.string)-1); +} + +/******************************************************************* + * fill a notify_info_data with the port name + ********************************************************************/ +static void spoolss_notify_port_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + /* even if it's strange, that's consistant in all the code */ + + data->notify_data.data.length=strlen(lp_servicename(snum)); + ascii_to_unistr(data->notify_data.data.string, + lp_servicename(snum), + sizeof(data->notify_data.data.string)-1); +} + +/******************************************************************* + * fill a notify_info_data with the printername + * jfmxxxx: it's incorrect, should be lp_printerdrivername() + * but it doesn't exist, have to see what to do + ********************************************************************/ +static void spoolss_notify_driver_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.data.length=strlen(printer->info_2->drivername); + ascii_to_unistr(data->notify_data.data.string, + printer->info_2->drivername, + sizeof(data->notify_data.data.string)-1); +} + +/******************************************************************* + * fill a notify_info_data with the comment + ********************************************************************/ +static void spoolss_notify_comment(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.data.length=strlen(lp_comment(snum)); + ascii_to_unistr(data->notify_data.data.string, + lp_comment(snum), + sizeof(data->notify_data.data.string)-1); +} + +/******************************************************************* + * fill a notify_info_data with the comment + * jfm:xxxx incorrect, have to create a new smb.conf option + * location = "Room 1, floor 2, building 3" + ********************************************************************/ +static void spoolss_notify_location(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.data.length=strlen(printer->info_2->location); + ascii_to_unistr(data->notify_data.data.string, + printer->info_2->location, + sizeof(data->notify_data.data.string)-1); +} + +/******************************************************************* + * fill a notify_info_data with the device mode + * jfm:xxxx don't to it for know but that's a real problem !!! + ********************************************************************/ +static void spoolss_notify_devmode(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ +} + +/******************************************************************* + * fill a notify_info_data with the separator file name + * jfm:xxxx just return no file could add an option to smb.conf + * separator file = "separator.txt" + ********************************************************************/ +static void spoolss_notify_sepfile(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.data.length=strlen(printer->info_2->sepfile); + ascii_to_unistr(data->notify_data.data.string, + printer->info_2->sepfile, + sizeof(data->notify_data.data.string)-1); +} + +/******************************************************************* + * fill a notify_info_data with the print processor + * jfm:xxxx return always winprint to indicate we don't do anything to it + ********************************************************************/ +static void spoolss_notify_print_processor(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.data.length=strlen(printer->info_2->printprocessor); + ascii_to_unistr(data->notify_data.data.string, + printer->info_2->printprocessor, + sizeof(data->notify_data.data.string)-1); +} + +/******************************************************************* + * fill a notify_info_data with the print processor options + * jfm:xxxx send an empty string + ********************************************************************/ +static void spoolss_notify_parameters(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.data.length=strlen(printer->info_2->parameters); + ascii_to_unistr(data->notify_data.data.string, + printer->info_2->parameters, + sizeof(data->notify_data.data.string)-1); +} + +/******************************************************************* + * fill a notify_info_data with the data type + * jfm:xxxx always send RAW as data type + ********************************************************************/ +static void spoolss_notify_datatype(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.data.length=strlen(printer->info_2->datatype); + ascii_to_unistr(data->notify_data.data.string, + printer->info_2->datatype, + sizeof(data->notify_data.data.string)-1); +} + +/******************************************************************* + * fill a notify_info_data with the security descriptor + * jfm:xxxx send an null pointer to say no security desc + * have to implement security before ! + ********************************************************************/ +static void spoolss_notify_security_desc(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.data.length=0; + data->notify_data.data.string[0]=0x00; +} + +/******************************************************************* + * fill a notify_info_data with the attributes + * jfm:xxxx a samba printer is always shared + ********************************************************************/ +static void spoolss_notify_attributes(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.value[0] = PRINTER_ATTRIBUTE_SHARED \ + | PRINTER_ATTRIBUTE_NETWORK \ + | PRINTER_ATTRIBUTE_RAW_ONLY ; +} + +/******************************************************************* + * fill a notify_info_data with the priority + ********************************************************************/ +static void spoolss_notify_priority(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.value[0] = printer->info_2->priority; +} + +/******************************************************************* + * fill a notify_info_data with the default priority + ********************************************************************/ +static void spoolss_notify_default_priority(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.value[0] = printer->info_2->default_priority; +} + +/******************************************************************* + * fill a notify_info_data with the start time + ********************************************************************/ +static void spoolss_notify_start_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.value[0] = printer->info_2->starttime; +} + +/******************************************************************* + * fill a notify_info_data with the until time + ********************************************************************/ +static void spoolss_notify_until_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.value[0] = printer->info_2->untiltime; +} + +/******************************************************************* + * fill a notify_info_data with the status + ********************************************************************/ +static void spoolss_notify_status(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + int count; + print_queue_struct *q=NULL; + print_status_struct status; + + bzero(&status,sizeof(status)); + + count=get_printqueue(snum, NULL, &q, &status); + + data->notify_data.value[0]=(uint32) status.status; + if (q) free(q); +} + +/******************************************************************* + * fill a notify_info_data with the number of jobs queued + ********************************************************************/ +static void spoolss_notify_cjobs(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + print_queue_struct *q=NULL; + print_status_struct status; + + bzero(&status,sizeof(status)); + + data->notify_data.value[0]=get_printqueue(snum, NULL, &q, &status); + if (q) free(q); +} + +/******************************************************************* + * fill a notify_info_data with the average ppm + ********************************************************************/ +static void spoolss_notify_average_ppm(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + /* always respond 8 pages per minutes */ + /* a little hard ! */ + data->notify_data.value[0] = printer->info_2->averageppm; +} + +/******************************************************************* + * fill a notify_info_data with + ********************************************************************/ +static void spoolss_notify_username(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.data.length=strlen(queue->user); + ascii_to_unistr(data->notify_data.data.string, queue->user, sizeof(data->notify_data.data.string)-1); +} + +/******************************************************************* + * fill a notify_info_data with + ********************************************************************/ +static void spoolss_notify_job_status(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.value[0]=queue->status; +} + +/******************************************************************* + * fill a notify_info_data with + ********************************************************************/ +static void spoolss_notify_job_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.data.length=strlen(queue->file); + ascii_to_unistr(data->notify_data.data.string, queue->file, sizeof(data->notify_data.data.string)-1); +} + +/******************************************************************* + * fill a notify_info_data with + ********************************************************************/ +static void spoolss_notify_job_status_string(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.data.length=strlen("En attente"); + ascii_to_unistr(data->notify_data.data.string, "En attente", sizeof(data->notify_data.data.string)-1); +} + +/******************************************************************* + * fill a notify_info_data with + ********************************************************************/ +static void spoolss_notify_job_time(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.value[0]=0x0; +} + +/******************************************************************* + * fill a notify_info_data with + ********************************************************************/ +static void spoolss_notify_job_size(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.value[0]=queue->size; +} + +/******************************************************************* + * fill a notify_info_data with + ********************************************************************/ +static void spoolss_notify_job_position(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer) +{ + data->notify_data.value[0]=queue->job; +} + +#define END 65535 + +struct s_notify_info_data_table notify_info_data_table[] = +{ +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", POINTER, spoolss_notify_server_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", POINTER, spoolss_notify_share_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", POINTER, spoolss_notify_comment }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", POINTER, spoolss_notify_location }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", POINTER, spoolss_notify_sepfile }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", POINTER, spoolss_notify_security_desc }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", ONE_VALUE, spoolss_notify_attributes }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", ONE_VALUE, spoolss_notify_default_priority }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_status }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", POINTER, NULL }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", ONE_VALUE, spoolss_notify_cjobs }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", ONE_VALUE, spoolss_notify_average_ppm }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", POINTER, NULL }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", POINTER, NULL }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", POINTER, NULL }, +{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", POINTER, NULL }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", POINTER, spoolss_notify_printer_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", POINTER, spoolss_notify_server_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", POINTER, spoolss_notify_port_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", POINTER, spoolss_notify_username }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", POINTER, spoolss_notify_username }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", POINTER, spoolss_notify_datatype }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", POINTER, spoolss_notify_print_processor }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", POINTER, spoolss_notify_parameters }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", POINTER, spoolss_notify_driver_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", POINTER, spoolss_notify_devmode }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", ONE_VALUE, spoolss_notify_job_status }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", POINTER, spoolss_notify_job_status_string }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", POINTER, NULL }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", POINTER, spoolss_notify_job_name }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", ONE_VALUE, spoolss_notify_priority }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", ONE_VALUE, spoolss_notify_job_position }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", POINTER, NULL }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", ONE_VALUE, spoolss_notify_start_time }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", ONE_VALUE, spoolss_notify_until_time }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", ONE_VALUE, spoolss_notify_job_time }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", ONE_VALUE, NULL }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", ONE_VALUE, NULL }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", ONE_VALUE, spoolss_notify_job_size }, +{ JOB_NOTIFY_TYPE, JOB_NOTIFY_BYTES_PRINTED, "JOB_NOTIFY_BYTES_PRINTED", ONE_VALUE, NULL }, +{ END, END, "", END, NULL } +}; + +/******************************************************************* +return the size of info_data structure +********************************************************************/ +static uint32 size_of_notify_info_data(uint16 type, uint16 field) +{ + int i=0; + + while (notify_info_data_table[i].type != END) + { + if ( (notify_info_data_table[i].type == type ) && + (notify_info_data_table[i].field == field ) ) + { + return (notify_info_data_table[i].size); + continue; + } + i++; + } + return (65535); +} + +/******************************************************************* +return the type of notify_info_data +********************************************************************/ +static BOOL type_of_notify_info_data(uint16 type, uint16 field) +{ + int i=0; + + while (notify_info_data_table[i].type != END) + { + if ( (notify_info_data_table[i].type == type ) && + (notify_info_data_table[i].field == field ) ) + { + if (notify_info_data_table[i].size == POINTER) + { + return (False); + } + else + { + return (True); + } + continue; + } + i++; + } + return (False); +} + +/**************************************************************************** +****************************************************************************/ +static int search_notify(uint16 type, uint16 field, int *value) +{ + int j; + BOOL found; + + DEBUG(4,("\tsearch_notify: in\n")); + for (j=0, found=False; found==False && notify_info_data_table[j].type != END ; j++) + { + if ( (notify_info_data_table[j].type == type ) && + (notify_info_data_table[j].field == field ) ) + { + found=True; + } + } + *value=--j; + + if ( found && (notify_info_data_table[j].fn != NULL) ) + { + DEBUG(4,("\tsearch_notify: out TRUE\n")); + return (True); + } + else + { + DEBUG(4,("\tsearch_notify: out FALSE\n")); + return (False); + } +} + +/**************************************************************************** +****************************************************************************/ +static void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id) +{ + DEBUG(4,("\tconstruct_info_data: in\n")); + info_data->type = type; + info_data->field = field; + info_data->id = id; + info_data->size = size_of_notify_info_data(type, field); + info_data->enc_type = type_of_notify_info_data(type, field); + DEBUG(4,("\tconstruct_info_data: out\n")); +} + + +/******************************************************************* + * + * fill a notify_info struct with info asked + * + ********************************************************************/ +static void construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int pnum, + int snum, int i, uint32 id) +{ + + int k,j; + uint16 type; + uint16 field; + + SPOOL_NOTIFY_INFO_DATA *info_data; + print_queue_struct *queue=NULL; + NT_PRINTER_INFO_LEVEL printer; + + DEBUG(4,("construct_notify_printer_info\n")); + + info_data=&(info->data[info->count]); + + type = Printer[pnum].notify_info[i].type; + + DEBUGADD(4,("Notify number %d -> number of notify info: %d\n",i,Printer[pnum].notify_info[i].count)); + + if (!get_a_printer(&printer, 2, lp_servicename(snum))) + { + + for(k=0; kcount++; + info_data=&(info->data[info->count]); + } + } + + free_a_printer(printer, 2); + } +} + +/******************************************************************* + * + * fill a notify_info struct with info asked + * + ********************************************************************/ +static void construct_notify_jobs_info(print_queue_struct *queue, SPOOL_NOTIFY_INFO *info, + int pnum, int snum, int i, uint32 id) +{ + + int k,j; + uint16 type; + uint16 field; + + SPOOL_NOTIFY_INFO_DATA *info_data; + NT_PRINTER_INFO_LEVEL printer; + + DEBUG(4,("construct_notify_jobs_info\n")); + info_data=&(info->data[info->count]); + + type = Printer[pnum].notify_info[i].type; + + DEBUGADD(4,("Notify number %d -> number of notify info: %d\n",i,Printer[pnum].notify_info[i].count)); + + if (!get_a_printer(&printer, 2, lp_servicename(snum))) + { + for(k=0; kcount++; + info_data=&(info->data[info->count]); + } + } + free_a_printer(printer, 2); + } +} + + +/******************************************************************* + * + * enumerate all printers on the printserver + * fill a notify_info struct with info asked + * + ********************************************************************/ +static uint32 printserver_notify_info(const POLICY_HND *hnd, + SPOOL_NOTIFY_INFO *info) +{ + int snum; + int pnum=find_printer_index_by_hnd(hnd); + int n_services=lp_numservices(); + int i=0; + uint32 id=1; + info->count=0; + + if (pnum == -1) + { + return NT_STATUS_INVALID_HANDLE; + } + + DEBUG(4,("Enumerating printers\n")); + + for (i=0; icount=0; + + if (pnum == -1 || !get_printer_snum(hnd, &snum) ) + { + return NT_STATUS_INVALID_HANDLE; + } + + for (i=0; iprintername); + + init_unistr(&(printer->printername), chaine); + + slprintf(chaine,sizeof(chaine)-1,"\\\\%s", servername); + 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->unknown7 = 0x1; + printer->unknown8 = 0x0; + printer->unknown9 = 0x2; + printer->unknown10 = 0x3; + printer->unknown11 = 0x0; + printer->unknown12 = 0x0; + printer->unknown13 = 0x0; + printer->unknown14 = 0x1; + printer->unknown15 = 0x024a; /*586 Pentium ? */ + printer->unknown16 = 0x0; + printer->unknown17 = 0x423ed444; + printer->unknown18 = 0x0; + printer->status = status.status; + printer->unknown20 = 0x0; + printer->unknown21 = 0x0648; + printer->unknown22 = 0x0; + printer->unknown23 = 0x5; + + safe_free(queue); + + free_a_printer(ntprinter, 2); + return (True); +} + +/******************************************************************** + * construct_printer_info_1 + * fill a printer_info_1 struct + ********************************************************************/ +static BOOL construct_printer_info_1(PRINTER_INFO_1 *printer,int snum, pstring servername) +{ + pstring chaine; + NT_PRINTER_INFO_LEVEL ntprinter; + + if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0) + { + return (False); + } + + printer->flags=PRINTER_ENUM_NAME; + + /* the description and the name are of the form \\server\share */ + slprintf(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); + + slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s", servername, ntprinter.info_2->printername); + init_unistr(&(printer->name), chaine); + + init_unistr(&(printer->comment), lp_comment(snum)); + + free_a_printer(ntprinter, 2); + return (True); +} + +/**************************************************************************** +****************************************************************************/ +static void construct_dev_mode(DEVICEMODE *devmode, int snum, char *servername) +{ + char adevice[32]; + char aform[32]; + NT_PRINTER_INFO_LEVEL printer; + NT_DEVICEMODE *ntdevmode; + + DEBUG(7,("construct_dev_mode\n")); + + bzero(&(devmode->devicename), 2*sizeof(adevice)); + bzero(&(devmode->formname), 2*sizeof(aform)); + + DEBUGADD(8,("getting printer characteristics\n")); + + get_a_printer(&printer, 2, lp_servicename(snum)); + ntdevmode=(printer.info_2)->devmode; + + DEBUGADD(8,("loading DEVICEMODE\n")); + snprintf(adevice, sizeof(adevice), "\\\\%s\\%s", global_myname, + printer.info_2->printername); + init_unistr(&(devmode->devicename), adevice); + + snprintf(aform, sizeof(aform), ntdevmode->formname); + init_unistr(&(devmode->formname), aform); + + devmode->specversion = ntdevmode->specversion; + devmode->driverversion = ntdevmode->driverversion; + devmode->size = ntdevmode->size; + devmode->driverextra = ntdevmode->driverextra; + devmode->fields = ntdevmode->fields; + + devmode->orientation = ntdevmode->orientation; + devmode->papersize = ntdevmode->papersize; + devmode->paperlength = ntdevmode->paperlength; + devmode->paperwidth = ntdevmode->paperwidth; + devmode->scale = ntdevmode->scale; + devmode->copies = ntdevmode->copies; + devmode->defaultsource = ntdevmode->defaultsource; + devmode->printquality = ntdevmode->printquality; + devmode->color = ntdevmode->color; + devmode->duplex = ntdevmode->duplex; + devmode->yresolution = ntdevmode->yresolution; + devmode->ttoption = ntdevmode->ttoption; + devmode->collate = ntdevmode->collate; + devmode->icmmethod = ntdevmode->icmmethod; + devmode->icmintent = ntdevmode->icmintent; + devmode->mediatype = ntdevmode->mediatype; + devmode->dithertype = ntdevmode->dithertype; + + if (ntdevmode->private != NULL) + { + devmode->private=(uint8 *)malloc(devmode->driverextra*sizeof(uint8)); + memcpy(devmode->private, ntdevmode->private, devmode->driverextra); + } + + free_a_printer(printer, 2); +} + +/******************************************************************** + * construct_printer_info_2 + * fill a printer_info_2 struct + ********************************************************************/ +static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum, pstring servername) +{ + pstring chaine; + int count; + DEVICEMODE *devmode; + NT_PRINTER_INFO_LEVEL ntprinter; + + print_queue_struct *queue=NULL; + print_status_struct status; + bzero(&status, sizeof(status)); + count=get_printqueue(snum, NULL, &queue, &status); + + if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 ) + { + return (False); + } + + snprintf(chaine, sizeof(chaine)-1, "\\\\%s", servername); + init_unistr(&(printer->servername), chaine); /* servername*/ + + snprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", servername, ntprinter.info_2->printername); + init_unistr(&(printer->printername), chaine); /* 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), 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) */ + + printer->attributes = PRINTER_ATTRIBUTE_SHARED \ + | PRINTER_ATTRIBUTE_NETWORK \ + | PRINTER_ATTRIBUTE_RAW_ONLY ; /* attributes */ + + printer->priority = ntprinter.info_2->priority; /* priority */ + printer->defaultpriority = ntprinter.info_2->default_priority; /* default priority */ + printer->starttime = ntprinter.info_2->starttime; /* starttime */ + printer->untiltime = ntprinter.info_2->untiltime; /* untiltime */ + printer->status = status.status; /* status */ + printer->cjobs = count; /* jobs */ + printer->averageppm = ntprinter.info_2->averageppm; /* average pages per minute */ + + devmode=(DEVICEMODE *)malloc(sizeof(DEVICEMODE)); + ZERO_STRUCTP(devmode); + construct_dev_mode(devmode, snum, servername); + printer->devmode=devmode; + + 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 enum_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 enum_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) + ********************************************************************/ +static void enum_all_printers_info_1(PRINTER_INFO_1 ***printers, uint32 *number) +{ + int snum; + int n_services=lp_numservices(); + *printers=NULL; + *number=0; + + for (snum=0;snumprinter.printers_1, returned ); + /*else + enum_one_printer_info_1(&r_u);*/ + break; + } + case 2: + if (flags == PRINTER_ENUM_NAME || + flags == PRINTER_ENUM_NETWORK ) + { + /*if (is_a_printerserver(servername))*/ + enum_all_printers_info_2(&ctr->printer.printers_2, returned ); + /*else + enum_one_printer_info_2(&r_u);*/ + break; + } + case 3: /* doesn't exist */ + return NT_STATUS_INVALID_INFO_CLASS; + case 4: /* can't, always on local machine */ + break; + case 5: + return NT_STATUS_INVALID_INFO_CLASS; + + } + DEBUG(4,("%d printers enumerated\n", *returned)); + (*offered) = buffer->size; + + return 0x0; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_getprinter( POLICY_HND *handle, + uint32 level, + PRINTER_INFO *ctr, + uint32 *offered, + uint32 *needed) +{ + int snum; + pstring servername; + + pstrcpy(servername, global_myname); + + if (!get_printer_snum(handle,&snum)) + { + return NT_STATUS_INVALID_HANDLE; + } + + DEBUG(0,("_spoolss_getprinter: offered and needed params ignored\n")); + + switch (level) + { + case 0: + { + PRINTER_INFO_0 *printer; + + printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0)); + construct_printer_info_0(printer, snum, servername); + ctr->printer.info0=printer; + + return 0x0; + } + case 1: + { + PRINTER_INFO_1 *printer; + + printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1)); + construct_printer_info_1(printer, snum, servername); + ctr->printer.info1=printer; + + return 0x0; + } + case 2: + { + PRINTER_INFO_2 *printer; + + printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)); + construct_printer_info_2(printer, snum, servername); + ctr->printer.info2=printer; + + return 0x0; + } + default: + { + break; + } + } + + return NT_STATUS_INVALID_INFO_CLASS; +} + +/******************************************************************** + * construct_printer_driver_info_1 + * fill a construct_printer_driver_info_1 struct + ********************************************************************/ +static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, + NT_PRINTER_DRIVER_INFO_LEVEL driver, + pstring servername, fstring architecture) +{ + init_unistr( &(info->name), driver.info_3->name); +} + +static void construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, + pstring servername, fstring architecture) +{ + NT_PRINTER_INFO_LEVEL printer; + NT_PRINTER_DRIVER_INFO_LEVEL driver; + + get_a_printer(&printer, 2, lp_servicename(snum) ); + get_a_printer_driver(&driver, 3, printer.info_2->drivername, architecture); + + fill_printer_driver_info_1(info, driver, servername, architecture); + + free_a_printer_driver(driver, 3); + free_a_printer(printer, 2); +} + +/******************************************************************** + * construct_printer_driver_info_2 + * fill a printer_info_2 struct + ********************************************************************/ +static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, + NT_PRINTER_DRIVER_INFO_LEVEL driver, + pstring servername, fstring architecture) +{ + pstring where; + pstring temp_driverpath; + pstring temp_datafile; + pstring temp_configfile; + fstring short_archi; + + get_short_archi(short_archi,architecture); + + snprintf(where,sizeof(where)-1,"\\\\%s\\print$\\%s\\", servername, short_archi); + + info->version=driver.info_3->cversion; + + init_unistr( &(info->name), driver.info_3->name ); + init_unistr( &(info->architecture), architecture ); + + snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "%s%s", where, + driver.info_3->driverpath); + init_unistr( &(info->driverpath), temp_driverpath ); + + snprintf(temp_datafile, sizeof(temp_datafile)-1, "%s%s", where, + driver.info_3->datafile); + init_unistr( &(info->datafile), temp_datafile ); + + snprintf(temp_configfile, sizeof(temp_configfile)-1, "%s%s", where, + driver.info_3->configfile); + init_unistr( &(info->configfile), temp_configfile ); +} + +/******************************************************************** + * 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) +{ + NT_PRINTER_INFO_LEVEL printer; + NT_PRINTER_DRIVER_INFO_LEVEL driver; + + get_a_printer(&printer, 2, lp_servicename(snum) ); + get_a_printer_driver(&driver, 3, printer.info_2->drivername, architecture); + + fill_printer_driver_info_2(info, driver, servername, architecture); + + free_a_printer_driver(driver, 3); + free_a_printer(printer, 2); +} + +/******************************************************************** + * copy a strings array and convert to UNICODE + ********************************************************************/ +static void init_unistr_array(UNISTR ***uni_array, char **char_array, char *where) +{ + int i=0; + char *v; + pstring line; + + DEBUG(6,("init_unistr_array\n")); + + 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])); + + snprintf(line, sizeof(line)-1, "%s%s", where, v); + init_unistr( (*uni_array)[i], line ); + DEBUGADD(7,("copy\n")); + + i++; + } + DEBUGADD(7,("last one\n")); + + *uni_array=(UNISTR **)Realloc(*uni_array, sizeof(UNISTR *)*(i+1)); + (*uni_array)[i]=0x0000; + DEBUGADD(6,("last one:done\n")); +} + +/******************************************************************** + * construct_printer_info_3 + * fill a printer_info_3 struct + ********************************************************************/ +static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, + NT_PRINTER_DRIVER_INFO_LEVEL driver, + pstring servername, fstring architecture) +{ + pstring where; + pstring temp_driverpath; + pstring temp_datafile; + pstring temp_configfile; + pstring temp_helpfile; + fstring short_archi; + + get_short_archi(short_archi, architecture); + + snprintf(where,sizeof(where)-1,"\\\\%s\\print$\\%s\\", servername, short_archi); + + info->version=driver.info_3->cversion; + + init_unistr( &(info->name), driver.info_3->name ); + init_unistr( &(info->architecture), architecture ); + + snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "%s%s", where, driver.info_3->driverpath); + init_unistr( &(info->driverpath), temp_driverpath ); + + snprintf(temp_datafile, sizeof(temp_datafile)-1, "%s%s", where, driver.info_3->datafile); + init_unistr( &(info->datafile), temp_datafile ); + + snprintf(temp_configfile, sizeof(temp_configfile)-1, "%s%s", where, driver.info_3->configfile); + init_unistr( &(info->configfile), temp_configfile ); + + snprintf(temp_helpfile, sizeof(temp_helpfile)-1, "%s%s", where, driver.info_3->helpfile); + init_unistr( &(info->helpfile), temp_helpfile ); + + init_unistr( &(info->monitorname), driver.info_3->monitorname ); + init_unistr( &(info->defaultdatatype), driver.info_3->defaultdatatype ); + + info->dependentfiles=NULL; + init_unistr_array(&(info->dependentfiles), driver.info_3->dependentfiles, where); +} + +/******************************************************************** + * construct_printer_info_3 + * fill a printer_info_3 struct + ********************************************************************/ +static void construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, + pstring servername, fstring architecture) +{ + NT_PRINTER_INFO_LEVEL printer; + NT_PRINTER_DRIVER_INFO_LEVEL driver; + + get_a_printer(&printer, 2, lp_servicename(snum) ); + get_a_printer_driver(&driver, 3, printer.info_2->drivername, architecture); + + fill_printer_driver_info_3(info, driver, servername, architecture); + + free_a_printer_driver(driver, 3); + free_a_printer(printer, 2); +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_getprinterdriver2( const POLICY_HND *handle, + const UNISTR2 *uni_arch, + uint32 level, + DRIVER_INFO *ctr, + uint32 *offered, + uint32 *needed) +{ + pstring servername; + fstring architecture; + int snum; + DRIVER_INFO_1 *info1=NULL; + DRIVER_INFO_2 *info2=NULL; + DRIVER_INFO_3 *info3=NULL; + + pstrcpy(servername, global_myname); + + if (!get_printer_snum(handle,&snum)) + { + return NT_STATUS_INVALID_HANDLE; + } + + unistr2_to_ascii(architecture, uni_arch, sizeof(architecture) ); + + DEBUG(1,("spoolss_getprinterdriver2:[%d]\n", level)); + + switch (level) + { + case 1: + { + info1=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1)); + construct_printer_driver_info_1(info1, snum, servername, architecture); + ctr->driver.info1=info1; + + return 0x0; + } + case 2: + { + info2=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2)); + construct_printer_driver_info_2(info2, snum, servername, architecture); + ctr->driver.info2=info2; + + return 0x0; + } + case 3: + { + info3=(DRIVER_INFO_3 *)malloc(sizeof(DRIVER_INFO_3)); + construct_printer_driver_info_3(info3, snum, servername, architecture); + ctr->driver.info3=info3; + + return 0x0; + } + default: + { + break; + } + } + return NT_STATUS_INVALID_INFO_CLASS; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_startpageprinter(const POLICY_HND *handle) +{ + int pnum = find_printer_index_by_hnd(handle); + + if (OPEN_HANDLE(pnum)) + { + Printer[pnum].page_started=True; + return 0x0; + } + + DEBUG(3,("Error in startpageprinter printer handle (pnum=%x)\n",pnum)); + return NT_STATUS_INVALID_HANDLE; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_endpageprinter(const POLICY_HND *handle) +{ + int pnum = find_printer_index_by_hnd(handle); + + if (OPEN_HANDLE(pnum)) + { + Printer[pnum].page_started=False; + return 0x0; + } + + DEBUG(3,("Error in endpageprinter printer handle (pnum=%x)\n",pnum)); + return NT_STATUS_INVALID_HANDLE; +} + + +/******************************************************************** + * api_spoolss_getprinter + * called from the spoolss dispatcher + * + ********************************************************************/ +uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level, + DOC_INFO *docinfo, uint32 *jobid) +{ + DOC_INFO_1 *info_1 = &docinfo->doc_info_1; + + pstring fname; + pstring tempname; + pstring datatype; + int fd = -1; + int snum; + int pnum; + + pnum = find_printer_index_by_hnd(handle); + + if (!VALID_HANDLE(pnum)) + { + return NT_STATUS_INVALID_HANDLE; + } + + /* + * a nice thing with NT is it doesn't listen to what you tell it. + * when asked to send _only_ RAW datas, it tries to send datas + * in EMF format. + * + * So I add checks like in NT Server ... + * + * lkclXXXX jean-francois, i love this kind of thing. oh, well, + * there's a bug in NT client-side code, so we'll fix it in the + * server-side code. *nnnnnggggh!* + */ + + if (info_1->p_datatype != 0) + { + unistr2_to_ascii(datatype, &(info_1->docname), sizeof(datatype)); + if (strcmp(datatype, "RAW") != 0) + { + (*jobid)=0; + return STATUS_1804; + } + } + + /* get the share number of the printer */ + if (!get_printer_snum(handle, &snum)) + { + return NT_STATUS_INVALID_HANDLE; + } + + /* Create a temporary file in the printer spool directory + * and open it + */ + + 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 ); + DEBUG(4,("Temp spool file created: [%s]\n", fname)); + + Printer[pnum].current_jobid=fd; + pstrcpy(Printer[pnum].document_name,fname); + + unistr2_to_ascii(Printer[pnum].job_name, + &info_1->docname, + sizeof(Printer[pnum].job_name)); + + Printer[pnum].document_fd=fd; + Printer[pnum].document_started=True; + (*jobid) = Printer[pnum].current_jobid; + + return 0x0; +} + +/******************************************************************** + * api_spoolss_getprinter + * called from the spoolss dispatcher + * + ********************************************************************/ +uint32 _spoolss_enddocprinter(const POLICY_HND *handle) +{ + int pnum; + int snum; + pstring filename; + pstring filename1; + pstring job_name; + pstring syscmd; + char *tstr; + + *syscmd=0; + + pnum = find_printer_index_by_hnd(handle); + + if (!OPEN_HANDLE(pnum)) + { + DEBUG(3,("Error in enddocprinter handle (pnum=%x)\n",pnum)); + return NT_STATUS_INVALID_HANDLE; + } + Printer[pnum].document_started=False; + close(Printer[pnum].document_fd); + DEBUG(4,("Temp spool file closed, printing now ...\n")); + + pstrcpy(filename1, Printer[pnum].document_name); + pstrcpy(job_name, Printer[pnum].job_name); + + if (!get_printer_snum(handle,&snum)) + { + return NT_STATUS_INVALID_HANDLE; + } + + /* copy the command into the buffer for extensive meddling. */ + StrnCpy(syscmd, lp_printcommand(snum), sizeof(pstring) - 1); + + /* look for "%s" in the string. If there is no %s, we cannot print. */ + if (!strstr(syscmd, "%s") && !strstr(syscmd, "%f")) + { + DEBUG(2,("WARNING! No placeholder for the filename in the print command for service %s!\n", SERVICE(snum))); + } + + if (strstr(syscmd,"%s")) + { + pstrcpy(filename,filename1); + pstring_sub(syscmd, "%s", filename); + } + + pstring_sub(syscmd, "%f", filename1); + + /* Does the service have a printername? If not, make a fake and empty + * printer name. That way a %p is treated sanely if no printer + * name was specified to replace it. This eventuality is logged. + */ + + tstr = lp_printername(snum); + if (tstr == NULL || tstr[0] == '\0') + { + DEBUG(3,( "No printer name - using %s.\n", SERVICE(snum))); + tstr = SERVICE(snum); + } + + pstring_sub(syscmd, "%p", tstr); + + /* If the lpr command support the 'Job' option replace here */ + pstring_sub(syscmd, "%j", job_name); + + if ( *syscmd != '\0') + { + int ret = smbrun(syscmd, NULL, False); + DEBUG(3,("Running the command `%s' gave %d\n", syscmd, ret)); + if (ret < 0) + { + lpq_reset(snum); + return NT_STATUS_ACCESS_DENIED; + } + } + else + { + DEBUG(0,("Null print command?\n")); + lpq_reset(snum); + return NT_STATUS_ACCESS_DENIED; + } + + lpq_reset(snum); + + return 0x0; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_writeprinter( const POLICY_HND *handle, + uint32 buffer_size, + const uint8 *buffer, + uint32 *buffer_written) +{ + int pnum; + int fd; + + pnum = find_printer_index_by_hnd(handle); + + if (!OPEN_HANDLE(pnum)) + { + DEBUG(3,("Error in writeprinter handle (pnum=%x)\n",pnum)); + return NT_STATUS_INVALID_HANDLE; + } + + fd = Printer[pnum].document_fd; + (*buffer_written) = write(fd, buffer, buffer_size); + Printer[pnum].document_lastwritten = (*buffer_written); + + return 0x0; +} + +/******************************************************************** + * api_spoolss_getprinter + * called from the spoolss dispatcher + * + ********************************************************************/ +static uint32 control_printer(const POLICY_HND *handle, uint32 command) +{ + int pnum; + int snum; + pnum = find_printer_index_by_hnd(handle); + + if ( pnum == -1 || !get_printer_snum(handle, &snum) ) + { + return NT_STATUS_INVALID_HANDLE; + } + + switch (command) + { + case PRINTER_CONTROL_PAUSE: + /* pause the printer here */ + status_printqueue(NULL, snum, LPSTAT_STOPPED); + return 0x0; + + case PRINTER_CONTROL_RESUME: + case PRINTER_CONTROL_UNPAUSE: + /* UN-pause the printer here */ + status_printqueue(NULL, snum, LPSTAT_OK); + return 0x0; + case PRINTER_CONTROL_PURGE: + /* Envoi des dragées FUCA dans l'imprimante */ + break; + } + + return NT_STATUS_INVALID_INFO_CLASS; +} + +/******************************************************************** + * called by spoolss_api_setprinter + * when updating a printer description + ********************************************************************/ +static uint32 update_printer(const POLICY_HND *handle, uint32 level, + const SPOOL_PRINTER_INFO_LEVEL *info, + const DEVICEMODE *devmode) +{ + int pnum; + int snum; + NT_PRINTER_INFO_LEVEL printer; + NT_DEVICEMODE *nt_devmode; + uint32 status = 0x0; + + nt_devmode=NULL; + + DEBUG(8,("update_printer\n")); + + if (level!=2) + { + DEBUG(0,("Send a mail to samba-bugs@samba.org\n")); + DEBUGADD(0,("with the following message: update_printer: level!=2\n")); + return NT_STATUS_INVALID_INFO_CLASS; + } + + pnum = find_printer_index_by_hnd(handle); + if ( pnum == -1 || !get_printer_snum(handle, &snum) ) + { + return NT_STATUS_INVALID_HANDLE; + } + get_a_printer(&printer, level, lp_servicename(snum)); + + DEBUGADD(8,("Converting info_2 struct\n")); + convert_printer_info(info, &printer, level); + + if ((info->info_2)->devmode_ptr != 0) + { + /* we have a valid devmode + convert it and link it*/ + + /* the nt_devmode memory is already alloced + * while doing the get_a_printer call + * but the devmode private part is not + * it's done by convert_devicemode + */ + DEBUGADD(8,("Converting the devicemode struct\n")); + nt_devmode=printer.info_2->devmode; + + init_devicemode(nt_devmode); + + convert_devicemode(*devmode, nt_devmode); + } + else + { + if (printer.info_2->devmode != NULL) + { + free(printer.info_2->devmode); + } + printer.info_2->devmode=NULL; + } + + if (status == 0x0) + { + status = add_a_printer(printer, level); + } + if (status == 0x0) + { + status = free_a_printer(printer, level); + } + + return status; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_setprinter( const POLICY_HND *handle, + uint32 level, + const SPOOL_PRINTER_INFO_LEVEL *info, + const DEVICEMODE *devmode, + uint32 sec_buf_size, + const char *sec_buf, + uint32 command) +{ + int pnum = find_printer_index_by_hnd(handle); + + if (!OPEN_HANDLE(pnum)) + { + return NT_STATUS_INVALID_HANDLE; + } + /* check the level */ + switch (level) + { + case 0: return control_printer(handle, command); + case 2: return update_printer(handle, level, info, devmode); + } + + return NT_STATUS_INVALID_INFO_CLASS; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_fcpn( const POLICY_HND *handle) +{ + return 0x0; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_addjob( const POLICY_HND *handle, uint32 level, + const BUFFER *buffer, + uint32 buf_size) +{ + return 0x0; +} + +/**************************************************************************** +****************************************************************************/ +static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue, + int position, int snum) +{ + pstring temp_name; + + struct tm *t; + time_t unixdate = time(NULL); + + t=gmtime(&unixdate); + snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname); + + job_info->jobid=queue->job; + init_unistr(&(job_info->printername), lp_servicename(snum)); + init_unistr(&(job_info->machinename), temp_name); + init_unistr(&(job_info->username), queue->user); + init_unistr(&(job_info->document), queue->file); + init_unistr(&(job_info->datatype), "RAW"); + init_unistr(&(job_info->text_status), ""); + job_info->status=queue->status; + job_info->priority=queue->priority; + job_info->position=position; + job_info->totalpages=0; + job_info->pagesprinted=0; + + make_systemtime(&(job_info->submitted), t); +} + +/**************************************************************************** +****************************************************************************/ +static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue, + int position, int snum) +{ + pstring temp_name; + DEVICEMODE *devmode; + NT_PRINTER_INFO_LEVEL ntprinter; + pstring chaine; + + struct tm *t; + time_t unixdate = time(NULL); + + if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 ) + { + return (False); + } + + t=gmtime(&unixdate); + snprintf(temp_name, sizeof(temp_name), "\\\\%s", global_myname); + + job_info->jobid=queue->job; + + snprintf(chaine, sizeof(chaine)-1, "\\\\%s\\%s", global_myname, ntprinter.info_2->printername); + init_unistr(&(job_info->printername), chaine); + + init_unistr(&(job_info->machinename), temp_name); + init_unistr(&(job_info->username), queue->user); + init_unistr(&(job_info->document), queue->file); + init_unistr(&(job_info->notifyname), queue->user); + init_unistr(&(job_info->datatype), "RAW"); + init_unistr(&(job_info->printprocessor), "winprint"); + init_unistr(&(job_info->parameters), ""); + init_unistr(&(job_info->text_status), ""); + +/* and here the security descriptor */ + + job_info->status=queue->status; + job_info->priority=queue->priority; + job_info->position=position; + job_info->starttime=0; + job_info->untiltime=0; + job_info->totalpages=0; + job_info->size=queue->size; + make_systemtime(&(job_info->submitted), t); + job_info->timeelapsed=0; + job_info->pagesprinted=0; + + devmode=(DEVICEMODE *)malloc(sizeof(DEVICEMODE)); + ZERO_STRUCTP(devmode); + construct_dev_mode(devmode, snum, global_myname); + job_info->devmode=devmode; + + free_a_printer(ntprinter, 2); + return (True); +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_enumjobs( const POLICY_HND *handle, + uint32 reqfirstjob, + uint32 reqnumofjobs, + uint32 level, + JOB_INFO_CTR *ctr, + uint32 *buf_size, + uint32 *numofjobs) +{ + int snum; + int count; + int i; + print_queue_struct *queue=NULL; + print_status_struct prt_status; + + DEBUG(4,("spoolss_enumjobs\n")); + + ZERO_STRUCT(prt_status); + + if (!get_printer_snum(handle, &snum)) + { + return NT_STATUS_INVALID_HANDLE; + } + + count = get_printqueue(snum, NULL, &queue, &prt_status); + (*numofjobs) = 0; + + DEBUG(4,("count:[%d], status:[%d], [%s]\n", + count, prt_status.status, prt_status.message)); + + switch (level) + { + case 1: + { + for (i=0; ijob.job_info_1, + job_info_1); + + fill_job_info_1(ctr->job.job_info_1[i], + &(queue[i]), i, snum); + } + safe_free(queue); + return 0x0; + } + case 2: + { + for (i=0; ijob.job_info_2, + job_info_2); + + fill_job_info_2(ctr->job.job_info_2[i], + &(queue[i]), i, snum); + } + safe_free(queue); + return 0x0; + } + } + + safe_free(queue); + + return NT_STATUS_INVALID_INFO_CLASS; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_schedulejob( const POLICY_HND *handle, uint32 jobid) +{ + return 0x0; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_setjob( const POLICY_HND *handle, + uint32 jobid, + uint32 level, + JOB_INFO *ctr, + uint32 command) + +{ + int snum; + print_queue_struct *queue=NULL; + print_status_struct prt_status; + int i=0; + BOOL found=False; + int count; + + bzero(&prt_status,sizeof(prt_status)); + + if (!get_printer_snum(handle, &snum)) + { + return NT_STATUS_INVALID_HANDLE; + } + + count=get_printqueue(snum, NULL, &queue, &prt_status); + + while ( (idriver.info1=driver_info_1; + break; + } + case 2: + { + DRIVER_INFO_2 *driver_info_2=NULL; + driver_info_2=(DRIVER_INFO_2 *)malloc(count*sizeof(DRIVER_INFO_2)); + + for (i=0; idriver.info2=driver_info_2; + break; + } + case 3: + { + DRIVER_INFO_3 *driver_info_3=NULL; + driver_info_3=(DRIVER_INFO_3 *)malloc(count*sizeof(DRIVER_INFO_3)); + + for (i=0; idriver.info3=driver_info_3; + break; + } + default: + { + return NT_STATUS_INVALID_INFO_CLASS; + } + } + return 0x0; + +} + +/**************************************************************************** +****************************************************************************/ +static void fill_form_1(FORM_1 *form, nt_forms_struct *list, int position) +{ + form->flag=list->flag; + init_unistr(&(form->name), list->name); + form->width=list->width; + form->length=list->length; + form->left=list->left; + form->top=list->top; + form->right=list->right; + form->bottom=list->bottom; +} + +/**************************************************************************** +****************************************************************************/ +static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size) +{ + prs_struct *ps; + uint32 extra_space; + + ps=&(buffer->prs); + + /* damn, I'm doing the reverse operation of prs_grow() :) */ + extra_space = buffer_size - prs_data_size(ps); + + if (!prs_grow(ps, extra_space)) + return False; + + buffer->string_at_end=buffer_size; + + return True; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _new_spoolss_enumforms( const POLICY_HND *handle, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *numofforms) +{ + nt_forms_struct *list=NULL; + FORM_1 *forms_1; + int buffer_size=0; + int i; + + + DEBUG(4,("_new_spoolss_enumforms\n")); + DEBUGADD(5,("Offered buffer size [%d]\n", offered)); + DEBUGADD(5,("Info level [%d]\n", level)); + + *numofforms = get_ntforms(&list); + DEBUGADD(5,("Number of forms [%d]\n", *numofforms)); + + switch (level) { + case 1: + forms_1=(FORM_1 *)malloc(*numofforms * sizeof(FORM_1)); + + /* construct the list of form structures */ + for (i=0; i<*numofforms; i++) + { + DEBUGADD(6,("Filling form number [%d]\n",i)); + fill_form_1(&(forms_1[i]), &(list[i]), i); + } + + /* check the required size. */ + 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)) + return ERROR_INSUFFICIENT_BUFFER; + + /* fill the buffer with the form structures */ + 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); + + if (*needed > offered) + return ERROR_INSUFFICIENT_BUFFER; + else + return NT_STATUS_NO_PROBLEMO; + + default: + safe_free(list); + return NT_STATUS_INVALID_INFO_CLASS; + } + +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_enumforms( const POLICY_HND *handle, + uint32 level, + FORM_1 **forms_1, + uint32 *offered, + uint32 *numofforms) +{ + int count; + int i; + nt_forms_struct *list=NULL; + (*forms_1)=NULL; + + DEBUG(4,("spoolss_enumforms\n")); + + count = get_ntforms(&list); + (*numofforms) = count; + + DEBUGADD(5,("Offered buffer size [%d]\n", *offered)); + DEBUGADD(5,("Number of forms [%d]\n", *numofforms)); + DEBUGADD(5,("Info level [%d]\n", level)); + + switch (level) + { + case 1: + { + (*forms_1)=(FORM_1 *)malloc(count*sizeof(FORM_1)); + for (i=0; iport_name), name); + init_unistr(&(port->monitor_name), "Moniteur Local"); + init_unistr(&(port->description), "Local Port"); +#define PORT_TYPE_WRITE 1 + port->port_type=PORT_TYPE_WRITE; + port->reserved=0x0; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_enumports( const UNISTR2 *name, + uint32 level, + PORT_INFO_CTR *ctr, + uint32 *offered, + uint32 *numofports) +{ + int n_services=lp_numservices(); + int snum; + + DEBUG(4,("spoolss_enumports\n")); + + (*numofports) = 0; + + switch (level) + { + case 2: + { + PORT_INFO_2 *ports_2=NULL; + ports_2=(PORT_INFO_2 *)malloc(n_services*sizeof(PORT_INFO_2)); + for (snum=0; snumport.info_2=ports_2; + return 0x0; + } + } + + return NT_STATUS_INVALID_INFO_CLASS; +} + +/**************************************************************************** +****************************************************************************/ +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_level, + const SPOOL_USER_LEVEL *user, + POLICY_HND *handle) +{ + NT_PRINTER_INFO_LEVEL printer; + fstring ascii_name; + fstring server_name; + fstring share_name; + UNISTR2 *portname; + SPOOL_PRINTER_INFO_LEVEL_2 *info2; + uint32 status = 0x0; + + if (!open_printer_hnd(handle)) + { + return NT_STATUS_ACCESS_DENIED; + } + + /* 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); + + /* write the ASCII on disk */ + status = add_a_printer(printer, level); + if (status != 0x0) + { + close_printer_handle(handle); + return status; + } + + info2=info->info_2; + portname=&(info2->portname); + + StrnCpy(server_name, global_myname, strlen(global_myname) ); + unistr2_to_ascii(share_name, portname, sizeof(share_name)-1); + + slprintf(ascii_name, sizeof(ascii_name)-1, "\\\\%s\\%s", + server_name, share_name); + + if (!set_printer_hnd_printertype(handle, ascii_name) || + !set_printer_hnd_printername(handle, ascii_name)) + { + close_printer_handle(handle); + return NT_STATUS_ACCESS_DENIED; + } + + return 0x0; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name, + uint32 level, + const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info) +{ + NT_PRINTER_DRIVER_INFO_LEVEL driver; + convert_printer_driver_info(info, &driver, level); + return add_a_printer_driver(driver, level); +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_getprinterdriverdirectory( const UNISTR2 *name, + const UNISTR2 *uni_environment, + uint32 level, + DRIVER_DIRECTORY_CTR *ctr, + uint32 *offered) +{ + pstring chaine; + pstring long_archi; + pstring archi; + + unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1); + get_short_archi(archi, long_archi); + + slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\print$\\%s", + global_myname, archi); + + DEBUG(4,("printer driver directory: [%s]\n", chaine)); + + init_unistr(&(ctr->driver.info_1.name), chaine); + + return 0x0; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, + uint32 idx, + uint32 *valuesize, + UNISTR *uni_value, + uint32 *realvaluesize, + uint32 *type, + uint32 *datasize, + uint8 **data, + uint32 *realdatasize) +{ + NT_PRINTER_INFO_LEVEL printer; + + fstring value; + + uint32 param_index; + uint32 biggest_valuesize; + uint32 biggest_datasize; + uint32 data_len; + uint32 status = 0x0; + + int pnum = find_printer_index_by_hnd(handle); + int snum; + + ZERO_STRUCT(printer); + (*data)=NULL; + + DEBUG(5,("spoolss_enumprinterdata\n")); + + if (!OPEN_HANDLE(pnum)) + { + return NT_STATUS_INVALID_HANDLE; + } + if (!get_printer_snum(handle, &snum)) + { + return NT_STATUS_INVALID_HANDLE; + } + status = get_a_printer(&printer, 2, lp_servicename(snum)); + + if (status != 0x0) + { + return status; + } + + /* The NT machine wants to know the biggest size of value and data */ + if ( ((*valuesize)==0) && ((*datasize)==0) ) + { + DEBUGADD(6,("Activating NT mega-hack to find sizes\n")); + + (*valuesize)=0; + (*realvaluesize)=0; + (*type)=0; + (*datasize)=0; + (*realdatasize)=0; + status=0; + + param_index=0; + biggest_valuesize=0; + biggest_datasize=0; + + while (get_specific_param_by_index(printer, 2, param_index, value, data, type, &data_len)) + { + if (strlen(value) > biggest_valuesize) biggest_valuesize=strlen(value); + if (data_len > biggest_datasize) biggest_datasize=data_len; + + param_index++; + } + + /* I wrote it, I didn't designed the protocol */ + if (biggest_valuesize!=0) + { + SIVAL(&(value),0, 2*(biggest_valuesize+1) ); + } + (*data)=(uint8 *)malloc(4*sizeof(uint8)); + SIVAL((*data), 0, biggest_datasize ); + } + else + { + /* + * the value len is wrong in NT sp3 + * that's the number of bytes not the number of unicode chars + */ + + if (get_specific_param_by_index(printer, 2, idx, value, data, type, &data_len)) + { + init_unistr(uni_value, value); + + /* the length are in bytes including leading NULL */ + (*realvaluesize)=2*(strlen(value)+1); + (*realdatasize)=data_len; + + status=0; + } + else + { + (*valuesize)=0; + (*realvaluesize)=0; + (*datasize)=0; + (*realdatasize)=0; + (*type)=0; + status=0x0103; /* ERROR_NO_MORE_ITEMS */ + } + } + + free_a_printer(printer, 2); + + return status; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_setprinterdata( const POLICY_HND *handle, + const UNISTR2 *value, + uint32 type, + uint32 max_len, + const uint8 *data, + uint32 real_len, + uint32 numeric_data) +{ + NT_PRINTER_INFO_LEVEL printer; + NT_PRINTER_PARAM *param = NULL; + + int pnum=0; + int snum=0; + uint32 status = 0x0; + + DEBUG(5,("spoolss_setprinterdata\n")); + + pnum = find_printer_index_by_hnd(handle); + + if (!OPEN_HANDLE(pnum)) + { + return NT_STATUS_INVALID_HANDLE; + } + if (!get_printer_snum(handle, &snum)) + { + return NT_STATUS_INVALID_HANDLE; + } + + status = get_a_printer(&printer, 2, lp_servicename(snum)); + if (status != 0x0) + { + return status; + } + + convert_specific_param(¶m, value , type, data, real_len); + unlink_specific_param_if_exist(printer.info_2, param); + + if (!add_a_specific_param(printer.info_2, param)) + { + status = NT_STATUS_INVALID_PARAMETER; + } + else + { + status = add_a_printer(printer, 2); + } + free_a_printer(printer, 2); + + return status; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_addform( const POLICY_HND *handle, + uint32 level, + const FORM *form) +{ + int pnum=0; + int count=0; + nt_forms_struct *list=NULL; + + DEBUG(5,("spoolss_addform\n")); + + pnum = find_printer_index_by_hnd(handle); + + if (!OPEN_HANDLE(pnum)) + { + return NT_STATUS_INVALID_HANDLE; + } + + count=get_ntforms(&list); + add_a_form(&list, form, &count); + write_ntforms(&list, count); + + safe_free(list); + + return 0x0; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_setform( const POLICY_HND *handle, + const UNISTR2 *uni_name, + uint32 level, + const FORM *form) +{ + int pnum=0; + int count=0; + nt_forms_struct *list=NULL; + + DEBUG(5,("spoolss_setform\n")); + + pnum = find_printer_index_by_hnd(handle); + if (!OPEN_HANDLE(pnum)) + { + return NT_STATUS_INVALID_HANDLE; + } + count=get_ntforms(&list); + update_a_form(&list, form, count); + write_ntforms(&list, count); + + safe_free(list); + + return 0x0; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_enumprintprocessors(const UNISTR2 *name, + const UNISTR2 *environment, + uint32 level, + PRINTPROCESSOR_1 **info_1, + uint32 *offered, + uint32 *numofprintprocessors) +{ + DEBUG(5,("spoolss_enumprintprocessors\n")); + + /* + * Enumerate the print processors ... + * + * Just reply with "winprint", to keep NT happy + * and I can use my nice printer checker. + */ + + (*numofprintprocessors) = 0x1; + (*info_1) = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1)); + + if ((*info_1) == NULL) + { + return NT_STATUS_NO_MEMORY; + } + + init_unistr(&((*info_1)->name), "winprint"); + + return 0x0; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_enumprintmonitors( const UNISTR2 *name, + uint32 level, + PRINTMONITOR_1 **info_1, + uint32 *offered, + uint32 *numofprintmonitors) +{ + DEBUG(5,("spoolss_enumprintmonitors\n")); + + /* + * Enumerate the print monitors ... + * + * Just reply with "Local Port", to keep NT happy + * and I can use my nice printer checker. + */ + + (*numofprintmonitors) = 0x1; + (*info_1) = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1)); + if ((*info_1) == NULL) + { + return NT_STATUS_NO_MEMORY; + } + + init_unistr(&((*info_1)->name), "Local Port"); + + return 0x0; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_getjob( const POLICY_HND *handle, + uint32 jobid, + uint32 level, + PJOB_INFO *ctr, + uint32 *offered) +{ + int snum; + int count; + int i; + print_queue_struct *queue=NULL; + print_status_struct prt_status; + + DEBUG(4,("spoolss_getjob\n")); + + bzero(&prt_status,sizeof(prt_status)); + + if (!get_printer_snum(handle, &snum)) + { + return NT_STATUS_INVALID_HANDLE; + } + count=get_printqueue(snum, NULL, &queue, &prt_status); + + DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n", + count, prt_status.status, prt_status.message)); + + switch (level) + { + case 1: + { + JOB_INFO_1 *job_info_1=NULL; + job_info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1)); + + if (job_info_1 == NULL) + { + safe_free(queue); + return NT_STATUS_NO_MEMORY; + } + + for (i=0; ijob.job_info_1=job_info_1; + break; + } + case 2: + { + JOB_INFO_2 *job_info_2=NULL; + job_info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2)); + + if (job_info_2 == NULL) + { + safe_free(queue); + return NT_STATUS_NO_MEMORY; + } + + for (i=0; ijob.job_info_2=job_info_2; + break; + } + default: + { + safe_free(queue); + return NT_STATUS_INVALID_INFO_CLASS; + } + } + + safe_free(queue); + return 0x0; +} -- cgit From b81dc7b7f832cae2e66076398a134fbb6c1f78ca Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Mon, 7 Feb 2000 16:22:16 +0000 Subject: Jeremy can you check lib/util_unistr.c for codepages support ? I added 2 UNICODE <-> ASCII functions which _don't_ honor codepage support. J.F. --- source/lib/util.c | 12 ++++++ source/lib/util_unistr.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++ source/param/loadparm.c | 9 +++++ source/smbd/nttrans.c | 1 + source/smbd/server.c | 7 +++- 5 files changed, 124 insertions(+), 2 deletions(-) diff --git a/source/lib/util.c b/source/lib/util.c index 71f440eae52..a824887e88b 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -1661,6 +1661,18 @@ void *Realloc(void *p,size_t size) } +/**************************************************************************** +free memory, checks for NULL +****************************************************************************/ +void safe_free(void *p) +{ + if (p != NULL) + { + free(p); + } +} + + /**************************************************************************** get my own name and IP ****************************************************************************/ diff --git a/source/lib/util_unistr.c b/source/lib/util_unistr.c index a512f68acc0..2c721aeb473 100644 --- a/source/lib/util_unistr.c +++ b/source/lib/util_unistr.c @@ -78,6 +78,61 @@ int dos_PutUniCode(char *dst,const char *src, ssize_t len) return(ret); } +/******************************************************************* + Put an ASCII string into a UNICODE array (uint16's). + + Warning: doesn't do any codepage !!! BAD !!! + + Help ! Fix Me ! Fix Me ! +********************************************************************/ + +void ascii_to_unistr(uint16 *dest, const char *src, int maxlen) +{ + uint16 *destend = dest + maxlen; + register char c; + + while (dest < destend) + { + c = *(src++); + if (c == 0) + { + break; + } + + *(dest++) = (uint16)c; + } + + *dest = 0; +} + +/******************************************************************* + Pull an ASCII string out of a UNICODE array (uint16's). + + Warning: doesn't do any codepage !!! BAD !!! + + Help ! Fix Me ! Fix Me ! +********************************************************************/ + +void unistr_to_ascii(char *dest, const uint16 *src, int len) +{ + char *destend = dest + len; + register uint16 c; + + while (dest < destend) + { + c = *(src++); + if (c == 0) + { + break; + } + + *(dest++) = (char)c; + } + + *dest = 0; +} + + /******************************************************************* Skip past some unicode strings in a buffer. ********************************************************************/ @@ -182,6 +237,48 @@ char *dos_unistr2_to_str(UNISTR2 *str) return lbuf; } +/******************************************************************* + Convert a UNISTR2 structure to an ASCII string + Warning: this version does DOS codepage. +********************************************************************/ + +void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen) +{ + char *destend; + const uint16 *src; + size_t len; + register uint16 c; + + src = str->buffer; + len = MIN(str->uni_str_len, maxlen); + destend = dest + len; + + while (dest < destend) + { + uint16 ucs2_val; + uint16 cp_val; + + c = *(src++); + if (c == 0) + { + break; + } + + ucs2_val = SVAL(src,0); + cp_val = ucs2_to_doscp[ucs2_val]; + + if (cp_val < 256) + *(dest++) = (char)cp_val; + else { + *dest= (cp_val >> 8) & 0xff; + *(dest++) = (cp_val & 0xff); + } + } + + *dest = 0; +} + + /******************************************************************* Return a number stored in a buffer ********************************************************************/ diff --git a/source/param/loadparm.c b/source/param/loadparm.c index 839c9c9e162..85082467412 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -159,6 +159,8 @@ typedef struct char *szAddUserScript; char *szDelUserScript; char *szWINSHook; + char *szNtForms; + char *szNtDriverFile; #ifdef WITH_UTMP char *szUtmpDir; #endif /* WITH_UTMP */ @@ -721,6 +723,8 @@ static struct parm_struct parm_table[] = {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL, NULL, 0}, {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL, NULL, FLAG_PRINT}, {"printer driver location", P_STRING, P_LOCAL, &sDefault.szPrinterDriverLocation, NULL, NULL, FLAG_PRINT|FLAG_GLOBAL}, + {"nt forms file", P_STRING, P_GLOBAL, &Globals.szNtForms, NULL, NULL, FLAG_GLOBAL}, + {"nt printer driver",P_STRING, P_GLOBAL, &Globals.szNtDriverFile, NULL, NULL, FLAG_GLOBAL}, {"Filename Handling", P_SEP, P_SEPARATOR}, @@ -908,6 +912,8 @@ static void init_globals(void) string_set(&Globals.szPasswdProgram, PASSWD_PROGRAM); string_set(&Globals.szPrintcapname, PRINTCAP_NAME); string_set(&Globals.szDriverFile, DRIVERFILE); + string_set(&Globals.szNtForms, FORMSFILE); + string_set(&Globals.szNtDriverFile, NTDRIVERSDIR); string_set(&Globals.szLockDir, LOCKDIR); string_set(&Globals.szRootdir, "/"); #ifdef WITH_UTMP @@ -1222,6 +1228,9 @@ FN_GLOBAL_STRING(lp_domain_guest_group,&Globals.szDomainGuestGroup) FN_GLOBAL_STRING(lp_domain_admin_users,&Globals.szDomainAdminUsers) FN_GLOBAL_STRING(lp_domain_guest_users,&Globals.szDomainGuestUsers) +FN_GLOBAL_STRING(lp_nt_forms,&Globals.szNtForms) +FN_GLOBAL_STRING(lp_nt_drivers_file,&Globals.szNtDriverFile) + #ifdef WITH_LDAP FN_GLOBAL_STRING(lp_ldap_server,&Globals.szLdapServer); FN_GLOBAL_STRING(lp_ldap_suffix,&Globals.szLdapSuffix); diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c index 4b344c33185..d9ad16e7d3c 100644 --- a/source/smbd/nttrans.c +++ b/source/smbd/nttrans.c @@ -44,6 +44,7 @@ static char *known_nt_pipes[] = { "\\lsass", "\\lsarpc", "\\winreg", + "\\spoolss", NULL }; diff --git a/source/smbd/server.c b/source/smbd/server.c index 44e347b1046..d1788678a7c 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -468,6 +468,9 @@ static void init_structs(void ) /* for LSA handles */ init_lsa_policy_hnd(); + /* for SPOOLSS handles */ + init_printer_hnd(); + init_dptrs(); } @@ -707,8 +710,8 @@ static void usage(char *pname) DEBUG( 3, ( "Becoming a daemon.\n" ) ); become_daemon(); } - - check_kernel_oplocks(); + + check_kernel_oplocks(); if (!directory_exist(lp_lockdir(), NULL)) { mkdir(lp_lockdir(), 0755); -- cgit From 81e375bbbe0fb022a44a2aaaa3729a9518b7a854 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Mon, 7 Feb 2000 16:25:15 +0000 Subject: spoolss definitions. also added some prs_struct functions, 'cause I'm handling buffers as prs_struct. J.F. --- source/rpc_parse/parse_misc.c | 25 ++++++++++++++++++++ source/rpc_parse/parse_prs.c | 50 ++++++++++++++++++++++++++++++++++++++++ source/rpc_parse/parse_rpc.c | 21 ++++++++--------- source/rpc_server/srv_pipe_srv.c | 47 +++++++++++++++++++++++++++++++++---- 4 files changed, 128 insertions(+), 15 deletions(-) diff --git a/source/rpc_parse/parse_misc.c b/source/rpc_parse/parse_misc.c index 5277825767f..21d97b444c3 100644 --- a/source/rpc_parse/parse_misc.c +++ b/source/rpc_parse/parse_misc.c @@ -592,6 +592,31 @@ BOOL smb_io_buffer3(char *desc, BUFFER3 *buf3, prs_struct *ps, int depth) return True; } +/******************************************************************* +reads or writes a BUFFER5 structure. +the buf_len member tells you how large the buffer is. +********************************************************************/ +BOOL smb_io_buffer5(char *desc, BUFFER5 *buf5, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "smb_io_buffer4"); + depth++; + + if (buf5 == NULL) return False; + + prs_align(ps); + prs_uint32("buf_len", ps, depth, &(buf5->buf_len)); + + /* reading: alloc the buffer first */ + if ( ps->io ) + { + buf5->buffer=(uint16 *)malloc( sizeof(uint16)*buf5->buf_len ); + } + + prs_uint16s(True, "buffer", ps, depth, buf5->buffer, buf5->buf_len); + + return True; +} + /******************************************************************* Inits a BUFFER2 structure. ********************************************************************/ diff --git a/source/rpc_parse/parse_prs.c b/source/rpc_parse/parse_prs.c index 6bb07c5f648..24eff1b7799 100644 --- a/source/rpc_parse/parse_prs.c +++ b/source/rpc_parse/parse_prs.c @@ -282,6 +282,21 @@ BOOL prs_append_prs_data(prs_struct *dst, prs_struct *src) return True; } +/******************************************************************* + Append some data from one parse_struct into another. + ********************************************************************/ + +BOOL prs_append_some_prs_data(prs_struct *dst, prs_struct *src, uint32 len) +{ + if(!prs_grow(dst, len)) + return False; + + memcpy(&dst->data_p[dst->data_offset], prs_data_p(src), (size_t)len); + dst->data_offset += len; + + return True; +} + /******************************************************************* Append the data from a buffer into a parse_struct. ********************************************************************/ @@ -351,6 +366,25 @@ char *prs_mem_get(prs_struct *ps, uint32 extra_size) return &ps->data_p[ps->data_offset]; } +/******************************************************************* + Change the struct type. + ********************************************************************/ + +BOOL prs_switch_type(prs_struct *ps, BOOL io) +{ + if ((ps->io ^ io) == True) + ps->io=io; +} + +/******************************************************************* + Force a prs_struct to be dynamic even when it's size is 0. + ********************************************************************/ + +void prs_force_dynamic(prs_struct *ps) +{ + ps->is_dynamic=True; +} + /******************************************************************* Stream a uint8. ********************************************************************/ @@ -416,6 +450,22 @@ BOOL prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *dat return True; } +/****************************************************************** + Stream an array of uint16s. Length is number of uint16s. + ********************************************************************/ + +BOOL prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len) +{ + char *q = prs_mem_get(ps, len * sizeof(uint16)); + if (q == NULL) + return False; + + DBG_RW_PSVAL(charmode, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, data16s, len) + ps->data_offset += (len * sizeof(uint16)); + + return True; +} + /****************************************************************** Stream an array of uint32s. Length is number of uint32s. ********************************************************************/ diff --git a/source/rpc_parse/parse_rpc.c b/source/rpc_parse/parse_rpc.c index d4ea84628ad..54d3eea74d8 100644 --- a/source/rpc_parse/parse_rpc.c +++ b/source/rpc_parse/parse_rpc.c @@ -105,6 +105,15 @@ interface/version dce/rpc pipe identification }, 0x01 \ } +#define SYNT_SPOOLSS_V1 \ +{ \ + { \ + 0x12345678, 0x1234, 0xabcb, \ + { 0xef, 0x00, 0x01, 0x23, \ + 0x45, 0x67, 0x89, 0xab } \ + }, 0x01 \ +} + #define SYNT_NONE_V0 \ { \ { \ @@ -114,17 +123,6 @@ interface/version dce/rpc pipe identification }, 0x00 \ } -/* pipe string names */ -#define PIPE_SRVSVC "\\PIPE\\srvsvc" -#define PIPE_SAMR "\\PIPE\\samr" -#define PIPE_WINREG "\\PIPE\\winreg" -#define PIPE_WKSSVC "\\PIPE\\wkssvc" -#define PIPE_NETLOGON "\\PIPE\\NETLOGON" -#define PIPE_NTLSA "\\PIPE\\ntlsa" -#define PIPE_NTSVCS "\\PIPE\\ntsvcs" -#define PIPE_LSASS "\\PIPE\\lsass" -#define PIPE_LSARPC "\\PIPE\\lsarpc" - struct pipe_id_info pipe_names [] = { /* client pipe , abstract syntax , server pipe , transfer syntax */ @@ -134,6 +132,7 @@ struct pipe_id_info pipe_names [] = { PIPE_SRVSVC , SYNT_SRVSVC_V3 , PIPE_NTSVCS , TRANS_SYNT_V2 }, { PIPE_WKSSVC , SYNT_WKSSVC_V1 , PIPE_NTSVCS , TRANS_SYNT_V2 }, { PIPE_WINREG , SYNT_WINREG_V1 , PIPE_WINREG , TRANS_SYNT_V2 }, + { PIPE_SPOOLSS , SYNT_SPOOLSS_V1 , PIPE_SPOOLSS , TRANS_SYNT_V2 }, { NULL , SYNT_NONE_V0 , NULL , SYNT_NONE_V0 } }; diff --git a/source/rpc_server/srv_pipe_srv.c b/source/rpc_server/srv_pipe_srv.c index 236558ba705..2cebc8148ba 100644 --- a/source/rpc_server/srv_pipe_srv.c +++ b/source/rpc_server/srv_pipe_srv.c @@ -465,6 +465,7 @@ static struct api_cmd api_fd_commands[] = #if DISABLED_IN_2_0 { "winreg", "winreg", api_reg_rpc }, #endif + { "spoolss", "spoolss", api_spoolss_rpc }, { NULL, NULL, NULL } }; @@ -585,7 +586,7 @@ static BOOL setup_bind_nak(pipes_struct *p, prs_struct *pd) Respond to a pipe bind request. *******************************************************************/ -static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) +static BOOL api_pipe_bind_and_alt_req(pipes_struct *p, prs_struct *pd, enum RPC_PKT_TYPE pkt_type) { RPC_HDR_BA hdr_ba; RPC_HDR_RB hdr_rb; @@ -684,9 +685,21 @@ static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) p->ntlmssp_auth_requested = True; } - /* name has to be \PIPE\xxxxx */ - fstrcpy(ack_pipe_name, "\\PIPE\\"); - fstrcat(ack_pipe_name, p->pipe_srv_name); + switch (pkt_type) { + case RPC_BINDACK: + /* name has to be \PIPE\xxxxx */ + fstrcpy(ack_pipe_name, "\\PIPE\\"); + fstrcat(ack_pipe_name, p->pipe_srv_name); + case RPC_ALTCONTRESP: + /* secondary address CAN be NULL + * as the specs says it's ignored. + * It MUST NULL to have the spoolss working. + */ + fstrcpy(ack_pipe_name, ""); + break; + default: + return False; + } DEBUG(5,("api_pipe_bind_req: make response. %d\n", __LINE__)); @@ -831,6 +844,29 @@ static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) return False; } +/******************************************************************* + Respond to a pipe bind request. +*******************************************************************/ + +static BOOL api_pipe_bind_req(pipes_struct *p, prs_struct *pd) +{ + return api_pipe_bind_and_alt_req(p, pd, RPC_BINDACK); +} + +/******************************************************************* + Respond to a pipe alter request. + + The RPC Alter-Context call is used only by the spoolss pipe + simply because there is a bug (?) in the MS unmarshalling code + or in the marshalling code. If it's in the later, then Samba + have the same bug. +*******************************************************************/ + +static BOOL api_pipe_altercontext_req(pipes_struct *p, prs_struct *pd) +{ + return api_pipe_bind_and_alt_req(p, pd, RPC_ALTCONTRESP); +} + /**************************************************************************** Deal with sign & seal processing on an RPC request. ****************************************************************************/ @@ -1011,6 +1047,9 @@ BOOL rpc_command(pipes_struct *p, char *input_data, int data_len) case RPC_BIND: reply = api_pipe_bind_req(p, &rpc_in); break; + case RPC_ALTCONT: + reply = api_pipe_altercontext_req(p, &rpc_in); + break; case RPC_REQUEST: if (p->ntlmssp_auth_requested && !p->ntlmssp_auth_validated) { /* authentication _was_ requested -- cgit From 853a1a3027dde7608027dc78f6e15789d5fc9152 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Mon, 7 Feb 2000 16:27:03 +0000 Subject: spoolss include definitions J.F. --- source/include/ntdomain.h | 26 +++++++++++++------------- source/include/nterr.h | 11 +++++++++++ source/include/rpc_dce.h | 2 ++ source/include/rpc_misc.h | 7 +++++++ source/include/smb.h | 4 ++-- 5 files changed, 35 insertions(+), 15 deletions(-) diff --git a/source/include/ntdomain.h b/source/include/ntdomain.h index 07d06656c06..c1b966aa592 100644 --- a/source/include/ntdomain.h +++ b/source/include/ntdomain.h @@ -24,6 +24,10 @@ #ifndef _NT_DOMAIN_H /* _NT_DOMAIN_H */ #define _NT_DOMAIN_H +/* + * A bunch of stuff that was put into smb.h + * in the NTDOM branch - it didn't belong there. + */ /* dce/rpc support */ #include "rpc_dce.h" @@ -33,19 +37,6 @@ /* security descriptor structures */ #include "rpc_secdes.h" - -/* different dce/rpc pipes */ -#include "rpc_lsa.h" -#include "rpc_netlogon.h" -#include "rpc_reg.h" -#include "rpc_samr.h" -#include "rpc_srvsvc.h" -#include "rpc_wkssvc.h" - -/* - * A bunch of stuff that was put into smb.h - * in the NTDOM branch - it didn't belong there. - */ typedef struct _prs_struct { @@ -157,4 +148,13 @@ struct acct_info uint32 smb_userid; /* domain-relative RID */ }; +/* different dce/rpc pipes */ +#include "rpc_lsa.h" +#include "rpc_netlogon.h" +#include "rpc_reg.h" +#include "rpc_samr.h" +#include "rpc_srvsvc.h" +#include "rpc_wkssvc.h" +#include "rpc_spoolss.h" + #endif /* _NT_DOMAIN_H */ diff --git a/source/include/nterr.h b/source/include/nterr.h index a94464a013e..87935091195 100644 --- a/source/include/nterr.h +++ b/source/include/nterr.h @@ -1,7 +1,18 @@ + +/* Win32 Status codes. */ + +#define STATUS_BUFFER_OVERFLOW (5) +#define STATUS_MORE_ENTRIES (0x105) +#define ERROR_INVALID_HANDLE (6) +#define ERROR_INVALID_PARAMETER (87) +#define ERROR_INSUFFICIENT_BUFFER (122) +#define STATUS_1804 (1804) + /* these are the NT error codes less than 1000. They are here for when we start supporting NT error codes in Samba. They were extracted using a loop in smbclient then printing a netmon sniff to a file */ +#define NT_STATUS_NO_PROBLEMO (0) #define NT_STATUS_UNSUCCESSFUL (1) #define NT_STATUS_NOT_IMPLEMENTED (2) #define NT_STATUS_INVALID_INFO_CLASS (3) diff --git a/source/include/rpc_dce.h b/source/include/rpc_dce.h index 9ffcf50337d..19527ca6e2e 100644 --- a/source/include/rpc_dce.h +++ b/source/include/rpc_dce.h @@ -37,6 +37,8 @@ enum RPC_PKT_TYPE RPC_BIND = 0x0B, RPC_BINDACK = 0x0C, RPC_BINDNACK = 0x0D, + RPC_ALTCONT = 0x0E, + RPC_ALTCONTRESP = 0x0F, RPC_BINDRESP = 0x10 /* not the real name! this is undocumented! */ }; diff --git a/source/include/rpc_misc.h b/source/include/rpc_misc.h index b837c8a67c5..e96d6d4527c 100644 --- a/source/include/rpc_misc.h +++ b/source/include/rpc_misc.h @@ -156,6 +156,13 @@ typedef struct buffer3_info } BUFFER3; +/* BUFFER5 */ +typedef struct buffer5_info +{ + uint32 buf_len; + uint16 *buffer; /* data */ +} BUFFER5; + /* UNISTR2 - unicode string size (in uint16 unicode chars) and buffer */ typedef struct unistr2_info { diff --git a/source/include/smb.h b/source/include/smb.h index f0ed34bd404..085325939fd 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -53,7 +53,6 @@ typedef int BOOL; #define SMB_SECONDARY_WAIT (60*1000) /* Debugging stuff */ - #include "debug.h" /* this defines the error codes that receive_smb can put in smb_read_error */ @@ -267,7 +266,7 @@ typedef smb_ucs2_t wfstring[128]; #define PIPE_NTSVCS "\\PIPE\\ntsvcs" #define PIPE_LSASS "\\PIPE\\lsass" #define PIPE_LSARPC "\\PIPE\\lsarpc" - +#define PIPE_SPOOLSS "\\PIPE\\spoolss" /* 64 bit time (100usec) since ????? - cifs6.txt, section 3.5, page 30 */ typedef struct nttime_info @@ -1604,6 +1603,7 @@ extern int chain_size; #include "smb_macros.h" +#include "nt_printing.h" #include "ntdomain.h" /* A netbios name structure. */ -- cgit From aa22586aac02c28aaa5f96e1a03a83fc138c840e Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Mon, 7 Feb 2000 16:28:41 +0000 Subject: make proto ... and the Makefile.in file J.F. --- source/Makefile.in | 12 +- source/include/proto.h | 1015 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 683 insertions(+), 344 deletions(-) diff --git a/source/Makefile.in b/source/Makefile.in index 171dfad337c..5ce92eb61fa 100644 --- a/source/Makefile.in +++ b/source/Makefile.in @@ -41,6 +41,8 @@ NMBLOGFILE = $(VARDIR)/log.nmb CONFIGFILE = $(LIBDIR)/smb.conf LMHOSTSFILE = $(LIBDIR)/lmhosts DRIVERFILE = $(LIBDIR)/printers.def +NTDRIVERSDIR = $(LIBDIR)/ntprinters +FORMSFILE = $(NTDRIVERSDIR)/ntforms.def PASSWD_PROGRAM = /bin/passwd # This is where smbpasswd et al go PRIVATEDIR = @privatedir@ @@ -71,7 +73,7 @@ PASSWD_FLAGS = -DPASSWD_PROGRAM=\"$(PASSWD_PROGRAM)\" -DSMB_PASSWD_FILE=\"$(SMB_ FLAGS1 = $(CFLAGS) -Iinclude -I$(srcdir)/include -I$(srcdir)/ubiqx -I$(srcdir)/smbwrapper $(CPPFLAGS) -DSMBLOGFILE=\"$(SMBLOGFILE)\" -DNMBLOGFILE=\"$(NMBLOGFILE)\" FLAGS2 = -DCONFIGFILE=\"$(CONFIGFILE)\" -DLMHOSTSFILE=\"$(LMHOSTSFILE)\" FLAGS3 = -DSWATDIR=\"$(SWATDIR)\" -DSBINDIR=\"$(SBINDIR)\" -DLOCKDIR=\"$(LOCKDIR)\" -DSMBRUN=\"$(SMBRUN)\" -DCODEPAGEDIR=\"$(CODEPAGEDIR)\" -FLAGS4 = -DDRIVERFILE=\"$(DRIVERFILE)\" -DBINDIR=\"$(BINDIR)\" +FLAGS4 = -DDRIVERFILE=\"$(DRIVERFILE)\" -DBINDIR=\"$(BINDIR)\" -DFORMSFILE=\"$(FORMSFILE)\" -DNTDRIVERSDIR=\"$(NTDRIVERSDIR)\" FLAGS5 = $(FLAGS1) $(FLAGS2) $(FLAGS3) $(FLAGS4) -DHAVE_INCLUDES_H FLAGS = $(ISA) $(FLAGS5) $(PASSWD_FLAGS) FLAGS32 = $(ISA32) $(FLAGS5) $(PASSWD_FLAGS) @@ -116,13 +118,15 @@ RPC_SERVER_OBJ = rpc_server/srv_lsa.o \ rpc_server/srv_pipe_hnd.o rpc_server/srv_reg.o \ rpc_server/srv_samr.o rpc_server/srv_srvsvc.o \ rpc_server/srv_util.o rpc_server/srv_wkssvc.o \ - rpc_server/srv_pipe_srv.o rpc_server/srv_pipe.o + rpc_server/srv_pipe_srv.o rpc_server/srv_pipe.o \ + rpc_server/srv_spoolss.o rpc_server/srv_spoolss_nt.o RPC_PARSE_OBJ = rpc_parse/parse_lsa.o rpc_parse/parse_misc.o \ rpc_parse/parse_net.o rpc_parse/parse_prs.o \ rpc_parse/parse_reg.o rpc_parse/parse_rpc.o \ rpc_parse/parse_samr.o rpc_parse/parse_srv.o \ - rpc_parse/parse_wks.o rpc_parse/parse_sec.o + rpc_parse/parse_wks.o rpc_parse/parse_sec.o \ + rpc_parse/parse_spoolss.o RPC_CLIENT_OBJ = \ rpc_client/cli_login.o \ @@ -151,7 +155,7 @@ SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \ smbd/vfs.o smbd/vfs-wrap.o \ lib/msrpc-client.o lib/msrpc_use.o \ rpc_parse/parse_creds.o \ - smbd/process.o smbd/oplock.o smbd/service.o smbd/error.o + smbd/process.o smbd/oplock.o smbd/service.o smbd/error.o printing/nt_printing.o PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/printing.o \ printing/print_cups.o diff --git a/source/include/proto.h b/source/include/proto.h index 590ca3bf45f..d654af1fa4a 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -186,208 +186,10 @@ void CatchChildLeaveStatus(void); int vslprintf(char *str, int n, char *format, va_list ap); -/*The following definitions come from libsmb/clientgen.c */ - -int cli_set_port(struct cli_state *cli, int port); -char *cli_errstr(struct cli_state *cli); -BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, - uint16 *setup, uint32 setup_count, uint32 max_setup_count, - char *params, uint32 param_count, uint32 max_param_count, - char *data, uint32 data_count, uint32 max_data_count, - char **rparam, uint32 *rparam_count, - char **rdata, uint32 *rdata_count); -BOOL cli_api(struct cli_state *cli, - char *param, int prcnt, int mprcnt, - char *data, int drcnt, int mdrcnt, - char **rparam, int *rprcnt, - char **rdata, int *rdrcnt); -BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation); -BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)); -BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, - void (*fn)(const char *, uint32, const char *)); -BOOL cli_session_setup(struct cli_state *cli, - char *user, - char *pass, int passlen, - char *ntpass, int ntpasslen, - char *workgroup); -BOOL cli_ulogoff(struct cli_state *cli); -BOOL cli_send_tconX(struct cli_state *cli, - char *share, char *dev, char *pass, int passlen); -BOOL cli_tdis(struct cli_state *cli); -BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst); -BOOL cli_unlink(struct cli_state *cli, char *fname); -BOOL cli_mkdir(struct cli_state *cli, char *dname); -BOOL cli_rmdir(struct cli_state *cli, char *dname); -int cli_nt_create(struct cli_state *cli, char *fname); -int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode); -BOOL cli_close(struct cli_state *cli, int fnum); -BOOL cli_lock(struct cli_state *cli, int fnum, - uint32 offset, uint32 len, int timeout, enum brl_type lock_type); -BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len); -size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size); -ssize_t cli_write(struct cli_state *cli, - int fnum, uint16 write_mode, - char *buf, off_t offset, size_t size); -ssize_t cli_smbwrite(struct cli_state *cli, - int fnum, char *buf, off_t offset, size_t size1); -BOOL cli_getattrE(struct cli_state *cli, int fd, - uint16 *attr, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time); -BOOL cli_getatr(struct cli_state *cli, char *fname, - uint16 *attr, size_t *size, time_t *t); -BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t); -BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - size_t *size, uint16 *mode); -BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, size_t *size, uint16 *mode, - SMB_INO_T *ino); -BOOL cli_qfileinfo(struct cli_state *cli, int fnum, - uint16 *mode, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, SMB_INO_T *ino); -int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *)); -BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, - const char *old_password); -BOOL cli_negprot(struct cli_state *cli); -BOOL cli_session_request(struct cli_state *cli, - struct nmb_name *calling, struct nmb_name *called); -BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip); -struct cli_state *cli_initialise(struct cli_state *cli); -void cli_shutdown(struct cli_state *cli); -int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error); -void cli_sockopt(struct cli_state *cli, char *options); -uint16 cli_setpid(struct cli_state *cli, uint16 pid); -BOOL cli_reestablish_connection(struct cli_state *cli); -BOOL cli_establish_connection(struct cli_state *cli, - char *dest_host, struct in_addr *dest_ip, - struct nmb_name *calling, struct nmb_name *called, - char *service, char *service_type, - BOOL do_shutdown, BOOL do_tcon); -int cli_printjob_del(struct cli_state *cli, int job); -int cli_print_queue(struct cli_state *cli, - void (*fn)(struct print_job_info *)); -BOOL cli_chkpath(struct cli_state *cli, char *path); -BOOL cli_message_start(struct cli_state *cli, char *host, char *username, - int *grp); -BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp); -BOOL cli_message_end(struct cli_state *cli, int grp); -BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail); -BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, - struct in_addr *pdest_ip); - -/*The following definitions come from libsmb/credentials.c */ - -char *credstr(uchar *cred); -void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, - uchar session_key[8]); -void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp, - DOM_CHAL *cred); -int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred, - UTIME timestamp); -BOOL clnt_deal_with_creds(uchar sess_key[8], - DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred); -BOOL deal_with_creds(uchar sess_key[8], - DOM_CRED *sto_clnt_cred, - DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred); - -/*The following definitions come from libsmb/namequery.c */ - -BOOL name_status(int fd,char *name,int name_type,BOOL recurse, - struct in_addr to_ip,char *master,char *rname); -struct in_addr *name_query(int fd,const char *name,int name_type, - BOOL bcast,BOOL recurse, - struct in_addr to_ip, int *count); -FILE *startlmhosts(char *fname); -BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr); -void endlmhosts(FILE *fp); -BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type); -BOOL find_master_ip(char *group, struct in_addr *master_ip); -BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name); -BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count); - -/*The following definitions come from libsmb/nmblib.c */ - -void debug_nmb_packet(struct packet_struct *p); -char *nmb_namestr(struct nmb_name *n); -struct packet_struct *copy_packet(struct packet_struct *packet); -void free_packet(struct packet_struct *packet); -struct packet_struct *parse_packet(char *buf,int length, - enum packet_type packet_type); -struct packet_struct *read_packet(int fd,enum packet_type packet_type); -void make_nmb_name( struct nmb_name *n, const char *name, int type); -BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2); -int build_packet(char *buf, struct packet_struct *p); -BOOL send_packet(struct packet_struct *p); -struct packet_struct *receive_packet(int fd,enum packet_type type,int t); -struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id); -struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name); -BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name); -void sort_query_replies(char *data, int n, struct in_addr ip); - -/*The following definitions come from libsmb/nterr.c */ - -char *get_nt_error_msg(uint32 nt_code); - -/*The following definitions come from libsmb/passchange.c */ - -BOOL remote_password_change(const char *remote_machine, const char *user_name, - const char *old_passwd, const char *new_passwd, - char *err_str, size_t err_str_len); - -/*The following definitions come from libsmb/pwd_cache.c */ - -void pwd_init(struct pwd_info *pwd); -void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key); -BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2); -void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt); -void pwd_set_nullpwd(struct pwd_info *pwd); -void pwd_set_cleartext(struct pwd_info *pwd, char *clr); -void pwd_get_cleartext(struct pwd_info *pwd, char *clr); -void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); -void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); -void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr); -void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]); -void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]); - /*The following definitions come from lib/smbrun.c */ int smbrun(char *cmd,char *outfile,BOOL shared); -/*The following definitions come from libsmb/smbdes.c */ - -void E_P16(unsigned char *p14,unsigned char *p16); -void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); -void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out); -void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out); -void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key); -void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key); -void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw); -void SamOEMhash( unsigned char *data, unsigned char *key, int val); - -/*The following definitions come from libsmb/smbencrypt.c */ - -void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24); -void E_md4hash(uchar *passwd, uchar *p16); -void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]); -void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]); -void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]); -void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24); -BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode); - -/*The following definitions come from libsmb/smberr.c */ - -char *smb_errstr(char *inbuf); - -/*The following definitions come from libsmb/unexpected.c */ - -void unexpected_packet(struct packet_struct *p); -void clear_unexpected(time_t t); -struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, - char *mailslot_name); - /*The following definitions come from lib/snprintf.c */ @@ -469,23 +271,6 @@ BOOL map_username(char *user); struct passwd *Get_Pwnam(char *user,BOOL allow_change); BOOL user_in_list(char *user,char *list); -/*The following definitions come from lib/util_array.c */ - -void free_void_array(uint32 num_entries, void **entries, - void(free_item)(void*)); -void* add_copy_to_array(uint32 *len, void ***array, const void *item, - void*(item_dup)(const void*), BOOL alloc_anyway); -void* add_item_to_array(uint32 *len, void ***array, void *item); -void free_use_info_array(uint32 num_entries, struct use_info **entries); -struct use_info* add_use_info_to_array(uint32 *len, struct use_info ***array, - const struct use_info *name); -void free_char_array(uint32 num_entries, char **entries); -char* add_chars_to_array(uint32 *len, char ***array, const char *name); -void free_uint32_array(uint32 num_entries, uint32 **entries); -uint32* add_uint32s_to_array(uint32 *len, uint32 ***array, const uint32 *name); -void free_sid_array(uint32 num_entries, DOM_SID **entries); -DOM_SID* add_sid_to_array(uint32 *len, DOM_SID ***array, const DOM_SID *sid); - /*The following definitions come from lib/util.c */ char *tmpdir(void); @@ -520,6 +305,7 @@ void become_daemon(void); BOOL yesno(char *p); int set_filelen(int fd, SMB_OFF_T len); void *Realloc(void *p,size_t size); +void safe_free(void *p); BOOL get_myname(char *my_name); int interpret_protocol(char *str,int def); BOOL is_ipaddress(const char *str); @@ -562,6 +348,23 @@ char *myhostname(void); char *lock_path(char *name); char *parent_dirname(const char *path); +/*The following definitions come from lib/util_array.c */ + +void free_void_array(uint32 num_entries, void **entries, + void(free_item)(void*)); +void* add_copy_to_array(uint32 *len, void ***array, const void *item, + void*(item_dup)(const void*), BOOL alloc_anyway); +void* add_item_to_array(uint32 *len, void ***array, void *item); +void free_use_info_array(uint32 num_entries, struct use_info **entries); +struct use_info* add_use_info_to_array(uint32 *len, struct use_info ***array, + const struct use_info *name); +void free_char_array(uint32 num_entries, char **entries); +char* add_chars_to_array(uint32 *len, char ***array, const char *name); +void free_uint32_array(uint32 num_entries, uint32 **entries); +uint32* add_uint32s_to_array(uint32 *len, uint32 ***array, const uint32 *name); +void free_sid_array(uint32 num_entries, DOM_SID **entries); +DOM_SID* add_sid_to_array(uint32 *len, DOM_SID ***array, const DOM_SID *sid); + /*The following definitions come from lib/util_file.c */ BOOL do_file_lock(int fd, int waitsecs, int type); @@ -675,10 +478,13 @@ char *string_truncate(char *s, int length); /*The following definitions come from lib/util_unistr.c */ int dos_PutUniCode(char *dst,const char *src, ssize_t len); +void ascii_to_unistr(uint16 *dest, const char *src, int maxlen); +void unistr_to_ascii(char *dest, const uint16 *src, int len); char *skip_unicode_string(char *buf,int n); char *dos_unistrn2(uint16 *src, int len); char *dos_unistr2(uint16 *src); char *dos_unistr2_to_str(UNISTR2 *str); +void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen); uint32 buffer2_to_uint32(BUFFER2 *str); char *dos_buffer2_to_str(BUFFER2 *str); char *dos_buffer2_to_multistr(BUFFER2 *str); @@ -748,6 +554,204 @@ void split_at_last_component_w(smb_ucs2_t *path, smb_ucs2_t *front, smb_ucs2_t s smb_ucs2_t *octal_string_w(int i); smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length); +/*The following definitions come from libsmb/clientgen.c */ + +int cli_set_port(struct cli_state *cli, int port); +char *cli_errstr(struct cli_state *cli); +BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, + uint16 *setup, uint32 setup_count, uint32 max_setup_count, + char *params, uint32 param_count, uint32 max_param_count, + char *data, uint32 data_count, uint32 max_data_count, + char **rparam, uint32 *rparam_count, + char **rdata, uint32 *rdata_count); +BOOL cli_api(struct cli_state *cli, + char *param, int prcnt, int mprcnt, + char *data, int drcnt, int mdrcnt, + char **rparam, int *rprcnt, + char **rdata, int *rdrcnt); +BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation); +BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)); +BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, + void (*fn)(const char *, uint32, const char *)); +BOOL cli_session_setup(struct cli_state *cli, + char *user, + char *pass, int passlen, + char *ntpass, int ntpasslen, + char *workgroup); +BOOL cli_ulogoff(struct cli_state *cli); +BOOL cli_send_tconX(struct cli_state *cli, + char *share, char *dev, char *pass, int passlen); +BOOL cli_tdis(struct cli_state *cli); +BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst); +BOOL cli_unlink(struct cli_state *cli, char *fname); +BOOL cli_mkdir(struct cli_state *cli, char *dname); +BOOL cli_rmdir(struct cli_state *cli, char *dname); +int cli_nt_create(struct cli_state *cli, char *fname); +int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode); +BOOL cli_close(struct cli_state *cli, int fnum); +BOOL cli_lock(struct cli_state *cli, int fnum, + uint32 offset, uint32 len, int timeout, enum brl_type lock_type); +BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len); +size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size); +ssize_t cli_write(struct cli_state *cli, + int fnum, uint16 write_mode, + char *buf, off_t offset, size_t size); +ssize_t cli_smbwrite(struct cli_state *cli, + int fnum, char *buf, off_t offset, size_t size1); +BOOL cli_getattrE(struct cli_state *cli, int fd, + uint16 *attr, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time); +BOOL cli_getatr(struct cli_state *cli, char *fname, + uint16 *attr, size_t *size, time_t *t); +BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t); +BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, + size_t *size, uint16 *mode); +BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, size_t *size, uint16 *mode, + SMB_INO_T *ino); +BOOL cli_qfileinfo(struct cli_state *cli, int fnum, + uint16 *mode, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, SMB_INO_T *ino); +int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, + void (*fn)(file_info *, const char *)); +BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, + const char *old_password); +BOOL cli_negprot(struct cli_state *cli); +BOOL cli_session_request(struct cli_state *cli, + struct nmb_name *calling, struct nmb_name *called); +BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip); +struct cli_state *cli_initialise(struct cli_state *cli); +void cli_shutdown(struct cli_state *cli); +int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error); +void cli_sockopt(struct cli_state *cli, char *options); +uint16 cli_setpid(struct cli_state *cli, uint16 pid); +BOOL cli_reestablish_connection(struct cli_state *cli); +BOOL cli_establish_connection(struct cli_state *cli, + char *dest_host, struct in_addr *dest_ip, + struct nmb_name *calling, struct nmb_name *called, + char *service, char *service_type, + BOOL do_shutdown, BOOL do_tcon); +int cli_printjob_del(struct cli_state *cli, int job); +int cli_print_queue(struct cli_state *cli, + void (*fn)(struct print_job_info *)); +BOOL cli_chkpath(struct cli_state *cli, char *path); +BOOL cli_message_start(struct cli_state *cli, char *host, char *username, + int *grp); +BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp); +BOOL cli_message_end(struct cli_state *cli, int grp); +BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail); +BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, + struct in_addr *pdest_ip); + +/*The following definitions come from libsmb/credentials.c */ + +char *credstr(uchar *cred); +void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, + uchar session_key[8]); +void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp, + DOM_CHAL *cred); +int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred, + UTIME timestamp); +BOOL clnt_deal_with_creds(uchar sess_key[8], + DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred); +BOOL deal_with_creds(uchar sess_key[8], + DOM_CRED *sto_clnt_cred, + DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred); + +/*The following definitions come from libsmb/namequery.c */ + +BOOL name_status(int fd,char *name,int name_type,BOOL recurse, + struct in_addr to_ip,char *master,char *rname); +struct in_addr *name_query(int fd,const char *name,int name_type, + BOOL bcast,BOOL recurse, + struct in_addr to_ip, int *count); +FILE *startlmhosts(char *fname); +BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr); +void endlmhosts(FILE *fp); +BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type); +BOOL find_master_ip(char *group, struct in_addr *master_ip); +BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name); +BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count); + +/*The following definitions come from libsmb/nmblib.c */ + +void debug_nmb_packet(struct packet_struct *p); +char *nmb_namestr(struct nmb_name *n); +struct packet_struct *copy_packet(struct packet_struct *packet); +void free_packet(struct packet_struct *packet); +struct packet_struct *parse_packet(char *buf,int length, + enum packet_type packet_type); +struct packet_struct *read_packet(int fd,enum packet_type packet_type); +void make_nmb_name( struct nmb_name *n, const char *name, int type); +BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2); +int build_packet(char *buf, struct packet_struct *p); +BOOL send_packet(struct packet_struct *p); +struct packet_struct *receive_packet(int fd,enum packet_type type,int t); +struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id); +struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name); +BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name); +void sort_query_replies(char *data, int n, struct in_addr ip); + +/*The following definitions come from libsmb/nterr.c */ + +char *get_nt_error_msg(uint32 nt_code); + +/*The following definitions come from libsmb/passchange.c */ + +BOOL remote_password_change(const char *remote_machine, const char *user_name, + const char *old_passwd, const char *new_passwd, + char *err_str, size_t err_str_len); + +/*The following definitions come from libsmb/pwd_cache.c */ + +void pwd_init(struct pwd_info *pwd); +void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key); +BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2); +void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt); +void pwd_set_nullpwd(struct pwd_info *pwd); +void pwd_set_cleartext(struct pwd_info *pwd, char *clr); +void pwd_get_cleartext(struct pwd_info *pwd, char *clr); +void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); +void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); +void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr); +void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]); +void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]); + +/*The following definitions come from libsmb/smbdes.c */ + +void E_P16(unsigned char *p14,unsigned char *p16); +void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); +void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out); +void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out); +void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key); +void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key); +void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw); +void SamOEMhash( unsigned char *data, unsigned char *key, int val); + +/*The following definitions come from libsmb/smbencrypt.c */ + +void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24); +void E_md4hash(uchar *passwd, uchar *p16); +void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]); +void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]); +void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]); +void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24); +BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode); + +/*The following definitions come from libsmb/smberr.c */ + +char *smb_errstr(char *inbuf); + +/*The following definitions come from libsmb/unexpected.c */ + +void unexpected_packet(struct packet_struct *p); +void clear_unexpected(time_t t); +struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, + char *mailslot_name); + /*The following definitions come from locking/brlock.c */ void brl_init(int read_only); @@ -805,6 +809,10 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question, struct name_record **n); void kill_async_dns_child(void); +/*The following definitions come from nmbd/nmbd.c */ + +BOOL reload_services(BOOL test); + /*The following definitions come from nmbd/nmbd_become_dmb.c */ void add_domain_names(time_t t); @@ -835,10 +843,6 @@ void announce_and_sync_with_domain_master_browser( struct subnet_record *subrec, void collect_all_workgroup_names_from_wins_server(time_t t); void sync_all_dmbs(time_t t); -/*The following definitions come from nmbd/nmbd.c */ - -BOOL reload_services(BOOL test); - /*The following definitions come from nmbd/nmbd_elections.c */ void check_master_browser_exists(time_t t); @@ -1179,6 +1183,8 @@ char *lp_domain_admin_group(void); char *lp_domain_guest_group(void); char *lp_domain_admin_users(void); char *lp_domain_guest_users(void); +char *lp_nt_forms(void); +char *lp_nt_drivers_file(void); char *lp_ldap_server(void); char *lp_ldap_suffix(void); char *lp_ldap_filter(void); @@ -1475,6 +1481,30 @@ BOOL get_trust_account_password( unsigned char *ret_pwd, time_t *pass_last_set_t BOOL set_trust_account_password( unsigned char *md4_new_pwd); BOOL trust_get_passwd( unsigned char trust_passwd[16], char *domain, char *myname); +/*The following definitions come from printing/nt_printing.c */ + +int get_ntforms(nt_forms_struct **list); +int write_ntforms(nt_forms_struct **list, int number); +void add_a_form(nt_forms_struct **list, const FORM *form, int *count); +void update_a_form(nt_forms_struct **list, const FORM *form, int count); +int get_ntdrivers(fstring **list, char *architecture); +void get_short_archi(char *short_archi, char *long_archi); +void dump_a_param(NT_PRINTER_PARAM *param); +BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param); +BOOL unlink_specific_param_if_exist(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param); +uint32 add_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level); +uint32 get_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level, fstring sharename); +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 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, + fstring printername, fstring architecture); +uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level); +BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index, + fstring value, uint8 **data, uint32 *type, uint32 *len); +BOOL get_specific_param(NT_PRINTER_INFO_LEVEL printer, uint32 level, + fstring value, uint8 **data, uint32 *type, uint32 *len); +void init_devicemode(NT_DEVICEMODE *nt_devmode); + /*The following definitions come from printing/pcap.c */ BOOL pcap_printername_ok(char *pszPrintername, char *pszPrintcapname); @@ -1485,6 +1515,11 @@ void pcap_printer_fn(void (*fn)(char *, char *)); void cups_printer_fn(void (*fn)(char *, char *)); int cups_printername_ok(char *name); +/*The following definitions come from printing/print_svid.c */ + +void sysv_printer_fn(void (*fn)(char *, char *)); +int sysv_printername_ok(char *name); + /*The following definitions come from printing/printing.c */ void lpq_reset(int snum); @@ -1499,11 +1534,6 @@ void printjob_decode(int jobid, int *snum, int *job); void status_printqueue(connection_struct *conn,int snum,int status); void load_printers(void); -/*The following definitions come from printing/print_svid.c */ - -void sysv_printer_fn(void (*fn)(char *, char *)); -int sysv_printername_ok(char *name); - /*The following definitions come from profile/profile.c */ BOOL profile_setup(BOOL rdonly); @@ -1669,109 +1699,6 @@ BOOL do_wks_query_info(struct cli_state *cli, char *server_name, uint32 switch_value, WKS_INFO_100 *wks100); -/*The following definitions come from rpcclient/cmd_lsarpc.c */ - -void cmd_lsa_query_info(struct client_info *info); -void cmd_lsa_lookup_sids(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_netlogon.c */ - -void cmd_netlogon_login_test(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_reg.c */ - -void cmd_reg_enum(struct client_info *info); -void cmd_reg_query_key(struct client_info *info); -void cmd_reg_create_val(struct client_info *info); -void cmd_reg_delete_val(struct client_info *info); -void cmd_reg_delete_key(struct client_info *info); -void cmd_reg_create_key(struct client_info *info); -void cmd_reg_test_key_sec(struct client_info *info); -void cmd_reg_get_key_sec(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_samr.c */ - -void cmd_sam_ntchange_pwd(struct client_info *info); -void cmd_sam_test(struct client_info *info); -void cmd_sam_enum_users(struct client_info *info); -void cmd_sam_query_user(struct client_info *info); -void cmd_sam_query_groups(struct client_info *info); -void cmd_sam_enum_aliases(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_srvsvc.c */ - -void cmd_srv_query_info(struct client_info *info); -void cmd_srv_enum_conn(struct client_info *info); -void cmd_srv_enum_shares(struct client_info *info); -void cmd_srv_enum_sess(struct client_info *info); -void cmd_srv_enum_files(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_wkssvc.c */ - -void cmd_wks_query_info(struct client_info *info); - -/*The following definitions come from rpcclient/display.c */ - -char *get_file_mode_str(uint32 share_mode); -char *get_file_oplock_str(uint32 op_type); -char *get_share_type_str(uint32 type); -char *get_server_type_str(uint32 type); -void display_srv_info_101(FILE *out_hnd, enum action_type action, - SRV_INFO_101 *sv101); -void display_srv_info_102(FILE *out_hnd, enum action_type action,SRV_INFO_102 *sv102); -void display_srv_info_ctr(FILE *out_hnd, enum action_type action,SRV_INFO_CTR *ctr); -void display_conn_info_0(FILE *out_hnd, enum action_type action, - CONN_INFO_0 *info0); -void display_conn_info_1(FILE *out_hnd, enum action_type action, - CONN_INFO_1 *info1, CONN_INFO_1_STR *str1); -void display_srv_conn_info_0_ctr(FILE *out_hnd, enum action_type action, - SRV_CONN_INFO_0 *ctr); -void display_srv_conn_info_1_ctr(FILE *out_hnd, enum action_type action, - SRV_CONN_INFO_1 *ctr); -void display_srv_conn_info_ctr(FILE *out_hnd, enum action_type action, - SRV_CONN_INFO_CTR *ctr); -void display_share_info_1(FILE *out_hnd, enum action_type action, - SRV_SHARE_INFO_1 *info1); -void display_share_info_2(FILE *out_hnd, enum action_type action, - SRV_SHARE_INFO_2 *info2); -void display_srv_share_info_ctr(FILE *out_hnd, enum action_type action, - SRV_SHARE_INFO_CTR *ctr); -void display_file_info_3(FILE *out_hnd, enum action_type action, - FILE_INFO_3 *info3, FILE_INFO_3_STR *str3); -void display_srv_file_info_3_ctr(FILE *out_hnd, enum action_type action, - SRV_FILE_INFO_3 *ctr); -void display_srv_file_info_ctr(FILE *out_hnd, enum action_type action, - SRV_FILE_INFO_CTR *ctr); -void display_server(FILE *out_hnd, enum action_type action, - char *sname, uint32 type, char *comment); -void display_share(FILE *out_hnd, enum action_type action, - char *sname, uint32 type, char *comment); -void display_share2(FILE *out_hnd, enum action_type action, - char *sname, uint32 type, char *comment, - uint32 perms, uint32 max_uses, uint32 num_uses, - char *path, char *passwd); -void display_name(FILE *out_hnd, enum action_type action, - char *sname); -void display_group_rid_info(FILE *out_hnd, enum action_type action, - uint32 num_gids, DOM_GID *gid); -void display_alias_name_info(FILE *out_hnd, enum action_type action, - uint32 num_aliases, fstring *alias_name, uint32 *num_als_usrs); -void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_INFO_21 *usr); -char *get_sec_mask_str(uint32 type); -void display_sec_access(FILE *out_hnd, enum action_type action, SEC_ACCESS *info); -void display_sec_ace(FILE *out_hnd, enum action_type action, SEC_ACE *ace); -void display_sec_acl(FILE *out_hnd, enum action_type action, SEC_ACL *sec_acl); -void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *sec); -char *get_reg_val_type_str(uint32 type); -void display_reg_value_info(FILE *out_hnd, enum action_type action, - char *val_name, uint32 val_type, BUFFER2 *value); -void display_reg_key_info(FILE *out_hnd, enum action_type action, - char *key_name, time_t key_mod_time); - -/*The following definitions come from rpcclient/rpcclient.c */ - -void rpcclient_init(void); - /*The following definitions come from rpc_parse/parse_creds.c */ BOOL make_creds_unix(CREDS_UNIX *r_u, const char* user_name, @@ -1883,6 +1810,7 @@ void init_buffer3_str(BUFFER3 *str, char *buf, int len); void init_buffer3_hex(BUFFER3 *str, char *buf); void init_buffer3_bytes(BUFFER3 *str, uint8 *buf, int len); BOOL smb_io_buffer3(char *desc, BUFFER3 *buf3, prs_struct *ps, int depth); +BOOL smb_io_buffer5(char *desc, BUFFER5 *buf5, prs_struct *ps, int depth); void init_buffer2(BUFFER2 *str, uint8 *buf, int len); BOOL smb_io_buffer2(char *desc, BUFFER2 *buf2, uint32 buffer, prs_struct *ps, int depth); void init_buf_unistr2(UNISTR2 *str, uint32 *ptr, char *buf); @@ -2012,14 +1940,18 @@ uint32 prs_data_size(prs_struct *ps); uint32 prs_offset(prs_struct *ps); BOOL prs_set_offset(prs_struct *ps, uint32 offset); BOOL prs_append_prs_data(prs_struct *dst, prs_struct *src); +BOOL prs_append_some_prs_data(prs_struct *dst, prs_struct *src, uint32 len); BOOL prs_append_data(prs_struct *dst, char *src, uint32 len); void prs_set_bigendian_data(prs_struct *ps); BOOL prs_align(prs_struct *ps); char *prs_mem_get(prs_struct *ps, uint32 extra_size); +BOOL prs_switch_type(prs_struct *ps, BOOL io); +void prs_force_dynamic(prs_struct *ps); BOOL prs_uint8(char *name, prs_struct *ps, int depth, uint8 *data8); BOOL prs_uint16(char *name, prs_struct *ps, int depth, uint16 *data16); BOOL prs_uint32(char *name, prs_struct *ps, int depth, uint32 *data32); BOOL prs_uint8s(BOOL charmode, char *name, prs_struct *ps, int depth, uint8 *data8s, int len); +BOOL prs_uint16s(BOOL charmode, char *name, prs_struct *ps, int depth, uint16 *data16s, int len); BOOL prs_uint32s(BOOL charmode, char *name, prs_struct *ps, int depth, uint32 *data32s, int len); BOOL prs_buffer2(BOOL charmode, char *name, prs_struct *ps, int depth, BUFFER2 *str); BOOL prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *str); @@ -2360,6 +2292,147 @@ SEC_DESC_BUF *dup_sec_desc_buf(SEC_DESC_BUF *src); void free_sec_desc_buf(SEC_DESC_BUF **ppsdb); BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth); +/*The following definitions come from rpc_parse/parse_spoolss.c */ + +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, + const char *printername, + uint32 cbbuf, uint32 devmod, uint32 des_access, + const char *station, + const char *username); +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, + POLICY_HND *handle, + char *valuename, + uint32 size); +BOOL spoolss_io_q_getprinterdata(char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_getprinterdata(char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth); +BOOL make_spoolss_q_closeprinter(SPOOL_Q_CLOSEPRINTER *q_u, POLICY_HND *hnd); +BOOL spoolss_io_q_closeprinter(char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_closeprinter(char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_startdocprinter(char *desc, SPOOL_Q_STARTDOCPRINTER *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_startdocprinter(char *desc, SPOOL_R_STARTDOCPRINTER *r_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_enddocprinter(char *desc, SPOOL_Q_ENDDOCPRINTER *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_enddocprinter(char *desc, SPOOL_R_ENDDOCPRINTER *r_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_startpageprinter(char *desc, SPOOL_Q_STARTPAGEPRINTER *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_startpageprinter(char *desc, SPOOL_R_STARTPAGEPRINTER *r_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_endpageprinter(char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_endpageprinter(char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_writeprinter(char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_writeprinter(char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_rffpcnex(char *desc, SPOOL_Q_RFFPCNEX *q_u, + prs_struct *ps, int depth); +BOOL spoolss_io_r_rffpcnex(char *desc, SPOOL_R_RFFPCNEX *r_u, + prs_struct *ps, int depth); +BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u, + prs_struct *ps, int depth); +BOOL spoolss_io_r_rfnpcnex(char *desc, + SPOOL_R_RFNPCNEX *r_u, + prs_struct *ps, int depth); +BOOL new_smb_io_form_1(char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth); +void new_spoolss_move_buffer(NEW_BUFFER *src, NEW_BUFFER **dest); +void new_spoolss_allocate_buffer(NEW_BUFFER **buffer); +void new_spoolss_free_buffer(NEW_BUFFER *buffer); +uint32 new_get_buffer_size(NEW_BUFFER *buffer); +uint32 spoolss_size_form_1(FORM_1 *info); +BOOL spoolss_io_free_buffer(BUFFER *buffer); +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, + const char* servername, + uint32 level, + uint32 size); +BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, + prs_struct *ps, int depth); +void free_r_enumprinters(SPOOL_R_ENUMPRINTERS *r_u); +BOOL 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 make_spoolss_q_getprinter(SPOOL_Q_GETPRINTER *q_u, + POLICY_HND *hnd, + uint32 level, + uint32 buf_size); +BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, + prs_struct *ps, int depth); +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); +BOOL spoolss_io_q_fcpn(char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_addjob(char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth); +void free_job_info_ctr(JOB_INFO_CTR *ctr, uint32 level, uint32 numofjobs); +void free_r_enumjobs(SPOOL_R_ENUMJOBS *r_u); +BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth); +BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd, + uint32 firstjob, + uint32 numofjobs, + uint32 level, + uint32 buf_size); +BOOL spoolss_io_q_enumjobs(char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_schedulejob(char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_schedulejob(char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_setjob(char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_setjob(char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_enumdrivers(char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth); +void free_spoolss_r_enumdrivers(SPOOL_R_ENUMPRINTERDRIVERS *r_u); +BOOL spoolss_io_q_enumprinterdrivers(char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_enumforms(char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth); +BOOL new_spoolss_io_r_enumforms(char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth); +void spoolss_free_r_enumports(SPOOL_R_ENUMPORTS *r_u); +BOOL spoolss_io_q_enumports(char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth); +BOOL spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 **q_u, 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); +BOOL spoolss_io_r_addprinterex(char *desc, SPOOL_R_ADDPRINTEREX *r_u, prs_struct *ps, int depth); +BOOL spool_io_printer_driver_info_level_3(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 **q_u, + prs_struct *ps, int depth); +BOOL uniarray_2_ascarray(BUFFER5 *buf5, char ***ar); +BOOL smb_io_unibuffer(char *desc, UNISTR2 *buffer, prs_struct *ps, int depth); +BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth); +BOOL spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_addprinterdriver(char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth); +BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni, + NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc); +BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni, + NT_PRINTER_INFO_LEVEL_2 **asc); +BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_enumprinterdata(char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_setprinterdata(char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_struct *ps, int depth); +BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value, + uint32 type, const uint8 *data, uint32 len); +BOOL spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_setform(char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_getjob(char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth); +void free_spoolss_r_getjob(SPOOL_R_GETJOB *r_u); +BOOL spoolss_io_q_getjob(char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth); +void free_devmode(DEVICEMODE *devmode); +void free_printer_info_2(PRINTER_INFO_2 *printer); +void free_print2_array(uint32 num_entries, PRINTER_INFO_2 **entries); +void free_print1_array(uint32 num_entries, PRINTER_INFO_1 **entries); +void free_job1_array(uint32 num_entries, JOB_INFO_1 **entries); +void free_job_info_2(JOB_INFO_2 *job); +void free_job2_array(uint32 num_entries, JOB_INFO_2 **entries); + /*The following definitions come from rpc_parse/parse_srv.c */ void init_srv_share_info1_str(SH_INFO_1_STR *sh1, char *net_name, char *remark); @@ -2514,6 +2587,165 @@ BOOL api_reg_rpc(pipes_struct *p, prs_struct *data); BOOL api_samr_rpc(pipes_struct *p, prs_struct *data); +/*The following definitions come from rpc_server/srv_spoolss.c */ + +BOOL api_spoolss_rpc(pipes_struct *p, prs_struct *data); + +/*The following definitions come from rpc_server/srv_spoolss_nt.c */ + +void init_printer_hnd(void); +uint32 _spoolss_open_printer_ex( const UNISTR2 *printername, + const PRINTER_DEFAULT *printer_default, + uint32 user_switch, SPOOL_USER_CTR user_ctr, + POLICY_HND *handle); +uint32 _spoolss_closeprinter(POLICY_HND *handle); +uint32 _spoolss_getprinterdata(const POLICY_HND *handle, UNISTR2 *valuename, + uint32 in_size, + uint32 *type, + uint32 *out_size, + uint8 **data, + uint32 *needed); +uint32 _spoolss_rffpcnex(const POLICY_HND *handle, + uint32 flags, uint32 options, + const UNISTR2 *localmachine, + uint32 printerlocal, + SPOOL_NOTIFY_OPTION *option); +uint32 _spoolss_rfnpcnex( const POLICY_HND *handle, + uint32 change, + const SPOOL_NOTIFY_OPTION *option, + uint32 *count, + SPOOL_NOTIFY_INFO *info); +uint32 _spoolss_enumprinters( + uint32 flags, + const UNISTR2 *servername, + uint32 level, + const BUFFER *buffer, + uint32 buf_size, + uint32 *offered, + uint32 *needed, + PRINTER_INFO_CTR *ctr, + uint32 *returned); +uint32 _spoolss_getprinter( POLICY_HND *handle, + uint32 level, + PRINTER_INFO *ctr, + uint32 *offered, + uint32 *needed); +uint32 _spoolss_getprinterdriver2( const POLICY_HND *handle, + const UNISTR2 *uni_arch, + uint32 level, + DRIVER_INFO *ctr, + uint32 *offered, + uint32 *needed); +uint32 _spoolss_startpageprinter(const POLICY_HND *handle); +uint32 _spoolss_endpageprinter(const POLICY_HND *handle); +uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level, + DOC_INFO *docinfo, uint32 *jobid); +uint32 _spoolss_enddocprinter(const POLICY_HND *handle); +uint32 _spoolss_writeprinter( const POLICY_HND *handle, + uint32 buffer_size, + const uint8 *buffer, + uint32 *buffer_written); +uint32 _spoolss_setprinter( const POLICY_HND *handle, + uint32 level, + const SPOOL_PRINTER_INFO_LEVEL *info, + const DEVICEMODE *devmode, + uint32 sec_buf_size, + const char *sec_buf, + uint32 command); +uint32 _spoolss_fcpn( const POLICY_HND *handle); +uint32 _spoolss_addjob( const POLICY_HND *handle, uint32 level, + const BUFFER *buffer, + uint32 buf_size); +uint32 _spoolss_enumjobs( const POLICY_HND *handle, + uint32 reqfirstjob, + uint32 reqnumofjobs, + uint32 level, + JOB_INFO_CTR *ctr, + uint32 *buf_size, + uint32 *numofjobs); +uint32 _spoolss_schedulejob( const POLICY_HND *handle, uint32 jobid); +uint32 _spoolss_setjob( const POLICY_HND *handle, + uint32 jobid, + uint32 level, + JOB_INFO *ctr, + uint32 command); +uint32 _spoolss_enumprinterdrivers( const UNISTR2 *name, + const UNISTR2 *environment, + uint32 level, + DRIVER_INFO *ctr, + uint32 *offered, + uint32 *numofdrivers); +uint32 _new_spoolss_enumforms( const POLICY_HND *handle, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *numofforms); +uint32 _spoolss_enumforms( const POLICY_HND *handle, + uint32 level, + FORM_1 **forms_1, + uint32 *offered, + uint32 *numofforms); +uint32 _spoolss_enumports( const UNISTR2 *name, + uint32 level, + PORT_INFO_CTR *ctr, + uint32 *offered, + uint32 *numofports); +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_level, + const SPOOL_USER_LEVEL *user, + POLICY_HND *handle); +uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name, + uint32 level, + const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info); +uint32 _spoolss_getprinterdriverdirectory( const UNISTR2 *name, + const UNISTR2 *uni_environment, + uint32 level, + DRIVER_DIRECTORY_CTR *ctr, + uint32 *offered); +uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, + uint32 idx, + uint32 *valuesize, + UNISTR *uni_value, + uint32 *realvaluesize, + uint32 *type, + uint32 *datasize, + uint8 **data, + uint32 *realdatasize); +uint32 _spoolss_setprinterdata( const POLICY_HND *handle, + const UNISTR2 *value, + uint32 type, + uint32 max_len, + const uint8 *data, + uint32 real_len, + uint32 numeric_data); +uint32 _spoolss_addform( const POLICY_HND *handle, + uint32 level, + const FORM *form); +uint32 _spoolss_setform( const POLICY_HND *handle, + const UNISTR2 *uni_name, + uint32 level, + const FORM *form); +uint32 _spoolss_enumprintprocessors(const UNISTR2 *name, + const UNISTR2 *environment, + uint32 level, + PRINTPROCESSOR_1 **info_1, + uint32 *offered, + uint32 *numofprintprocessors); +uint32 _spoolss_enumprintmonitors( const UNISTR2 *name, + uint32 level, + PRINTMONITOR_1 **info_1, + uint32 *offered, + uint32 *numofprintmonitors); +uint32 _spoolss_getjob( const POLICY_HND *handle, + uint32 jobid, + uint32 level, + PJOB_INFO *ctr, + uint32 *offered); + /*The following definitions come from rpc_server/srv_srvsvc.c */ BOOL api_srvsvc_rpc(pipes_struct *p, prs_struct *data); @@ -2533,6 +2765,109 @@ uint32 lookup_user_rid(char *user_name, uint32 *rid); BOOL api_wkssvc_rpc(pipes_struct *p, prs_struct *data); +/*The following definitions come from rpcclient/cmd_lsarpc.c */ + +void cmd_lsa_query_info(struct client_info *info); +void cmd_lsa_lookup_sids(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_netlogon.c */ + +void cmd_netlogon_login_test(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_reg.c */ + +void cmd_reg_enum(struct client_info *info); +void cmd_reg_query_key(struct client_info *info); +void cmd_reg_create_val(struct client_info *info); +void cmd_reg_delete_val(struct client_info *info); +void cmd_reg_delete_key(struct client_info *info); +void cmd_reg_create_key(struct client_info *info); +void cmd_reg_test_key_sec(struct client_info *info); +void cmd_reg_get_key_sec(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_samr.c */ + +void cmd_sam_ntchange_pwd(struct client_info *info); +void cmd_sam_test(struct client_info *info); +void cmd_sam_enum_users(struct client_info *info); +void cmd_sam_query_user(struct client_info *info); +void cmd_sam_query_groups(struct client_info *info); +void cmd_sam_enum_aliases(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_srvsvc.c */ + +void cmd_srv_query_info(struct client_info *info); +void cmd_srv_enum_conn(struct client_info *info); +void cmd_srv_enum_shares(struct client_info *info); +void cmd_srv_enum_sess(struct client_info *info); +void cmd_srv_enum_files(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_wkssvc.c */ + +void cmd_wks_query_info(struct client_info *info); + +/*The following definitions come from rpcclient/display.c */ + +char *get_file_mode_str(uint32 share_mode); +char *get_file_oplock_str(uint32 op_type); +char *get_share_type_str(uint32 type); +char *get_server_type_str(uint32 type); +void display_srv_info_101(FILE *out_hnd, enum action_type action, + SRV_INFO_101 *sv101); +void display_srv_info_102(FILE *out_hnd, enum action_type action,SRV_INFO_102 *sv102); +void display_srv_info_ctr(FILE *out_hnd, enum action_type action,SRV_INFO_CTR *ctr); +void display_conn_info_0(FILE *out_hnd, enum action_type action, + CONN_INFO_0 *info0); +void display_conn_info_1(FILE *out_hnd, enum action_type action, + CONN_INFO_1 *info1, CONN_INFO_1_STR *str1); +void display_srv_conn_info_0_ctr(FILE *out_hnd, enum action_type action, + SRV_CONN_INFO_0 *ctr); +void display_srv_conn_info_1_ctr(FILE *out_hnd, enum action_type action, + SRV_CONN_INFO_1 *ctr); +void display_srv_conn_info_ctr(FILE *out_hnd, enum action_type action, + SRV_CONN_INFO_CTR *ctr); +void display_share_info_1(FILE *out_hnd, enum action_type action, + SRV_SHARE_INFO_1 *info1); +void display_share_info_2(FILE *out_hnd, enum action_type action, + SRV_SHARE_INFO_2 *info2); +void display_srv_share_info_ctr(FILE *out_hnd, enum action_type action, + SRV_SHARE_INFO_CTR *ctr); +void display_file_info_3(FILE *out_hnd, enum action_type action, + FILE_INFO_3 *info3, FILE_INFO_3_STR *str3); +void display_srv_file_info_3_ctr(FILE *out_hnd, enum action_type action, + SRV_FILE_INFO_3 *ctr); +void display_srv_file_info_ctr(FILE *out_hnd, enum action_type action, + SRV_FILE_INFO_CTR *ctr); +void display_server(FILE *out_hnd, enum action_type action, + char *sname, uint32 type, char *comment); +void display_share(FILE *out_hnd, enum action_type action, + char *sname, uint32 type, char *comment); +void display_share2(FILE *out_hnd, enum action_type action, + char *sname, uint32 type, char *comment, + uint32 perms, uint32 max_uses, uint32 num_uses, + char *path, char *passwd); +void display_name(FILE *out_hnd, enum action_type action, + char *sname); +void display_group_rid_info(FILE *out_hnd, enum action_type action, + uint32 num_gids, DOM_GID *gid); +void display_alias_name_info(FILE *out_hnd, enum action_type action, + uint32 num_aliases, fstring *alias_name, uint32 *num_als_usrs); +void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_INFO_21 *usr); +char *get_sec_mask_str(uint32 type); +void display_sec_access(FILE *out_hnd, enum action_type action, SEC_ACCESS *info); +void display_sec_ace(FILE *out_hnd, enum action_type action, SEC_ACE *ace); +void display_sec_acl(FILE *out_hnd, enum action_type action, SEC_ACL *sec_acl); +void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *sec); +char *get_reg_val_type_str(uint32 type); +void display_reg_value_info(FILE *out_hnd, enum action_type action, + char *val_name, uint32 val_type, BUFFER2 *value); +void display_reg_key_info(FILE *out_hnd, enum action_type action, + char *key_name, time_t key_mod_time); + +/*The following definitions come from rpcclient/rpcclient.c */ + +void rpcclient_init(void); + /*The following definitions come from smbd/blocking.c */ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num); @@ -2918,19 +3253,6 @@ BOOL unbecome_authenticated_pipe_user(pipes_struct *p); void become_root(BOOL save_dir) ; void unbecome_root(BOOL restore_dir); -/*The following definitions come from smbd/vfs.c */ - -int vfs_init_default(connection_struct *conn); -BOOL vfs_init_custom(connection_struct *conn); -BOOL vfs_directory_exist(connection_struct *conn, char *dname, - SMB_STRUCT_STAT *st); -BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf); -ssize_t vfs_write_data(files_struct *fsp,char *buffer,size_t N); -SMB_OFF_T vfs_transfer_file(int in_fd, files_struct *in_fsp, - int out_fd, files_struct *out_fsp, - SMB_OFF_T n, char *header, int headlen, int align); -char *vfs_readdirname(connection_struct *conn, void *p); - /*The following definitions come from smbd/vfs-wrap.c */ int vfswrap_dummy_connect(struct vfs_connection_struct *conn, char *service, @@ -2958,6 +3280,19 @@ int vfswrap_unlink(char *path); int vfswrap_chmod(char *path, mode_t mode); int vfswrap_utime(char *path, struct utimbuf *times); +/*The following definitions come from smbd/vfs.c */ + +int vfs_init_default(connection_struct *conn); +BOOL vfs_init_custom(connection_struct *conn); +BOOL vfs_directory_exist(connection_struct *conn, char *dname, + SMB_STRUCT_STAT *st); +BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf); +ssize_t vfs_write_data(files_struct *fsp,char *buffer,size_t N); +SMB_OFF_T vfs_transfer_file(int in_fd, files_struct *in_fsp, + int out_fd, files_struct *out_fsp, + SMB_OFF_T n, char *header, int headlen, int align); +char *vfs_readdirname(connection_struct *conn, void *p); + /*The following definitions come from smbwrapper/realcalls.c */ int real_utime(const char *name, struct utimbuf *buf); -- cgit From 2f544a807714024c0fe2ddc26e11c9ddcb47e81f Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Mon, 7 Feb 2000 18:06:54 +0000 Subject: Hum, I should remove my gloves when I'm in front of an xterm :) fixed a stupid bug in unistr2_to_ascii that I introduced fixed getprinterdata() --- source/lib/util_unistr.c | 4 ++-- source/rpc_parse/parse_spoolss.c | 28 +++++++++++++++--------- source/rpc_server/srv_spoolss_nt.c | 45 ++++++++++++++++++++------------------ 3 files changed, 44 insertions(+), 33 deletions(-) diff --git a/source/lib/util_unistr.c b/source/lib/util_unistr.c index 2c721aeb473..c0701f0427a 100644 --- a/source/lib/util_unistr.c +++ b/source/lib/util_unistr.c @@ -258,13 +258,13 @@ void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen) uint16 ucs2_val; uint16 cp_val; - c = *(src++); + c = *src; if (c == 0) { break; } - ucs2_val = SVAL(src,0); + ucs2_val = SVAL(src++,0); cp_val = ucs2_to_doscp[ucs2_val]; if (cp_val < 256) diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c index a6f72a3181e..de998267b37 100644 --- a/source/rpc_parse/parse_spoolss.c +++ b/source/rpc_parse/parse_spoolss.c @@ -772,22 +772,30 @@ BOOL spoolss_io_q_getprinterdata(char *desc, SPOOL_Q_GETPRINTERDATA *q_u, prs_st ********************************************************************/ BOOL spoolss_io_r_getprinterdata(char *desc, SPOOL_R_GETPRINTERDATA *r_u, prs_struct *ps, int depth) { - if (r_u == NULL) return False; + if (r_u == NULL) + return False; prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdata"); depth++; - prs_align(ps); - prs_uint32("type", ps, depth, &(r_u->type)); - prs_uint32("size", ps, depth, &(r_u->size)); + if (!prs_align(ps)) + return False; + if (!prs_uint32("type", ps, depth, &(r_u->type))) + return False; + if (!prs_uint32("size", ps, depth, &(r_u->size))) + return False; - prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size); - prs_align(ps); + if (!prs_uint8s(False,"data", ps, depth, r_u->data, r_u->size)) + return False; + + if (!prs_align(ps)) + return False; - prs_uint32("needed", ps, depth, &(r_u->needed)); - prs_uint32("status", ps, depth, &(r_u->status)); - prs_align(ps); - + if (!prs_uint32("needed", ps, depth, &(r_u->needed))) + return False; + if (!prs_uint32("status", ps, depth, &(r_u->status))) + return False; + return True; } diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c index db48fa42ff4..d25281cea52 100644 --- a/source/rpc_server/srv_spoolss_nt.c +++ b/source/rpc_server/srv_spoolss_nt.c @@ -537,15 +537,17 @@ uint32 _spoolss_closeprinter(POLICY_HND *handle) /******************************************************************** ********************************************************************/ -static BOOL getprinterdata_printer_server(fstring value, uint32 *type, uint8 **data, uint32 *needed) +static BOOL getprinterdata_printer_server(fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size) { int i; + + DEBUG(8,("getprinterdata_printer_server:%s\n", value)); if (!strcmp(value, "BeepEnabled")) { *type = 0x4; *data = (uint8 *)malloc( 4*sizeof(uint8) ); - SIVAL(data, 0, 0x01); + SIVAL(*data, 0, 0x01); *needed = 0x4; return True; } @@ -554,7 +556,7 @@ static BOOL getprinterdata_printer_server(fstring value, uint32 *type, uint8 **d { *type = 0x4; *data = (uint8 *)malloc( 4*sizeof(uint8) ); - SIVAL(data, 0, 0x1B); + SIVAL(*data, 0, 0x1B); *needed = 0x4; return True; } @@ -563,7 +565,7 @@ static BOOL getprinterdata_printer_server(fstring value, uint32 *type, uint8 **d { *type = 0x4; *data = (uint8 *)malloc( 4*sizeof(uint8) ); - SIVAL(data, 0, 0x01); + SIVAL(*data, 0, 0x01); *needed = 0x4; return True; } @@ -572,23 +574,23 @@ static BOOL getprinterdata_printer_server(fstring value, uint32 *type, uint8 **d { *type = 0x4; *data = (uint8 *)malloc( 4*sizeof(uint8) ); - SIVAL(data, 0, 0x02); + SIVAL(*data, 0, 0x02); *needed = 0x4; return True; } if (!strcmp(value, "DefaultSpoolDirectory")) { - pstring directory="You are using a Samba server"; + pstring string="You are using a Samba server"; *type = 0x1; - *needed = 2*(strlen(directory)+1); - *data = (uint8 *)malloc(*needed *sizeof(uint8)); + *needed = 2*(strlen(string)+1); + *data = (uint8 *)malloc( ((*needed > in_size) ? *needed:in_size) *sizeof(uint8)); ZERO_STRUCTP(*data); /* it's done by hand ready to go on the wire */ - for (i=0; i in_size) ? *needed:in_size) *sizeof(uint8)); ZERO_STRUCTP(*data); - for (i=0; iin_size)?len:in_size *sizeof(uint8) ); bzero(*data, sizeof(uint8)*len); - memcpy(*data, idata, len); + memcpy(*data, idata, (len>in_size)?len:in_size); *needed = len; if (idata) free(idata); @@ -659,7 +661,7 @@ uint32 _spoolss_getprinterdata(const POLICY_HND *handle, UNISTR2 *valuename, uint32 *needed) { fstring value; - BOOL found; + BOOL found=False; int pnum = find_printer_index_by_hnd(handle); /* @@ -675,6 +677,7 @@ uint32 _spoolss_getprinterdata(const POLICY_HND *handle, UNISTR2 *valuename, *needed=in_size; *type=4; + DEBUG(4,("_spoolss_getprinterdata\n")); if (!OPEN_HANDLE(pnum)) { *data=(uint8 *)malloc(4*sizeof(uint8)); @@ -684,9 +687,9 @@ uint32 _spoolss_getprinterdata(const POLICY_HND *handle, UNISTR2 *valuename, unistr2_to_ascii(value, valuename, sizeof(value)-1); if (handle_is_printserver(handle)) - found=getprinterdata_printer_server(value, type, data, needed); + found=getprinterdata_printer_server(value, type, data, needed, *out_size); else - found=getprinterdata_printer(handle, value, type, data, needed); + found=getprinterdata_printer(handle, value, type, data, needed, *out_size); if (found==False) { /* reply this param doesn't exist */ -- cgit From ebcdb4afee04cc3b94e60b1de86c2b534d4e233e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 8 Feb 2000 11:32:43 +0000 Subject: Moved over lib/util_sec (with added fixes) as the HEAD source seems to have drifted a little. Jeremy. --- source/lib/util_sec.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/source/lib/util_sec.c b/source/lib/util_sec.c index 4a2ac2565e6..4306a94191d 100644 --- a/source/lib/util_sec.c +++ b/source/lib/util_sec.c @@ -30,6 +30,8 @@ extern int DEBUGLEVEL; #endif #include #include +#include +#include #ifdef HAVE_SYS_PRIV_H #include @@ -201,9 +203,21 @@ void save_re_uid(void) void restore_re_uid(void) { set_effective_uid(0); + +#if USE_SETRESUID + setresuid(saved_ruid, saved_euid, -1); +#elif USE_SETREUID + setreuid(saved_ruid, -1); + setreuid(-1,saved_euid); +#elif USE_SETUIDX + setuidx(ID_REAL, saved_ruid); + setuidx(ID_EFFECTIVE, saved_euid); +#else set_effective_uid(saved_euid); - if (getuid() != saved_ruid) setuid(saved_ruid); + if (getuid() != saved_ruid) + setuid(saved_ruid); set_effective_uid(saved_euid); +#endif assert_uid(saved_ruid, saved_euid); } @@ -291,6 +305,35 @@ void become_user_permanently(uid_t uid, gid_t gid) assert_gid(gid, gid); } + +/**************************************************************************** +this function just checks that we don't get ENOSYS back +****************************************************************************/ +static int have_syscall(void) +{ + errno = 0; + +#if USE_SETRESUID + setresuid(-1,-1,-1); +#endif + +#if USE_SETREUID + setreuid(-1,-1); +#endif + +#if USE_SETEUID + seteuid(-1); +#endif + +#if USE_SETUIDX + setuidx(ID_EFFECTIVE, -1); +#endif + + if (errno == ENOSYS) return -1; + + return 0; +} + #ifdef AUTOCONF_TEST main() { @@ -301,15 +344,18 @@ main() exit(1); #endif - /* assume that if we have the functions then they work */ - fprintf(stderr,"not running as root: assuming OK\n"); - exit(0); + /* if not running as root then at least check to see if we get ENOSYS - this + handles Linux 2.0.x with glibc 2.1 */ + fprintf(stderr,"not running as root: checking for ENOSYS\n"); + exit(have_syscall()); } gain_root_privilege(); gain_root_group_privilege(); set_effective_gid(1); set_effective_uid(1); + save_re_uid(); + restore_re_uid(); gain_root_privilege(); gain_root_group_privilege(); become_user_permanently(1, 1); -- cgit From 3f77690dade57f4ae9da7196b0aa7a3a43afcc46 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 9 Feb 2000 14:10:08 +0000 Subject: added masktest to head branch, in preparation for another assault on the wildcard handling code --- source/utils/masktest.c | 435 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 435 insertions(+) create mode 100644 source/utils/masktest.c diff --git a/source/utils/masktest.c b/source/utils/masktest.c new file mode 100644 index 00000000000..b4d919fe7c0 --- /dev/null +++ b/source/utils/masktest.c @@ -0,0 +1,435 @@ +/* + Unix SMB/Netbios implementation. + Version 2.0 + mask_match tester + Copyright (C) Andrew Tridgell 1999 + + 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. +*/ + +#define NO_SYSLOG + +#include "includes.h" + +extern int DEBUGLEVEL; +static fstring password; +static fstring username; +static fstring workgroup; +static int got_pass; + +static BOOL showall = False; + +static char *maskchars = "<>\"?*abc."; +static char *filechars = "abcdefghijklm."; + +char *standard_masks[] = {"*", "*.", "*.*", + ".*", "d2.??", "d2\">>", + NULL}; +char *standard_files[] = {"abc", "abc.", ".abc", + "abc.def", "abc.de.f", + "d2.x", + NULL}; + + +#include + +static char *reg_test(char *pattern, char *file) +{ + static fstring ret; + pstring rpattern; + regex_t preg; + + pattern = 1+strrchr(pattern,'\\'); + file = 1+strrchr(file,'\\'); + + fstrcpy(ret,"---"); + + if (strcmp(file,"..") == 0) file = "."; + if (strcmp(pattern,".") == 0) return ret; + + if (strcmp(pattern,"") == 0) { + ret[2] = '+'; + return ret; + } + + pstrcpy(rpattern,"^"); + pstrcat(rpattern, pattern); + + all_string_sub(rpattern,".", "[.]", 0); + all_string_sub(rpattern,"?", ".{1}", 0); + all_string_sub(rpattern,"*", ".*", 0); + all_string_sub(rpattern+strlen(rpattern)-1,">", "([^.]?|[.]?$)", 0); + all_string_sub(rpattern,">", "[^.]?", 0); + + all_string_sub(rpattern,"<[.]", ".*[.]", 0); + all_string_sub(rpattern,"<\"", "(.*[.]|.*$)", 0); + all_string_sub(rpattern,"<", "([^.]*|[^.]*[.]|[.][^.]*|[.].*[.])", 0); + if (strlen(pattern)>1) { + all_string_sub(rpattern+strlen(rpattern)-1,"\"", "[.]?", 0); + } + all_string_sub(rpattern,"\"", "([.]|$)", 0); + pstrcat(rpattern,"$"); + + /* printf("pattern=[%s] rpattern=[%s]\n", pattern, rpattern); */ + + regcomp(&preg, rpattern, REG_ICASE|REG_NOSUB|REG_EXTENDED); + if (regexec(&preg, ".", 0, NULL, 0) == 0) { + ret[0] = '+'; + ret[1] = '+'; + } + if (regexec(&preg, file, 0, NULL, 0) == 0) { + ret[2] = '+'; + } + regfree(&preg); + + return ret; +} + + +/***************************************************** +return a connection to a server +*******************************************************/ +struct cli_state *connect_one(char *share) +{ + struct cli_state *c; + struct nmb_name called, calling; + char *server_n; + char *server; + struct in_addr ip; + extern struct in_addr ipzero; + + server = share+2; + share = strchr(server,'\\'); + if (!share) return NULL; + *share = 0; + share++; + + server_n = server; + + ip = ipzero; + + make_nmb_name(&calling, "masktest", 0x0, ""); + make_nmb_name(&called , server, 0x20, ""); + + again: + ip = ipzero; + + /* have to open a new connection */ + if (!(c=cli_initialise(NULL)) || (cli_set_port(c, 139) == 0) || + !cli_connect(c, server_n, &ip)) { + DEBUG(0,("Connection to %s failed\n", server_n)); + return NULL; + } + + if (!cli_session_request(c, &calling, &called)) { + DEBUG(0,("session request to %s failed\n", called.name)); + cli_shutdown(c); + if (strcmp(called.name, "*SMBSERVER")) { + make_nmb_name(&called , "*SMBSERVER", 0x20, ""); + goto again; + } + return NULL; + } + + DEBUG(4,(" session request ok\n")); + + if (!cli_negprot(c)) { + DEBUG(0,("protocol negotiation failed\n")); + cli_shutdown(c); + return NULL; + } + + if (!got_pass) { + char *pass = getpass("Password: "); + if (pass) { + pstrcpy(password, pass); + } + } + + if (!cli_session_setup(c, username, + password, strlen(password), + password, strlen(password), + workgroup)) { + DEBUG(0,("session setup failed: %s\n", cli_errstr(c))); + return NULL; + } + + /* + * These next two lines are needed to emulate + * old client behaviour for people who have + * scripts based on client output. + * QUESTION ? Do we want to have a 'client compatibility + * mode to turn these on/off ? JRA. + */ + + if (*c->server_domain || *c->server_os || *c->server_type) + DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n", + c->server_domain,c->server_os,c->server_type)); + + DEBUG(4,(" session setup ok\n")); + + if (!cli_send_tconX(c, share, "?????", + password, strlen(password)+1)) { + DEBUG(0,("tree connect failed: %s\n", cli_errstr(c))); + cli_shutdown(c); + return NULL; + } + + DEBUG(4,(" tconx ok\n")); + + return c; +} + +static char *resultp; + +void listfn(file_info *f, const char *s) +{ + if (strcmp(f->name,".") == 0) { + resultp[0] = '+'; + } else if (strcmp(f->name,"..") == 0) { + resultp[1] = '+'; + } else { + resultp[2] = '+'; + } +} + + +static void testpair(struct cli_state *cli1, struct cli_state *cli2, + char *mask, char *file) +{ + int fnum; + fstring res1, res2; + char *res3; + static int count; + + count++; + + fstrcpy(res1, "---"); + fstrcpy(res2, "---"); + + fnum = cli_open(cli1, file, O_CREAT|O_TRUNC|O_RDWR, 0); + if (fnum == -1) { + DEBUG(0,("Can't create %s on cli1\n", file)); + return; + } + cli_close(cli1, fnum); + + fnum = cli_open(cli2, file, O_CREAT|O_TRUNC|O_RDWR, 0); + if (fnum == -1) { + DEBUG(0,("Can't create %s on cli2\n", file)); + return; + } + cli_close(cli2, fnum); + + resultp = res1; + cli_list(cli1, mask, aHIDDEN | aDIR, listfn); + + res3 = reg_test(mask, file); + + resultp = res2; + cli_list(cli2, mask, aHIDDEN | aDIR, listfn); + + if (showall || strcmp(res1, res2)) { + DEBUG(0,("%s %s %s %d mask=[%s] file=[%s]\n", + res1, res2, res3, count, mask, file)); + } + + cli_unlink(cli1, file); + cli_unlink(cli2, file); +} + +static void test_mask(int argc, char *argv[], + struct cli_state *cli1, struct cli_state *cli2) +{ + pstring mask, file; + int l1, l2, i, j, l; + int mc_len = strlen(maskchars); + int fc_len = strlen(filechars); + + cli_mkdir(cli1, "masktest"); + cli_mkdir(cli2, "masktest"); + + cli_unlink(cli1, "\\masktest\\*"); + cli_unlink(cli2, "\\masktest\\*"); + + if (argc >= 2) { + while (argc >= 2) { + pstrcpy(mask,"\\masktest\\"); + pstrcpy(file,"\\masktest\\"); + pstrcat(mask, argv[0]); + pstrcat(file, argv[1]); + testpair(cli1, cli2, mask, file); + argv += 2; + argc -= 2; + } + goto finished; + } + + for (i=0; standard_masks[i]; i++) { + for (j=0; standard_files[j]; j++) { + pstrcpy(mask,"\\masktest\\"); + pstrcpy(file,"\\masktest\\"); + pstrcat(mask, standard_masks[i]); + pstrcat(file, standard_files[j]); + testpair(cli1, cli2, mask, file); + } + } + + while (1) { + l1 = 1 + random() % 20; + l2 = 1 + random() % 20; + pstrcpy(mask,"\\masktest\\"); + pstrcpy(file,"\\masktest\\"); + l = strlen(mask); + for (i=0;i Date: Wed, 9 Feb 2000 14:17:12 +0000 Subject: update masktest for new make_nmb_name() syntax --- source/utils/masktest.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/utils/masktest.c b/source/utils/masktest.c index b4d919fe7c0..380a4d7c712 100644 --- a/source/utils/masktest.c +++ b/source/utils/masktest.c @@ -120,8 +120,8 @@ struct cli_state *connect_one(char *share) ip = ipzero; - make_nmb_name(&calling, "masktest", 0x0, ""); - make_nmb_name(&called , server, 0x20, ""); + make_nmb_name(&calling, "masktest", 0x0); + make_nmb_name(&called , server, 0x20); again: ip = ipzero; @@ -137,7 +137,7 @@ struct cli_state *connect_one(char *share) DEBUG(0,("session request to %s failed\n", called.name)); cli_shutdown(c); if (strcmp(called.name, "*SMBSERVER")) { - make_nmb_name(&called , "*SMBSERVER", 0x20, ""); + make_nmb_name(&called , "*SMBSERVER", 0x20); goto again; } return NULL; -- cgit From 94ed74d5b09d6f28b47b2855c4e4a1dc5c2108d3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Feb 2000 14:45:22 +0000 Subject: Defensive programming for cli_error(). Jeremy. --- source/libsmb/clientgen.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c index c510302301a..b1d8f8aa73f 100644 --- a/source/libsmb/clientgen.c +++ b/source/libsmb/clientgen.c @@ -2685,12 +2685,18 @@ void cli_shutdown(struct cli_state *cli) ****************************************************************************/ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error) { - int flgs2 = SVAL(cli->inbuf,smb_flg2); + int flgs2; char rcls; int code; if (eclass) *eclass = 0; if (num ) *num = 0; + if (nt_rpc_error) *nt_rpc_error = 0; + + if(!cli || !cli->initialised || !cli->inbuf) + return EINVAL; + + flgs2 = SVAL(cli->inbuf,smb_flg2); if (nt_rpc_error) *nt_rpc_error = cli->nt_error; if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { -- cgit From 34b0e2acb050e384c132ddfb50ec84157fb430c6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Feb 2000 15:43:09 +0000 Subject: Correct for for core dump in smbpasswd with cli_errstr(). Jeremy.plit the test for NetBIOS name being *SMBSERVER. --- source/libsmb/clientgen.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c index b1d8f8aa73f..0b669715b91 100644 --- a/source/libsmb/clientgen.c +++ b/source/libsmb/clientgen.c @@ -2693,9 +2693,12 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_ if (num ) *num = 0; if (nt_rpc_error) *nt_rpc_error = 0; - if(!cli || !cli->initialised || !cli->inbuf) + if(cli->initialised) return EINVAL; + if(!cli->inbuf) + return ENOMEM; + flgs2 = SVAL(cli->inbuf,smb_flg2); if (nt_rpc_error) *nt_rpc_error = cli->nt_error; @@ -3225,7 +3228,7 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) ****************************************************************************/ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, - struct in_addr *pdest_ip) + struct in_addr *pdest_ip) { struct nmb_name calling, called; @@ -3244,21 +3247,32 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char if (!cli_session_request(cli, &calling, &called)) { struct nmb_name smbservername; + make_nmb_name(&smbservername , "*SMBSERVER", 0x20); + /* * If the name wasn't *SMBSERVER then * try with *SMBSERVER if the first name fails. */ - cli_shutdown(cli); + if (nmb_name_equal(&called, &smbservername)) { - make_nmb_name(&smbservername , "*SMBSERVER", 0x20); + /* + * The name used was *SMBSERVER, don't bother with another name. + */ + + DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name %s \ +with error %s.\n", desthost, cli_errstr(cli) )); + cli_shutdown(cli); + return False; + } + + cli_shutdown(cli); - if (!nmb_name_equal(&called, &smbservername) || - !cli_initialise(cli) || + if (!cli_initialise(cli) || !cli_connect(cli, desthost, pdest_ip) || !cli_session_request(cli, &calling, &smbservername)) { - DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER.\n", - desthost)); + DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ +name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) )); cli_shutdown(cli); return False; } -- cgit From c8ca70f99ee2eae5e29ddf0dd4bc231fbcd188f2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Feb 2000 15:50:44 +0000 Subject: Fixed wildcard match bug with '****' with smbclient. Found by Andrew (damn him! :-). Jeremy. --- source/lib/util.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/lib/util.c b/source/lib/util.c index a824887e88b..564fc882222 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -1321,8 +1321,9 @@ BOOL mask_match(char *str, char *regexp, BOOL case_sig, BOOL trans2) #endif /* Remove any *? and ** as they are meaningless */ - pstring_sub(t_pattern, "*?", "*"); - pstring_sub(t_pattern, "**", "*"); + for(p = t_pattern; *p; p++) + while( *p == '*' && (p[1] == '?' || p[1] == '*')) + (void)pstrcpy( &p[1], &p[2]); if (strequal(t_pattern,"*")) return(True); -- cgit -- cgit From ef256de9d9a204cf91fe8b636d07400cd0648d1e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2000 13:43:59 +0000 Subject: the beginnings of a fnmatch() based wildcard matching routine --- source/utils/masktest.c | 86 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 66 insertions(+), 20 deletions(-) diff --git a/source/utils/masktest.c b/source/utils/masktest.c index 380a4d7c712..a1fe6d21868 100644 --- a/source/utils/masktest.c +++ b/source/utils/masktest.c @@ -35,7 +35,7 @@ static char *maskchars = "<>\"?*abc."; static char *filechars = "abcdefghijklm."; char *standard_masks[] = {"*", "*.", "*.*", - ".*", "d2.??", "d2\">>", + ".*", "d2.??", "d2\">>", "??", NULL}; char *standard_files[] = {"abc", "abc.", ".abc", "abc.def", "abc.de.f", @@ -45,23 +45,49 @@ char *standard_files[] = {"abc", "abc.", ".abc", #include -static char *reg_test(char *pattern, char *file) +static BOOL reg_match_one(char *pattern, char *file) { - static fstring ret; pstring rpattern; - regex_t preg; + pstring rfile; - pattern = 1+strrchr(pattern,'\\'); - file = 1+strrchr(file,'\\'); + pstrcpy(rpattern, pattern); + + if (strcmp(file,"..") == 0) file = "."; + if (strcmp(rpattern,".") == 0) return False; + + all_string_sub(rpattern,"\"", ".", 0); + all_string_sub(rpattern,"<", "*", 0); + + all_string_sub(rpattern,"*>", "*", 0); + all_string_sub(rpattern,">*", "*", 0); + all_string_sub(rpattern,">", "?", 0); - fstrcpy(ret,"---"); + if (is_8_3(file, False)) { + return fnmatch(rpattern, file, 0)==0; + } + + pstrcpy(rfile, file); + mangle_name_83(rfile); + strlower(rfile); + + return (fnmatch(rpattern, file, 0)==0 || + fnmatch(rpattern, rfile, 0)==0); +} + +static BOOL regex_reg_match_one(char *pattern, char *file) +{ + pstring rpattern; + regex_t preg; + BOOL ret = False; + + return fnmatch(pattern, file, 0)==0; if (strcmp(file,"..") == 0) file = "."; - if (strcmp(pattern,".") == 0) return ret; + if (strcmp(pattern,".") == 0) return False; if (strcmp(pattern,"") == 0) { - ret[2] = '+'; - return ret; + if (strcmp(file,".") == 0) return False; + return True; } pstrcpy(rpattern,"^"); @@ -85,18 +111,27 @@ static char *reg_test(char *pattern, char *file) /* printf("pattern=[%s] rpattern=[%s]\n", pattern, rpattern); */ regcomp(&preg, rpattern, REG_ICASE|REG_NOSUB|REG_EXTENDED); - if (regexec(&preg, ".", 0, NULL, 0) == 0) { - ret[0] = '+'; - ret[1] = '+'; - } - if (regexec(&preg, file, 0, NULL, 0) == 0) { - ret[2] = '+'; - } + ret = (regexec(&preg, file, 0, NULL, 0) == 0); + regfree(&preg); return ret; } +static char *reg_test(char *pattern, char *file) +{ + static fstring ret; + fstrcpy(ret, "---"); + + pattern = 1+strrchr(pattern,'\\'); + file = 1+strrchr(file,'\\'); + + if (reg_match_one(pattern, ".")) ret[0] = '+'; + if (reg_match_one(pattern, "..")) ret[1] = '+'; + if (reg_match_one(pattern, file)) ret[2] = '+'; + return ret; +} + /***************************************************** return a connection to a server @@ -241,13 +276,22 @@ static void testpair(struct cli_state *cli1, struct cli_state *cli2, resultp = res2; cli_list(cli2, mask, aHIDDEN | aDIR, listfn); - if (showall || strcmp(res1, res2)) { - DEBUG(0,("%s %s %s %d mask=[%s] file=[%s]\n", - res1, res2, res3, count, mask, file)); + if (showall || strcmp(res1, res3)) { + char *p; + pstring rfile; + p = strrchr(file,'\\'); + pstrcpy(rfile, p+1); + mangle_name_83(rfile); + strlower(rfile); + DEBUG(0,("%s %s %s %d mask=[%s] file=[%s] mfile=[%s]\n", + res1, res2, res3, count, mask, file, rfile)); } cli_unlink(cli1, file); cli_unlink(cli2, file); + + + if (count % 500 == 0) DEBUG(0,("%d\n", count)); } static void test_mask(int argc, char *argv[], @@ -277,6 +321,7 @@ static void test_mask(int argc, char *argv[], goto finished; } +#if 1 for (i=0; standard_masks[i]; i++) { for (j=0; standard_files[j]; j++) { pstrcpy(mask,"\\masktest\\"); @@ -286,6 +331,7 @@ static void test_mask(int argc, char *argv[], testpair(cli1, cli2, mask, file); } } +#endif while (1) { l1 = 1 + random() % 20; -- cgit From 6c09c0fd9e00036f6da9d29801e885ed3b559c42 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 10 Feb 2000 13:45:52 +0000 Subject: damn, masktest now needs the mangle code from smbd not very clean --- source/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Makefile.in b/source/Makefile.in index 5ce92eb61fa..584fec0b612 100644 --- a/source/Makefile.in +++ b/source/Makefile.in @@ -249,7 +249,7 @@ NMBLOOKUP_OBJ = utils/nmblookup.o $(PARAM_OBJ) $(UBIQX_OBJ) \ SMBTORTURE_OBJ = utils/torture.o utils/nbio.o $(LIBSMB_OBJ) $(PARAM_OBJ) \ $(UBIQX_OBJ) $(LIB_OBJ) -MASKTEST_OBJ = utils/masktest.o $(LIBSMB_OBJ) $(PARAM_OBJ) \ +MASKTEST_OBJ = utils/masktest.o smbd/mangle.o $(LIBSMB_OBJ) $(PARAM_OBJ) \ $(UBIQX_OBJ) $(LIB_OBJ) RPCTORTURE_OBJ = utils/rpctorture.o \ -- cgit From 0babc4baea62aa40e8698ab88b3a95d514c001b6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 14 Feb 2000 21:52:35 +0000 Subject: Ooops. Fixed stupid typo with missing ! in cli error code. Jeremy. --- source/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c index 0b669715b91..d40bfc379a5 100644 --- a/source/libsmb/clientgen.c +++ b/source/libsmb/clientgen.c @@ -2693,7 +2693,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_ if (num ) *num = 0; if (nt_rpc_error) *nt_rpc_error = 0; - if(cli->initialised) + if(!cli->initialised) return EINVAL; if(!cli->inbuf) -- cgit From 156f438bce607236b2d91c28f3dbe8559e048738 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 15 Feb 2000 05:06:53 +0000 Subject: Not enough args to DEBUG statement. --- source/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c index d40bfc379a5..32148a4e124 100644 --- a/source/libsmb/clientgen.c +++ b/source/libsmb/clientgen.c @@ -3261,7 +3261,7 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char */ DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name %s \ -with error %s.\n", desthost, cli_errstr(cli) )); +with error %s.\n", desthost, "*SMBSERVER", cli_errstr(cli) )); cli_shutdown(cli); return False; } -- cgit From ba9f24c0964054f22cd8f0de32cfeacb88b4800c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 15 Feb 2000 06:13:38 +0000 Subject: Return "Invalid tdb context" instead of crashing when tdb_error called with NULL tdb context. --- source/tdb/tdb.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/tdb/tdb.c b/source/tdb/tdb.c index c469436f75d..a754c583e60 100644 --- a/source/tdb/tdb.c +++ b/source/tdb/tdb.c @@ -575,9 +575,13 @@ char *tdb_error(TDB_CONTEXT *tdb) {TDB_ERR_OOM, "Out of memory"}, {TDB_ERR_EXISTS, "Record exists"}, {-1, NULL}}; - for (i=0;emap[i].estring;i++) { + if (tdb != NULL) { + for (i=0;emap[i].estring;i++) { if (tdb->ecode == emap[i].ecode) return emap[i].estring; - } + } + } else { + return "Invalid tdb context"; + } return "Invalid error code"; } -- cgit From 3d6d3863751787b08d40268c83221add1487a5c9 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Tue, 15 Feb 2000 18:07:45 +0000 Subject: fix the reply of rpc_alter_context OpenPrinterEx is now decoding correctly the query most of the EnumXXX use the new_buffer struct. check the (un)marshalling return code. conclusion: still a long way to go. all the client code has to be rewritten, and I still wonder how to implement correctly the notify stuff. --- source/include/proto.h | 783 ++++++++-------- source/include/rpc_spoolss.h | 98 +- source/printing/nt_printing.c | 140 +-- source/rpc_parse/parse_prs.c | 19 +- source/rpc_parse/parse_spoolss.c | 1777 +++++++++++++++++------------------- source/rpc_server/srv_pipe_srv.c | 2 +- source/rpc_server/srv_spoolss.c | 526 ++++++++--- source/rpc_server/srv_spoolss_nt.c | 1229 ++++++++++++++++--------- 8 files changed, 2552 insertions(+), 2022 deletions(-) diff --git a/source/include/proto.h b/source/include/proto.h index d654af1fa4a..7dc0d3e9e62 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -186,10 +186,208 @@ void CatchChildLeaveStatus(void); int vslprintf(char *str, int n, char *format, va_list ap); +/*The following definitions come from libsmb/clientgen.c */ + +int cli_set_port(struct cli_state *cli, int port); +char *cli_errstr(struct cli_state *cli); +BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, + uint16 *setup, uint32 setup_count, uint32 max_setup_count, + char *params, uint32 param_count, uint32 max_param_count, + char *data, uint32 data_count, uint32 max_data_count, + char **rparam, uint32 *rparam_count, + char **rdata, uint32 *rdata_count); +BOOL cli_api(struct cli_state *cli, + char *param, int prcnt, int mprcnt, + char *data, int drcnt, int mdrcnt, + char **rparam, int *rprcnt, + char **rdata, int *rdrcnt); +BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation); +BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)); +BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, + void (*fn)(const char *, uint32, const char *)); +BOOL cli_session_setup(struct cli_state *cli, + char *user, + char *pass, int passlen, + char *ntpass, int ntpasslen, + char *workgroup); +BOOL cli_ulogoff(struct cli_state *cli); +BOOL cli_send_tconX(struct cli_state *cli, + char *share, char *dev, char *pass, int passlen); +BOOL cli_tdis(struct cli_state *cli); +BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst); +BOOL cli_unlink(struct cli_state *cli, char *fname); +BOOL cli_mkdir(struct cli_state *cli, char *dname); +BOOL cli_rmdir(struct cli_state *cli, char *dname); +int cli_nt_create(struct cli_state *cli, char *fname); +int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode); +BOOL cli_close(struct cli_state *cli, int fnum); +BOOL cli_lock(struct cli_state *cli, int fnum, + uint32 offset, uint32 len, int timeout, enum brl_type lock_type); +BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len); +size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size); +ssize_t cli_write(struct cli_state *cli, + int fnum, uint16 write_mode, + char *buf, off_t offset, size_t size); +ssize_t cli_smbwrite(struct cli_state *cli, + int fnum, char *buf, off_t offset, size_t size1); +BOOL cli_getattrE(struct cli_state *cli, int fd, + uint16 *attr, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time); +BOOL cli_getatr(struct cli_state *cli, char *fname, + uint16 *attr, size_t *size, time_t *t); +BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t); +BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, + size_t *size, uint16 *mode); +BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, size_t *size, uint16 *mode, + SMB_INO_T *ino); +BOOL cli_qfileinfo(struct cli_state *cli, int fnum, + uint16 *mode, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, SMB_INO_T *ino); +int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, + void (*fn)(file_info *, const char *)); +BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, + const char *old_password); +BOOL cli_negprot(struct cli_state *cli); +BOOL cli_session_request(struct cli_state *cli, + struct nmb_name *calling, struct nmb_name *called); +BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip); +struct cli_state *cli_initialise(struct cli_state *cli); +void cli_shutdown(struct cli_state *cli); +int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error); +void cli_sockopt(struct cli_state *cli, char *options); +uint16 cli_setpid(struct cli_state *cli, uint16 pid); +BOOL cli_reestablish_connection(struct cli_state *cli); +BOOL cli_establish_connection(struct cli_state *cli, + char *dest_host, struct in_addr *dest_ip, + struct nmb_name *calling, struct nmb_name *called, + char *service, char *service_type, + BOOL do_shutdown, BOOL do_tcon); +int cli_printjob_del(struct cli_state *cli, int job); +int cli_print_queue(struct cli_state *cli, + void (*fn)(struct print_job_info *)); +BOOL cli_chkpath(struct cli_state *cli, char *path); +BOOL cli_message_start(struct cli_state *cli, char *host, char *username, + int *grp); +BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp); +BOOL cli_message_end(struct cli_state *cli, int grp); +BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail); +BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, + struct in_addr *pdest_ip); + +/*The following definitions come from libsmb/credentials.c */ + +char *credstr(uchar *cred); +void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, + uchar session_key[8]); +void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp, + DOM_CHAL *cred); +int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred, + UTIME timestamp); +BOOL clnt_deal_with_creds(uchar sess_key[8], + DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred); +BOOL deal_with_creds(uchar sess_key[8], + DOM_CRED *sto_clnt_cred, + DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred); + +/*The following definitions come from libsmb/namequery.c */ + +BOOL name_status(int fd,char *name,int name_type,BOOL recurse, + struct in_addr to_ip,char *master,char *rname); +struct in_addr *name_query(int fd,const char *name,int name_type, + BOOL bcast,BOOL recurse, + struct in_addr to_ip, int *count); +FILE *startlmhosts(char *fname); +BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr); +void endlmhosts(FILE *fp); +BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type); +BOOL find_master_ip(char *group, struct in_addr *master_ip); +BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name); +BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count); + +/*The following definitions come from libsmb/nmblib.c */ + +void debug_nmb_packet(struct packet_struct *p); +char *nmb_namestr(struct nmb_name *n); +struct packet_struct *copy_packet(struct packet_struct *packet); +void free_packet(struct packet_struct *packet); +struct packet_struct *parse_packet(char *buf,int length, + enum packet_type packet_type); +struct packet_struct *read_packet(int fd,enum packet_type packet_type); +void make_nmb_name( struct nmb_name *n, const char *name, int type); +BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2); +int build_packet(char *buf, struct packet_struct *p); +BOOL send_packet(struct packet_struct *p); +struct packet_struct *receive_packet(int fd,enum packet_type type,int t); +struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id); +struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name); +BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name); +void sort_query_replies(char *data, int n, struct in_addr ip); + +/*The following definitions come from libsmb/nterr.c */ + +char *get_nt_error_msg(uint32 nt_code); + +/*The following definitions come from libsmb/passchange.c */ + +BOOL remote_password_change(const char *remote_machine, const char *user_name, + const char *old_passwd, const char *new_passwd, + char *err_str, size_t err_str_len); + +/*The following definitions come from libsmb/pwd_cache.c */ + +void pwd_init(struct pwd_info *pwd); +void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key); +BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2); +void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt); +void pwd_set_nullpwd(struct pwd_info *pwd); +void pwd_set_cleartext(struct pwd_info *pwd, char *clr); +void pwd_get_cleartext(struct pwd_info *pwd, char *clr); +void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); +void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); +void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr); +void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]); +void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]); + /*The following definitions come from lib/smbrun.c */ int smbrun(char *cmd,char *outfile,BOOL shared); +/*The following definitions come from libsmb/smbdes.c */ + +void E_P16(unsigned char *p14,unsigned char *p16); +void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); +void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out); +void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out); +void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key); +void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key); +void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw); +void SamOEMhash( unsigned char *data, unsigned char *key, int val); + +/*The following definitions come from libsmb/smbencrypt.c */ + +void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24); +void E_md4hash(uchar *passwd, uchar *p16); +void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]); +void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]); +void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]); +void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24); +BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode); + +/*The following definitions come from libsmb/smberr.c */ + +char *smb_errstr(char *inbuf); + +/*The following definitions come from libsmb/unexpected.c */ + +void unexpected_packet(struct packet_struct *p); +void clear_unexpected(time_t t); +struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, + char *mailslot_name); + /*The following definitions come from lib/snprintf.c */ @@ -271,6 +469,23 @@ BOOL map_username(char *user); struct passwd *Get_Pwnam(char *user,BOOL allow_change); BOOL user_in_list(char *user,char *list); +/*The following definitions come from lib/util_array.c */ + +void free_void_array(uint32 num_entries, void **entries, + void(free_item)(void*)); +void* add_copy_to_array(uint32 *len, void ***array, const void *item, + void*(item_dup)(const void*), BOOL alloc_anyway); +void* add_item_to_array(uint32 *len, void ***array, void *item); +void free_use_info_array(uint32 num_entries, struct use_info **entries); +struct use_info* add_use_info_to_array(uint32 *len, struct use_info ***array, + const struct use_info *name); +void free_char_array(uint32 num_entries, char **entries); +char* add_chars_to_array(uint32 *len, char ***array, const char *name); +void free_uint32_array(uint32 num_entries, uint32 **entries); +uint32* add_uint32s_to_array(uint32 *len, uint32 ***array, const uint32 *name); +void free_sid_array(uint32 num_entries, DOM_SID **entries); +DOM_SID* add_sid_to_array(uint32 *len, DOM_SID ***array, const DOM_SID *sid); + /*The following definitions come from lib/util.c */ char *tmpdir(void); @@ -348,23 +563,6 @@ char *myhostname(void); char *lock_path(char *name); char *parent_dirname(const char *path); -/*The following definitions come from lib/util_array.c */ - -void free_void_array(uint32 num_entries, void **entries, - void(free_item)(void*)); -void* add_copy_to_array(uint32 *len, void ***array, const void *item, - void*(item_dup)(const void*), BOOL alloc_anyway); -void* add_item_to_array(uint32 *len, void ***array, void *item); -void free_use_info_array(uint32 num_entries, struct use_info **entries); -struct use_info* add_use_info_to_array(uint32 *len, struct use_info ***array, - const struct use_info *name); -void free_char_array(uint32 num_entries, char **entries); -char* add_chars_to_array(uint32 *len, char ***array, const char *name); -void free_uint32_array(uint32 num_entries, uint32 **entries); -uint32* add_uint32s_to_array(uint32 *len, uint32 ***array, const uint32 *name); -void free_sid_array(uint32 num_entries, DOM_SID **entries); -DOM_SID* add_sid_to_array(uint32 *len, DOM_SID ***array, const DOM_SID *sid); - /*The following definitions come from lib/util_file.c */ BOOL do_file_lock(int fd, int waitsecs, int type); @@ -554,204 +752,6 @@ void split_at_last_component_w(smb_ucs2_t *path, smb_ucs2_t *front, smb_ucs2_t s smb_ucs2_t *octal_string_w(int i); smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length); -/*The following definitions come from libsmb/clientgen.c */ - -int cli_set_port(struct cli_state *cli, int port); -char *cli_errstr(struct cli_state *cli); -BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, - uint16 *setup, uint32 setup_count, uint32 max_setup_count, - char *params, uint32 param_count, uint32 max_param_count, - char *data, uint32 data_count, uint32 max_data_count, - char **rparam, uint32 *rparam_count, - char **rdata, uint32 *rdata_count); -BOOL cli_api(struct cli_state *cli, - char *param, int prcnt, int mprcnt, - char *data, int drcnt, int mdrcnt, - char **rparam, int *rprcnt, - char **rdata, int *rdrcnt); -BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation); -BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)); -BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, - void (*fn)(const char *, uint32, const char *)); -BOOL cli_session_setup(struct cli_state *cli, - char *user, - char *pass, int passlen, - char *ntpass, int ntpasslen, - char *workgroup); -BOOL cli_ulogoff(struct cli_state *cli); -BOOL cli_send_tconX(struct cli_state *cli, - char *share, char *dev, char *pass, int passlen); -BOOL cli_tdis(struct cli_state *cli); -BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst); -BOOL cli_unlink(struct cli_state *cli, char *fname); -BOOL cli_mkdir(struct cli_state *cli, char *dname); -BOOL cli_rmdir(struct cli_state *cli, char *dname); -int cli_nt_create(struct cli_state *cli, char *fname); -int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode); -BOOL cli_close(struct cli_state *cli, int fnum); -BOOL cli_lock(struct cli_state *cli, int fnum, - uint32 offset, uint32 len, int timeout, enum brl_type lock_type); -BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len); -size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size); -ssize_t cli_write(struct cli_state *cli, - int fnum, uint16 write_mode, - char *buf, off_t offset, size_t size); -ssize_t cli_smbwrite(struct cli_state *cli, - int fnum, char *buf, off_t offset, size_t size1); -BOOL cli_getattrE(struct cli_state *cli, int fd, - uint16 *attr, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time); -BOOL cli_getatr(struct cli_state *cli, char *fname, - uint16 *attr, size_t *size, time_t *t); -BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t); -BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - size_t *size, uint16 *mode); -BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, size_t *size, uint16 *mode, - SMB_INO_T *ino); -BOOL cli_qfileinfo(struct cli_state *cli, int fnum, - uint16 *mode, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, SMB_INO_T *ino); -int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *)); -BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, - const char *old_password); -BOOL cli_negprot(struct cli_state *cli); -BOOL cli_session_request(struct cli_state *cli, - struct nmb_name *calling, struct nmb_name *called); -BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip); -struct cli_state *cli_initialise(struct cli_state *cli); -void cli_shutdown(struct cli_state *cli); -int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error); -void cli_sockopt(struct cli_state *cli, char *options); -uint16 cli_setpid(struct cli_state *cli, uint16 pid); -BOOL cli_reestablish_connection(struct cli_state *cli); -BOOL cli_establish_connection(struct cli_state *cli, - char *dest_host, struct in_addr *dest_ip, - struct nmb_name *calling, struct nmb_name *called, - char *service, char *service_type, - BOOL do_shutdown, BOOL do_tcon); -int cli_printjob_del(struct cli_state *cli, int job); -int cli_print_queue(struct cli_state *cli, - void (*fn)(struct print_job_info *)); -BOOL cli_chkpath(struct cli_state *cli, char *path); -BOOL cli_message_start(struct cli_state *cli, char *host, char *username, - int *grp); -BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp); -BOOL cli_message_end(struct cli_state *cli, int grp); -BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail); -BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, - struct in_addr *pdest_ip); - -/*The following definitions come from libsmb/credentials.c */ - -char *credstr(uchar *cred); -void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, - uchar session_key[8]); -void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp, - DOM_CHAL *cred); -int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred, - UTIME timestamp); -BOOL clnt_deal_with_creds(uchar sess_key[8], - DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred); -BOOL deal_with_creds(uchar sess_key[8], - DOM_CRED *sto_clnt_cred, - DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred); - -/*The following definitions come from libsmb/namequery.c */ - -BOOL name_status(int fd,char *name,int name_type,BOOL recurse, - struct in_addr to_ip,char *master,char *rname); -struct in_addr *name_query(int fd,const char *name,int name_type, - BOOL bcast,BOOL recurse, - struct in_addr to_ip, int *count); -FILE *startlmhosts(char *fname); -BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr); -void endlmhosts(FILE *fp); -BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type); -BOOL find_master_ip(char *group, struct in_addr *master_ip); -BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name); -BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count); - -/*The following definitions come from libsmb/nmblib.c */ - -void debug_nmb_packet(struct packet_struct *p); -char *nmb_namestr(struct nmb_name *n); -struct packet_struct *copy_packet(struct packet_struct *packet); -void free_packet(struct packet_struct *packet); -struct packet_struct *parse_packet(char *buf,int length, - enum packet_type packet_type); -struct packet_struct *read_packet(int fd,enum packet_type packet_type); -void make_nmb_name( struct nmb_name *n, const char *name, int type); -BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2); -int build_packet(char *buf, struct packet_struct *p); -BOOL send_packet(struct packet_struct *p); -struct packet_struct *receive_packet(int fd,enum packet_type type,int t); -struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id); -struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name); -BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name); -void sort_query_replies(char *data, int n, struct in_addr ip); - -/*The following definitions come from libsmb/nterr.c */ - -char *get_nt_error_msg(uint32 nt_code); - -/*The following definitions come from libsmb/passchange.c */ - -BOOL remote_password_change(const char *remote_machine, const char *user_name, - const char *old_passwd, const char *new_passwd, - char *err_str, size_t err_str_len); - -/*The following definitions come from libsmb/pwd_cache.c */ - -void pwd_init(struct pwd_info *pwd); -void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key); -BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2); -void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt); -void pwd_set_nullpwd(struct pwd_info *pwd); -void pwd_set_cleartext(struct pwd_info *pwd, char *clr); -void pwd_get_cleartext(struct pwd_info *pwd, char *clr); -void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); -void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); -void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr); -void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]); -void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]); - -/*The following definitions come from libsmb/smbdes.c */ - -void E_P16(unsigned char *p14,unsigned char *p16); -void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); -void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out); -void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out); -void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key); -void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key); -void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw); -void SamOEMhash( unsigned char *data, unsigned char *key, int val); - -/*The following definitions come from libsmb/smbencrypt.c */ - -void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24); -void E_md4hash(uchar *passwd, uchar *p16); -void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]); -void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]); -void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]); -void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24); -BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode); - -/*The following definitions come from libsmb/smberr.c */ - -char *smb_errstr(char *inbuf); - -/*The following definitions come from libsmb/unexpected.c */ - -void unexpected_packet(struct packet_struct *p); -void clear_unexpected(time_t t); -struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, - char *mailslot_name); - /*The following definitions come from locking/brlock.c */ void brl_init(int read_only); @@ -809,10 +809,6 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question, struct name_record **n); void kill_async_dns_child(void); -/*The following definitions come from nmbd/nmbd.c */ - -BOOL reload_services(BOOL test); - /*The following definitions come from nmbd/nmbd_become_dmb.c */ void add_domain_names(time_t t); @@ -843,6 +839,10 @@ void announce_and_sync_with_domain_master_browser( struct subnet_record *subrec, void collect_all_workgroup_names_from_wins_server(time_t t); void sync_all_dmbs(time_t t); +/*The following definitions come from nmbd/nmbd.c */ + +BOOL reload_services(BOOL test); + /*The following definitions come from nmbd/nmbd_elections.c */ void check_master_browser_exists(time_t t); @@ -1515,11 +1515,6 @@ void pcap_printer_fn(void (*fn)(char *, char *)); void cups_printer_fn(void (*fn)(char *, char *)); int cups_printername_ok(char *name); -/*The following definitions come from printing/print_svid.c */ - -void sysv_printer_fn(void (*fn)(char *, char *)); -int sysv_printername_ok(char *name); - /*The following definitions come from printing/printing.c */ void lpq_reset(int snum); @@ -1534,6 +1529,11 @@ void printjob_decode(int jobid, int *snum, int *job); void status_printqueue(connection_struct *conn,int snum,int status); void load_printers(void); +/*The following definitions come from printing/print_svid.c */ + +void sysv_printer_fn(void (*fn)(char *, char *)); +int sysv_printername_ok(char *name); + /*The following definitions come from profile/profile.c */ BOOL profile_setup(BOOL rdonly); @@ -1699,6 +1699,109 @@ BOOL do_wks_query_info(struct cli_state *cli, char *server_name, uint32 switch_value, WKS_INFO_100 *wks100); +/*The following definitions come from rpcclient/cmd_lsarpc.c */ + +void cmd_lsa_query_info(struct client_info *info); +void cmd_lsa_lookup_sids(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_netlogon.c */ + +void cmd_netlogon_login_test(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_reg.c */ + +void cmd_reg_enum(struct client_info *info); +void cmd_reg_query_key(struct client_info *info); +void cmd_reg_create_val(struct client_info *info); +void cmd_reg_delete_val(struct client_info *info); +void cmd_reg_delete_key(struct client_info *info); +void cmd_reg_create_key(struct client_info *info); +void cmd_reg_test_key_sec(struct client_info *info); +void cmd_reg_get_key_sec(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_samr.c */ + +void cmd_sam_ntchange_pwd(struct client_info *info); +void cmd_sam_test(struct client_info *info); +void cmd_sam_enum_users(struct client_info *info); +void cmd_sam_query_user(struct client_info *info); +void cmd_sam_query_groups(struct client_info *info); +void cmd_sam_enum_aliases(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_srvsvc.c */ + +void cmd_srv_query_info(struct client_info *info); +void cmd_srv_enum_conn(struct client_info *info); +void cmd_srv_enum_shares(struct client_info *info); +void cmd_srv_enum_sess(struct client_info *info); +void cmd_srv_enum_files(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_wkssvc.c */ + +void cmd_wks_query_info(struct client_info *info); + +/*The following definitions come from rpcclient/display.c */ + +char *get_file_mode_str(uint32 share_mode); +char *get_file_oplock_str(uint32 op_type); +char *get_share_type_str(uint32 type); +char *get_server_type_str(uint32 type); +void display_srv_info_101(FILE *out_hnd, enum action_type action, + SRV_INFO_101 *sv101); +void display_srv_info_102(FILE *out_hnd, enum action_type action,SRV_INFO_102 *sv102); +void display_srv_info_ctr(FILE *out_hnd, enum action_type action,SRV_INFO_CTR *ctr); +void display_conn_info_0(FILE *out_hnd, enum action_type action, + CONN_INFO_0 *info0); +void display_conn_info_1(FILE *out_hnd, enum action_type action, + CONN_INFO_1 *info1, CONN_INFO_1_STR *str1); +void display_srv_conn_info_0_ctr(FILE *out_hnd, enum action_type action, + SRV_CONN_INFO_0 *ctr); +void display_srv_conn_info_1_ctr(FILE *out_hnd, enum action_type action, + SRV_CONN_INFO_1 *ctr); +void display_srv_conn_info_ctr(FILE *out_hnd, enum action_type action, + SRV_CONN_INFO_CTR *ctr); +void display_share_info_1(FILE *out_hnd, enum action_type action, + SRV_SHARE_INFO_1 *info1); +void display_share_info_2(FILE *out_hnd, enum action_type action, + SRV_SHARE_INFO_2 *info2); +void display_srv_share_info_ctr(FILE *out_hnd, enum action_type action, + SRV_SHARE_INFO_CTR *ctr); +void display_file_info_3(FILE *out_hnd, enum action_type action, + FILE_INFO_3 *info3, FILE_INFO_3_STR *str3); +void display_srv_file_info_3_ctr(FILE *out_hnd, enum action_type action, + SRV_FILE_INFO_3 *ctr); +void display_srv_file_info_ctr(FILE *out_hnd, enum action_type action, + SRV_FILE_INFO_CTR *ctr); +void display_server(FILE *out_hnd, enum action_type action, + char *sname, uint32 type, char *comment); +void display_share(FILE *out_hnd, enum action_type action, + char *sname, uint32 type, char *comment); +void display_share2(FILE *out_hnd, enum action_type action, + char *sname, uint32 type, char *comment, + uint32 perms, uint32 max_uses, uint32 num_uses, + char *path, char *passwd); +void display_name(FILE *out_hnd, enum action_type action, + char *sname); +void display_group_rid_info(FILE *out_hnd, enum action_type action, + uint32 num_gids, DOM_GID *gid); +void display_alias_name_info(FILE *out_hnd, enum action_type action, + uint32 num_aliases, fstring *alias_name, uint32 *num_als_usrs); +void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_INFO_21 *usr); +char *get_sec_mask_str(uint32 type); +void display_sec_access(FILE *out_hnd, enum action_type action, SEC_ACCESS *info); +void display_sec_ace(FILE *out_hnd, enum action_type action, SEC_ACE *ace); +void display_sec_acl(FILE *out_hnd, enum action_type action, SEC_ACL *sec_acl); +void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *sec); +char *get_reg_val_type_str(uint32 type); +void display_reg_value_info(FILE *out_hnd, enum action_type action, + char *val_name, uint32 val_type, BUFFER2 *value); +void display_reg_key_info(FILE *out_hnd, enum action_type action, + char *key_name, time_t key_mod_time); + +/*The following definitions come from rpcclient/rpcclient.c */ + +void rpcclient_init(void); + /*The following definitions come from rpc_parse/parse_creds.c */ BOOL make_creds_unix(CREDS_UNIX *r_u, const char* user_name, @@ -1940,7 +2043,7 @@ uint32 prs_data_size(prs_struct *ps); uint32 prs_offset(prs_struct *ps); BOOL prs_set_offset(prs_struct *ps, uint32 offset); BOOL prs_append_prs_data(prs_struct *dst, prs_struct *src); -BOOL prs_append_some_prs_data(prs_struct *dst, prs_struct *src, uint32 len); +BOOL prs_append_some_prs_data(prs_struct *dst, prs_struct *src, int32 start, uint32 len); BOOL prs_append_data(prs_struct *dst, char *src, uint32 len); void prs_set_bigendian_data(prs_struct *ps); BOOL prs_align(prs_struct *ps); @@ -2332,12 +2435,36 @@ BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u, BOOL spoolss_io_r_rfnpcnex(char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth); +BOOL new_smb_io_printer_info_1(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info, int depth); +BOOL new_smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth); +BOOL new_smb_io_printer_driver_info_1(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) ; +BOOL new_smb_io_printer_driver_info_2(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) ; +BOOL new_smb_io_printer_driver_info_3(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_3 *info, int depth); +BOOL new_smb_io_job_info_1(char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, int depth); +BOOL new_smb_io_job_info_2(char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, int depth); BOOL new_smb_io_form_1(char *desc, NEW_BUFFER *buffer, FORM_1 *info, int depth); void new_spoolss_move_buffer(NEW_BUFFER *src, NEW_BUFFER **dest); void new_spoolss_allocate_buffer(NEW_BUFFER **buffer); void new_spoolss_free_buffer(NEW_BUFFER *buffer); uint32 new_get_buffer_size(NEW_BUFFER *buffer); +BOOL new_smb_io_port_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth); +BOOL new_smb_io_port_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth); +BOOL smb_io_printprocessor_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth); +BOOL smb_io_printmonitor_info_1(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_1 *info, int depth); +BOOL smb_io_printmonitor_info_2(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *info, int depth); +uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info); +uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info); +uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info); +uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info); +uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info); +uint32 spoolss_size_job_info_1(JOB_INFO_1 *info); +uint32 spoolss_size_job_info_2(JOB_INFO_2 *info); uint32 spoolss_size_form_1(FORM_1 *info); +uint32 spoolss_size_port_info_1(PORT_INFO_1 *info); +uint32 spoolss_size_port_info_2(PORT_INFO_2 *info); +uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info); +uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info); +uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info); BOOL spoolss_io_free_buffer(BUFFER *buffer); BOOL spoolss_io_q_getprinterdriver2(char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, @@ -2351,10 +2478,7 @@ BOOL make_spoolss_q_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u, uint32 size); BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth); -void free_r_enumprinters(SPOOL_R_ENUMPRINTERS *r_u); -BOOL spoolss_io_r_enumprinters(char *desc, - SPOOL_R_ENUMPRINTERS *r_u, - prs_struct *ps, int depth); +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); @@ -2370,8 +2494,6 @@ BOOL spoolss_io_r_fcpn(char *desc, SPOOL_R_FCPN *r_u, prs_struct *ps, int depth) BOOL spoolss_io_q_fcpn(char *desc, SPOOL_Q_FCPN *q_u, prs_struct *ps, int depth); BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_addjob(char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth); -void free_job_info_ctr(JOB_INFO_CTR *ctr, uint32 level, uint32 numofjobs); -void free_r_enumjobs(SPOOL_R_ENUMJOBS *r_u); BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth); BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd, uint32 firstjob, @@ -2383,13 +2505,11 @@ BOOL spoolss_io_r_schedulejob(char *desc, SPOOL_R_SCHEDULEJOB *r_u, prs_struct * BOOL spoolss_io_q_schedulejob(char *desc, SPOOL_Q_SCHEDULEJOB *q_u, prs_struct *ps, int depth); BOOL spoolss_io_r_setjob(char *desc, SPOOL_R_SETJOB *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_setjob(char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int depth); -BOOL spoolss_io_r_enumdrivers(char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth); -void free_spoolss_r_enumdrivers(SPOOL_R_ENUMPRINTERDRIVERS *r_u); +BOOL new_spoolss_io_r_enumprinterdrivers(char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_enumprinterdrivers(char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth); BOOL spoolss_io_q_enumforms(char *desc, SPOOL_Q_ENUMFORMS *q_u, prs_struct *ps, int depth); BOOL new_spoolss_io_r_enumforms(char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct *ps, int depth); -BOOL spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth); -void spoolss_free_r_enumports(SPOOL_R_ENUMPORTS *r_u); +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_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 **q_u, prs_struct *ps, int depth); BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth); @@ -2410,8 +2530,8 @@ BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth); BOOL spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth); -BOOL spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth); BOOL spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_enumprinterdata(char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_struct *ps, int depth); BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth); @@ -2615,16 +2735,9 @@ uint32 _spoolss_rfnpcnex( const POLICY_HND *handle, const SPOOL_NOTIFY_OPTION *option, uint32 *count, SPOOL_NOTIFY_INFO *info); -uint32 _spoolss_enumprinters( - uint32 flags, - const UNISTR2 *servername, - uint32 level, - const BUFFER *buffer, - uint32 buf_size, - uint32 *offered, - uint32 *needed, - PRINTER_INFO_CTR *ctr, - uint32 *returned); +uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned); uint32 _spoolss_getprinter( POLICY_HND *handle, uint32 level, PRINTER_INFO *ctr, @@ -2656,38 +2769,24 @@ uint32 _spoolss_fcpn( const POLICY_HND *handle); uint32 _spoolss_addjob( const POLICY_HND *handle, uint32 level, const BUFFER *buffer, uint32 buf_size); -uint32 _spoolss_enumjobs( const POLICY_HND *handle, - uint32 reqfirstjob, - uint32 reqnumofjobs, - uint32 level, - JOB_INFO_CTR *ctr, - uint32 *buf_size, - uint32 *numofjobs); +uint32 _spoolss_enumjobs( POLICY_HND *handle, uint32 firstjob, uint32 numofjobs, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned); uint32 _spoolss_schedulejob( const POLICY_HND *handle, uint32 jobid); uint32 _spoolss_setjob( const POLICY_HND *handle, uint32 jobid, uint32 level, JOB_INFO *ctr, uint32 command); -uint32 _spoolss_enumprinterdrivers( const UNISTR2 *name, - const UNISTR2 *environment, - uint32 level, - DRIVER_INFO *ctr, - uint32 *offered, - uint32 *numofdrivers); +uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned); uint32 _new_spoolss_enumforms( const POLICY_HND *handle, uint32 level, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *numofforms); -uint32 _spoolss_enumforms( const POLICY_HND *handle, - uint32 level, - FORM_1 **forms_1, - uint32 *offered, - uint32 *numofforms); -uint32 _spoolss_enumports( const UNISTR2 *name, - uint32 level, - PORT_INFO_CTR *ctr, - uint32 *offered, - uint32 *numofports); +uint32 _spoolss_enumports( UNISTR2 *name, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned); uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level, const SPOOL_PRINTER_INFO_LEVEL *info, @@ -2729,17 +2828,12 @@ uint32 _spoolss_setform( const POLICY_HND *handle, const UNISTR2 *uni_name, uint32 level, const FORM *form); -uint32 _spoolss_enumprintprocessors(const UNISTR2 *name, - const UNISTR2 *environment, - uint32 level, - PRINTPROCESSOR_1 **info_1, - uint32 *offered, - uint32 *numofprintprocessors); -uint32 _spoolss_enumprintmonitors( const UNISTR2 *name, - uint32 level, - PRINTMONITOR_1 **info_1, - uint32 *offered, - uint32 *numofprintmonitors); +uint32 _spoolss_enumprintprocessors(UNISTR2 *name, UNISTR2 *environment, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned); +uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned); uint32 _spoolss_getjob( const POLICY_HND *handle, uint32 jobid, uint32 level, @@ -2765,109 +2859,6 @@ uint32 lookup_user_rid(char *user_name, uint32 *rid); BOOL api_wkssvc_rpc(pipes_struct *p, prs_struct *data); -/*The following definitions come from rpcclient/cmd_lsarpc.c */ - -void cmd_lsa_query_info(struct client_info *info); -void cmd_lsa_lookup_sids(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_netlogon.c */ - -void cmd_netlogon_login_test(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_reg.c */ - -void cmd_reg_enum(struct client_info *info); -void cmd_reg_query_key(struct client_info *info); -void cmd_reg_create_val(struct client_info *info); -void cmd_reg_delete_val(struct client_info *info); -void cmd_reg_delete_key(struct client_info *info); -void cmd_reg_create_key(struct client_info *info); -void cmd_reg_test_key_sec(struct client_info *info); -void cmd_reg_get_key_sec(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_samr.c */ - -void cmd_sam_ntchange_pwd(struct client_info *info); -void cmd_sam_test(struct client_info *info); -void cmd_sam_enum_users(struct client_info *info); -void cmd_sam_query_user(struct client_info *info); -void cmd_sam_query_groups(struct client_info *info); -void cmd_sam_enum_aliases(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_srvsvc.c */ - -void cmd_srv_query_info(struct client_info *info); -void cmd_srv_enum_conn(struct client_info *info); -void cmd_srv_enum_shares(struct client_info *info); -void cmd_srv_enum_sess(struct client_info *info); -void cmd_srv_enum_files(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_wkssvc.c */ - -void cmd_wks_query_info(struct client_info *info); - -/*The following definitions come from rpcclient/display.c */ - -char *get_file_mode_str(uint32 share_mode); -char *get_file_oplock_str(uint32 op_type); -char *get_share_type_str(uint32 type); -char *get_server_type_str(uint32 type); -void display_srv_info_101(FILE *out_hnd, enum action_type action, - SRV_INFO_101 *sv101); -void display_srv_info_102(FILE *out_hnd, enum action_type action,SRV_INFO_102 *sv102); -void display_srv_info_ctr(FILE *out_hnd, enum action_type action,SRV_INFO_CTR *ctr); -void display_conn_info_0(FILE *out_hnd, enum action_type action, - CONN_INFO_0 *info0); -void display_conn_info_1(FILE *out_hnd, enum action_type action, - CONN_INFO_1 *info1, CONN_INFO_1_STR *str1); -void display_srv_conn_info_0_ctr(FILE *out_hnd, enum action_type action, - SRV_CONN_INFO_0 *ctr); -void display_srv_conn_info_1_ctr(FILE *out_hnd, enum action_type action, - SRV_CONN_INFO_1 *ctr); -void display_srv_conn_info_ctr(FILE *out_hnd, enum action_type action, - SRV_CONN_INFO_CTR *ctr); -void display_share_info_1(FILE *out_hnd, enum action_type action, - SRV_SHARE_INFO_1 *info1); -void display_share_info_2(FILE *out_hnd, enum action_type action, - SRV_SHARE_INFO_2 *info2); -void display_srv_share_info_ctr(FILE *out_hnd, enum action_type action, - SRV_SHARE_INFO_CTR *ctr); -void display_file_info_3(FILE *out_hnd, enum action_type action, - FILE_INFO_3 *info3, FILE_INFO_3_STR *str3); -void display_srv_file_info_3_ctr(FILE *out_hnd, enum action_type action, - SRV_FILE_INFO_3 *ctr); -void display_srv_file_info_ctr(FILE *out_hnd, enum action_type action, - SRV_FILE_INFO_CTR *ctr); -void display_server(FILE *out_hnd, enum action_type action, - char *sname, uint32 type, char *comment); -void display_share(FILE *out_hnd, enum action_type action, - char *sname, uint32 type, char *comment); -void display_share2(FILE *out_hnd, enum action_type action, - char *sname, uint32 type, char *comment, - uint32 perms, uint32 max_uses, uint32 num_uses, - char *path, char *passwd); -void display_name(FILE *out_hnd, enum action_type action, - char *sname); -void display_group_rid_info(FILE *out_hnd, enum action_type action, - uint32 num_gids, DOM_GID *gid); -void display_alias_name_info(FILE *out_hnd, enum action_type action, - uint32 num_aliases, fstring *alias_name, uint32 *num_als_usrs); -void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_INFO_21 *usr); -char *get_sec_mask_str(uint32 type); -void display_sec_access(FILE *out_hnd, enum action_type action, SEC_ACCESS *info); -void display_sec_ace(FILE *out_hnd, enum action_type action, SEC_ACE *ace); -void display_sec_acl(FILE *out_hnd, enum action_type action, SEC_ACL *sec_acl); -void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *sec); -char *get_reg_val_type_str(uint32 type); -void display_reg_value_info(FILE *out_hnd, enum action_type action, - char *val_name, uint32 val_type, BUFFER2 *value); -void display_reg_key_info(FILE *out_hnd, enum action_type action, - char *key_name, time_t key_mod_time); - -/*The following definitions come from rpcclient/rpcclient.c */ - -void rpcclient_init(void); - /*The following definitions come from smbd/blocking.c */ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num); @@ -3253,6 +3244,19 @@ BOOL unbecome_authenticated_pipe_user(pipes_struct *p); void become_root(BOOL save_dir) ; void unbecome_root(BOOL restore_dir); +/*The following definitions come from smbd/vfs.c */ + +int vfs_init_default(connection_struct *conn); +BOOL vfs_init_custom(connection_struct *conn); +BOOL vfs_directory_exist(connection_struct *conn, char *dname, + SMB_STRUCT_STAT *st); +BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf); +ssize_t vfs_write_data(files_struct *fsp,char *buffer,size_t N); +SMB_OFF_T vfs_transfer_file(int in_fd, files_struct *in_fsp, + int out_fd, files_struct *out_fsp, + SMB_OFF_T n, char *header, int headlen, int align); +char *vfs_readdirname(connection_struct *conn, void *p); + /*The following definitions come from smbd/vfs-wrap.c */ int vfswrap_dummy_connect(struct vfs_connection_struct *conn, char *service, @@ -3280,19 +3284,6 @@ int vfswrap_unlink(char *path); int vfswrap_chmod(char *path, mode_t mode); int vfswrap_utime(char *path, struct utimbuf *times); -/*The following definitions come from smbd/vfs.c */ - -int vfs_init_default(connection_struct *conn); -BOOL vfs_init_custom(connection_struct *conn); -BOOL vfs_directory_exist(connection_struct *conn, char *dname, - SMB_STRUCT_STAT *st); -BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf); -ssize_t vfs_write_data(files_struct *fsp,char *buffer,size_t N); -SMB_OFF_T vfs_transfer_file(int in_fd, files_struct *in_fsp, - int out_fd, files_struct *out_fsp, - SMB_OFF_T n, char *header, int headlen, int align); -char *vfs_readdirname(connection_struct *conn, void *p); - /*The following definitions come from smbwrapper/realcalls.c */ int real_utime(const char *name, struct utimbuf *buf); diff --git a/source/include/rpc_spoolss.h b/source/include/rpc_spoolss.h index 5aef2f3f639..fc8fd041d68 100755 --- a/source/include/rpc_spoolss.h +++ b/source/include/rpc_spoolss.h @@ -270,6 +270,7 @@ #define MIN_PRIORITY 1 #define DEF_PRIORITY 1 +/* the flags of the query */ #define PRINTER_ENUM_DEFAULT 0x00000001 #define PRINTER_ENUM_LOCAL 0x00000002 #define PRINTER_ENUM_CONNECTIONS 0x00000004 @@ -279,9 +280,9 @@ #define PRINTER_ENUM_SHARED 0x00000020 #define PRINTER_ENUM_NETWORK 0x00000040 +/* the flags of each printers */ #define PRINTER_ENUM_EXPAND 0x00004000 #define PRINTER_ENUM_CONTAINER 0x00008000 - #define PRINTER_ENUM_ICONMASK 0x00ff0000 #define PRINTER_ENUM_ICON1 0x00010000 #define PRINTER_ENUM_ICON2 0x00020000 @@ -685,10 +686,11 @@ typedef struct printer_info_2 typedef struct spool_q_enumprinters { uint32 flags; + uint32 servername_ptr; UNISTR2 servername; uint32 level; - BUFFER buffer; - uint32 buf_size; + NEW_BUFFER *buffer; + uint32 offered; } SPOOL_Q_ENUMPRINTERS; typedef struct printer_info_ctr_info @@ -703,14 +705,10 @@ typedef struct printer_info_ctr_info typedef struct spool_r_enumprinters { - uint32 offered; /* number of bytes offered */ + NEW_BUFFER *buffer; uint32 needed; /* bytes needed */ - uint32 level; - UNISTR servername; - PRINTER_INFO_CTR ctr; uint32 returned; /* number of printers */ uint32 status; - } SPOOL_R_ENUMPRINTERS; @@ -905,9 +903,8 @@ typedef struct spool_q_enumjobs uint32 firstjob; uint32 numofjobs; uint32 level; - BUFFER buffer; - uint32 buf_size; - + NEW_BUFFER *buffer; + uint32 offered; } SPOOL_Q_ENUMJOBS; typedef struct job_info_ctr_info @@ -922,12 +919,10 @@ typedef struct job_info_ctr_info typedef struct spool_r_enumjobs { - uint32 level; - uint32 offered; - JOB_INFO_CTR ctr; - uint32 numofjobs; + NEW_BUFFER *buffer; + uint32 needed; + uint32 returned; uint32 status; - } SPOOL_R_ENUMJOBS; typedef struct spool_q_schedulejob @@ -957,10 +952,11 @@ typedef struct s_port_info_2 typedef struct spool_q_enumports { + uint32 name_ptr; UNISTR2 name; uint32 level; - BUFFER buffer; - uint32 buf_size; + NEW_BUFFER *buffer; + uint32 offered; } SPOOL_Q_ENUMPORTS; typedef struct port_info_ctr_info @@ -974,12 +970,10 @@ typedef struct port_info_ctr_info typedef struct spool_r_enumports { - uint32 level; - PORT_INFO_CTR ctr; - uint32 offered; - uint32 numofports; + NEW_BUFFER *buffer; + uint32 needed; /* bytes needed */ + uint32 returned; /* number of printers */ uint32 status; - } SPOOL_R_ENUMPORTS; #define JOB_CONTROL_PAUSE 1 @@ -1015,22 +1009,21 @@ typedef struct spool_r_setjob typedef struct spool_q_enumprinterdrivers { + uint32 name_ptr; UNISTR2 name; + uint32 environment_ptr; UNISTR2 environment; uint32 level; - BUFFER buffer; - uint32 buf_size; - + NEW_BUFFER *buffer; + uint32 offered; } SPOOL_Q_ENUMPRINTERDRIVERS; typedef struct spool_r_enumprinterdrivers { - uint32 level; - DRIVER_INFO ctr; - uint32 offered; - uint32 numofdrivers; + NEW_BUFFER *buffer; + uint32 needed; + uint32 returned; uint32 status; - } SPOOL_R_ENUMPRINTERDRIVERS; typedef struct spool_form_1 @@ -1264,11 +1257,13 @@ typedef struct spool_r_getprinterdriverdirectory typedef struct spool_q_enumprintprocessors { + uint32 name_ptr; UNISTR2 name; + uint32 environment_ptr; UNISTR2 environment; uint32 level; - BUFFER buffer; - uint32 buf_size; + NEW_BUFFER *buffer; + uint32 offered; } SPOOL_Q_ENUMPRINTPROCESSORS; typedef struct printprocessor_1 @@ -1278,10 +1273,9 @@ typedef struct printprocessor_1 typedef struct spool_r_enumprintprocessors { - uint32 level; - PRINTPROCESSOR_1 *info_1; - uint32 offered; - uint32 numofprintprocessors; + NEW_BUFFER *buffer; + uint32 needed; + uint32 returned; uint32 status; } SPOOL_R_ENUMPRINTPROCESSORS; @@ -1308,28 +1302,36 @@ typedef struct spool_r_enumprintprocessordatatypes uint32 status; } SPOOL_R_ENUMPRINTPROCESSORDATATYPES; -typedef struct spool_q_enumprintmonitors -{ - UNISTR2 name; - uint32 level; - BUFFER buffer; - uint32 buf_size; -} SPOOL_Q_ENUMPRINTMONITORS; - typedef struct printmonitor_1 { UNISTR name; } PRINTMONITOR_1; -typedef struct spool_r_enumprintmonitors +typedef struct printmonitor_2 { + UNISTR name; + UNISTR environment; + UNISTR dll_name; +} PRINTMONITOR_2; + +typedef struct spool_q_enumprintmonitors +{ + uint32 name_ptr; + UNISTR2 name; uint32 level; - PRINTMONITOR_1 *info_1; + NEW_BUFFER *buffer; uint32 offered; - uint32 numofprintmonitors; +} SPOOL_Q_ENUMPRINTMONITORS; + +typedef struct spool_r_enumprintmonitors +{ + NEW_BUFFER *buffer; + uint32 needed; + uint32 returned; uint32 status; } SPOOL_R_ENUMPRINTMONITORS; + typedef struct spool_q_enumprinterdata { POLICY_HND handle; diff --git a/source/printing/nt_printing.c b/source/printing/nt_printing.c index 00e052772e6..a880184f3df 100644 --- a/source/printing/nt_printing.c +++ b/source/printing/nt_printing.c @@ -31,7 +31,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 +65,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) @@ -82,7 +82,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 +100,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 +115,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 +145,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 +175,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; ncversion)); - 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; @@ -676,7 +676,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 +693,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 +703,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 +715,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 +749,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 +763,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 +835,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 @@ -1008,7 +1008,7 @@ 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) { @@ -1023,26 +1023,26 @@ static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level) { 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,("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,("comment:[%s]\n", info2->comment)); + 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 +1114,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 +1124,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 +1140,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 +1168,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) @@ -1293,7 +1293,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 +1306,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 +1316,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); } diff --git a/source/rpc_parse/parse_prs.c b/source/rpc_parse/parse_prs.c index 24eff1b7799..5d0ea832c80 100644 --- a/source/rpc_parse/parse_prs.c +++ b/source/rpc_parse/parse_prs.c @@ -150,15 +150,13 @@ BOOL prs_grow(prs_struct *ps, uint32 extra_space) (unsigned int)extra_space)); return False; } - + /* * Decide how much extra space we really need. */ extra_space -= (ps->buffer_size - ps->data_offset); - if(ps->buffer_size == 0) { - /* * Ensure we have at least a PDU's length, or extra_space, whichever * is greater. @@ -172,21 +170,18 @@ BOOL prs_grow(prs_struct *ps, uint32 extra_space) } memset(new_data, '\0', new_size ); } else { - /* * If the current buffer size is bigger than the space needed, just * double it, else add extra_space. */ + new_size = MAX(ps->buffer_size*2, ps->buffer_size + extra_space); - new_size = MAX(ps->buffer_size*2, ps->buffer_size + extra_space); - - if((new_data = Realloc(ps->data_p, new_size)) == NULL) { + if ((new_data = Realloc(ps->data_p, new_size)) == NULL) { DEBUG(0,("prs_grow: Realloc failure for size %u.\n", (unsigned int)new_size)); return False; } } - ps->buffer_size = new_size; ps->data_p = new_data; @@ -286,12 +281,12 @@ BOOL prs_append_prs_data(prs_struct *dst, prs_struct *src) Append some data from one parse_struct into another. ********************************************************************/ -BOOL prs_append_some_prs_data(prs_struct *dst, prs_struct *src, uint32 len) -{ +BOOL prs_append_some_prs_data(prs_struct *dst, prs_struct *src, int32 start, uint32 len) +{ if(!prs_grow(dst, len)) return False; - - memcpy(&dst->data_p[dst->data_offset], prs_data_p(src), (size_t)len); + + memcpy(&dst->data_p[dst->data_offset], prs_data_p(src)+start, (size_t)len); dst->data_offset += len; return True; diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c index de998267b37..66fa2f1da5a 100644 --- a/source/rpc_parse/parse_spoolss.c +++ b/source/rpc_parse/parse_spoolss.c @@ -825,9 +825,11 @@ BOOL spoolss_io_q_closeprinter(char *desc, SPOOL_Q_CLOSEPRINTER *q_u, prs_struct prs_debug(ps, depth, desc, "spoolss_io_q_closeprinter"); depth++; - prs_align(ps); + if (!prs_align(ps)) + return False; - smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); + if (!smb_io_prt_hnd("printer handle",&q_u->handle,ps,depth)) + return False; return True; } @@ -841,12 +843,15 @@ BOOL spoolss_io_r_closeprinter(char *desc, SPOOL_R_CLOSEPRINTER *r_u, prs_struct { prs_debug(ps, depth, desc, "spoolss_io_r_closeprinter"); depth++; - prs_align(ps); - - smb_io_prt_hnd("printer handle",&(r_u->handle),ps,depth); - prs_uint32("status", ps, depth, &(r_u->status)); + if (!prs_align(ps)) + return False; + if (!smb_io_prt_hnd("printer handle",&r_u->handle,ps,depth)) + return False; + if (!prs_uint32("status", ps, depth, &r_u->status)) + return False; + return True; } @@ -1240,8 +1245,7 @@ static BOOL new_smb_io_relstr(char *desc, NEW_BUFFER *buffer, int depth, UNISTR { prs_struct *ps=&(buffer->prs); - if (MARSHALLING(ps)) - { + if (MARSHALLING(ps)) { uint32 struct_offset = prs_offset(ps); uint32 relative_offset; @@ -1254,13 +1258,12 @@ static BOOL new_smb_io_relstr(char *desc, NEW_BUFFER *buffer, int depth, UNISTR prs_set_offset(ps, struct_offset); - relative_offset=buffer->string_at_end-buffer->struct_start; + relative_offset=buffer->string_at_end - buffer->struct_start; /* write its offset */ if (!prs_uint32("offset", ps, depth, &relative_offset)) return False; } - else - { + else { uint32 old_offset; /* read the offset */ @@ -1284,6 +1287,67 @@ static BOOL new_smb_io_relstr(char *desc, NEW_BUFFER *buffer, int depth, UNISTR * write a array 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) +{ + 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 */ + buffer->string_at_end -= 2; + + /* jfm: FIXME: write a (uint16) 0 for the ending NULL */ + + do + { + buffer->string_at_end -= 2*(str_len_uni((*string)[i])+1); + prs_set_offset(ps, buffer->string_at_end); + + /* write the string */ + if (!spoolss_smb_io_unistr(desc, (*string)[i], ps, depth)) + return False; + + i--; + } + while (i>=0); + + prs_set_offset(ps, struct_offset); + + relative_offset=buffer->string_at_end - buffer->struct_start; + /* write its offset */ + if (!prs_uint32("offset", ps, depth, &relative_offset)) + return False; + } + else { + uint32 old_offset; + + /* 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 */ + +/* + if (!spoolss_smb_io_unistr(desc, string, ps, depth)) + return False; +*/ + prs_set_offset(ps, old_offset); + } + return True; +} + static BOOL smb_io_relarraystr(char *desc, prs_struct *ps, int depth, UNISTR ***buffer, uint32 *start_offset, uint32 *end_offset) { @@ -1321,9 +1385,54 @@ static BOOL smb_io_relarraystr(char *desc, prs_struct *ps, int depth, UNISTR *** } /******************************************************************* - * write a DEVMODE struct and its relative pointer. - * used by all the RPC structs passing a buffer - ********************************************************************/ + Parse a DEVMODE structure and its relative pointer. +********************************************************************/ +static BOOL new_smb_io_reldevmode(char *desc, NEW_BUFFER *buffer, int depth, DEVICEMODE *devmode) +{ + prs_struct *ps=&(buffer->prs); + + prs_debug(ps, depth, desc, "new_smb_io_reldevmode"); + depth++; + + if (MARSHALLING(ps)) { + uint32 struct_offset = prs_offset(ps); + uint32 relative_offset; + + buffer->string_at_end -= (devmode->size+devmode->driverextra); + + prs_set_offset(ps, buffer->string_at_end); + + /* write the DEVMODE */ + if (!spoolss_io_devmode(desc, ps, depth, devmode)) + return False; + + prs_set_offset(ps, struct_offset); + + relative_offset=buffer->string_at_end - buffer->struct_start; + /* write its offset */ + if (!prs_uint32("offset", ps, depth, &relative_offset)) + return False; + } + else { + uint32 old_offset; + + /* 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 + buffer->struct_start); + + /* read the string */ + if (!spoolss_io_devmode(desc, ps, depth, devmode)) + return False; + + prs_set_offset(ps, old_offset); + } + return True; +} + + static BOOL smb_io_reldevmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode, uint32 *start_offset, uint32 *end_offset) { @@ -1392,76 +1501,112 @@ static BOOL smb_io_printer_info_0(char *desc, PRINTER_INFO_0 *info, prs_struct * } /******************************************************************* + Parse a PRINTER_INFO_1 structure. ********************************************************************/ -static BOOL smb_io_printer_info_1(char *desc, PRINTER_INFO_1 *info, prs_struct *ps, int depth, - uint32 *start_offset, uint32 *end_offset) +BOOL new_smb_io_printer_info_1(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info, int depth) { - prs_debug(ps, depth, desc, "smb_io_printer_info_1"); + prs_struct *ps=&(buffer->prs); + + prs_debug(ps, depth, desc, "new_smb_io_printer_info_1"); depth++; - *start_offset=prs_offset(ps); - prs_uint32("flags", ps, depth, &(info->flags)); - smb_io_relstr("description",ps, depth, &(info->description), start_offset, end_offset); - smb_io_relstr("name",ps, depth, &(info->name), start_offset, end_offset); - smb_io_relstr("comment",ps, depth, &(info->comment), start_offset, end_offset); + buffer->struct_start=prs_offset(ps); + + if (!prs_uint32("flags", ps, depth, &info->flags)) + return False; + if (!new_smb_io_relstr("description", buffer, depth, &info->description)) + return False; + if (!new_smb_io_relstr("name", buffer, depth, &info->name)) + return False; + if (!new_smb_io_relstr("comment", buffer, depth, &info->comment)) + return False; return True; } /******************************************************************* + Parse a PRINTER_INFO_2 structure. ********************************************************************/ -static BOOL smb_io_printer_info_2(char *desc, PRINTER_INFO_2 *info, prs_struct *ps, int depth, - uint32 *start_offset, uint32 *end_offset) +BOOL new_smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth) { + /* hack for the SEC DESC */ uint32 pipo=0; - uint32 devmode_offset; - uint32 backup_offset; - prs_debug(ps, depth, desc, "smb_io_printer_info_2"); + prs_struct *ps=&(buffer->prs); + + prs_debug(ps, depth, desc, "new_smb_io_printer_info_2"); depth++; - *start_offset=prs_offset(ps); - smb_io_relstr("servername", ps, depth, &(info->servername), start_offset, end_offset); - smb_io_relstr("printername", ps, depth, &(info->printername), start_offset, end_offset); - smb_io_relstr("sharename", ps, depth, &(info->sharename), start_offset, end_offset); - smb_io_relstr("portname", ps, depth, &(info->portname), start_offset, end_offset); - smb_io_relstr("drivername", ps, depth, &(info->drivername), start_offset, end_offset); - smb_io_relstr("comment", ps, depth, &(info->comment), start_offset, end_offset); - smb_io_relstr("location", ps, depth, &(info->location), start_offset, end_offset); - - devmode_offset=prs_offset(ps); - prs_set_offset(ps, prs_offset(ps)+4); + buffer->struct_start=prs_offset(ps); - smb_io_relstr("sepfile", ps, depth, &(info->sepfile), start_offset, end_offset); - smb_io_relstr("printprocessor",ps, depth, &(info->printprocessor), start_offset, end_offset); - smb_io_relstr("datatype", ps, depth, &(info->datatype), start_offset, end_offset); - smb_io_relstr("parameters", ps, depth, &(info->parameters), start_offset, end_offset); - - prs_uint32("security descriptor", ps, depth, &(pipo)); - - prs_uint32("attributes", ps, depth, &(info->attributes)); - prs_uint32("priority", ps, depth, &(info->priority)); - prs_uint32("defpriority", ps, depth, &(info->defaultpriority)); - prs_uint32("starttime", ps, depth, &(info->starttime)); - prs_uint32("untiltime", ps, depth, &(info->untiltime)); - prs_uint32("status", ps, depth, &(info->status)); - prs_uint32("jobs", ps, depth, &(info->cjobs)); - prs_uint32("averageppm", ps, depth, &(info->averageppm)); + if (!new_smb_io_relstr("servername", buffer, depth, &info->servername)) + return False; + if (!new_smb_io_relstr("printername", buffer, depth, &info->printername)) + return False; + if (!new_smb_io_relstr("sharename", buffer, depth, &info->sharename)) + return False; + if (!new_smb_io_relstr("portname", buffer, depth, &info->portname)) + return False; + if (!new_smb_io_relstr("drivername", buffer, depth, &info->drivername)) + return False; + if (!new_smb_io_relstr("comment", buffer, depth, &info->comment)) + return False; + if (!new_smb_io_relstr("location", buffer, depth, &info->location)) + return False; - /* - I'm not sure if putting the devmode at the end the struct is worth it - but NT does it - */ - backup_offset=prs_offset(ps); - prs_set_offset(ps, devmode_offset); - smb_io_reldevmode("devmode", ps, depth, info->devmode, start_offset, end_offset); - prs_set_offset(ps, backup_offset); + /* NT parses the DEVMODE at the end of the struct */ + if (!new_smb_io_reldevmode("devmode", buffer, depth, info->devmode)) + return False; + + if (!new_smb_io_relstr("sepfile", buffer, depth, &info->sepfile)) + return False; + if (!new_smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor)) + return False; + if (!new_smb_io_relstr("datatype", buffer, depth, &info->datatype)) + return False; + if (!new_smb_io_relstr("parameters", buffer, depth, &info->parameters)) + return False; + + if (!prs_uint32("security descriptor", ps, depth, &pipo)) + return False; + if (!prs_uint32("attributes", ps, depth, &info->attributes)) + return False; + if (!prs_uint32("priority", ps, depth, &info->priority)) + return False; + if (!prs_uint32("defpriority", ps, depth, &info->defaultpriority)) + return False; + if (!prs_uint32("starttime", ps, depth, &info->starttime)) + return False; + if (!prs_uint32("untiltime", ps, depth, &info->untiltime)) + return False; + if (!prs_uint32("status", ps, depth, &info->status)) + return False; + if (!prs_uint32("jobs", ps, depth, &info->cjobs)) + return False; + if (!prs_uint32("averageppm", ps, depth, &info->averageppm)) + return False; return True; } /******************************************************************* -********************************************************************/ + Parse a DRIVER_INFO_1 structure. +********************************************************************/ +BOOL new_smb_io_printer_driver_info_1(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) +{ + prs_struct *ps=&(buffer->prs); + + prs_debug(ps, depth, desc, "new_smb_io_printer_driver_info_1"); + depth++; + + buffer->struct_start=prs_offset(ps); + + if (!new_smb_io_relstr("name", buffer, depth, &info->name)) + return False; + + return True; +} + static BOOL smb_io_printer_driver_info_1(char *desc, DRIVER_INFO_1 *info, prs_struct *ps, int depth, uint32 *start_offset, uint32 *end_offset) { @@ -1475,7 +1620,33 @@ static BOOL smb_io_printer_driver_info_1(char *desc, DRIVER_INFO_1 *info, prs_st } /******************************************************************* -********************************************************************/ + Parse a DRIVER_INFO_2 structure. +********************************************************************/ +BOOL new_smb_io_printer_driver_info_2(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_2 *info, int depth) +{ + prs_struct *ps=&(buffer->prs); + + prs_debug(ps, depth, desc, "new_smb_io_printer_driver_info_2"); + depth++; + + buffer->struct_start=prs_offset(ps); + + if (!prs_uint32("version", ps, depth, &info->version)) + return False; + if (!new_smb_io_relstr("name", buffer, depth, &info->name)) + return False; + if (!new_smb_io_relstr("architecture", buffer, depth, &info->architecture)) + return False; + if (!new_smb_io_relstr("driverpath", buffer, depth, &info->driverpath)) + return False; + if (!new_smb_io_relstr("datafile", buffer, depth, &info->datafile)) + return False; + if (!new_smb_io_relstr("configfile", buffer, depth, &info->configfile)) + return False; + + return True; +} + static BOOL smb_io_printer_driver_info_2(char *desc, DRIVER_INFO_2 *info,prs_struct *ps, int depth, uint32 *start_offset, uint32 *end_offset) { @@ -1494,7 +1665,43 @@ static BOOL smb_io_printer_driver_info_2(char *desc, DRIVER_INFO_2 *info,prs_str } /******************************************************************* -********************************************************************/ + Parse a DRIVER_INFO_3 structure. +********************************************************************/ +BOOL new_smb_io_printer_driver_info_3(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_3 *info, int depth) +{ + prs_struct *ps=&(buffer->prs); + + prs_debug(ps, depth, desc, "new_smb_io_printer_driver_info_3"); + depth++; + + buffer->struct_start=prs_offset(ps); + + if (!prs_uint32("version", ps, depth, &info->version)) + return False; + if (!new_smb_io_relstr("name", buffer, depth, &info->name)) + return False; + if (!new_smb_io_relstr("architecture", buffer, depth, &info->architecture)) + return False; + if (!new_smb_io_relstr("driverpath", buffer, depth, &info->driverpath)) + return False; + if (!new_smb_io_relstr("datafile", buffer, depth, &info->datafile)) + return False; + if (!new_smb_io_relstr("configfile", buffer, depth, &info->configfile)) + return False; + if (!new_smb_io_relstr("helpfile", buffer, depth, &info->helpfile)) + return False; + + if (!new_smb_io_relarraystr("dependentfiles", buffer, depth, &info->dependentfiles)) + return False; + + if (!new_smb_io_relstr("monitorname", buffer, depth, &info->monitorname)) + return False; + if (!new_smb_io_relstr("defaultdatatype", buffer, depth, &info->defaultdatatype)) + return False; + + return True; +} + static BOOL smb_io_printer_driver_info_3(char *desc, DRIVER_INFO_3 *info,prs_struct *ps, int depth, uint32 *start_offset, uint32 *end_offset) { @@ -1519,7 +1726,47 @@ static BOOL smb_io_printer_driver_info_3(char *desc, DRIVER_INFO_3 *info,prs_str } /******************************************************************* + Parse a JOB_INFO_1 structure. ********************************************************************/ +BOOL new_smb_io_job_info_1(char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, int depth) +{ + prs_struct *ps=&(buffer->prs); + + prs_debug(ps, depth, desc, "new_smb_io_job_info_1"); + depth++; + + buffer->struct_start=prs_offset(ps); + + if (!prs_uint32("jobid", ps, depth, &info->jobid)) + return False; + if (!new_smb_io_relstr("printername", buffer, depth, &info->printername)) + return False; + if (!new_smb_io_relstr("machinename", buffer, depth, &info->machinename)) + return False; + if (!new_smb_io_relstr("username", buffer, depth, &info->username)) + return False; + if (!new_smb_io_relstr("document", buffer, depth, &info->document)) + return False; + if (!new_smb_io_relstr("datatype", buffer, depth, &info->datatype)) + return False; + if (!new_smb_io_relstr("text_status", buffer, depth, &info->text_status)) + return False; + if (!prs_uint32("status", ps, depth, &info->status)) + return False; + if (!prs_uint32("priority", ps, depth, &info->priority)) + return False; + if (!prs_uint32("position", ps, depth, &info->position)) + return False; + if (!prs_uint32("totalpages", ps, depth, &info->totalpages)) + return False; + if (!prs_uint32("pagesprinted", ps, depth, &info->pagesprinted)) + return False; + if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted)) + return False; + + return True; +} + static BOOL smb_io_job_info_1(char *desc, JOB_INFO_1 *info, prs_struct *ps, int depth, uint32 *start_offset, uint32 *end_offset) { @@ -1545,30 +1792,94 @@ static BOOL smb_io_job_info_1(char *desc, JOB_INFO_1 *info, prs_struct *ps, int } /******************************************************************* + Parse a JOB_INFO_2 structure. ********************************************************************/ -static BOOL smb_io_job_info_2(char *desc, JOB_INFO_2 *info, prs_struct *ps, int depth, - uint32 *start_offset, uint32 *end_offset) +BOOL new_smb_io_job_info_2(char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, int depth) { int pipo=0; - prs_debug(ps, depth, desc, "smb_io_job_info_2"); - depth++; - *start_offset=prs_offset(ps); + prs_struct *ps=&(buffer->prs); - prs_uint32("jobid", ps, depth, &(info->jobid)); - smb_io_relstr("printername", ps, depth, &(info->printername), start_offset, end_offset); - smb_io_relstr("machinename", ps, depth, &(info->machinename), start_offset, end_offset); - smb_io_relstr("username", ps, depth, &(info->username), start_offset, end_offset); - smb_io_relstr("document", ps, depth, &(info->document), start_offset, end_offset); - smb_io_relstr("notifyname", ps, depth, &(info->notifyname), start_offset, end_offset); - smb_io_relstr("datatype", ps, depth, &(info->datatype), start_offset, end_offset); + prs_debug(ps, depth, desc, "new_smb_io_job_info_2"); + depth++; - smb_io_relstr("printprocessor", ps, depth, &(info->printprocessor), start_offset, end_offset); - smb_io_relstr("parameters", ps, depth, &(info->parameters), start_offset, end_offset); - smb_io_relstr("drivername", ps, depth, &(info->drivername), start_offset, end_offset); - smb_io_reldevmode("devmode", ps, depth, info->devmode, start_offset, end_offset); - smb_io_relstr("text_status", ps, depth, &(info->text_status), start_offset, end_offset); + buffer->struct_start=prs_offset(ps); + + if (!prs_uint32("jobid",ps, depth, &info->jobid)) + return False; + if (!new_smb_io_relstr("printername", buffer, depth, &info->printername)) + return False; + if (!new_smb_io_relstr("machinename", buffer, depth, &info->machinename)) + return False; + if (!new_smb_io_relstr("username", buffer, depth, &info->username)) + return False; + if (!new_smb_io_relstr("document", buffer, depth, &info->document)) + return False; + if (!new_smb_io_relstr("notifyname", buffer, depth, &info->notifyname)) + return False; + if (!new_smb_io_relstr("datatype", buffer, depth, &info->datatype)) + return False; -/* SEC_DESC sec_desc;*/ + if (!new_smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor)) + return False; + if (!new_smb_io_relstr("parameters", buffer, depth, &info->parameters)) + return False; + if (!new_smb_io_relstr("drivername", buffer, depth, &info->drivername)) + return False; + if (!new_smb_io_reldevmode("devmode", buffer, depth, info->devmode)) + return False; + if (!new_smb_io_relstr("text_status", buffer, depth, &info->text_status)) + return False; + +/* SEC_DESC sec_desc;*/ + if (!prs_uint32("Hack! sec desc", ps, depth, &pipo)) + return False; + + if (!prs_uint32("status",ps, depth, &info->status)) + return False; + if (!prs_uint32("priority",ps, depth, &info->priority)) + return False; + if (!prs_uint32("position",ps, depth, &info->position)) + return False; + if (!prs_uint32("starttime",ps, depth, &info->starttime)) + return False; + if (!prs_uint32("untiltime",ps, depth, &info->untiltime)) + return False; + if (!prs_uint32("totalpages",ps, depth, &info->totalpages)) + return False; + if (!prs_uint32("size",ps, depth, &info->size)) + return False; + if (!spoolss_io_system_time("submitted", ps, depth, &info->submitted) ) + return False; + if (!prs_uint32("timeelapsed",ps, depth, &info->timeelapsed)) + return False; + if (!prs_uint32("pagesprinted",ps, depth, &info->pagesprinted)) + return False; + + return True; +} +static BOOL smb_io_job_info_2(char *desc, JOB_INFO_2 *info, prs_struct *ps, int depth, + uint32 *start_offset, uint32 *end_offset) +{ + int pipo=0; + prs_debug(ps, depth, desc, "smb_io_job_info_2"); + depth++; + *start_offset=prs_offset(ps); + + prs_uint32("jobid", ps, depth, &(info->jobid)); + smb_io_relstr("printername", ps, depth, &(info->printername), start_offset, end_offset); + smb_io_relstr("machinename", ps, depth, &(info->machinename), start_offset, end_offset); + smb_io_relstr("username", ps, depth, &(info->username), start_offset, end_offset); + smb_io_relstr("document", ps, depth, &(info->document), start_offset, end_offset); + smb_io_relstr("notifyname", ps, depth, &(info->notifyname), start_offset, end_offset); + smb_io_relstr("datatype", ps, depth, &(info->datatype), start_offset, end_offset); + + smb_io_relstr("printprocessor", ps, depth, &(info->printprocessor), start_offset, end_offset); + smb_io_relstr("parameters", ps, depth, &(info->parameters), start_offset, end_offset); + smb_io_relstr("drivername", ps, depth, &(info->drivername), start_offset, end_offset); + smb_io_reldevmode("devmode", ps, depth, info->devmode, start_offset, end_offset); + smb_io_relstr("text_status", ps, depth, &(info->text_status), start_offset, end_offset); + +/* SEC_DESC sec_desc;*/ prs_uint32("Hack! sec desc", ps, depth, &pipo); prs_uint32("status", ps, depth, &(info->status)); @@ -1643,18 +1954,20 @@ static BOOL new_spoolss_io_buffer(char *desc, prs_struct *ps, int depth, NEW_BUF return True; } - if (!prs_uint32("size", ps, depth, &(buffer->size))) + if (!prs_uint32("size", ps, depth, &buffer->size)) return False; if (!prs_init(&(buffer->prs), buffer->size, 4, UNMARSHALL)) return False; - if (!prs_append_some_prs_data(&(buffer->prs), ps, buffer->size)) + if (!prs_append_some_prs_data(&(buffer->prs), ps, prs_offset(ps), buffer->size)) return False; - prs_set_offset(&(buffer->prs),0); + if (!prs_set_offset(&buffer->prs, 0)) + return False; - prs_set_offset(ps, buffer->size+prs_offset(ps)); + if (!prs_set_offset(ps, buffer->size+prs_offset(ps))) + return False; buffer->string_at_end=buffer->size; @@ -1667,12 +1980,9 @@ static BOOL new_spoolss_io_buffer(char *desc, prs_struct *ps, int depth, NEW_BUF if (!prs_uint32("size", ps, depth, &(buffer->size))) return False; - - if (!prs_append_some_prs_data(ps, &(buffer->prs), buffer->size)) + if (!prs_append_some_prs_data(ps, &(buffer->prs), 0, buffer->size)) return False; - } - - return True; + } } /******************************************************************* @@ -1746,9 +2056,50 @@ static BOOL smb_io_form_1(char *desc, FORM_1 *info, prs_struct *ps, int depth, return True; } +/******************************************************************* + Parse a PORT_INFO_2 structure. +********************************************************************/ +BOOL new_smb_io_port_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth) +{ + prs_struct *ps=&(buffer->prs); + + prs_debug(ps, depth, desc, "new_smb_io_port_1"); + depth++; + + buffer->struct_start=prs_offset(ps); + + if(!new_smb_io_relstr("port_name", buffer, depth, &info->port_name)) + return False; + + return True; +} /******************************************************************* + Parse a PORT_INFO_2 structure. ********************************************************************/ +BOOL new_smb_io_port_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth) +{ + prs_struct *ps=&(buffer->prs); + + prs_debug(ps, depth, desc, "new_smb_io_port_2"); + depth++; + + buffer->struct_start=prs_offset(ps); + + if(!new_smb_io_relstr("port_name", buffer, depth, &info->port_name)) + return False; + if(!new_smb_io_relstr("monitor_name", buffer, depth, &info->monitor_name)) + return False; + if(!new_smb_io_relstr("description", buffer, depth, &info->description)) + return False; + if(!prs_uint32("port_type", ps, depth, &info->port_type)) + return False; + if(!prs_uint32("reserved", ps, depth, &info->reserved)) + return False; + + return True; +} + static BOOL smb_io_port_2(char *desc, PORT_INFO_2 *info, prs_struct *ps, int depth, uint32 *start_offset, uint32 *end_offset) { @@ -1767,28 +2118,55 @@ static BOOL smb_io_port_2(char *desc, PORT_INFO_2 *info, prs_struct *ps, int dep /******************************************************************* ********************************************************************/ -static BOOL smb_io_processor_info_1(char *desc, PRINTPROCESSOR_1 *info, prs_struct *ps, int depth, - uint32 *start_offset, uint32 *end_offset) +BOOL smb_io_printprocessor_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth) { - prs_debug(ps, depth, desc, "smb_io_processor_info_1"); + prs_struct *ps=&(buffer->prs); + + prs_debug(ps, depth, desc, "smb_io_printprocessor_info_1"); depth++; - *start_offset=prs_offset(ps); - smb_io_relstr("name",ps, depth, &(info->name), start_offset, end_offset); + buffer->struct_start=prs_offset(ps); + + if (new_smb_io_relstr("name", buffer, depth, &info->name)) + return False; return True; } /******************************************************************* ********************************************************************/ -static BOOL smb_io_monitor_info_1(char *desc, PRINTMONITOR_1 *info, prs_struct *ps, int depth, - uint32 *start_offset, uint32 *end_offset) +BOOL smb_io_printmonitor_info_1(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_1 *info, int depth) { - prs_debug(ps, depth, desc, "smb_io_monitor_info_1"); + prs_struct *ps=&(buffer->prs); + + prs_debug(ps, depth, desc, "smb_io_printmonitor_info_1"); depth++; - *start_offset=prs_offset(ps); - smb_io_relstr("name",ps, depth, &(info->name), start_offset, end_offset); + buffer->struct_start=prs_offset(ps); + + if (!new_smb_io_relstr("name", buffer, depth, &info->name)) + return False; + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL smb_io_printmonitor_info_2(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *info, int depth) +{ + prs_struct *ps=&(buffer->prs); + + prs_debug(ps, depth, desc, "smb_io_printmonitor_info_2"); + depth++; + + buffer->struct_start=prs_offset(ps); + + if (!new_smb_io_relstr("name", buffer, depth, &info->name)) + return False; + if (!new_smb_io_relstr("environment", buffer, depth, &info->environment)) + return False; + if (!new_smb_io_relstr("dll_name", buffer, depth, &info->dll_name)) + return False; return True; } @@ -1811,7 +2189,7 @@ static uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info) /******************************************************************* return the size required by a struct in the stream ********************************************************************/ -static uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info) +uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info) { int size=0; @@ -1819,15 +2197,14 @@ static uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info) size+=size_of_relative_string( &(info->description) ); size+=size_of_relative_string( &(info->name) ); size+=size_of_relative_string( &(info->comment) ); - return (size); - return True; + return size; } /******************************************************************* return the size required by a struct in the stream -********************************************************************/ -static uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info) +********************************************************************/ +uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info) { int size=0; @@ -1856,15 +2233,13 @@ static uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info) size+=size_of_uint32( &(info->status) ); size+=size_of_uint32( &(info->cjobs) ); size+=size_of_uint32( &(info->averageppm) ); - return (size); - - return True; + return size; } /******************************************************************* return the size required by a struct in the stream -********************************************************************/ -static uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info) +********************************************************************/ +uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info) { int size=0; DEBUG(9,("Sizing driver info_1\n")); @@ -1878,8 +2253,8 @@ static uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info) /******************************************************************* return the size required by a struct in the stream -********************************************************************/ -static uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info) +********************************************************************/ +uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info) { int size=0; DEBUG(9,("Sizing driver info_2\n")); @@ -1898,8 +2273,8 @@ static uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info) /******************************************************************* return the size required by a struct in the stream -********************************************************************/ -static uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info) +********************************************************************/ +uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info) { int size=0; UNISTR **string; @@ -1934,7 +2309,7 @@ static uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info) /******************************************************************* return the size required by a struct in the stream ********************************************************************/ -static uint32 spoolss_size_job_info_1(JOB_INFO_1 *info) +uint32 spoolss_size_job_info_1(JOB_INFO_1 *info) { int size=0; size+=size_of_uint32( &(info->jobid) ); @@ -1950,15 +2325,14 @@ static uint32 spoolss_size_job_info_1(JOB_INFO_1 *info) size+=size_of_uint32( &(info->totalpages) ); size+=size_of_uint32( &(info->pagesprinted) ); size+=size_of_systemtime( &(info->submitted) ); - return (size); - return True; + return size; } /******************************************************************* return the size required by a struct in the stream ********************************************************************/ -static uint32 spoolss_size_job_info_2(JOB_INFO_2 *info) +uint32 spoolss_size_job_info_2(JOB_INFO_2 *info) { int size=0; @@ -2008,15 +2382,25 @@ uint32 spoolss_size_form_1(FORM_1 *info) size+=size_of_uint32( &(info->right) ); size+=size_of_uint32( &(info->bottom) ); - return (size); + return size; +} - return True; +/******************************************************************* +return the size required by a struct in the stream +********************************************************************/ +uint32 spoolss_size_port_info_1(PORT_INFO_1 *info) +{ + int size=0; + + size+=size_of_relative_string( &(info->port_name) ); + + return size; } /******************************************************************* return the size required by a struct in the stream ********************************************************************/ -static uint32 spoolss_size_port_info_2(PORT_INFO_2 *info) +uint32 spoolss_size_port_info_2(PORT_INFO_2 *info) { int size=0; @@ -2027,40 +2411,49 @@ static uint32 spoolss_size_port_info_2(PORT_INFO_2 *info) size+=size_of_uint32( &(info->port_type) ); size+=size_of_uint32( &(info->reserved) ); - return (size); + return size; +} - return True; +/******************************************************************* +return the size required by a struct in the stream +********************************************************************/ +uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info) +{ + int size=0; + size+=size_of_relative_string( &info->name ); + + return size; } /******************************************************************* return the size required by a struct in the stream ********************************************************************/ -static uint32 spoolss_size_processor_info_1(PRINTPROCESSOR_1 *info) +uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info) { int size=0; - size+=size_of_relative_string( &(info->name) ); + size+=size_of_relative_string( &info->name ); - return (size); + return size; - return True; } /******************************************************************* return the size required by a struct in the stream ********************************************************************/ -static uint32 spoolss_size_monitor_info_1(PRINTMONITOR_1 *info) +uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info) { int size=0; - size+=size_of_relative_string( &(info->name) ); + size+=size_of_relative_string( &info->name); + size+=size_of_relative_string( &info->environment); + size+=size_of_relative_string( &info->dll_name); - return (size); - - return True; + return size; } /******************************************************************* * make a structure. ********************************************************************/ +/* static BOOL make_spoolss_buffer(BUFFER* buffer, uint32 size) { buffer->ptr = (size != 0) ? 1 : 0; @@ -2069,6 +2462,7 @@ static BOOL make_spoolss_buffer(BUFFER* buffer, uint32 size) return (buffer->data != NULL || size == 0); } +*/ /******************************************************************* * read a uint8 buffer of size *size. @@ -2358,8 +2752,8 @@ BOOL make_spoolss_q_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u, init_unistr2(&q_u->servername, servername, len_name); q_u->level = level; - make_spoolss_buffer(&q_u->buffer, size); - q_u->buf_size = size; + /*make_spoolss_buffer(&q_u->buffer, size);*/ +/* q_u->buf_size = size;*/ return True; } @@ -2371,45 +2765,63 @@ BOOL make_spoolss_q_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u, BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth) { - uint32 useless_ptr = 0x01; prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters"); depth++; - prs_align(ps); - - prs_uint32("flags", ps, depth, &(q_u->flags)); - prs_uint32("useless ptr", ps, depth, &useless_ptr); + if (!prs_align(ps)) + return False; - smb_io_unistr2("", &q_u->servername,True,ps,depth); - prs_align(ps); + if (!prs_uint32("flags", ps, depth, &q_u->flags)) + return False; + if (!prs_uint32("servername_ptr", ps, depth, &q_u->servername_ptr)) + return False; - prs_uint32("level", ps, depth, &(q_u->level)); + if (!smb_io_unistr2("", &q_u->servername, q_u->servername_ptr, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + if (!prs_uint32("level", ps, depth, &q_u->level)) + return False; - spoolss_io_read_buffer("buffer", ps, depth, &(q_u->buffer)); + if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer)) + return False; - prs_uint32("buf_size", ps, depth, &q_u->buf_size); + if (!prs_align(ps)) + return False; + if (!prs_uint32("offered", ps, depth, &q_u->offered)) + return False; return True; } -/**************************************************************************** -****************************************************************************/ -void free_r_enumprinters(SPOOL_R_ENUMPRINTERS *r_u) -{ - DEBUG(4,("free_enum_printers_info: [%d] structs to free at level [%d]\n", r_u->returned, r_u->level)); - switch (r_u->level) - { - case 1: - { - free_print1_array(r_u->returned, r_u->ctr.printer.printers_1); - break; - } - case 2: - { - free_print2_array(r_u->returned, r_u->ctr.printer.printers_2); - break; - } - } +/******************************************************************* + Parse a SPOOL_R_ENUMPRINTERS structure. + ********************************************************************/ +BOOL new_spoolss_io_r_enumprinters(char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "new_spoolss_io_r_enumprinters"); + depth++; + + if (!prs_align(ps)) + return False; + + if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("needed", ps, depth, &r_u->needed)) + return False; + + if (!prs_uint32("returned", ps, depth, &r_u->returned)) + return False; + + if (!prs_uint32("status", ps, depth, &r_u->status)) + return False; + + return True; } /******************************************************************* @@ -2417,198 +2829,48 @@ void free_r_enumprinters(SPOOL_R_ENUMPRINTERS *r_u) * called from spoolss_r_enum_printers (srv_spoolss.c) * ********************************************************************/ -BOOL spoolss_io_r_enumprinters(char *desc, - SPOOL_R_ENUMPRINTERS *r_u, +BOOL spoolss_io_r_getprinter(char *desc, + SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth) { uint32 useless_ptr=0xADDE0FF0; - int i; uint32 start_offset, end_offset, beginning; uint32 bufsize_required=0; - uint32 tmp_ct = 0; - - PRINTER_INFO_1 *info1; - PRINTER_INFO_2 *info2; - fstring tmp; - - slprintf(tmp, sizeof(tmp)-1, "spoolss_io_r_enumprinters %d", r_u->level); - - prs_debug(ps, depth, desc, tmp); + + prs_debug(ps, depth, desc, "spoolss_io_r_getprinter"); depth++; + prs_align(ps); + prs_uint32("pointer", ps, depth, &useless_ptr); - if (!ps->io) + switch (r_u->level) { - /* writing */ - for(i=0;ireturned;i++) + case 0: { - switch (r_u->level) - { - case 1: - info1 = r_u->ctr.printer.printers_1[i]; - bufsize_required += spoolss_size_printer_info_1(info1); - break; - case 2: - info2 = r_u->ctr.printer.printers_2[i]; - bufsize_required += spoolss_size_printer_info_2(info2); - break; - } + PRINTER_INFO_0 *info; + info = r_u->ctr.printer.info0; + bufsize_required += spoolss_size_printer_info_0(info); + break; } - - DEBUG(4,("spoolss_io_r_enumprinters, size needed: %d\n",bufsize_required)); - DEBUG(4,("spoolss_io_r_enumprinters, size offered: %d\n",r_u->offered)); - - if (r_u->offeredstatus=ERROR_INSUFFICIENT_BUFFER; - r_u->offered=0; - /*r_u->returned=0;*/ - - DEBUG(4,("spoolss_io_r_enumprinters, buffer too small\n")); - - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - prs_uint32("size of buffer needed", ps, depth, &(bufsize_required)); - prs_uint32("count", ps, depth, &(r_u->returned)); - prs_uint32("status", ps, depth, &(r_u->status)); - return False; + case 1: + { + PRINTER_INFO_1 *info; + info = r_u->ctr.printer.info1; + bufsize_required += spoolss_size_printer_info_1(info); + break; + } + case 2: + { + PRINTER_INFO_2 *info; + info = r_u->ctr.printer.info2; + bufsize_required += spoolss_size_printer_info_2(info); + break; } - - DEBUG(4,("spoolss_io_r_enumprinters, buffer large enough\n")); } - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - - /* have to skip to end of buffer when reading, and have to record - * size of buffer when writing. *shudder*. - */ - - beginning = prs_offset(ps); - start_offset = prs_offset(ps); - end_offset = start_offset + r_u->offered; - - if (ps->io) - { - /* reading */ - prs_set_offset(ps, beginning + r_u->offered); - - prs_align(ps); - prs_uint32("buffer size", ps, depth, &(bufsize_required)); - prs_uint32("count", ps, depth, &(r_u->returned)); - - prs_set_offset(ps, beginning); - } - - for(i=0;ireturned;i++) - { - - switch (r_u->level) - { - case 1: - { - if (ps->io) - { - /* reading */ -/* r_u->ctr.printer.printers_1[i] = add_print1_to_array(&tmp_ct, &r_u->ctr.printer.printers_1, NULL);*/ - } - info1 = r_u->ctr.printer.printers_1[i]; - if (info1 == NULL) - { - return False; - } - smb_io_printer_info_1(desc, info1, ps, depth, - &start_offset, &end_offset); - break; - } - case 2: - { - if (ps->io) - { - /* reading */ -/* - r_u->ctr.printer.printers_2[i] = add_print2_to_array(&tmp_ct, &r_u->ctr.printer.printers_2, NULL); -*/ } - info2 = r_u->ctr.printer.printers_2[i]; - if (info2 == NULL) - { - return False; - } - smb_io_printer_info_2(desc, info2, ps, depth, - &start_offset, &end_offset); - break; - } - } - } - - prs_set_offset(ps, beginning + r_u->offered); - prs_align(ps); - - prs_uint32("buffer size", ps, depth, &(bufsize_required)); - prs_uint32("count", ps, depth, &(r_u->returned)); - prs_uint32("status", ps, depth, &(r_u->status)); - - if (!ps->io) - { - /* writing */ - free_r_enumprinters(r_u); - } - - return True; -} - -/******************************************************************* - * write a structure. - * called from spoolss_r_enum_printers (srv_spoolss.c) - * - ********************************************************************/ -BOOL spoolss_io_r_getprinter(char *desc, - SPOOL_R_GETPRINTER *r_u, - prs_struct *ps, int depth) -{ - uint32 useless_ptr=0xADDE0FF0; - uint32 start_offset, end_offset, beginning; - uint32 bufsize_required=0; - - prs_debug(ps, depth, desc, "spoolss_io_r_getprinter"); - depth++; - - prs_align(ps); - - prs_uint32("pointer", ps, depth, &useless_ptr); - - switch (r_u->level) - { - case 0: - { - PRINTER_INFO_0 *info; - info = r_u->ctr.printer.info0; - bufsize_required += spoolss_size_printer_info_0(info); - break; - } - case 1: - { - PRINTER_INFO_1 *info; - info = r_u->ctr.printer.info1; - bufsize_required += spoolss_size_printer_info_1(info); - break; - } - case 2: - { - PRINTER_INFO_2 *info; - info = r_u->ctr.printer.info2; - bufsize_required += spoolss_size_printer_info_2(info); - break; - } - } - - DEBUG(4,("spoolss_io_r_getprinter, size needed: %d\n",bufsize_required)); - DEBUG(4,("spoolss_io_r_getprinter, size offered: %d\n",r_u->offered)); + DEBUG(4,("spoolss_io_r_getprinter, size needed: %d\n",bufsize_required)); + DEBUG(4,("spoolss_io_r_getprinter, size offered: %d\n",r_u->offered)); /* check if the buffer is big enough for the datas */ if (r_u->offered < bufsize_required) @@ -2663,12 +2925,14 @@ BOOL spoolss_io_r_getprinter(char *desc, { PRINTER_INFO_1 *info; info = r_u->ctr.printer.info1; + /* smb_io_printer_info_1(desc, info, ps, depth, &start_offset, &end_offset); + */ if (!ps->io) { /* writing */ @@ -2680,12 +2944,14 @@ BOOL spoolss_io_r_getprinter(char *desc, { PRINTER_INFO_2 *info; info = r_u->ctr.printer.info2; + /* smb_io_printer_info_2(desc, info, ps, depth, &start_offset, &end_offset); + */ if (!ps->io) { /* writing */ @@ -2901,191 +3167,35 @@ BOOL spoolss_io_q_addjob(char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int de return True; } -/**************************************************************************** -****************************************************************************/ -void free_job_info_ctr(JOB_INFO_CTR *ctr, uint32 level, uint32 numofjobs) -{ - DEBUG(4,("free_enum_jobs_info: [%d] structs to free at level [%d]\n", - numofjobs, level)); - switch (level) - { - case 1: - { - free_job1_array(numofjobs, - ctr->job.job_info_1); - break; - } - case 2: - { - free_job2_array(numofjobs, - ctr->job.job_info_2); - break; - } - } -} - -/**************************************************************************** -****************************************************************************/ -void free_r_enumjobs(SPOOL_R_ENUMJOBS *r_u) -{ - free_job_info_ctr(&r_u->ctr, r_u->level, r_u->numofjobs); -} - /******************************************************************* ********************************************************************/ BOOL spoolss_io_r_enumjobs(char *desc, SPOOL_R_ENUMJOBS *r_u, prs_struct *ps, int depth) { - uint32 useless_ptr = 0; - uint32 start_offset, end_offset, beginning; - uint32 bufsize_required=0; - uint32 tmp_ct = 0; - int i; - prs_debug(ps, depth, desc, "spoolss_io_r_enumjobs"); depth++; - prs_align(ps); - - if (!ps->io) - { - /* writing */ - switch (r_u->level) - { - case 1: - { - for (i=0; inumofjobs; i++) - { - JOB_INFO_1 *info; - info=r_u->ctr.job.job_info_1[i]; - bufsize_required += spoolss_size_job_info_1(&(info[i])); - } - break; - } - case 2: - { - for (i=0; inumofjobs; i++) - { - JOB_INFO_2 *info; - info=r_u->ctr.job.job_info_2[i]; - - bufsize_required += spoolss_size_job_info_2(&(info[i])); - } - break; - } - } - - DEBUG(4,("spoolss_io_r_enumjobs, size needed: %d\n", - bufsize_required)); - DEBUG(4,("spoolss_io_r_enumjobs, size offered: %d\n", - r_u->offered)); - - /* check if the buffer is big enough for the datas */ - if (r_u->offeredstatus = ERROR_INSUFFICIENT_BUFFER; /* say so */ - r_u->offered = bufsize_required; - useless_ptr = 0; - - DEBUG(4,("spoolss_io_r_enumjobs, buffer too small\n")); - - } - else - { - useless_ptr = 1; - } - } - - prs_uint32("pointer", ps, depth, &useless_ptr); - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - - if (useless_ptr != 0) - { - beginning=prs_offset(ps); - start_offset=prs_offset(ps); - end_offset=start_offset+r_u->offered; + if (!prs_align(ps)) + return False; - tmp_ct = 0; - - if (ps->io) - { - /* reading */ - prs_set_offset(ps, beginning + r_u->offered); - - prs_align(ps); - prs_uint32("buffer size", ps, depth, &(bufsize_required)); - prs_uint32("numofjobs", ps, depth, &(r_u->numofjobs)); + if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer)) + return False; - prs_set_offset(ps, beginning); - } + if (!prs_align(ps)) + return False; - switch (r_u->level) - { - case 1: - { - JOB_INFO_1 *info; - for (i=0; inumofjobs; i++) - { - if (ps->io) - { - /* reading */ -/* r_u->ctr.job.job_info_1[i] = add_job1_to_array(&tmp_ct, &r_u->ctr.job.job_info_1, NULL);*/ - } - info = r_u->ctr.job.job_info_1[i]; - smb_io_job_info_1(desc, - info, - ps, - depth, - &start_offset, - &end_offset); - } - break; - } - case 2: - { - JOB_INFO_2 *info; - for (i=0; inumofjobs; i++) - { - if (ps->io) - { - /* reading */ -/* r_u->ctr.job.job_info_2[i] = add_job2_to_array(&tmp_ct, &r_u->ctr.job.job_info_2, NULL);*/ - } - info = r_u->ctr.job.job_info_2[i]; - smb_io_job_info_2(desc, - info, - ps, - depth, - &start_offset, - &end_offset); - } - break; - } + if (!prs_uint32("needed", ps, depth, &r_u->needed)) + return False; - } - prs_set_offset(ps, beginning+r_u->offered); - prs_align(ps); + if (!prs_uint32("returned", ps, depth, &r_u->returned)) + return False; - /* - * if the buffer was too small, send the minimum required size - * if it was too large, send the real needed size - */ - - prs_uint32("buffer size", ps, depth, &(bufsize_required)); - } - - prs_uint32("numofjobs", ps, depth, &(r_u->numofjobs)); - prs_uint32("status", ps, depth, &(r_u->status)); - - if (!ps->io) - { - /* writing */ - free_r_enumjobs(r_u); - } + if (!prs_uint32("status", ps, depth, &r_u->status)) + return False; - return True; + return True; } + /******************************************************************* ********************************************************************/ BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd, @@ -3102,13 +3212,13 @@ BOOL make_spoolss_q_enumjobs(SPOOL_Q_ENUMJOBS *q_u, const POLICY_HND *hnd, q_u->firstjob = firstjob; q_u->numofjobs = numofjobs; q_u->level = level; - +/* if (!make_spoolss_buffer(&q_u->buffer, buf_size)) { return False; } q_u->buf_size = buf_size; - +*/ return True; } @@ -3119,16 +3229,24 @@ BOOL spoolss_io_q_enumjobs(char *desc, SPOOL_Q_ENUMJOBS *q_u, prs_struct *ps, in prs_debug(ps, depth, desc, "spoolss_io_q_enumjobs"); depth++; - prs_align(ps); + if (!prs_align(ps)) + return False; - smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); - prs_uint32("firstjob", ps, depth, &(q_u->firstjob)); - prs_uint32("numofjobs", ps, depth, &(q_u->numofjobs)); - prs_uint32("level", ps, depth, &(q_u->level)); - - spoolss_io_read_buffer("", ps, depth, &(q_u->buffer)); + if (!smb_io_prt_hnd("printer handle",&q_u->handle, ps, depth)) + return False; + + if (!prs_uint32("firstjob", ps, depth, &q_u->firstjob)) + return False; + if (!prs_uint32("numofjobs", ps, depth, &q_u->numofjobs)) + return False; + if (!prs_uint32("level", ps, depth, &q_u->level)) + return False; - prs_uint32("buf_size", ps, depth, &(q_u->buf_size)); + if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer)) + return False; + + if (!prs_uint32("offered", ps, depth, &q_u->offered)) + return False; return True; } @@ -3198,199 +3316,72 @@ BOOL spoolss_io_q_setjob(char *desc, SPOOL_Q_SETJOB *q_u, prs_struct *ps, int de } /******************************************************************* + Parse a SPOOL_R_ENUMPRINTERDRIVERS structure. ********************************************************************/ -BOOL spoolss_io_r_enumdrivers(char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth) -{ - uint32 useless_ptr=0xADDE0FF0; - uint32 start_offset, end_offset, beginning; - uint32 bufsize_required=0; - int i; - - prs_debug(ps, depth, desc, "spoolss_io_r_enumdrivers"); +BOOL new_spoolss_io_r_enumprinterdrivers(char *desc, SPOOL_R_ENUMPRINTERDRIVERS *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "new_spoolss_io_r_enumprinterdrivers"); depth++; - prs_align(ps); - prs_uint32("pointer", ps, depth, &useless_ptr); - - DEBUG(7,("Level [%d], number [%d]\n", r_u->level, r_u->numofdrivers)); - switch (r_u->level) - { - case 1: - { - DRIVER_INFO_1 *driver_info_1; - driver_info_1=r_u->ctr.driver.info1; - - for (i=0; inumofdrivers; i++) - { - bufsize_required += spoolss_size_printer_driver_info_1(&(driver_info_1[i])); - } - break; - } - case 2: - { - DRIVER_INFO_2 *driver_info_2; - driver_info_2=r_u->ctr.driver.info2; - - for (i=0; inumofdrivers; i++) - { - bufsize_required += spoolss_size_printer_driver_info_2(&(driver_info_2[i])); - } - break; - } - case 3: - { - DRIVER_INFO_3 *driver_info_3; - driver_info_3=r_u->ctr.driver.info3; - - for (i=0; inumofdrivers; i++) - { - bufsize_required += spoolss_size_printer_driver_info_3(&(driver_info_3[i])); - } - break; - } - } - - DEBUGADD(7,("size needed: %d\n",bufsize_required)); - DEBUGADD(7,("size offered: %d\n",r_u->offered)); - - /* check if the buffer is big enough for the datas */ - - if (r_u->offeredstatus=ERROR_INSUFFICIENT_BUFFER; /* say so */ - r_u->offered=0; /* don't send back the buffer */ - DEBUGADD(8,("buffer too small\n")); + if (!prs_align(ps)) + return False; + + if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer)) + return False; - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - } - else - { - DEBUGADD(8,("buffer large enough\n")); - - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - beginning=prs_offset(ps); - start_offset=prs_offset(ps); - end_offset=start_offset+r_u->offered; + if (!prs_align(ps)) + return False; - switch (r_u->level) - { - case 1: - { - DRIVER_INFO_1 *info; - for (i=0; inumofdrivers; i++) - { - info = &(r_u->ctr.driver.info1[i]); - smb_io_printer_driver_info_1(desc, info, ps, depth, &start_offset, &end_offset); - } - break; - } - case 2: - { - DRIVER_INFO_2 *info; - for (i=0; inumofdrivers; i++) - { - info = &(r_u->ctr.driver.info2[i]); - smb_io_printer_driver_info_2(desc, info, ps, depth, &start_offset, &end_offset); - } - break; - } - case 3: - { - DRIVER_INFO_3 *info; - for (i=0; inumofdrivers; i++) - { - info = &(r_u->ctr.driver.info3[i]); - smb_io_printer_driver_info_3(desc, info, ps, depth, &start_offset, &end_offset); - } - break; - } - } - prs_set_offset(ps, beginning+r_u->offered); - prs_align(ps); - } - - /* - * if the buffer was too small, send the minimum required size - * if it was too large, send the real needed size - */ - - prs_uint32("size of buffer needed", ps, depth, &(bufsize_required)); - prs_uint32("numofdrivers", ps, depth, &(r_u->numofdrivers)); - prs_uint32("status", ps, depth, &(r_u->status)); + if (!prs_uint32("needed", ps, depth, &r_u->needed)) + return False; + + if (!prs_uint32("returned", ps, depth, &r_u->returned)) + return False; + + if (!prs_uint32("status", ps, depth, &r_u->status)) + return False; - return True; + return True; } -void free_spoolss_r_enumdrivers(SPOOL_R_ENUMPRINTERDRIVERS *r_u) -{ - switch (r_u->level) - { - case 1: - { - DRIVER_INFO_1 *driver_info_1; - driver_info_1=r_u->ctr.driver.info1; - - free(driver_info_1); - break; - } - case 2: - { - DRIVER_INFO_2 *driver_info_2; - driver_info_2=r_u->ctr.driver.info2; - - free(driver_info_2); - break; - } - case 3: - { - DRIVER_INFO_3 *driver_info_3; - - UNISTR **dependentfiles; - int i; - - driver_info_3=r_u->ctr.driver.info3; - - for (i=0; inumofdrivers; i++) - { - int j=0; - dependentfiles=(driver_info_3[i]).dependentfiles; - while ( dependentfiles[j] != NULL ) - { - free(dependentfiles[j]); - j++; - } - - free(dependentfiles); - } - free(driver_info_3); - break; - } - } -} - /******************************************************************* + Parse a SPOOL_Q_ENUMPRINTERDRIVERS structure. ********************************************************************/ BOOL spoolss_io_q_enumprinterdrivers(char *desc, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, prs_struct *ps, int depth) { - uint32 useless_ptr=0xADDE0FF0; - prs_debug(ps, depth, desc, ""); + prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdrivers"); depth++; - prs_align(ps); - prs_uint32("pointer", ps, depth, &useless_ptr); - smb_io_unistr2("", &(q_u->name),True,ps,depth); - prs_align(ps); - prs_uint32("pointer", ps, depth, &useless_ptr); - smb_io_unistr2("", &(q_u->environment),True,ps,depth); - prs_align(ps); - prs_uint32("level", ps, depth, &(q_u->level)); - spoolss_io_read_buffer("", ps, depth, &(q_u->buffer)); - prs_align(ps); - prs_uint32("buf_size", ps, depth, &(q_u->buf_size)); + if (!prs_align(ps)) + return False; + + if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr)) + return False; + if (!smb_io_unistr2("", &q_u->name, q_u->name_ptr,ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + if (!prs_uint32("environment_ptr", ps, depth, &q_u->environment_ptr)) + return False; + if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + if (!prs_uint32("level", ps, depth, &q_u->level)) + return False; + + if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("offered", ps, depth, &q_u->offered)) + return False; return True; } @@ -3451,114 +3442,61 @@ BOOL new_spoolss_io_r_enumforms(char *desc, SPOOL_R_ENUMFORMS *r_u, prs_struct * } /******************************************************************* + Parse a SPOOL_R_ENUMPORTS structure. ********************************************************************/ -BOOL spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth) -{ - uint32 useless_ptr=0xADDE0FF0; - uint32 start_offset, end_offset, beginning; - uint32 bufsize_required=0; - int i; - - prs_debug(ps, depth, desc, "spoolss_io_r_enumports"); +BOOL new_spoolss_io_r_enumports(char *desc, SPOOL_R_ENUMPORTS *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "new_spoolss_io_r_enumports"); depth++; - prs_align(ps); - prs_uint32("pointer", ps, depth, &useless_ptr); - switch (r_u->level) - { - case 2: - { - PORT_INFO_2 *port_2; - port_2=r_u->ctr.port.info_2; - - for (i=0; inumofports; i++) - { - bufsize_required += spoolss_size_port_info_2(&(port_2[i])); - } - break; - } - } - - DEBUG(4,("size needed: %d\n",bufsize_required)); - DEBUG(4,("size offered: %d\n",r_u->offered)); - - /* check if the buffer is big enough for the datas */ - if (r_u->offeredstatus=ERROR_INSUFFICIENT_BUFFER; /* say so */ - r_u->offered=0; /* don't send back the buffer */ - - DEBUG(4,("buffer too small\n")); - - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - } - else - { - DEBUG(4,("buffer large enough\n")); - - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - beginning=prs_offset(ps); - start_offset=prs_offset(ps); - end_offset=start_offset+r_u->offered; - - switch (r_u->level) - { - case 2: - { - PORT_INFO_2 *info; - for (i=0; inumofports; i++) - { - info = &(r_u->ctr.port.info_2[i]); - smb_io_port_2(desc, info, ps, depth, &start_offset, &end_offset); - } - break; - } - } - prs_set_offset(ps, beginning+r_u->offered); - prs_align(ps); - } - - /* - * if the buffer was too small, send the minimum required size - * if it was too large, send the real needed size - */ - - prs_uint32("size of buffer needed", ps, depth, &(bufsize_required)); - prs_uint32("numofports", ps, depth, &(r_u->numofports)); - prs_uint32("status", ps, depth, &(r_u->status)); + if (!prs_align(ps)) + return False; + + if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer)) + return False; - return True; -} + if (!prs_align(ps)) + return False; + + if (!prs_uint32("needed", ps, depth, &r_u->needed)) + return False; + + if (!prs_uint32("returned", ps, depth, &r_u->returned)) + return False; + + if (!prs_uint32("status", ps, depth, &r_u->status)) + return False; -void spoolss_free_r_enumports(SPOOL_R_ENUMPORTS *r_u) -{ - switch (r_u->level) - { - case 2: - { - safe_free(r_u->ctr.port.info_2); - break; - } - } + return True; } + /******************************************************************* ********************************************************************/ BOOL spoolss_io_q_enumports(char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, int depth) { - uint32 useless; prs_debug(ps, depth, desc, ""); depth++; - prs_align(ps); - prs_uint32("useless", ps, depth, &useless); - smb_io_unistr2("", &(q_u->name),True,ps,depth); - prs_align(ps); - prs_uint32("level", ps, depth, &(q_u->level)); - spoolss_io_read_buffer("", ps, depth, &(q_u->buffer)); - prs_align(ps); - prs_uint32("buf_size", ps, depth, &(q_u->buf_size)); + if (!prs_align(ps)) + return False; + + if (!prs_uint32("", ps, depth, &q_u->name_ptr)) + return False; + if (!smb_io_unistr2("", &q_u->name,True,ps,depth)) + return False; + + if (!prs_align(ps)) + return False; + if (!prs_uint32("level", ps, depth, &q_u->level)) + return False; + + if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer)) + return False; + + if (!prs_align(ps)) + return False; + if (!prs_uint32("offered", ps, depth, &q_u->offered)) + return False; return True; } @@ -4110,82 +4048,28 @@ BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q ********************************************************************/ BOOL spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth) { - uint32 useless_ptr=0xADDE0FF0; - uint32 start_offset, end_offset, beginning; - uint32 bufsize_required=0; - int i; - prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocessors"); depth++; - prs_align(ps); - prs_uint32("pointer", ps, depth, &useless_ptr); - switch (r_u->level) - { - case 1: - { - PRINTPROCESSOR_1 *info_1; - info_1=r_u->info_1; - - for (i=0; inumofprintprocessors; i++) - { - bufsize_required += spoolss_size_processor_info_1(&(info_1[i])); - } - break; - } - } - - DEBUG(4,("size needed: %d\n",bufsize_required)); - DEBUG(4,("size offered: %d\n",r_u->offered)); - - /* check if the buffer is big enough for the datas */ - if (r_u->offeredstatus=ERROR_INSUFFICIENT_BUFFER; /* say so */ - r_u->offered=0; /* don't send back the buffer */ + if (!prs_align(ps)) + return False; - DEBUG(4,("buffer too small\n")); + if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer)) + return False; - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - } - else - { - DEBUG(4,("buffer large enough\n")); - - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - beginning=prs_offset(ps); - start_offset=prs_offset(ps); - end_offset=start_offset+r_u->offered; + if (!prs_align(ps)) + return False; - switch (r_u->level) - { - case 1: - { - PRINTPROCESSOR_1 *info_1; - for (i=0; inumofprintprocessors; i++) - { - info_1 = &(r_u->info_1[i]); - smb_io_processor_info_1(desc, info_1, ps, depth, &start_offset, &end_offset); - } - break; - } - } - prs_set_offset(ps, beginning+r_u->offered); - prs_align(ps); - } - - /* - * if the buffer was too small, send the minimum required size - * if it was too large, send the real needed size - */ - - prs_uint32("size of buffer needed", ps, depth, &(bufsize_required)); - prs_uint32("numofprintprocessors", ps, depth, &(r_u->numofprintprocessors)); - prs_uint32("status", ps, depth, &(r_u->status)); + if (!prs_uint32("needed", ps, depth, &r_u->needed)) + return False; + + if (!prs_uint32("returned", ps, depth, &r_u->returned)) + return False; + + if (!prs_uint32("status", ps, depth, &r_u->status)) + return False; - return True; + return True; } /******************************************************************* @@ -4196,121 +4080,100 @@ BOOL spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocessors"); depth++; - prs_align(ps); - prs_uint32("useless", ps, depth, &useless); - smb_io_unistr2("", &(q_u->name),True,ps,depth); - prs_align(ps); - prs_uint32("useless", ps, depth, &useless); - smb_io_unistr2("", &(q_u->environment),True,ps,depth); - prs_align(ps); - prs_uint32("level", ps, depth, &(q_u->level)); - spoolss_io_read_buffer("", ps, depth, &(q_u->buffer)); - prs_align(ps); - prs_uint32("buf_size", ps, depth, &(q_u->buf_size)); + if (!prs_align(ps)) + return False; + + if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr)) + return False; + if (!smb_io_unistr2("name", &q_u->name, True, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("", ps, depth, &q_u->environment_ptr)) + return False; + if (!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("level", ps, depth, &q_u->level)) + return False; + + if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("offered", ps, depth, &q_u->offered)) + return False; return True; } /******************************************************************* + Parse a SPOOL_Q_ENUMPRINTMONITORS structure. ********************************************************************/ -BOOL spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth) -{ - uint32 useless_ptr=0xADDE0FF0; - uint32 start_offset, end_offset, beginning; - uint32 bufsize_required=0; - int i; - - prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors"); +BOOL spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors"); depth++; - prs_align(ps); - prs_uint32("pointer", ps, depth, &useless_ptr); - switch (r_u->level) - { - case 1: - { - PRINTMONITOR_1 *info_1; - info_1=r_u->info_1; - - for (i=0; inumofprintmonitors; i++) - { - bufsize_required += spoolss_size_monitor_info_1(&(info_1[i])); - } - break; - } - } - - DEBUG(4,("size needed: %d\n",bufsize_required)); - DEBUG(4,("size offered: %d\n",r_u->offered)); - - /* check if the buffer is big enough for the datas */ - if (r_u->offeredstatus=ERROR_INSUFFICIENT_BUFFER; /* say so */ - r_u->offered=0; /* don't send back the buffer */ + if (!prs_align(ps)) + return False; - DEBUG(4,("buffer too small\n")); - - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - } - else - { - DEBUG(4,("buffer large enough\n")); - - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - beginning=prs_offset(ps); - start_offset=prs_offset(ps); - end_offset=start_offset+r_u->offered; + if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr)) + return False; + if (!smb_io_unistr2("name", &q_u->name, True, ps, depth)) + return False; - switch (r_u->level) - { - case 1: - { - PRINTMONITOR_1 *info_1; - for (i=0; inumofprintmonitors; i++) - { - info_1 = &(r_u->info_1[i]); - smb_io_monitor_info_1(desc, info_1, ps, depth, &start_offset, &end_offset); - } - break; - } - } - prs_set_offset(ps, beginning+r_u->offered); - prs_align(ps); - } - - /* - * if the buffer was too small, send the minimum required size - * if it was too large, send the real needed size - */ - - prs_uint32("size of buffer needed", ps, depth, &(bufsize_required)); - prs_uint32("numofprintmonitors", ps, depth, &(r_u->numofprintmonitors)); - prs_uint32("status", ps, depth, &(r_u->status)); + if (!prs_align(ps)) + return False; + + if (!prs_uint32("level", ps, depth, &q_u->level)) + return False; + + if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("offered", ps, depth, &q_u->offered)) + return False; return True; } /******************************************************************* ********************************************************************/ -BOOL spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth) -{ - uint32 useless; - prs_debug(ps, depth, desc, "spoolss_io_q_enumprintmonitors"); +BOOL spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_enumprintmonitors"); depth++; - prs_align(ps); - prs_uint32("useless", ps, depth, &useless); - smb_io_unistr2("", &(q_u->name),True,ps,depth); - prs_align(ps); - prs_uint32("level", ps, depth, &(q_u->level)); - spoolss_io_read_buffer("", ps, depth, &(q_u->buffer)); - prs_align(ps); - prs_uint32("buf_size", ps, depth, &(q_u->buf_size)); + if (!prs_align(ps)) + return False; + + if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer)) + return False; - return True; + if (!prs_align(ps)) + return False; + + if (!prs_uint32("needed", ps, depth, &r_u->needed)) + return False; + + if (!prs_uint32("returned", ps, depth, &r_u->returned)) + return False; + + if (!prs_uint32("status", ps, depth, &r_u->status)) + return False; + + return True; } /******************************************************************* diff --git a/source/rpc_server/srv_pipe_srv.c b/source/rpc_server/srv_pipe_srv.c index 2cebc8148ba..6e8b3067600 100644 --- a/source/rpc_server/srv_pipe_srv.c +++ b/source/rpc_server/srv_pipe_srv.c @@ -796,7 +796,7 @@ static BOOL api_pipe_bind_and_alt_req(pipes_struct *p, prs_struct *pd, enum RPC_ * Create the header, now we know the length. */ - init_rpc_hdr(&p->hdr, RPC_BINDACK, RPC_FLG_FIRST | RPC_FLG_LAST, + init_rpc_hdr(&p->hdr, pkt_type, RPC_FLG_FIRST | RPC_FLG_LAST, p->hdr.call_id, RPC_HEADER_LEN + prs_offset(&out_hdr_ba) + prs_offset(&out_auth), auth_len); diff --git a/source/rpc_server/srv_spoolss.c b/source/rpc_server/srv_spoolss.c index 60333e1f3b4..50b6dd38460 100755 --- a/source/rpc_server/srv_spoolss.c +++ b/source/rpc_server/srv_spoolss.c @@ -107,10 +107,18 @@ static BOOL api_spoolss_closeprinter(uint16 vuid, prs_struct *data, prs_struct * ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_closeprinter("", &q_u, data, 0); + if (!spoolss_io_q_closeprinter("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_closeprinter: unable to unmarshall SPOOL_Q_CLOSEPRINTER.\n")); + return False; + } + r_u.status = _spoolss_closeprinter(&q_u.handle); memcpy(&r_u.handle, &q_u.handle, sizeof(r_u.handle)); - spoolss_io_r_closeprinter("",&r_u,rdata,0); + + if (!spoolss_io_r_closeprinter("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_closeprinter: unable to marshall SPOOL_R_CLOSEPRINTER.\n")); + return False; + } } /******************************************************************** @@ -125,12 +133,19 @@ static BOOL api_spoolss_rffpcnex(uint16 vuid, prs_struct *data, prs_struct *rdat ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_rffpcnex("", &q_u, data, 0); + if (!spoolss_io_q_rffpcnex("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_rffpcnex: unable to unmarshall SPOOL_Q_RFFPCNEX.\n")); + return False; + } r_u.status = _spoolss_rffpcnex(&q_u.handle, q_u.flags, q_u.options, &q_u.localmachine, q_u.printerlocal, &q_u.option); - spoolss_io_r_rffpcnex("",&r_u,rdata,0); + + if (!spoolss_io_r_rffpcnex("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_rffpcnex: unable to marshall SPOOL_R_RFFPCNEX.\n")); + return False; + } } @@ -148,11 +163,18 @@ static BOOL api_spoolss_rfnpcnex(uint16 vuid, prs_struct *data, prs_struct *rdat ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_rfnpcnex("", &q_u, data, 0); + if (!spoolss_io_q_rfnpcnex("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_rfnpcnex: unable to unmarshall SPOOL_Q_RFNPCNEX.\n")); + return False; + } r_u.status = _spoolss_rfnpcnex(&q_u.handle, q_u.change, &q_u.option, &r_u.count, &r_u.info); - spoolss_io_r_rfnpcnex("", &r_u, rdata, 0); + + if (!spoolss_io_r_rfnpcnex("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_rfnpcnex: unable to marshall SPOOL_R_RFNPCNEX.\n")); + return False; + } } @@ -169,32 +191,33 @@ static BOOL api_spoolss_enumprinters(uint16 vuid, prs_struct *data, prs_struct * ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_enumprinters("", &q_u, data, 0); + DEBUG(5,("api_spoolss_enumprinters\n")); - /* lkclXXX DAMN DAMN DAMN! MICROSOFT @#$%S IT UP, AGAIN, AND WE - HAVE TO DEAL WITH IT! AGH! - */ - r_u.level = q_u.level; - r_u.status = _spoolss_enumprinters( - q_u.flags, - &q_u.servername, - q_u.level, - &q_u.buffer, - q_u.buf_size, - &r_u.offered, - &r_u.needed, - &r_u.ctr, - &r_u.returned); + new_spoolss_allocate_buffer(&q_u.buffer); + + if (!spoolss_io_q_enumprinters("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_enumprinters: unable to unmarshall SPOOL_Q_ENUMPRINTERS.\n")); + return False; + } + + /* that's an [in out] buffer */ + new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); + + r_u.status = _spoolss_enumprinters( q_u.flags, &q_u.servername, q_u.level, + r_u.buffer, q_u.offered, + &r_u.needed, &r_u.returned); - memcpy(r_u.servername.buffer,q_u.servername.buffer, - 2*q_u.servername.uni_str_len); - r_u.servername.buffer[q_u.servername.uni_str_len] = 0; + if (!new_spoolss_io_r_enumprinters("", &r_u, rdata, 0)) { + DEBUG(0,("new_spoolss_io_r_enumprinters: unable to marshall SPOOL_R_ENUMPRINTERS.\n")); + new_spoolss_free_buffer(q_u.buffer); + return False; + } - spoolss_io_free_buffer(&(q_u.buffer)); - spoolss_io_r_enumprinters("",&r_u,rdata,0); + new_spoolss_free_buffer(q_u.buffer); + + return True; } - /******************************************************************** * api_spoolss_getprinter * called from the spoolss dispatcher @@ -208,7 +231,10 @@ static BOOL api_spoolss_getprinter(uint16 vuid, prs_struct *data, prs_struct *rd ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_getprinter("", &q_u, data, 0); + if(!spoolss_io_q_getprinter("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_getprinter: unable to unmarshall SPOOL_Q_GETPRINTER.\n")); + return False; + } r_u.status = _spoolss_getprinter(&q_u.handle, q_u.level, &r_u.ctr, &q_u.offered, &r_u.needed); @@ -218,7 +244,12 @@ static BOOL api_spoolss_getprinter(uint16 vuid, prs_struct *data, prs_struct *rd r_u.level = q_u.level; safe_free(q_u.buffer); - spoolss_io_r_getprinter("",&r_u,rdata,0); + if(!spoolss_io_r_getprinter("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_getprinter: unable to marshall SPOOL_R_GETPRINTER.\n")); + return False; + } + + return True; } @@ -235,7 +266,10 @@ static BOOL api_spoolss_getprinterdriver2(uint16 vuid, prs_struct *data, prs_str ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_getprinterdriver2("", &q_u, data, 0); + if(!spoolss_io_q_getprinterdriver2("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_getprinterdriver2: unable to unmarshall SPOOL_Q_GETPRINTERDRIVER2.\n")); + return False; + } r_u.status = _spoolss_getprinterdriver2(&q_u.handle, &q_u.architecture, q_u.level, @@ -246,7 +280,12 @@ static BOOL api_spoolss_getprinterdriver2(uint16 vuid, prs_struct *data, prs_str r_u.level = q_u.level; spoolss_io_free_buffer(&(q_u.buffer)); - spoolss_io_r_getprinterdriver2("",&r_u,rdata,0); + if(!spoolss_io_r_getprinterdriver2("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_getprinterdriver2: unable to marshall SPOOL_R_GETPRINTERDRIVER2.\n")); + return False; + } + + return True; } /******************************************************************** @@ -262,9 +301,19 @@ static BOOL api_spoolss_startpageprinter(uint16 vuid, prs_struct *data, prs_stru ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_startpageprinter("", &q_u, data, 0); + if(!spoolss_io_q_startpageprinter("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_startpageprinter: unable to unmarshall SPOOL_Q_STARTPAGEPRINTER.\n")); + return False; + } + r_u.status = _spoolss_startpageprinter(&q_u.handle); - spoolss_io_r_startpageprinter("",&r_u,rdata,0); + + if(!spoolss_io_r_startpageprinter("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_startpageprinter: unable to marshall SPOOL_R_STARTPAGEPRINTER.\n")); + return False; + } + + return True; } @@ -281,9 +330,19 @@ static BOOL api_spoolss_endpageprinter(uint16 vuid, prs_struct *data, prs_struct ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_endpageprinter("", &q_u, data, 0); + if(!spoolss_io_q_endpageprinter("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_endpageprinter: unable to unmarshall SPOOL_Q_ENDPAGEPRINTER.\n")); + return False; + } + r_u.status = _spoolss_endpageprinter(&q_u.handle); - spoolss_io_r_endpageprinter("",&r_u,rdata,0); + + if(!spoolss_io_r_endpageprinter("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_endpageprinter: unable to marshall SPOOL_R_ENDPAGEPRINTER.\n")); + return False; + } + + return True; } /******************************************************************** @@ -299,12 +358,22 @@ static BOOL api_spoolss_startdocprinter(uint16 vuid, prs_struct *data, prs_struc ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_startdocprinter("", &q_u, data, 0); + if(!spoolss_io_q_startdocprinter("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_startdocprinter: unable to unmarshall SPOOL_Q_STARTDOCPRINTER.\n")); + return False; + } + r_u.status = _spoolss_startdocprinter(&q_u.handle, q_u.doc_info_container.level, &q_u.doc_info_container.docinfo, &r_u.jobid); - spoolss_io_r_startdocprinter("",&r_u,rdata,0); + + if(!spoolss_io_r_startdocprinter("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_startdocprinter: unable to marshall SPOOL_R_STARTDOCPRINTER.\n")); + return False; + } + + return True; } /******************************************************************** @@ -320,9 +389,19 @@ static BOOL api_spoolss_enddocprinter(uint16 vuid, prs_struct *data, prs_struct ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_enddocprinter("", &q_u, data, 0); + if(!spoolss_io_q_enddocprinter("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_enddocprinter: unable to unmarshall SPOOL_Q_ENDDOCPRINTER.\n")); + return False; + } + r_u.status = _spoolss_enddocprinter(&q_u.handle); - spoolss_io_r_enddocprinter("",&r_u,rdata,0); + + if(!spoolss_io_r_enddocprinter("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_enddocprinter: unable to marshall SPOOL_R_ENDDOCPRINTER.\n")); + return False; + } + + return True; } @@ -339,14 +418,24 @@ static BOOL api_spoolss_writeprinter(uint16 vuid, prs_struct *data, prs_struct * ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_writeprinter("", &q_u, data, 0); + if(!spoolss_io_q_writeprinter("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_writeprinter: unable to unmarshall SPOOL_Q_WRITEPRINTER.\n")); + return False; + } + r_u.status = _spoolss_writeprinter(&q_u.handle, q_u.buffer_size, q_u.buffer, &q_u.buffer_size2); r_u.buffer_written = q_u.buffer_size2; safe_free(q_u.buffer); - spoolss_io_r_writeprinter("",&r_u,rdata,0); + + if(!spoolss_io_r_writeprinter("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_writeprinter: unable to marshall SPOOL_R_WRITEPRINTER.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -359,7 +448,11 @@ static BOOL api_spoolss_setprinter(uint16 vuid, prs_struct *data, prs_struct *rd ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_setprinter("", &q_u, data, 0); + if(!spoolss_io_q_setprinter("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_setprinter: unable to unmarshall SPOOL_Q_SETPRINTER.\n")); + return False; + } + DEBUG(0,("api_spoolss_setprinter: typecast sec_des to uint8*!\n")); r_u.status = _spoolss_setprinter(&q_u.handle, q_u.level, &q_u.info, @@ -367,7 +460,13 @@ static BOOL api_spoolss_setprinter(uint16 vuid, prs_struct *data, prs_struct *rd q_u.security.size_of_buffer, (const uint8*)q_u.security.data, q_u.command); - spoolss_io_r_setprinter("",&r_u,rdata,0); + + if(!spoolss_io_r_setprinter("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_setprinter: unable to marshall SPOOL_R_SETPRINTER.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -380,9 +479,19 @@ static BOOL api_spoolss_fcpn(uint16 vuid, prs_struct *data, prs_struct *rdata) ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_fcpn("", &q_u, data, 0); + if(!spoolss_io_q_fcpn("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_fcpn: unable to unmarshall SPOOL_Q_FCPN.\n")); + return False; + } + r_u.status = _spoolss_fcpn(&q_u.handle); - spoolss_io_r_fcpn("",&r_u,rdata,0); + + if(!spoolss_io_r_fcpn("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_fcpn: unable to marshall SPOOL_R_FCPN.\n")); + return False; + } + + return True; } @@ -396,13 +505,22 @@ static BOOL api_spoolss_addjob(uint16 vuid, prs_struct *data, prs_struct *rdata) ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_addjob("", &q_u, data, 0); + if(!spoolss_io_q_addjob("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_addjob: unable to unmarshall SPOOL_Q_ADDJOB.\n")); + return False; + } r_u.status = _spoolss_addjob(&q_u.handle, q_u.level, &q_u.buffer, q_u.buf_size); spoolss_io_free_buffer(&(q_u.buffer)); - spoolss_io_r_addjob("",&r_u,rdata,0); + + if(!spoolss_io_r_addjob("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_addjob: unable to marshall SPOOL_R_ADDJOB.\n")); + return False; + } + + return True; } @@ -415,15 +533,30 @@ static BOOL api_spoolss_enumjobs(uint16 vuid, prs_struct *data, prs_struct *rdat ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); + + new_spoolss_allocate_buffer(&q_u.buffer); + + if (!spoolss_io_q_enumjobs("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_enumjobs: unable to unmarshall SPOOL_Q_ENUMJOBS.\n")); + return False; + } + + /* that's an [in out] buffer */ + new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); + + r_u.status = _spoolss_enumjobs(&q_u.handle, q_u.firstjob, q_u.numofjobs, q_u.level, + r_u.buffer, q_u.offered, + &r_u.needed, &r_u.returned); + + if (!spoolss_io_r_enumjobs("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_enumjobs: unable to marshall SPOOL_R_ENUMJOBS.\n")); + new_spoolss_free_buffer(q_u.buffer); + return False; + } + + new_spoolss_free_buffer(q_u.buffer); - spoolss_io_q_enumjobs("", &q_u, data, 0); - r_u.offered = q_u.buf_size; - r_u.level = q_u.level; - r_u.status = _spoolss_enumjobs(&q_u.handle, - q_u.firstjob, q_u.numofjobs, q_u.level, - &r_u.ctr, &r_u.offered, &r_u.numofjobs); - spoolss_io_free_buffer(&(q_u.buffer)); - spoolss_io_r_enumjobs("",&r_u,rdata,0); + return True; } @@ -437,9 +570,19 @@ static BOOL api_spoolss_schedulejob(uint16 vuid, prs_struct *data, prs_struct *r ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_schedulejob("", &q_u, data, 0); + if(!spoolss_io_q_schedulejob("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_schedulejob: unable to unmarshall SPOOL_Q_SCHEDULEJOB.\n")); + return False; + } + r_u.status = _spoolss_schedulejob(&q_u.handle, q_u.jobid); - spoolss_io_r_schedulejob("",&r_u,rdata,0); + + if(!spoolss_io_r_schedulejob("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_schedulejob: unable to marshall SPOOL_R_SCHEDULEJOB.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -452,10 +595,20 @@ static BOOL api_spoolss_setjob(uint16 vuid, prs_struct *data, prs_struct *rdata) ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_setjob("", &q_u, data, 0); + if(!spoolss_io_q_setjob("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_setjob: unable to unmarshall SPOOL_Q_SETJOB.\n")); + return False; + } + r_u.status = _spoolss_setjob(&q_u.handle, q_u.jobid, q_u.level, &q_u.ctr, q_u.command); - spoolss_io_r_setjob("",&r_u,rdata,0); + + if(!spoolss_io_r_setjob("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_setjob: unable to marshall SPOOL_R_SETJOB.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -468,18 +621,30 @@ static BOOL api_spoolss_enumprinterdrivers(uint16 vuid, prs_struct *data, prs_st ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - - spoolss_io_q_enumprinterdrivers("", &q_u, data, 0); - r_u.offered = q_u.buf_size; - r_u.level = q_u.level; - r_u.status = _spoolss_enumprinterdrivers(&q_u.name, - &q_u.environment, q_u. level, - &r_u.ctr, &r_u.offered, &r_u.numofdrivers); + new_spoolss_allocate_buffer(&q_u.buffer); - spoolss_io_free_buffer(&q_u.buffer); - spoolss_io_r_enumdrivers("",&r_u,rdata,0); - free_spoolss_r_enumdrivers(&r_u); + if (!spoolss_io_q_enumprinterdrivers("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_enumprinterdrivers: unable to unmarshall SPOOL_Q_ENUMPRINTERDRIVERS.\n")); + return False; + } + + /* that's an [in out] buffer */ + new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); + + r_u.status = _spoolss_enumprinterdrivers(&q_u.name, &q_u.environment, q_u.level, + r_u.buffer, q_u.offered, + &r_u.needed, &r_u.returned); + + if (!new_spoolss_io_r_enumprinterdrivers("",&r_u,rdata,0)) { + DEBUG(0,("new_spoolss_io_r_enumprinterdrivers: unable to marshall SPOOL_R_ENUMPRINTERDRIVERS.\n")); + new_spoolss_free_buffer(q_u.buffer); + return False; + } + + new_spoolss_free_buffer(q_u.buffer); + + return True; } @@ -493,12 +658,12 @@ static BOOL api_spoolss_enumforms(uint16 vuid, prs_struct *data, prs_struct *rda ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - DEBUG(5,("spoolss_io_q_enumforms\n")); - new_spoolss_allocate_buffer(&q_u.buffer); - if (!spoolss_io_q_enumforms("", &q_u, data, 0)) + if (!spoolss_io_q_enumforms("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_enumforms: unable to unmarshall SPOOL_Q_ENUMFORMS.\n")); return False; + } /* that's an [in out] buffer */ new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); @@ -508,6 +673,7 @@ static BOOL api_spoolss_enumforms(uint16 vuid, prs_struct *data, prs_struct *rda &r_u.needed, &r_u.numofforms); if (!new_spoolss_io_r_enumforms("",&r_u,rdata,0)) { + DEBUG(0,("new_spoolss_io_r_enumforms: unable to marshall SPOOL_R_ENUMFORMS.\n")); new_spoolss_free_buffer(q_u.buffer); return False; } @@ -527,20 +693,30 @@ static BOOL api_spoolss_enumports(uint16 vuid, prs_struct *data, prs_struct *rda ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - - spoolss_io_q_enumports("", &q_u, data, 0); - r_u.offered = q_u.buf_size; - r_u.level = q_u.level; - r_u.status = _spoolss_enumports(&q_u.name, - q_u.level, - &r_u.ctr, - &r_u.offered, - &r_u.numofports); + new_spoolss_allocate_buffer(&q_u.buffer); + + if(!spoolss_io_q_enumports("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_enumports: unable to unmarshall SPOOL_Q_ENUMPORTS.\n")); + return False; + } + + /* that's an [in out] buffer */ + new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); - spoolss_io_free_buffer(&(q_u.buffer)); - spoolss_io_r_enumports("",&r_u,rdata,0); - spoolss_free_r_enumports(&r_u); + r_u.status = _spoolss_enumports(&q_u.name, q_u.level, + r_u.buffer, q_u.offered, + &r_u.needed, &r_u.returned); + + if (!new_spoolss_io_r_enumports("",&r_u,rdata,0)) { + DEBUG(0,("new_spoolss_io_r_enumports: unable to marshall SPOOL_R_ENUMPORTS.\n")); + new_spoolss_free_buffer(q_u.buffer); + return False; + } + + new_spoolss_free_buffer(q_u.buffer); + + return True; } @@ -554,13 +730,23 @@ static BOOL api_spoolss_addprinterex(uint16 vuid, prs_struct *data, prs_struct * ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_addprinterex("", &q_u, data, 0); + if(!spoolss_io_q_addprinterex("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_addprinterex: unable to unmarshall SPOOL_Q_ADDPRINTEREX.\n")); + return False; + } + r_u.status = _spoolss_addprinterex(&q_u.server_name, q_u.level, &q_u.info, q_u.unk0, q_u.unk1, q_u.unk2, q_u.unk3, q_u.user_level, &q_u.user, &r_u.handle); - spoolss_io_r_addprinterex("", &r_u, rdata, 0); + + if(!spoolss_io_r_addprinterex("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_addprinterex: unable to marshall SPOOL_R_ADDPRINTEREX.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -573,10 +759,20 @@ static BOOL api_spoolss_addprinterdriver(uint16 vuid, prs_struct *data, prs_stru ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_addprinterdriver("", &q_u, data, 0); + if(!spoolss_io_q_addprinterdriver("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_addprinterdriver: unable to unmarshall SPOOL_Q_ADDPRINTERDRIVER.\n")); + return False; + } + r_u.status = _spoolss_addprinterdriver(&q_u.server_name, q_u.level, &q_u.info); - spoolss_io_r_addprinterdriver("", &r_u, rdata, 0); + + if(!spoolss_io_r_addprinterdriver("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_addprinterdriver: unable to marshall SPOOL_R_ADDPRINTERDRIVER.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -586,7 +782,10 @@ static BOOL api_spoolss_getprinterdriverdirectory(uint16 vuid, prs_struct *data, SPOOL_Q_GETPRINTERDRIVERDIR q_u; SPOOL_R_GETPRINTERDRIVERDIR r_u; - spoolss_io_q_getprinterdriverdir("", &q_u, data, 0); + if(!spoolss_io_q_getprinterdriverdir("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_getprinterdriverdir: unable to unmarshall SPOOL_Q_GETPRINTERDRIVERDIR.\n")); + return False; + } r_u.offered = q_u.buf_size; r_u.level = q_u.level; @@ -596,7 +795,13 @@ static BOOL api_spoolss_getprinterdriverdirectory(uint16 vuid, prs_struct *data, &r_u.ctr, &r_u.offered); spoolss_io_free_buffer(&q_u.buffer); - spoolss_io_r_getprinterdriverdir("", &r_u, rdata, 0); + + if(!spoolss_io_r_getprinterdriverdir("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_getprinterdriverdir: unable to marshall SPOOL_R_GETPRINTERDRIVERDIR.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -609,7 +814,11 @@ static BOOL api_spoolss_enumprinterdata(uint16 vuid, prs_struct *data, prs_struc ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_enumprinterdata("", &q_u, data, 0); + if(!spoolss_io_q_enumprinterdata("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_enumprinterdata: unable to unmarshall SPOOL_Q_ENUMPRINTERDATA.\n")); + return False; + } + r_u.valuesize = q_u.valuesize; r_u.datasize = q_u.datasize; @@ -622,8 +831,15 @@ static BOOL api_spoolss_enumprinterdata(uint16 vuid, prs_struct *data, prs_struc &r_u.datasize,/* in out */ &r_u.data,/* out */ &r_u.realdatasize);/* out */ - spoolss_io_r_enumprinterdata("", &r_u, rdata, 0); + + if(!spoolss_io_r_enumprinterdata("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_enumprinterdata: unable to marshall SPOOL_R_ENUMPRINTERDATA.\n")); + return False; + } + safe_free(r_u.data); + + return True; } /**************************************************************************** @@ -636,12 +852,21 @@ static BOOL api_spoolss_setprinterdata(uint16 vuid, prs_struct *data, prs_struct ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_setprinterdata("", &q_u, data, 0); + if(!spoolss_io_q_setprinterdata("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_setprinterdata: unable to unmarshall SPOOL_Q_SETPRINTERDATA.\n")); + return False; + } + r_u.status = _spoolss_setprinterdata(&q_u.handle, &q_u.value, q_u.type, q_u.max_len, q_u.data, q_u.real_len, q_u.numeric_data); - spoolss_io_r_setprinterdata("", &r_u, rdata, 0); - safe_free(q_u.data); + + if(!spoolss_io_r_setprinterdata("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_setprinterdata: unable to marshall SPOOL_R_SETPRINTERDATA.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -654,9 +879,19 @@ static BOOL api_spoolss_addform(uint16 vuid, prs_struct *data, prs_struct *rdata ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_addform("", &q_u, data, 0); + if(!spoolss_io_q_addform("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_addform: unable to unmarshall SPOOL_Q_ADDFORM.\n")); + return False; + } + r_u.status = _spoolss_addform(&q_u.handle, q_u.level, &q_u.form); - spoolss_io_r_addform("", &r_u, rdata, 0); + + if(!spoolss_io_r_addform("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_addform: unable to marshall SPOOL_R_ADDFORM.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -669,10 +904,20 @@ static BOOL api_spoolss_setform(uint16 vuid, prs_struct *data, prs_struct *rdata ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_setform("", &q_u, data, 0); + if(!spoolss_io_q_setform("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_setform: unable to unmarshall SPOOL_Q_SETFORM.\n")); + return False; + } + r_u.status = _spoolss_setform(&q_u.handle, &q_u.name, q_u.level, &q_u.form); - spoolss_io_r_setform("", &r_u, rdata, 0); + + if(!spoolss_io_r_setform("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_setform: unable to marshall SPOOL_R_SETFORM.\n")); + return False; + } + + return True; } /**************************************************************************** @@ -685,18 +930,29 @@ static BOOL api_spoolss_enumprintprocessors(uint16 vuid, prs_struct *data, prs_s ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_enumprintprocessors("", &q_u, data, 0); - r_u.offered = q_u.buf_size; - r_u.level = q_u.level; - r_u.status = _spoolss_enumprintprocessors(&q_u.name, - &q_u.environment, - q_u.level, - &r_u.info_1, - &r_u.offered, - &r_u.numofprintprocessors); - spoolss_io_free_buffer(&q_u.buffer); - spoolss_io_r_enumprintprocessors("", &r_u, rdata, 0); - safe_free(r_u.info_1); + new_spoolss_allocate_buffer(&q_u.buffer); + + if(!spoolss_io_q_enumprintprocessors("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_enumprintprocessors: unable to unmarshall SPOOL_Q_ENUMPRINTPROCESSORS.\n")); + return False; + } + + /* that's an [in out] buffer */ + new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); + + r_u.status = _spoolss_enumprintprocessors(&q_u.name, &q_u.environment, q_u.level, + r_u.buffer, q_u.offered, + &r_u.needed, &r_u.returned); + + if(!spoolss_io_r_enumprintprocessors("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_enumprintprocessors: unable to marshall SPOOL_R_ENUMPRINTPROCESSORS.\n")); + new_spoolss_free_buffer(q_u.buffer); + return False; + } + + new_spoolss_free_buffer(q_u.buffer); + + return True; } /**************************************************************************** @@ -709,17 +965,29 @@ static BOOL api_spoolss_enumprintmonitors(uint16 vuid, prs_struct *data, prs_str ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - spoolss_io_q_enumprintmonitors("", &q_u, data, 0); - r_u.offered = q_u.buf_size; - r_u.level = q_u.level; - r_u.status = _spoolss_enumprintmonitors(&q_u.name, - q_u.level, - &r_u.info_1, - &r_u.offered, - &r_u.numofprintmonitors); - spoolss_io_free_buffer(&q_u.buffer); - spoolss_io_r_enumprintmonitors("", &r_u, rdata, 0); - safe_free(r_u.info_1); + new_spoolss_allocate_buffer(&q_u.buffer); + + if (!spoolss_io_q_enumprintmonitors("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_enumprintmonitors: unable to unmarshall SPOOL_Q_ENUMPRINTMONITORS.\n")); + return False; + } + + /* that's an [in out] buffer */ + new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); + + r_u.status = _spoolss_enumprintmonitors(&q_u.name, q_u.level, + r_u.buffer, q_u.offered, + &r_u.needed, &r_u.returned); + + if (!spoolss_io_r_enumprintmonitors("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_enumprintmonitors: unable to marshall SPOOL_R_ENUMPRINTMONITORS.\n")); + new_spoolss_free_buffer(q_u.buffer); + return False; + } + + new_spoolss_free_buffer(q_u.buffer); + + return True; } /**************************************************************************** @@ -729,7 +997,10 @@ static BOOL api_spoolss_getjob(uint16 vuid, prs_struct *data, prs_struct *rdata) SPOOL_Q_GETJOB q_u; SPOOL_R_GETJOB r_u; - spoolss_io_q_getjob("", &q_u, data, 0); + if(!spoolss_io_q_getjob("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_getjob: unable to unmarshall SPOOL_Q_GETJOB.\n")); + return False; + } r_u.offered = q_u.buf_size; r_u.level = q_u.level; @@ -739,8 +1010,15 @@ static BOOL api_spoolss_getjob(uint16 vuid, prs_struct *data, prs_struct *rdata) &r_u.ctr, &r_u.offered); spoolss_io_free_buffer(&(q_u.buffer)); - spoolss_io_r_getjob("",&r_u,rdata,0); + + if(!spoolss_io_r_getjob("",&r_u,rdata,0)) { + DEBUG(0,("spoolss_io_r_getjob: unable to marshall SPOOL_R_GETJOB.\n")); + return False; + } + free_spoolss_r_getjob(&r_u); + + return True; } /******************************************************************* diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c index d25281cea52..2e80cbdbf6f 100644 --- a/source/rpc_server/srv_spoolss_nt.c +++ b/source/rpc_server/srv_spoolss_nt.c @@ -200,11 +200,8 @@ static BOOL open_printer_hnd(POLICY_HND *hnd) { if (!Printer[i].open) { - Printer[i].open = True; - Printer[i].ok = True; - + Printer[i].open = True; memcpy(&(Printer[i].printer_hnd), hnd, sizeof(*hnd)); - DEBUG(4,("Opened printer handle[%x] ", i)); dump_data(4, hnd->data, sizeof(hnd->data)); return True; @@ -221,32 +218,14 @@ static BOOL set_printer_hnd_accesstype(POLICY_HND *hnd, uint32 access_required) { int pnum = find_printer_index_by_hnd(hnd); - if (OPEN_HANDLE(pnum)) { - DEBUG(4,("Setting printer access=%x (pnum=%x)\n", access_required, pnum)); - Printer[pnum].access = access_required; - return True; - } - else { + if (!OPEN_HANDLE(pnum)) { DEBUG(4,("Error setting printer type=%x (pnum=%x)", access_required, pnum)); return False; } - return False; -} - -/**************************************************************************** - . -****************************************************************************/ -static BOOL printer_entry_is_valid(POLICY_HND *hnd) -{ - int pnum = find_printer_index_by_hnd(hnd); - if (!OPEN_HANDLE(pnum)) - return False; - - if (Printer[pnum].ok == False) - return False; - - return True; + DEBUG(4,("Setting printer access=%x (pnum=%x)\n", access_required, pnum)); + Printer[pnum].access = access_required; + return True; } /**************************************************************************** @@ -266,23 +245,19 @@ static BOOL set_printer_hnd_printertype(POLICY_HND *hnd, char *printername) if ( strlen(printername) < 3 ) { DEBUGADD(4,("A print server must have at least 1 char ! %s\n", printername)); - Printer[pnum].ok=False; return False; } /* it's a print server */ if (!strchr(printername+2, '\\')) { DEBUGADD(4,("Printer is a print server\n")); - Printer[pnum].printer_type = PRINTER_HANDLE_IS_PRINTSERVER; - Printer[pnum].ok=True; - + Printer[pnum].printer_type = PRINTER_HANDLE_IS_PRINTSERVER; return True; } /* it's a printer */ else { DEBUGADD(4,("Printer is a printer\n")); Printer[pnum].printer_type = PRINTER_HANDLE_IS_PRINTER; - Printer[pnum].ok=True; return True; } @@ -295,11 +270,11 @@ static BOOL set_printer_hnd_printertype(POLICY_HND *hnd, char *printername) static BOOL set_printer_hnd_printername(POLICY_HND *hnd, char *printername) { int pnum = find_printer_index_by_hnd(hnd); - char *back; NT_PRINTER_INFO_LEVEL printer; int snum; int n_services=lp_numservices(); - uint32 marche; + char *aprinter; + BOOL found=False; if (!OPEN_HANDLE(pnum)) { @@ -309,54 +284,66 @@ static BOOL set_printer_hnd_printername(POLICY_HND *hnd, char *printername) DEBUG(4,("Setting printer name=%s (len=%d) (pnum=%x)\n", printername, strlen(printername), pnum)); - switch (Printer[pnum].printer_type) { - case PRINTER_HANDLE_IS_PRINTSERVER: + if (Printer[pnum].printer_type==PRINTER_HANDLE_IS_PRINTSERVER) { ZERO_STRUCT(Printer[pnum].dev.printerservername); strncpy(Printer[pnum].dev.printerservername, printername, strlen(printername)); return True; - break; + } - case PRINTER_HANDLE_IS_PRINTER: - back=strchr(printername+2, '\\'); - back=back+1; - DEBUGADD(5,("searching for %s (len=%d)\n", back,strlen(back))); - /* - * store the Samba share name in it - * in back we have the long printer name - * need to iterate all the snum and do a - * get_a_printer each time to find the printer - * faster to do it here than later. - */ - for (snum=0;snumprintername) == strlen(back) ) - && ( !strncasecmp(printer.info_2->printername, back, strlen(back))) - ) { - DEBUGADD(4,("Printer found: %s[%x]\n",lp_servicename(snum),snum)); - ZERO_STRUCT(Printer[pnum].dev.printername); - strncpy(Printer[pnum].dev.printername, lp_servicename(snum), strlen(lp_servicename(snum))); - free_a_printer(printer, 2); - return True; - break; - } - free_a_printer(printer, 2); - } - } + if (Printer[pnum].printer_type!=PRINTER_HANDLE_IS_PRINTER) return False; - break; - - default: + + aprinter=strchr(printername+2, '\\'); + aprinter++; + + DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter, strlen(aprinter))); + /* + * store the Samba share name in it + * in back we have the long printer name + * need to iterate all the snum and do a + * get_a_printer each time to find the printer + * faster to do it here than later. + */ + + for (snum=0;snumprintername) != strlen(aprinter) ) { + free_a_printer(printer, 2); + continue; + } + + if ( strncasecmp(printer.info_2->printername, aprinter, strlen(aprinter))) { + free_a_printer(printer, 2); + continue; + } + + found=True; + } + + if (found==False) + { + DEBUGADD(4,("Printer not found\n")); return False; - break; - } + } + + DEBUGADD(4,("Printer found: %s[%x]\n",lp_servicename(snum),snum)); + ZERO_STRUCT(Printer[pnum].dev.printername); + strncpy(Printer[pnum].dev.printername, lp_servicename(snum), strlen(lp_servicename(snum))); + free_a_printer(printer, 2); + + return True; } /******************************************************************** + Return True is the handle is a print server. ********************************************************************/ static BOOL handle_is_printserver(const POLICY_HND *handle) { @@ -371,6 +358,30 @@ static BOOL handle_is_printserver(const POLICY_HND *handle) return True; } +/**************************************************************************** + allocate more memory for a BUFFER. +****************************************************************************/ +static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size) +{ + prs_struct *ps; + uint32 extra_space; + + ps=&(buffer->prs); + + /* damn, I'm doing the reverse operation of prs_grow() :) */ + if (buffer_size < prs_data_size(ps)) + extra_space=0; + else + extra_space = buffer_size - prs_data_size(ps); + + if (!prs_grow(ps, extra_space)) + return False; + + buffer->string_at_end=prs_data_size(ps); + + return True; +} + /******************************************************************** * spoolss_open_printer * @@ -400,9 +411,15 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername, open_printer_hnd(handle); - set_printer_hnd_printertype(handle, name); + if (!set_printer_hnd_printertype(handle, name)) { + close_printer_handle(handle); + return NT_STATUS_ACCESS_DENIED; + } - set_printer_hnd_printername(handle, name); + if (!set_printer_hnd_printername(handle, name)) { + close_printer_handle(handle); + return NT_STATUS_ACCESS_DENIED; + } /* if (printer_default->datatype_ptr != NULL) @@ -414,14 +431,11 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername, set_printer_hnd_datatype(handle, ""); */ - set_printer_hnd_accesstype(handle, printer_default->access_required); - - if (!printer_entry_is_valid(handle)) - { + if (!set_printer_hnd_accesstype(handle, printer_default->access_required)) { close_printer_handle(handle); return NT_STATUS_ACCESS_DENIED; } - + return NT_STATUS_NO_PROBLEMO; } @@ -536,7 +550,8 @@ uint32 _spoolss_closeprinter(POLICY_HND *handle) } /******************************************************************** - ********************************************************************/ + GetPrinterData on a printer server Handle. +********************************************************************/ static BOOL getprinterdata_printer_server(fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size) { int i; @@ -585,7 +600,7 @@ static BOOL getprinterdata_printer_server(fstring value, uint32 *type, uint8 **d *type = 0x1; *needed = 2*(strlen(string)+1); *data = (uint8 *)malloc( ((*needed > in_size) ? *needed:in_size) *sizeof(uint8)); - ZERO_STRUCTP(*data); + memset(*data, 0, (*needed > in_size) ? *needed:in_size); /* it's done by hand ready to go on the wire */ for (i=0; i in_size) ? *needed:in_size) *sizeof(uint8)); - ZERO_STRUCTP(*data); + memset(*data, 0, (*needed > in_size) ? *needed:in_size); for (i=0; iflags=PRINTER_ENUM_NAME; + printer->flags=PRINTER_ENUM_ICON8; /* the description and the name are of the form \\server\share */ - slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s,%s,%s",servername, + + 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); - slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\%s", servername, ntprinter.info_2->printername); - init_unistr(&(printer->name), chaine); + snprintf(chaine2,sizeof(chaine)-1,"\\\\%s\\%s", servername, ntprinter.info_2->printername); + init_unistr(&(printer->name), chaine2); init_unistr(&(printer->comment), lp_comment(snum)); free_a_printer(ntprinter, 2); + return (True); } @@ -1648,29 +1668,26 @@ static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum, pstring * enum_printer_info_1 * glue between spoolss_enumprinters and construct_printer_info_1 ********************************************************************/ -static BOOL enum_printer_info_1(PRINTER_INFO_1 **printer, int snum, int number) +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)) - { + if (!construct_printer_info_1(*printer, snum, servername)) { free(*printer); - return (False); + return False; } else - { - return (True); - } + return True; } /******************************************************************** * enum_printer_info_2 * glue between spoolss_enumprinters and construct_printer_info_2 ********************************************************************/ -static BOOL enum_printer_info_2(PRINTER_INFO_2 **printer, int snum, int number) +static BOOL get_printer_info_2(PRINTER_INFO_2 **printer, int snum, int number) { pstring servername; @@ -1693,26 +1710,100 @@ static BOOL enum_printer_info_2(PRINTER_INFO_2 **printer, int snum, int number) * * called from api_spoolss_enumprinters (see this to understand) ********************************************************************/ -static void enum_all_printers_info_1(PRINTER_INFO_1 ***printers, uint32 *number) +static BOOL enum_printer_info_1(fstring name, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int snum; + int i; int n_services=lp_numservices(); - *printers=NULL; - *number=0; + PRINTER_INFO_1 *printer=NULL; +DEBUG(1,("enum_printer_info_1\n")); + for (snum=0; snum offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; +} + +/******************************************************************** + Spoolss_enumprinters. +********************************************************************/ +static BOOL enum_all_printers_info_1(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")); + + pstrcpy(servername, global_myname); + + for (snum=0; snum offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; } /******************************************************************** @@ -1720,26 +1811,90 @@ static void enum_all_printers_info_1(PRINTER_INFO_1 ***printers, uint32 *number) * * called from api_spoolss_enumprinters (see this to understand) ********************************************************************/ -static void enum_all_printers_info_2(PRINTER_INFO_2 ***printers, uint32 *number) +static BOOL enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int snum; + int i; int n_services=lp_numservices(); - *printers=NULL; - *number=0; + PRINTER_INFO_2 **printers=NULL; - for (snum=0;snum offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; +} + +/******************************************************************** + * handle enumeration of printers at level 1 + ********************************************************************/ +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); + + 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_REMOTE) + return enum_all_printers_info_1(buffer, offered, needed, returned); + + +} + +/******************************************************************** + * handle enumeration of printers at level 2 + ********************************************************************/ +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); +} + +/******************************************************************** + * handle enumeration of printers at level 5 + ********************************************************************/ +static uint32 enumprinters_level5( uint32 flags, fstring servername, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) +{ +/* return enum_all_printers_info_5(buffer, offered, needed, returned);*/ + return NT_STATUS_NO_PROBLEMO; } /******************************************************************** @@ -1747,55 +1902,48 @@ static void enum_all_printers_info_2(PRINTER_INFO_2 ***printers, uint32 *number) * * called from api_spoolss_enumprinters (see this to understand) ********************************************************************/ -uint32 _spoolss_enumprinters( - uint32 flags, - const UNISTR2 *servername, - uint32 level, - const BUFFER *buffer, - uint32 buf_size, - uint32 *offered, - uint32 *needed, - PRINTER_INFO_CTR *ctr, - uint32 *returned) +uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) { - DEBUG(4,("Enumerating printers\n")); + fstring name; + + DEBUG(4,("_spoolss_enumprinters\n")); - (*returned)=0; + *needed=0; + *returned=0; + + /* + * Level 1: + * flags==PRINTER_ENUM_NAME + * if name=="" then enumerates all printers + * if name!="" then enumerate the printer + * flags==PRINTER_ENUM_REMOTE + * name is NULL, enumerate printers + * Level 2: name!="" enumerates printers, name can't be NULL + * Level 3: doesn't exist + * Level 4: does a local registry lookup + * Level 5: same as Level 2 + */ - switch (level) - { - case 1: - if (flags == PRINTER_ENUM_NAME || - flags == PRINTER_ENUM_NETWORK ) - { - /*if (is_a_printerserver(servername))*/ - enum_all_printers_info_1(&ctr->printer.printers_1, returned ); - /*else - enum_one_printer_info_1(&r_u);*/ - break; - } - case 2: - if (flags == PRINTER_ENUM_NAME || - flags == PRINTER_ENUM_NETWORK ) - { - /*if (is_a_printerserver(servername))*/ - enum_all_printers_info_2(&ctr->printer.printers_2, returned ); - /*else - enum_one_printer_info_2(&r_u);*/ - break; - } - case 3: /* doesn't exist */ - return NT_STATUS_INVALID_INFO_CLASS; - case 4: /* can't, always on local machine */ - break; - case 5: - return NT_STATUS_INVALID_INFO_CLASS; - - } - DEBUG(4,("%d printers enumerated\n", *returned)); - (*offered) = buffer->size; + unistr2_to_ascii(name, servername, sizeof(name)-1); - return 0x0; + switch (level) { + case 1: + return enumprinters_level1(flags, name, buffer, offered, needed, returned); + break; + case 2: + return enumprinters_level2(flags, name, buffer, offered, needed, returned); + break; + case 5: + return enumprinters_level5(flags, name, buffer, offered, needed, returned); + break; + case 3: + case 4: + default: + return NT_STATUS_INVALID_LEVEL; + break; + } } /**************************************************************************** @@ -2562,86 +2710,135 @@ static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue, } /**************************************************************************** + Enumjobs at level 1. ****************************************************************************/ -uint32 _spoolss_enumjobs( const POLICY_HND *handle, - uint32 reqfirstjob, - uint32 reqnumofjobs, - uint32 level, - JOB_INFO_CTR *ctr, - uint32 *buf_size, - uint32 *numofjobs) +static uint32 enumjobs_level1(print_queue_struct *queue, int snum, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) { - int snum; - int count; + JOB_INFO_1 *info; int i; - print_queue_struct *queue=NULL; - print_status_struct prt_status; - - DEBUG(4,("spoolss_enumjobs\n")); - - ZERO_STRUCT(prt_status); - - if (!get_printer_snum(handle, &snum)) - { - return NT_STATUS_INVALID_HANDLE; - } - - count = get_printqueue(snum, NULL, &queue, &prt_status); - (*numofjobs) = 0; - DEBUG(4,("count:[%d], status:[%d], [%s]\n", - count, prt_status.status, prt_status.message)); + info=(JOB_INFO_1 *)malloc(*returned*sizeof(JOB_INFO_1)); - switch (level) + for (i=0; i<*returned; i++) { - case 1: - { - for (i=0; ijob.job_info_1, - job_info_1); - - fill_job_info_1(ctr->job.job_info_1[i], - &(queue[i]), i, snum); - } - safe_free(queue); - return 0x0; - } - case 2: - { - for (i=0; ijob.job_info_2, - job_info_2); - - fill_job_info_2(ctr->job.job_info_2[i], - &(queue[i]), i, snum); - } - safe_free(queue); - return 0x0; - } + fill_job_info_1(&(info[i]), &(queue[i]), i, snum); } + /* check the required size. */ + for (i=0; i<*returned; i++) + (*needed) += spoolss_size_job_info_1(&(info[i])); + + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + /* fill the buffer with the structures */ + for (i=0; i<*returned; i++) + new_smb_io_job_info_1("", buffer, &(info[i]), 0); + + /* clear memory */ safe_free(queue); + safe_free(info); - return NT_STATUS_INVALID_INFO_CLASS; + if (*needed > offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; } /**************************************************************************** + Enumjobs at level 2. ****************************************************************************/ -uint32 _spoolss_schedulejob( const POLICY_HND *handle, uint32 jobid) +static uint32 enumjobs_level2(print_queue_struct *queue, int snum, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) { - return 0x0; -} - -/**************************************************************************** -****************************************************************************/ + JOB_INFO_2 *info; + int i; + + info=(JOB_INFO_2 *)malloc(*returned*sizeof(JOB_INFO_2)); + + for (i=0; i<*returned; i++) + { + fill_job_info_2(&(info[i]), &(queue[i]), i, snum); + } + + /* check the required size. */ + for (i=0; i<*returned; i++) + (*needed) += spoolss_size_job_info_2(&(info[i])); + + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + /* fill the buffer with the structures */ + for (i=0; i<*returned; i++) + new_smb_io_job_info_2("", buffer, &(info[i]), 0); + + /* clear memory */ + safe_free(queue); + safe_free(info); + + if (*needed > offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; +} + +/**************************************************************************** + Enumjobs. +****************************************************************************/ +uint32 _spoolss_enumjobs( POLICY_HND *handle, uint32 firstjob, uint32 numofjobs, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) +{ + int snum; + print_queue_struct *queue=NULL; + print_status_struct prt_status; + + DEBUG(4,("_spoolss_enumjobs\n")); + + ZERO_STRUCT(prt_status); + + *needed=0; + *returned=0; + + if (!get_printer_snum(handle, &snum)) + { + return NT_STATUS_INVALID_HANDLE; + } + + *returned = get_printqueue(snum, NULL, &queue, &prt_status); + DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message)); + + switch (level) { + case 1: + return enumjobs_level1(queue, snum, buffer, offered, needed, returned); + break; + case 2: + return enumjobs_level2(queue, snum, buffer, offered, needed, returned); + break; + default: + return NT_STATUS_INVALID_LEVEL; + break; + } +} + + + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_schedulejob( const POLICY_HND *handle, uint32 jobid) +{ + return 0x0; +} + +/**************************************************************************** +****************************************************************************/ uint32 _spoolss_setjob( const POLICY_HND *handle, uint32 jobid, uint32 level, @@ -2705,86 +2902,166 @@ uint32 _spoolss_setjob( const POLICY_HND *handle, } /**************************************************************************** + Enumerates all printer drivers at level 1. ****************************************************************************/ -uint32 _spoolss_enumprinterdrivers( const UNISTR2 *name, - const UNISTR2 *environment, - uint32 level, - DRIVER_INFO *ctr, - uint32 *offered, - uint32 *numofdrivers) +static uint32 enumprinterdrivers_level1(fstring *list, fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { - NT_PRINTER_DRIVER_INFO_LEVEL driver; - int count; int i; - fstring *list; - fstring servername; - fstring architecture; + NT_PRINTER_DRIVER_INFO_LEVEL driver; + DRIVER_INFO_1 *driver_info_1=NULL; + driver_info_1=(DRIVER_INFO_1 *)malloc(*returned * sizeof(DRIVER_INFO_1)); - DEBUG(4,("spoolss_enumdrivers\n")); - fstrcpy(servername, global_myname); + for (i=0; i<*returned; i++) { + get_a_printer_driver(&driver, 3, list[i], architecture); + fill_printer_driver_info_1(&(driver_info_1[i]), driver, servername, architecture ); + free_a_printer_driver(driver, 3); + } + + /* check the required size. */ + 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])); + } - unistr2_to_ascii(architecture, environment, sizeof(architecture)); - count=get_ntdrivers(&list, architecture); + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; - DEBUGADD(4,("we have: [%d] drivers on archi [%s]\n",count, architecture)); - for (i=0; i offered) + return ERROR_INSUFFICIENT_BUFFER; + else + return NT_STATUS_NO_PROBLEMO; +} + +/**************************************************************************** + Enumerates all printer drivers at level 2. +****************************************************************************/ +static uint32 enumprinterdrivers_level2(fstring *list, fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +{ + int i; + NT_PRINTER_DRIVER_INFO_LEVEL driver; + DRIVER_INFO_2 *driver_info_2=NULL; + driver_info_2=(DRIVER_INFO_2 *)malloc(*returned * sizeof(DRIVER_INFO_2)); + + for (i=0; i<*returned; i++) { + get_a_printer_driver(&driver, 3, list[i], architecture); + fill_printer_driver_info_2(&(driver_info_2[i]), driver, servername, architecture ); + free_a_printer_driver(driver, 3); } - (*numofdrivers)=count; + /* check the required size. */ + 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)) + return ERROR_INSUFFICIENT_BUFFER; + + /* fill the buffer with the form structures */ + for (i=0; i<*returned; i++) + { + DEBUGADD(6,("adding form [%d] to buffer\n",i)); + new_smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0); + } + + safe_free(list); + + if (*needed > offered) + return ERROR_INSUFFICIENT_BUFFER; + else + return NT_STATUS_NO_PROBLEMO; +} + +/**************************************************************************** + Enumerates all printer drivers at level 3. +****************************************************************************/ +static uint32 enumprinterdrivers_level3(fstring *list, fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +{ + int i; + NT_PRINTER_DRIVER_INFO_LEVEL driver; + DRIVER_INFO_3 *driver_info_3=NULL; + driver_info_3=(DRIVER_INFO_3 *)malloc((*returned)*sizeof(DRIVER_INFO_3)); + + for (i=0; i<*returned; i++) { + get_a_printer_driver(&driver, 3, list[i], architecture); + fill_printer_driver_info_3(&(driver_info_3[i]), driver, servername, architecture ); + free_a_printer_driver(driver, 3); + } - switch (level) + /* check the required size. */ + for (i=0; i<*returned; i++) { - case 1: - { - DRIVER_INFO_1 *driver_info_1=NULL; - driver_info_1=(DRIVER_INFO_1 *)malloc(count*sizeof(DRIVER_INFO_1)); + DEBUGADD(6,("adding driver [%d]'s size\n",i)); + *needed += spoolss_size_printer_driver_info_3(&(driver_info_3[i])); + } - for (i=0; idriver.info1=driver_info_1; - break; - } - case 2: - { - DRIVER_INFO_2 *driver_info_2=NULL; - driver_info_2=(DRIVER_INFO_2 *)malloc(count*sizeof(DRIVER_INFO_2)); - - for (i=0; idriver.info2=driver_info_2; - break; - } - case 3: - { - DRIVER_INFO_3 *driver_info_3=NULL; - driver_info_3=(DRIVER_INFO_3 *)malloc(count*sizeof(DRIVER_INFO_3)); - - for (i=0; idriver.info3=driver_info_3; - break; - } - default: - { - return NT_STATUS_INVALID_INFO_CLASS; - } + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + /* fill the buffer with the form structures */ + 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); } - return 0x0; + safe_free(list); + + if (*needed > offered) + return ERROR_INSUFFICIENT_BUFFER; + else + return NT_STATUS_NO_PROBLEMO; +} + +/**************************************************************************** + Enumerates all printer drivers. +****************************************************************************/ +uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) +{ + int i; + fstring *list; + fstring servername; + fstring architecture; + + DEBUG(4,("_spoolss_enumprinterdrivers\n")); + fstrcpy(servername, global_myname); + *needed=0; + *returned=0; + + unistr2_to_ascii(architecture, environment, sizeof(architecture)-1); + *returned=get_ntdrivers(&list, architecture); + + DEBUGADD(4,("we have: [%d] drivers in environment [%s]\n", *returned, architecture)); + for (i=0; i<*returned; i++) + DEBUGADD(5,("driver: [%s]\n", list[i])); + + switch (level) { + case 1: + return enumprinterdrivers_level1(list, servername, architecture, buffer, offered, needed, returned); + break; + case 2: + return enumprinterdrivers_level2(list, servername, architecture, buffer, offered, needed, returned); + break; + case 3: + return enumprinterdrivers_level3(list, servername, architecture, buffer, offered, needed, returned); + break; + default: + return NT_STATUS_INVALID_INFO_CLASS; + break; + } } /**************************************************************************** @@ -2801,26 +3078,6 @@ static void fill_form_1(FORM_1 *form, nt_forms_struct *list, int position) form->bottom=list->bottom; } -/**************************************************************************** -****************************************************************************/ -static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size) -{ - prs_struct *ps; - uint32 extra_space; - - ps=&(buffer->prs); - - /* damn, I'm doing the reverse operation of prs_grow() :) */ - extra_space = buffer_size - prs_data_size(ps); - - if (!prs_grow(ps, extra_space)) - return False; - - buffer->string_at_end=buffer_size; - - return True; -} - /**************************************************************************** ****************************************************************************/ uint32 _new_spoolss_enumforms( const POLICY_HND *handle, uint32 level, @@ -2832,7 +3089,6 @@ uint32 _new_spoolss_enumforms( const POLICY_HND *handle, uint32 level, int buffer_size=0; int i; - DEBUG(4,("_new_spoolss_enumforms\n")); DEBUGADD(5,("Offered buffer size [%d]\n", offered)); DEBUGADD(5,("Info level [%d]\n", level)); @@ -2886,43 +3142,9 @@ uint32 _new_spoolss_enumforms( const POLICY_HND *handle, uint32 level, /**************************************************************************** ****************************************************************************/ -uint32 _spoolss_enumforms( const POLICY_HND *handle, - uint32 level, - FORM_1 **forms_1, - uint32 *offered, - uint32 *numofforms) +static void fill_port_1(PORT_INFO_1 *port, char *name) { - int count; - int i; - nt_forms_struct *list=NULL; - (*forms_1)=NULL; - - DEBUG(4,("spoolss_enumforms\n")); - - count = get_ntforms(&list); - (*numofforms) = count; - - DEBUGADD(5,("Offered buffer size [%d]\n", *offered)); - DEBUGADD(5,("Number of forms [%d]\n", *numofforms)); - DEBUGADD(5,("Info level [%d]\n", level)); - - switch (level) - { - case 1: - { - (*forms_1)=(FORM_1 *)malloc(count*sizeof(FORM_1)); - for (i=0; iport_name), name); } /**************************************************************************** @@ -2938,45 +3160,135 @@ static void fill_port_2(PORT_INFO_2 *port, char *name) } /**************************************************************************** + enumports level 1. ****************************************************************************/ -uint32 _spoolss_enumports( const UNISTR2 *name, - uint32 level, - PORT_INFO_CTR *ctr, - uint32 *offered, - uint32 *numofports) +static uint32 enumports_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { int n_services=lp_numservices(); int snum; + int i=0; + + PORT_INFO_1 *ports=NULL; - DEBUG(4,("spoolss_enumports\n")); + for (snum=0; snumport.info_2=ports_2; - return 0x0; - } + DEBUGADD(6,("adding port [%d]'s size\n", i)); + *needed += spoolss_size_port_info_1(&(ports[i])); + } + + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + /* fill the buffer with the ports structures */ + for (i=0; i<*returned; i++) + { + DEBUGADD(6,("adding port [%d] to buffer\n", i)); + new_smb_io_port_1("", buffer, &(ports[i]), 0); + } + + safe_free(ports); + + if (*needed > offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; +} + + +/**************************************************************************** + enumports level 2. +****************************************************************************/ +static uint32 enumports_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +{ + int n_services=lp_numservices(); + int snum; + int i=0; + + PORT_INFO_2 *ports=NULL; + + for (snum=0; snum offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; +} + +/**************************************************************************** + enumports. +****************************************************************************/ +uint32 _spoolss_enumports( UNISTR2 *name, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) +{ + DEBUG(4,("spoolss_enumports\n")); + + *returned=0; + *needed=0; + + switch (level) { + case 1: + return enumports_level_1(buffer, offered, needed, returned); + break; + case 2: + return enumports_level_2(buffer, offered, needed, returned); + break; + default: + return NT_STATUS_INVALID_INFO_CLASS; + break; + } } /**************************************************************************** @@ -3293,13 +3605,39 @@ uint32 _spoolss_setform( const POLICY_HND *handle, } /**************************************************************************** + enumprintprocessors level 1. ****************************************************************************/ -uint32 _spoolss_enumprintprocessors(const UNISTR2 *name, - const UNISTR2 *environment, - uint32 level, - PRINTPROCESSOR_1 **info_1, - uint32 *offered, - uint32 *numofprintprocessors) +static uint32 enumprintprocessors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +{ + PRINTPROCESSOR_1 *info_1=NULL; + + info_1 = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1)); + (*returned) = 0x1; + + init_unistr(&(info_1->name), "winprint"); + + *needed += spoolss_size_printprocessor_info_1(info_1); + + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + smb_io_printprocessor_info_1("", buffer, info_1, 0); + + safe_free(info_1); + + if (*needed > offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_enumprintprocessors(UNISTR2 *name, UNISTR2 *environment, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) { DEBUG(5,("spoolss_enumprintprocessors\n")); @@ -3310,26 +3648,85 @@ uint32 _spoolss_enumprintprocessors(const UNISTR2 *name, * and I can use my nice printer checker. */ - (*numofprintprocessors) = 0x1; - (*info_1) = (PRINTPROCESSOR_1 *)malloc(sizeof(PRINTPROCESSOR_1)); + *returned=0; + *needed=0; - if ((*info_1) == NULL) - { - return NT_STATUS_NO_MEMORY; + switch (level) { + case 1: + return enumprintprocessors_level_1(buffer, offered, needed, returned); + break; + default: + return NT_STATUS_INVALID_INFO_CLASS; + break; } - init_unistr(&((*info_1)->name), "winprint"); +} - return 0x0; +/**************************************************************************** + enumprintmonitors level 1. +****************************************************************************/ +static uint32 enumprintmonitors_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +{ + PRINTMONITOR_1 *info_1=NULL; + + info_1 = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1)); + (*returned) = 0x1; + + init_unistr(&(info_1->name), "Local Port"); + + *needed += spoolss_size_printmonitor_info_1(info_1); + + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + smb_io_printmonitor_info_1("", buffer, info_1, 0); + + safe_free(info_1); + + if (*needed > offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; } /**************************************************************************** + enumprintmonitors level 2. ****************************************************************************/ -uint32 _spoolss_enumprintmonitors( const UNISTR2 *name, - uint32 level, - PRINTMONITOR_1 **info_1, - uint32 *offered, - uint32 *numofprintmonitors) +static uint32 enumprintmonitors_level_2(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +{ + PRINTMONITOR_2 *info_2=NULL; + + info_2 = (PRINTMONITOR_2 *)malloc(sizeof(PRINTMONITOR_2)); + (*returned) = 0x1; + + init_unistr(&(info_2->name), "Local Port"); + init_unistr(&(info_2->environment), "Windows NT X86"); + init_unistr(&(info_2->dll_name), "localmon.dll"); + + *needed += spoolss_size_printmonitor_info_2(info_2); + + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + smb_io_printmonitor_info_2("", buffer, info_2, 0); + + safe_free(info_2); + + if (*needed > offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) { DEBUG(5,("spoolss_enumprintmonitors\n")); @@ -3340,16 +3737,20 @@ uint32 _spoolss_enumprintmonitors( const UNISTR2 *name, * and I can use my nice printer checker. */ - (*numofprintmonitors) = 0x1; - (*info_1) = (PRINTMONITOR_1 *)malloc(sizeof(PRINTMONITOR_1)); - if ((*info_1) == NULL) - { - return NT_STATUS_NO_MEMORY; - } + *returned=0; + *needed=0; - init_unistr(&((*info_1)->name), "Local Port"); - - return 0x0; + switch (level) { + case 1: + return enumprintmonitors_level_1(buffer, offered, needed, returned); + break; + case 2: + return enumprintmonitors_level_2(buffer, offered, needed, returned); + break; + default: + return NT_STATUS_INVALID_INFO_CLASS; + break; + } } /**************************************************************************** -- cgit From b52e92b09d4ca3b66e534f520468dee27065d048 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 15 Feb 2000 19:36:47 +0000 Subject: Added replacement functions sys_popen and sys_pclose. These are based on the glibc source code and are safer than the traditional popen as they don't use a shell to exec the requested command. Now we have these functions they can be tightened up (environment etc.) as required to make a safe popen. It should now be safe to add the environement variable loading code to loadparm.c Jeremy. --- source/acconfig.h | 1 + source/configure | 235 ++++++++------ source/configure.in | 12 +- source/include/config.h.in | 7 +- source/include/includes.h | 3 + source/include/proto.h | 683 +++++++++++++++++++++-------------------- source/lib/debug.c | 12 +- source/lib/replace.c | 16 +- source/lib/system.c | 231 +++++++++++++- source/printing/print_svid.c | 8 +- source/smbd/dfree.c | 10 +- source/smbd/nttrans.c | 6 +- source/smbd/password.c | 6 +- source/utils/make_printerdef.c | 44 ++- 14 files changed, 786 insertions(+), 488 deletions(-) diff --git a/source/acconfig.h b/source/acconfig.h index 1dd2af10225..4bf614c04f3 100644 --- a/source/acconfig.h +++ b/source/acconfig.h @@ -116,3 +116,4 @@ #undef USE_SETUIDX #undef HAVE_LIBDL #undef NEED_SGI_SEMUN_HACK +#undef SYSCONF_SC_NGROUPS_MAX diff --git a/source/configure b/source/configure index a5c87073af7..63c87c508d4 100755 --- a/source/configure +++ b/source/configure @@ -4204,7 +4204,7 @@ else fi done -for ac_func in initgroups select rdchk getgrnam getgrent pathconf popen +for ac_func in initgroups select rdchk getgrnam getgrent pathconf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:4211: checking for $ac_func" >&5 @@ -4259,7 +4259,7 @@ else fi done -for ac_func in setpriv setgidx setuidx setgroups mktime rename ftruncate stat64 fstat64 +for ac_func in setpriv setgidx setuidx setgroups sysconf mktime rename ftruncate stat64 fstat64 do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:4266: checking for $ac_func" >&5 @@ -8509,8 +8509,45 @@ EOF fi +echo $ac_n "checking for sysconf(_SC_NGROUPS_MAX)""... $ac_c" 1>&6 +echo "configure:8514: checking for sysconf(_SC_NGROUPS_MAX)" >&5 +if eval "test \"`echo '$''{'samba_cv_SYSCONF_SC_NGROUPS_MAX'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + +if test "$cross_compiling" = yes; then + samba_cv_SYSCONF_SC_NGROUPS_MAX=cross +else + cat > conftest.$ac_ext < +main() { exit(sysconf(_SC_NGROUPS_MAX) == -1 ? 1 : 0); } +EOF +if { (eval echo configure:8528: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + samba_cv_SYSCONF_SC_NGROUPS_MAX=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + samba_cv_SYSCONF_SC_NGROUPS_MAX=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$samba_cv_SYSCONF_SC_NGROUPS_MAX" 1>&6 +if test x"$samba_cv_SYSCONF_SC_NGROUPS_MAX" = x"yes"; then + cat >> confdefs.h <<\EOF +#define SYSCONF_SC_NGROUPS_MAX 1 +EOF + +fi + echo $ac_n "checking for root""... $ac_c" 1>&6 -echo "configure:8514: checking for root" >&5 +echo "configure:8551: checking for root" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_ROOT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8519,11 +8556,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_ROOT=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:8564: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_ROOT=yes else @@ -8551,7 +8588,7 @@ fi # look for a method of finding the list of network interfaces iface=no; echo $ac_n "checking for iface AIX""... $ac_c" 1>&6 -echo "configure:8555: checking for iface AIX" >&5 +echo "configure:8592: checking for iface AIX" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_IFACE_AIX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8560,7 +8597,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_IFACE_AIX=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:8609: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_IFACE_AIX=yes else @@ -8592,7 +8629,7 @@ fi if test $iface = no; then echo $ac_n "checking for iface ifconf""... $ac_c" 1>&6 -echo "configure:8596: checking for iface ifconf" >&5 +echo "configure:8633: checking for iface ifconf" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_IFACE_IFCONF'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8601,7 +8638,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_IFACE_IFCONF=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:8650: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_IFACE_IFCONF=yes else @@ -8634,7 +8671,7 @@ fi if test $iface = no; then echo $ac_n "checking for iface ifreq""... $ac_c" 1>&6 -echo "configure:8638: checking for iface ifreq" >&5 +echo "configure:8675: checking for iface ifreq" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_IFACE_IFREQ'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8643,7 +8680,7 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_IFACE_IFREQ=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:8692: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_IFACE_IFREQ=yes else @@ -8680,7 +8717,7 @@ fi seteuid=no; if test $seteuid = no; then echo $ac_n "checking for setresuid""... $ac_c" 1>&6 -echo "configure:8684: checking for setresuid" >&5 +echo "configure:8721: checking for setresuid" >&5 if eval "test \"`echo '$''{'samba_cv_USE_SETRESUID'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8689,7 +8726,7 @@ if test "$cross_compiling" = yes; then samba_cv_USE_SETRESUID=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:8738: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then samba_cv_USE_SETRESUID=yes else @@ -8723,7 +8760,7 @@ fi if test $seteuid = no; then echo $ac_n "checking for setreuid""... $ac_c" 1>&6 -echo "configure:8727: checking for setreuid" >&5 +echo "configure:8764: checking for setreuid" >&5 if eval "test \"`echo '$''{'samba_cv_USE_SETREUID'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8732,7 +8769,7 @@ if test "$cross_compiling" = yes; then samba_cv_USE_SETREUID=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:8781: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then samba_cv_USE_SETREUID=yes else @@ -8765,7 +8802,7 @@ fi if test $seteuid = no; then echo $ac_n "checking for seteuid""... $ac_c" 1>&6 -echo "configure:8769: checking for seteuid" >&5 +echo "configure:8806: checking for seteuid" >&5 if eval "test \"`echo '$''{'samba_cv_USE_SETEUID'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8774,7 +8811,7 @@ if test "$cross_compiling" = yes; then samba_cv_USE_SETEUID=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:8823: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then samba_cv_USE_SETEUID=yes else @@ -8807,7 +8844,7 @@ fi if test $seteuid = no; then echo $ac_n "checking for setuidx""... $ac_c" 1>&6 -echo "configure:8811: checking for setuidx" >&5 +echo "configure:8848: checking for setuidx" >&5 if eval "test \"`echo '$''{'samba_cv_USE_SETUIDX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8816,7 +8853,7 @@ if test "$cross_compiling" = yes; then samba_cv_USE_SETUIDX=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:8865: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then samba_cv_USE_SETUIDX=yes else @@ -8849,7 +8886,7 @@ fi echo $ac_n "checking for shared mmap""... $ac_c" 1>&6 -echo "configure:8853: checking for shared mmap" >&5 +echo "configure:8890: checking for shared mmap" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_SHARED_MMAP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8858,11 +8895,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_SHARED_MMAP=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:8903: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_SHARED_MMAP=yes else @@ -8889,7 +8926,7 @@ EOF fi echo $ac_n "checking for ftruncate needs root""... $ac_c" 1>&6 -echo "configure:8893: checking for ftruncate needs root" >&5 +echo "configure:8930: checking for ftruncate needs root" >&5 if eval "test \"`echo '$''{'samba_cv_FTRUNCATE_NEEDS_ROOT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8898,11 +8935,11 @@ if test "$cross_compiling" = yes; then samba_cv_FTRUNCATE_NEEDS_ROOT=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:8943: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then samba_cv_FTRUNCATE_NEEDS_ROOT=yes else @@ -8925,7 +8962,7 @@ EOF fi echo $ac_n "checking for fcntl locking""... $ac_c" 1>&6 -echo "configure:8929: checking for fcntl locking" >&5 +echo "configure:8966: checking for fcntl locking" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_FCNTL_LOCK'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8934,11 +8971,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_FCNTL_LOCK=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:8979: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_FCNTL_LOCK=yes else @@ -8961,7 +8998,7 @@ EOF fi echo $ac_n "checking for broken (glibc2.1/x86) 64 bit fcntl locking""... $ac_c" 1>&6 -echo "configure:8965: checking for broken (glibc2.1/x86) 64 bit fcntl locking" >&5 +echo "configure:9002: checking for broken (glibc2.1/x86) 64 bit fcntl locking" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_BROKEN_FCNTL64_LOCKS'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8970,11 +9007,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9015: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_BROKEN_FCNTL64_LOCKS=yes else @@ -8999,7 +9036,7 @@ else echo $ac_n "checking for 64 bit fcntl locking""... $ac_c" 1>&6 -echo "configure:9003: checking for 64 bit fcntl locking" >&5 +echo "configure:9040: checking for 64 bit fcntl locking" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_STRUCT_FLOCK64'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9008,7 +9045,7 @@ else samba_cv_HAVE_STRUCT_FLOCK64=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9073: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_STRUCT_FLOCK64=yes else @@ -9057,7 +9094,7 @@ EOF fi echo $ac_n "checking for sysv ipc""... $ac_c" 1>&6 -echo "configure:9061: checking for sysv ipc" >&5 +echo "configure:9098: checking for sysv ipc" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_SYSV_IPC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9066,11 +9103,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_SYSV_IPC=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9111: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_SYSV_IPC=yes else @@ -9093,7 +9130,7 @@ EOF fi echo $ac_n "checking for IRIX sysv ipc semun problem using gcc""... $ac_c" 1>&6 -echo "configure:9097: checking for IRIX sysv ipc semun problem using gcc" >&5 +echo "configure:9134: checking for IRIX sysv ipc semun problem using gcc" >&5 if eval "test \"`echo '$''{'samba_cv_NEED_SGI_SEMUN_HACK'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9102,11 +9139,11 @@ if test "$cross_compiling" = yes; then samba_cv_NEED_SGI_SEMUN_HACK=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9147: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then samba_cv_NEED_SGI_SEMUN_HACK=yes else @@ -9129,7 +9166,7 @@ EOF fi echo $ac_n "checking for a crypt that needs truncated salt""... $ac_c" 1>&6 -echo "configure:9133: checking for a crypt that needs truncated salt" >&5 +echo "configure:9170: checking for a crypt that needs truncated salt" >&5 if eval "test \"`echo '$''{'samba_cv_HAVE_TRUNCATED_SALT'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9138,11 +9175,11 @@ if test "$cross_compiling" = yes; then samba_cv_HAVE_TRUNCATED_SALT=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9183: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then samba_cv_HAVE_TRUNCATED_SALT=no else @@ -9165,13 +9202,13 @@ EOF fi echo $ac_n "checking for broken nisplus include files""... $ac_c" 1>&6 -echo "configure:9169: checking for broken nisplus include files" >&5 +echo "configure:9206: checking for broken nisplus include files" >&5 if eval "test \"`echo '$''{'samba_cv_BROKEN_NISPLUS_INCLUDE_FILES'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if defined(HAVE_RPCSVC_NIS_H) @@ -9181,7 +9218,7 @@ int main() { return 0; ; return 0; } EOF -if { (eval echo configure:9185: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:9222: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_BROKEN_NISPLUS_INCLUDE_FILES=no else @@ -9205,7 +9242,7 @@ fi ################################################# # check for smbwrapper support echo $ac_n "checking whether to use smbwrapper""... $ac_c" 1>&6 -echo "configure:9209: checking whether to use smbwrapper" >&5 +echo "configure:9246: checking whether to use smbwrapper" >&5 # Check whether --with-smbwrapper or --without-smbwrapper was given. if test "${with_smbwrapper+set}" = set; then withval="$with_smbwrapper" @@ -9249,7 +9286,7 @@ fi ################################################# # check for the AFS filesystem echo $ac_n "checking whether to use AFS""... $ac_c" 1>&6 -echo "configure:9253: checking whether to use AFS" >&5 +echo "configure:9290: checking whether to use AFS" >&5 # Check whether --with-afs or --without-afs was given. if test "${with_afs+set}" = set; then withval="$with_afs" @@ -9275,7 +9312,7 @@ fi ################################################# # check for the DFS auth system echo $ac_n "checking whether to use DFS auth""... $ac_c" 1>&6 -echo "configure:9279: checking whether to use DFS auth" >&5 +echo "configure:9316: checking whether to use DFS auth" >&5 # Check whether --with-dfs or --without-dfs was given. if test "${with_dfs+set}" = set; then withval="$with_dfs" @@ -9300,7 +9337,7 @@ fi ################################################# # check for Kerberos IV auth system echo $ac_n "checking whether to use Kerberos IV""... $ac_c" 1>&6 -echo "configure:9304: checking whether to use Kerberos IV" >&5 +echo "configure:9341: checking whether to use Kerberos IV" >&5 # Check whether --with-krb4 or --without-krb4 was given. if test "${with_krb4+set}" = set; then withval="$with_krb4" @@ -9310,7 +9347,7 @@ if test "${with_krb4+set}" = set; then EOF echo $ac_n "checking for dn_expand in -lresolv""... $ac_c" 1>&6 -echo "configure:9314: checking for dn_expand in -lresolv" >&5 +echo "configure:9351: checking for dn_expand in -lresolv" >&5 ac_lib_var=`echo resolv'_'dn_expand | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -9318,7 +9355,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:9370: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -9368,7 +9405,7 @@ fi ################################################# # check for Kerberos 5 auth system echo $ac_n "checking whether to use Kerberos 5""... $ac_c" 1>&6 -echo "configure:9372: checking whether to use Kerberos 5" >&5 +echo "configure:9409: checking whether to use Kerberos 5" >&5 # Check whether --with-krb5 or --without-krb5 was given. if test "${with_krb5+set}" = set; then withval="$with_krb5" @@ -9389,7 +9426,7 @@ fi ################################################# # check for automount support echo $ac_n "checking whether to use AUTOMOUNT""... $ac_c" 1>&6 -echo "configure:9393: checking whether to use AUTOMOUNT" >&5 +echo "configure:9430: checking whether to use AUTOMOUNT" >&5 # Check whether --with-automount or --without-automount was given. if test "${with_automount+set}" = set; then withval="$with_automount" @@ -9414,7 +9451,7 @@ fi ################################################# # check for smbmount support echo $ac_n "checking whether to use SMBMOUNT""... $ac_c" 1>&6 -echo "configure:9418: checking whether to use SMBMOUNT" >&5 +echo "configure:9455: checking whether to use SMBMOUNT" >&5 # Check whether --with-smbmount or --without-smbmount was given. if test "${with_smbmount+set}" = set; then withval="$with_smbmount" @@ -9443,7 +9480,7 @@ fi ################################################# # check for a PAM password database echo $ac_n "checking whether to use PAM password database""... $ac_c" 1>&6 -echo "configure:9447: checking whether to use PAM password database" >&5 +echo "configure:9484: checking whether to use PAM password database" >&5 # Check whether --with-pam or --without-pam was given. if test "${with_pam+set}" = set; then withval="$with_pam" @@ -9470,7 +9507,7 @@ fi ################################################# # check for a LDAP password database echo $ac_n "checking whether to use LDAP password database""... $ac_c" 1>&6 -echo "configure:9474: checking whether to use LDAP password database" >&5 +echo "configure:9511: checking whether to use LDAP password database" >&5 # Check whether --with-ldap or --without-ldap was given. if test "${with_ldap+set}" = set; then withval="$with_ldap" @@ -9496,7 +9533,7 @@ fi ################################################# # check for a NISPLUS password database echo $ac_n "checking whether to use NISPLUS password database""... $ac_c" 1>&6 -echo "configure:9500: checking whether to use NISPLUS password database" >&5 +echo "configure:9537: checking whether to use NISPLUS password database" >&5 # Check whether --with-nisplus or --without-nisplus was given. if test "${with_nisplus+set}" = set; then withval="$with_nisplus" @@ -9521,7 +9558,7 @@ fi ################################################# # check for a NISPLUS_HOME support echo $ac_n "checking whether to use NISPLUS_HOME""... $ac_c" 1>&6 -echo "configure:9525: checking whether to use NISPLUS_HOME" >&5 +echo "configure:9562: checking whether to use NISPLUS_HOME" >&5 # Check whether --with-nisplus-home or --without-nisplus-home was given. if test "${with_nisplus_home+set}" = set; then withval="$with_nisplus_home" @@ -9546,7 +9583,7 @@ fi ################################################# # check for the secure socket layer echo $ac_n "checking whether to use SSL""... $ac_c" 1>&6 -echo "configure:9550: checking whether to use SSL" >&5 +echo "configure:9587: checking whether to use SSL" >&5 # Check whether --with-ssl or --without-ssl was given. if test "${with_ssl+set}" = set; then withval="$with_ssl" @@ -9605,7 +9642,7 @@ fi ################################################# # check for syslog logging echo $ac_n "checking whether to use syslog logging""... $ac_c" 1>&6 -echo "configure:9609: checking whether to use syslog logging" >&5 +echo "configure:9646: checking whether to use syslog logging" >&5 # Check whether --with-syslog or --without-syslog was given. if test "${with_syslog+set}" = set; then withval="$with_syslog" @@ -9630,7 +9667,7 @@ fi ################################################# # check for a shared memory profiling support echo $ac_n "checking whether to use profiling""... $ac_c" 1>&6 -echo "configure:9634: checking whether to use profiling" >&5 +echo "configure:9671: checking whether to use profiling" >&5 # Check whether --with-profile or --without-profile was given. if test "${with_profile+set}" = set; then withval="$with_profile" @@ -9656,7 +9693,7 @@ fi ################################################# # check for experimental netatalk resource fork support echo $ac_n "checking whether to support netatalk""... $ac_c" 1>&6 -echo "configure:9660: checking whether to support netatalk" >&5 +echo "configure:9697: checking whether to support netatalk" >&5 # Check whether --with-netatalk or --without-netatalk was given. if test "${with_netatalk+set}" = set; then withval="$with_netatalk" @@ -9683,7 +9720,7 @@ fi QUOTAOBJS=noquotas.o echo $ac_n "checking whether to support disk-quotas""... $ac_c" 1>&6 -echo "configure:9687: checking whether to support disk-quotas" >&5 +echo "configure:9724: checking whether to support disk-quotas" >&5 # Check whether --with-quotas or --without-quotas was given. if test "${with_quotas+set}" = set; then withval="$with_quotas" @@ -9707,7 +9744,7 @@ fi # check for experimental utmp accounting echo $ac_n "checking whether to support utmp accounting""... $ac_c" 1>&6 -echo "configure:9711: checking whether to support utmp accounting" >&5 +echo "configure:9748: checking whether to support utmp accounting" >&5 # Check whether --with-utmp or --without-utmp was given. if test "${with_utmp+set}" = set; then withval="$with_utmp" @@ -9807,14 +9844,14 @@ fi ################################################# # these tests are taken from the GNU fileutils package echo "checking how to get filesystem space usage" 1>&6 -echo "configure:9811: checking how to get filesystem space usage" >&5 +echo "configure:9848: checking how to get filesystem space usage" >&5 space=no # Test for statvfs64. if test $space = no; then # SVR4 echo $ac_n "checking statvfs64 function (SVR4)""... $ac_c" 1>&6 -echo "configure:9818: checking statvfs64 function (SVR4)" >&5 +echo "configure:9855: checking statvfs64 function (SVR4)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_statvfs64'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9822,7 +9859,7 @@ else fu_cv_sys_stat_statvfs64=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9877: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then fu_cv_sys_stat_statvfs64=yes else @@ -9869,12 +9906,12 @@ fi if test $space = no; then # SVR4 echo $ac_n "checking statvfs function (SVR4)""... $ac_c" 1>&6 -echo "configure:9873: checking statvfs function (SVR4)" >&5 +echo "configure:9910: checking statvfs function (SVR4)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_statvfs'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -9882,7 +9919,7 @@ int main() { struct statvfs fsd; statvfs (0, &fsd); ; return 0; } EOF -if { (eval echo configure:9886: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:9923: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* fu_cv_sys_stat_statvfs=yes else @@ -9907,7 +9944,7 @@ fi if test $space = no; then # DEC Alpha running OSF/1 echo $ac_n "checking for 3-argument statfs function (DEC OSF/1)""... $ac_c" 1>&6 -echo "configure:9911: checking for 3-argument statfs function (DEC OSF/1)" >&5 +echo "configure:9948: checking for 3-argument statfs function (DEC OSF/1)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs3_osf1'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9915,7 +9952,7 @@ else fu_cv_sys_stat_statfs3_osf1=no else cat > conftest.$ac_ext < @@ -9928,7 +9965,7 @@ else exit (statfs (".", &fsd, sizeof (struct statfs))); } EOF -if { (eval echo configure:9932: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:9969: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then fu_cv_sys_stat_statfs3_osf1=yes else @@ -9955,7 +9992,7 @@ fi if test $space = no; then # AIX echo $ac_n "checking for two-argument statfs with statfs.bsize member (AIX, 4.3BSD)""... $ac_c" 1>&6 -echo "configure:9959: checking for two-argument statfs with statfs.bsize member (AIX, 4.3BSD)" >&5 +echo "configure:9996: checking for two-argument statfs with statfs.bsize member (AIX, 4.3BSD)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs2_bsize'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -9963,7 +10000,7 @@ else fu_cv_sys_stat_statfs2_bsize=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10023: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then fu_cv_sys_stat_statfs2_bsize=yes else @@ -10009,7 +10046,7 @@ fi if test $space = no; then # SVR3 echo $ac_n "checking for four-argument statfs (AIX-3.2.5, SVR3)""... $ac_c" 1>&6 -echo "configure:10013: checking for four-argument statfs (AIX-3.2.5, SVR3)" >&5 +echo "configure:10050: checking for four-argument statfs (AIX-3.2.5, SVR3)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs4'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10017,7 +10054,7 @@ else fu_cv_sys_stat_statfs4=no else cat > conftest.$ac_ext < #include @@ -10027,7 +10064,7 @@ else exit (statfs (".", &fsd, sizeof fsd, 0)); } EOF -if { (eval echo configure:10031: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10068: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then fu_cv_sys_stat_statfs4=yes else @@ -10054,7 +10091,7 @@ fi if test $space = no; then # 4.4BSD and NetBSD echo $ac_n "checking for two-argument statfs with statfs.fsize member (4.4BSD and NetBSD)""... $ac_c" 1>&6 -echo "configure:10058: checking for two-argument statfs with statfs.fsize member (4.4BSD and NetBSD)" >&5 +echo "configure:10095: checking for two-argument statfs with statfs.fsize member (4.4BSD and NetBSD)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_statfs2_fsize'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10062,7 +10099,7 @@ else fu_cv_sys_stat_statfs2_fsize=no else cat > conftest.$ac_ext < #ifdef HAVE_SYS_PARAM_H @@ -10078,7 +10115,7 @@ else exit (statfs (".", &fsd)); } EOF -if { (eval echo configure:10082: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10119: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then fu_cv_sys_stat_statfs2_fsize=yes else @@ -10105,7 +10142,7 @@ fi if test $space = no; then # Ultrix echo $ac_n "checking for two-argument statfs with struct fs_data (Ultrix)""... $ac_c" 1>&6 -echo "configure:10109: checking for two-argument statfs with struct fs_data (Ultrix)" >&5 +echo "configure:10146: checking for two-argument statfs with struct fs_data (Ultrix)" >&5 if eval "test \"`echo '$''{'fu_cv_sys_stat_fs_data'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -10113,7 +10150,7 @@ else fu_cv_sys_stat_fs_data=no else cat > conftest.$ac_ext < #ifdef HAVE_SYS_PARAM_H @@ -10133,7 +10170,7 @@ else exit (statfs (".", &fsd) != 1); } EOF -if { (eval echo configure:10137: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10174: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then fu_cv_sys_stat_fs_data=yes else @@ -10167,7 +10204,7 @@ fi # echo "checking if large file support can be enabled" cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:10221: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* samba_cv_HAVE_EXPLICIT_LARGEFILE_SUPPORT=yes else @@ -10205,11 +10242,11 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:10250: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null then echo "configure OK"; else diff --git a/source/configure.in b/source/configure.in index 51505e82834..4d8ef647c80 100644 --- a/source/configure.in +++ b/source/configure.in @@ -353,8 +353,8 @@ AC_CHECK_FUNCS(waitpid getcwd strdup strtoul strerror chown chmod chroot) AC_CHECK_FUNCS(fstat strchr utime utimes getrlimit fsync bzero memset) AC_CHECK_FUNCS(memmove vsnprintf snprintf setsid glob strpbrk pipe crypt16 getauthuid) AC_CHECK_FUNCS(strftime sigprocmask sigblock sigaction innetgr setnetgrent getnetgrent endnetgrent) -AC_CHECK_FUNCS(initgroups select rdchk getgrnam getgrent pathconf popen) -AC_CHECK_FUNCS(setpriv setgidx setuidx setgroups mktime rename ftruncate stat64 fstat64) +AC_CHECK_FUNCS(initgroups select rdchk getgrnam getgrent pathconf) +AC_CHECK_FUNCS(setpriv setgidx setuidx setgroups sysconf mktime rename ftruncate stat64 fstat64) AC_CHECK_FUNCS(lstat64 fopen64 atexit grantpt dup2 lseek64 ftruncate64 readdir64) AC_CHECK_FUNCS(fseek64 fseeko64 ftell64 ftello64 setluid yp_get_default_domain getpwanam) AC_CHECK_FUNCS(srandom random srand rand setenv usleep mmap64 strcasecmp fcvt fcvtl) @@ -845,6 +845,14 @@ if test x"$samba_cv_REPLACE_INET_NTOA" = x"yes"; then AC_DEFINE(REPLACE_INET_NTOA) fi +AC_CACHE_CHECK([for sysconf(_SC_NGROUPS_MAX)],samba_cv_SYSCONF_SC_NGROUPS_MAX,[ +AC_TRY_RUN([#include +main() { exit(sysconf(_SC_NGROUPS_MAX) == -1 ? 1 : 0); }], +samba_cv_SYSCONF_SC_NGROUPS_MAX=yes,samba_cv_SYSCONF_SC_NGROUPS_MAX=no,samba_cv_SYSCONF_SC_NGROUPS_MAX=cross)]) +if test x"$samba_cv_SYSCONF_SC_NGROUPS_MAX" = x"yes"; then + AC_DEFINE(SYSCONF_SC_NGROUPS_MAX) +fi + AC_CACHE_CHECK([for root],samba_cv_HAVE_ROOT,[ AC_TRY_RUN([main() { exit(getuid() != 0); }], samba_cv_HAVE_ROOT=yes,samba_cv_HAVE_ROOT=no,samba_cv_HAVE_ROOT=cross)]) diff --git a/source/include/config.h.in b/source/include/config.h.in index c8d5d892335..0b3872e7ced 100644 --- a/source/include/config.h.in +++ b/source/include/config.h.in @@ -182,6 +182,7 @@ #undef USE_SETUIDX #undef HAVE_LIBDL #undef NEED_SGI_SEMUN_HACK +#undef SYSCONF_SC_NGROUPS_MAX /* The number of bytes in a int. */ #undef SIZEOF_INT @@ -549,9 +550,6 @@ /* Define if you have the pipe function. */ #undef HAVE_PIPE -/* Define if you have the popen function. */ -#undef HAVE_POPEN - /* Define if you have the pread function. */ #undef HAVE_PREAD @@ -657,6 +655,9 @@ /* Define if you have the syscall function. */ #undef HAVE_SYSCALL +/* Define if you have the sysconf function. */ +#undef HAVE_SYSCONF + /* Define if you have the usleep function. */ #undef HAVE_USLEEP diff --git a/source/include/includes.h b/source/include/includes.h index 127e6d59af3..1929df3b7d0 100644 --- a/source/include/includes.h +++ b/source/include/includes.h @@ -628,6 +628,9 @@ extern int errno; #define GID_T gid_t #endif +#ifndef NGROUPS_MAX +#define NGROUPS_MAX 32 /* Guess... */ +#endif /* Lists, trees, caching, datbase... */ #include "ubi_sLinkList.h" diff --git a/source/include/proto.h b/source/include/proto.h index 7dc0d3e9e62..9209f3063e1 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -186,208 +186,10 @@ void CatchChildLeaveStatus(void); int vslprintf(char *str, int n, char *format, va_list ap); -/*The following definitions come from libsmb/clientgen.c */ - -int cli_set_port(struct cli_state *cli, int port); -char *cli_errstr(struct cli_state *cli); -BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, - uint16 *setup, uint32 setup_count, uint32 max_setup_count, - char *params, uint32 param_count, uint32 max_param_count, - char *data, uint32 data_count, uint32 max_data_count, - char **rparam, uint32 *rparam_count, - char **rdata, uint32 *rdata_count); -BOOL cli_api(struct cli_state *cli, - char *param, int prcnt, int mprcnt, - char *data, int drcnt, int mdrcnt, - char **rparam, int *rprcnt, - char **rdata, int *rdrcnt); -BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation); -BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)); -BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, - void (*fn)(const char *, uint32, const char *)); -BOOL cli_session_setup(struct cli_state *cli, - char *user, - char *pass, int passlen, - char *ntpass, int ntpasslen, - char *workgroup); -BOOL cli_ulogoff(struct cli_state *cli); -BOOL cli_send_tconX(struct cli_state *cli, - char *share, char *dev, char *pass, int passlen); -BOOL cli_tdis(struct cli_state *cli); -BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst); -BOOL cli_unlink(struct cli_state *cli, char *fname); -BOOL cli_mkdir(struct cli_state *cli, char *dname); -BOOL cli_rmdir(struct cli_state *cli, char *dname); -int cli_nt_create(struct cli_state *cli, char *fname); -int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode); -BOOL cli_close(struct cli_state *cli, int fnum); -BOOL cli_lock(struct cli_state *cli, int fnum, - uint32 offset, uint32 len, int timeout, enum brl_type lock_type); -BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len); -size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size); -ssize_t cli_write(struct cli_state *cli, - int fnum, uint16 write_mode, - char *buf, off_t offset, size_t size); -ssize_t cli_smbwrite(struct cli_state *cli, - int fnum, char *buf, off_t offset, size_t size1); -BOOL cli_getattrE(struct cli_state *cli, int fd, - uint16 *attr, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time); -BOOL cli_getatr(struct cli_state *cli, char *fname, - uint16 *attr, size_t *size, time_t *t); -BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t); -BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - size_t *size, uint16 *mode); -BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, size_t *size, uint16 *mode, - SMB_INO_T *ino); -BOOL cli_qfileinfo(struct cli_state *cli, int fnum, - uint16 *mode, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, SMB_INO_T *ino); -int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *)); -BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, - const char *old_password); -BOOL cli_negprot(struct cli_state *cli); -BOOL cli_session_request(struct cli_state *cli, - struct nmb_name *calling, struct nmb_name *called); -BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip); -struct cli_state *cli_initialise(struct cli_state *cli); -void cli_shutdown(struct cli_state *cli); -int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error); -void cli_sockopt(struct cli_state *cli, char *options); -uint16 cli_setpid(struct cli_state *cli, uint16 pid); -BOOL cli_reestablish_connection(struct cli_state *cli); -BOOL cli_establish_connection(struct cli_state *cli, - char *dest_host, struct in_addr *dest_ip, - struct nmb_name *calling, struct nmb_name *called, - char *service, char *service_type, - BOOL do_shutdown, BOOL do_tcon); -int cli_printjob_del(struct cli_state *cli, int job); -int cli_print_queue(struct cli_state *cli, - void (*fn)(struct print_job_info *)); -BOOL cli_chkpath(struct cli_state *cli, char *path); -BOOL cli_message_start(struct cli_state *cli, char *host, char *username, - int *grp); -BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp); -BOOL cli_message_end(struct cli_state *cli, int grp); -BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail); -BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, - struct in_addr *pdest_ip); - -/*The following definitions come from libsmb/credentials.c */ - -char *credstr(uchar *cred); -void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, - uchar session_key[8]); -void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp, - DOM_CHAL *cred); -int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred, - UTIME timestamp); -BOOL clnt_deal_with_creds(uchar sess_key[8], - DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred); -BOOL deal_with_creds(uchar sess_key[8], - DOM_CRED *sto_clnt_cred, - DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred); - -/*The following definitions come from libsmb/namequery.c */ - -BOOL name_status(int fd,char *name,int name_type,BOOL recurse, - struct in_addr to_ip,char *master,char *rname); -struct in_addr *name_query(int fd,const char *name,int name_type, - BOOL bcast,BOOL recurse, - struct in_addr to_ip, int *count); -FILE *startlmhosts(char *fname); -BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr); -void endlmhosts(FILE *fp); -BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type); -BOOL find_master_ip(char *group, struct in_addr *master_ip); -BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name); -BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count); - -/*The following definitions come from libsmb/nmblib.c */ - -void debug_nmb_packet(struct packet_struct *p); -char *nmb_namestr(struct nmb_name *n); -struct packet_struct *copy_packet(struct packet_struct *packet); -void free_packet(struct packet_struct *packet); -struct packet_struct *parse_packet(char *buf,int length, - enum packet_type packet_type); -struct packet_struct *read_packet(int fd,enum packet_type packet_type); -void make_nmb_name( struct nmb_name *n, const char *name, int type); -BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2); -int build_packet(char *buf, struct packet_struct *p); -BOOL send_packet(struct packet_struct *p); -struct packet_struct *receive_packet(int fd,enum packet_type type,int t); -struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id); -struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name); -BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name); -void sort_query_replies(char *data, int n, struct in_addr ip); - -/*The following definitions come from libsmb/nterr.c */ - -char *get_nt_error_msg(uint32 nt_code); - -/*The following definitions come from libsmb/passchange.c */ - -BOOL remote_password_change(const char *remote_machine, const char *user_name, - const char *old_passwd, const char *new_passwd, - char *err_str, size_t err_str_len); - -/*The following definitions come from libsmb/pwd_cache.c */ - -void pwd_init(struct pwd_info *pwd); -void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key); -BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2); -void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt); -void pwd_set_nullpwd(struct pwd_info *pwd); -void pwd_set_cleartext(struct pwd_info *pwd, char *clr); -void pwd_get_cleartext(struct pwd_info *pwd, char *clr); -void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); -void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); -void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr); -void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]); -void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]); - /*The following definitions come from lib/smbrun.c */ int smbrun(char *cmd,char *outfile,BOOL shared); -/*The following definitions come from libsmb/smbdes.c */ - -void E_P16(unsigned char *p14,unsigned char *p16); -void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); -void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out); -void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out); -void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key); -void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key); -void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw); -void SamOEMhash( unsigned char *data, unsigned char *key, int val); - -/*The following definitions come from libsmb/smbencrypt.c */ - -void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24); -void E_md4hash(uchar *passwd, uchar *p16); -void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]); -void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]); -void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]); -void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24); -BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode); - -/*The following definitions come from libsmb/smberr.c */ - -char *smb_errstr(char *inbuf); - -/*The following definitions come from libsmb/unexpected.c */ - -void unexpected_packet(struct packet_struct *p); -void clear_unexpected(time_t t); -struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, - char *mailslot_name); - /*The following definitions come from lib/snprintf.c */ @@ -417,6 +219,7 @@ BOOL set_process_capability( uint32 cap_flag, BOOL enable ); BOOL set_inherited_process_capability( uint32 cap_flag, BOOL enable ); long sys_random(void); void sys_srandom(unsigned int seed); +int groups_max(void); int sys_getgroups(int setlen, gid_t *gidset); int sys_setgroups(int setlen, gid_t *gidset); struct passwd *sys_getpwnam(const char *name); @@ -430,6 +233,8 @@ DIR *wsys_opendir(const smb_ucs2_t *wfname); smb_ucs2_t *wsys_getwd(smb_ucs2_t *s); int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid); int wsys_chroot(const smb_ucs2_t *wfname); +FILE *sys_popen(const char *command, const char *mode); +int sys_pclose( FILE *fp); /*The following definitions come from lib/talloc.c */ @@ -469,23 +274,6 @@ BOOL map_username(char *user); struct passwd *Get_Pwnam(char *user,BOOL allow_change); BOOL user_in_list(char *user,char *list); -/*The following definitions come from lib/util_array.c */ - -void free_void_array(uint32 num_entries, void **entries, - void(free_item)(void*)); -void* add_copy_to_array(uint32 *len, void ***array, const void *item, - void*(item_dup)(const void*), BOOL alloc_anyway); -void* add_item_to_array(uint32 *len, void ***array, void *item); -void free_use_info_array(uint32 num_entries, struct use_info **entries); -struct use_info* add_use_info_to_array(uint32 *len, struct use_info ***array, - const struct use_info *name); -void free_char_array(uint32 num_entries, char **entries); -char* add_chars_to_array(uint32 *len, char ***array, const char *name); -void free_uint32_array(uint32 num_entries, uint32 **entries); -uint32* add_uint32s_to_array(uint32 *len, uint32 ***array, const uint32 *name); -void free_sid_array(uint32 num_entries, DOM_SID **entries); -DOM_SID* add_sid_to_array(uint32 *len, DOM_SID ***array, const DOM_SID *sid); - /*The following definitions come from lib/util.c */ char *tmpdir(void); @@ -563,6 +351,23 @@ char *myhostname(void); char *lock_path(char *name); char *parent_dirname(const char *path); +/*The following definitions come from lib/util_array.c */ + +void free_void_array(uint32 num_entries, void **entries, + void(free_item)(void*)); +void* add_copy_to_array(uint32 *len, void ***array, const void *item, + void*(item_dup)(const void*), BOOL alloc_anyway); +void* add_item_to_array(uint32 *len, void ***array, void *item); +void free_use_info_array(uint32 num_entries, struct use_info **entries); +struct use_info* add_use_info_to_array(uint32 *len, struct use_info ***array, + const struct use_info *name); +void free_char_array(uint32 num_entries, char **entries); +char* add_chars_to_array(uint32 *len, char ***array, const char *name); +void free_uint32_array(uint32 num_entries, uint32 **entries); +uint32* add_uint32s_to_array(uint32 *len, uint32 ***array, const uint32 *name); +void free_sid_array(uint32 num_entries, DOM_SID **entries); +DOM_SID* add_sid_to_array(uint32 *len, DOM_SID ***array, const DOM_SID *sid); + /*The following definitions come from lib/util_file.c */ BOOL do_file_lock(int fd, int waitsecs, int type); @@ -752,6 +557,204 @@ void split_at_last_component_w(smb_ucs2_t *path, smb_ucs2_t *front, smb_ucs2_t s smb_ucs2_t *octal_string_w(int i); smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length); +/*The following definitions come from libsmb/clientgen.c */ + +int cli_set_port(struct cli_state *cli, int port); +char *cli_errstr(struct cli_state *cli); +BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, + uint16 *setup, uint32 setup_count, uint32 max_setup_count, + char *params, uint32 param_count, uint32 max_param_count, + char *data, uint32 data_count, uint32 max_data_count, + char **rparam, uint32 *rparam_count, + char **rdata, uint32 *rdata_count); +BOOL cli_api(struct cli_state *cli, + char *param, int prcnt, int mprcnt, + char *data, int drcnt, int mdrcnt, + char **rparam, int *rprcnt, + char **rdata, int *rdrcnt); +BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation); +BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)); +BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, + void (*fn)(const char *, uint32, const char *)); +BOOL cli_session_setup(struct cli_state *cli, + char *user, + char *pass, int passlen, + char *ntpass, int ntpasslen, + char *workgroup); +BOOL cli_ulogoff(struct cli_state *cli); +BOOL cli_send_tconX(struct cli_state *cli, + char *share, char *dev, char *pass, int passlen); +BOOL cli_tdis(struct cli_state *cli); +BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst); +BOOL cli_unlink(struct cli_state *cli, char *fname); +BOOL cli_mkdir(struct cli_state *cli, char *dname); +BOOL cli_rmdir(struct cli_state *cli, char *dname); +int cli_nt_create(struct cli_state *cli, char *fname); +int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode); +BOOL cli_close(struct cli_state *cli, int fnum); +BOOL cli_lock(struct cli_state *cli, int fnum, + uint32 offset, uint32 len, int timeout, enum brl_type lock_type); +BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len); +size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size); +ssize_t cli_write(struct cli_state *cli, + int fnum, uint16 write_mode, + char *buf, off_t offset, size_t size); +ssize_t cli_smbwrite(struct cli_state *cli, + int fnum, char *buf, off_t offset, size_t size1); +BOOL cli_getattrE(struct cli_state *cli, int fd, + uint16 *attr, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time); +BOOL cli_getatr(struct cli_state *cli, char *fname, + uint16 *attr, size_t *size, time_t *t); +BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t); +BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, + size_t *size, uint16 *mode); +BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, size_t *size, uint16 *mode, + SMB_INO_T *ino); +BOOL cli_qfileinfo(struct cli_state *cli, int fnum, + uint16 *mode, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, SMB_INO_T *ino); +int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, + void (*fn)(file_info *, const char *)); +BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, + const char *old_password); +BOOL cli_negprot(struct cli_state *cli); +BOOL cli_session_request(struct cli_state *cli, + struct nmb_name *calling, struct nmb_name *called); +BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip); +struct cli_state *cli_initialise(struct cli_state *cli); +void cli_shutdown(struct cli_state *cli); +int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error); +void cli_sockopt(struct cli_state *cli, char *options); +uint16 cli_setpid(struct cli_state *cli, uint16 pid); +BOOL cli_reestablish_connection(struct cli_state *cli); +BOOL cli_establish_connection(struct cli_state *cli, + char *dest_host, struct in_addr *dest_ip, + struct nmb_name *calling, struct nmb_name *called, + char *service, char *service_type, + BOOL do_shutdown, BOOL do_tcon); +int cli_printjob_del(struct cli_state *cli, int job); +int cli_print_queue(struct cli_state *cli, + void (*fn)(struct print_job_info *)); +BOOL cli_chkpath(struct cli_state *cli, char *path); +BOOL cli_message_start(struct cli_state *cli, char *host, char *username, + int *grp); +BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp); +BOOL cli_message_end(struct cli_state *cli, int grp); +BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail); +BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, + struct in_addr *pdest_ip); + +/*The following definitions come from libsmb/credentials.c */ + +char *credstr(uchar *cred); +void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, + uchar session_key[8]); +void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp, + DOM_CHAL *cred); +int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred, + UTIME timestamp); +BOOL clnt_deal_with_creds(uchar sess_key[8], + DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred); +BOOL deal_with_creds(uchar sess_key[8], + DOM_CRED *sto_clnt_cred, + DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred); + +/*The following definitions come from libsmb/namequery.c */ + +BOOL name_status(int fd,char *name,int name_type,BOOL recurse, + struct in_addr to_ip,char *master,char *rname); +struct in_addr *name_query(int fd,const char *name,int name_type, + BOOL bcast,BOOL recurse, + struct in_addr to_ip, int *count); +FILE *startlmhosts(char *fname); +BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr); +void endlmhosts(FILE *fp); +BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type); +BOOL find_master_ip(char *group, struct in_addr *master_ip); +BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name); +BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count); + +/*The following definitions come from libsmb/nmblib.c */ + +void debug_nmb_packet(struct packet_struct *p); +char *nmb_namestr(struct nmb_name *n); +struct packet_struct *copy_packet(struct packet_struct *packet); +void free_packet(struct packet_struct *packet); +struct packet_struct *parse_packet(char *buf,int length, + enum packet_type packet_type); +struct packet_struct *read_packet(int fd,enum packet_type packet_type); +void make_nmb_name( struct nmb_name *n, const char *name, int type); +BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2); +int build_packet(char *buf, struct packet_struct *p); +BOOL send_packet(struct packet_struct *p); +struct packet_struct *receive_packet(int fd,enum packet_type type,int t); +struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id); +struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name); +BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name); +void sort_query_replies(char *data, int n, struct in_addr ip); + +/*The following definitions come from libsmb/nterr.c */ + +char *get_nt_error_msg(uint32 nt_code); + +/*The following definitions come from libsmb/passchange.c */ + +BOOL remote_password_change(const char *remote_machine, const char *user_name, + const char *old_passwd, const char *new_passwd, + char *err_str, size_t err_str_len); + +/*The following definitions come from libsmb/pwd_cache.c */ + +void pwd_init(struct pwd_info *pwd); +void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key); +BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2); +void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt); +void pwd_set_nullpwd(struct pwd_info *pwd); +void pwd_set_cleartext(struct pwd_info *pwd, char *clr); +void pwd_get_cleartext(struct pwd_info *pwd, char *clr); +void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); +void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); +void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr); +void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]); +void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]); + +/*The following definitions come from libsmb/smbdes.c */ + +void E_P16(unsigned char *p14,unsigned char *p16); +void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); +void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out); +void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out); +void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key); +void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key); +void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw); +void SamOEMhash( unsigned char *data, unsigned char *key, int val); + +/*The following definitions come from libsmb/smbencrypt.c */ + +void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24); +void E_md4hash(uchar *passwd, uchar *p16); +void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]); +void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]); +void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]); +void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24); +BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode); + +/*The following definitions come from libsmb/smberr.c */ + +char *smb_errstr(char *inbuf); + +/*The following definitions come from libsmb/unexpected.c */ + +void unexpected_packet(struct packet_struct *p); +void clear_unexpected(time_t t); +struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, + char *mailslot_name); + /*The following definitions come from locking/brlock.c */ void brl_init(int read_only); @@ -809,6 +812,10 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question, struct name_record **n); void kill_async_dns_child(void); +/*The following definitions come from nmbd/nmbd.c */ + +BOOL reload_services(BOOL test); + /*The following definitions come from nmbd/nmbd_become_dmb.c */ void add_domain_names(time_t t); @@ -839,10 +846,6 @@ void announce_and_sync_with_domain_master_browser( struct subnet_record *subrec, void collect_all_workgroup_names_from_wins_server(time_t t); void sync_all_dmbs(time_t t); -/*The following definitions come from nmbd/nmbd.c */ - -BOOL reload_services(BOOL test); - /*The following definitions come from nmbd/nmbd_elections.c */ void check_master_browser_exists(time_t t); @@ -1515,6 +1518,11 @@ void pcap_printer_fn(void (*fn)(char *, char *)); void cups_printer_fn(void (*fn)(char *, char *)); int cups_printername_ok(char *name); +/*The following definitions come from printing/print_svid.c */ + +void sysv_printer_fn(void (*fn)(char *, char *)); +int sysv_printername_ok(char *name); + /*The following definitions come from printing/printing.c */ void lpq_reset(int snum); @@ -1529,11 +1537,6 @@ void printjob_decode(int jobid, int *snum, int *job); void status_printqueue(connection_struct *conn,int snum,int status); void load_printers(void); -/*The following definitions come from printing/print_svid.c */ - -void sysv_printer_fn(void (*fn)(char *, char *)); -int sysv_printername_ok(char *name); - /*The following definitions come from profile/profile.c */ BOOL profile_setup(BOOL rdonly); @@ -1699,109 +1702,6 @@ BOOL do_wks_query_info(struct cli_state *cli, char *server_name, uint32 switch_value, WKS_INFO_100 *wks100); -/*The following definitions come from rpcclient/cmd_lsarpc.c */ - -void cmd_lsa_query_info(struct client_info *info); -void cmd_lsa_lookup_sids(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_netlogon.c */ - -void cmd_netlogon_login_test(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_reg.c */ - -void cmd_reg_enum(struct client_info *info); -void cmd_reg_query_key(struct client_info *info); -void cmd_reg_create_val(struct client_info *info); -void cmd_reg_delete_val(struct client_info *info); -void cmd_reg_delete_key(struct client_info *info); -void cmd_reg_create_key(struct client_info *info); -void cmd_reg_test_key_sec(struct client_info *info); -void cmd_reg_get_key_sec(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_samr.c */ - -void cmd_sam_ntchange_pwd(struct client_info *info); -void cmd_sam_test(struct client_info *info); -void cmd_sam_enum_users(struct client_info *info); -void cmd_sam_query_user(struct client_info *info); -void cmd_sam_query_groups(struct client_info *info); -void cmd_sam_enum_aliases(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_srvsvc.c */ - -void cmd_srv_query_info(struct client_info *info); -void cmd_srv_enum_conn(struct client_info *info); -void cmd_srv_enum_shares(struct client_info *info); -void cmd_srv_enum_sess(struct client_info *info); -void cmd_srv_enum_files(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_wkssvc.c */ - -void cmd_wks_query_info(struct client_info *info); - -/*The following definitions come from rpcclient/display.c */ - -char *get_file_mode_str(uint32 share_mode); -char *get_file_oplock_str(uint32 op_type); -char *get_share_type_str(uint32 type); -char *get_server_type_str(uint32 type); -void display_srv_info_101(FILE *out_hnd, enum action_type action, - SRV_INFO_101 *sv101); -void display_srv_info_102(FILE *out_hnd, enum action_type action,SRV_INFO_102 *sv102); -void display_srv_info_ctr(FILE *out_hnd, enum action_type action,SRV_INFO_CTR *ctr); -void display_conn_info_0(FILE *out_hnd, enum action_type action, - CONN_INFO_0 *info0); -void display_conn_info_1(FILE *out_hnd, enum action_type action, - CONN_INFO_1 *info1, CONN_INFO_1_STR *str1); -void display_srv_conn_info_0_ctr(FILE *out_hnd, enum action_type action, - SRV_CONN_INFO_0 *ctr); -void display_srv_conn_info_1_ctr(FILE *out_hnd, enum action_type action, - SRV_CONN_INFO_1 *ctr); -void display_srv_conn_info_ctr(FILE *out_hnd, enum action_type action, - SRV_CONN_INFO_CTR *ctr); -void display_share_info_1(FILE *out_hnd, enum action_type action, - SRV_SHARE_INFO_1 *info1); -void display_share_info_2(FILE *out_hnd, enum action_type action, - SRV_SHARE_INFO_2 *info2); -void display_srv_share_info_ctr(FILE *out_hnd, enum action_type action, - SRV_SHARE_INFO_CTR *ctr); -void display_file_info_3(FILE *out_hnd, enum action_type action, - FILE_INFO_3 *info3, FILE_INFO_3_STR *str3); -void display_srv_file_info_3_ctr(FILE *out_hnd, enum action_type action, - SRV_FILE_INFO_3 *ctr); -void display_srv_file_info_ctr(FILE *out_hnd, enum action_type action, - SRV_FILE_INFO_CTR *ctr); -void display_server(FILE *out_hnd, enum action_type action, - char *sname, uint32 type, char *comment); -void display_share(FILE *out_hnd, enum action_type action, - char *sname, uint32 type, char *comment); -void display_share2(FILE *out_hnd, enum action_type action, - char *sname, uint32 type, char *comment, - uint32 perms, uint32 max_uses, uint32 num_uses, - char *path, char *passwd); -void display_name(FILE *out_hnd, enum action_type action, - char *sname); -void display_group_rid_info(FILE *out_hnd, enum action_type action, - uint32 num_gids, DOM_GID *gid); -void display_alias_name_info(FILE *out_hnd, enum action_type action, - uint32 num_aliases, fstring *alias_name, uint32 *num_als_usrs); -void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_INFO_21 *usr); -char *get_sec_mask_str(uint32 type); -void display_sec_access(FILE *out_hnd, enum action_type action, SEC_ACCESS *info); -void display_sec_ace(FILE *out_hnd, enum action_type action, SEC_ACE *ace); -void display_sec_acl(FILE *out_hnd, enum action_type action, SEC_ACL *sec_acl); -void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *sec); -char *get_reg_val_type_str(uint32 type); -void display_reg_value_info(FILE *out_hnd, enum action_type action, - char *val_name, uint32 val_type, BUFFER2 *value); -void display_reg_key_info(FILE *out_hnd, enum action_type action, - char *key_name, time_t key_mod_time); - -/*The following definitions come from rpcclient/rpcclient.c */ - -void rpcclient_init(void); - /*The following definitions come from rpc_parse/parse_creds.c */ BOOL make_creds_unix(CREDS_UNIX *r_u, const char* user_name, @@ -2859,6 +2759,109 @@ uint32 lookup_user_rid(char *user_name, uint32 *rid); BOOL api_wkssvc_rpc(pipes_struct *p, prs_struct *data); +/*The following definitions come from rpcclient/cmd_lsarpc.c */ + +void cmd_lsa_query_info(struct client_info *info); +void cmd_lsa_lookup_sids(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_netlogon.c */ + +void cmd_netlogon_login_test(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_reg.c */ + +void cmd_reg_enum(struct client_info *info); +void cmd_reg_query_key(struct client_info *info); +void cmd_reg_create_val(struct client_info *info); +void cmd_reg_delete_val(struct client_info *info); +void cmd_reg_delete_key(struct client_info *info); +void cmd_reg_create_key(struct client_info *info); +void cmd_reg_test_key_sec(struct client_info *info); +void cmd_reg_get_key_sec(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_samr.c */ + +void cmd_sam_ntchange_pwd(struct client_info *info); +void cmd_sam_test(struct client_info *info); +void cmd_sam_enum_users(struct client_info *info); +void cmd_sam_query_user(struct client_info *info); +void cmd_sam_query_groups(struct client_info *info); +void cmd_sam_enum_aliases(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_srvsvc.c */ + +void cmd_srv_query_info(struct client_info *info); +void cmd_srv_enum_conn(struct client_info *info); +void cmd_srv_enum_shares(struct client_info *info); +void cmd_srv_enum_sess(struct client_info *info); +void cmd_srv_enum_files(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_wkssvc.c */ + +void cmd_wks_query_info(struct client_info *info); + +/*The following definitions come from rpcclient/display.c */ + +char *get_file_mode_str(uint32 share_mode); +char *get_file_oplock_str(uint32 op_type); +char *get_share_type_str(uint32 type); +char *get_server_type_str(uint32 type); +void display_srv_info_101(FILE *out_hnd, enum action_type action, + SRV_INFO_101 *sv101); +void display_srv_info_102(FILE *out_hnd, enum action_type action,SRV_INFO_102 *sv102); +void display_srv_info_ctr(FILE *out_hnd, enum action_type action,SRV_INFO_CTR *ctr); +void display_conn_info_0(FILE *out_hnd, enum action_type action, + CONN_INFO_0 *info0); +void display_conn_info_1(FILE *out_hnd, enum action_type action, + CONN_INFO_1 *info1, CONN_INFO_1_STR *str1); +void display_srv_conn_info_0_ctr(FILE *out_hnd, enum action_type action, + SRV_CONN_INFO_0 *ctr); +void display_srv_conn_info_1_ctr(FILE *out_hnd, enum action_type action, + SRV_CONN_INFO_1 *ctr); +void display_srv_conn_info_ctr(FILE *out_hnd, enum action_type action, + SRV_CONN_INFO_CTR *ctr); +void display_share_info_1(FILE *out_hnd, enum action_type action, + SRV_SHARE_INFO_1 *info1); +void display_share_info_2(FILE *out_hnd, enum action_type action, + SRV_SHARE_INFO_2 *info2); +void display_srv_share_info_ctr(FILE *out_hnd, enum action_type action, + SRV_SHARE_INFO_CTR *ctr); +void display_file_info_3(FILE *out_hnd, enum action_type action, + FILE_INFO_3 *info3, FILE_INFO_3_STR *str3); +void display_srv_file_info_3_ctr(FILE *out_hnd, enum action_type action, + SRV_FILE_INFO_3 *ctr); +void display_srv_file_info_ctr(FILE *out_hnd, enum action_type action, + SRV_FILE_INFO_CTR *ctr); +void display_server(FILE *out_hnd, enum action_type action, + char *sname, uint32 type, char *comment); +void display_share(FILE *out_hnd, enum action_type action, + char *sname, uint32 type, char *comment); +void display_share2(FILE *out_hnd, enum action_type action, + char *sname, uint32 type, char *comment, + uint32 perms, uint32 max_uses, uint32 num_uses, + char *path, char *passwd); +void display_name(FILE *out_hnd, enum action_type action, + char *sname); +void display_group_rid_info(FILE *out_hnd, enum action_type action, + uint32 num_gids, DOM_GID *gid); +void display_alias_name_info(FILE *out_hnd, enum action_type action, + uint32 num_aliases, fstring *alias_name, uint32 *num_als_usrs); +void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_INFO_21 *usr); +char *get_sec_mask_str(uint32 type); +void display_sec_access(FILE *out_hnd, enum action_type action, SEC_ACCESS *info); +void display_sec_ace(FILE *out_hnd, enum action_type action, SEC_ACE *ace); +void display_sec_acl(FILE *out_hnd, enum action_type action, SEC_ACL *sec_acl); +void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *sec); +char *get_reg_val_type_str(uint32 type); +void display_reg_value_info(FILE *out_hnd, enum action_type action, + char *val_name, uint32 val_type, BUFFER2 *value); +void display_reg_key_info(FILE *out_hnd, enum action_type action, + char *key_name, time_t key_mod_time); + +/*The following definitions come from rpcclient/rpcclient.c */ + +void rpcclient_init(void); + /*The following definitions come from smbd/blocking.c */ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num); @@ -3244,19 +3247,6 @@ BOOL unbecome_authenticated_pipe_user(pipes_struct *p); void become_root(BOOL save_dir) ; void unbecome_root(BOOL restore_dir); -/*The following definitions come from smbd/vfs.c */ - -int vfs_init_default(connection_struct *conn); -BOOL vfs_init_custom(connection_struct *conn); -BOOL vfs_directory_exist(connection_struct *conn, char *dname, - SMB_STRUCT_STAT *st); -BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf); -ssize_t vfs_write_data(files_struct *fsp,char *buffer,size_t N); -SMB_OFF_T vfs_transfer_file(int in_fd, files_struct *in_fsp, - int out_fd, files_struct *out_fsp, - SMB_OFF_T n, char *header, int headlen, int align); -char *vfs_readdirname(connection_struct *conn, void *p); - /*The following definitions come from smbd/vfs-wrap.c */ int vfswrap_dummy_connect(struct vfs_connection_struct *conn, char *service, @@ -3284,6 +3274,19 @@ int vfswrap_unlink(char *path); int vfswrap_chmod(char *path, mode_t mode); int vfswrap_utime(char *path, struct utimbuf *times); +/*The following definitions come from smbd/vfs.c */ + +int vfs_init_default(connection_struct *conn); +BOOL vfs_init_custom(connection_struct *conn); +BOOL vfs_directory_exist(connection_struct *conn, char *dname, + SMB_STRUCT_STAT *st); +BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf); +ssize_t vfs_write_data(files_struct *fsp,char *buffer,size_t N); +SMB_OFF_T vfs_transfer_file(int in_fd, files_struct *in_fsp, + int out_fd, files_struct *out_fsp, + SMB_OFF_T n, char *header, int headlen, int align); +char *vfs_readdirname(connection_struct *conn, void *p); + /*The following definitions come from smbwrapper/realcalls.c */ int real_utime(const char *name, struct utimbuf *buf); diff --git a/source/lib/debug.c b/source/lib/debug.c index a0dfe61f7df..c88f4e1a41f 100644 --- a/source/lib/debug.c +++ b/source/lib/debug.c @@ -318,7 +318,8 @@ va_dcl va_start( ap ); format_str = va_arg( ap, char * ); #endif - (void)vfprintf( dbf, format_str, ap ); + if(dbf) + (void)vfprintf( dbf, format_str, ap ); va_end( ap ); errno = old_errno; return( 0 ); @@ -397,9 +398,11 @@ va_dcl va_start( ap ); format_str = va_arg( ap, char * ); #endif - (void)vfprintf( dbf, format_str, ap ); + if(dbf) + (void)vfprintf( dbf, format_str, ap ); va_end( ap ); - (void)fflush( dbf ); + if(dbf) + (void)fflush( dbf ); } errno = old_errno; @@ -488,7 +491,8 @@ static void format_debug_text( char *msg ) void dbgflush( void ) { bufr_print(); - (void)fflush( dbf ); + if(dbf) + (void)fflush( dbf ); } /* dbgflush */ /* ************************************************************************** ** diff --git a/source/lib/replace.c b/source/lib/replace.c index 6a492f977c3..8d91c2d785c 100644 --- a/source/lib/replace.c +++ b/source/lib/replace.c @@ -163,15 +163,21 @@ Corrections by richard.kettlewell@kewill.com /* yikes! no SETGROUPS or INITGROUPS? how can this work? */ return(0); #else /* HAVE_SETGROUPS */ - gid_t grouplst[NGROUPS_MAX]; + gid_t *grouplst = NULL; + int max_gr = groups_max(); + int ret; int i,j; struct group *g; char *gr; + if((grouplst = (gid_t *)malloc(sizeof(gid_t) * max_gr)) == NULL) { + DEBUG(0,("initgroups: malloc fail !\n"); + return -1; + } + grouplst[0] = id; i = 1; - while (i < NGROUPS_MAX && - ((g = (struct group *)getgrent()) != (struct group *)NULL)) { + while (i < max_gr && ((g = (struct group *)getgrent()) != (struct group *)NULL)) { if (g->gr_gid == id) continue; j = 0; @@ -187,7 +193,9 @@ Corrections by richard.kettlewell@kewill.com } } endgrent(); - return(sys_setgroups(i,grouplst)); + ret = sys_setgroups(i,grouplst); + free((char *)grouplst); + return ret; #endif /* HAVE_SETGROUPS */ } #endif /* HAVE_INITGROUPS */ diff --git a/source/lib/system.c b/source/lib/system.c index d1467499747..25925b6d8ec 100644 --- a/source/lib/system.c +++ b/source/lib/system.c @@ -561,6 +561,20 @@ void sys_srandom(unsigned int seed) #endif } +/************************************************************************** + Returns equivalent to NGROUPS_MAX - using sysconf if needed. +****************************************************************************/ + +int groups_max(void) +{ +#if defined(SYSCONF_SC_NGROUPS_MAX) + int ret = sysconf(_SC_NGROUPS_MAX); + return (ret == -1) ? NGROUPS_MAX : ret; +#else + return NGROUPS_MAX; +#endif +} + /************************************************************************** Wrapper for getgroups. Deals with broken (int) case. ****************************************************************************/ @@ -590,7 +604,7 @@ int sys_getgroups(int setlen, gid_t *gidset) } if (setlen == 0) - setlen = 1; + setlen = groups_max(); if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) { DEBUG(0,("sys_getgroups: Malloc fail.\n")); @@ -631,21 +645,16 @@ int sys_setgroups(int setlen, gid_t *gidset) if (setlen == 0) return 0 ; -#ifdef NGROUPS_MAX - if (setlen > NGROUPS_MAX) { + if (setlen < 0 || setlen > groups_max()) { errno = EINVAL; return -1; } -#endif /* * Broken case. We need to allocate a * GID_T array of size setlen. */ - if (setlen == 0) - setlen = 1; - if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) { DEBUG(0,("sys_setgroups: Malloc fail.\n")); return -1; @@ -892,3 +901,211 @@ SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid) return &retval; } + +/************************************************************************** + Extract a command into an arg list. Uses a static pstring for storage. + Caller frees returned arg list (which contains pointers into the static pstring). +****************************************************************************/ + +static char **extract_args(const char *command) +{ + static pstring trunc_cmd; + char *ptr; + int argcl; + char **argl = NULL; + int i; + + pstrcpy(trunc_cmd, command); + + if(!(ptr = strtok(trunc_cmd, " \t"))) { + errno = EINVAL; + return NULL; + } + + /* + * Count the args. + */ + + for( argcl = 1; ptr; ptr = strtok(NULL, " \t")) + argcl++; + + if((argl = (char **)malloc((argcl + 1) * sizeof(char *))) == NULL) + return NULL; + + /* + * Now do the extraction. + */ + + pstrcpy(trunc_cmd, command); + + ptr = strtok(trunc_cmd, " \t"); + i = 0; + argl[i++] = ptr; + + while((ptr = strtok(NULL, " \t")) != NULL) + argl[i++] = ptr; + + argl[i++] = NULL; + return argl; +} + +/************************************************************************** + Wrapper for popen. Safer as it doesn't search a path. + Modified from the glibc sources. +****************************************************************************/ + +typedef struct _popen_list +{ + FILE *fp; + pid_t child_pid; + struct _popen_list *next; +} popen_list; + +static popen_list *popen_chain; + +FILE *sys_popen(const char *command, const char *mode) +{ + int parent_end, child_end; + int pipe_fds[2]; + popen_list *entry = NULL; + pid_t child_pid; + char **argl = NULL; + + if (pipe(pipe_fds) < 0) + return NULL; + + if (mode[0] == 'r' && mode[1] == '\0') { + parent_end = pipe_fds[0]; + child_end = pipe_fds[1]; + } else if (mode[0] == 'w' && mode[1] == '\0') { + parent_end = pipe_fds[1]; + child_end = pipe_fds[0]; + } else { + errno = EINVAL; + goto err_exit; + } + + if (!*command) { + errno = EINVAL; + goto err_exit; + } + + if((entry = (popen_list *)malloc(sizeof(popen_list))) == NULL) + goto err_exit; + + /* + * Extract the command and args into a NULL terminated array. + */ + + if(!(argl = extract_args(command))) + goto err_exit; + + entry->child_pid = fork(); + + if (entry->child_pid == -1) { + + /* + * Error ! + */ + + goto err_exit; + } + + if (entry->child_pid == 0) { + + /* + * Child ! + */ + + int child_std_end = (mode[0] == 'r') ? STDOUT_FILENO : STDIN_FILENO; + popen_list *p; + + close(parent_end); + if (child_end != child_std_end) { + dup2 (child_end, child_std_end); + close (child_end); + } + + /* + * POSIX.2: "popen() shall ensure that any streams from previous + * popen() calls that remain open in the parent process are closed + * in the new child process." + */ + + for (p = popen_chain; p; p = p->next) + close(fileno(p->fp)); + + execv(argl[0], argl); + _exit (127); + } + + /* + * Parent. + */ + + close (child_end); + free((char *)argl); + + /* + * Create the FILE * representing this fd. + */ + entry->fp = fdopen(parent_end, mode); + + /* Link into popen_chain. */ + entry->next = popen_chain; + popen_chain = entry; + + return entry->fp; + +err_exit: + + if(entry) + free((char *)entry); + if(argl) + free((char *)argl); + close(pipe_fds[0]); + close(pipe_fds[1]); + return NULL; +} + +/************************************************************************** + Wrapper for pclose. Modified from the glibc sources. +****************************************************************************/ + +int sys_pclose( FILE *fp) +{ + int wstatus; + popen_list **ptr = &popen_chain; + popen_list *entry = NULL; + pid_t wait_pid; + int status = -1; + + /* Unlink from popen_chain. */ + for ( ; *ptr != NULL; ptr = &(*ptr)->next) { + if ((*ptr)->fp == fp) { + entry = *ptr; + *ptr = (*ptr)->next; + status = 0; + break; + } + } + + if (status < 0 || close(fileno(entry->fp)) < 0) + return -1; + + /* + * As Samba is catching and eating child process + * exits we don't really care about the child exit + * code, a -1 with errno = ECHILD will do fine for us. + */ + + do { + wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0); + } while (wait_pid == -1 && errno == EINTR); + + free((char *)entry); + + if (wait_pid == -1) + return -1; + return wstatus; +} diff --git a/source/printing/print_svid.c b/source/printing/print_svid.c index ffc059f9f91..9891e158a27 100644 --- a/source/printing/print_svid.c +++ b/source/printing/print_svid.c @@ -47,10 +47,9 @@ static printer_t *printers = NULL; static void populate_printers(void) { -#ifdef HAVE_POPEN FILE *fp; - if ((fp = popen("/usr/bin/lpstat -v", "r")) != NULL) { + if ((fp = sys_popen("/usr/bin/lpstat -v", "r")) != NULL) { char buf[BUFSIZ]; while (fgets(buf, sizeof (buf), fp) != NULL) { @@ -88,13 +87,10 @@ static void populate_printers(void) DEBUG(0,("populate_printers: malloc fail for ptmp\n")); } } - pclose(fp); + sys_pclose(fp); } else { DEBUG(0,( "Unable to run lpstat!\n")); } -#else - DEBUG(0,( "No popen() defined: Unable to run lpstat!\n")); -#endif } diff --git a/source/smbd/dfree.c b/source/smbd/dfree.c index 78380804615..7866d60277d 100644 --- a/source/smbd/dfree.c +++ b/source/smbd/dfree.c @@ -208,7 +208,6 @@ static SMB_BIG_UINT disk_free(char *path, BOOL small_query, * If external disk calculation specified, use it. */ -#ifdef HAVE_POPEN dfree_command = lp_dfree_command(); if (dfree_command && *dfree_command) { pstring line; @@ -216,7 +215,9 @@ static SMB_BIG_UINT disk_free(char *path, BOOL small_query, FILE *pp; slprintf (line, sizeof(pstring) - 1, "%s %s", dfree_command, path); - pp = popen(line, "r"); + DEBUG (3, ("disk_free: Running command %s\n", line)); + + pp = sys_popen(line, "r"); if (pp) { fgets(line, sizeof(pstring), pp); line[sizeof(pstring)-1] = '\0'; @@ -236,7 +237,7 @@ static SMB_BIG_UINT disk_free(char *path, BOOL small_query, *bsize = (SMB_BIG_UINT)strtoul(p, NULL, 10); else *bsize = 1024; - pclose (pp); + sys_pclose (pp); DEBUG (3, ("Parsed output of dfree, dsize=%u, dfree=%u, bsize=%u\n", (unsigned int)*dsize, (unsigned int)*dfree, (unsigned int)*bsize)); @@ -245,12 +246,11 @@ static SMB_BIG_UINT disk_free(char *path, BOOL small_query, if (!*dfree) *dfree = 1024; } else { - DEBUG (0, ("disk_free: popen() failed for command %s. Error was : %s\n", + DEBUG (0, ("disk_free: sys_popen() failed for command %s. Error was : %s\n", line, strerror(errno) )); fsusage(path, dfree, dsize); } } else -#endif /* HAVE_POPEN */ fsusage(path, dfree, dsize); if (disk_quotas(path, &bsize_q, &dfree_q, &dsize_q)) { diff --git a/source/smbd/nttrans.c b/source/smbd/nttrans.c index d9ad16e7d3c..e94e603661a 100644 --- a/source/smbd/nttrans.c +++ b/source/smbd/nttrans.c @@ -843,15 +843,13 @@ int reply_ntcreate_and_X(connection_struct *conn, } if(fsp->is_directory) { - if(fsp->conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False), - &sbuf) != 0) { + if(conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name, False), &sbuf) != 0) { close_file(fsp,True); restore_case_semantics(file_attributes); return(ERROR(ERRDOS,ERRnoaccess)); } } else { - if (fsp->conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) - != 0) { + if (conn->vfs_ops.fstat(fsp->fd_ptr->fd,&sbuf) != 0) { close_file(fsp,False); restore_case_semantics(file_attributes); return(ERROR(ERRDOS,ERRnoaccess)); diff --git a/source/smbd/password.c b/source/smbd/password.c index 44fbdfa8ec4..19e7d36443d 100644 --- a/source/smbd/password.c +++ b/source/smbd/password.c @@ -175,14 +175,10 @@ int setup_groups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_gro ngroups = sys_getgroups(0,&grp); if (ngroups <= 0) { - ngroups = 32; + ngroups = groups_max(); } -#ifdef NGROUPS_MAX - if((groups = (gid_t *)malloc(sizeof(gid_t)*NGROUPS_MAX)) == NULL) -#else /* NGROUPS_MAX */ if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL) -#endif /* NGROUPS_MAX */ { DEBUG(0,("setup_groups malloc fail !\n")); return -1; diff --git a/source/utils/make_printerdef.c b/source/utils/make_printerdef.c index fc1f8ad7812..33aec325c2e 100644 --- a/source/utils/make_printerdef.c +++ b/source/utils/make_printerdef.c @@ -27,7 +27,7 @@ */ char *files_to_copy; -char *driverfile, *datafile, *helpfile, *languagemonitor, *datatype; +char *driverfile, *datafile, *helpfile, *languagemonitor, *datatype, *vendorsetup; char buffer[50][sizeof(pstring)]; char sbuffer[50][sizeof(pstring)]; char sub_dir[50][2][sizeof(pstring)]; @@ -96,13 +96,20 @@ static char *scan(char *chaine,char **entry) i++; } (*entry)[i]='\0'; - pstrcpy(value,temp+i+1); + if (temp[i]!='\0') { + i++; + } + while( temp[i]==' ' && temp[i]!='\0') { + i++; + } + pstrcpy(value,temp+i); return (value); } static void build_subdir(void) { int i=0; + int j=0; char *entry; char *data; @@ -111,12 +118,18 @@ static void build_subdir(void) #ifdef DEBUGIT fprintf(stderr,"\tentry=data %s:%s\n",entry,data); #endif + j = strlen(entry); + while (j) { + if (entry[j-1] != ' ') break; + j--; + } + entry[j] = '\0'; - if (strcmp(data,"11")==0) { + if (strncmp(data,"11",2)==0) { pstrcpy(sub_dir[i][0],entry); pstrcpy(sub_dir[i][1],""); } - if (strcmp(data,"23")==0) { + if (strncmp(data,"23",2)==0) { pstrcpy(sub_dir[i][0],entry); pstrcpy(sub_dir[i][1],"color\\"); } @@ -362,15 +375,21 @@ static void scan_copyfiles(FILE *fichier, char *chaine) else break; } } - if (strlen(files_to_copy) != 0) - pstrcat(files_to_copy,","); - pstrcat(files_to_copy,direc); - pstrcat(files_to_copy,buffer[i]); - fprintf(stderr,"%s%s\n",direc,buffer[i]); + if (*buffer[i] != ';') { + if (strlen(files_to_copy) != 0) + pstrcat(files_to_copy,","); + pstrcat(files_to_copy,direc); + pstrcat(files_to_copy,buffer[i]); + fprintf(stderr,"%s%s\n",direc,buffer[i]); + } i++; } } part=strtok(NULL,","); + if (part) + while( *part ==' ' && *part != '\0') { + part++; + } } while (part!=NULL); fprintf(stderr,"\n"); @@ -385,6 +404,7 @@ static void scan_short_desc(FILE *fichier, char *short_desc) helpfile=0; languagemonitor=0; + vendorsetup=0; datatype="RAW"; if((temp=(char *)malloc(sizeof(pstring))) == NULL) { fprintf(stderr, "scan_short_desc: malloc fail !\n"); @@ -414,6 +434,8 @@ static void scan_short_desc(FILE *fichier, char *short_desc) languagemonitor=scan(buffer[i],&temp); else if (strncasecmp(buffer[i],"DefaultDataType",15)==0) datatype=scan(buffer[i],&temp); + else if (strncasecmp(buffer[i],"VendorSetup",11)==0) + vendorsetup=scan(buffer[i],&temp); i++; } @@ -439,6 +461,8 @@ static void scan_short_desc(FILE *fichier, char *short_desc) languagemonitor=scan(buffer[i],&temp); else if (strncasecmp(buffer[i],"DefaultDataType",15)==0) datatype=scan(buffer[i],&temp); + else if (strncasecmp(buffer[i],"VendorSetup",11)==0) + vendorsetup=scan(buffer[i],&temp); i++; } } @@ -464,6 +488,8 @@ static void scan_short_desc(FILE *fichier, char *short_desc) helpfile?helpfile:"(null)"); fprintf(stderr,"LanguageMonitor: %s\n", languagemonitor?languagemonitor:"(null)"); + fprintf(stderr,"VendorSetup: %s\n", + vendorsetup?vendorsetup:"(null)"); if (copyfiles) scan_copyfiles(fichier,copyfiles); } -- cgit From f29847cbeeb0109f1fa61e9851e8cb0689b5228d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Feb 2000 02:35:53 +0000 Subject: Added "source environment" parameter from Nicolas Williams . Jeremy. --- source/param/loadparm.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 136 insertions(+), 1 deletion(-) diff --git a/source/param/loadparm.c b/source/param/loadparm.c index 85082467412..7a225b035e6 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -164,6 +164,7 @@ typedef struct #ifdef WITH_UTMP char *szUtmpDir; #endif /* WITH_UTMP */ + char *szSourceEnv; int max_log_size; int mangled_stack; int max_xmit; @@ -493,6 +494,8 @@ static BOOL handle_character_set(char *pszParmValue,char **ptr); static BOOL handle_coding_system(char *pszParmValue,char **ptr); static BOOL handle_client_code_page(char *pszParmValue,char **ptr); static BOOL handle_vfs_object(char *pszParmValue, char **ptr); +static BOOL handle_source_env(char *pszParmValue,char **ptr); +static BOOL handle_netbios_name(char *pszParmValue,char **ptr); static void set_default_server_announce_type(void); @@ -561,7 +564,7 @@ static struct parm_struct parm_table[] = {"path", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_BASIC|FLAG_SHARE|FLAG_PRINT|FLAG_DOS_STRING}, {"directory", P_STRING, P_LOCAL, &sDefault.szPath, NULL, NULL, FLAG_DOS_STRING}, {"workgroup", P_USTRING, P_GLOBAL, &Globals.szWorkGroup, NULL, NULL, FLAG_BASIC|FLAG_DOS_STRING}, - {"netbios name", P_UGSTRING,P_GLOBAL, global_myname, NULL, NULL, FLAG_BASIC|FLAG_DOS_STRING}, + {"netbios name", P_UGSTRING,P_GLOBAL, global_myname, handle_netbios_name, NULL, FLAG_BASIC|FLAG_DOS_STRING}, {"netbios aliases", P_STRING, P_GLOBAL, &Globals.szNetbiosAliases, NULL, NULL, FLAG_DOS_STRING}, {"netbios scope", P_UGSTRING,P_GLOBAL, global_scope, NULL, NULL, FLAG_DOS_STRING}, {"server string", P_STRING, P_GLOBAL, &Globals.szServerString, NULL, NULL, FLAG_BASIC|FLAG_DOS_STRING}, @@ -853,6 +856,7 @@ static struct parm_struct parm_table[] = {"volume", P_STRING, P_LOCAL, &sDefault.volume, NULL, NULL, FLAG_SHARE}, {"fstype", P_STRING, P_LOCAL, &sDefault.fstype, NULL, NULL, FLAG_SHARE}, {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL, NULL, FLAG_SHARE}, + {"source environment",P_STRING, P_GLOBAL, &Globals.szSourceEnv, handle_source_env,NULL,0}, {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL, NULL, FLAG_SHARE|FLAG_GLOBAL}, {"dont descend", P_STRING, P_LOCAL, &sDefault.szDontdescend, NULL, NULL, FLAG_SHARE}, @@ -1190,6 +1194,7 @@ FN_GLOBAL_STRING(lp_lockdir,&Globals.szLockDir) FN_GLOBAL_STRING(lp_utmpdir,&Globals.szUtmpDir) #endif /* WITH_UTMP */ FN_GLOBAL_STRING(lp_rootdir,&Globals.szRootdir) +FN_GLOBAL_STRING(lp_source_environment,&Globals.szSourceEnv) FN_GLOBAL_STRING(lp_defaultservice,&Globals.szDefaultService) FN_GLOBAL_STRING(lp_msg_command,&Globals.szMsgCommand) FN_GLOBAL_STRING(lp_dfree_command,&Globals.szDfree) @@ -1906,6 +1911,136 @@ BOOL lp_file_list_changed(void) return(False); } +/*************************************************************************** + Run standard_sub_basic on netbios name... needed because global_myname + is not accessed through any lp_ macro. +***************************************************************************/ + +static BOOL handle_netbios_name(char *pszParmValue,char **ptr) +{ + pstring netbios_name; + + pstrcpy(netbios_name,pszParmValue); + + standard_sub_basic(netbios_name); + strupper(netbios_name); + string_set(ptr,netbios_name); + + /* + * Convert from UNIX to DOS string - the UNIX to DOS converter + * isn't called on the special handlers. + */ + unix_to_dos(netbios_name, True); + pstrcpy(global_myname,netbios_name); + + DEBUG(4,("handle_netbios_name: set global_myname to: %s\n", global_myname)); + + return(True); +} + +/*************************************************************************** + Do the work of sourcing in environment variable/value pairs. +***************************************************************************/ + +static BOOL source_env(FILE *fenv) +{ + pstring line; + char *varval; + size_t len; + char *p; + + while (!feof(fenv)) { + if (fgets(line, sizeof(line), fenv) == NULL) + break; + + if(feof(fenv)) + break; + + if((len = strlen(line)) == 0) + continue; + + if (line[len - 1] == '\n') + line[--len] = '\0'; + + if ((varval=malloc(len+1)) == NULL) { + DEBUG(0,("source_env: Not enough memory!\n")); + return(False); + } + + DEBUG(4,("source_env: Adding to environment: %s\n", line)); + strncpy(varval, line, len); + varval[len] = '\0'; + + p=strchr(line, (int) '='); + if (p == NULL) { + DEBUG(4,("source_env: missing '=': %s\n", line)); + continue; + } + + if (putenv(varval)) { + DEBUG(0,("source_env: Failed to put environment variable %s\n", varval )); + continue; + } + + *p='\0'; + p++; + DEBUG(4,("source_env: getting var %s = %s\n", line, getenv(line))); + } + + DEBUG(4,("source_env: returning successfully\n")); + return(True); +} + +/*************************************************************************** + Handle the source environment operation +***************************************************************************/ + +static BOOL handle_source_env(char *pszParmValue,char **ptr) +{ + pstring fname; + char *p = fname; + FILE *env; + BOOL result; + + pstrcpy(fname,pszParmValue); + + standard_sub_basic(fname); + + string_set(ptr,pszParmValue); + + DEBUG(4, ("handle_source_env: checking env type\n")); + + /* + * Filename starting with '|' means popen and read from stdin. + */ + + if (*p == '|') { + + DEBUG(4, ("handle_source_env: source env from pipe\n")); + p++; + + if ((env = sys_popen(p, "r")) == NULL) { + DEBUG(0,("handle_source_env: Failed to popen %s. Error was %s\n", p, strerror(errno) )); + return(False); + } + + DEBUG(4, ("handle_source_env: calling source_env()\n")); + result = source_env(env); + sys_pclose(env); + + } else { + + DEBUG(4, ("handle_source_env: source env from file %s\n", fname)); + if ((env = sys_fopen(fname, "r")) == NULL) { + DEBUG(0,("handle_source_env: Failed to open file %s, Error was %s\n", fname, strerror(errno) )); + return(False); + } + result=source_env(env); + fclose(env); + } + return(result); +} + /*************************************************************************** handle the interpretation of the vfs object parameter *************************************************************************/ -- cgit From 2d3e2f8877fb8eb21b4ccf4d7a56f1c625c71780 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 16 Feb 2000 04:56:11 +0000 Subject: tdb_traverse() now takes three arguments. --- source/tdb/tdbtorture.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/tdb/tdbtorture.c b/source/tdb/tdbtorture.c index 3eb462d79eb..d72d7b35255 100644 --- a/source/tdb/tdbtorture.c +++ b/source/tdb/tdbtorture.c @@ -106,9 +106,9 @@ int main(int argc, char *argv[]) srand(seed + getpid()); for (i=0;i Date: Wed, 16 Feb 2000 17:52:25 +0000 Subject: Make proto. --- source/include/proto.h | 1 + 1 file changed, 1 insertion(+) diff --git a/source/include/proto.h b/source/include/proto.h index 9209f3063e1..b7a08e60de9 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -1153,6 +1153,7 @@ char *lp_printcapname(void); char *lp_lockdir(void); char *lp_utmpdir(void); char *lp_rootdir(void); +char *lp_source_environment(void); char *lp_defaultservice(void); char *lp_msg_command(void); char *lp_dfree_command(void); -- cgit From 377515cf9624720362c0b76969b9381d9972a13f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Feb 2000 22:48:19 +0000 Subject: Added support for SO_REUSEPORT for systems that have it. Jeremy. --- source/lib/util_sock.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c index 3a09c52a7a5..fd5ed71c9cc 100644 --- a/source/lib/util_sock.c +++ b/source/lib/util_sock.c @@ -76,6 +76,9 @@ struct #ifdef IPTOS_THROUGHPUT {"IPTOS_THROUGHPUT", IPPROTO_IP, IP_TOS, IPTOS_THROUGHPUT, OPT_ON}, #endif +#ifdef SO_REUSEPORT + {"SO_REUSEPORT", SOL_SOCKET, SO_REUSEPORT, 0, OPT_BOOL}, +#endif #ifdef SO_SNDBUF {"SO_SNDBUF", SOL_SOCKET, SO_SNDBUF, 0, OPT_INT}, #endif @@ -841,7 +844,14 @@ int open_socket_in(int type, int port, int dlevel,uint32 socket_addr, BOOL rebin val=1; else val=0; - setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)); + if(setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val)) == -1) + DEBUG(dlevel,("setsockopt: SO_REUSEADDR=%d on port %d failed with error = %s\n", + val, port, strerror(errno) )); +#ifdef SO_REUSEPORT + if(setsockopt(res,SOL_SOCKET,SO_REUSEPORT,(char *)&val,sizeof(val)) == -1) + DEBUG(dlevel,("setsockopt: SO_REUSEPORT=%d on port %d failed with error = %s\n", + val, port, strerror(errno) )); +#endif /* SO_REUSEPORT */ } /* now we've got a socket - we need to bind it */ -- cgit From 7faa70d254549e60520de1ed1112d41fe9a4d77c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 16 Feb 2000 22:57:57 +0000 Subject: More checks for passing NULL tdb contexts to tdb functions. --- source/tdb/tdb.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/source/tdb/tdb.c b/source/tdb/tdb.c index a754c583e60..15a4a37945c 100644 --- a/source/tdb/tdb.c +++ b/source/tdb/tdb.c @@ -597,6 +597,13 @@ int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf) tdb_off rec_ptr; int ret = -1; + if (tdb == NULL) { +#ifdef TDB_DEBUG + printf("tdb_update() called with null context\n"); +#endif + return -1; + } + /* find which hash bucket it is in */ hash = tdb_hash(&key); @@ -634,6 +641,13 @@ TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key) struct list_struct rec; TDB_DATA ret = null_data; + if (tdb == NULL) { +#ifdef TDB_DEBUG + printf("tdb_fetch() called with null context\n"); +#endif + return null_data; + } + /* find which hash bucket it is in */ hash = tdb_hash(&key); @@ -687,6 +701,13 @@ int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, TDB_DATA key, TDB char *data; TDB_DATA key, dbuf; + if (tdb == NULL) { +#ifdef TDB_DEBUG + printf("tdb_traverse() called with null context\n"); +#endif + return -1; + } + /* loop over all hash chains */ for (h = 0; h < tdb->header.hash_size; h++) { tdb_lock(tdb, BUCKET(h)); @@ -749,6 +770,13 @@ TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb) unsigned hash; TDB_DATA ret; + if (tdb == NULL) { +#ifdef TDB_DEBUG + printf("tdb_firstkey() called with null context\n"); +#endif + return null_data; + } + /* look for a non-empty hash chain */ for (hash = 0, rec_ptr = 0; hash < tdb->header.hash_size; @@ -794,6 +822,13 @@ TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key) struct list_struct rec; TDB_DATA ret; + if (tdb == NULL) { +#ifdef TDB_DEBUG + printf("tdb_nextkey() called with null context\n"); +#endif + return null_data; + } + /* find which hash bucket it is in */ hash = tdb_hash(&key); hbucket = BUCKET(hash); @@ -842,6 +877,13 @@ int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key) struct list_struct rec, lastrec; char *data = NULL; + if (tdb == NULL) { +#ifdef TDB_DEBUG + printf("tdb_delete() called with null context\n"); +#endif + return -1; + } + /* find which hash bucket it is in */ hash = tdb_hash(&key); @@ -940,6 +982,13 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) tdb_off rec_ptr, offset; char *p = NULL; + if (tdb == NULL) { +#ifdef TDB_DEBUG + printf("tdb_store() called with null context\n"); +#endif + return -1; + } + /* find which hash bucket it is in */ hash = tdb_hash(&key); @@ -1136,12 +1185,26 @@ int tdb_close(TDB_CONTEXT *tdb) /* lock the database. If we already have it locked then don't do anything */ int tdb_writelock(TDB_CONTEXT *tdb) { + if (tdb == NULL) { +#ifdef TDB_DEBUG + printf("tdb_writelock() called with null context\n"); +#endif + return -1; + } + return tdb_lock(tdb, -1); } /* unlock the database. */ int tdb_writeunlock(TDB_CONTEXT *tdb) { + if (tdb == NULL) { +#ifdef TDB_DEBUG + printf("tdb_writeunlock() called with null context\n"); +#endif + return -1; + } + return tdb_unlock(tdb, -1); } @@ -1149,6 +1212,13 @@ int tdb_writeunlock(TDB_CONTEXT *tdb) contention - it cannot guarantee how many records will be locked */ int tdb_lockchain(TDB_CONTEXT *tdb, TDB_DATA key) { + if (tdb == NULL) { +#ifdef TDB_DEBUG + printf("tdb_lockchain() called with null context\n"); +#endif + return -1; + } + return tdb_lock(tdb, BUCKET(tdb_hash(&key))); } @@ -1156,5 +1226,12 @@ int tdb_lockchain(TDB_CONTEXT *tdb, TDB_DATA key) /* unlock one hash chain */ int tdb_unlockchain(TDB_CONTEXT *tdb, TDB_DATA key) { + if (tdb == NULL) { +#ifdef TDB_DEBUG + printf("tdb_unlockchain() called with null context\n"); +#endif + return -1; + } + return tdb_unlock(tdb, BUCKET(tdb_hash(&key))); } -- cgit From 8cbc7dfa031cb66d1f011705b6bd76d56c68cae5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 17 Feb 2000 00:16:40 +0000 Subject: Updated docs for tdb_traverse. --- source/tdb/README | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/tdb/README b/source/tdb/README index 7901bf1c424..9eef521075a 100644 --- a/source/tdb/README +++ b/source/tdb/README @@ -101,9 +101,10 @@ int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); ---------------------------------------------------------------------- int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, - TDB_DATA key, TDB_DATA dbuf)); + TDB_DATA key, TDB_DATA dbuf, void *state), void *state); - traverse the entire database - calling fn(tdb, key, data) on each element. + traverse the entire database - calling fn(tdb, key, data, state) on each + element. return -1 on error or the record count traversed -- cgit From 02f845e54351ec57ee873a8ed887285552c6ecab Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 17 Feb 2000 23:22:26 +0000 Subject: Don't assume that the (files_struct *) passed to fd_attempt_close() will be non-NULL. --- source/smbd/open.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/source/smbd/open.c b/source/smbd/open.c index 30409707d30..6352233dbcf 100644 --- a/source/smbd/open.c +++ b/source/smbd/open.c @@ -152,11 +152,18 @@ Decrements the ref_count and returns it. uint16 fd_attempt_close(files_struct *fsp, int *err_ret) { extern struct current_user current_user; - file_fd_struct *fd_ptr = fsp->fd_ptr; - uint16 ret_ref = fd_ptr->ref_count; + file_fd_struct *fd_ptr; + uint16 ret_ref; *err_ret = 0; + if ((fsp == NULL) || (fsp->fd_ptr == NULL)) { + return 0; + } + + fd_ptr = fsp->fd_ptr; + ret_ref = fd_ptr->ref_count; + DEBUG(3,("fd_attempt_close fd = %d, dev = %x, inode = %.0f, open_flags = %d, ref_count = %d.\n", fd_ptr->fd, (unsigned int)fd_ptr->dev, (double)fd_ptr->inode, fd_ptr->real_open_flags, -- cgit From 0ec82d661a27a02322e5c8da20a18f33bfb24a3e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 18 Feb 2000 03:11:22 +0000 Subject: Fixes for Eastern Europe code page. Jeremy. --- source/codepages/codepage_def.852 | 1 + source/lib/charcnv.c | 1 + 2 files changed, 2 insertions(+) diff --git a/source/codepages/codepage_def.852 b/source/codepages/codepage_def.852 index ed1423428ca..76f6f7de4a6 100644 --- a/source/codepages/codepage_def.852 +++ b/source/codepages/codepage_def.852 @@ -61,3 +61,4 @@ 0xEE 0xDD True True 0xFB 0xEB True True 0xFD 0xFC True True + 0xFF 0xFF True True diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c index 8f91e4573af..2916f0cedab 100644 --- a/source/lib/charcnv.c +++ b/source/lib/charcnv.c @@ -108,6 +108,7 @@ static void init_iso8859_2(void) { */ /* MSDOS Code Page 852 -> ISO-8859-2 */ +update_map("\240\377"); /* Fix for non-breaking space */ update_map("\241\244\242\364\243\235\244\317\245\225\246\227\247\365"); update_map("\250\371\251\346\252\270\253\233\254\215\256\246\257\275"); update_map("\261\245\262\362\263\210\264\357\265\226\266\230\267\363"); -- cgit From 801ed2389b97f921aa855513696d304c542fda04 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 18 Feb 2000 03:54:26 +0000 Subject: Fix for reporting file system attributes correctly. Jeremy. --- source/include/smb.h | 15 +++++++++++---- source/smbd/trans2.c | 3 ++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/source/include/smb.h b/source/include/smb.h index 085325939fd..18b2cb15424 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -1247,10 +1247,17 @@ struct bitmap { #define RENAME_REPLACE_IF_EXISTS 1 /* Filesystem Attributes. */ -#define FILE_CASE_SENSITIVE_SEARCH 0x1 -#define FILE_CASE_PRESERVED_NAMES 0x2 -#define FILE_UNICODE_ON_DISK 0x4 -#define FILE_PERSISTENT_ACLS 0x8 +#define FILE_CASE_SENSITIVE_SEARCH 0x01 +#define FILE_CASE_PRESERVED_NAMES 0x02 +#define FILE_UNICODE_ON_DISK 0x04 +/* According to cifs9f, this is 4, not 8 */ +/* Acconding to testing, this actually sets the security attribute! */ +#define FILE_PERSISTENT_ACLS 0x08 +/* These entries added from cifs9f --tsb */ +#define FILE_FILE_COMPRESSION 0x08 +#define FILE_VOLUME_QUOTAS 0x10 +#define FILE_DEVICE_IS_MOUNTED 0x20 +#define FILE_VOLUME_IS_COMPRESSED 0x8000 /* ChangeNotify flags. */ #define FILE_NOTIFY_CHANGE_FILE_NAME 0x001 diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c index bd2237253e4..dff57a41c2a 100644 --- a/source/smbd/trans2.c +++ b/source/smbd/trans2.c @@ -1170,7 +1170,8 @@ static int call_trans2qfsinfo(connection_struct *conn, { int fstype_len; SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH| - lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0); /* FS ATTRIBUTES */ + FILE_DEVICE_IS_MOUNTED| + (lp_nt_acl_support() ? FILE_PERSISTENT_ACLS : 0)); /* FS ATTRIBUTES */ #if 0 /* Old code. JRA. */ SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */ #endif /* Old code. */ -- cgit From f9c20801114f72b587a6e8c3177cbab13dbdcc28 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Mon, 21 Feb 2000 01:58:13 +0000 Subject: more rewrite ... comitting before starting on new functions. J.F. --- source/include/proto.h | 71 +- source/include/rpc_spoolss.h | 100 ++- source/rpc_parse/parse_spoolss.c | 1309 ++++++++++++------------------------ source/rpc_server/srv_spoolss.c | 255 +++---- source/rpc_server/srv_spoolss_nt.c | 655 +++++++++++------- 5 files changed, 1055 insertions(+), 1335 deletions(-) diff --git a/source/include/proto.h b/source/include/proto.h index b7a08e60de9..ee0de29eb63 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -2336,6 +2336,7 @@ BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u, BOOL spoolss_io_r_rfnpcnex(char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth); +BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *info, int depth); BOOL new_smb_io_printer_info_1(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info, int depth); BOOL new_smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth); BOOL new_smb_io_printer_driver_info_1(char *desc, NEW_BUFFER *buffer, DRIVER_INFO_1 *info, int depth) ; @@ -2348,11 +2349,13 @@ void new_spoolss_move_buffer(NEW_BUFFER *src, NEW_BUFFER **dest); void new_spoolss_allocate_buffer(NEW_BUFFER **buffer); void new_spoolss_free_buffer(NEW_BUFFER *buffer); uint32 new_get_buffer_size(NEW_BUFFER *buffer); +BOOL new_smb_io_driverdir_1(char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth); BOOL new_smb_io_port_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth); BOOL new_smb_io_port_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth); BOOL smb_io_printprocessor_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth); BOOL smb_io_printmonitor_info_1(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_1 *info, int depth); BOOL smb_io_printmonitor_info_2(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *info, int depth); +uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info); uint32 spoolss_size_printer_info_1(PRINTER_INFO_1 *info); uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info); uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info); @@ -2362,33 +2365,26 @@ uint32 spoolss_size_job_info_1(JOB_INFO_1 *info); uint32 spoolss_size_job_info_2(JOB_INFO_2 *info); uint32 spoolss_size_form_1(FORM_1 *info); uint32 spoolss_size_port_info_1(PORT_INFO_1 *info); +uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info); uint32 spoolss_size_port_info_2(PORT_INFO_2 *info); uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info); uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info); uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info); -BOOL spoolss_io_free_buffer(BUFFER *buffer); -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 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, const char* servername, uint32 level, uint32 size); -BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, - prs_struct *ps, int depth); +BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth); 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_r_getprinter(char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth); BOOL make_spoolss_q_getprinter(SPOOL_Q_GETPRINTER *q_u, POLICY_HND *hnd, uint32 level, uint32 buf_size); -BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, - prs_struct *ps, int depth); +BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth); 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); @@ -2427,8 +2423,8 @@ BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni, NT_PRINTER_DRIVER_INFO_LEVEL_3 **asc); BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni, NT_PRINTER_INFO_LEVEL_2 **asc); -BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth); BOOL spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth); BOOL spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth); @@ -2444,7 +2440,6 @@ BOOL spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int BOOL spoolss_io_q_setform(char *desc, SPOOL_Q_SETFORM *q_u, prs_struct *ps, int depth); BOOL spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int depth); BOOL spoolss_io_r_getjob(char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth); -void free_spoolss_r_getjob(SPOOL_R_GETJOB *r_u); BOOL spoolss_io_q_getjob(char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth); void free_devmode(DEVICEMODE *devmode); void free_printer_info_2(PRINTER_INFO_2 *printer); @@ -2639,17 +2634,11 @@ uint32 _spoolss_rfnpcnex( const POLICY_HND *handle, uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 level, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned); -uint32 _spoolss_getprinter( POLICY_HND *handle, - uint32 level, - PRINTER_INFO *ctr, - uint32 *offered, - uint32 *needed); -uint32 _spoolss_getprinterdriver2( const POLICY_HND *handle, - const UNISTR2 *uni_arch, - uint32 level, - DRIVER_INFO *ctr, - uint32 *offered, - uint32 *needed); +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, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *unknown0, uint32 *unknown1); uint32 _spoolss_startpageprinter(const POLICY_HND *handle); uint32 _spoolss_endpageprinter(const POLICY_HND *handle); uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level, @@ -2668,8 +2657,7 @@ uint32 _spoolss_setprinter( const POLICY_HND *handle, uint32 command); uint32 _spoolss_fcpn( const POLICY_HND *handle); uint32 _spoolss_addjob( const POLICY_HND *handle, uint32 level, - const BUFFER *buffer, - uint32 buf_size); + NEW_BUFFER *buffer, uint32 offered); uint32 _spoolss_enumjobs( POLICY_HND *handle, uint32 firstjob, uint32 numofjobs, uint32 level, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned); @@ -2688,24 +2676,17 @@ uint32 _new_spoolss_enumforms( const POLICY_HND *handle, uint32 level, uint32 _spoolss_enumports( UNISTR2 *name, uint32 level, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned); -uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_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_level, - const SPOOL_USER_LEVEL *user, + uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3, + uint32 user_switch, const SPOOL_USER_CTR *user, POLICY_HND *handle); uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name, uint32 level, const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info); -uint32 _spoolss_getprinterdriverdirectory( const UNISTR2 *name, - const UNISTR2 *uni_environment, - uint32 level, - DRIVER_DIRECTORY_CTR *ctr, - uint32 *offered); +uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environment, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed); uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 idx, uint32 *valuesize, @@ -2735,11 +2716,9 @@ uint32 _spoolss_enumprintprocessors(UNISTR2 *name, UNISTR2 *environment, uint32 uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned); -uint32 _spoolss_getjob( const POLICY_HND *handle, - uint32 jobid, - uint32 level, - PJOB_INFO *ctr, - uint32 *offered); +uint32 _spoolss_getjob( POLICY_HND *handle, uint32 jobid, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed); /*The following definitions come from rpc_server/srv_srvsvc.c */ diff --git a/source/include/rpc_spoolss.h b/source/include/rpc_spoolss.h index fc8fd041d68..1556c56686b 100755 --- a/source/include/rpc_spoolss.h +++ b/source/include/rpc_spoolss.h @@ -381,7 +381,7 @@ typedef struct spool_q_open_printer_ex SPOOL_USER_CTR user_ctr; } SPOOL_Q_OPEN_PRINTER_EX; -/* SPOOL_Q_OPEN_PRINTER_EX reply to an open printer */ +/* SPOOL_R_OPEN_PRINTER_EX reply to an open printer */ typedef struct spool_r_open_printer_ex { POLICY_HND handle; /* handle used along all transactions (20*uint8) */ @@ -410,7 +410,7 @@ typedef struct s_header_type } data; } HEADER_TYPE; -typedef struct s_buffer +/*typedef struct s_buffer { uint32 ptr; uint32 size; @@ -418,7 +418,7 @@ typedef struct s_buffer uint8 *data; HEADER_TYPE *header; } BUFFER; - +*/ typedef struct new_buffer { uint32 ptr; @@ -716,9 +716,8 @@ typedef struct spool_q_getprinter { POLICY_HND handle; uint32 level; - uint8* buffer; + NEW_BUFFER *buffer; uint32 offered; - } SPOOL_Q_GETPRINTER; typedef struct printer_info_info @@ -729,17 +728,11 @@ typedef struct printer_info_info PRINTER_INFO_2 *info2; void *info; } printer; - } PRINTER_INFO; typedef struct spool_r_getprinter { - POLICY_HND handle; - uint32 level; - - PRINTER_INFO ctr; - - uint32 offered; + NEW_BUFFER *buffer; uint32 needed; uint32 status; @@ -754,17 +747,6 @@ struct s_notify_info_data_table void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer); }; -typedef struct spool_q_getprinterdriver2 -{ - POLICY_HND handle; - UNISTR2 architecture; - uint32 level; - BUFFER buffer; - uint32 buf_size; - uint32 unknown; - -} SPOOL_Q_GETPRINTERDRIVER2; - typedef struct driver_info_1 { UNISTR name; @@ -804,17 +786,27 @@ typedef struct driver_info_info } DRIVER_INFO; -typedef struct spool_r_getprinterdriver2 +typedef struct spool_q_getprinterdriver2 { + POLICY_HND handle; + uint32 architecture_ptr; + UNISTR2 architecture; uint32 level; - DRIVER_INFO ctr; - uint32 needed; + NEW_BUFFER *buffer; uint32 offered; - uint32 returned; - uint32 status; + uint32 unknown; +} SPOOL_Q_GETPRINTERDRIVER2; +typedef struct spool_r_getprinterdriver2 +{ + NEW_BUFFER *buffer; + uint32 needed; + uint32 unknown0; + uint32 unknown1; + uint32 status; } SPOOL_R_GETPRINTERDRIVER2; + typedef struct add_jobinfo_1 { UNISTR path; @@ -826,8 +818,8 @@ typedef struct spool_q_addjob { POLICY_HND handle; uint32 level; - BUFFER buffer; - uint32 buf_size; + NEW_BUFFER *buffer; + uint32 offered; } SPOOL_Q_ADDJOB; typedef struct spool_r_addjob @@ -1125,6 +1117,8 @@ typedef struct spool_printer_driver_info_level_3 typedef struct spool_printer_driver_info_level { + uint32 level; + uint32 ptr; SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *info_3; } SPOOL_PRINTER_DRIVER_INFO_LEVEL; @@ -1191,8 +1185,10 @@ typedef struct spool_r_addprinter uint32 status; } SPOOL_R_ADDPRINTER; + typedef struct spool_q_addprinterex { + uint32 server_name_ptr; UNISTR2 server_name; uint32 level; SPOOL_PRINTER_INFO_LEVEL info; @@ -1200,19 +1196,20 @@ typedef struct spool_q_addprinterex uint32 unk1; uint32 unk2; uint32 unk3; - uint32 user_level; - SPOOL_USER_LEVEL user; + uint32 user_switch; + SPOOL_USER_CTR user_ctr; } SPOOL_Q_ADDPRINTEREX; - typedef struct spool_r_addprinterex { POLICY_HND handle; uint32 status; } SPOOL_R_ADDPRINTEREX; + typedef struct spool_q_addprinterdriver { + uint32 server_name_ptr; UNISTR2 server_name; uint32 level; SPOOL_PRINTER_DRIVER_INFO_LEVEL info; @@ -1223,19 +1220,10 @@ typedef struct spool_r_addprinterdriver uint32 status; } SPOOL_R_ADDPRINTERDRIVER; -typedef struct spool_q_getprinterdriverdirectory -{ - UNISTR2 name; - UNISTR2 environment; - uint32 level; - BUFFER buffer; - uint32 buf_size; -} SPOOL_Q_GETPRINTERDRIVERDIR; typedef struct driver_directory_1 { UNISTR name; - } DRIVER_DIRECTORY_1 ; typedef struct driver_info_ctr_info @@ -1243,16 +1231,24 @@ typedef struct driver_info_ctr_info union { DRIVER_DIRECTORY_1 info_1; } driver; - } DRIVER_DIRECTORY_CTR; -typedef struct spool_r_getprinterdriverdirectory +typedef struct spool_q_getprinterdriverdirectory { + uint32 name_ptr; + UNISTR2 name; + uint32 environment_ptr; + UNISTR2 environment; uint32 level; - DRIVER_DIRECTORY_CTR ctr; + NEW_BUFFER *buffer; uint32 offered; - uint32 status; +} SPOOL_Q_GETPRINTERDRIVERDIR; +typedef struct spool_r_getprinterdriverdirectory +{ + NEW_BUFFER *buffer; + uint32 needed; + uint32 status; } SPOOL_R_GETPRINTERDRIVERDIR; typedef struct spool_q_enumprintprocessors @@ -1284,7 +1280,7 @@ typedef struct spool_q_enumprintprocessordatatypes UNISTR2 name; UNISTR2 printprocessor; uint32 level; - BUFFER buffer; + NEW_BUFFER *buffer; uint32 buf_size; } SPOOL_Q_ENUMPRINTPROCESSORDATATYPES; @@ -1413,9 +1409,8 @@ typedef struct spool_q_getjob POLICY_HND handle; uint32 jobid; uint32 level; - BUFFER buffer; - uint32 buf_size; - + NEW_BUFFER *buffer; + uint32 offered; } SPOOL_Q_GETJOB; typedef struct pjob_info_info @@ -1430,9 +1425,8 @@ typedef struct pjob_info_info typedef struct spool_r_getjob { - uint32 level; - PJOB_INFO ctr; - uint32 offered; + NEW_BUFFER *buffer; + uint32 needed; uint32 status; } SPOOL_R_GETJOB; diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c index 66fa2f1da5a..796466337f8 100644 --- a/source/rpc_parse/parse_spoolss.c +++ b/source/rpc_parse/parse_spoolss.c @@ -675,21 +675,20 @@ BOOL spoolss_io_q_open_printer_ex(char *desc, SPOOL_Q_OPEN_PRINTER_EX *q_u, prs_ if (!prs_align(ps)) return False; - if (!prs_uint32("printername_ptr", ps, depth, &(q_u->printername_ptr))) + if (!prs_uint32("printername_ptr", ps, depth, &q_u->printername_ptr)) return False; - if (!smb_io_unistr2("", &(q_u->printername), q_u->printername_ptr, ps,depth)) + if (!smb_io_unistr2("", &q_u->printername, q_u->printername_ptr, ps,depth)) return False; if (!prs_align(ps)) return False; - if (!spoolss_io_printer_default("", &(q_u->printer_default), ps, depth)) + if (!spoolss_io_printer_default("", &q_u->printer_default, ps, depth)) return False; - if (!prs_uint32("user_switch", ps, depth, &(q_u->user_switch))) - return False; - - if (!spool_io_user_level("", &(q_u->user_ctr), ps, depth)) + if (!prs_uint32("user_switch", ps, depth, &q_u->user_switch)) + return False; + if (!spool_io_user_level("", &q_u->user_ctr, ps, depth)) return False; return True; @@ -1116,8 +1115,6 @@ BOOL spoolss_io_r_rfnpcnex(char *desc, static uint32 size_of_uint32(uint32 *value) { return (sizeof(*value)); - - return True; } /******************************************************************* @@ -1133,9 +1130,8 @@ static uint32 size_of_relative_string(UNISTR *string) size=size+1; /* add the leading zero */ size=size*2; /* convert in char */ size=size+4; /* add the size of the ptr */ - return (size); - return True; + return size; } /******************************************************************* @@ -1147,8 +1143,6 @@ static uint32 size_of_device_mode(DEVICEMODE *devmode) return (4); else return (0xDC+4); - - return True; } /******************************************************************* @@ -1160,8 +1154,6 @@ static uint32 size_of_systemtime(SYSTEMTIME *systime) return (4); else return (sizeof(SYSTEMTIME) +4); - - return True; } /******************************************************************* @@ -1177,8 +1169,6 @@ static BOOL spoolss_smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth++; if (!prs_unistr("unistr", ps, depth, uni)) return False; - - return True; } @@ -1457,45 +1447,79 @@ static BOOL smb_io_reldevmode(char *desc, prs_struct *ps, int depth, DEVICEMODE } /******************************************************************* + Parse a PRINTER_INFO_0 structure. ********************************************************************/ -static BOOL smb_io_printer_info_0(char *desc, PRINTER_INFO_0 *info, prs_struct *ps, int depth, - uint32 *start_offset, uint32 *end_offset) +BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *info, int depth) { + prs_struct *ps=&(buffer->prs); + prs_debug(ps, depth, desc, "smb_io_printer_info_0"); depth++; - *start_offset=prs_offset(ps); - smb_io_relstr("printername",ps, depth, &(info->printername), start_offset, end_offset); - smb_io_relstr("servername",ps, depth, &(info->servername), start_offset, end_offset); - prs_uint32("cjobs", ps, depth, &(info->cjobs)); - prs_uint32("attributes", ps, depth, &(info->attributes)); - - prs_uint32("unknown0", ps, depth, &(info->unknown0)); - prs_uint32("unknown1", ps, depth, &(info->unknown1)); - prs_uint32("unknown2", ps, depth, &(info->unknown2)); - prs_uint32("unknown3", ps, depth, &(info->unknown3)); - prs_uint32("unknown4", ps, depth, &(info->unknown4)); - prs_uint32("unknown5", ps, depth, &(info->unknown5)); - prs_uint32("unknown6", ps, depth, &(info->unknown6)); - prs_uint16("majorversion", ps, depth, &(info->majorversion)); - prs_uint16("buildversion", ps, depth, &(info->buildversion)); - prs_uint32("unknown7", ps, depth, &(info->unknown7)); - prs_uint32("unknown8", ps, depth, &(info->unknown8)); - prs_uint32("unknown9", ps, depth, &(info->unknown9)); - prs_uint32("unknown10", ps, depth, &(info->unknown10)); - prs_uint32("unknown11", ps, depth, &(info->unknown11)); - prs_uint32("unknown12", ps, depth, &(info->unknown12)); - prs_uint32("unknown13", ps, depth, &(info->unknown13)); - prs_uint32("unknown14", ps, depth, &(info->unknown14)); - prs_uint32("unknown15", ps, depth, &(info->unknown15)); - prs_uint32("unknown16", ps, depth, &(info->unknown16)); - prs_uint32("unknown17", ps, depth, &(info->unknown17)); - prs_uint32("unknown18", ps, depth, &(info->unknown18)); - prs_uint32("status" , ps, depth, &(info->status)); - prs_uint32("unknown20", ps, depth, &(info->unknown20)); - prs_uint32("unknown21", ps, depth, &(info->unknown21)); - prs_uint16("unknown22", ps, depth, &(info->unknown22)); - prs_uint32("unknown23", ps, depth, &(info->unknown23)); + buffer->struct_start=prs_offset(ps); + + if (!new_smb_io_relstr("printername", buffer, depth, &info->printername)) + return False; + if (!new_smb_io_relstr("servername", buffer, depth, &info->servername)) + return False; + + if(!prs_uint32("cjobs", ps, depth, &info->cjobs)) + return False; + if(!prs_uint32("attributes", ps, depth, &info->attributes)) + return False; + + if(!prs_uint32("unknown0", ps, depth, &info->unknown0)) + return False; + if(!prs_uint32("unknown1", ps, depth, &info->unknown1)) + return False; + if(!prs_uint32("unknown2", ps, depth, &info->unknown2)) + return False; + if(!prs_uint32("unknown3", ps, depth, &info->unknown3)) + return False; + if(!prs_uint32("unknown4", ps, depth, &info->unknown4)) + return False; + if(!prs_uint32("unknown5", ps, depth, &info->unknown5)) + return False; + if(!prs_uint32("unknown6", ps, depth, &info->unknown6)) + return False; + if(!prs_uint16("majorversion", ps, depth, &info->majorversion)) + return False; + if(!prs_uint16("buildversion", ps, depth, &info->buildversion)) + return False; + if(!prs_uint32("unknown7", ps, depth, &info->unknown7)) + return False; + if(!prs_uint32("unknown8", ps, depth, &info->unknown8)) + return False; + if(!prs_uint32("unknown9", ps, depth, &info->unknown9)) + return False; + if(!prs_uint32("unknown10", ps, depth, &info->unknown10)) + return False; + if(!prs_uint32("unknown11", ps, depth, &info->unknown11)) + return False; + if(!prs_uint32("unknown12", ps, depth, &info->unknown12)) + return False; + if(!prs_uint32("unknown13", ps, depth, &info->unknown13)) + return False; + if(!prs_uint32("unknown14", ps, depth, &info->unknown14)) + return False; + if(!prs_uint32("unknown15", ps, depth, &info->unknown15)) + return False; + if(!prs_uint32("unknown16", ps, depth, &info->unknown16)) + return False; + if(!prs_uint32("unknown17", ps, depth, &info->unknown17)) + return False; + if(!prs_uint32("unknown18", ps, depth, &info->unknown18)) + return False; + if(!prs_uint32("status" , ps, depth, &info->status)) + return False; + if(!prs_uint32("unknown20", ps, depth, &info->unknown20)) + return False; + if(!prs_uint32("unknown21", ps, depth, &info->unknown21)) + return False; + if(!prs_uint16("unknown22", ps, depth, &info->unknown22)) + return False; + if(!prs_uint32("unknown23", ps, depth, &info->unknown23)) + return False; return True; } @@ -1767,30 +1791,6 @@ BOOL new_smb_io_job_info_1(char *desc, NEW_BUFFER *buffer, JOB_INFO_1 *info, int return True; } -static BOOL smb_io_job_info_1(char *desc, JOB_INFO_1 *info, prs_struct *ps, int depth, - uint32 *start_offset, uint32 *end_offset) -{ - prs_debug(ps, depth, desc, "smb_io_job_info_1"); - depth++; - *start_offset=prs_offset(ps); - - prs_uint32("jobid", ps, depth, &(info->jobid)); - smb_io_relstr("printername", ps, depth, &(info->printername), start_offset, end_offset); - smb_io_relstr("machinename", ps, depth, &(info->machinename), start_offset, end_offset); - smb_io_relstr("username", ps, depth, &(info->username), start_offset, end_offset); - smb_io_relstr("document", ps, depth, &(info->document), start_offset, end_offset); - smb_io_relstr("datatype", ps, depth, &(info->datatype), start_offset, end_offset); - smb_io_relstr("text_status", ps, depth, &(info->text_status), start_offset, end_offset); - prs_uint32("status", ps, depth, &(info->status)); - prs_uint32("priority", ps, depth, &(info->priority)); - prs_uint32("position", ps, depth, &(info->position)); - prs_uint32("totalpages", ps, depth, &(info->totalpages)); - prs_uint32("pagesprinted", ps, depth, &(info->pagesprinted)); - spoolss_io_system_time("submitted", ps, depth, &(info->submitted) ); - - return True; -} - /******************************************************************* Parse a JOB_INFO_2 structure. ********************************************************************/ @@ -1857,44 +1857,6 @@ BOOL new_smb_io_job_info_2(char *desc, NEW_BUFFER *buffer, JOB_INFO_2 *info, int return True; } -static BOOL smb_io_job_info_2(char *desc, JOB_INFO_2 *info, prs_struct *ps, int depth, - uint32 *start_offset, uint32 *end_offset) -{ - int pipo=0; - prs_debug(ps, depth, desc, "smb_io_job_info_2"); - depth++; - *start_offset=prs_offset(ps); - - prs_uint32("jobid", ps, depth, &(info->jobid)); - smb_io_relstr("printername", ps, depth, &(info->printername), start_offset, end_offset); - smb_io_relstr("machinename", ps, depth, &(info->machinename), start_offset, end_offset); - smb_io_relstr("username", ps, depth, &(info->username), start_offset, end_offset); - smb_io_relstr("document", ps, depth, &(info->document), start_offset, end_offset); - smb_io_relstr("notifyname", ps, depth, &(info->notifyname), start_offset, end_offset); - smb_io_relstr("datatype", ps, depth, &(info->datatype), start_offset, end_offset); - - smb_io_relstr("printprocessor", ps, depth, &(info->printprocessor), start_offset, end_offset); - smb_io_relstr("parameters", ps, depth, &(info->parameters), start_offset, end_offset); - smb_io_relstr("drivername", ps, depth, &(info->drivername), start_offset, end_offset); - smb_io_reldevmode("devmode", ps, depth, info->devmode, start_offset, end_offset); - smb_io_relstr("text_status", ps, depth, &(info->text_status), start_offset, end_offset); - -/* SEC_DESC sec_desc;*/ - prs_uint32("Hack! sec desc", ps, depth, &pipo); - - prs_uint32("status", ps, depth, &(info->status)); - prs_uint32("priority", ps, depth, &(info->priority)); - prs_uint32("position", ps, depth, &(info->position)); - prs_uint32("starttime", ps, depth, &(info->starttime)); - prs_uint32("untiltime", ps, depth, &(info->untiltime)); - prs_uint32("totalpages", ps, depth, &(info->totalpages)); - prs_uint32("size", ps, depth, &(info->size)); - spoolss_io_system_time("submitted", ps, depth, &(info->submitted) ); - prs_uint32("timeelapsed", ps, depth, &(info->timeelapsed)); - prs_uint32("pagesprinted", ps, depth, &(info->pagesprinted)); - - return True; -} /******************************************************************* ********************************************************************/ @@ -2056,8 +2018,27 @@ static BOOL smb_io_form_1(char *desc, FORM_1 *info, prs_struct *ps, int depth, return True; } + /******************************************************************* - Parse a PORT_INFO_2 structure. + Parse a DRIVER_DIRECTORY_1 structure. +********************************************************************/ +BOOL new_smb_io_driverdir_1(char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info, int depth) +{ + prs_struct *ps=&(buffer->prs); + + prs_debug(ps, depth, desc, "new_smb_io_driverdir_1"); + depth++; + + buffer->struct_start=prs_offset(ps); + + if(!new_smb_io_relstr("name", buffer, depth, &info->name)) + return False; + + return True; +} + +/******************************************************************* + Parse a PORT_INFO_1 structure. ********************************************************************/ BOOL new_smb_io_port_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth) { @@ -2174,16 +2155,18 @@ BOOL smb_io_printmonitor_info_2(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 * /******************************************************************* return the size required by a struct in the stream ********************************************************************/ -static uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info) +uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info) { int size=0; - + + size+=24*4; + size+=6; + size+=size_of_uint32( &(info->attributes) ); size+=size_of_relative_string( &(info->printername) ); size+=size_of_relative_string( &(info->servername) ); - return (size); - return True; + return size; } /******************************************************************* @@ -2242,13 +2225,9 @@ return the size required by a struct in the stream uint32 spoolss_size_printer_driver_info_1(DRIVER_INFO_1 *info) { int size=0; - DEBUG(9,("Sizing driver info_1\n")); size+=size_of_relative_string( &(info->name) ); - DEBUGADD(9,("size: [%d]\n", size)); - return (size); - - return True; + return size; } /******************************************************************* @@ -2257,7 +2236,6 @@ return the size required by a struct in the stream uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info) { int size=0; - DEBUG(9,("Sizing driver info_2\n")); size+=size_of_uint32( &(info->version) ); size+=size_of_relative_string( &(info->name) ); size+=size_of_relative_string( &(info->architecture) ); @@ -2265,10 +2243,7 @@ uint32 spoolss_size_printer_driver_info_2(DRIVER_INFO_2 *info) size+=size_of_relative_string( &(info->datafile) ); size+=size_of_relative_string( &(info->configfile) ); - DEBUGADD(9,("size: [%d]\n", size)); - return (size); - - return True; + return size; } /******************************************************************* @@ -2280,7 +2255,6 @@ uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info) UNISTR **string; int i=0; - DEBUG(9,("Sizing driver info_3\n")); size+=size_of_uint32( &(info->version) ); size+=size_of_relative_string( &(info->name) ); size+=size_of_relative_string( &(info->architecture) ); @@ -2300,10 +2274,7 @@ uint32 spoolss_size_printer_driver_info_3(DRIVER_INFO_3 *info) } size+=6; - DEBUGADD(9,("size: [%d]\n", size)); - return (size); - - return True; + return size; } /******************************************************************* @@ -2361,9 +2332,8 @@ uint32 spoolss_size_job_info_2(JOB_INFO_2 *info) size+=size_of_systemtime( &(info->submitted) ); size+=size_of_uint32( &(info->timeelapsed) ); size+=size_of_uint32( &(info->pagesprinted) ); - return (size); - return True; + return size; } /******************************************************************* @@ -2392,7 +2362,19 @@ uint32 spoolss_size_port_info_1(PORT_INFO_1 *info) { int size=0; - size+=size_of_relative_string( &(info->port_name) ); + size+=size_of_relative_string( &info->port_name ); + + return size; +} + +/******************************************************************* +return the size required by a struct in the stream +********************************************************************/ +uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info) +{ + int size=0; + + size+=size_of_relative_string( &info->name ); return size; } @@ -2404,12 +2386,12 @@ uint32 spoolss_size_port_info_2(PORT_INFO_2 *info) { int size=0; - size+=size_of_relative_string( &(info->port_name) ); - size+=size_of_relative_string( &(info->monitor_name) ); - size+=size_of_relative_string( &(info->description) ); + size+=size_of_relative_string( &info->port_name ); + size+=size_of_relative_string( &info->monitor_name ); + size+=size_of_relative_string( &info->description ); - size+=size_of_uint32( &(info->port_type) ); - size+=size_of_uint32( &(info->reserved) ); + size+=size_of_uint32( &info->port_type ); + size+=size_of_uint32( &info->reserved ); return size; } @@ -2434,7 +2416,6 @@ uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info) size+=size_of_relative_string( &info->name ); return size; - } /******************************************************************* @@ -2450,123 +2431,41 @@ uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info) return size; } -/******************************************************************* - * make a structure. - ********************************************************************/ -/* -static BOOL make_spoolss_buffer(BUFFER* buffer, uint32 size) -{ - buffer->ptr = (size != 0) ? 1 : 0; - buffer->size = size; - buffer->data = (uint8 *)Realloc( NULL, (buffer->size) * sizeof(uint8) ); - - return (buffer->data != NULL || size == 0); -} -*/ - -/******************************************************************* - * read a uint8 buffer of size *size. - * allocate memory for it - * return a pointer to the allocated memory and the size - * return NULL and a size of 0 if the buffer is empty - * - * jfmxxxx: fix it to also write a buffer - ********************************************************************/ -static BOOL spoolss_io_read_buffer(char *desc, prs_struct *ps, int depth, BUFFER *buffer) -{ - prs_debug(ps, depth, desc, "spoolss_io_read_buffer"); - depth++; - - prs_align(ps); - - prs_uint32("pointer", ps, depth, &(buffer->ptr)); - - if (buffer->ptr != 0x0000) - { - prs_uint32("size", ps, depth, &(buffer->size)); - if (ps->io) - { - /* reading */ - buffer->data=(uint8 *)Realloc(NULL, buffer->size * sizeof(uint8) ); - } - if (buffer->data == NULL) - { - return False; - } - prs_uint8s(True, "buffer", ps, depth, buffer->data, buffer->size); - prs_align(ps); - - } - else - { - if (ps->io) - { - /* reading */ - buffer->data=0x0000; - buffer->size=0x0000; - } - } - - if (!ps->io) - { - /* writing */ - if (buffer->data != NULL) - { - free(buffer->data); - } - buffer->data = NULL; - } - return True; -} - -/******************************************************************* - * read a uint8 buffer of size *size. - * allocate memory for it - * return a pointer to the allocated memory and the size - * return NULL and a size of 0 if the buffer is empty - * - * jfmxxxx: fix it to also write a buffer - ********************************************************************/ -BOOL spoolss_io_free_buffer(BUFFER *buffer) -{ - DEBUG(8,("spoolss_io_free_buffer\n")); - - if (buffer->ptr != 0x0000) - { - free(buffer->data); - } - - return True; -} - /******************************************************************* * read a structure. * called from spoolss_getprinterdriver2 (srv_spoolss.c) ********************************************************************/ -BOOL spoolss_io_q_getprinterdriver2(char *desc, - SPOOL_Q_GETPRINTERDRIVER2 *q_u, - prs_struct *ps, int depth) +BOOL spoolss_io_q_getprinterdriver2(char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth) { - uint32 useless_ptr; prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriver2"); depth++; - prs_align(ps); - - smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); - prs_uint32("pointer", ps, depth, &useless_ptr); - smb_io_unistr2("architecture", &(q_u->architecture),True,ps,depth); + if(!prs_align(ps)) + return False; - prs_align(ps); + if(!smb_io_prt_hnd("printer handle", &q_u->handle, ps, depth)) + return False; + if(!prs_uint32("architecture_ptr", ps, depth, &q_u->architecture_ptr)) + return False; + if(!smb_io_unistr2("architecture", &q_u->architecture, q_u->architecture_ptr, ps, depth)) + return False; - prs_uint32("level", ps, depth, &(q_u->level)); - spoolss_io_read_buffer("", ps, depth, &(q_u->buffer)); + if(!prs_align(ps)) + return False; + if(!prs_uint32("level", ps, depth, &q_u->level)) + return False; + + if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer)) + return False; - prs_align(ps); + if(!prs_align(ps)) + return False; - prs_uint32("buffer size", ps, depth, &(q_u->buf_size)); - DEBUG(0,("spoolss_io_q_getprinterdriver2: renamed status - unknown\n")); - prs_uint32("unknown", ps, depth, &(q_u->unknown)); + if(!prs_uint32("offered", ps, depth, &q_u->offered)) + return False; + + if(!prs_uint32("unknown", ps, depth, &q_u->unknown)) + return False; return True; } @@ -2575,164 +2474,44 @@ BOOL spoolss_io_q_getprinterdriver2(char *desc, * read a structure. * called from spoolss_getprinterdriver2 (srv_spoolss.c) ********************************************************************/ -BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, - prs_struct *ps, int depth) +BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, prs_struct *ps, int depth) { - uint32 useless_ptr=0xADDE0FF0; - uint32 start_offset, end_offset, beginning; - uint32 bufsize_required=0; - uint32 pipo=0; - DRIVER_INFO_1 *info1; - DRIVER_INFO_2 *info2; - DRIVER_INFO_3 *info3; - prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriver2"); depth++; - prs_align(ps); - prs_uint32("pointer", ps, depth, &useless_ptr); - - info1 = r_u->ctr.driver.info1; - info2 = r_u->ctr.driver.info2; - info3 = r_u->ctr.driver.info3; - - switch (r_u->level) - { - case 1: - { - bufsize_required += spoolss_size_printer_driver_info_1(info1); - break; - } - case 2: - { - bufsize_required += spoolss_size_printer_driver_info_2(info2); - break; - } - case 3: - { - bufsize_required += spoolss_size_printer_driver_info_3(info3); - break; - } - } - - if (ps->io) - { - /* reading */ - r_u->offered = bufsize_required; - } - - DEBUG(4,("spoolss_io_r_getprinterdriver2, size needed: %d\n",bufsize_required)); - DEBUG(4,("spoolss_io_r_getprinterdriver2, size offered: %d\n",r_u->offered)); - - /* check if the buffer is big enough for the datas */ - if (r_u->offered < bufsize_required) - { - /* it's too small */ - r_u->status=ERROR_INSUFFICIENT_BUFFER; /* say so */ - r_u->offered=0; /* don't send back the buffer */ + if (!prs_align(ps)) + return False; - DEBUG(4,("spoolss_io_r_getprinterdriver2, buffer too small\n")); + if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer)) + return False; - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - } - else - { - DEBUG(4,("spoolss_io_r_getprinterdriver2, buffer large enough\n")); - - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); + if (!prs_align(ps)) + return False; + if (!prs_uint32("needed", ps, depth, &r_u->needed)) + return False; + if (!prs_uint32("unknown0", ps, depth, &r_u->unknown0)) + return False; + if (!prs_uint32("unknown1", ps, depth, &r_u->unknown1)) + return False; + if (!prs_uint32("status", ps, depth, &r_u->status)) + return False; - beginning=prs_offset(ps); - start_offset=prs_offset(ps); - end_offset=start_offset+r_u->offered; - - switch (r_u->level) - { - case 1: - { - smb_io_printer_driver_info_1(desc, - info1, - ps, - depth, - &start_offset, - &end_offset); - break; - } - case 2: - { - smb_io_printer_driver_info_2(desc, - info2, - ps, - depth, - &start_offset, - &end_offset); - break; - } - case 3: - { - smb_io_printer_driver_info_3(desc, - info3, - ps, - depth, - &start_offset, - &end_offset); - break; - } - - } - - prs_set_offset(ps, beginning+r_u->offered); - prs_align(ps); - } - - if (!ps->io) + return True; +} + +/* + UNISTR **dependentfiles; + int j=0; + dependentfiles=info3->dependentfiles; + while ( dependentfiles[j] != NULL ) { - /* writing */ - switch (r_u->level) - { - case 1: - { - safe_free(info1); - break; - } - case 2: - { - safe_free(info2); - break; - } - case 3: - { - if (info3!=NULL) - { - UNISTR **dependentfiles; - int j=0; - dependentfiles=info3->dependentfiles; - while ( dependentfiles[j] != NULL ) - { - free(dependentfiles[j]); - j++; - } - free(dependentfiles); - - free(info3); - } - break; - } - - } + free(dependentfiles[j]); + j++; } + free(dependentfiles); - /* - * if the buffer was too small, send the minimum required size - * if it was too large, send the real needed size - */ - - prs_uint32("size of buffer needed", ps, depth, &(bufsize_required)); - prs_uint32("pipo", ps, depth, &pipo); - prs_uint32("pipo", ps, depth, &pipo); - prs_uint32("status", ps, depth, &(r_u->status)); - - return True; -} + free(info3); +*/ /******************************************************************* * make a structure. @@ -2762,8 +2541,7 @@ BOOL make_spoolss_q_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u, * read a structure. * called from spoolss_enumprinters (srv_spoolss.c) ********************************************************************/ -BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, - prs_struct *ps, int depth) +BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth) { prs_debug(ps, depth, desc, "spoolss_io_q_enumprinters"); depth++; @@ -2829,175 +2607,27 @@ BOOL new_spoolss_io_r_enumprinters(char *desc, SPOOL_R_ENUMPRINTERS *r_u, prs_st * called from spoolss_r_enum_printers (srv_spoolss.c) * ********************************************************************/ -BOOL spoolss_io_r_getprinter(char *desc, - SPOOL_R_GETPRINTER *r_u, - prs_struct *ps, int depth) +BOOL spoolss_io_r_getprinter(char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps, int depth) { - uint32 useless_ptr=0xADDE0FF0; - uint32 start_offset, end_offset, beginning; - uint32 bufsize_required=0; - prs_debug(ps, depth, desc, "spoolss_io_r_getprinter"); depth++; - prs_align(ps); - - prs_uint32("pointer", ps, depth, &useless_ptr); - - switch (r_u->level) - { - case 0: - { - PRINTER_INFO_0 *info; - info = r_u->ctr.printer.info0; - bufsize_required += spoolss_size_printer_info_0(info); - break; - } - case 1: - { - PRINTER_INFO_1 *info; - info = r_u->ctr.printer.info1; - bufsize_required += spoolss_size_printer_info_1(info); - break; - } - case 2: - { - PRINTER_INFO_2 *info; - info = r_u->ctr.printer.info2; - bufsize_required += spoolss_size_printer_info_2(info); - break; - } - } - - DEBUG(4,("spoolss_io_r_getprinter, size needed: %d\n",bufsize_required)); - DEBUG(4,("spoolss_io_r_getprinter, size offered: %d\n",r_u->offered)); - - /* check if the buffer is big enough for the datas */ - if (r_u->offered < bufsize_required) - { - /* it's too small */ - r_u->status = ERROR_INSUFFICIENT_BUFFER; /* say so */ - r_u->offered = 0; /* don't send back the buffer */ + if (!prs_align(ps)) + return False; - DEBUG(4,("spoolss_io_r_getprinter, buffer too small\n")); - - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - } - else - { - DEBUG(4,("spoolss_io_r_getprinter, buffer large enough\n")); - - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - } - - if (ps->io) - { - /* reading */ - r_u->ctr.printer.info = Realloc(NULL, r_u->offered); - } + if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer)) + return False; - if (bufsize_required <= r_u->offered) - { - beginning=prs_offset(ps); - start_offset=prs_offset(ps); - end_offset=start_offset+r_u->offered; - - switch (r_u->level) - { - case 0: - { - PRINTER_INFO_0 *info; - info = r_u->ctr.printer.info0; - smb_io_printer_info_0(desc, - info, - ps, - depth, - &start_offset, - &end_offset); - if (!ps->io) - { - /* writing */ - free(info); - } - break; - } - case 1: - { - PRINTER_INFO_1 *info; - info = r_u->ctr.printer.info1; - /* - smb_io_printer_info_1(desc, - info, - ps, - depth, - &start_offset, - &end_offset); - */ - if (!ps->io) - { - /* writing */ - free(info); - } - break; - } - case 2: - { - PRINTER_INFO_2 *info; - info = r_u->ctr.printer.info2; - /* - smb_io_printer_info_2(desc, - info, - ps, - depth, - &start_offset, - &end_offset); - */ - if (!ps->io) - { - /* writing */ - free_printer_info_2(info); - } - break; - } + if (!prs_align(ps)) + return False; - } + if (!prs_uint32("needed", ps, depth, &r_u->needed)) + return False; - prs_set_offset(ps, beginning+r_u->offered); - prs_align(ps); - } - - /* - * if the buffer was too small, send the minimum required size - * if it was too large, send the real needed size - */ - - prs_uint32("size of buffer needed", ps, depth, &(bufsize_required)); - prs_uint32("status", ps, depth, &(r_u->status)); - - return True; -} - -/******************************************************************* - * read a uint8 buffer of size *size. - * allocate memory for it - * return a pointer to the allocated memory and the size - * return NULL and a size of 0 if the buffer is empty - * - * jfmxxxx: fix it to also write a buffer - ********************************************************************/ -static BOOL spoolss_io_read_buffer8(char *desc, prs_struct *ps, uint8 **buffer, uint32 *size,int depth) -{ - prs_debug(ps, depth, desc, "spoolss_io_read_buffer8"); - depth++; - - prs_align(ps); - - prs_uint32("buffer size", ps, depth, size); - *buffer = (uint8 *)Realloc(NULL, (*size) * sizeof(uint8) ); - prs_uint8s(True,"buffer",ps,depth,*buffer,*size); - prs_align(ps); + if (!prs_uint32("status", ps, depth, &r_u->status)) + return False; - return True; + return True; } /******************************************************************* @@ -3024,38 +2654,28 @@ BOOL make_spoolss_q_getprinter(SPOOL_Q_GETPRINTER *q_u, * read a structure. * called from spoolss_getprinter (srv_spoolss.c) ********************************************************************/ -BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, - prs_struct *ps, int depth) +BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth) { - uint32 count = 0; - uint32 buf_ptr = q_u->buffer != NULL ? 1 : 0; prs_debug(ps, depth, desc, "spoolss_io_q_getprinter"); depth++; - prs_align(ps); + if (!prs_align(ps)) + return False; - smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); - - prs_uint32("level", ps, depth, &(q_u->level)); + if(!smb_io_prt_hnd("printer handle", &q_u->handle, ps, depth)) + return False; + if (!prs_uint32("level", ps, depth, &q_u->level)) + return False; - if (!ps->io) - { - /* writing */ - buf_ptr = q_u->buffer != NULL ? 1 : 0; - } - prs_uint32("buffer pointer", ps, depth, &buf_ptr); + if (!new_spoolss_io_buffer("", ps, depth, q_u->buffer)) + return False; - if (buf_ptr != 0) - { - spoolss_io_read_buffer8("",ps, &q_u->buffer, &count,depth); - } - if (q_u->buffer != NULL) - { - free(q_u->buffer); - } - prs_uint32("buffer size", ps, depth, &(q_u->offered)); + if (!prs_align(ps)) + return False; + if (!prs_uint32("offered", ps, depth, &q_u->offered)) + return False; - return count == q_u->offered; + return True; } /******************************************************************* @@ -3138,9 +2758,11 @@ BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int de prs_debug(ps, depth, desc, ""); 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; } @@ -3149,20 +2771,25 @@ BOOL spoolss_io_r_addjob(char *desc, SPOOL_R_ADDJOB *r_u, prs_struct *ps, int de ********************************************************************/ BOOL spoolss_io_q_addjob(char *desc, SPOOL_Q_ADDJOB *q_u, prs_struct *ps, int depth) { - prs_debug(ps, depth, desc, ""); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; - smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); - prs_uint32("level", ps, depth, &(q_u->level)); + if(!smb_io_prt_hnd("printer handle", &q_u->handle, ps, depth)) + return False; + if(!prs_uint32("level", ps, depth, &q_u->level)) + return False; - spoolss_io_read_buffer("", ps, depth, &(q_u->buffer)); + if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer)) + return False; - prs_align(ps); + if(!prs_align(ps)) + return False; - prs_uint32("buf_size", ps, depth, &(q_u->buf_size)); + if(!prs_uint32("offered", ps, depth, &q_u->offered)) + return False; return True; } @@ -3589,8 +3216,7 @@ BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_s prs_uint32("info level", ps, depth, &level); prs_uint32("useless", ps, depth, &useless); - switch (level) - { + switch (level) { /* * level 0 is used by setprinter when managing the queue * (hold, stop, start a queue) @@ -3614,7 +3240,6 @@ BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_s ********************************************************************/ BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct *ps, int depth) { - uint32 useless; prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex"); depth++; @@ -3624,32 +3249,44 @@ BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct * the info level are handled in a nice way. */ - prs_align(ps); - prs_uint32("useless", ps, depth, &useless); - smb_io_unistr2("", &(q_u->server_name),True,ps,depth); - prs_align(ps); + if(!prs_align(ps)) + return False; + if(!prs_uint32("", ps, depth, &q_u->server_name_ptr)) + return False; + if(!smb_io_unistr2("", &q_u->server_name, q_u->server_name_ptr, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("info_level", ps, depth, &q_u->level)) + return False; - prs_uint32("info_level", ps, depth, &(q_u->level)); - - spool_io_printer_info_level("", &(q_u->info), ps, depth); - - /* the 4 unknown are all 0 */ + if(!spool_io_printer_info_level("", &(q_u->info), ps, depth)) + return False; + /* the 4 unknown are all 0 */ + /* * en fait ils sont pas inconnu * par recoupement avec rpcSetPrinter * c'est le devicemode * et le security descriptor. */ - - prs_uint32("unk0", ps, depth, &(q_u->unk0)); - prs_uint32("unk1", ps, depth, &(q_u->unk1)); - prs_uint32("unk2", ps, depth, &(q_u->unk2)); - prs_uint32("unk3", ps, depth, &(q_u->unk3)); - - prs_uint32("info_level", ps, depth, &(q_u->user_level)); - spool_io_user_level("", &(q_u->user), ps, depth); + if(!prs_uint32("unk0", ps, depth, &q_u->unk0)) + return False; + if(!prs_uint32("unk1", ps, depth, &q_u->unk1)) + return False; + if(!prs_uint32("unk2", ps, depth, &q_u->unk2)) + return False; + if(!prs_uint32("unk3", ps, depth, &q_u->unk3)) + return False; + + if(!prs_uint32("user_switch", ps, depth, &q_u->user_switch)) + return False; + if(!spool_io_user_level("", &q_u->user_ctr, ps, depth)) + return False; return True; } @@ -3676,52 +3313,71 @@ BOOL spool_io_printer_driver_info_level_3(char *desc, SPOOL_PRINTER_DRIVER_INFO_ { SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *il; - prs_debug(ps, depth, desc, ""); + prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level_3"); depth++; /* reading */ - if (ps->io) - { + if (UNMARSHALLING(ps)) { il=(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *)malloc(sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3)); ZERO_STRUCTP(il); *q_u=il; - DEBUG(1,("lecture: memoire ok\n")); } - else - { + else { il=*q_u; } - prs_align(ps); + if(!prs_align(ps)) + return False; - prs_uint32("cversion", ps, depth, &(il->cversion)); - prs_uint32("name", ps, depth, &(il->name_ptr)); - prs_uint32("environment", ps, depth, &(il->environment_ptr)); - prs_uint32("driverpath", ps, depth, &(il->driverpath_ptr)); - prs_uint32("datafile", ps, depth, &(il->datafile_ptr)); - prs_uint32("configfile", ps, depth, &(il->configfile_ptr)); - prs_uint32("helpfile", ps, depth, &(il->helpfile_ptr)); - prs_uint32("monitorname", ps, depth, &(il->monitorname_ptr)); - prs_uint32("defaultdatatype", ps, depth, &(il->defaultdatatype_ptr)); - prs_uint32("dependentfilessize", ps, depth, &(il->dependentfilessize)); - prs_uint32("dependentfiles", ps, depth, &(il->dependentfiles_ptr)); + if(!prs_uint32("cversion", ps, depth, &il->cversion)) + return False; + if(!prs_uint32("name", ps, depth, &il->name_ptr)) + return False; + if(!prs_uint32("environment", ps, depth, &il->environment_ptr)) + return False; + if(!prs_uint32("driverpath", ps, depth, &il->driverpath_ptr)) + return False; + if(!prs_uint32("datafile", ps, depth, &il->datafile_ptr)) + return False; + if(!prs_uint32("configfile", ps, depth, &il->configfile_ptr)) + return False; + if(!prs_uint32("helpfile", ps, depth, &il->helpfile_ptr)) + return False; + if(!prs_uint32("monitorname", ps, depth, &il->monitorname_ptr)) + return False; + if(!prs_uint32("defaultdatatype", ps, depth, &il->defaultdatatype_ptr)) + return False; + if(!prs_uint32("dependentfilessize", ps, depth, &il->dependentfilessize)) + return False; + if(!prs_uint32("dependentfiles", ps, depth, &il->dependentfiles_ptr)) + return False; - prs_align(ps); + if(!prs_align(ps)) + return False; - smb_io_unistr2("", &(il->name), il->name_ptr, ps, depth); - smb_io_unistr2("", &(il->environment), il->environment_ptr, ps, depth); - smb_io_unistr2("", &(il->driverpath), il->driverpath_ptr, ps, depth); - smb_io_unistr2("", &(il->datafile), il->datafile_ptr, ps, depth); - smb_io_unistr2("", &(il->configfile), il->configfile_ptr, ps, depth); - smb_io_unistr2("", &(il->helpfile), il->helpfile_ptr, ps, depth); - smb_io_unistr2("", &(il->monitorname), il->monitorname_ptr, ps, depth); - smb_io_unistr2("", &(il->defaultdatatype), il->defaultdatatype_ptr, ps, depth); + if(!smb_io_unistr2("name", &il->name, il->name_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("environment", &il->environment, il->environment_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("driverpath", &il->driverpath, il->driverpath_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("datafile", &il->datafile, il->datafile_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("configfile", &il->configfile, il->configfile_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("helpfile", &il->helpfile, il->helpfile_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("monitorname", &il->monitorname, il->monitorname_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("defaultdatatype", &il->defaultdatatype, il->defaultdatatype_ptr, ps, depth)) + return False; - prs_align(ps); + if(!prs_align(ps)) + return False; + if (il->dependentfiles_ptr) smb_io_buffer5("", &(il->dependentfiles), ps, depth); - return True; } @@ -3807,23 +3463,25 @@ BOOL smb_io_unibuffer(char *desc, UNISTR2 *buffer, prs_struct *ps, int depth) ********************************************************************/ BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LEVEL *il, prs_struct *ps, int depth) { - uint32 useless; - uint32 level; - prs_debug(ps, depth, desc, ""); + prs_debug(ps, depth, desc, "spool_io_printer_driver_info_level"); depth++; - prs_align(ps); - prs_uint32("info level", ps, depth, &level); - prs_uint32("useless", ps, depth, &useless); + if(!prs_align(ps)) + return False; + if(!prs_uint32("level", ps, depth, &il->level)) + return False; + if(!prs_uint32("ptr", ps, depth, &il->ptr)) + return False; + + if (il->ptr==0) + return True; - switch (level) - { + switch (il->level) { case 3: spool_io_printer_driver_info_level_3("", &(il->info_3), ps, depth); break; } - return True; } @@ -3831,17 +3489,24 @@ BOOL spool_io_printer_driver_info_level(char *desc, SPOOL_PRINTER_DRIVER_INFO_LE ********************************************************************/ BOOL spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth) { - uint32 useless; - prs_debug(ps, depth, desc, ""); + prs_debug(ps, depth, desc, "spoolss_io_q_addprinterdriver"); depth++; - prs_align(ps); - prs_uint32("useless", ps, depth, &useless); - smb_io_unistr2("", &(q_u->server_name),True,ps,depth); - prs_align(ps); - prs_uint32("info_level", ps, depth, &(q_u->level)); + if(!prs_align(ps)) + return False; + + if(!prs_uint32("server_name_ptr", ps, depth, &q_u->server_name_ptr)) + return False; + if(!smb_io_unistr2("server_name", &q_u->server_name, q_u->server_name_ptr, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; + if(!prs_uint32("info_level", ps, depth, &q_u->level)) + return False; - spool_io_printer_driver_info_level("", &(q_u->info), ps, depth); + if(!spool_io_printer_driver_info_level("", &q_u->info, ps, depth)) + return False; return True; } @@ -3850,10 +3515,11 @@ BOOL spoolss_io_q_addprinterdriver(char *desc, SPOOL_Q_ADDPRINTERDRIVER *q_u, pr ********************************************************************/ BOOL spoolss_io_r_addprinterdriver(char *desc, SPOOL_R_ADDPRINTERDRIVER *q_u, prs_struct *ps, int depth) { - prs_debug(ps, depth, desc, ""); + prs_debug(ps, depth, desc, "spoolss_io_r_addprinterdriver"); depth++; - prs_uint32("status", ps, depth, &(q_u->status)); + if(!prs_uint32("status", ps, depth, &q_u->status)) + return False; return True; } @@ -3944,104 +3610,70 @@ BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni, } /******************************************************************* + Parse a SPOOL_Q_GETPRINTERDRIVERDIR structure. ********************************************************************/ -BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth) -{ - uint32 useless_ptr=0xADDE0FF0; - uint32 start_offset, end_offset, beginning; - uint32 bufsize_required=0; - - prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriverdir"); +BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_q_getprinterdriverdir"); depth++; - prs_align(ps); - - prs_uint32("pointer", ps, depth, &useless_ptr); - - switch (r_u->level) - { - case 1: - { - DRIVER_DIRECTORY_1 *driver_info_1; - driver_info_1=&(r_u->ctr.driver.info_1); - - bufsize_required = size_of_relative_string(&(driver_info_1->name)); - break; - } - } - - DEBUG(4,("spoolss_io_r_getprinterdriverdir, size needed: %d\n",bufsize_required)); - DEBUG(4,("spoolss_io_r_getprinterdriverdir, size offered: %d\n",r_u->offered)); - - /* check if the buffer is big enough for the datas */ - - if (r_u->offeredname_ptr)) + return False; + if(!smb_io_unistr2("", &q_u->name, q_u->name_ptr, ps, depth)) + return False; - /* it's too small */ - r_u->status=ERROR_INSUFFICIENT_BUFFER; /* say so */ - r_u->offered=0; /* don't send back the buffer */ - DEBUG(4,("spoolss_io_r_getprinterdriverdir, buffer too small\n")); + if(!prs_align(ps)) + return False; + + if(!prs_uint32("", ps, depth, &q_u->environment_ptr)) + return False; + if(!smb_io_unistr2("", &q_u->environment, q_u->environment_ptr, ps, depth)) + return False; + + if(!prs_align(ps)) + return False; - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - } - else - { - DEBUG(4,("spoolss_io_r_getprinterdriverdir, buffer large enough\n")); - - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - beginning=prs_offset(ps); - start_offset=prs_offset(ps); - end_offset=start_offset+r_u->offered; + if(!prs_uint32("level", ps, depth, &q_u->level)) + return False; - switch (r_u->level) - { - case 1: - { - DRIVER_DIRECTORY_1 *info; - info = &(r_u->ctr.driver.info_1); - prs_unistr("name", ps, depth, &(info->name)); - /*smb_io_printer_driver_dir_1(desc, info, ps, depth, &start_offset, &end_offset);*/ - break; - } - } - prs_set_offset(ps, beginning+r_u->offered); - prs_align(ps); - } - - /* - * if the buffer was too small, send the minimum required size - * if it was too large, send the real needed size - */ - - prs_uint32("size of buffer needed", ps, depth, &(bufsize_required)); - prs_uint32("status", ps, depth, &(r_u->status)); + if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer)) + return False; + + if(!prs_align(ps)) + return False; + + if(!prs_uint32("offered", ps, depth, &q_u->offered)) + return False; return True; } /******************************************************************* + Parse a SPOOL_R_GETPRINTERDRIVERDIR structure. ********************************************************************/ -BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, prs_struct *ps, int depth) -{ - - uint32 useless_ptr=0xADDE0FF0; - prs_debug(ps, depth, desc, ""); +BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_getprinterdriverdir"); depth++; - prs_align(ps); - prs_uint32("pointer", ps, depth, &useless_ptr); - smb_io_unistr2("", &(q_u->name),True,ps,depth); - prs_align(ps); - prs_uint32("pointer", ps, depth, &useless_ptr); - smb_io_unistr2("", &(q_u->environment),True,ps,depth); - prs_align(ps); - prs_uint32("level", ps, depth, &(q_u->level)); - spoolss_io_read_buffer("", ps, depth, &(q_u->buffer)); - prs_align(ps); - prs_uint32("buf_size", ps, depth, &(q_u->buf_size)); + if (!prs_align(ps)) + return False; + + if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer)) + return False; - return True; + if (!prs_align(ps)) + return False; + + if (!prs_uint32("needed", ps, depth, &r_u->needed)) + return False; + + if (!prs_uint32("status", ps, depth, &r_u->status)) + return False; + + return True; } /******************************************************************* @@ -4295,23 +3927,23 @@ BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value, ********************************************************************/ static BOOL spoolss_io_addform(char *desc, FORM *f, uint32 ptr, prs_struct *ps, int depth) { - prs_debug(ps, depth, desc, "spoolss_io_addform"); - depth++; - prs_align(ps); - - 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)); + prs_debug(ps, depth, desc, "spoolss_io_addform"); + depth++; + prs_align(ps); - smb_io_unistr2("", &(f->name), f->name_ptr, ps, depth); - } + 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); + } return True; } @@ -4320,20 +3952,20 @@ static BOOL spoolss_io_addform(char *desc, FORM *f, uint32 ptr, prs_struct *ps, ********************************************************************/ BOOL spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth) { - uint32 useless_ptr=0; - prs_debug(ps, depth, desc, "spoolss_io_q_addform"); - depth++; + uint32 useless_ptr=0; + prs_debug(ps, depth, desc, "spoolss_io_q_addform"); + depth++; - prs_align(ps); - smb_io_prt_hnd("printer handle", &(q_u->handle), ps, depth); - prs_uint32("level", ps, depth, &(q_u->level)); - prs_uint32("level2", ps, depth, &(q_u->level2)); + prs_align(ps); + smb_io_prt_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 (q_u->level==1) - { - prs_uint32("useless_ptr", ps, depth, &(useless_ptr)); - spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth); - } + if (q_u->level==1) + { + prs_uint32("useless_ptr", ps, depth, &(useless_ptr)); + spoolss_io_addform("", &(q_u->form), useless_ptr, ps, depth); + } return True; } @@ -4342,11 +3974,11 @@ BOOL spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int ********************************************************************/ BOOL spoolss_io_r_addform(char *desc, SPOOL_R_ADDFORM *r_u, prs_struct *ps, int depth) { - prs_debug(ps, depth, desc, "spoolss_io_r_addform"); - depth++; + prs_debug(ps, depth, desc, "spoolss_io_r_addform"); + depth++; - prs_align(ps); - prs_uint32("status", ps, depth, &(r_u->status)); + prs_align(ps); + prs_uint32("status", ps, depth, &(r_u->status)); return True; } @@ -4391,134 +4023,57 @@ BOOL spoolss_io_r_setform(char *desc, SPOOL_R_SETFORM *r_u, prs_struct *ps, int } /******************************************************************* + Parse a SPOOL_R_GETJOB structure. ********************************************************************/ BOOL spoolss_io_r_getjob(char *desc, SPOOL_R_GETJOB *r_u, prs_struct *ps, int depth) { - uint32 useless_ptr=0xADDE0FF0; - uint32 start_offset, end_offset, beginning; - uint32 bufsize_required=0; - prs_debug(ps, depth, desc, "spoolss_io_r_getjob"); depth++; - prs_align(ps); - - prs_uint32("pointer", ps, depth, &useless_ptr); - - switch (r_u->level) - { - case 1: - { - JOB_INFO_1 *info; - info=r_u->ctr.job.job_info_1; - - bufsize_required += spoolss_size_job_info_1(info); - break; - } - case 2: - { - JOB_INFO_2 *info; - info=r_u->ctr.job.job_info_2; - - bufsize_required += spoolss_size_job_info_2(info); - break; - } - } - - DEBUG(4,("spoolss_io_r_getjob, size needed: %d\n",bufsize_required)); - DEBUG(4,("spoolss_io_r_getjob, size offered: %d\n",r_u->offered)); - - /* check if the buffer is big enough for the datas */ - if (r_u->offeredstatus=ERROR_INSUFFICIENT_BUFFER; /* say so */ - r_u->offered=0; /* don't send back the buffer */ + if (!prs_align(ps)) + return False; - DEBUG(4,("spoolss_io_r_getjob, buffer too small\n")); + if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer)) + return False; - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - } - else - { - DEBUG(4,("spoolss_io_r_enumjobs, buffer large enough\n")); - - prs_uint32("size of buffer", ps, depth, &(r_u->offered)); - beginning=prs_offset(ps); - start_offset=prs_offset(ps); - end_offset=start_offset+r_u->offered; + if (!prs_align(ps)) + return False; - switch (r_u->level) - { - case 1: - { - JOB_INFO_1 *info; - info = r_u->ctr.job.job_info_1; - smb_io_job_info_1(desc, info, ps, depth, &start_offset, &end_offset); - break; - } - case 2: - { - JOB_INFO_2 *info; - info = r_u->ctr.job.job_info_2; - smb_io_job_info_2(desc, info, ps, depth, &start_offset, &end_offset); - break; - } + if (!prs_uint32("needed", ps, depth, &r_u->needed)) + return False; - } - prs_set_offset(ps, beginning+r_u->offered); - prs_align(ps); - } - - /* - * if the buffer was too small, send the minimum required size - * if it was too large, send the real needed size - */ - - prs_uint32("size of buffer needed", ps, depth, &(bufsize_required)); - prs_uint32("status", ps, depth, &(r_u->status)); - - return True; -} + if (!prs_uint32("status", ps, depth, &r_u->status)) + return False; -/**************************************************************************** -****************************************************************************/ -void free_spoolss_r_getjob(SPOOL_R_GETJOB *r_u) -{ - switch (r_u->level) - { - case 1: - { - free(r_u->ctr.job.job_info_1); - break; - } - case 2: - { - free_job_info_2(r_u->ctr.job.job_info_2); - break; - } - } + return True; } /******************************************************************* + Parse a SPOOL_Q_GETJOB structure. ********************************************************************/ BOOL spoolss_io_q_getjob(char *desc, SPOOL_Q_GETJOB *q_u, prs_struct *ps, int depth) { - prs_debug(ps, depth, desc, ""); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; - smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); - prs_uint32("jobid", ps, depth, &(q_u->jobid)); - prs_uint32("level", ps, depth, &(q_u->level)); + if(!smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth)) + return False; + if(!prs_uint32("jobid", ps, depth, &q_u->jobid)) + return False; + if(!prs_uint32("level", ps, depth, &q_u->level)) + return False; - spoolss_io_read_buffer("", ps, depth, &(q_u->buffer)); + if(!new_spoolss_io_buffer("", ps, depth, q_u->buffer)) + return False; - prs_align(ps); + if(!prs_align(ps)) + return False; - prs_uint32("buf_size", ps, depth, &(q_u->buf_size)); + if(!prs_uint32("offered", ps, depth, &q_u->offered)) + return False; return True; } diff --git a/source/rpc_server/srv_spoolss.c b/source/rpc_server/srv_spoolss.c index 50b6dd38460..4965542d73e 100755 --- a/source/rpc_server/srv_spoolss.c +++ b/source/rpc_server/srv_spoolss.c @@ -42,17 +42,15 @@ static BOOL api_spoolss_open_printer_ex(uint16 vuid, prs_struct *data, prs_struc DEBUG(0,("spoolss_io_q_open_printer_ex: unable to unmarshall SPOOL_Q_OPEN_PRINTER_EX.\n")); return False; } - + if (q_u.printername_ptr != 0) - { printername = &q_u.printername; - } - + r_u.status = _spoolss_open_printer_ex( printername, &q_u.printer_default, q_u.user_switch, q_u.user_ctr, &r_u.handle); - + if (!spoolss_io_r_open_printer_ex("",&r_u,rdata,0)){ DEBUG(0,("spoolss_io_r_open_printer_ex: unable to marshall SPOOL_R_OPEN_PRINTER_EX.\n")); return False; @@ -88,9 +86,9 @@ static BOOL api_spoolss_getprinterdata(uint16 vuid, prs_struct *data, prs_struct DEBUG(0,("spoolss_io_r_getprinterdata: unable to marshall SPOOL_R_GETPRINTERDATA.\n")); return False; } - + safe_free(r_u.data); - + return True; } @@ -111,7 +109,7 @@ static BOOL api_spoolss_closeprinter(uint16 vuid, prs_struct *data, prs_struct * DEBUG(0,("spoolss_io_q_closeprinter: unable to unmarshall SPOOL_Q_CLOSEPRINTER.\n")); return False; } - + r_u.status = _spoolss_closeprinter(&q_u.handle); memcpy(&r_u.handle, &q_u.handle, sizeof(r_u.handle)); @@ -119,6 +117,8 @@ static BOOL api_spoolss_closeprinter(uint16 vuid, prs_struct *data, prs_struct * DEBUG(0,("spoolss_io_r_closeprinter: unable to marshall SPOOL_R_CLOSEPRINTER.\n")); return False; } + + return True; } /******************************************************************** @@ -141,11 +141,13 @@ static BOOL api_spoolss_rffpcnex(uint16 vuid, prs_struct *data, prs_struct *rdat r_u.status = _spoolss_rffpcnex(&q_u.handle, q_u.flags, q_u.options, &q_u.localmachine, q_u.printerlocal, &q_u.option); - + if (!spoolss_io_r_rffpcnex("",&r_u,rdata,0)) { DEBUG(0,("spoolss_io_r_rffpcnex: unable to marshall SPOOL_R_RFFPCNEX.\n")); return False; } + + return True; } @@ -170,11 +172,13 @@ static BOOL api_spoolss_rfnpcnex(uint16 vuid, prs_struct *data, prs_struct *rdat r_u.status = _spoolss_rfnpcnex(&q_u.handle, q_u.change, &q_u.option, &r_u.count, &r_u.info); - + if (!spoolss_io_r_rfnpcnex("", &r_u, rdata, 0)) { DEBUG(0,("spoolss_io_r_rfnpcnex: unable to marshall SPOOL_R_RFNPCNEX.\n")); return False; } + + return True; } @@ -191,8 +195,6 @@ static BOOL api_spoolss_enumprinters(uint16 vuid, prs_struct *data, prs_struct * ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - DEBUG(5,("api_spoolss_enumprinters\n")); - new_spoolss_allocate_buffer(&q_u.buffer); if (!spoolss_io_q_enumprinters("", &q_u, data, 0)) { @@ -206,7 +208,7 @@ static BOOL api_spoolss_enumprinters(uint16 vuid, prs_struct *data, prs_struct * r_u.status = _spoolss_enumprinters( q_u.flags, &q_u.servername, q_u.level, r_u.buffer, q_u.offered, &r_u.needed, &r_u.returned); - + if (!new_spoolss_io_r_enumprinters("", &r_u, rdata, 0)) { DEBUG(0,("new_spoolss_io_r_enumprinters: unable to marshall SPOOL_R_ENUMPRINTERS.\n")); new_spoolss_free_buffer(q_u.buffer); @@ -214,7 +216,7 @@ static BOOL api_spoolss_enumprinters(uint16 vuid, prs_struct *data, prs_struct * } new_spoolss_free_buffer(q_u.buffer); - + return True; } @@ -231,24 +233,27 @@ static BOOL api_spoolss_getprinter(uint16 vuid, prs_struct *data, prs_struct *rd ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); + new_spoolss_allocate_buffer(&q_u.buffer); + if(!spoolss_io_q_getprinter("", &q_u, data, 0)) { DEBUG(0,("spoolss_io_q_getprinter: unable to unmarshall SPOOL_Q_GETPRINTER.\n")); return False; } - r_u.status = _spoolss_getprinter(&q_u.handle, q_u.level, - &r_u.ctr, &q_u.offered, &r_u.needed); + /* that's an [in out] buffer */ + new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); - memcpy(&r_u.handle, &q_u.handle, sizeof(&r_u.handle)); - r_u.offered = q_u.offered; - r_u.level = q_u.level; - safe_free(q_u.buffer); + r_u.status = _spoolss_getprinter(&q_u.handle, q_u.level, + r_u.buffer, q_u.offered, + &r_u.needed); if(!spoolss_io_r_getprinter("",&r_u,rdata,0)) { DEBUG(0,("spoolss_io_r_getprinter: unable to marshall SPOOL_R_GETPRINTER.\n")); + new_spoolss_free_buffer(q_u.buffer); return False; } - + + new_spoolss_free_buffer(q_u.buffer); return True; } @@ -265,26 +270,28 @@ static BOOL api_spoolss_getprinterdriver2(uint16 vuid, prs_struct *data, prs_str ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - + + new_spoolss_allocate_buffer(&q_u.buffer); + if(!spoolss_io_q_getprinterdriver2("", &q_u, data, 0)) { DEBUG(0,("spoolss_io_q_getprinterdriver2: unable to unmarshall SPOOL_Q_GETPRINTERDRIVER2.\n")); return False; } - - r_u.status = _spoolss_getprinterdriver2(&q_u.handle, - &q_u.architecture, q_u.level, - &r_u.ctr, &q_u.buf_size, - &r_u.needed); - - r_u.offered = q_u.buf_size; - r_u.level = q_u.level; - spoolss_io_free_buffer(&(q_u.buffer)); + /* that's an [in out] buffer */ + new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); + + r_u.status = _spoolss_getprinterdriver2(&q_u.handle, &q_u.architecture, q_u.level, q_u.unknown, + r_u.buffer, q_u.offered, + &r_u.needed, &r_u.unknown0, &r_u.unknown1); + if(!spoolss_io_r_getprinterdriver2("",&r_u,rdata,0)) { DEBUG(0,("spoolss_io_r_getprinterdriver2: unable to marshall SPOOL_R_GETPRINTERDRIVER2.\n")); + new_spoolss_free_buffer(q_u.buffer); return False; } + new_spoolss_free_buffer(q_u.buffer); return True; } @@ -300,20 +307,20 @@ static BOOL api_spoolss_startpageprinter(uint16 vuid, prs_struct *data, prs_stru ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - + if(!spoolss_io_q_startpageprinter("", &q_u, data, 0)) { DEBUG(0,("spoolss_io_q_startpageprinter: unable to unmarshall SPOOL_Q_STARTPAGEPRINTER.\n")); return False; } - + r_u.status = _spoolss_startpageprinter(&q_u.handle); - + if(!spoolss_io_r_startpageprinter("",&r_u,rdata,0)) { DEBUG(0,("spoolss_io_r_startpageprinter: unable to marshall SPOOL_R_STARTPAGEPRINTER.\n")); return False; } - - return True; + + return True; } @@ -329,58 +336,53 @@ static BOOL api_spoolss_endpageprinter(uint16 vuid, prs_struct *data, prs_struct ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - + if(!spoolss_io_q_endpageprinter("", &q_u, data, 0)) { DEBUG(0,("spoolss_io_q_endpageprinter: unable to unmarshall SPOOL_Q_ENDPAGEPRINTER.\n")); return False; } - + r_u.status = _spoolss_endpageprinter(&q_u.handle); - + if(!spoolss_io_r_endpageprinter("",&r_u,rdata,0)) { DEBUG(0,("spoolss_io_r_endpageprinter: unable to marshall SPOOL_R_ENDPAGEPRINTER.\n")); return False; } - + return True; } /******************************************************************** - * api_spoolss_getprinter - * called from the spoolss dispatcher - * - ********************************************************************/ +********************************************************************/ static BOOL api_spoolss_startdocprinter(uint16 vuid, prs_struct *data, prs_struct *rdata) { SPOOL_Q_STARTDOCPRINTER q_u; SPOOL_R_STARTDOCPRINTER r_u; - + ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - + if(!spoolss_io_q_startdocprinter("", &q_u, data, 0)) { DEBUG(0,("spoolss_io_q_startdocprinter: unable to unmarshall SPOOL_Q_STARTDOCPRINTER.\n")); return False; } - + r_u.status = _spoolss_startdocprinter(&q_u.handle, q_u.doc_info_container.level, &q_u.doc_info_container.docinfo, &r_u.jobid); - + if(!spoolss_io_r_startdocprinter("",&r_u,rdata,0)) { DEBUG(0,("spoolss_io_r_startdocprinter: unable to marshall SPOOL_R_STARTDOCPRINTER.\n")); return False; } - + return True; } + /******************************************************************** - * api_spoolss_getprinter - * called from the spoolss dispatcher - * - ********************************************************************/ +********************************************************************/ static BOOL api_spoolss_enddocprinter(uint16 vuid, prs_struct *data, prs_struct *rdata) { SPOOL_Q_ENDDOCPRINTER q_u; @@ -388,28 +390,25 @@ static BOOL api_spoolss_enddocprinter(uint16 vuid, prs_struct *data, prs_struct ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - + if(!spoolss_io_q_enddocprinter("", &q_u, data, 0)) { DEBUG(0,("spoolss_io_q_enddocprinter: unable to unmarshall SPOOL_Q_ENDDOCPRINTER.\n")); return False; } - + r_u.status = _spoolss_enddocprinter(&q_u.handle); - + if(!spoolss_io_r_enddocprinter("",&r_u,rdata,0)) { DEBUG(0,("spoolss_io_r_enddocprinter: unable to marshall SPOOL_R_ENDDOCPRINTER.\n")); return False; } - + return True; } /******************************************************************** - * api_spoolss_getprinter - * called from the spoolss dispatcher - * - ********************************************************************/ +********************************************************************/ static BOOL api_spoolss_writeprinter(uint16 vuid, prs_struct *data, prs_struct *rdata) { SPOOL_Q_WRITEPRINTER q_u; @@ -417,19 +416,19 @@ static BOOL api_spoolss_writeprinter(uint16 vuid, prs_struct *data, prs_struct * ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - + if(!spoolss_io_q_writeprinter("", &q_u, data, 0)) { DEBUG(0,("spoolss_io_q_writeprinter: unable to unmarshall SPOOL_Q_WRITEPRINTER.\n")); return False; } - + r_u.status = _spoolss_writeprinter(&q_u.handle, q_u.buffer_size, q_u.buffer, &q_u.buffer_size2); r_u.buffer_written = q_u.buffer_size2; safe_free(q_u.buffer); - + if(!spoolss_io_r_writeprinter("",&r_u,rdata,0)) { DEBUG(0,("spoolss_io_r_writeprinter: unable to marshall SPOOL_R_WRITEPRINTER.\n")); return False; @@ -439,6 +438,9 @@ static BOOL api_spoolss_writeprinter(uint16 vuid, prs_struct *data, prs_struct * } /**************************************************************************** + +FIX ME: JFM: freeing memory ???? + ****************************************************************************/ static BOOL api_spoolss_setprinter(uint16 vuid, prs_struct *data, prs_struct *rdata) { @@ -483,9 +485,9 @@ static BOOL api_spoolss_fcpn(uint16 vuid, prs_struct *data, prs_struct *rdata) DEBUG(0,("spoolss_io_q_fcpn: unable to unmarshall SPOOL_Q_FCPN.\n")); return False; } - + r_u.status = _spoolss_fcpn(&q_u.handle); - + if(!spoolss_io_r_fcpn("",&r_u,rdata,0)) { DEBUG(0,("spoolss_io_r_fcpn: unable to marshall SPOOL_R_FCPN.\n")); return False; @@ -501,25 +503,30 @@ static BOOL api_spoolss_addjob(uint16 vuid, prs_struct *data, prs_struct *rdata) { SPOOL_Q_ADDJOB q_u; SPOOL_R_ADDJOB r_u; - + ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - + + new_spoolss_allocate_buffer(&q_u.buffer); + if(!spoolss_io_q_addjob("", &q_u, data, 0)) { DEBUG(0,("spoolss_io_q_addjob: unable to unmarshall SPOOL_Q_ADDJOB.\n")); return False; } + /* that's only an [in] buffer ! */ + r_u.status = _spoolss_addjob(&q_u.handle, q_u.level, - &q_u.buffer, q_u.buf_size); - - spoolss_io_free_buffer(&(q_u.buffer)); - + q_u.buffer, q_u.offered); + if(!spoolss_io_r_addjob("",&r_u,rdata,0)) { DEBUG(0,("spoolss_io_r_addjob: unable to marshall SPOOL_R_ADDJOB.\n")); + new_spoolss_free_buffer(q_u.buffer); return False; } + new_spoolss_free_buffer(q_u.buffer); + return True; } @@ -555,7 +562,7 @@ static BOOL api_spoolss_enumjobs(uint16 vuid, prs_struct *data, prs_struct *rdat } new_spoolss_free_buffer(q_u.buffer); - + return True; } @@ -566,22 +573,22 @@ static BOOL api_spoolss_schedulejob(uint16 vuid, prs_struct *data, prs_struct *r { SPOOL_Q_SCHEDULEJOB q_u; SPOOL_R_SCHEDULEJOB r_u; - + ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - + if(!spoolss_io_q_schedulejob("", &q_u, data, 0)) { DEBUG(0,("spoolss_io_q_schedulejob: unable to unmarshall SPOOL_Q_SCHEDULEJOB.\n")); return False; } - + r_u.status = _spoolss_schedulejob(&q_u.handle, q_u.jobid); - + if(!spoolss_io_r_schedulejob("",&r_u,rdata,0)) { DEBUG(0,("spoolss_io_r_schedulejob: unable to marshall SPOOL_R_SCHEDULEJOB.\n")); return False; } - + return True; } @@ -591,23 +598,23 @@ static BOOL api_spoolss_setjob(uint16 vuid, prs_struct *data, prs_struct *rdata) { SPOOL_Q_SETJOB q_u; SPOOL_R_SETJOB r_u; - + ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); - + if(!spoolss_io_q_setjob("", &q_u, data, 0)) { DEBUG(0,("spoolss_io_q_setjob: unable to unmarshall SPOOL_Q_SETJOB.\n")); return False; } - + r_u.status = _spoolss_setjob(&q_u.handle, q_u.jobid, q_u.level, &q_u.ctr, q_u.command); - + if(!spoolss_io_r_setjob("",&r_u,rdata,0)) { DEBUG(0,("spoolss_io_r_setjob: unable to marshall SPOOL_R_SETJOB.\n")); return False; } - + return True; } @@ -618,7 +625,7 @@ static BOOL api_spoolss_enumprinterdrivers(uint16 vuid, prs_struct *data, prs_st { SPOOL_Q_ENUMPRINTERDRIVERS q_u; SPOOL_R_ENUMPRINTERDRIVERS r_u; - + ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); @@ -643,7 +650,7 @@ static BOOL api_spoolss_enumprinterdrivers(uint16 vuid, prs_struct *data, prs_st } new_spoolss_free_buffer(q_u.buffer); - + return True; } @@ -654,7 +661,7 @@ static BOOL api_spoolss_enumforms(uint16 vuid, prs_struct *data, prs_struct *rda { SPOOL_Q_ENUMFORMS q_u; SPOOL_R_ENUMFORMS r_u; - + ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); @@ -667,7 +674,7 @@ static BOOL api_spoolss_enumforms(uint16 vuid, prs_struct *data, prs_struct *rda /* that's an [in out] buffer */ new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); - + r_u.status = _new_spoolss_enumforms(&q_u.handle, q_u.level, r_u.buffer, q_u.offered, &r_u.needed, &r_u.numofforms); @@ -677,9 +684,9 @@ static BOOL api_spoolss_enumforms(uint16 vuid, prs_struct *data, prs_struct *rda new_spoolss_free_buffer(q_u.buffer); return False; } - + new_spoolss_free_buffer(q_u.buffer); - + return True; } @@ -690,7 +697,7 @@ static BOOL api_spoolss_enumports(uint16 vuid, prs_struct *data, prs_struct *rda { SPOOL_Q_ENUMPORTS q_u; SPOOL_R_ENUMPORTS r_u; - + ZERO_STRUCT(q_u); ZERO_STRUCT(r_u); @@ -703,19 +710,19 @@ static BOOL api_spoolss_enumports(uint16 vuid, prs_struct *data, prs_struct *rda /* that's an [in out] buffer */ new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); - + r_u.status = _spoolss_enumports(&q_u.name, q_u.level, r_u.buffer, q_u.offered, &r_u.needed, &r_u.returned); - + if (!new_spoolss_io_r_enumports("",&r_u,rdata,0)) { DEBUG(0,("new_spoolss_io_r_enumports: unable to marshall SPOOL_R_ENUMPORTS.\n")); new_spoolss_free_buffer(q_u.buffer); return False; } - + new_spoolss_free_buffer(q_u.buffer); - + return True; } @@ -738,7 +745,7 @@ static BOOL api_spoolss_addprinterex(uint16 vuid, prs_struct *data, prs_struct * r_u.status = _spoolss_addprinterex(&q_u.server_name, q_u.level, &q_u.info, q_u.unk0, q_u.unk1, q_u.unk2, q_u.unk3, - q_u.user_level, &q_u.user, + q_u.user_switch, &q_u.user_ctr, &r_u.handle); if(!spoolss_io_r_addprinterex("", &r_u, rdata, 0)) { @@ -764,8 +771,7 @@ static BOOL api_spoolss_addprinterdriver(uint16 vuid, prs_struct *data, prs_stru return False; } - r_u.status = _spoolss_addprinterdriver(&q_u.server_name, - q_u.level, &q_u.info); + r_u.status = _spoolss_addprinterdriver(&q_u.server_name, q_u.level, &q_u.info); if(!spoolss_io_r_addprinterdriver("", &r_u, rdata, 0)) { DEBUG(0,("spoolss_io_r_addprinterdriver: unable to marshall SPOOL_R_ADDPRINTERDRIVER.\n")); @@ -781,26 +787,32 @@ static BOOL api_spoolss_getprinterdriverdirectory(uint16 vuid, prs_struct *data, { SPOOL_Q_GETPRINTERDRIVERDIR q_u; SPOOL_R_GETPRINTERDRIVERDIR r_u; - + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + new_spoolss_allocate_buffer(&q_u.buffer); + if(!spoolss_io_q_getprinterdriverdir("", &q_u, data, 0)) { DEBUG(0,("spoolss_io_q_getprinterdriverdir: unable to unmarshall SPOOL_Q_GETPRINTERDRIVERDIR.\n")); return False; } - - r_u.offered = q_u.buf_size; - r_u.level = q_u.level; - r_u.status = _spoolss_getprinterdriverdirectory(&q_u.name, - &q_u.environment, - q_u.level, - &r_u.ctr, - &r_u.offered); - spoolss_io_free_buffer(&q_u.buffer); - + + /* that's an [in out] buffer */ + new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); + + r_u.status = _spoolss_getprinterdriverdirectory(&q_u.name, &q_u.environment, q_u.level, + r_u.buffer, q_u.offered, + &r_u.needed); + if(!spoolss_io_r_getprinterdriverdir("", &r_u, rdata, 0)) { DEBUG(0,("spoolss_io_r_getprinterdriverdir: unable to marshall SPOOL_R_GETPRINTERDRIVERDIR.\n")); + new_spoolss_free_buffer(q_u.buffer); return False; } - + + new_spoolss_free_buffer(q_u.buffer); + return True; } @@ -909,8 +921,7 @@ static BOOL api_spoolss_setform(uint16 vuid, prs_struct *data, prs_struct *rdata return False; } - r_u.status = _spoolss_setform(&q_u.handle, - &q_u.name, q_u.level, &q_u.form); + r_u.status = _spoolss_setform(&q_u.handle, &q_u.name, q_u.level, &q_u.form); if(!spoolss_io_r_setform("", &r_u, rdata, 0)) { DEBUG(0,("spoolss_io_r_setform: unable to marshall SPOOL_R_SETFORM.\n")); @@ -997,27 +1008,27 @@ static BOOL api_spoolss_getjob(uint16 vuid, prs_struct *data, prs_struct *rdata) SPOOL_Q_GETJOB q_u; SPOOL_R_GETJOB r_u; + new_spoolss_allocate_buffer(&q_u.buffer); + if(!spoolss_io_q_getjob("", &q_u, data, 0)) { DEBUG(0,("spoolss_io_q_getjob: unable to unmarshall SPOOL_Q_GETJOB.\n")); return False; } - r_u.offered = q_u.buf_size; - r_u.level = q_u.level; - r_u.status = _spoolss_getjob(&q_u.handle, - q_u.jobid, - q_u.level, - &r_u.ctr, - &r_u.offered); - spoolss_io_free_buffer(&(q_u.buffer)); + /* that's an [in out] buffer */ + new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); + + r_u.status = _spoolss_getjob(&q_u.handle, q_u.jobid, q_u.level, + r_u.buffer, q_u.offered, + &r_u.needed); if(!spoolss_io_r_getjob("",&r_u,rdata,0)) { DEBUG(0,("spoolss_io_r_getjob: unable to marshall SPOOL_R_GETJOB.\n")); + new_spoolss_free_buffer(q_u.buffer); return False; } - - free_spoolss_r_getjob(&r_u); - + + new_spoolss_free_buffer(q_u.buffer); return True; } diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c index 2e80cbdbf6f..90a7b44aef3 100644 --- a/source/rpc_server/srv_spoolss_nt.c +++ b/source/rpc_server/srv_spoolss_nt.c @@ -392,7 +392,6 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername, uint32 user_switch, SPOOL_USER_CTR user_ctr, POLICY_HND *handle) { - BOOL printer_open = False; fstring name; fstring datatype; @@ -439,57 +438,41 @@ uint32 _spoolss_open_printer_ex( const UNISTR2 *printername, return NT_STATUS_NO_PROBLEMO; } +/**************************************************************************** +****************************************************************************/ static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni, - NT_PRINTER_INFO_LEVEL *printer, - uint32 level) + NT_PRINTER_INFO_LEVEL *printer, uint32 level) { - switch (level) - { + switch (level) { case 2: - { - uni_2_asc_printer_info_2(uni->info_2, - &(printer->info_2)); + uni_2_asc_printer_info_2(uni->info_2, &(printer->info_2)); break; - } default: break; } - - return True; } static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni, - NT_PRINTER_DRIVER_INFO_LEVEL *printer, - uint32 level) + NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level) { - switch (level) - { + switch (level) { case 3: - { printer->info_3=NULL; uni_2_asc_printer_driver_3(uni->info_3, &(printer->info_3)); break; - } default: break; } - - return True; } static BOOL convert_devicemode(DEVICEMODE devmode, NT_DEVICEMODE *nt_devmode) { - unistr_to_ascii(nt_devmode->devicename, - devmode.devicename.buffer, - 31); - - unistr_to_ascii(nt_devmode->formname, - devmode.formname.buffer, - 31); + unistr_to_ascii(nt_devmode->devicename, devmode.devicename.buffer, 31); + unistr_to_ascii(nt_devmode->formname, devmode.formname.buffer, 31); nt_devmode->specversion=devmode.specversion; nt_devmode->driverversion=devmode.driverversion; @@ -524,7 +507,7 @@ static BOOL convert_devicemode(DEVICEMODE devmode, NT_DEVICEMODE *nt_devmode) nt_devmode->reserved2=devmode.reserved2; nt_devmode->panningwidth=devmode.panningwidth; nt_devmode->panningheight=devmode.panningheight; - + if (nt_devmode->driverextra != 0) { /* if we had a previous private delete it and make a new one */ @@ -533,7 +516,6 @@ static BOOL convert_devicemode(DEVICEMODE devmode, NT_DEVICEMODE *nt_devmode) nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8)); memcpy(nt_devmode->private, devmode.private, nt_devmode->driverextra); } - return True; } @@ -1948,65 +1930,121 @@ uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 le /**************************************************************************** ****************************************************************************/ -uint32 _spoolss_getprinter( POLICY_HND *handle, - uint32 level, - PRINTER_INFO *ctr, - uint32 *offered, - uint32 *needed) +static uint32 getprinter_level_0(pstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { - int snum; - pstring servername; + PRINTER_INFO_0 *printer=NULL; + + printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0)); + construct_printer_info_0(printer, snum, servername); - pstrcpy(servername, global_myname); + /* check the required size. */ + *needed += spoolss_size_printer_info_0(printer); - if (!get_printer_snum(handle,&snum)) - { - return NT_STATUS_INVALID_HANDLE; + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + /* fill the buffer with the structures */ + new_smb_io_printer_info_0("", buffer, printer, 0); + + /* clear memory */ + safe_free(printer); + + if (*needed > offered) { + return ERROR_INSUFFICIENT_BUFFER; } + else + return NT_STATUS_NO_PROBLEMO; +} - DEBUG(0,("_spoolss_getprinter: offered and needed params ignored\n")); +/**************************************************************************** +****************************************************************************/ +static uint32 getprinter_level_1(pstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +{ + PRINTER_INFO_1 *printer=NULL; - switch (level) - { - case 0: - { - PRINTER_INFO_0 *printer; - - printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0)); - construct_printer_info_0(printer, snum, servername); - ctr->printer.info0=printer; - - return 0x0; - } - case 1: - { - PRINTER_INFO_1 *printer; - - printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1)); - construct_printer_info_1(printer, snum, servername); - ctr->printer.info1=printer; + printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1)); + construct_printer_info_1(printer, snum, servername); + + /* check the required size. */ + *needed += spoolss_size_printer_info_1(printer); - return 0x0; - } - case 2: - { - PRINTER_INFO_2 *printer; - - printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)); - construct_printer_info_2(printer, snum, servername); - ctr->printer.info2=printer; + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; - return 0x0; - } - default: - { - break; - } + /* fill the buffer with the structures */ + new_smb_io_printer_info_1("", buffer, printer, 0); + + /* clear memory */ + safe_free(printer); + + if (*needed > offered) { + return ERROR_INSUFFICIENT_BUFFER; } + else + return NT_STATUS_NO_PROBLEMO; +} - return NT_STATUS_INVALID_INFO_CLASS; +/**************************************************************************** +****************************************************************************/ +static uint32 getprinter_level_2(pstring servername, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +{ + PRINTER_INFO_2 *printer=NULL; + + printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)); + construct_printer_info_2(printer, snum, servername); + + /* check the required size. */ + *needed += spoolss_size_printer_info_2(printer); + + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + /* fill the buffer with the structures */ + new_smb_io_printer_info_2("", buffer, printer, 0); + + /* clear memory */ + safe_free(printer); + + if (*needed > offered) { + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; } +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level, + NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +{ + int snum; + pstring servername; + + *needed=0; + + pstrcpy(servername, global_myname); + + if (!get_printer_snum(handle, &snum)) + { + return NT_STATUS_INVALID_HANDLE; + } + + switch (level) { + case 0: + return getprinter_level_0(servername, snum, buffer, offered, needed); + break; + case 1: + return getprinter_level_1(servername,snum, buffer, offered, needed); + break; + case 2: + return getprinter_level_2(servername,snum, buffer, offered, needed); + break; + default: + return NT_STATUS_INVALID_LEVEL; + break; + } +} + /******************************************************************** * construct_printer_driver_info_1 * fill a construct_printer_driver_info_1 struct @@ -2187,63 +2225,129 @@ static void construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, /**************************************************************************** ****************************************************************************/ -uint32 _spoolss_getprinterdriver2( const POLICY_HND *handle, - const UNISTR2 *uni_arch, - uint32 level, - DRIVER_INFO *ctr, - uint32 *offered, - uint32 *needed) +static uint32 getprinterdriver2_level1(pstring servername, pstring architecture, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +{ + DRIVER_INFO_1 *info=NULL; + + info=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1)); + + construct_printer_driver_info_1(info, snum, servername, architecture); + + /* check the required size. */ + *needed += spoolss_size_printer_driver_info_1(info); + + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + /* fill the buffer with the structures */ + new_smb_io_printer_driver_info_1("", buffer, info, 0); + + /* clear memory */ + safe_free(info); + + if (*needed > offered) { + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; +} + +/**************************************************************************** +****************************************************************************/ +static uint32 getprinterdriver2_level2(pstring servername, pstring architecture, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +{ + DRIVER_INFO_2 *info=NULL; + + info=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2)); + + construct_printer_driver_info_2(info, snum, servername, architecture); + + /* check the required size. */ + *needed += spoolss_size_printer_driver_info_2(info); + + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + /* fill the buffer with the structures */ + new_smb_io_printer_driver_info_2("", buffer, info, 0); + + /* clear memory */ + safe_free(info); + + if (*needed > offered) { + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; +} + +/**************************************************************************** +****************************************************************************/ +static uint32 getprinterdriver2_level3(pstring servername, pstring architecture, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +{ + DRIVER_INFO_3 *info=NULL; + + info=(DRIVER_INFO_3 *)malloc(sizeof(DRIVER_INFO_3)); + + construct_printer_driver_info_3(info, snum, servername, architecture); + + /* check the required size. */ + *needed += spoolss_size_printer_driver_info_3(info); + + if (!alloc_buffer_size(buffer, *needed)) + 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); + + 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, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *unknown0, uint32 *unknown1) { pstring servername; fstring architecture; int snum; - DRIVER_INFO_1 *info1=NULL; - DRIVER_INFO_2 *info2=NULL; - DRIVER_INFO_3 *info3=NULL; + + DEBUG(4,("_spoolss_getprinterdriver2\n")); + + *needed=0; + *unknown0=0; + *unknown1=0; pstrcpy(servername, global_myname); + unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1); - if (!get_printer_snum(handle,&snum)) + if (!get_printer_snum(handle, &snum)) { return NT_STATUS_INVALID_HANDLE; } - unistr2_to_ascii(architecture, uni_arch, sizeof(architecture) ); - - DEBUG(1,("spoolss_getprinterdriver2:[%d]\n", level)); - - switch (level) - { - case 1: - { - info1=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1)); - construct_printer_driver_info_1(info1, snum, servername, architecture); - ctr->driver.info1=info1; - - return 0x0; - } - case 2: - { - info2=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2)); - construct_printer_driver_info_2(info2, snum, servername, architecture); - ctr->driver.info2=info2; - - return 0x0; - } - case 3: - { - info3=(DRIVER_INFO_3 *)malloc(sizeof(DRIVER_INFO_3)); - construct_printer_driver_info_3(info3, snum, servername, architecture); - ctr->driver.info3=info3; - - return 0x0; - } - default: - { - break; - } + switch (level) { + case 1: + return getprinterdriver2_level1(servername, architecture, snum, buffer, offered, needed); + break; + case 2: + return getprinterdriver2_level2(servername, architecture, snum, buffer, offered, needed); + break; + case 3: + return getprinterdriver2_level3(servername, architecture, snum, buffer, offered, needed); + break; + default: + return NT_STATUS_INVALID_LEVEL; + break; } - return NT_STATUS_INVALID_INFO_CLASS; } /**************************************************************************** @@ -2617,10 +2721,9 @@ uint32 _spoolss_fcpn( const POLICY_HND *handle) /**************************************************************************** ****************************************************************************/ uint32 _spoolss_addjob( const POLICY_HND *handle, uint32 level, - const BUFFER *buffer, - uint32 buf_size) + NEW_BUFFER *buffer, uint32 offered) { - return 0x0; + return NT_STATUS_NO_PROBLEMO; } /**************************************************************************** @@ -3273,7 +3376,7 @@ uint32 _spoolss_enumports( UNISTR2 *name, uint32 level, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) { - DEBUG(4,("spoolss_enumports\n")); + DEBUG(4,("_spoolss_enumports\n")); *returned=0; *needed=0; @@ -3293,30 +3396,23 @@ uint32 _spoolss_enumports( UNISTR2 *name, uint32 level, /**************************************************************************** ****************************************************************************/ -uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_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_level, - const SPOOL_USER_LEVEL *user, + uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3, + uint32 user_switch, const SPOOL_USER_CTR *user, POLICY_HND *handle) { NT_PRINTER_INFO_LEVEL printer; - fstring ascii_name; - fstring server_name; + fstring name; fstring share_name; - UNISTR2 *portname; - SPOOL_PRINTER_INFO_LEVEL_2 *info2; - uint32 status = 0x0; - - if (!open_printer_hnd(handle)) - { - return NT_STATUS_ACCESS_DENIED; - } + 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; @@ -3324,31 +3420,31 @@ uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, /* convert from UNICODE to ASCII */ convert_printer_info(info, &printer, level); - /* write the ASCII on disk */ - status = add_a_printer(printer, level); - if (status != 0x0) - { - close_printer_handle(handle); - return status; - } + unistr2_to_ascii(share_name, &((info->info_2)->portname), sizeof(share_name)-1); + + slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname, share_name); + + create_printer_hnd(handle); - info2=info->info_2; - portname=&(info2->portname); + open_printer_hnd(handle); - StrnCpy(server_name, global_myname, strlen(global_myname) ); - unistr2_to_ascii(share_name, portname, sizeof(share_name)-1); + if (!set_printer_hnd_printertype(handle, name)) { + close_printer_handle(handle); + return NT_STATUS_ACCESS_DENIED; + } - slprintf(ascii_name, sizeof(ascii_name)-1, "\\\\%s\\%s", - server_name, share_name); - - if (!set_printer_hnd_printertype(handle, ascii_name) || - !set_printer_hnd_printername(handle, ascii_name)) - { + if (!set_printer_hnd_printername(handle, name)) { close_printer_handle(handle); return NT_STATUS_ACCESS_DENIED; } - return 0x0; + /* 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; } /**************************************************************************** @@ -3358,35 +3454,77 @@ uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name, const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info) { NT_PRINTER_DRIVER_INFO_LEVEL driver; + convert_printer_driver_info(info, &driver, level); - return add_a_printer_driver(driver, level); + + if (add_a_printer_driver(driver, level)!=0) + return NT_STATUS_ACCESS_DENIED; + + return NT_STATUS_NO_PROBLEMO; } /**************************************************************************** ****************************************************************************/ -uint32 _spoolss_getprinterdriverdirectory( const UNISTR2 *name, - const UNISTR2 *uni_environment, - uint32 level, - DRIVER_DIRECTORY_CTR *ctr, - uint32 *offered) +static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name) +{ + init_unistr(&(info->name), name); +} + +/**************************************************************************** +****************************************************************************/ +static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { pstring chaine; pstring long_archi; - pstring archi; - + pstring short_archi; + DRIVER_DIRECTORY_1 *info=NULL; + + info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1)); + unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1); - get_short_archi(archi, long_archi); + get_short_archi(short_archi, long_archi); - slprintf(chaine,sizeof(chaine)-1,"\\\\%s\\print$\\%s", - global_myname, archi); + slprintf(chaine, sizeof(chaine)-1, "\\\\%s\\print$\\%s", global_myname, short_archi); DEBUG(4,("printer driver directory: [%s]\n", chaine)); - - init_unistr(&(ctr->driver.info_1.name), chaine); - return 0x0; + fill_driverdir_1(info, chaine); + + *needed += spoolss_size_driverdir_info_1(info); + + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + new_smb_io_driverdir_1("", buffer, info, 0); + + safe_free(info); + + if (*needed > offered) + return ERROR_INSUFFICIENT_BUFFER; + else + return NT_STATUS_NO_PROBLEMO; } +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environment, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed) +{ + DEBUG(4,("_spoolss_getprinterdriverdirectory\n")); + + *needed=0; + + switch(level) { + case 1: + return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed); + break; + default: + return NT_STATUS_INVALID_INFO_CLASS; + break; + } +} + /**************************************************************************** ****************************************************************************/ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, @@ -3755,84 +3893,127 @@ uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level, /**************************************************************************** ****************************************************************************/ -uint32 _spoolss_getjob( const POLICY_HND *handle, - uint32 jobid, - uint32 level, - PJOB_INFO *ctr, - uint32 *offered) +static uint32 getjob_level_1(print_queue_struct *queue, int count, int snum, uint32 jobid, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +{ + int i=0; + BOOL found=False; + JOB_INFO_1 *info_1=NULL; + info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1)); + + if (info_1 == NULL) { + safe_free(queue); + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i offered) + return ERROR_INSUFFICIENT_BUFFER; + else + return NT_STATUS_NO_PROBLEMO; +} + + +/**************************************************************************** +****************************************************************************/ +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; + BOOL found=False; + JOB_INFO_2 *info_2=NULL; + info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2)); + + if (info_2 == NULL) { + safe_free(queue); + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i offered) + return ERROR_INSUFFICIENT_BUFFER; + else + return NT_STATUS_NO_PROBLEMO; +} + +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_getjob( POLICY_HND *handle, uint32 jobid, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed) { int snum; int count; - int i; print_queue_struct *queue=NULL; print_status_struct prt_status; - DEBUG(4,("spoolss_getjob\n")); + DEBUG(5,("spoolss_getjob\n")); - bzero(&prt_status,sizeof(prt_status)); + bzero(&prt_status, sizeof(prt_status)); + *needed=0; + if (!get_printer_snum(handle, &snum)) { return NT_STATUS_INVALID_HANDLE; } + count=get_printqueue(snum, NULL, &queue, &prt_status); DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n", count, prt_status.status, prt_status.message)); - - switch (level) - { - case 1: - { - JOB_INFO_1 *job_info_1=NULL; - job_info_1=(JOB_INFO_1 *)malloc(sizeof(JOB_INFO_1)); - - if (job_info_1 == NULL) - { - safe_free(queue); - return NT_STATUS_NO_MEMORY; - } - - for (i=0; ijob.job_info_1=job_info_1; - break; - } - case 2: - { - JOB_INFO_2 *job_info_2=NULL; - job_info_2=(JOB_INFO_2 *)malloc(sizeof(JOB_INFO_2)); - - if (job_info_2 == NULL) - { - safe_free(queue); - return NT_STATUS_NO_MEMORY; - } - - for (i=0; ijob.job_info_2=job_info_2; - break; - } - default: - { - safe_free(queue); - return NT_STATUS_INVALID_INFO_CLASS; - } + + switch (level) { + case 1: + return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed); + break; + case 2: + return getjob_level_1(queue, count, snum, jobid, buffer, offered, needed); + break; + default: + safe_free(queue); + return NT_STATUS_INVALID_INFO_CLASS; + break; } - - safe_free(queue); - return 0x0; } + -- cgit From 89aa4d8ca9cc9e8e6dd4566076c0cace8b82d838 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 21 Feb 2000 18:47:21 +0000 Subject: Fix for crash bug from Paul Tyler . Jeremy. --- source/lib/snprintf.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/source/lib/snprintf.c b/source/lib/snprintf.c index 54095985485..70ce95916fc 100644 --- a/source/lib/snprintf.c +++ b/source/lib/snprintf.c @@ -694,8 +694,7 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, if ( r_length < dec_pt ) dec_pt = r_length; - if (dec_pt <= 0) - { + if (dec_pt <= 0) { iplace = 1; iconvert[0] = '0'; iconvert[1] = '\0'; @@ -705,22 +704,24 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, while(r_length) fconvert[fplace++] = result[--r_length]; - while(dec_pt < 0) - fconvert[fplace++] = '0'; - } - else - { + while ((dec_pt < 0) && (fplace < max)) { + fconvert[fplace++] = '0'; + dec_pt++; + } + } else { int c; iplace=0; - for(c=dec_pt; c; iconvert[iplace++] = result[--c]); + for(c=dec_pt; c; iconvert[iplace++] = result[--c]) + ; iconvert[iplace] = '\0'; result += dec_pt; fplace = 0; - for(c=(r_length-dec_pt); c; fconvert[fplace++] = result[--c]); - } + for(c=(r_length-dec_pt); c; fconvert[fplace++] = result[--c]) + ; + } #endif /* fcvt */ /* -1 for decimal point, another -1 if we are printing a sign */ -- cgit From 27ef1789267c7af70071ac9b1d216b4dd745578a Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 22 Feb 2000 21:00:01 +0000 Subject: richard got the short request for GETDC right (hooray!) win9x _and_ nt now work. --- source/nmbd/nmbd_processlogon.c | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/source/nmbd/nmbd_processlogon.c b/source/nmbd/nmbd_processlogon.c index 279ab1c764f..e13dff8302b 100644 --- a/source/nmbd/nmbd_processlogon.c +++ b/source/nmbd/nmbd_processlogon.c @@ -44,10 +44,11 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len, pstring outbuf; int code; uint16 token = 0; - uint32 ntversion; - uint16 lmnttoken; - uint16 lm20token; + uint32 ntversion = 0; + uint16 lmnttoken = 0; + uint16 lm20token = 0; uint32 domainsidsize; + BOOL short_request = 0; char *getdc; char *uniuser; /* Unicode user name. */ pstring ascuser; @@ -120,12 +121,21 @@ logons are not enabled.\n", inet_ntoa(p->ip) )); q = skip_unicode_string(q, 1); - ntversion = IVAL(q, 0); - q += 4; - lmnttoken = SVAL(q, 0); - q += 2; - lm20token = SVAL(q, 0); - q += 2; + if ((buf - q) >= len) { /* Check for a short request */ + + short_request = 1; + + } + else { /* A full length request */ + + ntversion = IVAL(q, 0); + q += 4; + lmnttoken = SVAL(q, 0); + q += 2; + lm20token = SVAL(q, 0); + q += 2; + + } /* Construct reply. */ @@ -135,10 +145,11 @@ logons are not enabled.\n", inet_ntoa(p->ip) )); fstrcpy(reply_name,my_name); fstrcpy(q, reply_name); - q = skip_string(q, 1); /* PDC name */ - if (strcmp(mailslot, NT_LOGON_MAILSLOT)==0) { + /* PDC and domain name */ + if (!short_request) /* Make a full reply */ + { q = align2(q, buf); dos_PutUniCode(q, my_name, sizeof(pstring)); /* PDC name */ @@ -155,6 +166,8 @@ logons are not enabled.\n", inet_ntoa(p->ip) )); q += 2; } + /* RJS, 21-Feb-2000, we send a short reply if the request was short */ + DEBUG(3,("process_logon_packet: GETDC request from %s at IP %s, \ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", machine,inet_ntoa(p->ip), reply_name, lp_workgroup(), -- cgit From 9f879ec396230deba34fbe5e82d8a65f92137c54 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Feb 2000 02:02:33 +0000 Subject: lib/system.c: Fixed gcc warnings. nmbd/nmbd_processlogon.c: Use "True" and "False" instead of 1 and 0. Others - preparing for multiple pdu write code. Jeremy. --- source/include/ntdomain.h | 66 +++++++++++++++++++++++++++++++--------- source/include/proto.h | 2 +- source/lib/system.c | 1 - source/libsmb/clientgen.c | 4 +-- source/nmbd/nmbd_processlogon.c | 4 +-- source/rpc_server/srv_pipe_hnd.c | 46 ++++++++++++++-------------- source/rpc_server/srv_pipe_srv.c | 40 ++++++++++++------------ source/smbd/ipc.c | 2 +- 8 files changed, 101 insertions(+), 64 deletions(-) diff --git a/source/include/ntdomain.h b/source/include/ntdomain.h index c1b966aa592..7f3d4b49503 100644 --- a/source/include/ntdomain.h +++ b/source/include/ntdomain.h @@ -63,6 +63,52 @@ typedef struct _prs_struct #define MARSHALLING(ps) (!(ps)->io) #define UNMARSHALLING(ps) ((ps)->io) +typedef struct _input_data { + /* + * This is the current incoming pdu. The data here + * is collected via multiple writes until a complete + * pdu is seen, then the data is copied into the in_data + * structure. The maximum size of this is 64k (2 byte length). + */ + prs_struct in_pdu; + + /* + * The amount of data needed to complete the in_pdu. + * If this is zero, then we are at the start of a new + * pdu. + */ + uint32 in_pdu_needed_len; + + /* + * This is the collection of input data with all + * the rpc headers and auth footers removed. + * The maximum length of this is strictly enforced. + */ + prs_struct in_data; +} input_data; + +typedef struct _output_data { + /* + * Raw RPC output data. This does not include RPC headers or footers. + */ + prs_struct rdata; + + /* The amount of data sent from the current rdata struct. */ + uint32 data_sent_length; + + /* + * The current PDU being returned. This inclues + * headers, data and authentication footer. + */ + unsigned char current_pdu[MAX_PDU_FRAG_LEN]; + + /* The amount of data in the current_pdu buffer. */ + uint32 current_pdu_len; + + /* The amount of data sent from the current PDU. */ + uint32 current_pdu_sent; +} output_data; + typedef struct pipes_struct { struct pipes_struct *next, *prev; @@ -99,25 +145,17 @@ typedef struct pipes_struct uid_t uid; gid_t gid; - /* - * Raw RPC output data. This does not include RPC headers or footers. + /* + * Struct to deal with multiple pdu inputs. */ - prs_struct rdata; - /* The amount of data sent from the current rdata struct. */ - uint32 data_sent_length; + input_data in_data; - /* - * The current PDU being returned. This inclues - * headers, data and authentication footer. + /* + * Struct to deal with multiple pdu outputs. */ - unsigned char current_pdu[MAX_PDU_FRAG_LEN]; - /* The amount of data in the current_pdu buffer. */ - uint32 current_pdu_len; - - /* The amount of data sent from the current PDU. */ - uint32 current_pdu_sent; + output_data out_data; /* When replying to an SMBtrans, this is the maximum amount of data that can be sent in the initial reply. */ diff --git a/source/include/proto.h b/source/include/proto.h index ee0de29eb63..837eb27eda0 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -2577,7 +2577,7 @@ int read_pipe(pipes_struct *p, char *data, int n); void set_pipe_handle_offset(int max_open_files); void reset_chain_p(void); void init_rpc_pipe_hnd(void); -BOOL pipe_init_outgoing_data( pipes_struct *p); +BOOL pipe_init_outgoing_data(output_data *out_data); pipes_struct *open_rpc_pipe_p(char *pipe_name, connection_struct *conn, uint16 vuid); ssize_t write_to_pipe(pipes_struct *p, char *data, size_t n); diff --git a/source/lib/system.c b/source/lib/system.c index 25925b6d8ec..9ef0af494f3 100644 --- a/source/lib/system.c +++ b/source/lib/system.c @@ -968,7 +968,6 @@ FILE *sys_popen(const char *command, const char *mode) int parent_end, child_end; int pipe_fds[2]; popen_list *entry = NULL; - pid_t child_pid; char **argl = NULL; if (pipe(pipe_fds) < 0) diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c index 32148a4e124..df3df0b4ba3 100644 --- a/source/libsmb/clientgen.c +++ b/source/libsmb/clientgen.c @@ -3260,8 +3260,8 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char * The name used was *SMBSERVER, don't bother with another name. */ - DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name %s \ -with error %s.\n", desthost, "*SMBSERVER", cli_errstr(cli) )); + DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ +with error %s.\n", desthost, cli_errstr(cli) )); cli_shutdown(cli); return False; } diff --git a/source/nmbd/nmbd_processlogon.c b/source/nmbd/nmbd_processlogon.c index e13dff8302b..d3b7f92fc78 100644 --- a/source/nmbd/nmbd_processlogon.c +++ b/source/nmbd/nmbd_processlogon.c @@ -48,7 +48,7 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len, uint16 lmnttoken = 0; uint16 lm20token = 0; uint32 domainsidsize; - BOOL short_request = 0; + BOOL short_request = False; char *getdc; char *uniuser; /* Unicode user name. */ pstring ascuser; @@ -123,7 +123,7 @@ logons are not enabled.\n", inet_ntoa(p->ip) )); if ((buf - q) >= len) { /* Check for a short request */ - short_request = 1; + short_request = True; } else { /* A full length request */ diff --git a/source/rpc_server/srv_pipe_hnd.c b/source/rpc_server/srv_pipe_hnd.c index b8e7c1946a7..32a804d5d58 100644 --- a/source/rpc_server/srv_pipe_hnd.c +++ b/source/rpc_server/srv_pipe_hnd.c @@ -78,27 +78,27 @@ void init_rpc_pipe_hnd(void) Initialise an outgoing packet. ****************************************************************************/ -BOOL pipe_init_outgoing_data( pipes_struct *p) +BOOL pipe_init_outgoing_data(output_data *out_data) { - memset(p->current_pdu, '\0', sizeof(p->current_pdu)); + memset(out_data->current_pdu, '\0', sizeof(out_data->current_pdu)); /* Free any memory in the current return data buffer. */ - prs_mem_free(&p->rdata); + prs_mem_free(&out_data->rdata); /* * Initialize the outgoing RPC data buffer. * we will use this as the raw data area for replying to rpc requests. */ - if(!prs_init(&p->rdata, 1024, 4, MARSHALL)) { + if(!prs_init(&out_data->rdata, 1024, 4, MARSHALL)) { DEBUG(0,("pipe_init_outgoing_data: malloc fail.\n")); return False; } /* Reset the offset counters. */ - p->data_sent_length = 0; - p->current_pdu_len = 0; - p->current_pdu_sent = 0; + out_data->data_sent_length = 0; + out_data->current_pdu_len = 0; + out_data->current_pdu_sent = 0; return True; } @@ -188,7 +188,7 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name, /* * Initialize the RPC and PDU data buffers with no memory. */ - prs_init(&p->rdata, 0, 4, MARSHALL); + prs_init(&p->out_data.rdata, 0, 4, MARSHALL); DLIST_ADD(Pipes, p); @@ -213,9 +213,9 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name, p->ntlmssp_auth_validated = False; p->ntlmssp_auth_requested = False; - p->current_pdu_len = 0; - p->current_pdu_sent = 0; - p->data_sent_length = 0; + p->out_data.current_pdu_len = 0; + p->out_data.current_pdu_sent = 0; + p->out_data.data_sent_length = 0; p->uid = (uid_t)-1; p->gid = (gid_t)-1; @@ -303,15 +303,15 @@ only service %d sized reads.\n", n, p->name, MAX_PDU_FRAG_LEN )); * PDU. */ - if((pdu_remaining = p->current_pdu_len - p->current_pdu_sent) > 0) { + if((pdu_remaining = p->out_data.current_pdu_len - p->out_data.current_pdu_sent) > 0) { data_returned = MIN(n, pdu_remaining); DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, current_pdu_sent = %u \ -returning %d bytes.\n", p->name, (unsigned int)p->current_pdu_len, - (unsigned int)p->current_pdu_sent, (int)data_returned)); +returning %d bytes.\n", p->name, (unsigned int)p->out_data.current_pdu_len, + (unsigned int)p->out_data.current_pdu_sent, (int)data_returned)); - memcpy( data, &p->current_pdu[p->current_pdu_sent], (size_t)data_returned); - p->current_pdu_sent += (uint32)data_returned; + memcpy( data, &p->out_data.current_pdu[p->out_data.current_pdu_sent], (size_t)data_returned); + p->out_data.current_pdu_sent += (uint32)data_returned; return data_returned; } @@ -320,10 +320,10 @@ returning %d bytes.\n", p->name, (unsigned int)p->current_pdu_len, * may of course be zero if this is the first return fragment. */ - DEBUG(10,("read_from_pipe: %s: data_sent_length = %u, prs_offset(&p->rdata) = %u.\n", - p->name, (unsigned int)p->data_sent_length, (unsigned int)prs_offset(&p->rdata) )); + DEBUG(10,("read_from_pipe: %s: data_sent_length = %u, prs_offset(&p->out_data.rdata) = %u.\n", + p->name, (unsigned int)p->out_data.data_sent_length, (unsigned int)prs_offset(&p->out_data.rdata) )); - if(p->data_sent_length >= prs_offset(&p->rdata)) { + if(p->out_data.data_sent_length >= prs_offset(&p->out_data.rdata)) { /* * We have sent all possible data. Return 0. */ @@ -343,10 +343,10 @@ returning %d bytes.\n", p->name, (unsigned int)p->current_pdu_len, return -1; } - data_returned = MIN(n, p->current_pdu_len); + data_returned = MIN(n, p->out_data.current_pdu_len); - memcpy( data, p->current_pdu, (size_t)data_returned); - p->current_pdu_sent += (uint32)data_returned; + memcpy( data, p->out_data.current_pdu, (size_t)data_returned); + p->out_data.current_pdu_sent += (uint32)data_returned; return data_returned; } @@ -409,7 +409,7 @@ BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn) return False; } - prs_mem_free(&p->rdata); + prs_mem_free(&p->out_data.rdata); bitmap_clear(bmap, p->pnum - pipe_handle_offset); diff --git a/source/rpc_server/srv_pipe_srv.c b/source/rpc_server/srv_pipe_srv.c index 6e8b3067600..86cc9e47e64 100644 --- a/source/rpc_server/srv_pipe_srv.c +++ b/source/rpc_server/srv_pipe_srv.c @@ -94,7 +94,7 @@ BOOL create_next_pdu(pipes_struct *p) p->hdr.pkt_type = RPC_RESPONSE; /* Set up rpc header flags. */ - if (p->data_sent_length == 0) + if (p->out_data.data_sent_length == 0) p->hdr.flags = RPC_FLG_FIRST; else p->hdr.flags = 0; @@ -103,7 +103,7 @@ BOOL create_next_pdu(pipes_struct *p) * Work out how much we can fit in a sigle PDU. */ - data_space_available = sizeof(p->current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN; + data_space_available = sizeof(p->out_data.current_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN; if(p->ntlmssp_auth_validated) data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN); @@ -112,7 +112,7 @@ BOOL create_next_pdu(pipes_struct *p) * space and the amount left to send. */ - data_len_left = prs_offset(&p->rdata) - p->data_sent_length; + data_len_left = prs_offset(&p->out_data.rdata) - p->out_data.data_sent_length; /* * Ensure there really is data left to send. @@ -149,7 +149,7 @@ BOOL create_next_pdu(pipes_struct *p) * Work out if this PDU will be the last. */ - if(p->data_sent_length + data_len >= prs_offset(&p->rdata)) + if(p->out_data.data_sent_length + data_len >= prs_offset(&p->out_data.rdata)) p->hdr.flags |= RPC_FLG_LAST; /* @@ -158,7 +158,7 @@ BOOL create_next_pdu(pipes_struct *p) */ prs_init( &outgoing_pdu, 0, 4, MARSHALL); - prs_give_memory( &outgoing_pdu, (char *)p->current_pdu, sizeof(p->current_pdu), False); + prs_give_memory( &outgoing_pdu, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); /* Store the header in the data stream. */ if(!smb_io_rpc_hdr("hdr", &p->hdr, &outgoing_pdu, 0)) { @@ -175,7 +175,7 @@ BOOL create_next_pdu(pipes_struct *p) data_pos = prs_offset(&outgoing_pdu); /* Copy the data into the PDU. */ - data_from = prs_data_p(&p->rdata) + p->data_sent_length; + data_from = prs_data_p(&p->out_data.rdata) + p->out_data.data_sent_length; if(!prs_append_data(&outgoing_pdu, data_from, data_len)) { DEBUG(0,("create_next_pdu: failed to copy %u bytes of data.\n", (unsigned int)data_len)); @@ -230,9 +230,9 @@ BOOL create_next_pdu(pipes_struct *p) * Setup the counts for this PDU. */ - p->data_sent_length += data_len; - p->current_pdu_len = p->hdr.frag_len; - p->current_pdu_sent = 0; + p->out_data.data_sent_length += data_len; + p->out_data.current_pdu_len = p->hdr.frag_len; + p->out_data.current_pdu_sent = 0; return True; } @@ -549,7 +549,7 @@ static BOOL setup_bind_nak(pipes_struct *p, prs_struct *pd) */ prs_init( &outgoing_rpc, 0, 4, MARSHALL); - prs_give_memory( &outgoing_rpc, (char *)p->current_pdu, sizeof(p->current_pdu), False); + prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); /* @@ -575,9 +575,9 @@ static BOOL setup_bind_nak(pipes_struct *p, prs_struct *pd) if(!prs_uint16("reject code", &outgoing_rpc, 0, &zero)) return False; - p->data_sent_length = 0; - p->current_pdu_len = prs_offset(&outgoing_rpc); - p->current_pdu_sent = 0; + p->out_data.data_sent_length = 0; + p->out_data.current_pdu_len = prs_offset(&outgoing_rpc); + p->out_data.current_pdu_sent = 0; return True; } @@ -710,7 +710,7 @@ static BOOL api_pipe_bind_and_alt_req(pipes_struct *p, prs_struct *pd, enum RPC_ */ prs_init( &outgoing_rpc, 0, 4, MARSHALL); - prs_give_memory( &outgoing_rpc, (char *)p->current_pdu, sizeof(p->current_pdu), False); + prs_give_memory( &outgoing_rpc, (char *)p->out_data.current_pdu, sizeof(p->out_data.current_pdu), False); /* * Setup the memory to marshall the ba header, and the @@ -828,9 +828,9 @@ static BOOL api_pipe_bind_and_alt_req(pipes_struct *p, prs_struct *pd, enum RPC_ * Setup the lengths for the initial reply. */ - p->data_sent_length = 0; - p->current_pdu_len = prs_offset(&outgoing_rpc); - p->current_pdu_sent = 0; + p->out_data.data_sent_length = 0; + p->out_data.current_pdu_len = prs_offset(&outgoing_rpc); + p->out_data.current_pdu_sent = 0; prs_mem_free(&out_hdr_ba); prs_mem_free(&out_auth); @@ -1038,7 +1038,7 @@ BOOL rpc_command(pipes_struct *p, char *input_data, int data_len) * Create the response data buffer. */ - if(!pipe_init_outgoing_data(p)) { + if(!pipe_init_outgoing_data(&p->out_data)) { DEBUG(0,("rpc_command: failed to unmarshall RPC_HDR.\n")); return False; } @@ -1104,9 +1104,9 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds } /* do the actual command */ - if(!api_rpc_cmds[fn_num].fn(p->vuid, rpc_in, &p->rdata)) { + if(!api_rpc_cmds[fn_num].fn(p->vuid, rpc_in, &p->out_data.rdata)) { DEBUG(0,("api_rpcTNP: %s: failed.\n", rpc_name)); - prs_mem_free(&p->rdata); + prs_mem_free(&p->out_data.rdata); return False; } diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c index b5a6e4ba902..5ee70e7d949 100644 --- a/source/smbd/ipc.c +++ b/source/smbd/ipc.c @@ -3225,7 +3225,7 @@ static BOOL api_rpc_trans_reply(char *outbuf, pipes_struct *p, return False; } - send_trans_reply(outbuf, NULL, 0, rdata, data_len, (int)prs_offset(&p->rdata) > data_len); + send_trans_reply(outbuf, NULL, 0, rdata, data_len, (int)prs_offset(&p->out_data.rdata) > data_len); free(rdata); return True; -- cgit From 693a582c23599bbdd45adb30401b1162e44fd274 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Feb 2000 22:29:27 +0000 Subject: Multiple-dot scope handling fix from Greg Bowering gb@pobox.com Jeremy. --- source/libsmb/nmblib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/libsmb/nmblib.c b/source/libsmb/nmblib.c index b83081d7f0d..7b62ca45461 100644 --- a/source/libsmb/nmblib.c +++ b/source/libsmb/nmblib.c @@ -301,8 +301,8 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) p = &buf[offset+1]; while ((p = strchr(p,'.'))) { - buf[offset] = PTR_DIFF(p,&buf[offset]); - offset += buf[offset]; + buf[offset] = PTR_DIFF(p,&buf[offset+1]); + offset += (buf[offset] + 1); p = &buf[offset+1]; } buf[offset] = strlen(&buf[offset+1]); -- cgit From aa9054d14bc940f251639ab897d9f356814f5fc0 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Thu, 24 Feb 2000 16:27:06 +0000 Subject: converted a couple of bzero() to memset() rewrote the printer notify code, so now it's compatible with SP5 and fully dynamic. No more limits on printers and job lists. removed the make_xxx() functions as they are not used and broken fixed a bug in the open handle function. J.F. --- source/include/proto.h | 46 +--- source/include/rpc_spoolss.h | 96 ++++++-- source/rpc_parse/parse_spoolss.c | 344 ++++++++++++--------------- source/rpc_server/srv_spoolss.c | 11 +- source/rpc_server/srv_spoolss_nt.c | 469 +++++++++++++++++++++---------------- 5 files changed, 504 insertions(+), 462 deletions(-) diff --git a/source/include/proto.h b/source/include/proto.h index 837eb27eda0..934ec5a4c82 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -2301,11 +2301,6 @@ BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth 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, - const char *printername, - uint32 cbbuf, uint32 devmod, uint32 des_access, - const char *station, - const char *username); 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, @@ -2327,15 +2322,10 @@ BOOL spoolss_io_q_endpageprinter(char *desc, SPOOL_Q_ENDPAGEPRINTER *q_u, prs_st BOOL spoolss_io_r_endpageprinter(char *desc, SPOOL_R_ENDPAGEPRINTER *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_writeprinter(char *desc, SPOOL_Q_WRITEPRINTER *q_u, prs_struct *ps, int depth); BOOL spoolss_io_r_writeprinter(char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct *ps, int depth); -BOOL spoolss_io_q_rffpcnex(char *desc, SPOOL_Q_RFFPCNEX *q_u, - prs_struct *ps, int depth); -BOOL spoolss_io_r_rffpcnex(char *desc, SPOOL_R_RFFPCNEX *r_u, - prs_struct *ps, int depth); -BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u, - prs_struct *ps, int depth); -BOOL spoolss_io_r_rfnpcnex(char *desc, - SPOOL_R_RFNPCNEX *r_u, - prs_struct *ps, int depth); +BOOL spoolss_io_q_rffpcnex(char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_rffpcnex(char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_rfnpcnex(char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth); BOOL new_smb_io_printer_info_0(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_0 *info, int depth); BOOL new_smb_io_printer_info_1(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info, int depth); BOOL new_smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth); @@ -2372,18 +2362,9 @@ uint32 spoolss_size_printmonitor_info_1(PRINTMONITOR_1 *info); uint32 spoolss_size_printmonitor_info_2(PRINTMONITOR_2 *info); 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, - const char* servername, - uint32 level, - uint32 size); BOOL spoolss_io_q_enumprinters(char *desc, SPOOL_Q_ENUMPRINTERS *q_u, prs_struct *ps, int depth); 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 make_spoolss_q_getprinter(SPOOL_Q_GETPRINTER *q_u, - POLICY_HND *hnd, - uint32 level, - uint32 buf_size); BOOL spoolss_io_q_getprinter(char *desc, SPOOL_Q_GETPRINTER *q_u, prs_struct *ps, int depth); 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); @@ -2621,16 +2602,11 @@ uint32 _spoolss_getprinterdata(const POLICY_HND *handle, UNISTR2 *valuename, uint32 *out_size, uint8 **data, uint32 *needed); -uint32 _spoolss_rffpcnex(const POLICY_HND *handle, - uint32 flags, uint32 options, - const UNISTR2 *localmachine, - uint32 printerlocal, - SPOOL_NOTIFY_OPTION *option); -uint32 _spoolss_rfnpcnex( const POLICY_HND *handle, - uint32 change, - const SPOOL_NOTIFY_OPTION *option, - uint32 *count, - SPOOL_NOTIFY_INFO *info); +uint32 _spoolss_rffpcnex(const POLICY_HND *handle, uint32 flags, uint32 options, + const UNISTR2 *localmachine, uint32 printerlocal, + SPOOL_NOTIFY_OPTION *option); +uint32 _spoolss_rfnpcnex( const POLICY_HND *handle, uint32 change, + SPOOL_NOTIFY_OPTION *option, SPOOL_NOTIFY_INFO *info); uint32 _spoolss_enumprinters( uint32 flags, const UNISTR2 *servername, uint32 level, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned); @@ -2655,8 +2631,8 @@ uint32 _spoolss_setprinter( const POLICY_HND *handle, uint32 sec_buf_size, const char *sec_buf, uint32 command); -uint32 _spoolss_fcpn( const POLICY_HND *handle); -uint32 _spoolss_addjob( const POLICY_HND *handle, uint32 level, +uint32 _spoolss_fcpn(const POLICY_HND *handle); +uint32 _spoolss_addjob(const POLICY_HND *handle, uint32 level, NEW_BUFFER *buffer, uint32 offered); uint32 _spoolss_enumjobs( POLICY_HND *handle, uint32 firstjob, uint32 numofjobs, uint32 level, NEW_BUFFER *buffer, uint32 offered, diff --git a/source/include/rpc_spoolss.h b/source/include/rpc_spoolss.h index 1556c56686b..19b6c2845ce 100755 --- a/source/include/rpc_spoolss.h +++ b/source/include/rpc_spoolss.h @@ -185,6 +185,9 @@ #define JOB_NOTIFY_TYPE 0x01 #define MAX_PRINTER_NOTIFY 26 +#define MAX_JOB_NOTIFY 24 + +#define MAX_NOTIFY_TYPE_FOR_NOW 26 #define PRINTER_NOTIFY_SERVER_NAME 0x00 #define PRINTER_NOTIFY_PRINTER_NAME 0x01 @@ -213,8 +216,6 @@ #define PRINTER_NOTIFY_TOTAL_BYTES 0x18 #define PRINTER_NOTIFY_BYTES_PRINTED 0x19 -#define MAX_JOB_NOTIFY 24 - #define JOB_NOTIFY_PRINTER_NAME 0x00 #define JOB_NOTIFY_MACHINE_NAME 0x01 #define JOB_NOTIFY_PORT_NAME 0x02 @@ -240,6 +241,57 @@ #define JOB_NOTIFY_TOTAL_BYTES 0x16 #define JOB_NOTIFY_BYTES_PRINTED 0x17 +#define PRINTER_CHANGE_ADD_PRINTER 0x00000001 +#define PRINTER_CHANGE_SET_PRINTER 0x00000002 +#define PRINTER_CHANGE_DELETE_PRINTER 0x00000004 +#define PRINTER_CHANGE_FAILED_CONNECTION_PRINTER 0x00000008 +#define PRINTER_CHANGE_PRINTER (PRINTER_CHANGE_ADD_PRINTER | \ + PRINTER_CHANGE_SET_PRINTER | \ + PRINTER_CHANGE_DELETE_PRINTER | \ + PRINTER_CHANGE_FAILED_CONNECTION_PRINTER ) + +#define PRINTER_CHANGE_ADD_JOB 0x00000100 +#define PRINTER_CHANGE_SET_JOB 0x00000200 +#define PRINTER_CHANGE_DELETE_JOB 0x00000400 +#define PRINTER_CHANGE_WRITE_JOB 0x00000800 +#define PRINTER_CHANGE_JOB (PRINTER_CHANGE_ADD_JOB | \ + PRINTER_CHANGE_SET_JOB | \ + PRINTER_CHANGE_DELETE_JOB | \ + PRINTER_CHANGE_WRITE_JOB ) + +#define PRINTER_CHANGE_ADD_FORM 0x00010000 +#define PRINTER_CHANGE_SET_FORM 0x00020000 +#define PRINTER_CHANGE_DELETE_FORM 0x00040000 +#define PRINTER_CHANGE_FORM (PRINTER_CHANGE_ADD_FORM | \ + PRINTER_CHANGE_SET_FORM | \ + PRINTER_CHANGE_DELETE_FORM ) + +#define PRINTER_CHANGE_ADD_PORT 0x00100000 +#define PRINTER_CHANGE_CONFIGURE_PORT 0x00200000 +#define PRINTER_CHANGE_DELETE_PORT 0x00400000 +#define PRINTER_CHANGE_PORT (PRINTER_CHANGE_ADD_PORT | \ + PRINTER_CHANGE_CONFIGURE_PORT | \ + PRINTER_CHANGE_DELETE_PORT ) + +#define PRINTER_CHANGE_ADD_PRINT_PROCESSOR 0x01000000 +#define PRINTER_CHANGE_DELETE_PRINT_PROCESSOR 0x04000000 +#define PRINTER_CHANGE_PRINT_PROCESSOR (PRINTER_CHANGE_ADD_PRINT_PROCESSOR | \ + PRINTER_CHANGE_DELETE_PRINT_PROCESSOR ) + +#define PRINTER_CHANGE_ADD_PRINTER_DRIVER 0x10000000 +#define PRINTER_CHANGE_SET_PRINTER_DRIVER 0x20000000 +#define PRINTER_CHANGE_DELETE_PRINTER_DRIVER 0x40000000 +#define PRINTER_CHANGE_PRINTER_DRIVER (PRINTER_CHANGE_ADD_PRINTER_DRIVER | \ + PRINTER_CHANGE_SET_PRINTER_DRIVER | \ + PRINTER_CHANGE_DELETE_PRINTER_DRIVER ) + +#define PRINTER_CHANGE_TIMEOUT 0x80000000 +#define PRINTER_CHANGE_ALL (PRINTER_CHANGE_JOB | \ + PRINTER_CHANGE_FORM | \ + PRINTER_CHANGE_PORT | \ + PRINTER_CHANGE_PRINT_PROCESSOR | \ + PRINTER_CHANGE_PRINTER_DRIVER ) + /* * The printer attributes. * I #defined all of them (grabbed form MSDN) @@ -396,9 +448,18 @@ typedef struct spool_notify_option_type uint32 reserved1; uint32 reserved2; uint32 count; - uint16 fields[16]; + uint32 fields_ptr; + uint32 count2; + uint16 fields[MAX_NOTIFY_TYPE_FOR_NOW]; } SPOOL_NOTIFY_OPTION_TYPE; +typedef struct spool_notify_option_type_ctr +{ + uint32 count; + SPOOL_NOTIFY_OPTION_TYPE *type; +} SPOOL_NOTIFY_OPTION_TYPE_CTR; + + typedef struct s_header_type { @@ -410,15 +471,6 @@ typedef struct s_header_type } data; } HEADER_TYPE; -/*typedef struct s_buffer -{ - uint32 ptr; - uint32 size; - uint32 count; - uint8 *data; - HEADER_TYPE *header; -} BUFFER; -*/ typedef struct new_buffer { uint32 ptr; @@ -536,9 +588,10 @@ typedef struct spool_r_writeprinter typedef struct spool_notify_option { uint32 version; - uint32 reserved; + uint32 flags; uint32 count; - SPOOL_NOTIFY_OPTION_TYPE type[16]; /* totally arbitrary !!! */ + uint32 option_type_ptr; + SPOOL_NOTIFY_OPTION_TYPE_CTR ctr; } SPOOL_NOTIFY_OPTION; typedef struct spool_notify_info_data @@ -565,10 +618,7 @@ typedef struct spool_notify_info uint32 version; uint32 flags; uint32 count; - SPOOL_NOTIFY_INFO_DATA data[26*16]; - /* 26 differents data types */ - /* so size it for 16 printers at max */ - /* jfmxxxx: Have to make it dynamic !!!*/ + SPOOL_NOTIFY_INFO_DATA *data; } SPOOL_NOTIFY_INFO; /* If the struct name looks obscure, yes it is ! */ @@ -578,9 +628,11 @@ typedef struct spoolss_q_rffpcnex POLICY_HND handle; uint32 flags; uint32 options; + uint32 localmachine_ptr; UNISTR2 localmachine; uint32 printerlocal; - SPOOL_NOTIFY_OPTION option; + uint32 option_ptr; + SPOOL_NOTIFY_OPTION *option; } SPOOL_Q_RFFPCNEX; typedef struct spool_r_rffpcnex @@ -593,15 +645,15 @@ typedef struct spool_q_rfnpcnex { POLICY_HND handle; uint32 change; - SPOOL_NOTIFY_OPTION option; + uint32 option_ptr; + SPOOL_NOTIFY_OPTION *option; } SPOOL_Q_RFNPCNEX; typedef struct spool_r_rfnpcnex { - uint32 count; + uint32 info_ptr; SPOOL_NOTIFY_INFO info; uint32 status; - } SPOOL_R_RFNPCNEX; /* Find Close Printer Notify */ diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c index 796466337f8..0979799a98b 100644 --- a/source/rpc_parse/parse_spoolss.c +++ b/source/rpc_parse/parse_spoolss.c @@ -179,24 +179,26 @@ static BOOL smb_io_doc_info_container(char *desc, DOC_INFO_CONTAINER *cont, prs_ /******************************************************************* reads or writes an NOTIFY OPTION TYPE structure. ********************************************************************/ -static BOOL smb_io_notify_option_type(char *desc, - SPOOL_NOTIFY_OPTION_TYPE *type, - prs_struct *ps, int depth) +static BOOL smb_io_notify_option_type(char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth) { - uint32 useless_ptr; - prs_debug(ps, depth, desc, "smb_io_notify_option_type"); depth++; - prs_align(ps); - - prs_uint16("type", ps, depth, &(type->type)); - prs_uint16("reserved0", ps, depth, &(type->reserved0)); - prs_uint32("reserved1", ps, depth, &(type->reserved1)); - prs_uint32("reserved2", ps, depth, &(type->reserved2)); - prs_uint32("count", ps, depth, &(type->count)); - prs_uint32("useless ptr", ps, depth, &useless_ptr); + if (!prs_align(ps)) + return False; + if(!prs_uint16("type", ps, depth, &type->type)) + return False; + if(!prs_uint16("reserved0", ps, depth, &type->reserved0)) + return False; + if(!prs_uint32("reserved1", ps, depth, &type->reserved1)) + return False; + if(!prs_uint32("reserved2", ps, depth, &type->reserved2)) + return False; + if(!prs_uint32("count", ps, depth, &type->count)) + return False; + if(!prs_uint32("fields_ptr", ps, depth, &type->fields_ptr)) + return False; return True; } @@ -204,79 +206,97 @@ static BOOL smb_io_notify_option_type(char *desc, /******************************************************************* reads or writes an NOTIFY OPTION TYPE DATA. ********************************************************************/ -static BOOL smb_io_notify_option_type_data(char *desc, - SPOOL_NOTIFY_OPTION_TYPE *type, - prs_struct *ps, int depth) +static BOOL smb_io_notify_option_type_data(char *desc, SPOOL_NOTIFY_OPTION_TYPE *type, prs_struct *ps, int depth) { - uint32 count; int i; prs_debug(ps, depth, desc, "smb_io_notify_option_type_data"); depth++; - prs_align(ps); + /* if there are no fields just return */ + if (type->fields_ptr==0) + return True; + + if(!prs_align(ps)) + return False; - prs_uint32("count", ps, depth, &count); + if(!prs_uint32("count2", ps, depth, &type->count2)) + return False; - if (count != type->count) - { - DEBUG(4,("What a mess, count was %x now is %x !\n",type->count,count)); - type->count=count; - } - for(i=0;ifields[i])); - } + if (type->count2 != type->count) + DEBUG(4,("What a mess, count was %x now is %x !\n", type->count, type->count2)); + /* parse the option type data */ + for(i=0;icount2;i++) + if(!prs_uint16("fields",ps,depth,&(type->fields[i]))) + return False; return True; } /******************************************************************* reads or writes an NOTIFY OPTION structure. ********************************************************************/ -static BOOL smb_io_notify_option(char *desc, SPOOL_NOTIFY_OPTION *option, - prs_struct *ps, int depth) -{ - uint32 useless_ptr; +static BOOL smb_io_notify_option_type_ctr(char *desc, SPOOL_NOTIFY_OPTION_TYPE_CTR *ctr , prs_struct *ps, int depth) +{ int i; - - prs_debug(ps, depth, desc, "smb_io_notify_option"); + + prs_debug(ps, depth, desc, "smb_io_notify_option_type_ctr"); depth++; - prs_align(ps); + if(!prs_uint32("count", ps, depth, &ctr->count)) + return False; - /* memory pointer to the struct */ - prs_uint32("useless ptr", ps, depth, &useless_ptr); + /* reading */ + if (UNMARSHALLING(ps)) + ctr->type=(SPOOL_NOTIFY_OPTION_TYPE *)malloc(ctr->count*sizeof(SPOOL_NOTIFY_OPTION_TYPE)); + + /* the option type struct */ + for(i=0;icount;i++) + if(!smb_io_notify_option_type("", &(ctr->type[i]) , ps, depth)) + return False; + + /* the type associated with the option type struct */ + for(i=0;icount;i++) + if(!smb_io_notify_option_type_data("", &(ctr->type[i]) , ps, depth)) + return False; - prs_uint32("version", ps, depth, &(option->version)); - prs_uint32("reserved", ps, depth, &(option->reserved)); - prs_uint32("count", ps, depth, &(option->count)); - prs_uint32("useless ptr", ps, depth, &useless_ptr); - prs_uint32("count", ps, depth, &(option->count)); - - /* read the option type struct */ - for(i=0;icount;i++) - { - smb_io_notify_option_type("",&(option->type[i]) ,ps, depth); - } + return True; +} - /* now read the type associated with the option type struct */ - for(i=0;icount;i++) - { - smb_io_notify_option_type_data("",&(option->type[i]) ,ps, depth); +/******************************************************************* +reads or writes an NOTIFY OPTION structure. +********************************************************************/ +static BOOL smb_io_notify_option(char *desc, SPOOL_NOTIFY_OPTION *option, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "smb_io_notify_option"); + depth++; + + if(!prs_uint32("version", ps, depth, &option->version)) + return False; + if(!prs_uint32("flags", ps, depth, &option->flags)) + return False; + if(!prs_uint32("count", ps, depth, &option->count)) + return False; + if(!prs_uint32("option_type_ptr", ps, depth, &option->option_type_ptr)) + return False; + + /* marshalling or unmarshalling, that would work */ + if (option->option_type_ptr!=0) { + if(!smb_io_notify_option_type_ctr("", &option->ctr ,ps, depth)) + return False; + } + else { + option->ctr.type=NULL; + option->ctr.count=0; } - return True; } - /******************************************************************* reads or writes an NOTIFY INFO DATA structure. ********************************************************************/ -static BOOL smb_io_notify_info_data(char *desc,SPOOL_NOTIFY_INFO_DATA *data, - prs_struct *ps, int depth) +static BOOL smb_io_notify_info_data(char *desc,SPOOL_NOTIFY_INFO_DATA *data, prs_struct *ps, int depth) { uint32 useless_ptr=0xADDE0FF0; @@ -354,19 +374,16 @@ BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data, /******************************************************************* reads or writes an NOTIFY INFO structure. ********************************************************************/ -static BOOL smb_io_notify_info(char *desc, SPOOL_NOTIFY_INFO *info, - prs_struct *ps, int depth) +static BOOL smb_io_notify_info(char *desc, SPOOL_NOTIFY_INFO *info, prs_struct *ps, int depth) { - uint32 useless_ptr=0x0001; int i; - info->version=0x02; prs_debug(ps, depth, desc, "smb_io_notify_info"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; - prs_uint32("pointer", ps, depth, &useless_ptr); prs_uint32("count", ps, depth, &(info->count)); prs_uint32("version", ps, depth, &(info->version)); prs_uint32("flags", ps, depth, &(info->flags)); @@ -380,8 +397,7 @@ static BOOL smb_io_notify_info(char *desc, SPOOL_NOTIFY_INFO *info, /* now do the strings at the end of the stream */ for (i=0;icount;i++) { - smb_io_notify_info_data_strings(desc, &(info->data[i]), - ps, depth); + smb_io_notify_info_data_strings(desc, &(info->data[i]), ps, depth); } return True; @@ -617,49 +633,6 @@ static BOOL spoolss_io_printer_default(char *desc, PRINTER_DEFAULT *pd, prs_stru return True; } -/******************************************************************* - * make a structure. - ********************************************************************/ -BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u, - const char *printername, - uint32 cbbuf, uint32 devmod, uint32 des_access, - const char *station, - const char *username) -{ - int len_name = printername != NULL ? strlen(printername) : 0; - int len_sta = station != NULL ? strlen(station ) : 0; - int len_user = username != NULL ? strlen(username ) : 0; - - if (q_u == NULL) return False; - - DEBUG(5,("make_spoolss_io_q_open_printer_ex\n")); - - q_u->printername_ptr = 1; - init_unistr2(&(q_u->printername), printername, len_name); - -/* - q_u->unknown0 = 0x0; - q_u->cbbuf = cbbuf; - q_u->devmod = devmod; - q_u->access_required = des_access; -*/ -/* q_u->unknown1 = 0x1; - q_u->unknown2 = 0x1; - q_u->unknown3 = 0x149f7d8; - q_u->unknown4 = 0x1c; - q_u->unknown5 = 0x00b94dd0; - q_u->unknown6 = 0x0149f5cc; - q_u->unknown7 = 0x00000565; - q_u->unknown8 = 0x2; - q_u->unknown9 = 0x0; - q_u->unknown10 = 0x0; - - init_unistr2(&(q_u->station), station, len_sta); - init_unistr2(&(q_u->username), username, len_user); -*/ - return True; -} - /******************************************************************* * read a structure. * called from spoolss_q_open_printer_ex (srv_spoolss.c) @@ -1026,29 +999,43 @@ BOOL spoolss_io_r_writeprinter(char *desc, SPOOL_R_WRITEPRINTER *r_u, prs_struct * read a structure. * called from spoolss_q_rffpcnex (srv_spoolss.c) ********************************************************************/ -BOOL spoolss_io_q_rffpcnex(char *desc, SPOOL_Q_RFFPCNEX *q_u, - prs_struct *ps, int depth) +BOOL spoolss_io_q_rffpcnex(char *desc, SPOOL_Q_RFFPCNEX *q_u, prs_struct *ps, int depth) { - uint32 useless_ptr; - prs_debug(ps, depth, desc, "spoolss_io_q_rffpcnex"); depth++; - prs_align(ps); - - smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); - prs_uint32("flags", ps, depth, &(q_u->flags)); - prs_uint32("options", ps, depth, &(q_u->options)); - prs_uint32("useless ptr", ps, depth, &useless_ptr); - /*prs_align(ps);*/ - smb_io_unistr2("", &(q_u->localmachine), True, ps, depth); - - prs_align(ps); - prs_uint32("printerlocal", ps, depth, &(q_u->printerlocal)); + if(!prs_align(ps)) + return False; - smb_io_notify_option("notify option", &(q_u->option), ps, depth); + if(!smb_io_prt_hnd("printer handle", &q_u->handle, ps, depth)) + return False; + if(!prs_uint32("flags", ps, depth, &q_u->flags)) + return False; + if(!prs_uint32("options", ps, depth, &q_u->options)) + return False; + if(!prs_uint32("localmachine_ptr", ps, depth, &q_u->localmachine_ptr)) + return False; + if(!smb_io_unistr2("localmachine", &q_u->localmachine, q_u->localmachine_ptr, ps, depth)) + return False; + if(!prs_align(ps)) + return False; + + if(!prs_uint32("printerlocal", ps, depth, &q_u->printerlocal)) + return False; + if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr)) + return False; + + if (q_u->option_ptr!=0) { + + if (UNMARSHALLING(ps)) + q_u->option=(SPOOL_NOTIFY_OPTION *)malloc(sizeof(SPOOL_NOTIFY_OPTION)); + + if(!smb_io_notify_option("notify option", q_u->option, ps, depth)) + return False; + } + return True; } @@ -1056,13 +1043,13 @@ BOOL spoolss_io_q_rffpcnex(char *desc, SPOOL_Q_RFFPCNEX *q_u, * write a structure. * called from spoolss_r_rffpcnex (srv_spoolss.c) ********************************************************************/ -BOOL spoolss_io_r_rffpcnex(char *desc, SPOOL_R_RFFPCNEX *r_u, - prs_struct *ps, int depth) +BOOL spoolss_io_r_rffpcnex(char *desc, SPOOL_R_RFFPCNEX *r_u, prs_struct *ps, int depth) { prs_debug(ps, depth, desc, "spoolss_io_r_rffpcnex"); depth++; - prs_uint32("status", ps, depth, &(r_u->status)); + if(!prs_uint32("status", ps, depth, &r_u->status)) + return False; return True; } @@ -1071,20 +1058,31 @@ BOOL spoolss_io_r_rffpcnex(char *desc, SPOOL_R_RFFPCNEX *r_u, * read a structure. * called from spoolss_q_rfnpcnex (srv_spoolss.c) ********************************************************************/ -BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u, - prs_struct *ps, int depth) +BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u, prs_struct *ps, int depth) { - prs_debug(ps, depth, desc, "spoolss_io_q_rfnpcnex"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; - smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); + if(!smb_io_prt_hnd("printer handle",&q_u->handle,ps,depth)) + return False; - prs_uint32("change", ps, depth, &(q_u->change)); + if(!prs_uint32("change", ps, depth, &q_u->change)) + return False; + + if(!prs_uint32("option_ptr", ps, depth, &q_u->option_ptr)) + return False; + + if (q_u->option_ptr!=0) { + + if (UNMARSHALLING(ps)) + q_u->option=(SPOOL_NOTIFY_OPTION *)malloc(sizeof(SPOOL_NOTIFY_OPTION)); - smb_io_notify_option("notify option",&(q_u->option),ps,depth); + if(!smb_io_notify_option("notify option", q_u->option, ps, depth)) + return False; + } return True; } @@ -1093,18 +1091,24 @@ BOOL spoolss_io_q_rfnpcnex(char *desc, SPOOL_Q_RFNPCNEX *q_u, * write a structure. * called from spoolss_r_rfnpcnex (srv_spoolss.c) ********************************************************************/ -BOOL spoolss_io_r_rfnpcnex(char *desc, - SPOOL_R_RFNPCNEX *r_u, - prs_struct *ps, int depth) +BOOL spoolss_io_r_rfnpcnex(char *desc, SPOOL_R_RFNPCNEX *r_u, prs_struct *ps, int depth) { prs_debug(ps, depth, desc, "spoolss_io_r_rfnpcnex"); depth++; - prs_align(ps); + if(!prs_align(ps)) + return False; + + if (!prs_uint32("info_ptr", ps, depth, &r_u->info_ptr)) + return False; - smb_io_notify_info("notify info",&(r_u->info),ps,depth); - prs_align(ps); - prs_uint32("status", ps, depth, &r_u->status); + if(!smb_io_notify_info("notify info", &r_u->info ,ps,depth)) + return False; + + if(!prs_align(ps)) + return False; + if(!prs_uint32("status", ps, depth, &r_u->status)) + return False; return True; } @@ -2499,44 +2503,6 @@ BOOL spoolss_io_r_getprinterdriver2(char *desc, SPOOL_R_GETPRINTERDRIVER2 *r_u, return True; } -/* - UNISTR **dependentfiles; - int j=0; - dependentfiles=info3->dependentfiles; - while ( dependentfiles[j] != NULL ) - { - free(dependentfiles[j]); - j++; - } - free(dependentfiles); - - free(info3); -*/ - -/******************************************************************* - * make a structure. - ********************************************************************/ -BOOL make_spoolss_q_enumprinters(SPOOL_Q_ENUMPRINTERS *q_u, - uint32 flags, - const char* servername, - uint32 level, - uint32 size) -{ - size_t len_name = servername != NULL ? strlen(servername) : 0; - - DEBUG(5,("make_spoolss_q_enumprinters. size: %d\n", size)); - - q_u->flags = flags; - - init_unistr2(&q_u->servername, servername, len_name); - - q_u->level = level; - /*make_spoolss_buffer(&q_u->buffer, size);*/ -/* q_u->buf_size = size;*/ - - return True; -} - /******************************************************************* * read a structure. * called from spoolss_enumprinters (srv_spoolss.c) @@ -2630,26 +2596,6 @@ BOOL spoolss_io_r_getprinter(char *desc, SPOOL_R_GETPRINTER *r_u, prs_struct *ps return True; } -/******************************************************************* - * make a structure. - * called from spoolss_getprinter (srv_spoolss.c) - ********************************************************************/ -BOOL make_spoolss_q_getprinter(SPOOL_Q_GETPRINTER *q_u, - POLICY_HND *hnd, - uint32 level, - uint32 buf_size) -{ - if (q_u == NULL) return False; - - memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); - - q_u->level = level; - q_u->buffer = (uint8 *)Realloc(NULL, (buf_size) * sizeof(uint8) ); - q_u->offered = buf_size; - - return True; -} - /******************************************************************* * read a structure. * called from spoolss_getprinter (srv_spoolss.c) diff --git a/source/rpc_server/srv_spoolss.c b/source/rpc_server/srv_spoolss.c index 4965542d73e..be6775f35d2 100755 --- a/source/rpc_server/srv_spoolss.c +++ b/source/rpc_server/srv_spoolss.c @@ -140,9 +140,9 @@ static BOOL api_spoolss_rffpcnex(uint16 vuid, prs_struct *data, prs_struct *rdat r_u.status = _spoolss_rffpcnex(&q_u.handle, q_u.flags, q_u.options, &q_u.localmachine, - q_u.printerlocal, &q_u.option); + q_u.printerlocal, q_u.option); - if (!spoolss_io_r_rffpcnex("",&r_u,rdata,0)) { + if (!spoolss_io_r_rffpcnex("", &r_u, rdata, 0)) { DEBUG(0,("spoolss_io_r_rffpcnex: unable to marshall SPOOL_R_RFFPCNEX.\n")); return False; } @@ -171,13 +171,18 @@ static BOOL api_spoolss_rfnpcnex(uint16 vuid, prs_struct *data, prs_struct *rdat } r_u.status = _spoolss_rfnpcnex(&q_u.handle, q_u.change, - &q_u.option, &r_u.count, &r_u.info); + q_u.option, &r_u.info); + + /* we always have a NOTIFY_INFO struct */ + r_u.info_ptr=0x1; if (!spoolss_io_r_rfnpcnex("", &r_u, rdata, 0)) { DEBUG(0,("spoolss_io_r_rfnpcnex: unable to marshall SPOOL_R_RFNPCNEX.\n")); return False; } + safe_free(r_u.info.data); + return True; } diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c index 90a7b44aef3..cd0d0a8ab18 100644 --- a/source/rpc_server/srv_spoolss_nt.c +++ b/source/rpc_server/srv_spoolss_nt.c @@ -39,28 +39,31 @@ extern pstring global_myname; /* and a reference to what it's pointing to */ /* and the notify info asked about */ /* that's the central struct */ -static struct -{ - BOOL open; - BOOL ok; - BOOL document_started; - BOOL page_started; - uint32 current_jobid; - uint32 document_fd; - uint32 document_lastwritten; - pstring document_name; - pstring job_name; - POLICY_HND printer_hnd; - BOOL printer_type; - union - { - fstring printername; - fstring printerservername; - } dev; - uint32 type; - uint32 access; - uint32 number_of_notify; - SPOOL_NOTIFY_OPTION_TYPE notify_info[MAX_PRINTER_NOTIFY+MAX_JOB_NOTIFY]; +static struct { + BOOL open; + BOOL ok; + BOOL document_started; + BOOL page_started; + uint32 current_jobid; + uint32 document_fd; + uint32 document_lastwritten; + pstring document_name; + pstring job_name; + POLICY_HND printer_hnd; + BOOL printer_type; + union { + fstring printername; + fstring printerservername; + } dev; + uint32 type; + uint32 access; + struct { + uint32 flags; + uint32 options; + fstring localmachine; + uint32 printerlocal; + SPOOL_NOTIFY_OPTION *option; + } notify; } Printer[MAX_OPEN_PRINTER_EXS]; #define VALID_HANDLE(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_PRINTER_EXS)) @@ -110,13 +113,13 @@ static int find_printer_index_by_hnd(const POLICY_HND *hnd) { if (memcmp(&(Printer[i].printer_hnd), hnd, sizeof(*hnd)) == 0) { - DEBUG(4,("Found printer handle[%x] ", i)); - dump_data(4, hnd->data, sizeof(hnd->data)); + DEBUG(4,("Found printer handle[%x] \n", i)); + /*dump_data(4, hnd->data, sizeof(hnd->data));*/ return i; } } DEBUG(3,("Whoops, Printer handle not found: ")); - dump_data(4, hnd->data, sizeof(hnd->data)); + /*dump_data(4, hnd->data, sizeof(hnd->data));*/ return -1; } @@ -125,7 +128,7 @@ static int find_printer_index_by_hnd(const POLICY_HND *hnd) ****************************************************************************/ static void clear_handle(POLICY_HND *hnd) { - bzero(hnd->data, POLICY_HND_SIZE); + memset(hnd->data, 0, POLICY_HND_SIZE); } /**************************************************************************** @@ -142,6 +145,13 @@ static BOOL close_printer_handle(POLICY_HND *hnd) } Printer[pnum].open=False; + Printer[pnum].notify.flags=0; + Printer[pnum].notify.options=0; + Printer[pnum].notify.localmachine[0]='\0'; + Printer[pnum].notify.printerlocal=0; + safe_free(Printer[pnum].notify.option); + Printer[pnum].notify.option=NULL; + clear_handle(hnd); return True; @@ -204,6 +214,7 @@ static BOOL open_printer_hnd(POLICY_HND *hnd) memcpy(&(Printer[i].printer_hnd), hnd, sizeof(*hnd)); DEBUG(4,("Opened printer handle[%x] ", i)); dump_data(4, hnd->data, sizeof(hnd->data)); + Printer[i].notify.option=NULL; return True; } } @@ -334,6 +345,7 @@ static BOOL set_printer_hnd_printername(POLICY_HND *hnd, char *printername) return False; } + snum--; DEBUGADD(4,("Printer found: %s[%x]\n",lp_servicename(snum),snum)); ZERO_STRUCT(Printer[pnum].dev.printername); strncpy(Printer[pnum].dev.printername, lp_servicename(snum), strlen(lp_servicename(snum))); @@ -635,7 +647,7 @@ static BOOL getprinterdata_printer(const POLICY_HND *handle, if (get_specific_param(printer, 2, value, &idata, type, &len)) { *data = (uint8 *)malloc( (len>in_size)?len:in_size *sizeof(uint8) ); - bzero(*data, sizeof(uint8)*len); + memset(*data, 0, sizeof(uint8)*len); memcpy(*data, idata, (len>in_size)?len:in_size); *needed = len; @@ -713,42 +725,26 @@ uint32 _spoolss_getprinterdata(const POLICY_HND *handle, UNISTR2 *valuename, * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe * called from api_spoolss_rffpcnex ********************************************************************/ -uint32 _spoolss_rffpcnex(const POLICY_HND *handle, - uint32 flags, uint32 options, - const UNISTR2 *localmachine, - uint32 printerlocal, - SPOOL_NOTIFY_OPTION *option) +uint32 _spoolss_rffpcnex(const POLICY_HND *handle, uint32 flags, uint32 options, + const UNISTR2 *localmachine, uint32 printerlocal, + SPOOL_NOTIFY_OPTION *option) { - int i,j,k; + int i; /* store the notify value in the printer struct */ i=find_printer_index_by_hnd(handle); if (i == -1) - { return NT_STATUS_INVALID_HANDLE; - } - - Printer[i].number_of_notify=option->count; - DEBUG(3,("Copying %x notify option info\n",Printer[i].number_of_notify)); + Printer[i].notify.flags=flags; + Printer[i].notify.options=options; + Printer[i].notify.printerlocal=printerlocal; + Printer[i].notify.option=option; + unistr2_to_ascii(Printer[i].notify.localmachine, localmachine, sizeof(Printer[i].notify.localmachine)-1); - for (j=0;jtype[j].count; - Printer[i].notify_info[j].type=option->type[j].type ; - - DEBUG(4,("Copying %x info fields of type %x\n", - Printer[i].notify_info[j].count, - Printer[i].notify_info[j].type)); - for(k=0;ktype[j].fields[k]; - } - } - - return 0x0; + return NT_STATUS_NO_PROBLEMO; } /******************************************************************* @@ -961,7 +957,7 @@ static void spoolss_notify_status(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_ print_queue_struct *q=NULL; print_status_struct status; - bzero(&status,sizeof(status)); + memset(&status, 0, sizeof(status)); count=get_printqueue(snum, NULL, &q, &status); @@ -977,7 +973,7 @@ static void spoolss_notify_cjobs(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_q print_queue_struct *q=NULL; print_status_struct status; - bzero(&status,sizeof(status)); + memset(&status, 0, sizeof(status)); data->notify_data.value[0]=get_printqueue(snum, NULL, &q, &status); if (q) free(q); @@ -1163,40 +1159,30 @@ static int search_notify(uint16 type, uint16 field, int *value) int j; BOOL found; - DEBUG(4,("\tsearch_notify: in\n")); for (j=0, found=False; found==False && notify_info_data_table[j].type != END ; j++) { if ( (notify_info_data_table[j].type == type ) && (notify_info_data_table[j].field == field ) ) - { found=True; - } } *value=--j; if ( found && (notify_info_data_table[j].fn != NULL) ) - { - DEBUG(4,("\tsearch_notify: out TRUE\n")); - return (True); - } + return True; else - { - DEBUG(4,("\tsearch_notify: out FALSE\n")); - return (False); - } + return False; } /**************************************************************************** ****************************************************************************/ static void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id) { - DEBUG(4,("\tconstruct_info_data: in\n")); info_data->type = type; info_data->field = field; + info_data->reserved = 0; info_data->id = id; info_data->size = size_of_notify_info_data(type, field); info_data->enc_type = type_of_notify_info_data(type, field); - DEBUG(4,("\tconstruct_info_data: out\n")); } @@ -1205,49 +1191,48 @@ static void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, * fill a notify_info struct with info asked * ********************************************************************/ -static void construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int pnum, - int snum, int i, uint32 id) +static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int snum, SPOOL_NOTIFY_OPTION_TYPE *option_type, uint32 id) { - - int k,j; + int field_num,j; uint16 type; uint16 field; - SPOOL_NOTIFY_INFO_DATA *info_data; - print_queue_struct *queue=NULL; + SPOOL_NOTIFY_INFO_DATA *current_data; NT_PRINTER_INFO_LEVEL printer; + print_queue_struct *queue=NULL; DEBUG(4,("construct_notify_printer_info\n")); - info_data=&(info->data[info->count]); - - type = Printer[pnum].notify_info[i].type; + type=option_type->type; - DEBUGADD(4,("Notify number %d -> number of notify info: %d\n",i,Printer[pnum].notify_info[i].count)); + DEBUGADD(4,("Notify type: [%s], number of notify info: [%d] on printer: [%s]\n", + (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"), + option_type->count, lp_servicename(snum))); - if (!get_a_printer(&printer, 2, lp_servicename(snum))) + if (get_a_printer(&printer, 2, lp_servicename(snum))!=0) + { + return False; + } + + for(field_num=0; field_numcount; field_num++) { + field = option_type->fields[field_num]; + DEBUGADD(4,("notify [%d]: type [%x], field [%x]\n", field_num, type, field)); + + if (!search_notify(type, field, &j) ) + continue; - for(k=0; kdata=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA)); + current_data=&(info->data[info->count]); - if (search_notify(type, field, &j) ) - { - DEBUGADD(4,("j=[%d]:%s\n", j, notify_info_data_table[j].name)); - construct_info_data(info_data, type, field, id); - - DEBUGADD(4,("notify_info_data_table: in\n")); - notify_info_data_table[j].fn(snum, info_data, queue, &printer); - DEBUGADD(4,("notify_info_data_table: out\n")); - info->count++; - info_data=&(info->data[info->count]); - } - } - - free_a_printer(printer, 2); + construct_info_data(current_data, type, field, id); + notify_info_data_table[j].fn(snum, current_data, queue, &printer); + + info->count++; } + + free_a_printer(printer, 2); + return True; } /******************************************************************* @@ -1255,46 +1240,72 @@ static void construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int pnum, * fill a notify_info struct with info asked * ********************************************************************/ -static void construct_notify_jobs_info(print_queue_struct *queue, SPOOL_NOTIFY_INFO *info, - int pnum, int snum, int i, uint32 id) +static BOOL construct_notify_jobs_info(print_queue_struct *queue, SPOOL_NOTIFY_INFO *info, int snum, SPOOL_NOTIFY_OPTION_TYPE *option_type, uint32 id) { - - int k,j; + int field_num,j; uint16 type; uint16 field; - SPOOL_NOTIFY_INFO_DATA *info_data; + SPOOL_NOTIFY_INFO_DATA *current_data; NT_PRINTER_INFO_LEVEL printer; DEBUG(4,("construct_notify_jobs_info\n")); - info_data=&(info->data[info->count]); - type = Printer[pnum].notify_info[i].type; + type = option_type->type; - DEBUGADD(4,("Notify number %d -> number of notify info: %d\n",i,Printer[pnum].notify_info[i].count)); + DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n", + (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"), + option_type->count)); - if (!get_a_printer(&printer, 2, lp_servicename(snum))) + if (get_a_printer(&printer, 2, lp_servicename(snum))!=0) { - for(k=0; kcount; field_num++) + { + field = option_type->fields[field_num]; - if (search_notify(type, field, &j) ) - { - DEBUGADD(4,("j=[%d]:%s\n", j, notify_info_data_table[j].name)); - construct_info_data(info_data, type, field, id); - DEBUGADD(4,("notify_info_data_table: in\n")); - notify_info_data_table[j].fn(snum, info_data, queue, &printer); - DEBUGADD(4,("notify_info_data_table: out\n")); - info->count++; - info_data=&(info->data[info->count]); - } - } - free_a_printer(printer, 2); + if (!search_notify(type, field, &j) ) + continue; + + info->data=Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA)); + current_data=&(info->data[info->count]); + + construct_info_data(current_data, type, field, id); + notify_info_data_table[j].fn(snum, current_data, queue, &printer); + info->count++; } + + free_a_printer(printer, 2); + + return True; } +/* + * JFM: The enumeration is not that simple, it's even non obvious. + * + * let's take an example: I want to monitor the PRINTER SERVER for + * the printer's name and the number of jobs currently queued. + * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure. + * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS. + * + * I have 3 printers on the back of my server. + * + * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA + * structures. + * Number Data Id + * 1 printer 1 name 1 + * 2 printer 1 cjob 1 + * 3 printer 2 name 2 + * 4 printer 2 cjob 2 + * 5 printer 3 name 3 + * 6 printer 3 name 3 + * + * that's the print server case, the printer case is even worse. + */ + + /******************************************************************* * @@ -1302,40 +1313,54 @@ static void construct_notify_jobs_info(print_queue_struct *queue, SPOOL_NOTIFY_I * fill a notify_info struct with info asked * ********************************************************************/ -static uint32 printserver_notify_info(const POLICY_HND *hnd, - SPOOL_NOTIFY_INFO *info) +static uint32 printserver_notify_info(const POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info) { int snum; int pnum=find_printer_index_by_hnd(hnd); int n_services=lp_numservices(); - int i=0; - uint32 id=1; + int i; + uint32 id; + SPOOL_NOTIFY_OPTION *option; + SPOOL_NOTIFY_OPTION_TYPE *option_type; + + DEBUG(4,("printserver_notify_info\n")); + + option=Printer[pnum].notify.option; + id=1; + info->version=2; + info->data=NULL; info->count=0; - if (pnum == -1) + for (i=0; icount; i++) { - return NT_STATUS_INVALID_HANDLE; + option_type=&(option->ctr.type[i]); + + if (option_type->type!=PRINTER_NOTIFY_TYPE) + continue; + + for (snum=0; snumversion:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count)); + DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n")); + + for (i=0; icount; i++) { - if ( Printer[pnum].notify_info[i].type == PRINTER_NOTIFY_TYPE ) - { - for (snum=0; snumdata[i].type, info->data[i].field, info->data[i].reserved, + info->data[i].id, info->data[i].size, info->data[i].enc_type)); } - DEBUG(4,("All printers enumerated\n")); - - return 0x0; + */ + + return NT_STATUS_NO_PROBLEMO; } /******************************************************************* @@ -1343,59 +1368,72 @@ static uint32 printserver_notify_info(const POLICY_HND *hnd, * fill a notify_info struct with info asked * ********************************************************************/ -static uint32 printer_notify_info(const POLICY_HND *hnd, - SPOOL_NOTIFY_INFO *info) +static uint32 printer_notify_info(const POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info) { int snum; int pnum=find_printer_index_by_hnd(hnd); - int i=0, j; - uint32 id=0xFFFF; + int i; + uint32 id; + SPOOL_NOTIFY_OPTION *option; + SPOOL_NOTIFY_OPTION_TYPE *option_type; + int count,j; + print_queue_struct *queue=NULL; + print_status_struct status; + DEBUG(4,("printer_notify_info\n")); + + option=Printer[pnum].notify.option; + id=1; + info->version=2; + info->data=NULL; info->count=0; - if (pnum == -1 || !get_printer_snum(hnd, &snum) ) - { - return NT_STATUS_INVALID_HANDLE; - } + get_printer_snum(hnd, &snum); - for (i=0; icount; i++) { - switch ( Printer[pnum].notify_info[i].type ) - { - case PRINTER_NOTIFY_TYPE: - { - construct_notify_printer_info(info, pnum, snum, i, id); - id--; - break; - } - case JOB_NOTIFY_TYPE: - { - int count; - print_queue_struct *queue=NULL; - print_status_struct status; - bzero(&status, sizeof(status)); - count=get_printqueue(snum, NULL, &queue, &status); - for (j=0; jctr.type[i]); + + switch ( option_type->type ) { + case PRINTER_NOTIFY_TYPE: + if(construct_notify_printer_info(info, snum, option_type, id)) + id++; + break; + + case JOB_NOTIFY_TYPE: + memset(&status, 0, sizeof(status)); + count=get_printqueue(snum, NULL, &queue, &status); + for (j=0; jversion:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count)); + DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n")); + + for (i=0; icount; i++) + { + DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n", + i, info->data[i].type, info->data[i].field, info->data[i].reserved, + info->data[i].id, info->data[i].size, info->data[i].enc_type)); + } + */ + return NT_STATUS_NO_PROBLEMO; } /******************************************************************** * spoolss_rfnpcnex ********************************************************************/ -uint32 _spoolss_rfnpcnex( const POLICY_HND *handle, - uint32 change, - const SPOOL_NOTIFY_OPTION *option, - uint32 *count, - SPOOL_NOTIFY_INFO *info) +uint32 _spoolss_rfnpcnex( const POLICY_HND *handle, uint32 change, + SPOOL_NOTIFY_OPTION *option, SPOOL_NOTIFY_INFO *info) { int pnum=find_printer_index_by_hnd(handle); @@ -1404,21 +1442,32 @@ uint32 _spoolss_rfnpcnex( const POLICY_HND *handle, return NT_STATUS_INVALID_HANDLE; } - DEBUG(4,("Printer %x of type %x\n",pnum,Printer[pnum].printer_type)); + DEBUG(4,("Printer %x of type %x\n",pnum, Printer[pnum].printer_type)); + + /* jfm: the change value isn't used right now. + * we will honour it when + * a) we'll be able to send notification to the client + * b) we'll have a way to communicate between the spoolss process. + * + * same thing for option->flags + * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as + * I don't have a global notification system, I'm sending back all the + * informations even when _NOTHING_ has changed. + */ - /* lkxlXXXX - jfm, is this right? put a warning in for you to review! */ - DEBUG(0,("_spoolss_rfnpcnex: change, option and count ignored\n")); + /* just discard the SPOOL_NOTIFY_OPTION */ + if (option!=NULL) + safe_free(option->ctr.type); + + safe_free(option); - switch (Printer[pnum].printer_type) - { + switch (Printer[pnum].printer_type) { case PRINTER_HANDLE_IS_PRINTSERVER: - { return printserver_notify_info(handle, info); - } + break; case PRINTER_HANDLE_IS_PRINTER: - { return printer_notify_info(handle, info); - } + break; } return NT_STATUS_INVALID_INFO_CLASS; @@ -1436,7 +1485,7 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer,int snum, pstring s print_queue_struct *queue=NULL; print_status_struct status; - bzero(&status,sizeof(status)); + memset(&status, 0, sizeof(status)); if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) != 0) { @@ -1476,7 +1525,7 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer,int snum, pstring s printer->unknown14 = 0x1; printer->unknown15 = 0x024a; /*586 Pentium ? */ printer->unknown16 = 0x0; - printer->unknown17 = 0x423ed444; + printer->unknown17 = 0x423ed444; /* CacheChangeID */ printer->unknown18 = 0x0; printer->status = status.status; printer->unknown20 = 0x0; @@ -1536,8 +1585,8 @@ static void construct_dev_mode(DEVICEMODE *devmode, int snum, char *servername) DEBUG(7,("construct_dev_mode\n")); - bzero(&(devmode->devicename), 2*sizeof(adevice)); - bzero(&(devmode->formname), 2*sizeof(aform)); + memset(&(devmode->devicename), 0, 2*sizeof(adevice)); + memset(&(devmode->formname), 0, 2*sizeof(aform)); DEBUGADD(8,("getting printer characteristics\n")); @@ -1598,7 +1647,7 @@ static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum, pstring print_queue_struct *queue=NULL; print_status_struct status; - bzero(&status, sizeof(status)); + memset(&status, 0, sizeof(status)); count=get_printqueue(snum, NULL, &queue, &status); if (get_a_printer(&ntprinter, 2, lp_servicename(snum)) !=0 ) @@ -2713,14 +2762,28 @@ uint32 _spoolss_setprinter( const POLICY_HND *handle, /**************************************************************************** ****************************************************************************/ -uint32 _spoolss_fcpn( const POLICY_HND *handle) +uint32 _spoolss_fcpn(const POLICY_HND *handle) { - return 0x0; + int pnum = find_printer_index_by_hnd(handle); + + if (!OPEN_HANDLE(pnum)) + { + return NT_STATUS_INVALID_HANDLE; + } + + Printer[pnum].notify.flags=0; + Printer[pnum].notify.options=0; + Printer[pnum].notify.localmachine[0]='\0'; + Printer[pnum].notify.printerlocal=0; + safe_free(Printer[pnum].notify.option); + Printer[pnum].notify.option=NULL; + + return NT_STATUS_NO_PROBLEMO; } /**************************************************************************** ****************************************************************************/ -uint32 _spoolss_addjob( const POLICY_HND *handle, uint32 level, +uint32 _spoolss_addjob(const POLICY_HND *handle, uint32 level, NEW_BUFFER *buffer, uint32 offered) { return NT_STATUS_NO_PROBLEMO; @@ -2956,7 +3019,7 @@ uint32 _spoolss_setjob( const POLICY_HND *handle, BOOL found=False; int count; - bzero(&prt_status,sizeof(prt_status)); + memset(&prt_status, 0, sizeof(prt_status)); if (!get_printer_snum(handle, &snum)) { @@ -3989,7 +4052,7 @@ uint32 _spoolss_getjob( POLICY_HND *handle, uint32 jobid, uint32 level, DEBUG(5,("spoolss_getjob\n")); - bzero(&prt_status, sizeof(prt_status)); + memset(&prt_status, 0, sizeof(prt_status)); *needed=0; -- cgit From b59233b3b61b17e85f5d5b44cc6f2ced9d27b497 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Thu, 24 Feb 2000 23:01:24 +0000 Subject: made dynamic the Printer struct. No more limits :-) J.F. --- source/rpc_server/srv_spoolss_nt.c | 356 ++++++++++++++++++------------------- 1 file changed, 169 insertions(+), 187 deletions(-) diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c index cd0d0a8ab18..da7eda57958 100644 --- a/source/rpc_server/srv_spoolss_nt.c +++ b/source/rpc_server/srv_spoolss_nt.c @@ -39,9 +39,11 @@ extern pstring global_myname; /* and a reference to what it's pointing to */ /* and the notify info asked about */ /* that's the central struct */ -static struct { +typedef struct _Printer{ + ubi_dlNode Next; + ubi_dlNode Prev; + BOOL open; - BOOL ok; BOOL document_started; BOOL page_started; uint32 current_jobid; @@ -64,21 +66,18 @@ static struct { uint32 printerlocal; SPOOL_NOTIFY_OPTION *option; } notify; -} Printer[MAX_OPEN_PRINTER_EXS]; +} Printer_entry; + +static ubi_dlList Printer_list; -#define VALID_HANDLE(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_PRINTER_EXS)) -#define OPEN_HANDLE(pnum) (VALID_HANDLE(pnum) && Printer[pnum].open) +#define OPEN_HANDLE(pnum) ((pnum!=NULL) && (pnum->open!=False)) /**************************************************************************** initialise printer handle states... ****************************************************************************/ void init_printer_hnd(void) { - int i; - for (i = 0; i < MAX_OPEN_PRINTER_EXS; i++) - { - Printer[i].open = False; - } + ubi_dlInitList(&Printer_list); } /**************************************************************************** @@ -105,22 +104,25 @@ static void create_printer_hnd(POLICY_HND *hnd) /**************************************************************************** find printer index by handle ****************************************************************************/ -static int find_printer_index_by_hnd(const POLICY_HND *hnd) +static Printer_entry *find_printer_index_by_hnd(const POLICY_HND *hnd) { - int i; + Printer_entry *find_printer; - for (i = 0; i < MAX_OPEN_PRINTER_EXS; i++) - { - if (memcmp(&(Printer[i].printer_hnd), hnd, sizeof(*hnd)) == 0) + find_printer = (Printer_entry *)ubi_dlFirst(&Printer_list); + + for(; find_printer; find_printer = (Printer_entry *)ubi_dlNext(find_printer)) { + + if (memcmp(&(find_printer->printer_hnd), hnd, sizeof(*hnd)) == 0) { - DEBUG(4,("Found printer handle[%x] \n", i)); + DEBUG(4,("Found printer handle \n")); /*dump_data(4, hnd->data, sizeof(hnd->data));*/ - return i; + return find_printer; } } + DEBUG(3,("Whoops, Printer handle not found: ")); /*dump_data(4, hnd->data, sizeof(hnd->data));*/ - return -1; + return NULL; } /**************************************************************************** @@ -136,24 +138,30 @@ static void clear_handle(POLICY_HND *hnd) ****************************************************************************/ static BOOL close_printer_handle(POLICY_HND *hnd) { - int pnum = find_printer_index_by_hnd(hnd); + Printer_entry *Printer = find_printer_index_by_hnd(hnd); - if (pnum == -1) + if (!OPEN_HANDLE(Printer)) { - DEBUG(3,("Error closing printer handle (pnum=%x)\n", pnum)); + DEBUG(3,("Error closing printer handle\n")); return False; } - Printer[pnum].open=False; - Printer[pnum].notify.flags=0; - Printer[pnum].notify.options=0; - Printer[pnum].notify.localmachine[0]='\0'; - Printer[pnum].notify.printerlocal=0; - safe_free(Printer[pnum].notify.option); - Printer[pnum].notify.option=NULL; + Printer->open=False; + Printer->notify.flags=0; + Printer->notify.options=0; + Printer->notify.localmachine[0]='\0'; + Printer->notify.printerlocal=0; + safe_free(Printer->notify.option); + Printer->notify.option=NULL; clear_handle(hnd); + ubi_dlRemThis(&Printer_list, Printer); + + safe_free(Printer); + + DEBUG(0,("[%d] entrys still in list\n", ubi_dlCount(&Printer_list))); + return True; } @@ -163,23 +171,23 @@ static BOOL close_printer_handle(POLICY_HND *hnd) static BOOL get_printer_snum(const POLICY_HND *hnd, int *number) { int snum; - int pnum = find_printer_index_by_hnd(hnd); + Printer_entry *Printer = find_printer_index_by_hnd(hnd); int n_services=lp_numservices(); - if (!OPEN_HANDLE(pnum)) { + if (!OPEN_HANDLE(Printer)) { DEBUG(3,("Error getting printer - take a nap quickly !\n")); return False; } - switch (Printer[pnum].printer_type) { + switch (Printer->printer_type) { case PRINTER_HANDLE_IS_PRINTER: - DEBUG(4,("short name:%s\n", Printer[pnum].dev.printername)); + DEBUG(4,("short name:%s\n", Printer->dev.printername)); for (snum=0;snumdev.printername ) ) && ( !strncasecmp(lp_servicename(snum), - Printer[pnum].dev.printername, + Printer->dev.printername, strlen( lp_servicename(snum) ))) ) { DEBUG(4,("Printer found: %s[%x]\n",lp_servicename(snum),snum)); *number=snum; @@ -204,22 +212,19 @@ static BOOL get_printer_snum(const POLICY_HND *hnd, int *number) ****************************************************************************/ static BOOL open_printer_hnd(POLICY_HND *hnd) { - int i; + Printer_entry *new_printer; - for (i = 0; i < MAX_OPEN_PRINTER_EXS; i++) - { - if (!Printer[i].open) - { - Printer[i].open = True; - memcpy(&(Printer[i].printer_hnd), hnd, sizeof(*hnd)); - DEBUG(4,("Opened printer handle[%x] ", i)); - dump_data(4, hnd->data, sizeof(hnd->data)); - Printer[i].notify.option=NULL; - return True; - } - } - DEBUG(1,("ERROR - open_printer_hnd: out of Printers Handles!\n")); - return False; + new_printer=(Printer_entry *)malloc(sizeof(Printer_entry)); + ZERO_STRUCTP(new_printer); + + new_printer->open = True; + new_printer->notify.option=NULL; + + memcpy(&(new_printer->printer_hnd), hnd, sizeof(*hnd)); + + ubi_dlAddHead( &Printer_list, (ubi_dlNode *)new_printer); + + return True; } /**************************************************************************** @@ -227,15 +232,15 @@ static BOOL open_printer_hnd(POLICY_HND *hnd) ****************************************************************************/ static BOOL set_printer_hnd_accesstype(POLICY_HND *hnd, uint32 access_required) { - int pnum = find_printer_index_by_hnd(hnd); + Printer_entry *Printer = find_printer_index_by_hnd(hnd); - if (!OPEN_HANDLE(pnum)) { - DEBUG(4,("Error setting printer type=%x (pnum=%x)", access_required, pnum)); + if (!OPEN_HANDLE(Printer)) { + DEBUG(4,("Error setting printer type=%x", access_required)); return False; } - DEBUG(4,("Setting printer access=%x (pnum=%x)\n", access_required, pnum)); - Printer[pnum].access = access_required; + DEBUG(4,("Setting printer access=%x\n", access_required)); + Printer->access = access_required; return True; } @@ -245,14 +250,14 @@ static BOOL set_printer_hnd_accesstype(POLICY_HND *hnd, uint32 access_required) ****************************************************************************/ static BOOL set_printer_hnd_printertype(POLICY_HND *hnd, char *printername) { - int pnum = find_printer_index_by_hnd(hnd); + Printer_entry *Printer = find_printer_index_by_hnd(hnd); - if (!OPEN_HANDLE(pnum)) { - DEBUGADD(4,("Error setting printer name %s (pnum=%x)", printername, pnum)); + if (!OPEN_HANDLE(Printer)) { + DEBUGADD(4,("Error setting printer name %s", printername)); return False; } - DEBUG(3,("Setting printer type=%s (pnum=%x)\n", printername, pnum)); + DEBUG(3,("Setting printer type=%s\n", printername)); if ( strlen(printername) < 3 ) { DEBUGADD(4,("A print server must have at least 1 char ! %s\n", printername)); @@ -262,13 +267,13 @@ static BOOL set_printer_hnd_printertype(POLICY_HND *hnd, char *printername) /* it's a print server */ if (!strchr(printername+2, '\\')) { DEBUGADD(4,("Printer is a print server\n")); - Printer[pnum].printer_type = PRINTER_HANDLE_IS_PRINTSERVER; + Printer->printer_type = PRINTER_HANDLE_IS_PRINTSERVER; return True; } /* it's a printer */ else { DEBUGADD(4,("Printer is a printer\n")); - Printer[pnum].printer_type = PRINTER_HANDLE_IS_PRINTER; + Printer->printer_type = PRINTER_HANDLE_IS_PRINTER; return True; } @@ -280,28 +285,28 @@ static BOOL set_printer_hnd_printertype(POLICY_HND *hnd, char *printername) ****************************************************************************/ static BOOL set_printer_hnd_printername(POLICY_HND *hnd, char *printername) { - int pnum = find_printer_index_by_hnd(hnd); + Printer_entry *Printer = find_printer_index_by_hnd(hnd); NT_PRINTER_INFO_LEVEL printer; int snum; int n_services=lp_numservices(); char *aprinter; BOOL found=False; - if (!OPEN_HANDLE(pnum)) + if (!OPEN_HANDLE(Printer)) { - DEBUG(0,("Error setting printer name=%s (pnum=%x)\n", printername, pnum)); + DEBUG(0,("Error setting printer name=%s\n", printername)); return False; } - DEBUG(4,("Setting printer name=%s (len=%d) (pnum=%x)\n", printername, strlen(printername), pnum)); + DEBUG(4,("Setting printer name=%s (len=%d)\n", printername, strlen(printername))); - if (Printer[pnum].printer_type==PRINTER_HANDLE_IS_PRINTSERVER) { - ZERO_STRUCT(Printer[pnum].dev.printerservername); - strncpy(Printer[pnum].dev.printerservername, printername, strlen(printername)); + if (Printer->printer_type==PRINTER_HANDLE_IS_PRINTSERVER) { + ZERO_STRUCT(Printer->dev.printerservername); + strncpy(Printer->dev.printerservername, printername, strlen(printername)); return True; } - if (Printer[pnum].printer_type!=PRINTER_HANDLE_IS_PRINTER) + if (Printer->printer_type!=PRINTER_HANDLE_IS_PRINTER) return False; aprinter=strchr(printername+2, '\\'); @@ -347,8 +352,8 @@ static BOOL set_printer_hnd_printername(POLICY_HND *hnd, char *printername) snum--; DEBUGADD(4,("Printer found: %s[%x]\n",lp_servicename(snum),snum)); - ZERO_STRUCT(Printer[pnum].dev.printername); - strncpy(Printer[pnum].dev.printername, lp_servicename(snum), strlen(lp_servicename(snum))); + ZERO_STRUCT(Printer->dev.printername); + strncpy(Printer->dev.printername, lp_servicename(snum), strlen(lp_servicename(snum))); free_a_printer(printer, 2); return True; @@ -359,12 +364,12 @@ static BOOL set_printer_hnd_printername(POLICY_HND *hnd, char *printername) ********************************************************************/ static BOOL handle_is_printserver(const POLICY_HND *handle) { - int pnum=find_printer_index_by_hnd(handle); + Printer_entry *Printer=find_printer_index_by_hnd(handle); - if (!OPEN_HANDLE(pnum)) + if (!OPEN_HANDLE(Printer)) return False; - if (Printer[pnum].printer_type != PRINTER_HANDLE_IS_PRINTSERVER) + if (Printer->printer_type != PRINTER_HANDLE_IS_PRINTSERVER) return False; return True; @@ -631,15 +636,14 @@ static BOOL getprinterdata_printer(const POLICY_HND *handle, uint8 **data, uint32 *needed, uint32 in_size ) { NT_PRINTER_INFO_LEVEL printer; - int pnum=0; int snum=0; uint8 *idata=NULL; uint32 len; + Printer_entry *Printer = find_printer_index_by_hnd(handle); DEBUG(5,("getprinterdata_printer\n")); - pnum = find_printer_index_by_hnd(handle); - if (OPEN_HANDLE(pnum)) + if (OPEN_HANDLE(Printer)) { get_printer_snum(handle, &snum); get_a_printer(&printer, 2, lp_servicename(snum)); @@ -672,7 +676,7 @@ uint32 _spoolss_getprinterdata(const POLICY_HND *handle, UNISTR2 *valuename, { fstring value; BOOL found=False; - int pnum = find_printer_index_by_hnd(handle); + Printer_entry *Printer = find_printer_index_by_hnd(handle); /* * Reminder: when it's a string, the length is in BYTES @@ -689,7 +693,7 @@ uint32 _spoolss_getprinterdata(const POLICY_HND *handle, UNISTR2 *valuename, DEBUG(4,("_spoolss_getprinterdata\n")); - if (!OPEN_HANDLE(pnum)) { + if (!OPEN_HANDLE(Printer)) { *data=(uint8 *)malloc(4*sizeof(uint8)); return NT_STATUS_INVALID_HANDLE; } @@ -729,20 +733,18 @@ uint32 _spoolss_rffpcnex(const POLICY_HND *handle, uint32 flags, uint32 options, const UNISTR2 *localmachine, uint32 printerlocal, SPOOL_NOTIFY_OPTION *option) { - int i; - /* store the notify value in the printer struct */ - i=find_printer_index_by_hnd(handle); + Printer_entry *Printer=find_printer_index_by_hnd(handle); - if (i == -1) + if (!OPEN_HANDLE(Printer)) return NT_STATUS_INVALID_HANDLE; - Printer[i].notify.flags=flags; - Printer[i].notify.options=options; - Printer[i].notify.printerlocal=printerlocal; - Printer[i].notify.option=option; - unistr2_to_ascii(Printer[i].notify.localmachine, localmachine, sizeof(Printer[i].notify.localmachine)-1); + Printer->notify.flags=flags; + Printer->notify.options=options; + Printer->notify.printerlocal=printerlocal; + Printer->notify.option=option; + unistr2_to_ascii(Printer->notify.localmachine, localmachine, sizeof(Printer->notify.localmachine)-1); return NT_STATUS_NO_PROBLEMO; } @@ -1316,7 +1318,7 @@ static BOOL construct_notify_jobs_info(print_queue_struct *queue, SPOOL_NOTIFY_I static uint32 printserver_notify_info(const POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info) { int snum; - int pnum=find_printer_index_by_hnd(hnd); + Printer_entry *Printer=find_printer_index_by_hnd(hnd); int n_services=lp_numservices(); int i; uint32 id; @@ -1325,7 +1327,7 @@ static uint32 printserver_notify_info(const POLICY_HND *hnd, SPOOL_NOTIFY_INFO * DEBUG(4,("printserver_notify_info\n")); - option=Printer[pnum].notify.option; + option=Printer->notify.option; id=1; info->version=2; info->data=NULL; @@ -1371,7 +1373,7 @@ static uint32 printserver_notify_info(const POLICY_HND *hnd, SPOOL_NOTIFY_INFO * static uint32 printer_notify_info(const POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info) { int snum; - int pnum=find_printer_index_by_hnd(hnd); + Printer_entry *Printer=find_printer_index_by_hnd(hnd); int i; uint32 id; SPOOL_NOTIFY_OPTION *option; @@ -1382,7 +1384,7 @@ static uint32 printer_notify_info(const POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info DEBUG(4,("printer_notify_info\n")); - option=Printer[pnum].notify.option; + option=Printer->notify.option; id=1; info->version=2; info->data=NULL; @@ -1435,14 +1437,12 @@ static uint32 printer_notify_info(const POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info uint32 _spoolss_rfnpcnex( const POLICY_HND *handle, uint32 change, SPOOL_NOTIFY_OPTION *option, SPOOL_NOTIFY_INFO *info) { - int pnum=find_printer_index_by_hnd(handle); + Printer_entry *Printer=find_printer_index_by_hnd(handle); - if (pnum == -1 || !OPEN_HANDLE(pnum)) - { + if (!OPEN_HANDLE(Printer)) return NT_STATUS_INVALID_HANDLE; - } - DEBUG(4,("Printer %x of type %x\n",pnum, Printer[pnum].printer_type)); + DEBUG(4,("Printer type %x\n",Printer->printer_type)); /* jfm: the change value isn't used right now. * we will honour it when @@ -1461,7 +1461,7 @@ uint32 _spoolss_rfnpcnex( const POLICY_HND *handle, uint32 change, safe_free(option); - switch (Printer[pnum].printer_type) { + switch (Printer->printer_type) { case PRINTER_HANDLE_IS_PRINTSERVER: return printserver_notify_info(handle, info); break; @@ -2403,15 +2403,15 @@ uint32 _spoolss_getprinterdriver2(const POLICY_HND *handle, const UNISTR2 *uni_a ****************************************************************************/ uint32 _spoolss_startpageprinter(const POLICY_HND *handle) { - int pnum = find_printer_index_by_hnd(handle); + Printer_entry *Printer = find_printer_index_by_hnd(handle); - if (OPEN_HANDLE(pnum)) + if (OPEN_HANDLE(Printer)) { - Printer[pnum].page_started=True; + Printer->page_started=True; return 0x0; } - DEBUG(3,("Error in startpageprinter printer handle (pnum=%x)\n",pnum)); + DEBUG(3,("Error in startpageprinter printer handle\n")); return NT_STATUS_INVALID_HANDLE; } @@ -2419,16 +2419,17 @@ uint32 _spoolss_startpageprinter(const POLICY_HND *handle) ****************************************************************************/ uint32 _spoolss_endpageprinter(const POLICY_HND *handle) { - int pnum = find_printer_index_by_hnd(handle); + Printer_entry *Printer = find_printer_index_by_hnd(handle); - if (OPEN_HANDLE(pnum)) + if (!OPEN_HANDLE(Printer)) { - Printer[pnum].page_started=False; - return 0x0; + DEBUG(3,("Error in endpageprinter printer handle\n")); + return NT_STATUS_INVALID_HANDLE; } + + Printer->page_started=False; - DEBUG(3,("Error in endpageprinter printer handle (pnum=%x)\n",pnum)); - return NT_STATUS_INVALID_HANDLE; + return NT_STATUS_NO_PROBLEMO; } @@ -2447,11 +2448,9 @@ uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level, pstring datatype; int fd = -1; int snum; - int pnum; - - pnum = find_printer_index_by_hnd(handle); + Printer_entry *Printer = find_printer_index_by_hnd(handle); - if (!VALID_HANDLE(pnum)) + if (!OPEN_HANDLE(Printer)) { return NT_STATUS_INVALID_HANDLE; } @@ -2494,16 +2493,14 @@ uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level, fd=open(fname, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR ); DEBUG(4,("Temp spool file created: [%s]\n", fname)); - Printer[pnum].current_jobid=fd; - pstrcpy(Printer[pnum].document_name,fname); + Printer->current_jobid=fd; + pstrcpy(Printer->document_name, fname); - unistr2_to_ascii(Printer[pnum].job_name, - &info_1->docname, - sizeof(Printer[pnum].job_name)); + unistr2_to_ascii(Printer->job_name, &info_1->docname, sizeof(Printer->job_name)); - Printer[pnum].document_fd=fd; - Printer[pnum].document_started=True; - (*jobid) = Printer[pnum].current_jobid; + Printer->document_fd=fd; + Printer->document_started=True; + (*jobid) = Printer->current_jobid; return 0x0; } @@ -2515,29 +2512,28 @@ uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level, ********************************************************************/ uint32 _spoolss_enddocprinter(const POLICY_HND *handle) { - int pnum; int snum; pstring filename; pstring filename1; pstring job_name; pstring syscmd; char *tstr; + Printer_entry *Printer=find_printer_index_by_hnd(handle); *syscmd=0; - pnum = find_printer_index_by_hnd(handle); - - if (!OPEN_HANDLE(pnum)) + if (!OPEN_HANDLE(Printer)) { - DEBUG(3,("Error in enddocprinter handle (pnum=%x)\n",pnum)); + DEBUG(3,("Error in enddocprinter handle\n")); return NT_STATUS_INVALID_HANDLE; } - Printer[pnum].document_started=False; - close(Printer[pnum].document_fd); + + Printer->document_started=False; + close(Printer->document_fd); DEBUG(4,("Temp spool file closed, printing now ...\n")); - pstrcpy(filename1, Printer[pnum].document_name); - pstrcpy(job_name, Printer[pnum].job_name); + pstrcpy(filename1, Printer->document_name); + pstrcpy(job_name, Printer->job_name); if (!get_printer_snum(handle,&snum)) { @@ -2607,20 +2603,18 @@ uint32 _spoolss_writeprinter( const POLICY_HND *handle, const uint8 *buffer, uint32 *buffer_written) { - int pnum; int fd; + Printer_entry *Printer = find_printer_index_by_hnd(handle); - pnum = find_printer_index_by_hnd(handle); - - if (!OPEN_HANDLE(pnum)) + if (!OPEN_HANDLE(Printer)) { - DEBUG(3,("Error in writeprinter handle (pnum=%x)\n",pnum)); + DEBUG(3,("Error in writeprinter handle\n")); return NT_STATUS_INVALID_HANDLE; } - fd = Printer[pnum].document_fd; + fd = Printer->document_fd; (*buffer_written) = write(fd, buffer, buffer_size); - Printer[pnum].document_lastwritten = (*buffer_written); + Printer->document_lastwritten = (*buffer_written); return 0x0; } @@ -2632,11 +2626,13 @@ uint32 _spoolss_writeprinter( const POLICY_HND *handle, ********************************************************************/ static uint32 control_printer(const POLICY_HND *handle, uint32 command) { - int pnum; int snum; - pnum = find_printer_index_by_hnd(handle); + Printer_entry *Printer = find_printer_index_by_hnd(handle); + + if (!OPEN_HANDLE(Printer)) + return NT_STATUS_INVALID_HANDLE; - if ( pnum == -1 || !get_printer_snum(handle, &snum) ) + if (!get_printer_snum(handle, &snum) ) { return NT_STATUS_INVALID_HANDLE; } @@ -2669,11 +2665,11 @@ static uint32 update_printer(const POLICY_HND *handle, uint32 level, const SPOOL_PRINTER_INFO_LEVEL *info, const DEVICEMODE *devmode) { - int pnum; int snum; NT_PRINTER_INFO_LEVEL printer; NT_DEVICEMODE *nt_devmode; uint32 status = 0x0; + Printer_entry *Printer = find_printer_index_by_hnd(handle); nt_devmode=NULL; @@ -2686,11 +2682,12 @@ static uint32 update_printer(const POLICY_HND *handle, uint32 level, return NT_STATUS_INVALID_INFO_CLASS; } - pnum = find_printer_index_by_hnd(handle); - if ( pnum == -1 || !get_printer_snum(handle, &snum) ) - { + if (!OPEN_HANDLE(Printer)) return NT_STATUS_INVALID_HANDLE; - } + + if (!get_printer_snum(handle, &snum) ) + return NT_STATUS_INVALID_HANDLE; + get_a_printer(&printer, level, lp_servicename(snum)); DEBUGADD(8,("Converting info_2 struct\n")); @@ -2744,17 +2741,20 @@ uint32 _spoolss_setprinter( const POLICY_HND *handle, const char *sec_buf, uint32 command) { - int pnum = find_printer_index_by_hnd(handle); + Printer_entry *Printer = find_printer_index_by_hnd(handle); - if (!OPEN_HANDLE(pnum)) - { + if (!OPEN_HANDLE(Printer)) return NT_STATUS_INVALID_HANDLE; - } + /* check the level */ switch (level) { - case 0: return control_printer(handle, command); - case 2: return update_printer(handle, level, info, devmode); + case 0: + return control_printer(handle, command); + break; + case 2: + return update_printer(handle, level, info, devmode); + break; } return NT_STATUS_INVALID_INFO_CLASS; @@ -2764,19 +2764,17 @@ uint32 _spoolss_setprinter( const POLICY_HND *handle, ****************************************************************************/ uint32 _spoolss_fcpn(const POLICY_HND *handle) { - int pnum = find_printer_index_by_hnd(handle); + Printer_entry *Printer= find_printer_index_by_hnd(handle); - if (!OPEN_HANDLE(pnum)) - { + if (!OPEN_HANDLE(Printer)) return NT_STATUS_INVALID_HANDLE; - } - Printer[pnum].notify.flags=0; - Printer[pnum].notify.options=0; - Printer[pnum].notify.localmachine[0]='\0'; - Printer[pnum].notify.printerlocal=0; - safe_free(Printer[pnum].notify.option); - Printer[pnum].notify.option=NULL; + Printer->notify.flags=0; + Printer->notify.options=0; + Printer->notify.localmachine[0]='\0'; + Printer->notify.printerlocal=0; + safe_free(Printer->notify.option); + Printer->notify.option=NULL; return NT_STATUS_NO_PROBLEMO; } @@ -3608,9 +3606,8 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 biggest_valuesize; uint32 biggest_datasize; uint32 data_len; - uint32 status = 0x0; - - int pnum = find_printer_index_by_hnd(handle); + uint32 status = 0x0; + Printer_entry *Printer = find_printer_index_by_hnd(handle); int snum; ZERO_STRUCT(printer); @@ -3618,20 +3615,16 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, DEBUG(5,("spoolss_enumprinterdata\n")); - if (!OPEN_HANDLE(pnum)) - { + if (!OPEN_HANDLE(Printer)) return NT_STATUS_INVALID_HANDLE; - } + if (!get_printer_snum(handle, &snum)) - { return NT_STATUS_INVALID_HANDLE; - } + status = get_a_printer(&printer, 2, lp_servicename(snum)); if (status != 0x0) - { return status; - } /* The NT machine wants to know the biggest size of value and data */ if ( ((*valuesize)==0) && ((*datasize)==0) ) @@ -3711,28 +3704,22 @@ uint32 _spoolss_setprinterdata( const POLICY_HND *handle, NT_PRINTER_INFO_LEVEL printer; NT_PRINTER_PARAM *param = NULL; - int pnum=0; int snum=0; uint32 status = 0x0; + Printer_entry *Printer=find_printer_index_by_hnd(handle); DEBUG(5,("spoolss_setprinterdata\n")); - pnum = find_printer_index_by_hnd(handle); - if (!OPEN_HANDLE(pnum)) - { + if (!OPEN_HANDLE(Printer)) return NT_STATUS_INVALID_HANDLE; - } + if (!get_printer_snum(handle, &snum)) - { return NT_STATUS_INVALID_HANDLE; - } status = get_a_printer(&printer, 2, lp_servicename(snum)); if (status != 0x0) - { return status; - } convert_specific_param(¶m, value , type, data, real_len); unlink_specific_param_if_exist(printer.info_2, param); @@ -3756,18 +3743,14 @@ uint32 _spoolss_addform( const POLICY_HND *handle, uint32 level, const FORM *form) { - int pnum=0; int count=0; nt_forms_struct *list=NULL; + Printer_entry *Printer = find_printer_index_by_hnd(handle); DEBUG(5,("spoolss_addform\n")); - pnum = find_printer_index_by_hnd(handle); - - if (!OPEN_HANDLE(pnum)) - { + if (!OPEN_HANDLE(Printer)) return NT_STATUS_INVALID_HANDLE; - } count=get_ntforms(&list); add_a_form(&list, form, &count); @@ -3785,14 +3768,13 @@ uint32 _spoolss_setform( const POLICY_HND *handle, uint32 level, const FORM *form) { - int pnum=0; int count=0; nt_forms_struct *list=NULL; + Printer_entry *Printer = find_printer_index_by_hnd(handle); DEBUG(5,("spoolss_setform\n")); - pnum = find_printer_index_by_hnd(handle); - if (!OPEN_HANDLE(pnum)) + if (!OPEN_HANDLE(Printer)) { return NT_STATUS_INVALID_HANDLE; } -- cgit From 9f6ad046761adecafba59040baa3abc9f0959e65 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 25 Feb 2000 22:25:25 +0000 Subject: client/client.c: libsmb/clientgen.c: Fixes for Win2k smbclient browsing. Other fixes implement smbpasswd -x user to delete users. Also allows swat to do the same. Jeremy. --- source/client/client.c | 7 +- source/include/proto.h | 7 +- source/include/smb.h | 12 ++ source/libsmb/clientgen.c | 10 +- source/passdb/ldap.c | 6 + source/passdb/nispass.c | 6 + source/passdb/passdb.c | 9 ++ source/passdb/smbpass.c | 358 ++++++++++++++++++++++++++++++++++-------- source/passdb/smbpasschange.c | 70 +++++---- source/utils/smbpasswd.c | 96 +++++------ source/web/swat.c | 40 +++-- 11 files changed, 453 insertions(+), 168 deletions(-) diff --git a/source/client/client.c b/source/client/client.c index 6beff70c9bc..ea029d4df7f 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -1560,10 +1560,15 @@ try and browse available connections on a host ****************************************************************************/ static BOOL browse_host(BOOL sort) { + int ret; + printf("\n\tSharename Type Comment\n"); printf("\t--------- ---- -------\n"); - return cli_RNetShareEnum(cli, browse_fn); + if((ret = cli_RNetShareEnum(cli, browse_fn)) == -1) + printf("Error returning browse list: %s\n", cli_errstr(cli)); + + return (ret != -1); } /**************************************************************************** diff --git a/source/include/proto.h b/source/include/proto.h index 934ec5a4c82..830e7bc5b1f 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -573,7 +573,7 @@ BOOL cli_api(struct cli_state *cli, char **rparam, int *rprcnt, char **rdata, int *rdrcnt); BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation); -BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)); +int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)); BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, void (*fn)(const char *, uint32, const char *)); BOOL cli_session_setup(struct cli_state *cli, @@ -1426,6 +1426,7 @@ void endsmbpwent(void *vp); struct smb_passwd *getsmbpwent(void *vp); BOOL add_smbpwd_entry(struct smb_passwd *newpwd); BOOL mod_smbpwd_entry(struct smb_passwd* pwd, BOOL override); +BOOL del_smbpwd_entry(const char *name); struct smb_passwd *getsmbpwnam(char *name); struct smb_passwd *getsmbpwrid(uint32 user_rid); struct smb_passwd *getsmbpwuid(uid_t smb_userid); @@ -1464,12 +1465,12 @@ BOOL lookup_local_name(char *domain, char *user, DOM_SID *psid, uint8 *psid_name /*The following definitions come from passdb/smbpass.c */ +char *format_new_smbpasswd_entry(struct smb_passwd *newpwd); struct passdb_ops *file_initialize_password_db(void); /*The following definitions come from passdb/smbpasschange.c */ -BOOL local_password_change(char *user_name, BOOL trust_account, BOOL add_user, - BOOL enable_user, BOOL disable_user, BOOL set_no_password, +BOOL local_password_change(char *user_name, int local_flags, char *new_passwd, char *err_str, size_t err_str_len, char *msg_str, size_t msg_str_len); diff --git a/source/include/smb.h b/source/include/smb.h index 18b2cb15424..54fb4d5cc7c 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -747,6 +747,7 @@ struct passdb_ops { */ BOOL (*add_smbpwd_entry)(struct smb_passwd *); BOOL (*mod_smbpwd_entry)(struct smb_passwd *, BOOL); + BOOL (*del_smbpwd_entry)(const char *); /* * Functions that manupulate a struct sam_passwd. @@ -783,6 +784,17 @@ struct passdb_ops { #endif }; +/* + * Flags for local user manipulation. + */ + +#define LOCAL_ADD_USER 0x1 +#define LOCAL_DELETE_USER 0x2 +#define LOCAL_DISABLE_USER 0x4 +#define LOCAL_ENABLE_USER 0x8 +#define LOCAL_TRUST_ACCOUNT 0x10 +#define LOCAL_SET_NO_PASSWORD 0x20 + /* key and data in the connections database - used in smbstatus and smbd */ struct connections_key { pid_t pid; diff --git a/source/libsmb/clientgen.c b/source/libsmb/clientgen.c index df3df0b4ba3..8d7dbec8590 100644 --- a/source/libsmb/clientgen.c +++ b/source/libsmb/clientgen.c @@ -600,7 +600,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) /**************************************************************************** call a NetShareEnum - try and browse available connections on a host ****************************************************************************/ -BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)) +int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)) { char *rparam = NULL; char *rdata = NULL; @@ -618,12 +618,16 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, c pstrcpy(p,"B13BWz"); p = skip_string(p,1); SSVAL(p,0,1); - SSVAL(p,2,0xFFFF); + /* + * Win2k needs a *smaller* buffer than 0xFFFF here - + * it returns "out of server memory" with 0xFFFF !!! JRA. + */ + SSVAL(p,2,0xFFE0); p += 4; if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ - NULL, 0, 0xFFFF, /* data, length, maxlen */ + NULL, 0, 0xFFE0, /* data, length, maxlen - Win2k needs a small buffer here too ! */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ { diff --git a/source/passdb/ldap.c b/source/passdb/ldap.c index 43fea00a644..54566e454b9 100644 --- a/source/passdb/ldap.c +++ b/source/passdb/ldap.c @@ -970,6 +970,11 @@ static BOOL mod_ldappwd_entry(struct smb_passwd* pwd, BOOL override) return mod_ldap21pwd_entry(pdb_smb_to_sam(pwd), override); } +static BOOL del_ldappwd_entry(const char *name) +{ + return False; /* Dummy... */ +} + static struct sam_disp_info *getldapdispnam(char *name) { return pdb_sam_to_dispinfo(getldap21pwnam(name)); @@ -1002,6 +1007,7 @@ static struct passdb_ops ldap_ops = getldappwent, add_ldappwd_entry, mod_ldappwd_entry, + del_ldappwd_entry, getldap21pwent, iterate_getsam21pwnam, /* From passdb.c */ iterate_getsam21pwuid, /* From passdb.c */ diff --git a/source/passdb/nispass.c b/source/passdb/nispass.c index 27409eca4cd..4b4e281c29d 100644 --- a/source/passdb/nispass.c +++ b/source/passdb/nispass.c @@ -1005,6 +1005,11 @@ static BOOL mod_nisppwd_entry(struct smb_passwd* pwd, BOOL override) return mod_nisp21pwd_entry(pdb_smb_to_sam(pwd), override); } +static BOOL del_nisppwd_entry(const char *name) +{ + return False; /* Dummy. */ +} + static struct smb_passwd *getnisppwnam(char *name) { return pdb_sam_to_smb(getnisp21pwnam(name)); @@ -1051,6 +1056,7 @@ static struct passdb_ops nispasswd_ops = { getnisppwent, add_nisppwd_entry, mod_nisppwd_entry, + del_nisppwd_entry, getnisp21pwent, getnisp21pwnam, getnisp21pwuid, diff --git a/source/passdb/passdb.c b/source/passdb/passdb.c index f6502c238c4..30ea1d9bd6e 100644 --- a/source/passdb/passdb.c +++ b/source/passdb/passdb.c @@ -225,6 +225,15 @@ BOOL mod_smbpwd_entry(struct smb_passwd* pwd, BOOL override) return pdb_ops->mod_smbpwd_entry(pwd, override); } +/************************************************************************ + Routine to delete an entry from the smb passwd file. +*************************************************************************/ + +BOOL del_smbpwd_entry(const char *name) +{ + return pdb_ops->del_smbpwd_entry(name); +} + /************************************************************************ Routine to search smb passwd by name. *************************************************************************/ diff --git a/source/passdb/smbpass.c b/source/passdb/smbpass.c index 4cfac6d9484..4ca37a92965 100644 --- a/source/passdb/smbpass.c +++ b/source/passdb/smbpass.c @@ -28,39 +28,127 @@ extern BOOL sam_logon_in_ssb; static char s_readbuf[1024]; static int pw_file_lock_depth; +enum pwf_access_type { PWF_READ, PWF_UPDATE, PWF_CREATE }; + /*************************************************************** - Start to enumerate the smbpasswd list. Returns a void pointer - to ensure no modification outside this module. + Internal fn to enumerate the smbpasswd list. Returns a void pointer + to ensure no modification outside this module. Checks for atomic + rename of smbpasswd file on update or create once the lock has + been granted to prevent race conditions. JRA. ****************************************************************/ -static void *startsmbfilepwent(BOOL update) +static void *startsmbfilepwent_internal(const char *pfile, enum pwf_access_type type, int *lock_depth) { FILE *fp = NULL; - char *pfile = lp_smb_passwd_file(); + const char *open_mode = NULL; + int race_loop = 0; + int lock_type; if (!*pfile) { DEBUG(0, ("startsmbfilepwent: No SMB password file set\n")); return (NULL); } - DEBUG(10, ("startsmbfilepwent: opening file %s\n", pfile)); - fp = sys_fopen(pfile, update ? "r+b" : "rb"); + switch(type) { + case PWF_READ: + open_mode = "rb"; + lock_type = F_RDLCK; + break; + case PWF_UPDATE: + open_mode = "r+b"; + lock_type = F_WRLCK; + break; + case PWF_CREATE: + /* + * Ensure atomic file creation. + */ + { + int i, fd = -1; - if (fp == NULL) { - DEBUG(0, ("startsmbfilepwent: unable to open file %s\n", pfile)); - return NULL; + for(i = 0; i < 5; i++) { + if((fd = sys_open(pfile, O_CREAT|O_TRUNC|O_EXCL|O_RDWR, 0600))!=-1) + break; + sys_usleep(200); /* Spin, spin... */ + } + if(fd == -1) { + DEBUG(0,("startsmbfilepwent_internal: too many race conditions creating file %s\n", pfile)); + return NULL; + } + close(fd); + open_mode = "r+b"; + lock_type = F_WRLCK; + break; + } } + + for(race_loop = 0; race_loop < 5; race_loop++) { + DEBUG(10, ("startsmbfilepwent_internal: opening file %s\n", pfile)); - /* Set a buffer to do more efficient reads */ - setvbuf(fp, s_readbuf, _IOFBF, sizeof(s_readbuf)); + if((fp = sys_fopen(pfile, open_mode)) == NULL) { + DEBUG(0, ("startsmbfilepwent_internal: unable to open file %s. Error was %s\n", pfile, strerror(errno) )); + return NULL; + } - if (!pw_file_lock(fileno(fp), (update ? F_WRLCK : F_RDLCK), 5, &pw_file_lock_depth)) - { - DEBUG(0, ("startsmbfilepwent: unable to lock file %s\n", pfile)); - fclose(fp); + if (!pw_file_lock(fileno(fp), lock_type, 5, lock_depth)) { + DEBUG(0, ("startsmbfilepwent_internal: unable to lock file %s. Error was %s\n", pfile, strerror(errno) )); + fclose(fp); + return NULL; + } + + /* + * Only check for replacement races on update or create. + * For read we don't mind if the data is one record out of date. + */ + + if(type == PWF_READ) { + break; + } else { + SMB_STRUCT_STAT sbuf1, sbuf2; + + /* + * Avoid the potential race condition between the open and the lock + * by doing a stat on the filename and an fstat on the fd. If the + * two inodes differ then someone did a rename between the open and + * the lock. Back off and try the open again. Only do this 5 times to + * prevent infinate loops. JRA. + */ + + if (sys_stat(pfile,&sbuf1) != 0) { + DEBUG(0, ("startsmbfilepwent_internal: unable to stat file %s. Error was %s\n", pfile, strerror(errno))); + pw_file_unlock(fileno(fp), lock_depth); + fclose(fp); + return False; + } + + if (sys_fstat(fileno(fp),&sbuf2) != 0) { + DEBUG(0, ("startsmbfilepwent_internal: unable to fstat file %s. Error was %s\n", pfile, strerror(errno))); + pw_file_unlock(fileno(fp), lock_depth); + fclose(fp); + return False; + } + + if( sbuf1.st_ino == sbuf2.st_ino) { + /* No race. */ + break; + } + + /* + * Race occurred - back off and try again... + */ + + pw_file_unlock(fileno(fp), lock_depth); + fclose(fp); + } + } + + if(race_loop == 5) { + DEBUG(0, ("startsmbfilepwent_internal: too many race conditions opening file %s\n", pfile)); return NULL; } + /* Set a buffer to do more efficient reads */ + setvbuf(fp, s_readbuf, _IOFBF, sizeof(s_readbuf)); + /* Make sure it is only rw by the owner */ chmod(pfile, 0600); @@ -68,22 +156,43 @@ static void *startsmbfilepwent(BOOL update) return (void *)fp; } +/*************************************************************** + Start to enumerate the smbpasswd list. Returns a void pointer + to ensure no modification outside this module. +****************************************************************/ + +static void *startsmbfilepwent(BOOL update) +{ + return startsmbfilepwent_internal(lp_smb_passwd_file(), update ? PWF_UPDATE : PWF_READ, &pw_file_lock_depth); +} + /*************************************************************** End enumeration of the smbpasswd list. ****************************************************************/ -static void endsmbfilepwent(void *vp) +static void endsmbfilepwent_internal(void *vp, int *lock_depth) { FILE *fp = (FILE *)vp; - pw_file_unlock(fileno(fp), &pw_file_lock_depth); + pw_file_unlock(fileno(fp), lock_depth); fclose(fp); - DEBUG(7, ("endsmbfilepwent: closed password file.\n")); + DEBUG(7, ("endsmbfilepwent_internal: closed password file.\n")); +} + +/*************************************************************** + End enumeration of the smbpasswd list - operate on the default + lock_depth. +****************************************************************/ + +static void endsmbfilepwent(void *vp) +{ + endsmbfilepwent_internal(vp, &pw_file_lock_depth); } /************************************************************************* Routine to return the next entry in the smbpasswd list. *************************************************************************/ + static struct smb_passwd *getsmbfilepwent(void *vp) { /* Static buffers we will return. */ @@ -431,6 +540,65 @@ static BOOL setsmbfilepwpos(void *vp, SMB_BIG_UINT tok) return !sys_fseek((FILE *)vp, (SMB_OFF_T)tok, SEEK_SET); } +/************************************************************************ + Create a new smbpasswd entry - malloced space returned. +*************************************************************************/ + +char *format_new_smbpasswd_entry(struct smb_passwd *newpwd) +{ + int new_entry_length; + char *new_entry; + char *p; + int i; + + new_entry_length = strlen(newpwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + NEW_PW_FORMAT_SPACE_PADDED_LEN + 1 + 13 + 2; + + if((new_entry = (char *)malloc( new_entry_length )) == NULL) { + DEBUG(0, ("format_new_smbpasswd_entry: Malloc failed adding entry for user %s.\n", newpwd->smb_name )); + return NULL; + } + + slprintf(new_entry, new_entry_length - 1, "%s:%u:", newpwd->smb_name, (unsigned)newpwd->smb_userid); + p = &new_entry[strlen(new_entry)]; + + if(newpwd->smb_passwd != NULL) { + for( i = 0; i < 16; i++) { + slprintf((char *)&p[i*2], new_entry_length - (p - new_entry) - 1, "%02X", newpwd->smb_passwd[i]); + } + } else { + i=0; + if(newpwd->acct_ctrl & ACB_PWNOTREQ) + safe_strcpy((char *)p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry)); + else + safe_strcpy((char *)p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry)); + } + + p += 32; + + *p++ = ':'; + + if(newpwd->smb_nt_passwd != NULL) { + for( i = 0; i < 16; i++) { + slprintf((char *)&p[i*2], new_entry_length - 1 - (p - new_entry), "%02X", newpwd->smb_nt_passwd[i]); + } + } else { + if(newpwd->acct_ctrl & ACB_PWNOTREQ) + safe_strcpy((char *)p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry)); + else + safe_strcpy((char *)p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry)); + } + + p += 32; + + *p++ = ':'; + + /* Add the account encoding and the last change time. */ + slprintf((char *)p, new_entry_length - 1 - (p - new_entry), "%s:LCT-%08X:\n", + pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN), (uint32)time(NULL)); + + return new_entry; +} + /************************************************************************ Routine to add an entry to the smbpasswd file. *************************************************************************/ @@ -440,15 +608,11 @@ static BOOL add_smbfilepwd_entry(struct smb_passwd *newpwd) char *pfile = lp_smb_passwd_file(); struct smb_passwd *pwd = NULL; FILE *fp = NULL; - - int i; int wr_len; - int fd; - int new_entry_length; + size_t new_entry_length; char *new_entry; SMB_OFF_T offpos; - char *p; /* Open the smbpassword file - for update. */ fp = startsmbfilepwent(True); @@ -486,59 +650,21 @@ Error was %s\n", newpwd->smb_name, pfile, strerror(errno))); return False; } - new_entry_length = strlen(newpwd->smb_name) + 1 + 15 + 1 + 32 + 1 + 32 + 1 + NEW_PW_FORMAT_SPACE_PADDED_LEN + 1 + 13 + 2; - - if((new_entry = (char *)malloc( new_entry_length )) == NULL) { + if((new_entry = format_new_smbpasswd_entry(newpwd)) == NULL) { DEBUG(0, ("add_smbfilepwd_entry(malloc): Failed to add entry for user %s to file %s. \ Error was %s\n", newpwd->smb_name, pfile, strerror(errno))); endsmbfilepwent(fp); return False; } - slprintf(new_entry, new_entry_length - 1, "%s:%u:", newpwd->smb_name, (unsigned)newpwd->smb_userid); - p = &new_entry[strlen(new_entry)]; - - if(newpwd->smb_passwd != NULL) { - for( i = 0; i < 16; i++) { - slprintf((char *)&p[i*2], new_entry_length - (p - new_entry) - 1, "%02X", newpwd->smb_passwd[i]); - } - } else { - i=0; - if(newpwd->acct_ctrl & ACB_PWNOTREQ) - safe_strcpy((char *)p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry)); - else - safe_strcpy((char *)p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry)); - } - - p += 32; - - *p++ = ':'; - - if(newpwd->smb_nt_passwd != NULL) { - for( i = 0; i < 16; i++) { - slprintf((char *)&p[i*2], new_entry_length - 1 - (p - new_entry), "%02X", newpwd->smb_nt_passwd[i]); - } - } else { - if(newpwd->acct_ctrl & ACB_PWNOTREQ) - safe_strcpy((char *)p, "NO PASSWORDXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry)); - else - safe_strcpy((char *)p, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", new_entry_length - 1 - (p - new_entry)); - } - - p += 32; - - *p++ = ':'; - - /* Add the account encoding and the last change time. */ - slprintf((char *)p, new_entry_length - 1 - (p - new_entry), "%s:LCT-%08X:\n", - pdb_encode_acct_ctrl(newpwd->acct_ctrl, NEW_PW_FORMAT_SPACE_PADDED_LEN), (uint32)time(NULL)); + new_entry_length = strlen(new_entry); #ifdef DEBUG_PASSWORD - DEBUG(100, ("add_smbfilepwd_entry(%d): new_entry_len %d entry_len %d made line |%s|", - fd, new_entry_length, strlen(new_entry), new_entry)); + DEBUG(100, ("add_smbfilepwd_entry(%d): new_entry_len %d made line |%s|", + fd, new_entry_length, new_entry)); #endif - if ((wr_len = write(fd, new_entry, strlen(new_entry))) != strlen(new_entry)) { + if ((wr_len = write(fd, new_entry, new_entry_length)) != new_entry_length) { DEBUG(0, ("add_smbfilepwd_entry(write): %d Failed to add entry for user %s to file %s. \ Error was %s\n", wr_len, newpwd->smb_name, pfile, strerror(errno))); @@ -960,6 +1086,105 @@ static BOOL mod_smbfilepwd_entry(struct smb_passwd* pwd, BOOL override) return True; } +/************************************************************************ + Routine to delete an entry in the smbpasswd file by name. +*************************************************************************/ + +static BOOL del_smbfilepwd_entry(const char *name) +{ + char *pfile = lp_smb_passwd_file(); + pstring pfile2; + struct smb_passwd *pwd = NULL; + FILE *fp = NULL; + FILE *fp_write = NULL; + int pfile2_lockdepth = 0; + + slprintf(pfile2, sizeof(pfile2)-1, "%s.%u", pfile, (unsigned)getpid() ); + + /* + * Open the smbpassword file - for update. It needs to be update + * as we need any other processes to wait until we have replaced + * it. + */ + + if((fp = startsmbfilepwent(True)) == NULL) { + DEBUG(0, ("del_smbfilepwd_entry: unable to open file %s.\n", pfile)); + return False; + } + + /* + * Create the replacement password file. + */ + if((fp_write = startsmbfilepwent_internal(pfile2, PWF_CREATE, &pfile2_lockdepth)) == NULL) { + DEBUG(0, ("del_smbfilepwd_entry: unable to open file %s.\n", pfile)); + endsmbfilepwent(fp); + return False; + } + + /* + * Scan the file, a line at a time and check if the name matches. + */ + + while ((pwd = getsmbfilepwent(fp)) != NULL) { + char *new_entry; + size_t new_entry_length; + + if (strequal(name, pwd->smb_name)) { + DEBUG(10, ("add_smbfilepwd_entry: found entry with name %s - deleting it.\n", name)); + continue; + } + + /* + * We need to copy the entry out into the second file. + */ + + if((new_entry = format_new_smbpasswd_entry(pwd)) == NULL) { + DEBUG(0, ("del_smbfilepwd_entry(malloc): Failed to copy entry for user %s to file %s. \ +Error was %s\n", pwd->smb_name, pfile2, strerror(errno))); + unlink(pfile2); + endsmbfilepwent(fp); + endsmbfilepwent_internal(fp_write,&pfile2_lockdepth); + return False; + } + + new_entry_length = strlen(new_entry); + + if(fwrite(new_entry, 1, new_entry_length, fp_write) != new_entry_length) { + DEBUG(0, ("del_smbfilepwd_entry(write): Failed to copy entry for user %s to file %s. \ +Error was %s\n", pwd->smb_name, pfile2, strerror(errno))); + unlink(pfile2); + endsmbfilepwent(fp); + endsmbfilepwent_internal(fp_write,&pfile2_lockdepth); + free(new_entry); + return False; + } + + free(new_entry); + } + + /* + * Ensure pfile2 is flushed before rename. + */ + + if(fflush(fp_write) != 0) { + DEBUG(0, ("del_smbfilepwd_entry: Failed to flush file %s. Error was %s\n", pfile2, strerror(errno))); + endsmbfilepwent(fp); + endsmbfilepwent_internal(fp_write,&pfile2_lockdepth); + return False; + } + + /* + * Do an atomic rename - then release the locks. + */ + + if(rename(pfile2,pfile) != 0) { + unlink(pfile2); + } + endsmbfilepwent(fp); + endsmbfilepwent_internal(fp_write,&pfile2_lockdepth); + return True; +} + /* * Stub functions - implemented in terms of others. */ @@ -1000,6 +1225,7 @@ static struct passdb_ops file_ops = { getsmbfilepwent, add_smbfilepwd_entry, mod_smbfilepwd_entry, + del_smbfilepwd_entry, getsmbfile21pwent, iterate_getsam21pwnam, iterate_getsam21pwuid, diff --git a/source/passdb/smbpasschange.c b/source/passdb/smbpasschange.c index 9d0aecf8b8a..0348a2b97b1 100644 --- a/source/passdb/smbpasschange.c +++ b/source/passdb/smbpasschange.c @@ -25,8 +25,8 @@ /************************************************************* add a new user to the local smbpasswd file *************************************************************/ -static BOOL add_new_user(char *user_name, uid_t uid, BOOL trust_account, - BOOL disable_user, BOOL set_no_password, + +static BOOL add_new_user(char *user_name, uid_t uid, int local_flags, uchar *new_p16, uchar *new_nt_p16) { struct smb_passwd new_smb_pwent; @@ -36,16 +36,17 @@ static BOOL add_new_user(char *user_name, uid_t uid, BOOL trust_account, new_smb_pwent.smb_name = user_name; new_smb_pwent.smb_passwd = NULL; new_smb_pwent.smb_nt_passwd = NULL; - new_smb_pwent.acct_ctrl = (trust_account ? ACB_WSTRUST : ACB_NORMAL); + new_smb_pwent.acct_ctrl = ((local_flags & LOCAL_TRUST_ACCOUNT) ? ACB_WSTRUST : ACB_NORMAL); - if(disable_user) { + if(local_flags & LOCAL_DISABLE_USER) { new_smb_pwent.acct_ctrl |= ACB_DISABLED; - } else if (set_no_password) { + } else if (local_flags & LOCAL_SET_NO_PASSWORD) { new_smb_pwent.acct_ctrl |= ACB_PWNOTREQ; } else { new_smb_pwent.smb_passwd = new_p16; new_smb_pwent.smb_nt_passwd = new_nt_p16; } + return add_smbpwd_entry(&new_smb_pwent); } @@ -55,13 +56,12 @@ static BOOL add_new_user(char *user_name, uid_t uid, BOOL trust_account, change a password entry in the local smbpasswd file *************************************************************/ -BOOL local_password_change(char *user_name, BOOL trust_account, BOOL add_user, - BOOL enable_user, BOOL disable_user, BOOL set_no_password, +BOOL local_password_change(char *user_name, int local_flags, char *new_passwd, char *err_str, size_t err_str_len, char *msg_str, size_t msg_str_len) { - struct passwd *pwd; + struct passwd *pwd = NULL; void *vp; struct smb_passwd *smb_pwent; uchar new_p16[16]; @@ -70,17 +70,18 @@ BOOL local_password_change(char *user_name, BOOL trust_account, BOOL add_user, *err_str = '\0'; *msg_str = '\0'; - pwd = sys_getpwnam(user_name); + if (local_flags & LOCAL_ADD_USER) { - /* - * Check for a local account. - */ + /* + * Check for a local account - if we're adding only. + */ - if(!pwd) { - slprintf(err_str, err_str_len - 1, "User %s does not \ + if(!(pwd = sys_getpwnam(user_name))) { + slprintf(err_str, err_str_len - 1, "User %s does not \ exist in system password file (usually /etc/passwd). Cannot add \ account without a valid local system user.\n", user_name); - return False; + return False; + } } /* Calculate the MD4 hash (NT compatible) of the new password. */ @@ -111,15 +112,14 @@ account without a valid local system user.\n", user_name); /* Get the smb passwd entry for this user */ smb_pwent = getsmbpwnam(user_name); if (smb_pwent == NULL) { - if(add_user == False) { + if(!(local_flags & LOCAL_ADD_USER)) { slprintf(err_str, err_str_len-1, - "Failed to find entry for user %s.\n", pwd->pw_name); + "Failed to find entry for user %s.\n", user_name); endsmbpwent(vp); return False; } - if (add_new_user(user_name, pwd->pw_uid, trust_account, disable_user, - set_no_password, new_p16, new_nt_p16)) { + if (add_new_user(user_name, pwd->pw_uid, local_flags, new_p16, new_nt_p16)) { slprintf(msg_str, msg_str_len-1, "Added user %s.\n", user_name); endsmbpwent(vp); return True; @@ -130,7 +130,7 @@ account without a valid local system user.\n", user_name); } } else { /* the entry already existed */ - add_user = False; + local_flags &= ~LOCAL_ADD_USER; } /* @@ -138,15 +138,15 @@ account without a valid local system user.\n", user_name); * and the valid last change time. */ - if(disable_user) { + if(local_flags & LOCAL_DISABLE_USER) { smb_pwent->acct_ctrl |= ACB_DISABLED; - } else if (enable_user) { + } else if (local_flags & LOCAL_ENABLE_USER) { if(smb_pwent->smb_passwd == NULL) { smb_pwent->smb_passwd = new_p16; smb_pwent->smb_nt_passwd = new_nt_p16; } smb_pwent->acct_ctrl &= ~ACB_DISABLED; - } else if (set_no_password) { + } else if (local_flags & LOCAL_SET_NO_PASSWORD) { smb_pwent->acct_ctrl |= ACB_PWNOTREQ; /* This is needed to preserve ACB_PWNOTREQ in mod_smbfilepwd_entry */ smb_pwent->smb_passwd = NULL; @@ -168,11 +168,25 @@ account without a valid local system user.\n", user_name); smb_pwent->smb_nt_passwd = new_nt_p16; } - if(mod_smbpwd_entry(smb_pwent,True) == False) { - slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", - pwd->pw_name); - endsmbpwent(vp); - return False; + if(local_flags & LOCAL_DELETE_USER) { + if (del_smbpwd_entry(user_name)==False) { + slprintf(err_str,err_str_len-1, "Failed to delete entry for user %s.\n", user_name); + endsmbpwent(vp); + return False; + } + slprintf(msg_str, msg_str_len-1, "Deleted user %s.\n", user_name); + } else { + if(mod_smbpwd_entry(smb_pwent,True) == False) { + slprintf(err_str, err_str_len-1, "Failed to modify entry for user %s.\n", user_name); + endsmbpwent(vp); + return False; + } + if(local_flags & LOCAL_DISABLE_USER) + slprintf(msg_str, msg_str_len-1, "Disabled user %s.\n", user_name); + else if (local_flags & LOCAL_ENABLE_USER) + slprintf(msg_str, msg_str_len-1, "Enabled user %s.\n", user_name); + else if (local_flags & LOCAL_SET_NO_PASSWORD) + slprintf(msg_str, msg_str_len-1, "User %s password set to none.\n", user_name); } endsmbpwent(vp); diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c index ec6ce15f07d..dcfafaa8b92 100644 --- a/source/utils/smbpasswd.c +++ b/source/utils/smbpasswd.c @@ -63,6 +63,7 @@ static void usage(void) printf(" -R ORDER name resolve order\n"); printf(" -j DOMAIN join domain name\n"); printf(" -a add user\n"); + printf(" -x delete user\n"); printf(" -d disable user\n"); printf(" -e enable user\n"); printf(" -n set no password\n"); @@ -218,20 +219,19 @@ static char *prompt_for_new_password(BOOL stdin_get) /************************************************************* -change a password either locally or remotely + Change a password either locally or remotely. *************************************************************/ + static BOOL password_change(const char *remote_machine, char *user_name, - char *old_passwd, char *new_passwd, - BOOL add_user, BOOL enable_user, - BOOL disable_user, BOOL set_no_password, - BOOL trust_account) + char *old_passwd, char *new_passwd, int local_flags) { BOOL ret; pstring err_str; pstring msg_str; if (remote_machine != NULL) { - if (add_user || enable_user || disable_user || set_no_password || trust_account) { + if (local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER|LOCAL_DISABLE_USER|LOCAL_ENABLE_USER| + LOCAL_TRUST_ACCOUNT|LOCAL_SET_NO_PASSWORD)) { /* these things can't be done remotely yet */ return False; } @@ -242,8 +242,7 @@ static BOOL password_change(const char *remote_machine, char *user_name, return ret; } - ret = local_password_change(user_name, trust_account, add_user, enable_user, - disable_user, set_no_password, new_passwd, + ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str), msg_str, sizeof(msg_str)); if(*msg_str) @@ -256,18 +255,15 @@ static BOOL password_change(const char *remote_machine, char *user_name, /************************************************************* -handle password changing for root + Handle password changing for root. *************************************************************/ + static int process_root(int argc, char *argv[]) { struct passwd *pwd; int ch; BOOL joining_domain = False; - BOOL trust_account = False; - BOOL add_user = False; - BOOL disable_user = False; - BOOL enable_user = False; - BOOL set_no_password = False; + int local_flags = 0; BOOL stdin_passwd_get = False; char *user_name = NULL; char *new_domain = NULL; @@ -275,24 +271,37 @@ static int process_root(int argc, char *argv[]) char *old_passwd = NULL; char *remote_machine = NULL; - while ((ch = getopt(argc, argv, "adehmnj:r:sR:D:U:")) != EOF) { + while ((ch = getopt(argc, argv, "a:x:d:e:mnj:r:sR:D:U:")) != EOF) { switch(ch) { case 'a': - add_user = True; + local_flags |= LOCAL_ADD_USER; + user_name = optarg; + break; + case 'x': + local_flags |= LOCAL_DELETE_USER; + user_name = optarg; + new_passwd = "XXXXXX"; break; case 'd': - disable_user = True; + local_flags |= LOCAL_DISABLE_USER; + user_name = optarg; new_passwd = "XXXXXX"; break; case 'e': - enable_user = True; + local_flags |= LOCAL_ENABLE_USER; + user_name = optarg; break; - case 'D': - DEBUGLEVEL = atoi(optarg); + case 'm': + local_flags |= LOCAL_TRUST_ACCOUNT; break; case 'n': - set_no_password = True; + local_flags |= LOCAL_SET_NO_PASSWORD; new_passwd = "NO PASSWORD"; + case 'j': + new_domain = optarg; + strupper(new_domain); + joining_domain = True; + break; case 'r': remote_machine = optarg; break; @@ -305,13 +314,8 @@ static int process_root(int argc, char *argv[]) case 'R': lp_set_name_resolve_order(optarg); break; - case 'm': - trust_account = True; - break; - case 'j': - new_domain = optarg; - strupper(new_domain); - joining_domain = True; + case 'D': + DEBUGLEVEL = atoi(optarg); break; case 'U': user_name = optarg; @@ -326,15 +330,16 @@ static int process_root(int argc, char *argv[]) /* - * Ensure add_user and either remote machine or join domain are + * Ensure add/delete user and either remote machine or join domain are * not both set. */ - if(add_user && ((remote_machine != NULL) || joining_domain)) { + if((local_flags & (LOCAL_ADD_USER|LOCAL_DELETE_USER)) && ((remote_machine != NULL) || joining_domain)) { usage(); } if(joining_domain) { - if (argc != 0) usage(); + if (argc != 0) + usage(); return join_domain(new_domain, remote_machine); } @@ -365,7 +370,7 @@ static int process_root(int argc, char *argv[]) exit(1); } - if (trust_account) { + if (local_flags & LOCAL_TRUST_ACCOUNT) { /* add the $ automatically */ static fstring buf; @@ -378,7 +383,7 @@ static int process_root(int argc, char *argv[]) user_name[strlen(user_name)-1] = 0; } - if (add_user) { + if (local_flags & LOCAL_ADD_USER) { new_passwd = xstrdup(user_name); strlower(new_passwd); } @@ -392,12 +397,6 @@ static int process_root(int argc, char *argv[]) user_name = buf; } - if (!remote_machine && !Get_Pwnam(user_name, True)) { - fprintf(stderr, "User \"%s\" was not found in system password file.\n", - user_name); - exit(1); - } - if (remote_machine != NULL) { old_passwd = get_pass("Old SMB password:",stdin_passwd_get); } @@ -413,7 +412,7 @@ static int process_root(int argc, char *argv[]) * smbpasswd file) then we need to prompt for a new password. */ - if(enable_user) { + if(local_flags & LOCAL_ENABLE_USER) { struct smb_passwd *smb_pass = getsmbpwnam(user_name); if((smb_pass != NULL) && (smb_pass->smb_passwd != NULL)) { new_passwd = "XXXX"; /* Don't care. */ @@ -429,20 +428,12 @@ static int process_root(int argc, char *argv[]) } } - if (!password_change(remote_machine, user_name, old_passwd, new_passwd, - add_user, enable_user, disable_user, set_no_password, - trust_account)) { - fprintf(stderr,"Failed to change password entry for %s\n", user_name); + if (!password_change(remote_machine, user_name, old_passwd, new_passwd, local_flags)) { + fprintf(stderr,"Failed to modify password entry for user %s\n", user_name); return 1; } - if(disable_user) { - printf("User %s disabled.\n", user_name); - } else if(enable_user) { - printf("User %s enabled.\n", user_name); - } else if (set_no_password) { - printf("User %s - set to no password.\n", user_name); - } else { + if(!(local_flags & (LOCAL_ADD_USER|LOCAL_DISABLE_USER|LOCAL_ENABLE_USER|LOCAL_DELETE_USER|LOCAL_SET_NO_PASSWORD))) { struct smb_passwd *smb_pass = getsmbpwnam(user_name); printf("Password changed for user %s.", user_name ); if((smb_pass != NULL) && (smb_pass->acct_ctrl & ACB_DISABLED )) @@ -534,8 +525,7 @@ static int process_nonroot(int argc, char *argv[]) exit(1); } - if (!password_change(remote_machine, user_name, old_passwd, new_passwd, - False, False, False, False, False)) { + if (!password_change(remote_machine, user_name, old_passwd, new_passwd, 0)) { fprintf(stderr,"Failed to change password for %s\n", user_name); return 1; } diff --git a/source/web/swat.c b/source/web/swat.c index 48c3ae07e25..3c9858a3d38 100644 --- a/source/web/swat.c +++ b/source/web/swat.c @@ -44,6 +44,7 @@ static int iNumNonAutoPrintServices = 0; #define CHG_S_PASSWD_FLAG "chg_s_passwd_flag" #define CHG_R_PASSWD_FLAG "chg_r_passwd_flag" #define ADD_USER_FLAG "add_user_flag" +#define DELETE_USER_FLAG "delete_user_flag" #define DISABLE_USER_FLAG "disable_user_flag" #define ENABLE_USER_FLAG "enable_user_flag" #define RHOST "remote_host" @@ -617,7 +618,7 @@ change a password either locally or remotely *************************************************************/ static BOOL change_password(const char *remote_machine, char *user_name, char *old_passwd, char *new_passwd, - BOOL add_user, BOOL enable_user, BOOL disable_user) + int local_flags) { BOOL ret = False; pstring err_str; @@ -641,8 +642,7 @@ static BOOL change_password(const char *remote_machine, char *user_name, return False; } - ret = local_password_change(user_name, False, add_user, enable_user, - disable_user, False, new_passwd, err_str, sizeof(err_str), + ret = local_password_change(user_name, local_flags, new_passwd, err_str, sizeof(err_str), msg_str, sizeof(msg_str)); if(*msg_str) @@ -660,6 +660,7 @@ static void chg_passwd(void) { char *host; BOOL rslt; + int local_flags = 0; /* Make sure users name has been specified */ if (strlen(cgi_variable(SWAT_USER)) == 0) { @@ -668,10 +669,10 @@ static void chg_passwd(void) } /* - * smbpasswd doesn't require anything but the users name to disable or enable the user, + * smbpasswd doesn't require anything but the users name to delete, disable or enable the user, * so if that's what we're doing, skip the rest of the checks */ - if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG)) { + if (!cgi_variable(DISABLE_USER_FLAG) && !cgi_variable(ENABLE_USER_FLAG) && !cgi_variable(DELETE_USER_FLAG)) { /* * If current user is not root, make sure old password has been specified @@ -710,18 +711,27 @@ static void chg_passwd(void) } else { host = "127.0.0.1"; } + + /* + * Set up the local flags. + */ + + local_flags |= (cgi_variable(ADD_USER_FLAG) ? LOCAL_ADD_USER : 0); + local_flags |= (cgi_variable(DELETE_USER_FLAG) ? LOCAL_DELETE_USER : 0); + local_flags |= (cgi_variable(ENABLE_USER_FLAG) ? LOCAL_ENABLE_USER : 0); + local_flags |= (cgi_variable(DISABLE_USER_FLAG) ? LOCAL_DISABLE_USER : 0); + rslt = change_password(host, cgi_variable(SWAT_USER), cgi_variable(OLD_PSWD), cgi_variable(NEW_PSWD), - cgi_variable(ADD_USER_FLAG)? True : False, - cgi_variable(ENABLE_USER_FLAG)? True : False, - cgi_variable(DISABLE_USER_FLAG)? True : False); + local_flags); - - if (rslt == True) { - printf("

The passwd for '%s' has been changed. \n", cgi_variable(SWAT_USER)); - } else { - printf("

The passwd for '%s' has NOT been changed. \n",cgi_variable(SWAT_USER)); + if(local_flags == 0) { + if (rslt == True) { + printf("

The passwd for '%s' has been changed. \n", cgi_variable(SWAT_USER)); + } else { + printf("

The passwd for '%s' has NOT been changed. \n",cgi_variable(SWAT_USER)); + } } return; @@ -773,6 +783,8 @@ static void passwd_page(void) if (demo_mode || am_root()) { printf("\n", ADD_USER_FLAG); + printf("\n", + DELETE_USER_FLAG); printf("\n", DISABLE_USER_FLAG); printf("\n", @@ -784,7 +796,7 @@ static void passwd_page(void) * Do some work if change, add, disable or enable was * requested. It could be this is the first time through this * code, so there isn't anything to do. */ - if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || + if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) || (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) { chg_passwd(); } -- cgit From b76ae1f92f4f12b38c4245456cdd2db970724077 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Sat, 26 Feb 2000 22:22:24 +0000 Subject: rewrote enumprinterdata. still a bug in it but reproducing it hard and borring. I need a client test program urgently!!! rewrote setprinter, doesn't coredump anymore, and no memleak. J.F. --- source/include/proto.h | 711 ++++++++++++++++++------------------- source/include/rpc_spoolss.h | 7 +- source/rpc_parse/parse_spoolss.c | 241 +++++++------ source/rpc_server/srv_spoolss.c | 37 +- source/rpc_server/srv_spoolss_nt.c | 213 +++++------ 5 files changed, 621 insertions(+), 588 deletions(-) diff --git a/source/include/proto.h b/source/include/proto.h index 830e7bc5b1f..53daacc098b 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -186,10 +186,208 @@ void CatchChildLeaveStatus(void); int vslprintf(char *str, int n, char *format, va_list ap); +/*The following definitions come from libsmb/clientgen.c */ + +int cli_set_port(struct cli_state *cli, int port); +char *cli_errstr(struct cli_state *cli); +BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, + uint16 *setup, uint32 setup_count, uint32 max_setup_count, + char *params, uint32 param_count, uint32 max_param_count, + char *data, uint32 data_count, uint32 max_data_count, + char **rparam, uint32 *rparam_count, + char **rdata, uint32 *rdata_count); +BOOL cli_api(struct cli_state *cli, + char *param, int prcnt, int mprcnt, + char *data, int drcnt, int mdrcnt, + char **rparam, int *rprcnt, + char **rdata, int *rdrcnt); +BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation); +int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)); +BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, + void (*fn)(const char *, uint32, const char *)); +BOOL cli_session_setup(struct cli_state *cli, + char *user, + char *pass, int passlen, + char *ntpass, int ntpasslen, + char *workgroup); +BOOL cli_ulogoff(struct cli_state *cli); +BOOL cli_send_tconX(struct cli_state *cli, + char *share, char *dev, char *pass, int passlen); +BOOL cli_tdis(struct cli_state *cli); +BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst); +BOOL cli_unlink(struct cli_state *cli, char *fname); +BOOL cli_mkdir(struct cli_state *cli, char *dname); +BOOL cli_rmdir(struct cli_state *cli, char *dname); +int cli_nt_create(struct cli_state *cli, char *fname); +int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode); +BOOL cli_close(struct cli_state *cli, int fnum); +BOOL cli_lock(struct cli_state *cli, int fnum, + uint32 offset, uint32 len, int timeout, enum brl_type lock_type); +BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len); +size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size); +ssize_t cli_write(struct cli_state *cli, + int fnum, uint16 write_mode, + char *buf, off_t offset, size_t size); +ssize_t cli_smbwrite(struct cli_state *cli, + int fnum, char *buf, off_t offset, size_t size1); +BOOL cli_getattrE(struct cli_state *cli, int fd, + uint16 *attr, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time); +BOOL cli_getatr(struct cli_state *cli, char *fname, + uint16 *attr, size_t *size, time_t *t); +BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t); +BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, + size_t *size, uint16 *mode); +BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, size_t *size, uint16 *mode, + SMB_INO_T *ino); +BOOL cli_qfileinfo(struct cli_state *cli, int fnum, + uint16 *mode, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, SMB_INO_T *ino); +int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, + void (*fn)(file_info *, const char *)); +BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, + const char *old_password); +BOOL cli_negprot(struct cli_state *cli); +BOOL cli_session_request(struct cli_state *cli, + struct nmb_name *calling, struct nmb_name *called); +BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip); +struct cli_state *cli_initialise(struct cli_state *cli); +void cli_shutdown(struct cli_state *cli); +int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error); +void cli_sockopt(struct cli_state *cli, char *options); +uint16 cli_setpid(struct cli_state *cli, uint16 pid); +BOOL cli_reestablish_connection(struct cli_state *cli); +BOOL cli_establish_connection(struct cli_state *cli, + char *dest_host, struct in_addr *dest_ip, + struct nmb_name *calling, struct nmb_name *called, + char *service, char *service_type, + BOOL do_shutdown, BOOL do_tcon); +int cli_printjob_del(struct cli_state *cli, int job); +int cli_print_queue(struct cli_state *cli, + void (*fn)(struct print_job_info *)); +BOOL cli_chkpath(struct cli_state *cli, char *path); +BOOL cli_message_start(struct cli_state *cli, char *host, char *username, + int *grp); +BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp); +BOOL cli_message_end(struct cli_state *cli, int grp); +BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail); +BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, + struct in_addr *pdest_ip); + +/*The following definitions come from libsmb/credentials.c */ + +char *credstr(uchar *cred); +void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, + uchar session_key[8]); +void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp, + DOM_CHAL *cred); +int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred, + UTIME timestamp); +BOOL clnt_deal_with_creds(uchar sess_key[8], + DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred); +BOOL deal_with_creds(uchar sess_key[8], + DOM_CRED *sto_clnt_cred, + DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred); + +/*The following definitions come from libsmb/namequery.c */ + +BOOL name_status(int fd,char *name,int name_type,BOOL recurse, + struct in_addr to_ip,char *master,char *rname); +struct in_addr *name_query(int fd,const char *name,int name_type, + BOOL bcast,BOOL recurse, + struct in_addr to_ip, int *count); +FILE *startlmhosts(char *fname); +BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr); +void endlmhosts(FILE *fp); +BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type); +BOOL find_master_ip(char *group, struct in_addr *master_ip); +BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name); +BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count); + +/*The following definitions come from libsmb/nmblib.c */ + +void debug_nmb_packet(struct packet_struct *p); +char *nmb_namestr(struct nmb_name *n); +struct packet_struct *copy_packet(struct packet_struct *packet); +void free_packet(struct packet_struct *packet); +struct packet_struct *parse_packet(char *buf,int length, + enum packet_type packet_type); +struct packet_struct *read_packet(int fd,enum packet_type packet_type); +void make_nmb_name( struct nmb_name *n, const char *name, int type); +BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2); +int build_packet(char *buf, struct packet_struct *p); +BOOL send_packet(struct packet_struct *p); +struct packet_struct *receive_packet(int fd,enum packet_type type,int t); +struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id); +struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name); +BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name); +void sort_query_replies(char *data, int n, struct in_addr ip); + +/*The following definitions come from libsmb/nterr.c */ + +char *get_nt_error_msg(uint32 nt_code); + +/*The following definitions come from libsmb/passchange.c */ + +BOOL remote_password_change(const char *remote_machine, const char *user_name, + const char *old_passwd, const char *new_passwd, + char *err_str, size_t err_str_len); + +/*The following definitions come from libsmb/pwd_cache.c */ + +void pwd_init(struct pwd_info *pwd); +void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key); +BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2); +void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt); +void pwd_set_nullpwd(struct pwd_info *pwd); +void pwd_set_cleartext(struct pwd_info *pwd, char *clr); +void pwd_get_cleartext(struct pwd_info *pwd, char *clr); +void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); +void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); +void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr); +void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]); +void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]); + /*The following definitions come from lib/smbrun.c */ int smbrun(char *cmd,char *outfile,BOOL shared); +/*The following definitions come from libsmb/smbdes.c */ + +void E_P16(unsigned char *p14,unsigned char *p16); +void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); +void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out); +void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out); +void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key); +void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key); +void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw); +void SamOEMhash( unsigned char *data, unsigned char *key, int val); + +/*The following definitions come from libsmb/smbencrypt.c */ + +void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24); +void E_md4hash(uchar *passwd, uchar *p16); +void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]); +void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]); +void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]); +void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24); +BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode); + +/*The following definitions come from libsmb/smberr.c */ + +char *smb_errstr(char *inbuf); + +/*The following definitions come from libsmb/unexpected.c */ + +void unexpected_packet(struct packet_struct *p); +void clear_unexpected(time_t t); +struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, + char *mailslot_name); + /*The following definitions come from lib/snprintf.c */ @@ -274,6 +472,23 @@ BOOL map_username(char *user); struct passwd *Get_Pwnam(char *user,BOOL allow_change); BOOL user_in_list(char *user,char *list); +/*The following definitions come from lib/util_array.c */ + +void free_void_array(uint32 num_entries, void **entries, + void(free_item)(void*)); +void* add_copy_to_array(uint32 *len, void ***array, const void *item, + void*(item_dup)(const void*), BOOL alloc_anyway); +void* add_item_to_array(uint32 *len, void ***array, void *item); +void free_use_info_array(uint32 num_entries, struct use_info **entries); +struct use_info* add_use_info_to_array(uint32 *len, struct use_info ***array, + const struct use_info *name); +void free_char_array(uint32 num_entries, char **entries); +char* add_chars_to_array(uint32 *len, char ***array, const char *name); +void free_uint32_array(uint32 num_entries, uint32 **entries); +uint32* add_uint32s_to_array(uint32 *len, uint32 ***array, const uint32 *name); +void free_sid_array(uint32 num_entries, DOM_SID **entries); +DOM_SID* add_sid_to_array(uint32 *len, DOM_SID ***array, const DOM_SID *sid); + /*The following definitions come from lib/util.c */ char *tmpdir(void); @@ -351,23 +566,6 @@ char *myhostname(void); char *lock_path(char *name); char *parent_dirname(const char *path); -/*The following definitions come from lib/util_array.c */ - -void free_void_array(uint32 num_entries, void **entries, - void(free_item)(void*)); -void* add_copy_to_array(uint32 *len, void ***array, const void *item, - void*(item_dup)(const void*), BOOL alloc_anyway); -void* add_item_to_array(uint32 *len, void ***array, void *item); -void free_use_info_array(uint32 num_entries, struct use_info **entries); -struct use_info* add_use_info_to_array(uint32 *len, struct use_info ***array, - const struct use_info *name); -void free_char_array(uint32 num_entries, char **entries); -char* add_chars_to_array(uint32 *len, char ***array, const char *name); -void free_uint32_array(uint32 num_entries, uint32 **entries); -uint32* add_uint32s_to_array(uint32 *len, uint32 ***array, const uint32 *name); -void free_sid_array(uint32 num_entries, DOM_SID **entries); -DOM_SID* add_sid_to_array(uint32 *len, DOM_SID ***array, const DOM_SID *sid); - /*The following definitions come from lib/util_file.c */ BOOL do_file_lock(int fd, int waitsecs, int type); @@ -554,206 +752,8 @@ void fstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *ins void pstring_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,smb_ucs2_t *insert); void all_string_sub_w(smb_ucs2_t *s,const smb_ucs2_t *pattern,const smb_ucs2_t *insert, size_t len); void split_at_last_component_w(smb_ucs2_t *path, smb_ucs2_t *front, smb_ucs2_t sep, smb_ucs2_t *back); -smb_ucs2_t *octal_string_w(int i); -smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length); - -/*The following definitions come from libsmb/clientgen.c */ - -int cli_set_port(struct cli_state *cli, int port); -char *cli_errstr(struct cli_state *cli); -BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, - uint16 *setup, uint32 setup_count, uint32 max_setup_count, - char *params, uint32 param_count, uint32 max_param_count, - char *data, uint32 data_count, uint32 max_data_count, - char **rparam, uint32 *rparam_count, - char **rdata, uint32 *rdata_count); -BOOL cli_api(struct cli_state *cli, - char *param, int prcnt, int mprcnt, - char *data, int drcnt, int mdrcnt, - char **rparam, int *rprcnt, - char **rdata, int *rdrcnt); -BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation); -int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)); -BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, - void (*fn)(const char *, uint32, const char *)); -BOOL cli_session_setup(struct cli_state *cli, - char *user, - char *pass, int passlen, - char *ntpass, int ntpasslen, - char *workgroup); -BOOL cli_ulogoff(struct cli_state *cli); -BOOL cli_send_tconX(struct cli_state *cli, - char *share, char *dev, char *pass, int passlen); -BOOL cli_tdis(struct cli_state *cli); -BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst); -BOOL cli_unlink(struct cli_state *cli, char *fname); -BOOL cli_mkdir(struct cli_state *cli, char *dname); -BOOL cli_rmdir(struct cli_state *cli, char *dname); -int cli_nt_create(struct cli_state *cli, char *fname); -int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode); -BOOL cli_close(struct cli_state *cli, int fnum); -BOOL cli_lock(struct cli_state *cli, int fnum, - uint32 offset, uint32 len, int timeout, enum brl_type lock_type); -BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len); -size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size); -ssize_t cli_write(struct cli_state *cli, - int fnum, uint16 write_mode, - char *buf, off_t offset, size_t size); -ssize_t cli_smbwrite(struct cli_state *cli, - int fnum, char *buf, off_t offset, size_t size1); -BOOL cli_getattrE(struct cli_state *cli, int fd, - uint16 *attr, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time); -BOOL cli_getatr(struct cli_state *cli, char *fname, - uint16 *attr, size_t *size, time_t *t); -BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t); -BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - size_t *size, uint16 *mode); -BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, size_t *size, uint16 *mode, - SMB_INO_T *ino); -BOOL cli_qfileinfo(struct cli_state *cli, int fnum, - uint16 *mode, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, SMB_INO_T *ino); -int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *)); -BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, - const char *old_password); -BOOL cli_negprot(struct cli_state *cli); -BOOL cli_session_request(struct cli_state *cli, - struct nmb_name *calling, struct nmb_name *called); -BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip); -struct cli_state *cli_initialise(struct cli_state *cli); -void cli_shutdown(struct cli_state *cli); -int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error); -void cli_sockopt(struct cli_state *cli, char *options); -uint16 cli_setpid(struct cli_state *cli, uint16 pid); -BOOL cli_reestablish_connection(struct cli_state *cli); -BOOL cli_establish_connection(struct cli_state *cli, - char *dest_host, struct in_addr *dest_ip, - struct nmb_name *calling, struct nmb_name *called, - char *service, char *service_type, - BOOL do_shutdown, BOOL do_tcon); -int cli_printjob_del(struct cli_state *cli, int job); -int cli_print_queue(struct cli_state *cli, - void (*fn)(struct print_job_info *)); -BOOL cli_chkpath(struct cli_state *cli, char *path); -BOOL cli_message_start(struct cli_state *cli, char *host, char *username, - int *grp); -BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp); -BOOL cli_message_end(struct cli_state *cli, int grp); -BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail); -BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, - struct in_addr *pdest_ip); - -/*The following definitions come from libsmb/credentials.c */ - -char *credstr(uchar *cred); -void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, - uchar session_key[8]); -void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp, - DOM_CHAL *cred); -int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred, - UTIME timestamp); -BOOL clnt_deal_with_creds(uchar sess_key[8], - DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred); -BOOL deal_with_creds(uchar sess_key[8], - DOM_CRED *sto_clnt_cred, - DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred); - -/*The following definitions come from libsmb/namequery.c */ - -BOOL name_status(int fd,char *name,int name_type,BOOL recurse, - struct in_addr to_ip,char *master,char *rname); -struct in_addr *name_query(int fd,const char *name,int name_type, - BOOL bcast,BOOL recurse, - struct in_addr to_ip, int *count); -FILE *startlmhosts(char *fname); -BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr); -void endlmhosts(FILE *fp); -BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type); -BOOL find_master_ip(char *group, struct in_addr *master_ip); -BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name); -BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count); - -/*The following definitions come from libsmb/nmblib.c */ - -void debug_nmb_packet(struct packet_struct *p); -char *nmb_namestr(struct nmb_name *n); -struct packet_struct *copy_packet(struct packet_struct *packet); -void free_packet(struct packet_struct *packet); -struct packet_struct *parse_packet(char *buf,int length, - enum packet_type packet_type); -struct packet_struct *read_packet(int fd,enum packet_type packet_type); -void make_nmb_name( struct nmb_name *n, const char *name, int type); -BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2); -int build_packet(char *buf, struct packet_struct *p); -BOOL send_packet(struct packet_struct *p); -struct packet_struct *receive_packet(int fd,enum packet_type type,int t); -struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id); -struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name); -BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name); -void sort_query_replies(char *data, int n, struct in_addr ip); - -/*The following definitions come from libsmb/nterr.c */ - -char *get_nt_error_msg(uint32 nt_code); - -/*The following definitions come from libsmb/passchange.c */ - -BOOL remote_password_change(const char *remote_machine, const char *user_name, - const char *old_passwd, const char *new_passwd, - char *err_str, size_t err_str_len); - -/*The following definitions come from libsmb/pwd_cache.c */ - -void pwd_init(struct pwd_info *pwd); -void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key); -BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2); -void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt); -void pwd_set_nullpwd(struct pwd_info *pwd); -void pwd_set_cleartext(struct pwd_info *pwd, char *clr); -void pwd_get_cleartext(struct pwd_info *pwd, char *clr); -void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); -void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); -void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr); -void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]); -void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]); - -/*The following definitions come from libsmb/smbdes.c */ - -void E_P16(unsigned char *p14,unsigned char *p16); -void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); -void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out); -void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out); -void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key); -void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key); -void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw); -void SamOEMhash( unsigned char *data, unsigned char *key, int val); - -/*The following definitions come from libsmb/smbencrypt.c */ - -void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24); -void E_md4hash(uchar *passwd, uchar *p16); -void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]); -void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]); -void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]); -void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24); -BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode); - -/*The following definitions come from libsmb/smberr.c */ - -char *smb_errstr(char *inbuf); - -/*The following definitions come from libsmb/unexpected.c */ - -void unexpected_packet(struct packet_struct *p); -void clear_unexpected(time_t t); -struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, - char *mailslot_name); +smb_ucs2_t *octal_string_w(int i); +smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length); /*The following definitions come from locking/brlock.c */ @@ -812,10 +812,6 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question, struct name_record **n); void kill_async_dns_child(void); -/*The following definitions come from nmbd/nmbd.c */ - -BOOL reload_services(BOOL test); - /*The following definitions come from nmbd/nmbd_become_dmb.c */ void add_domain_names(time_t t); @@ -846,6 +842,10 @@ void announce_and_sync_with_domain_master_browser( struct subnet_record *subrec, void collect_all_workgroup_names_from_wins_server(time_t t); void sync_all_dmbs(time_t t); +/*The following definitions come from nmbd/nmbd.c */ + +BOOL reload_services(BOOL test); + /*The following definitions come from nmbd/nmbd_elections.c */ void check_master_browser_exists(time_t t); @@ -1520,11 +1520,6 @@ void pcap_printer_fn(void (*fn)(char *, char *)); void cups_printer_fn(void (*fn)(char *, char *)); int cups_printername_ok(char *name); -/*The following definitions come from printing/print_svid.c */ - -void sysv_printer_fn(void (*fn)(char *, char *)); -int sysv_printername_ok(char *name); - /*The following definitions come from printing/printing.c */ void lpq_reset(int snum); @@ -1539,6 +1534,11 @@ void printjob_decode(int jobid, int *snum, int *job); void status_printqueue(connection_struct *conn,int snum,int status); void load_printers(void); +/*The following definitions come from printing/print_svid.c */ + +void sysv_printer_fn(void (*fn)(char *, char *)); +int sysv_printername_ok(char *name); + /*The following definitions come from profile/profile.c */ BOOL profile_setup(BOOL rdonly); @@ -1704,6 +1704,109 @@ BOOL do_wks_query_info(struct cli_state *cli, char *server_name, uint32 switch_value, WKS_INFO_100 *wks100); +/*The following definitions come from rpcclient/cmd_lsarpc.c */ + +void cmd_lsa_query_info(struct client_info *info); +void cmd_lsa_lookup_sids(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_netlogon.c */ + +void cmd_netlogon_login_test(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_reg.c */ + +void cmd_reg_enum(struct client_info *info); +void cmd_reg_query_key(struct client_info *info); +void cmd_reg_create_val(struct client_info *info); +void cmd_reg_delete_val(struct client_info *info); +void cmd_reg_delete_key(struct client_info *info); +void cmd_reg_create_key(struct client_info *info); +void cmd_reg_test_key_sec(struct client_info *info); +void cmd_reg_get_key_sec(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_samr.c */ + +void cmd_sam_ntchange_pwd(struct client_info *info); +void cmd_sam_test(struct client_info *info); +void cmd_sam_enum_users(struct client_info *info); +void cmd_sam_query_user(struct client_info *info); +void cmd_sam_query_groups(struct client_info *info); +void cmd_sam_enum_aliases(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_srvsvc.c */ + +void cmd_srv_query_info(struct client_info *info); +void cmd_srv_enum_conn(struct client_info *info); +void cmd_srv_enum_shares(struct client_info *info); +void cmd_srv_enum_sess(struct client_info *info); +void cmd_srv_enum_files(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_wkssvc.c */ + +void cmd_wks_query_info(struct client_info *info); + +/*The following definitions come from rpcclient/display.c */ + +char *get_file_mode_str(uint32 share_mode); +char *get_file_oplock_str(uint32 op_type); +char *get_share_type_str(uint32 type); +char *get_server_type_str(uint32 type); +void display_srv_info_101(FILE *out_hnd, enum action_type action, + SRV_INFO_101 *sv101); +void display_srv_info_102(FILE *out_hnd, enum action_type action,SRV_INFO_102 *sv102); +void display_srv_info_ctr(FILE *out_hnd, enum action_type action,SRV_INFO_CTR *ctr); +void display_conn_info_0(FILE *out_hnd, enum action_type action, + CONN_INFO_0 *info0); +void display_conn_info_1(FILE *out_hnd, enum action_type action, + CONN_INFO_1 *info1, CONN_INFO_1_STR *str1); +void display_srv_conn_info_0_ctr(FILE *out_hnd, enum action_type action, + SRV_CONN_INFO_0 *ctr); +void display_srv_conn_info_1_ctr(FILE *out_hnd, enum action_type action, + SRV_CONN_INFO_1 *ctr); +void display_srv_conn_info_ctr(FILE *out_hnd, enum action_type action, + SRV_CONN_INFO_CTR *ctr); +void display_share_info_1(FILE *out_hnd, enum action_type action, + SRV_SHARE_INFO_1 *info1); +void display_share_info_2(FILE *out_hnd, enum action_type action, + SRV_SHARE_INFO_2 *info2); +void display_srv_share_info_ctr(FILE *out_hnd, enum action_type action, + SRV_SHARE_INFO_CTR *ctr); +void display_file_info_3(FILE *out_hnd, enum action_type action, + FILE_INFO_3 *info3, FILE_INFO_3_STR *str3); +void display_srv_file_info_3_ctr(FILE *out_hnd, enum action_type action, + SRV_FILE_INFO_3 *ctr); +void display_srv_file_info_ctr(FILE *out_hnd, enum action_type action, + SRV_FILE_INFO_CTR *ctr); +void display_server(FILE *out_hnd, enum action_type action, + char *sname, uint32 type, char *comment); +void display_share(FILE *out_hnd, enum action_type action, + char *sname, uint32 type, char *comment); +void display_share2(FILE *out_hnd, enum action_type action, + char *sname, uint32 type, char *comment, + uint32 perms, uint32 max_uses, uint32 num_uses, + char *path, char *passwd); +void display_name(FILE *out_hnd, enum action_type action, + char *sname); +void display_group_rid_info(FILE *out_hnd, enum action_type action, + uint32 num_gids, DOM_GID *gid); +void display_alias_name_info(FILE *out_hnd, enum action_type action, + uint32 num_aliases, fstring *alias_name, uint32 *num_als_usrs); +void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_INFO_21 *usr); +char *get_sec_mask_str(uint32 type); +void display_sec_access(FILE *out_hnd, enum action_type action, SEC_ACCESS *info); +void display_sec_ace(FILE *out_hnd, enum action_type action, SEC_ACE *ace); +void display_sec_acl(FILE *out_hnd, enum action_type action, SEC_ACL *sec_acl); +void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *sec); +char *get_reg_val_type_str(uint32 type); +void display_reg_value_info(FILE *out_hnd, enum action_type action, + char *val_name, uint32 val_type, BUFFER2 *value); +void display_reg_key_info(FILE *out_hnd, enum action_type action, + char *key_name, time_t key_mod_time); + +/*The following definitions come from rpcclient/rpcclient.c */ + +void rpcclient_init(void); + /*The following definitions come from rpc_parse/parse_creds.c */ BOOL make_creds_unix(CREDS_UNIX *r_u, const char* user_name, @@ -2390,7 +2493,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_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 **q_u, 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); BOOL spoolss_io_r_addprinterex(char *desc, SPOOL_R_ADDPRINTEREX *r_u, prs_struct *ps, int depth); @@ -2625,13 +2728,10 @@ uint32 _spoolss_writeprinter( const POLICY_HND *handle, uint32 buffer_size, const uint8 *buffer, uint32 *buffer_written); -uint32 _spoolss_setprinter( const POLICY_HND *handle, - uint32 level, - const SPOOL_PRINTER_INFO_LEVEL *info, - const DEVICEMODE *devmode, - uint32 sec_buf_size, - const char *sec_buf, - uint32 command); +uint32 _spoolss_setprinter(const POLICY_HND *handle, uint32 level, + const SPOOL_PRINTER_INFO_LEVEL *info, + const DEVMODE_CTR devmode_ctr, + uint32 command); uint32 _spoolss_fcpn(const POLICY_HND *handle); uint32 _spoolss_addjob(const POLICY_HND *handle, uint32 level, NEW_BUFFER *buffer, uint32 offered); @@ -2664,15 +2764,11 @@ uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name, uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environment, uint32 level, NEW_BUFFER *buffer, uint32 offered, uint32 *needed); -uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, - uint32 idx, - uint32 *valuesize, - UNISTR *uni_value, - uint32 *realvaluesize, - uint32 *type, - uint32 *datasize, - uint8 **data, - uint32 *realdatasize); +uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 index, + 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_data, uint32 *out_data_len); uint32 _spoolss_setprinterdata( const POLICY_HND *handle, const UNISTR2 *value, uint32 type, @@ -2716,109 +2812,6 @@ uint32 lookup_user_rid(char *user_name, uint32 *rid); BOOL api_wkssvc_rpc(pipes_struct *p, prs_struct *data); -/*The following definitions come from rpcclient/cmd_lsarpc.c */ - -void cmd_lsa_query_info(struct client_info *info); -void cmd_lsa_lookup_sids(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_netlogon.c */ - -void cmd_netlogon_login_test(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_reg.c */ - -void cmd_reg_enum(struct client_info *info); -void cmd_reg_query_key(struct client_info *info); -void cmd_reg_create_val(struct client_info *info); -void cmd_reg_delete_val(struct client_info *info); -void cmd_reg_delete_key(struct client_info *info); -void cmd_reg_create_key(struct client_info *info); -void cmd_reg_test_key_sec(struct client_info *info); -void cmd_reg_get_key_sec(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_samr.c */ - -void cmd_sam_ntchange_pwd(struct client_info *info); -void cmd_sam_test(struct client_info *info); -void cmd_sam_enum_users(struct client_info *info); -void cmd_sam_query_user(struct client_info *info); -void cmd_sam_query_groups(struct client_info *info); -void cmd_sam_enum_aliases(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_srvsvc.c */ - -void cmd_srv_query_info(struct client_info *info); -void cmd_srv_enum_conn(struct client_info *info); -void cmd_srv_enum_shares(struct client_info *info); -void cmd_srv_enum_sess(struct client_info *info); -void cmd_srv_enum_files(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_wkssvc.c */ - -void cmd_wks_query_info(struct client_info *info); - -/*The following definitions come from rpcclient/display.c */ - -char *get_file_mode_str(uint32 share_mode); -char *get_file_oplock_str(uint32 op_type); -char *get_share_type_str(uint32 type); -char *get_server_type_str(uint32 type); -void display_srv_info_101(FILE *out_hnd, enum action_type action, - SRV_INFO_101 *sv101); -void display_srv_info_102(FILE *out_hnd, enum action_type action,SRV_INFO_102 *sv102); -void display_srv_info_ctr(FILE *out_hnd, enum action_type action,SRV_INFO_CTR *ctr); -void display_conn_info_0(FILE *out_hnd, enum action_type action, - CONN_INFO_0 *info0); -void display_conn_info_1(FILE *out_hnd, enum action_type action, - CONN_INFO_1 *info1, CONN_INFO_1_STR *str1); -void display_srv_conn_info_0_ctr(FILE *out_hnd, enum action_type action, - SRV_CONN_INFO_0 *ctr); -void display_srv_conn_info_1_ctr(FILE *out_hnd, enum action_type action, - SRV_CONN_INFO_1 *ctr); -void display_srv_conn_info_ctr(FILE *out_hnd, enum action_type action, - SRV_CONN_INFO_CTR *ctr); -void display_share_info_1(FILE *out_hnd, enum action_type action, - SRV_SHARE_INFO_1 *info1); -void display_share_info_2(FILE *out_hnd, enum action_type action, - SRV_SHARE_INFO_2 *info2); -void display_srv_share_info_ctr(FILE *out_hnd, enum action_type action, - SRV_SHARE_INFO_CTR *ctr); -void display_file_info_3(FILE *out_hnd, enum action_type action, - FILE_INFO_3 *info3, FILE_INFO_3_STR *str3); -void display_srv_file_info_3_ctr(FILE *out_hnd, enum action_type action, - SRV_FILE_INFO_3 *ctr); -void display_srv_file_info_ctr(FILE *out_hnd, enum action_type action, - SRV_FILE_INFO_CTR *ctr); -void display_server(FILE *out_hnd, enum action_type action, - char *sname, uint32 type, char *comment); -void display_share(FILE *out_hnd, enum action_type action, - char *sname, uint32 type, char *comment); -void display_share2(FILE *out_hnd, enum action_type action, - char *sname, uint32 type, char *comment, - uint32 perms, uint32 max_uses, uint32 num_uses, - char *path, char *passwd); -void display_name(FILE *out_hnd, enum action_type action, - char *sname); -void display_group_rid_info(FILE *out_hnd, enum action_type action, - uint32 num_gids, DOM_GID *gid); -void display_alias_name_info(FILE *out_hnd, enum action_type action, - uint32 num_aliases, fstring *alias_name, uint32 *num_als_usrs); -void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_INFO_21 *usr); -char *get_sec_mask_str(uint32 type); -void display_sec_access(FILE *out_hnd, enum action_type action, SEC_ACCESS *info); -void display_sec_ace(FILE *out_hnd, enum action_type action, SEC_ACE *ace); -void display_sec_acl(FILE *out_hnd, enum action_type action, SEC_ACL *sec_acl); -void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *sec); -char *get_reg_val_type_str(uint32 type); -void display_reg_value_info(FILE *out_hnd, enum action_type action, - char *val_name, uint32 val_type, BUFFER2 *value); -void display_reg_key_info(FILE *out_hnd, enum action_type action, - char *key_name, time_t key_mod_time); - -/*The following definitions come from rpcclient/rpcclient.c */ - -void rpcclient_init(void); - /*The following definitions come from smbd/blocking.c */ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num); @@ -3204,6 +3197,19 @@ BOOL unbecome_authenticated_pipe_user(pipes_struct *p); void become_root(BOOL save_dir) ; void unbecome_root(BOOL restore_dir); +/*The following definitions come from smbd/vfs.c */ + +int vfs_init_default(connection_struct *conn); +BOOL vfs_init_custom(connection_struct *conn); +BOOL vfs_directory_exist(connection_struct *conn, char *dname, + SMB_STRUCT_STAT *st); +BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf); +ssize_t vfs_write_data(files_struct *fsp,char *buffer,size_t N); +SMB_OFF_T vfs_transfer_file(int in_fd, files_struct *in_fsp, + int out_fd, files_struct *out_fsp, + SMB_OFF_T n, char *header, int headlen, int align); +char *vfs_readdirname(connection_struct *conn, void *p); + /*The following definitions come from smbd/vfs-wrap.c */ int vfswrap_dummy_connect(struct vfs_connection_struct *conn, char *service, @@ -3231,19 +3237,6 @@ int vfswrap_unlink(char *path); int vfswrap_chmod(char *path, mode_t mode); int vfswrap_utime(char *path, struct utimbuf *times); -/*The following definitions come from smbd/vfs.c */ - -int vfs_init_default(connection_struct *conn); -BOOL vfs_init_custom(connection_struct *conn); -BOOL vfs_directory_exist(connection_struct *conn, char *dname, - SMB_STRUCT_STAT *st); -BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf); -ssize_t vfs_write_data(files_struct *fsp,char *buffer,size_t N); -SMB_OFF_T vfs_transfer_file(int in_fd, files_struct *in_fsp, - int out_fd, files_struct *out_fsp, - SMB_OFF_T n, char *header, int headlen, int align); -char *vfs_readdirname(connection_struct *conn, void *p); - /*The following definitions come from smbwrapper/realcalls.c */ int real_utime(const char *name, struct utimbuf *buf); diff --git a/source/include/rpc_spoolss.h b/source/include/rpc_spoolss.h index 19b6c2845ce..84812ed98a6 100755 --- a/source/include/rpc_spoolss.h +++ b/source/include/rpc_spoolss.h @@ -1138,6 +1138,8 @@ typedef struct spool_printer_info_level_2 typedef struct spool_printer_info_level { + uint32 level; + uint32 info_ptr; SPOOL_PRINTER_INFO_LEVEL_2 *info_2; } SPOOL_PRINTER_INFO_LEVEL; @@ -1200,8 +1202,7 @@ typedef struct spool_q_setprinter POLICY_HND handle; uint32 level; SPOOL_PRINTER_INFO_LEVEL info; - - DEVICEMODE *devmode; + DEVMODE_CTR devmode_ctr; /* lkclXXXX jean-francois, see SEC_DESC_BUF code */ struct @@ -1391,7 +1392,7 @@ typedef struct spool_q_enumprinterdata typedef struct spool_r_enumprinterdata { uint32 valuesize; - UNISTR value; + uint16 *value; uint32 realvaluesize; uint32 type; uint32 datasize; diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c index 0979799a98b..d1f7ed61a40 100644 --- a/source/rpc_parse/parse_spoolss.c +++ b/source/rpc_parse/parse_spoolss.c @@ -575,6 +575,9 @@ static BOOL spoolss_io_devmode_cont(char *desc, DEVMODE_CTR *dm_c, prs_struct *p prs_debug(ps, depth, desc, "spoolss_io_devmode_cont"); depth++; + if(!prs_align(ps)) + return False; + if (!prs_uint32("size", ps, depth, &dm_c->size)) return False; @@ -1164,8 +1167,9 @@ static uint32 size_of_systemtime(SYSTEMTIME *systime) * write a UNICODE string. * used by all the RPC structs passing a buffer ********************************************************************/ -static BOOL spoolss_smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth) +static BOOL spoolss_smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth) { + uint16 zero=0; if (uni == NULL) return False; @@ -1173,6 +1177,8 @@ static BOOL spoolss_smb_io_unistr(char *desc, UNISTR *uni, prs_struct *ps, int depth++; if (!prs_unistr("unistr", ps, depth, uni)) return False; + if (!prs_uint16("null", ps, depth, &zero)) + return False; } @@ -2645,24 +2651,25 @@ BOOL spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps prs_debug(ps, depth, desc, "spoolss_io_q_setprinter"); depth++; - prs_align(ps); - - smb_io_prt_hnd("printer handle", &(q_u->handle),ps,depth); - prs_uint32("level", ps, depth, &(q_u->level)); - - /* again a designed mess */ - /* sometimes I'm wondering how all of this work ! */ + if(!prs_align(ps)) + return False; - /* To be correct it need to be split in 3 functions */ + if(!smb_io_prt_hnd("printer handle", &q_u->handle ,ps, depth)) + return False; + if(!prs_uint32("level", ps, depth, &q_u->level)) + return False; - spool_io_printer_info_level("", &(q_u->info), ps, depth); + if(!spool_io_printer_info_level("", &q_u->info, ps, depth)) + return False; - spoolss_io_devmode(desc, ps, depth, q_u->devmode); + 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)); + prs_uint32("security.size_of_buffer", ps, depth, &q_u->security.size_of_buffer); + prs_uint32("security.data", ps, depth, &q_u->security.data); - prs_uint32("command", ps, depth, &(q_u->command)); + if(!prs_uint32("command", ps, depth, &q_u->command)) + return False; return True; } @@ -3074,77 +3081,83 @@ BOOL spoolss_io_q_enumports(char *desc, SPOOL_Q_ENUMPORTS *q_u, prs_struct *ps, return True; } - /******************************************************************* + Parse a SPOOL_PRINTER_INFO_LEVEL_2 structure. ********************************************************************/ -BOOL spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 **q_u, 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) { - SPOOL_PRINTER_INFO_LEVEL_2 *il; - - prs_debug(ps, depth, desc, ""); + prs_debug(ps, depth, desc, "spool_io_printer_info_level_2"); depth++; - - /* reading */ - if (ps->io) - { - il=(SPOOL_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(SPOOL_PRINTER_INFO_LEVEL_2)); - ZERO_STRUCTP(il); - *q_u=il; - DEBUG(7,("lecture: memoire ok\n")); - } - else - { - il=*q_u; - } - prs_align(ps); - - prs_uint32("servername_ptr", ps, depth, &(il->servername_ptr)); - prs_uint32("printername_ptr", ps, depth, &(il->printername_ptr)); - prs_uint32("sharename_ptr", ps, depth, &(il->sharename_ptr)); - prs_uint32("portname_ptr", ps, depth, &(il->portname_ptr)); - prs_uint32("drivername_ptr", ps, depth, &(il->drivername_ptr)); - prs_uint32("comment_ptr", ps, depth, &(il->comment_ptr)); - prs_uint32("location_ptr", ps, depth, &(il->location_ptr)); - prs_uint32("devmode_ptr", ps, depth, &(il->devmode_ptr)); - prs_uint32("sepfile_ptr", ps, depth, &(il->sepfile_ptr)); - prs_uint32("printprocessor_ptr", ps, depth, &(il->printprocessor_ptr)); - prs_uint32("datatype_ptr", ps, depth, &(il->datatype_ptr)); - prs_uint32("parameters_ptr", ps, depth, &(il->parameters_ptr)); - prs_uint32("secdesc_ptr", ps, depth, &(il->secdesc_ptr)); - - prs_uint32("attributes", ps, depth, &(il->attributes)); - prs_uint32("priority", ps, depth, &(il->priority)); - prs_uint32("default_priority", ps, depth, &(il->default_priority)); - prs_uint32("starttime", ps, depth, &(il->starttime)); - prs_uint32("untiltime", ps, depth, &(il->untiltime)); - prs_uint32("status", ps, depth, &(il->status)); - prs_uint32("cjobs", ps, depth, &(il->cjobs)); - prs_uint32("averageppm", ps, depth, &(il->averageppm)); - - smb_io_unistr2("", &(il->servername), il->servername_ptr, ps, depth); - smb_io_unistr2("", &(il->printername), il->printername_ptr, ps, depth); - smb_io_unistr2("", &(il->sharename), il->sharename_ptr, ps, depth); - smb_io_unistr2("", &(il->portname), il->portname_ptr, ps, depth); - smb_io_unistr2("", &(il->drivername), il->drivername_ptr, ps, depth); - smb_io_unistr2("", &(il->comment), il->comment_ptr, ps, depth); - smb_io_unistr2("", &(il->location), il->location_ptr, ps, depth); - smb_io_unistr2("", &(il->sepfile), il->sepfile_ptr, ps, depth); - smb_io_unistr2("", &(il->printprocessor), il->printprocessor_ptr, ps, depth); - smb_io_unistr2("", &(il->datatype), il->datatype_ptr, ps, depth); - smb_io_unistr2("", &(il->parameters), il->parameters_ptr, ps, depth); + if(!prs_align(ps)) + return False; - prs_align(ps); + if(!prs_uint32("servername_ptr", ps, depth, &il->servername_ptr)) + return False; + if(!prs_uint32("printername_ptr", ps, depth, &il->printername_ptr)) + return False; + if(!prs_uint32("sharename_ptr", ps, depth, &il->sharename_ptr)) + return False; + if(!prs_uint32("portname_ptr", ps, depth, &il->portname_ptr)) + return False; + if(!prs_uint32("drivername_ptr", ps, depth, &il->drivername_ptr)) + return False; + if(!prs_uint32("comment_ptr", ps, depth, &il->comment_ptr)) + return False; + if(!prs_uint32("location_ptr", ps, depth, &il->location_ptr)) + return False; + if(!prs_uint32("devmode_ptr", ps, depth, &il->devmode_ptr)) + return False; + if(!prs_uint32("sepfile_ptr", ps, depth, &il->sepfile_ptr)) + return False; + if(!prs_uint32("printprocessor_ptr", ps, depth, &il->printprocessor_ptr)) + return False; + if(!prs_uint32("datatype_ptr", ps, depth, &il->datatype_ptr)) + return False; + if(!prs_uint32("parameters_ptr", ps, depth, &il->parameters_ptr)) + return False; + if(!prs_uint32("secdesc_ptr", ps, depth, &il->secdesc_ptr)) + return False; - /* this code as nothing to do here !!! - - if (il->secdesc_ptr) - { - il->secdesc=NULL; - sec_io_desc_buf("", &(il->secdesc), ps, depth); - } - - */ + if(!prs_uint32("attributes", ps, depth, &il->attributes)) + return False; + if(!prs_uint32("priority", ps, depth, &il->priority)) + return False; + if(!prs_uint32("default_priority", ps, depth, &il->default_priority)) + return False; + if(!prs_uint32("starttime", ps, depth, &il->starttime)) + return False; + if(!prs_uint32("untiltime", ps, depth, &il->untiltime)) + return False; + if(!prs_uint32("status", ps, depth, &il->status)) + return False; + if(!prs_uint32("cjobs", ps, depth, &il->cjobs)) + return False; + if(!prs_uint32("averageppm", ps, depth, &il->averageppm)) + return False; + + if(!smb_io_unistr2("servername", &il->servername, il->servername_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("printername", &il->printername, il->printername_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("sharename", &il->sharename, il->sharename_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("portname", &il->portname, il->portname_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("drivername", &il->drivername, il->drivername_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("comment", &il->comment, il->comment_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("location", &il->location, il->location_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("sepfile", &il->sepfile, il->sepfile_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("printprocessor", &il->printprocessor, il->printprocessor_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("datatype", &il->datatype, il->datatype_ptr, ps, depth)) + return False; + if(!smb_io_unistr2("parameters", &il->parameters, il->parameters_ptr, ps, depth)) + return False; return True; } @@ -3153,16 +3166,24 @@ BOOL spool_io_printer_info_level_2(char *desc, SPOOL_PRINTER_INFO_LEVEL_2 **q_u, ********************************************************************/ BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_struct *ps, int depth) { - uint32 useless; - uint32 level; - prs_debug(ps, depth, desc, ""); + prs_debug(ps, depth, desc, "spool_io_printer_info_level"); depth++; - prs_align(ps); - prs_uint32("info level", ps, depth, &level); - prs_uint32("useless", ps, depth, &useless); - - switch (level) { + if(!prs_align(ps)) + return False; + if(!prs_uint32("level", ps, depth, &il->level)) + return False; + if(!prs_uint32("info_ptr", ps, depth, &il->info_ptr)) + return False; + + /* if no struct inside just return */ + if (il->info_ptr==0) { + if (UNMARSHALLING(ps)) + il->info_2=NULL; + return True; + } + + switch (il->level) { /* * level 0 is used by setprinter when managing the queue * (hold, stop, start a queue) @@ -3174,11 +3195,13 @@ BOOL spool_io_printer_info_level(char *desc, SPOOL_PRINTER_INFO_LEVEL *il, prs_s * and by setprinter when updating printer's info */ case 2: - spool_io_printer_info_level_2("", &(il->info_2), ps, depth); + if (UNMARSHALLING(ps)) + il->info_2=(SPOOL_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(SPOOL_PRINTER_INFO_LEVEL_2)); + if (!spool_io_printer_info_level_2("", il->info_2, ps, depth)) + return False; break; } - return True; } @@ -3761,17 +3784,26 @@ BOOL spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_ prs_debug(ps, depth, desc, "spoolss_io_r_enumprinterdata"); depth++; - prs_align(ps); - prs_uint32("valuesize", ps, depth, &(r_u->valuesize)); - prs_unistr("value", ps, depth, &(r_u->value)); - prs_uint32("realvaluesize", ps, depth, &(r_u->realvaluesize)); + if(!prs_align(ps)) + return False; + if(!prs_uint32("valuesize", ps, depth, &r_u->valuesize)) + return False; + if(!prs_uint16s(False, "value", ps, depth, r_u->value, r_u->valuesize)) + return False; + if(!prs_uint32("realvaluesize", ps, depth, &r_u->realvaluesize)) + return False; - prs_uint32("type", ps, depth, &(r_u->type)); + if(!prs_uint32("type", ps, depth, &r_u->type)) + return False; - prs_uint32("datasize", ps, depth, &(r_u->datasize)); - prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize); - prs_uint32("realdatasize", ps, depth, &(r_u->realdatasize)); - prs_uint32("status", ps, depth, &(r_u->status)); + if(!prs_uint32("datasize", ps, depth, &r_u->datasize)) + return False; + if(!prs_uint8s(False, "data", ps, depth, r_u->data, r_u->datasize)) + return False; + if(!prs_uint32("realdatasize", ps, depth, &r_u->realdatasize)) + return False; + if(!prs_uint32("status", ps, depth, &r_u->status)) + return False; return True; } @@ -3783,11 +3815,16 @@ BOOL spoolss_io_q_enumprinterdata(char *desc, SPOOL_Q_ENUMPRINTERDATA *q_u, prs_ prs_debug(ps, depth, desc, "spoolss_io_q_enumprinterdata"); depth++; - prs_align(ps); - smb_io_prt_hnd("printer handle",&(q_u->handle),ps,depth); - prs_uint32("index", ps, depth, &(q_u->index)); - prs_uint32("valuesize", ps, depth, &(q_u->valuesize)); - prs_uint32("datasize", ps, depth, &(q_u->datasize)); + if(!prs_align(ps)) + return False; + if(!smb_io_prt_hnd("printer handle",&q_u->handle,ps,depth)) + return False; + if(!prs_uint32("index", ps, depth, &q_u->index)) + return False; + if(!prs_uint32("valuesize", ps, depth, &q_u->valuesize)) + return False; + if(!prs_uint32("datasize", ps, depth, &q_u->datasize)) + return False; return True; } diff --git a/source/rpc_server/srv_spoolss.c b/source/rpc_server/srv_spoolss.c index be6775f35d2..d20f6c1616f 100755 --- a/source/rpc_server/srv_spoolss.c +++ b/source/rpc_server/srv_spoolss.c @@ -444,8 +444,6 @@ static BOOL api_spoolss_writeprinter(uint16 vuid, prs_struct *data, prs_struct * /**************************************************************************** -FIX ME: JFM: freeing memory ???? - ****************************************************************************/ static BOOL api_spoolss_setprinter(uint16 vuid, prs_struct *data, prs_struct *rdata) { @@ -460,13 +458,15 @@ static BOOL api_spoolss_setprinter(uint16 vuid, prs_struct *data, prs_struct *rd return False; } - DEBUG(0,("api_spoolss_setprinter: typecast sec_des to uint8*!\n")); - r_u.status = _spoolss_setprinter(&q_u.handle, - q_u.level, &q_u.info, - q_u.devmode, - q_u.security.size_of_buffer, - (const uint8*)q_u.security.data, - q_u.command); + r_u.status = _spoolss_setprinter(&q_u.handle, q_u.level, &q_u.info, + q_u.devmode_ctr, q_u.command); + + /* now, we can free the memory */ + if (q_u.info.level==2 && q_u.info.info_ptr!=0) + safe_free(q_u.info.info_2); + + if (q_u.devmode_ctr.devmode_ptr!=0) + safe_free(q_u.devmode_ctr.devmode); if(!spoolss_io_r_setprinter("",&r_u,rdata,0)) { DEBUG(0,("spoolss_io_r_setprinter: unable to marshall SPOOL_R_SETPRINTER.\n")); @@ -836,24 +836,19 @@ static BOOL api_spoolss_enumprinterdata(uint16 vuid, prs_struct *data, prs_struc return False; } - r_u.valuesize = q_u.valuesize; - r_u.datasize = q_u.datasize; - - r_u.status = _spoolss_enumprinterdata(&q_u.handle, - q_u.index,/* in */ - &r_u.valuesize,/* in out */ - &r_u.value,/* out */ - &r_u.realvaluesize,/* out */ - &r_u.type,/* out */ - &r_u.datasize,/* in out */ - &r_u.data,/* out */ - &r_u.realdatasize);/* out */ + r_u.status = _spoolss_enumprinterdata(&q_u.handle, q_u.index, q_u.valuesize, q_u.datasize, + &r_u.valuesize, &r_u.value, &r_u.realvaluesize, + &r_u.type, + &r_u.datasize, &r_u.data, &r_u.realdatasize); if(!spoolss_io_r_enumprinterdata("", &r_u, rdata, 0)) { DEBUG(0,("spoolss_io_r_enumprinterdata: unable to marshall SPOOL_R_ENUMPRINTERDATA.\n")); + safe_free(r_u.value); + safe_free(r_u.data); return False; } + safe_free(r_u.value); safe_free(r_u.data); return True; diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c index da7eda57958..3ab426e9c2c 100644 --- a/source/rpc_server/srv_spoolss_nt.c +++ b/source/rpc_server/srv_spoolss_nt.c @@ -66,6 +66,10 @@ typedef struct _Printer{ uint32 printerlocal; SPOOL_NOTIFY_OPTION *option; } notify; + struct { + fstring machine; + fstring user; + } client; } Printer_entry; static ubi_dlList Printer_list; @@ -160,8 +164,6 @@ static BOOL close_printer_handle(POLICY_HND *hnd) safe_free(Printer); - DEBUG(0,("[%d] entrys still in list\n", ubi_dlCount(&Printer_list))); - return True; } @@ -2632,25 +2634,30 @@ static uint32 control_printer(const POLICY_HND *handle, uint32 command) if (!OPEN_HANDLE(Printer)) return NT_STATUS_INVALID_HANDLE; - if (!get_printer_snum(handle, &snum) ) - { + if (!get_printer_snum(handle, &snum) ) return NT_STATUS_INVALID_HANDLE; - } - switch (command) - { + switch (command) { case PRINTER_CONTROL_PAUSE: /* pause the printer here */ status_printqueue(NULL, snum, LPSTAT_STOPPED); return 0x0; - + break; case PRINTER_CONTROL_RESUME: case PRINTER_CONTROL_UNPAUSE: /* UN-pause the printer here */ status_printqueue(NULL, snum, LPSTAT_OK); return 0x0; + break; case PRINTER_CONTROL_PURGE: - /* Envoi des dragées FUCA dans l'imprimante */ + /* + * It's not handled by samba + * we need a smb.conf param to do + * lprm -P%p - on BSD + * lprm -P%p all on LPRNG + * I don't know on SysV + * we could do it by looping in the job's list... + */ break; } @@ -2675,9 +2682,8 @@ static uint32 update_printer(const POLICY_HND *handle, uint32 level, DEBUG(8,("update_printer\n")); - if (level!=2) - { - DEBUG(0,("Send a mail to samba-bugs@samba.org\n")); + if (level!=2) { + DEBUG(0,("Send a mail to jfm@samba.org\n")); DEBUGADD(0,("with the following message: update_printer: level!=2\n")); return NT_STATUS_INVALID_INFO_CLASS; } @@ -2688,13 +2694,12 @@ static uint32 update_printer(const POLICY_HND *handle, uint32 level, if (!get_printer_snum(handle, &snum) ) return NT_STATUS_INVALID_HANDLE; - get_a_printer(&printer, level, lp_servicename(snum)); + get_a_printer(&printer, 2, lp_servicename(snum)); DEBUGADD(8,("Converting info_2 struct\n")); convert_printer_info(info, &printer, level); - if ((info->info_2)->devmode_ptr != 0) - { + if ((info->info_2)->devmode_ptr != 0) { /* we have a valid devmode convert it and link it*/ @@ -2710,36 +2715,30 @@ static uint32 update_printer(const POLICY_HND *handle, uint32 level, convert_devicemode(*devmode, nt_devmode); } - else - { + else { if (printer.info_2->devmode != NULL) - { free(printer.info_2->devmode); - } printer.info_2->devmode=NULL; } - if (status == 0x0) - { - status = add_a_printer(printer, level); - } - if (status == 0x0) - { - status = free_a_printer(printer, level); + if (add_a_printer(printer, 2)!=0) { + free_a_printer(printer, 2); + + /* I don't really know what to return here !!! */ + return NT_STATUS_INVALID_INFO_CLASS; } - return status; + free_a_printer(printer, 2); + + return NT_STATUS_NO_PROBLEMO; } /**************************************************************************** ****************************************************************************/ -uint32 _spoolss_setprinter( const POLICY_HND *handle, - uint32 level, - const SPOOL_PRINTER_INFO_LEVEL *info, - const DEVICEMODE *devmode, - uint32 sec_buf_size, - const char *sec_buf, - uint32 command) +uint32 _spoolss_setprinter(const POLICY_HND *handle, uint32 level, + const SPOOL_PRINTER_INFO_LEVEL *info, + const DEVMODE_CTR devmode_ctr, + uint32 command) { Printer_entry *Printer = find_printer_index_by_hnd(handle); @@ -2747,13 +2746,12 @@ uint32 _spoolss_setprinter( const POLICY_HND *handle, return NT_STATUS_INVALID_HANDLE; /* check the level */ - switch (level) - { + switch (level) { case 0: return control_printer(handle, command); break; case 2: - return update_printer(handle, level, info, devmode); + return update_printer(handle, level, info, devmode_ctr.devmode); break; } @@ -3094,7 +3092,7 @@ static uint32 enumprinterdrivers_level1(fstring *list, fstring servername, fstri /* fill the buffer with the form structures */ for (i=0; i<*returned; i++) { - DEBUGADD(6,("adding form [%d] to buffer\n",i)); + DEBUGADD(6,("adding driver [%d] to buffer\n",i)); new_smb_io_printer_driver_info_1("", buffer, &(driver_info_1[i]), 0); } @@ -3135,7 +3133,7 @@ static uint32 enumprinterdrivers_level2(fstring *list, fstring servername, fstri /* fill the buffer with the form structures */ for (i=0; i<*returned; i++) { - DEBUGADD(6,("adding form [%d] to buffer\n",i)); + DEBUGADD(6,("adding driver [%d] to buffer\n",i)); new_smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0); } @@ -3588,15 +3586,11 @@ uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environmen /**************************************************************************** ****************************************************************************/ -uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, - uint32 idx, - uint32 *valuesize, - UNISTR *uni_value, - uint32 *realvaluesize, - uint32 *type, - uint32 *datasize, - uint8 **data, - uint32 *realdatasize) +uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 index, + 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_data, uint32 *out_data_len) { NT_PRINTER_INFO_LEVEL printer; @@ -3606,12 +3600,22 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, uint32 biggest_valuesize; uint32 biggest_datasize; uint32 data_len; - uint32 status = 0x0; Printer_entry *Printer = find_printer_index_by_hnd(handle); int snum; + uint8 *data=NULL; + uint32 type; ZERO_STRUCT(printer); - (*data)=NULL; + + *out_max_value_len=0; + *out_value=NULL; + *out_value_len=0; + + *out_type=0; + + *out_max_data_len=0; + *out_data=NULL; + *out_data_len=0; DEBUG(5,("spoolss_enumprinterdata\n")); @@ -3621,74 +3625,77 @@ uint32 _spoolss_enumprinterdata(const POLICY_HND *handle, if (!get_printer_snum(handle, &snum)) return NT_STATUS_INVALID_HANDLE; - status = get_a_printer(&printer, 2, lp_servicename(snum)); - - if (status != 0x0) - return status; + if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0x0) + return NT_STATUS_INVALID_HANDLE; - /* The NT machine wants to know the biggest size of value and data */ - if ( ((*valuesize)==0) && ((*datasize)==0) ) - { + /* + * The NT machine wants to know the biggest size of value and data + * + * cf: MSDN EnumPrinterData remark section + */ + if ( (in_value_len==0) && (in_data_len==0) ) { DEBUGADD(6,("Activating NT mega-hack to find sizes\n")); - (*valuesize)=0; - (*realvaluesize)=0; - (*type)=0; - (*datasize)=0; - (*realdatasize)=0; - status=0; - param_index=0; biggest_valuesize=0; biggest_datasize=0; - while (get_specific_param_by_index(printer, 2, param_index, value, data, type, &data_len)) - { + while (get_specific_param_by_index(printer, 2, param_index, value, &data, &type, &data_len)) { if (strlen(value) > biggest_valuesize) biggest_valuesize=strlen(value); - if (data_len > biggest_datasize) biggest_datasize=data_len; + if (data_len > biggest_datasize) biggest_datasize=data_len; + DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize, biggest_datasize)); + + safe_free(data); param_index++; } - - /* I wrote it, I didn't designed the protocol */ - if (biggest_valuesize!=0) - { - SIVAL(&(value),0, 2*(biggest_valuesize+1) ); - } - (*data)=(uint8 *)malloc(4*sizeof(uint8)); - SIVAL((*data), 0, biggest_datasize ); + + /* the value is an UNICODE string but realvaluesize is the length in bytes including the leading 0 */ + *out_value_len=2*(1+biggest_valuesize); + *out_data_len=biggest_datasize; + + DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len)); + + free_a_printer(printer, 2); + return NT_STATUS_NO_PROBLEMO; } - else - { - /* - * the value len is wrong in NT sp3 - * that's the number of bytes not the number of unicode chars - */ - - if (get_specific_param_by_index(printer, 2, idx, value, data, type, &data_len)) - { - init_unistr(uni_value, value); - - /* the length are in bytes including leading NULL */ - (*realvaluesize)=2*(strlen(value)+1); - (*realdatasize)=data_len; - - status=0; - } - else - { - (*valuesize)=0; - (*realvaluesize)=0; - (*datasize)=0; - (*realdatasize)=0; - (*type)=0; - status=0x0103; /* ERROR_NO_MORE_ITEMS */ - } + + /* + * the value len is wrong in NT sp3 + * that's the number of bytes not the number of unicode chars + */ + + if (!get_specific_param_by_index(printer, 2, index, value, &data, &type, &data_len)) { + free_a_printer(printer, 2); + return 0x0103; /* ERROR_NO_MORE_ITEMS */ } + + /* + * the value is: + * - counted in bytes in the request + * - counted in UNICODE chars in the max reply + * - counted in bytes in the real size + * + * take a pause *before* coding not *during* coding + */ + + *out_max_value_len=in_value_len/2; + *out_value=(uint16 *)malloc(in_value_len*sizeof(uint8)); + ascii_to_unistr(*out_value, value, *out_max_value_len); + *out_value_len=2*(1+strlen(value)); + + *out_type=type; + + /* the data is counted in bytes */ + *out_max_data_len=in_data_len; + *out_data=(uint8 *)malloc(in_data_len*sizeof(uint8)); + memcpy(*out_data, data, data_len); + *out_data_len=data_len; + + safe_free(data); free_a_printer(printer, 2); - - return status; + return NT_STATUS_NO_PROBLEMO; } /**************************************************************************** -- cgit From d7bcfe17cee64a513595d7c44456e93e88f2448b Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Sat, 26 Feb 2000 23:01:02 +0000 Subject: added enumprintprocessordatatypes now NT is happy and the "always send data in RAW mode" is checked J.F. --- source/include/proto.h | 687 +++++++++++++++++++------------------ source/include/rpc_spoolss.h | 25 +- source/rpc_parse/parse_spoolss.c | 98 ++++++ source/rpc_server/srv_spoolss.c | 36 ++ source/rpc_server/srv_spoolss_nt.c | 49 +++ 5 files changed, 543 insertions(+), 352 deletions(-) diff --git a/source/include/proto.h b/source/include/proto.h index 53daacc098b..234e51d1846 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -186,208 +186,10 @@ void CatchChildLeaveStatus(void); int vslprintf(char *str, int n, char *format, va_list ap); -/*The following definitions come from libsmb/clientgen.c */ - -int cli_set_port(struct cli_state *cli, int port); -char *cli_errstr(struct cli_state *cli); -BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, - uint16 *setup, uint32 setup_count, uint32 max_setup_count, - char *params, uint32 param_count, uint32 max_param_count, - char *data, uint32 data_count, uint32 max_data_count, - char **rparam, uint32 *rparam_count, - char **rdata, uint32 *rdata_count); -BOOL cli_api(struct cli_state *cli, - char *param, int prcnt, int mprcnt, - char *data, int drcnt, int mdrcnt, - char **rparam, int *rprcnt, - char **rdata, int *rdrcnt); -BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation); -int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)); -BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, - void (*fn)(const char *, uint32, const char *)); -BOOL cli_session_setup(struct cli_state *cli, - char *user, - char *pass, int passlen, - char *ntpass, int ntpasslen, - char *workgroup); -BOOL cli_ulogoff(struct cli_state *cli); -BOOL cli_send_tconX(struct cli_state *cli, - char *share, char *dev, char *pass, int passlen); -BOOL cli_tdis(struct cli_state *cli); -BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst); -BOOL cli_unlink(struct cli_state *cli, char *fname); -BOOL cli_mkdir(struct cli_state *cli, char *dname); -BOOL cli_rmdir(struct cli_state *cli, char *dname); -int cli_nt_create(struct cli_state *cli, char *fname); -int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode); -BOOL cli_close(struct cli_state *cli, int fnum); -BOOL cli_lock(struct cli_state *cli, int fnum, - uint32 offset, uint32 len, int timeout, enum brl_type lock_type); -BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len); -size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size); -ssize_t cli_write(struct cli_state *cli, - int fnum, uint16 write_mode, - char *buf, off_t offset, size_t size); -ssize_t cli_smbwrite(struct cli_state *cli, - int fnum, char *buf, off_t offset, size_t size1); -BOOL cli_getattrE(struct cli_state *cli, int fd, - uint16 *attr, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time); -BOOL cli_getatr(struct cli_state *cli, char *fname, - uint16 *attr, size_t *size, time_t *t); -BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t); -BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - size_t *size, uint16 *mode); -BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, size_t *size, uint16 *mode, - SMB_INO_T *ino); -BOOL cli_qfileinfo(struct cli_state *cli, int fnum, - uint16 *mode, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, SMB_INO_T *ino); -int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *)); -BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, - const char *old_password); -BOOL cli_negprot(struct cli_state *cli); -BOOL cli_session_request(struct cli_state *cli, - struct nmb_name *calling, struct nmb_name *called); -BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip); -struct cli_state *cli_initialise(struct cli_state *cli); -void cli_shutdown(struct cli_state *cli); -int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error); -void cli_sockopt(struct cli_state *cli, char *options); -uint16 cli_setpid(struct cli_state *cli, uint16 pid); -BOOL cli_reestablish_connection(struct cli_state *cli); -BOOL cli_establish_connection(struct cli_state *cli, - char *dest_host, struct in_addr *dest_ip, - struct nmb_name *calling, struct nmb_name *called, - char *service, char *service_type, - BOOL do_shutdown, BOOL do_tcon); -int cli_printjob_del(struct cli_state *cli, int job); -int cli_print_queue(struct cli_state *cli, - void (*fn)(struct print_job_info *)); -BOOL cli_chkpath(struct cli_state *cli, char *path); -BOOL cli_message_start(struct cli_state *cli, char *host, char *username, - int *grp); -BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp); -BOOL cli_message_end(struct cli_state *cli, int grp); -BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail); -BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, - struct in_addr *pdest_ip); - -/*The following definitions come from libsmb/credentials.c */ - -char *credstr(uchar *cred); -void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, - uchar session_key[8]); -void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp, - DOM_CHAL *cred); -int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred, - UTIME timestamp); -BOOL clnt_deal_with_creds(uchar sess_key[8], - DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred); -BOOL deal_with_creds(uchar sess_key[8], - DOM_CRED *sto_clnt_cred, - DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred); - -/*The following definitions come from libsmb/namequery.c */ - -BOOL name_status(int fd,char *name,int name_type,BOOL recurse, - struct in_addr to_ip,char *master,char *rname); -struct in_addr *name_query(int fd,const char *name,int name_type, - BOOL bcast,BOOL recurse, - struct in_addr to_ip, int *count); -FILE *startlmhosts(char *fname); -BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr); -void endlmhosts(FILE *fp); -BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type); -BOOL find_master_ip(char *group, struct in_addr *master_ip); -BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name); -BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count); - -/*The following definitions come from libsmb/nmblib.c */ - -void debug_nmb_packet(struct packet_struct *p); -char *nmb_namestr(struct nmb_name *n); -struct packet_struct *copy_packet(struct packet_struct *packet); -void free_packet(struct packet_struct *packet); -struct packet_struct *parse_packet(char *buf,int length, - enum packet_type packet_type); -struct packet_struct *read_packet(int fd,enum packet_type packet_type); -void make_nmb_name( struct nmb_name *n, const char *name, int type); -BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2); -int build_packet(char *buf, struct packet_struct *p); -BOOL send_packet(struct packet_struct *p); -struct packet_struct *receive_packet(int fd,enum packet_type type,int t); -struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id); -struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name); -BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name); -void sort_query_replies(char *data, int n, struct in_addr ip); - -/*The following definitions come from libsmb/nterr.c */ - -char *get_nt_error_msg(uint32 nt_code); - -/*The following definitions come from libsmb/passchange.c */ - -BOOL remote_password_change(const char *remote_machine, const char *user_name, - const char *old_passwd, const char *new_passwd, - char *err_str, size_t err_str_len); - -/*The following definitions come from libsmb/pwd_cache.c */ - -void pwd_init(struct pwd_info *pwd); -void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key); -BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2); -void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt); -void pwd_set_nullpwd(struct pwd_info *pwd); -void pwd_set_cleartext(struct pwd_info *pwd, char *clr); -void pwd_get_cleartext(struct pwd_info *pwd, char *clr); -void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); -void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); -void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr); -void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]); -void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]); - /*The following definitions come from lib/smbrun.c */ int smbrun(char *cmd,char *outfile,BOOL shared); -/*The following definitions come from libsmb/smbdes.c */ - -void E_P16(unsigned char *p14,unsigned char *p16); -void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); -void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out); -void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out); -void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key); -void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key); -void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw); -void SamOEMhash( unsigned char *data, unsigned char *key, int val); - -/*The following definitions come from libsmb/smbencrypt.c */ - -void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24); -void E_md4hash(uchar *passwd, uchar *p16); -void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]); -void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]); -void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]); -void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24); -BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode); - -/*The following definitions come from libsmb/smberr.c */ - -char *smb_errstr(char *inbuf); - -/*The following definitions come from libsmb/unexpected.c */ - -void unexpected_packet(struct packet_struct *p); -void clear_unexpected(time_t t); -struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, - char *mailslot_name); - /*The following definitions come from lib/snprintf.c */ @@ -472,23 +274,6 @@ BOOL map_username(char *user); struct passwd *Get_Pwnam(char *user,BOOL allow_change); BOOL user_in_list(char *user,char *list); -/*The following definitions come from lib/util_array.c */ - -void free_void_array(uint32 num_entries, void **entries, - void(free_item)(void*)); -void* add_copy_to_array(uint32 *len, void ***array, const void *item, - void*(item_dup)(const void*), BOOL alloc_anyway); -void* add_item_to_array(uint32 *len, void ***array, void *item); -void free_use_info_array(uint32 num_entries, struct use_info **entries); -struct use_info* add_use_info_to_array(uint32 *len, struct use_info ***array, - const struct use_info *name); -void free_char_array(uint32 num_entries, char **entries); -char* add_chars_to_array(uint32 *len, char ***array, const char *name); -void free_uint32_array(uint32 num_entries, uint32 **entries); -uint32* add_uint32s_to_array(uint32 *len, uint32 ***array, const uint32 *name); -void free_sid_array(uint32 num_entries, DOM_SID **entries); -DOM_SID* add_sid_to_array(uint32 *len, DOM_SID ***array, const DOM_SID *sid); - /*The following definitions come from lib/util.c */ char *tmpdir(void); @@ -566,6 +351,23 @@ char *myhostname(void); char *lock_path(char *name); char *parent_dirname(const char *path); +/*The following definitions come from lib/util_array.c */ + +void free_void_array(uint32 num_entries, void **entries, + void(free_item)(void*)); +void* add_copy_to_array(uint32 *len, void ***array, const void *item, + void*(item_dup)(const void*), BOOL alloc_anyway); +void* add_item_to_array(uint32 *len, void ***array, void *item); +void free_use_info_array(uint32 num_entries, struct use_info **entries); +struct use_info* add_use_info_to_array(uint32 *len, struct use_info ***array, + const struct use_info *name); +void free_char_array(uint32 num_entries, char **entries); +char* add_chars_to_array(uint32 *len, char ***array, const char *name); +void free_uint32_array(uint32 num_entries, uint32 **entries); +uint32* add_uint32s_to_array(uint32 *len, uint32 ***array, const uint32 *name); +void free_sid_array(uint32 num_entries, DOM_SID **entries); +DOM_SID* add_sid_to_array(uint32 *len, DOM_SID ***array, const DOM_SID *sid); + /*The following definitions come from lib/util_file.c */ BOOL do_file_lock(int fd, int waitsecs, int type); @@ -755,6 +557,204 @@ void split_at_last_component_w(smb_ucs2_t *path, smb_ucs2_t *front, smb_ucs2_t s smb_ucs2_t *octal_string_w(int i); smb_ucs2_t *string_truncate_w(smb_ucs2_t *s, size_t length); +/*The following definitions come from libsmb/clientgen.c */ + +int cli_set_port(struct cli_state *cli, int port); +char *cli_errstr(struct cli_state *cli); +BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, + uint16 *setup, uint32 setup_count, uint32 max_setup_count, + char *params, uint32 param_count, uint32 max_param_count, + char *data, uint32 data_count, uint32 max_data_count, + char **rparam, uint32 *rparam_count, + char **rdata, uint32 *rdata_count); +BOOL cli_api(struct cli_state *cli, + char *param, int prcnt, int mprcnt, + char *data, int drcnt, int mdrcnt, + char **rparam, int *rprcnt, + char **rdata, int *rdrcnt); +BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation); +int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)); +BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, + void (*fn)(const char *, uint32, const char *)); +BOOL cli_session_setup(struct cli_state *cli, + char *user, + char *pass, int passlen, + char *ntpass, int ntpasslen, + char *workgroup); +BOOL cli_ulogoff(struct cli_state *cli); +BOOL cli_send_tconX(struct cli_state *cli, + char *share, char *dev, char *pass, int passlen); +BOOL cli_tdis(struct cli_state *cli); +BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst); +BOOL cli_unlink(struct cli_state *cli, char *fname); +BOOL cli_mkdir(struct cli_state *cli, char *dname); +BOOL cli_rmdir(struct cli_state *cli, char *dname); +int cli_nt_create(struct cli_state *cli, char *fname); +int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode); +BOOL cli_close(struct cli_state *cli, int fnum); +BOOL cli_lock(struct cli_state *cli, int fnum, + uint32 offset, uint32 len, int timeout, enum brl_type lock_type); +BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len); +size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size); +ssize_t cli_write(struct cli_state *cli, + int fnum, uint16 write_mode, + char *buf, off_t offset, size_t size); +ssize_t cli_smbwrite(struct cli_state *cli, + int fnum, char *buf, off_t offset, size_t size1); +BOOL cli_getattrE(struct cli_state *cli, int fd, + uint16 *attr, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time); +BOOL cli_getatr(struct cli_state *cli, char *fname, + uint16 *attr, size_t *size, time_t *t); +BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t); +BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, + size_t *size, uint16 *mode); +BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, size_t *size, uint16 *mode, + SMB_INO_T *ino); +BOOL cli_qfileinfo(struct cli_state *cli, int fnum, + uint16 *mode, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, SMB_INO_T *ino); +int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, + void (*fn)(file_info *, const char *)); +BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, + const char *old_password); +BOOL cli_negprot(struct cli_state *cli); +BOOL cli_session_request(struct cli_state *cli, + struct nmb_name *calling, struct nmb_name *called); +BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip); +struct cli_state *cli_initialise(struct cli_state *cli); +void cli_shutdown(struct cli_state *cli); +int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error); +void cli_sockopt(struct cli_state *cli, char *options); +uint16 cli_setpid(struct cli_state *cli, uint16 pid); +BOOL cli_reestablish_connection(struct cli_state *cli); +BOOL cli_establish_connection(struct cli_state *cli, + char *dest_host, struct in_addr *dest_ip, + struct nmb_name *calling, struct nmb_name *called, + char *service, char *service_type, + BOOL do_shutdown, BOOL do_tcon); +int cli_printjob_del(struct cli_state *cli, int job); +int cli_print_queue(struct cli_state *cli, + void (*fn)(struct print_job_info *)); +BOOL cli_chkpath(struct cli_state *cli, char *path); +BOOL cli_message_start(struct cli_state *cli, char *host, char *username, + int *grp); +BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp); +BOOL cli_message_end(struct cli_state *cli, int grp); +BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail); +BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, + struct in_addr *pdest_ip); + +/*The following definitions come from libsmb/credentials.c */ + +char *credstr(uchar *cred); +void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, + uchar session_key[8]); +void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp, + DOM_CHAL *cred); +int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred, + UTIME timestamp); +BOOL clnt_deal_with_creds(uchar sess_key[8], + DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred); +BOOL deal_with_creds(uchar sess_key[8], + DOM_CRED *sto_clnt_cred, + DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred); + +/*The following definitions come from libsmb/namequery.c */ + +BOOL name_status(int fd,char *name,int name_type,BOOL recurse, + struct in_addr to_ip,char *master,char *rname); +struct in_addr *name_query(int fd,const char *name,int name_type, + BOOL bcast,BOOL recurse, + struct in_addr to_ip, int *count); +FILE *startlmhosts(char *fname); +BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr); +void endlmhosts(FILE *fp); +BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type); +BOOL find_master_ip(char *group, struct in_addr *master_ip); +BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name); +BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count); + +/*The following definitions come from libsmb/nmblib.c */ + +void debug_nmb_packet(struct packet_struct *p); +char *nmb_namestr(struct nmb_name *n); +struct packet_struct *copy_packet(struct packet_struct *packet); +void free_packet(struct packet_struct *packet); +struct packet_struct *parse_packet(char *buf,int length, + enum packet_type packet_type); +struct packet_struct *read_packet(int fd,enum packet_type packet_type); +void make_nmb_name( struct nmb_name *n, const char *name, int type); +BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2); +int build_packet(char *buf, struct packet_struct *p); +BOOL send_packet(struct packet_struct *p); +struct packet_struct *receive_packet(int fd,enum packet_type type,int t); +struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id); +struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name); +BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name); +void sort_query_replies(char *data, int n, struct in_addr ip); + +/*The following definitions come from libsmb/nterr.c */ + +char *get_nt_error_msg(uint32 nt_code); + +/*The following definitions come from libsmb/passchange.c */ + +BOOL remote_password_change(const char *remote_machine, const char *user_name, + const char *old_passwd, const char *new_passwd, + char *err_str, size_t err_str_len); + +/*The following definitions come from libsmb/pwd_cache.c */ + +void pwd_init(struct pwd_info *pwd); +void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key); +BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2); +void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt); +void pwd_set_nullpwd(struct pwd_info *pwd); +void pwd_set_cleartext(struct pwd_info *pwd, char *clr); +void pwd_get_cleartext(struct pwd_info *pwd, char *clr); +void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); +void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]); +void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr); +void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]); +void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]); + +/*The following definitions come from libsmb/smbdes.c */ + +void E_P16(unsigned char *p14,unsigned char *p16); +void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); +void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out); +void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out); +void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key); +void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key); +void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw); +void SamOEMhash( unsigned char *data, unsigned char *key, int val); + +/*The following definitions come from libsmb/smbencrypt.c */ + +void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24); +void E_md4hash(uchar *passwd, uchar *p16); +void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]); +void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]); +void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]); +void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24); +BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode); + +/*The following definitions come from libsmb/smberr.c */ + +char *smb_errstr(char *inbuf); + +/*The following definitions come from libsmb/unexpected.c */ + +void unexpected_packet(struct packet_struct *p); +void clear_unexpected(time_t t); +struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, + char *mailslot_name); + /*The following definitions come from locking/brlock.c */ void brl_init(int read_only); @@ -812,6 +812,10 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question, struct name_record **n); void kill_async_dns_child(void); +/*The following definitions come from nmbd/nmbd.c */ + +BOOL reload_services(BOOL test); + /*The following definitions come from nmbd/nmbd_become_dmb.c */ void add_domain_names(time_t t); @@ -842,10 +846,6 @@ void announce_and_sync_with_domain_master_browser( struct subnet_record *subrec, void collect_all_workgroup_names_from_wins_server(time_t t); void sync_all_dmbs(time_t t); -/*The following definitions come from nmbd/nmbd.c */ - -BOOL reload_services(BOOL test); - /*The following definitions come from nmbd/nmbd_elections.c */ void check_master_browser_exists(time_t t); @@ -1520,6 +1520,11 @@ void pcap_printer_fn(void (*fn)(char *, char *)); void cups_printer_fn(void (*fn)(char *, char *)); int cups_printername_ok(char *name); +/*The following definitions come from printing/print_svid.c */ + +void sysv_printer_fn(void (*fn)(char *, char *)); +int sysv_printername_ok(char *name); + /*The following definitions come from printing/printing.c */ void lpq_reset(int snum); @@ -1534,11 +1539,6 @@ void printjob_decode(int jobid, int *snum, int *job); void status_printqueue(connection_struct *conn,int snum,int status); void load_printers(void); -/*The following definitions come from printing/print_svid.c */ - -void sysv_printer_fn(void (*fn)(char *, char *)); -int sysv_printername_ok(char *name); - /*The following definitions come from profile/profile.c */ BOOL profile_setup(BOOL rdonly); @@ -1704,109 +1704,6 @@ BOOL do_wks_query_info(struct cli_state *cli, char *server_name, uint32 switch_value, WKS_INFO_100 *wks100); -/*The following definitions come from rpcclient/cmd_lsarpc.c */ - -void cmd_lsa_query_info(struct client_info *info); -void cmd_lsa_lookup_sids(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_netlogon.c */ - -void cmd_netlogon_login_test(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_reg.c */ - -void cmd_reg_enum(struct client_info *info); -void cmd_reg_query_key(struct client_info *info); -void cmd_reg_create_val(struct client_info *info); -void cmd_reg_delete_val(struct client_info *info); -void cmd_reg_delete_key(struct client_info *info); -void cmd_reg_create_key(struct client_info *info); -void cmd_reg_test_key_sec(struct client_info *info); -void cmd_reg_get_key_sec(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_samr.c */ - -void cmd_sam_ntchange_pwd(struct client_info *info); -void cmd_sam_test(struct client_info *info); -void cmd_sam_enum_users(struct client_info *info); -void cmd_sam_query_user(struct client_info *info); -void cmd_sam_query_groups(struct client_info *info); -void cmd_sam_enum_aliases(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_srvsvc.c */ - -void cmd_srv_query_info(struct client_info *info); -void cmd_srv_enum_conn(struct client_info *info); -void cmd_srv_enum_shares(struct client_info *info); -void cmd_srv_enum_sess(struct client_info *info); -void cmd_srv_enum_files(struct client_info *info); - -/*The following definitions come from rpcclient/cmd_wkssvc.c */ - -void cmd_wks_query_info(struct client_info *info); - -/*The following definitions come from rpcclient/display.c */ - -char *get_file_mode_str(uint32 share_mode); -char *get_file_oplock_str(uint32 op_type); -char *get_share_type_str(uint32 type); -char *get_server_type_str(uint32 type); -void display_srv_info_101(FILE *out_hnd, enum action_type action, - SRV_INFO_101 *sv101); -void display_srv_info_102(FILE *out_hnd, enum action_type action,SRV_INFO_102 *sv102); -void display_srv_info_ctr(FILE *out_hnd, enum action_type action,SRV_INFO_CTR *ctr); -void display_conn_info_0(FILE *out_hnd, enum action_type action, - CONN_INFO_0 *info0); -void display_conn_info_1(FILE *out_hnd, enum action_type action, - CONN_INFO_1 *info1, CONN_INFO_1_STR *str1); -void display_srv_conn_info_0_ctr(FILE *out_hnd, enum action_type action, - SRV_CONN_INFO_0 *ctr); -void display_srv_conn_info_1_ctr(FILE *out_hnd, enum action_type action, - SRV_CONN_INFO_1 *ctr); -void display_srv_conn_info_ctr(FILE *out_hnd, enum action_type action, - SRV_CONN_INFO_CTR *ctr); -void display_share_info_1(FILE *out_hnd, enum action_type action, - SRV_SHARE_INFO_1 *info1); -void display_share_info_2(FILE *out_hnd, enum action_type action, - SRV_SHARE_INFO_2 *info2); -void display_srv_share_info_ctr(FILE *out_hnd, enum action_type action, - SRV_SHARE_INFO_CTR *ctr); -void display_file_info_3(FILE *out_hnd, enum action_type action, - FILE_INFO_3 *info3, FILE_INFO_3_STR *str3); -void display_srv_file_info_3_ctr(FILE *out_hnd, enum action_type action, - SRV_FILE_INFO_3 *ctr); -void display_srv_file_info_ctr(FILE *out_hnd, enum action_type action, - SRV_FILE_INFO_CTR *ctr); -void display_server(FILE *out_hnd, enum action_type action, - char *sname, uint32 type, char *comment); -void display_share(FILE *out_hnd, enum action_type action, - char *sname, uint32 type, char *comment); -void display_share2(FILE *out_hnd, enum action_type action, - char *sname, uint32 type, char *comment, - uint32 perms, uint32 max_uses, uint32 num_uses, - char *path, char *passwd); -void display_name(FILE *out_hnd, enum action_type action, - char *sname); -void display_group_rid_info(FILE *out_hnd, enum action_type action, - uint32 num_gids, DOM_GID *gid); -void display_alias_name_info(FILE *out_hnd, enum action_type action, - uint32 num_aliases, fstring *alias_name, uint32 *num_als_usrs); -void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_INFO_21 *usr); -char *get_sec_mask_str(uint32 type); -void display_sec_access(FILE *out_hnd, enum action_type action, SEC_ACCESS *info); -void display_sec_ace(FILE *out_hnd, enum action_type action, SEC_ACE *ace); -void display_sec_acl(FILE *out_hnd, enum action_type action, SEC_ACL *sec_acl); -void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *sec); -char *get_reg_val_type_str(uint32 type); -void display_reg_value_info(FILE *out_hnd, enum action_type action, - char *val_name, uint32 val_type, BUFFER2 *value); -void display_reg_key_info(FILE *out_hnd, enum action_type action, - char *key_name, time_t key_mod_time); - -/*The following definitions come from rpcclient/rpcclient.c */ - -void rpcclient_init(void); - /*The following definitions come from rpc_parse/parse_creds.c */ BOOL make_creds_unix(CREDS_UNIX *r_u, const char* user_name, @@ -2447,6 +2344,7 @@ BOOL new_smb_io_driverdir_1(char *desc, NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 * BOOL new_smb_io_port_1(char *desc, NEW_BUFFER *buffer, PORT_INFO_1 *info, int depth); BOOL new_smb_io_port_2(char *desc, NEW_BUFFER *buffer, PORT_INFO_2 *info, int depth); BOOL smb_io_printprocessor_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR_1 *info, int depth); +BOOL smb_io_printprocdatatype_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth); BOOL smb_io_printmonitor_info_1(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_1 *info, int depth); BOOL smb_io_printmonitor_info_2(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_2 *info, int depth); uint32 spoolss_size_printer_info_0(PRINTER_INFO_0 *info); @@ -2462,6 +2360,7 @@ uint32 spoolss_size_port_info_1(PORT_INFO_1 *info); uint32 spoolss_size_driverdir_info_1(DRIVER_DIRECTORY_1 *info); uint32 spoolss_size_port_info_2(PORT_INFO_2 *info); 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 spoolss_io_q_getprinterdriver2(char *desc, SPOOL_Q_GETPRINTERDRIVER2 *q_u, prs_struct *ps, int depth); @@ -2512,6 +2411,8 @@ BOOL spoolss_io_q_getprinterdriverdir(char *desc, SPOOL_Q_GETPRINTERDRIVERDIR *q BOOL spoolss_io_r_getprinterdriverdir(char *desc, SPOOL_R_GETPRINTERDRIVERDIR *r_u, prs_struct *ps, int depth); BOOL spoolss_io_r_enumprintprocessors(char *desc, SPOOL_R_ENUMPRINTPROCESSORS *r_u, prs_struct *ps, int depth); BOOL spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, prs_struct *ps, int depth); +BOOL spoolss_io_r_enumprintprocdatatypes(char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth); +BOOL spoolss_io_q_enumprintprocdatatypes(char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth); BOOL spoolss_io_q_enumprintmonitors(char *desc, SPOOL_Q_ENUMPRINTMONITORS *q_u, prs_struct *ps, int depth); BOOL spoolss_io_r_enumprintmonitors(char *desc, SPOOL_R_ENUMPRINTMONITORS *r_u, prs_struct *ps, int depth); BOOL spoolss_io_r_enumprinterdata(char *desc, SPOOL_R_ENUMPRINTERDATA *r_u, prs_struct *ps, int depth); @@ -2786,6 +2687,9 @@ uint32 _spoolss_setform( const POLICY_HND *handle, uint32 _spoolss_enumprintprocessors(UNISTR2 *name, UNISTR2 *environment, uint32 level, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned); +uint32 _spoolss_enumprintprocdatatypes(UNISTR2 *name, UNISTR2 *processor, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned); uint32 _spoolss_enumprintmonitors(UNISTR2 *name,uint32 level, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned); @@ -2812,6 +2716,109 @@ uint32 lookup_user_rid(char *user_name, uint32 *rid); BOOL api_wkssvc_rpc(pipes_struct *p, prs_struct *data); +/*The following definitions come from rpcclient/cmd_lsarpc.c */ + +void cmd_lsa_query_info(struct client_info *info); +void cmd_lsa_lookup_sids(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_netlogon.c */ + +void cmd_netlogon_login_test(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_reg.c */ + +void cmd_reg_enum(struct client_info *info); +void cmd_reg_query_key(struct client_info *info); +void cmd_reg_create_val(struct client_info *info); +void cmd_reg_delete_val(struct client_info *info); +void cmd_reg_delete_key(struct client_info *info); +void cmd_reg_create_key(struct client_info *info); +void cmd_reg_test_key_sec(struct client_info *info); +void cmd_reg_get_key_sec(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_samr.c */ + +void cmd_sam_ntchange_pwd(struct client_info *info); +void cmd_sam_test(struct client_info *info); +void cmd_sam_enum_users(struct client_info *info); +void cmd_sam_query_user(struct client_info *info); +void cmd_sam_query_groups(struct client_info *info); +void cmd_sam_enum_aliases(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_srvsvc.c */ + +void cmd_srv_query_info(struct client_info *info); +void cmd_srv_enum_conn(struct client_info *info); +void cmd_srv_enum_shares(struct client_info *info); +void cmd_srv_enum_sess(struct client_info *info); +void cmd_srv_enum_files(struct client_info *info); + +/*The following definitions come from rpcclient/cmd_wkssvc.c */ + +void cmd_wks_query_info(struct client_info *info); + +/*The following definitions come from rpcclient/display.c */ + +char *get_file_mode_str(uint32 share_mode); +char *get_file_oplock_str(uint32 op_type); +char *get_share_type_str(uint32 type); +char *get_server_type_str(uint32 type); +void display_srv_info_101(FILE *out_hnd, enum action_type action, + SRV_INFO_101 *sv101); +void display_srv_info_102(FILE *out_hnd, enum action_type action,SRV_INFO_102 *sv102); +void display_srv_info_ctr(FILE *out_hnd, enum action_type action,SRV_INFO_CTR *ctr); +void display_conn_info_0(FILE *out_hnd, enum action_type action, + CONN_INFO_0 *info0); +void display_conn_info_1(FILE *out_hnd, enum action_type action, + CONN_INFO_1 *info1, CONN_INFO_1_STR *str1); +void display_srv_conn_info_0_ctr(FILE *out_hnd, enum action_type action, + SRV_CONN_INFO_0 *ctr); +void display_srv_conn_info_1_ctr(FILE *out_hnd, enum action_type action, + SRV_CONN_INFO_1 *ctr); +void display_srv_conn_info_ctr(FILE *out_hnd, enum action_type action, + SRV_CONN_INFO_CTR *ctr); +void display_share_info_1(FILE *out_hnd, enum action_type action, + SRV_SHARE_INFO_1 *info1); +void display_share_info_2(FILE *out_hnd, enum action_type action, + SRV_SHARE_INFO_2 *info2); +void display_srv_share_info_ctr(FILE *out_hnd, enum action_type action, + SRV_SHARE_INFO_CTR *ctr); +void display_file_info_3(FILE *out_hnd, enum action_type action, + FILE_INFO_3 *info3, FILE_INFO_3_STR *str3); +void display_srv_file_info_3_ctr(FILE *out_hnd, enum action_type action, + SRV_FILE_INFO_3 *ctr); +void display_srv_file_info_ctr(FILE *out_hnd, enum action_type action, + SRV_FILE_INFO_CTR *ctr); +void display_server(FILE *out_hnd, enum action_type action, + char *sname, uint32 type, char *comment); +void display_share(FILE *out_hnd, enum action_type action, + char *sname, uint32 type, char *comment); +void display_share2(FILE *out_hnd, enum action_type action, + char *sname, uint32 type, char *comment, + uint32 perms, uint32 max_uses, uint32 num_uses, + char *path, char *passwd); +void display_name(FILE *out_hnd, enum action_type action, + char *sname); +void display_group_rid_info(FILE *out_hnd, enum action_type action, + uint32 num_gids, DOM_GID *gid); +void display_alias_name_info(FILE *out_hnd, enum action_type action, + uint32 num_aliases, fstring *alias_name, uint32 *num_als_usrs); +void display_sam_user_info_21(FILE *out_hnd, enum action_type action, SAM_USER_INFO_21 *usr); +char *get_sec_mask_str(uint32 type); +void display_sec_access(FILE *out_hnd, enum action_type action, SEC_ACCESS *info); +void display_sec_ace(FILE *out_hnd, enum action_type action, SEC_ACE *ace); +void display_sec_acl(FILE *out_hnd, enum action_type action, SEC_ACL *sec_acl); +void display_sec_desc(FILE *out_hnd, enum action_type action, SEC_DESC *sec); +char *get_reg_val_type_str(uint32 type); +void display_reg_value_info(FILE *out_hnd, enum action_type action, + char *val_name, uint32 val_type, BUFFER2 *value); +void display_reg_key_info(FILE *out_hnd, enum action_type action, + char *key_name, time_t key_mod_time); + +/*The following definitions come from rpcclient/rpcclient.c */ + +void rpcclient_init(void); + /*The following definitions come from smbd/blocking.c */ BOOL push_blocking_lock_request( char *inbuf, int length, int lock_timeout, int lock_num); @@ -3197,19 +3204,6 @@ BOOL unbecome_authenticated_pipe_user(pipes_struct *p); void become_root(BOOL save_dir) ; void unbecome_root(BOOL restore_dir); -/*The following definitions come from smbd/vfs.c */ - -int vfs_init_default(connection_struct *conn); -BOOL vfs_init_custom(connection_struct *conn); -BOOL vfs_directory_exist(connection_struct *conn, char *dname, - SMB_STRUCT_STAT *st); -BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf); -ssize_t vfs_write_data(files_struct *fsp,char *buffer,size_t N); -SMB_OFF_T vfs_transfer_file(int in_fd, files_struct *in_fsp, - int out_fd, files_struct *out_fsp, - SMB_OFF_T n, char *header, int headlen, int align); -char *vfs_readdirname(connection_struct *conn, void *p); - /*The following definitions come from smbd/vfs-wrap.c */ int vfswrap_dummy_connect(struct vfs_connection_struct *conn, char *service, @@ -3237,6 +3231,19 @@ int vfswrap_unlink(char *path); int vfswrap_chmod(char *path, mode_t mode); int vfswrap_utime(char *path, struct utimbuf *times); +/*The following definitions come from smbd/vfs.c */ + +int vfs_init_default(connection_struct *conn); +BOOL vfs_init_custom(connection_struct *conn); +BOOL vfs_directory_exist(connection_struct *conn, char *dname, + SMB_STRUCT_STAT *st); +BOOL vfs_file_exist(connection_struct *conn,char *fname,SMB_STRUCT_STAT *sbuf); +ssize_t vfs_write_data(files_struct *fsp,char *buffer,size_t N); +SMB_OFF_T vfs_transfer_file(int in_fd, files_struct *in_fsp, + int out_fd, files_struct *out_fsp, + SMB_OFF_T n, char *header, int headlen, int align); +char *vfs_readdirname(connection_struct *conn, void *p); + /*The following definitions come from smbwrapper/realcalls.c */ int real_utime(const char *name, struct utimbuf *buf); diff --git a/source/include/rpc_spoolss.h b/source/include/rpc_spoolss.h index 84812ed98a6..b5aa50ecba6 100755 --- a/source/include/rpc_spoolss.h +++ b/source/include/rpc_spoolss.h @@ -94,7 +94,7 @@ #define SPOOLSS_ENUMFORMS 0x22 #define SPOOLSS_ENUMPORTS 0x23 #define SPOOLSS_ENUMMONITORS 0x24 -#define SPOOLSS_ENUMPRINTPROCESSORDATATYPES 0x33 +#define SPOOLSS_ENUMPRINTPROCDATATYPES 0x33 #define SPOOLSS_GETPRINTERDRIVER2 0x35 /* find close printer notification */ #define SPOOLSS_FCPN 0x38 @@ -1328,28 +1328,29 @@ typedef struct spool_r_enumprintprocessors uint32 status; } SPOOL_R_ENUMPRINTPROCESSORS; -typedef struct spool_q_enumprintprocessordatatypes +typedef struct spool_q_enumprintprocdatatypes { + uint32 name_ptr; UNISTR2 name; - UNISTR2 printprocessor; + uint32 processor_ptr; + UNISTR2 processor; uint32 level; NEW_BUFFER *buffer; - uint32 buf_size; -} SPOOL_Q_ENUMPRINTPROCESSORDATATYPES; + uint32 offered; +} SPOOL_Q_ENUMPRINTPROCDATATYPES; typedef struct ppdatatype_1 { UNISTR name; -} PPDATATYPE_1; +} PRINTPROCDATATYPE_1; -typedef struct spool_r_enumprintprocessordatatypes +typedef struct spool_r_enumprintprocdatatypes { - uint32 level; - PPDATATYPE_1 *info_1; - uint32 offered; - uint32 numofppdatatypes; + NEW_BUFFER *buffer; + uint32 needed; + uint32 returned; uint32 status; -} SPOOL_R_ENUMPRINTPROCESSORDATATYPES; +} SPOOL_R_ENUMPRINTPROCDATATYPES; typedef struct printmonitor_1 { diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c index d1f7ed61a40..452cbb1531d 100644 --- a/source/rpc_parse/parse_spoolss.c +++ b/source/rpc_parse/parse_spoolss.c @@ -2124,6 +2124,23 @@ BOOL smb_io_printprocessor_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCESSOR return True; } +/******************************************************************* +********************************************************************/ +BOOL smb_io_printprocdatatype_info_1(char *desc, NEW_BUFFER *buffer, PRINTPROCDATATYPE_1 *info, int depth) +{ + prs_struct *ps=&(buffer->prs); + + prs_debug(ps, depth, desc, "smb_io_printprocdatatype_info_1"); + depth++; + + buffer->struct_start=prs_offset(ps); + + if (new_smb_io_relstr("name", buffer, depth, &info->name)) + return False; + + return True; +} + /******************************************************************* ********************************************************************/ BOOL smb_io_printmonitor_info_1(char *desc, NEW_BUFFER *buffer, PRINTMONITOR_1 *info, int depth) @@ -2417,6 +2434,17 @@ uint32 spoolss_size_printprocessor_info_1(PRINTPROCESSOR_1 *info) return size; } +/******************************************************************* +return the size required by a struct in the stream +********************************************************************/ +uint32 spoolss_size_printprocdatatype_info_1(PRINTPROCDATATYPE_1 *info) +{ + int size=0; + size+=size_of_relative_string( &info->name ); + + return size; +} + /******************************************************************* return the size required by a struct in the stream ********************************************************************/ @@ -3715,6 +3743,76 @@ BOOL spoolss_io_q_enumprintprocessors(char *desc, SPOOL_Q_ENUMPRINTPROCESSORS *q return True; } +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_r_enumprintprocdatatypes(char *desc, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_enumprintprocdatatypes"); + depth++; + + if (!prs_align(ps)) + return False; + + if (!new_spoolss_io_buffer("", ps, depth, r_u->buffer)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("needed", ps, depth, &r_u->needed)) + return False; + + if (!prs_uint32("returned", ps, depth, &r_u->returned)) + return False; + + if (!prs_uint32("status", ps, depth, &r_u->status)) + return False; + + return True; +} + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_q_enumprintprocdatatypes(char *desc, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, prs_struct *ps, int depth) +{ + uint32 useless; + prs_debug(ps, depth, desc, "spoolss_io_q_enumprintprocdatatypes"); + depth++; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("name_ptr", ps, depth, &q_u->name_ptr)) + return False; + if (!smb_io_unistr2("name", &q_u->name, True, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("processor_ptr", ps, depth, &q_u->processor_ptr)) + return False; + if (!smb_io_unistr2("processor", &q_u->processor, q_u->processor_ptr, ps, depth)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("level", ps, depth, &q_u->level)) + return False; + + if(!new_spoolss_io_buffer("buffer", ps, depth, q_u->buffer)) + return False; + + if (!prs_align(ps)) + return False; + + if (!prs_uint32("offered", ps, depth, &q_u->offered)) + return False; + + return True; +} + /******************************************************************* Parse a SPOOL_Q_ENUMPRINTMONITORS structure. ********************************************************************/ diff --git a/source/rpc_server/srv_spoolss.c b/source/rpc_server/srv_spoolss.c index d20f6c1616f..75493b7a303 100755 --- a/source/rpc_server/srv_spoolss.c +++ b/source/rpc_server/srv_spoolss.c @@ -966,6 +966,41 @@ static BOOL api_spoolss_enumprintprocessors(uint16 vuid, prs_struct *data, prs_s return True; } +/**************************************************************************** +****************************************************************************/ +static BOOL api_spoolss_enumprintprocdatatypes(uint16 vuid, prs_struct *data, prs_struct *rdata) +{ + SPOOL_Q_ENUMPRINTPROCDATATYPES q_u; + SPOOL_R_ENUMPRINTPROCDATATYPES r_u; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + new_spoolss_allocate_buffer(&q_u.buffer); + + if(!spoolss_io_q_enumprintprocdatatypes("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_enumprintprocdatatypes: unable to unmarshall SPOOL_Q_ENUMPRINTPROCDATATYPES.\n")); + return False; + } + + /* that's an [in out] buffer */ + new_spoolss_move_buffer(q_u.buffer, &r_u.buffer); + + r_u.status = _spoolss_enumprintprocdatatypes(&q_u.name, &q_u.processor, q_u.level, + r_u.buffer, q_u.offered, + &r_u.needed, &r_u.returned); + + if(!spoolss_io_r_enumprintprocdatatypes("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_enumprintprocdatatypes: unable to marshall SPOOL_R_ENUMPRINTPROCDATATYPES.\n")); + new_spoolss_free_buffer(q_u.buffer); + return False; + } + + new_spoolss_free_buffer(q_u.buffer); + + return True; +} + /**************************************************************************** ****************************************************************************/ static BOOL api_spoolss_enumprintmonitors(uint16 vuid, prs_struct *data, prs_struct *rdata) @@ -1069,6 +1104,7 @@ struct api_struct api_spoolss_cmds[] = {"SPOOLSS_ENUMPRINTPROCESSORS", SPOOLSS_ENUMPRINTPROCESSORS, api_spoolss_enumprintprocessors }, {"SPOOLSS_ENUMMONITORS", SPOOLSS_ENUMMONITORS, api_spoolss_enumprintmonitors }, {"SPOOLSS_GETJOB", SPOOLSS_GETJOB, api_spoolss_getjob }, + {"SPOOLSS_ENUMPRINTPROCDATATYPES", SPOOLSS_ENUMPRINTPROCDATATYPES, api_spoolss_enumprintprocdatatypes }, { NULL, 0, NULL } }; diff --git a/source/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c index 3ab426e9c2c..90a0ef6d608 100644 --- a/source/rpc_server/srv_spoolss_nt.c +++ b/source/rpc_server/srv_spoolss_nt.c @@ -3849,7 +3849,56 @@ uint32 _spoolss_enumprintprocessors(UNISTR2 *name, UNISTR2 *environment, uint32 return NT_STATUS_INVALID_INFO_CLASS; break; } +} + +/**************************************************************************** + enumprintprocdatatypes level 1. +****************************************************************************/ +static uint32 enumprintprocdatatypes_level_1(NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) +{ + PRINTPROCDATATYPE_1 *info_1=NULL; + + info_1 = (PRINTPROCDATATYPE_1 *)malloc(sizeof(PRINTPROCDATATYPE_1)); + (*returned) = 0x1; + + init_unistr(&(info_1->name), "RAW"); + + *needed += spoolss_size_printprocdatatype_info_1(info_1); + + if (!alloc_buffer_size(buffer, *needed)) + return ERROR_INSUFFICIENT_BUFFER; + + smb_io_printprocdatatype_info_1("", buffer, info_1, 0); + + safe_free(info_1); + + if (*needed > offered) { + *returned=0; + return ERROR_INSUFFICIENT_BUFFER; + } + else + return NT_STATUS_NO_PROBLEMO; +} +/**************************************************************************** +****************************************************************************/ +uint32 _spoolss_enumprintprocdatatypes(UNISTR2 *name, UNISTR2 *processor, uint32 level, + NEW_BUFFER *buffer, uint32 offered, + uint32 *needed, uint32 *returned) +{ + DEBUG(5,("_spoolss_enumprintprocdatatypes\n")); + + *returned=0; + *needed=0; + + switch (level) { + case 1: + return enumprintprocdatatypes_level_1(buffer, offered, needed, returned); + break; + default: + return NT_STATUS_INVALID_INFO_CLASS; + break; + } } /**************************************************************************** -- cgit From 2892f6e534d5084b50287bf3859be74d52978cb7 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 28 Feb 2000 00:22:45 +0000 Subject: Added tdbtool to .cvsignore list. --- source/tdb/.cvsignore | 1 + 1 file changed, 1 insertion(+) diff --git a/source/tdb/.cvsignore b/source/tdb/.cvsignore index f8f1c6f015b..afd8da72c94 100644 --- a/source/tdb/.cvsignore +++ b/source/tdb/.cvsignore @@ -1,3 +1,4 @@ +tdbtool tdbtest tdbtorture test.db -- cgit From b345c0a1058bcde7689bb9566535e9f1c46ee173 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 28 Feb 2000 00:25:37 +0000 Subject: Allow tdb databases to be created "in memory" without having a file associated with them. tdb can then be used as a hash table data structure. --- source/tdb/tdb.c | 154 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 99 insertions(+), 55 deletions(-) diff --git a/source/tdb/tdb.c b/source/tdb/tdb.c index 15a4a37945c..c7b70aa1533 100644 --- a/source/tdb/tdb.c +++ b/source/tdb/tdb.c @@ -92,6 +92,8 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset, #else struct flock fl; + if (tdb->fd == -1) return 0; /* for in memory tdb */ + if (tdb->read_only) return -1; fl.l_type = set==LOCK_SET?rw_type:F_UNLCK; @@ -194,7 +196,7 @@ static tdb_off tdb_hash_top(TDB_CONTEXT *tdb, unsigned hash) static int tdb_oob(TDB_CONTEXT *tdb, tdb_off offset) { struct stat st; - if (offset <= tdb->map_size) return 0; + if ((offset <= tdb->map_size) || (tdb->fd == -1)) return 0; fstat(tdb->fd, &st); if (st.st_size <= (ssize_t)offset) { @@ -337,8 +339,10 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off length) length = ((tdb->map_size + length + TDB_PAGE_SIZE) & ~(TDB_PAGE_SIZE - 1)) - tdb->map_size; /* expand the file itself */ - lseek(tdb->fd, tdb->map_size + length - 1, SEEK_SET); - if (write(tdb->fd, &b, 1) != 1) goto fail; + if (tdb->fd != -1) { + lseek(tdb->fd, tdb->map_size + length - 1, SEEK_SET); + if (write(tdb->fd, &b, 1) != 1) goto fail; + } /* form a new freelist record */ offset = FREELIST_TOP; @@ -349,7 +353,7 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off length) } #if HAVE_MMAP - if (tdb->map_ptr) { + if (tdb->fd != -1 && tdb->map_ptr) { munmap(tdb->map_ptr, tdb->map_size); tdb->map_ptr = NULL; } @@ -357,6 +361,10 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off length) tdb->map_size += length; + if (tdb->fd == -1) { + tdb->map_ptr = realloc(tdb->map_ptr, tdb->map_size); + } + /* write it out */ if (rec_write(tdb, tdb->map_size - length, &rec) == -1) { goto fail; @@ -367,10 +375,13 @@ static int tdb_expand(TDB_CONTEXT *tdb, tdb_off length) if (ofs_write(tdb, offset, &ptr) == -1) goto fail; #if HAVE_MMAP - tdb->map_ptr = (void *)mmap(NULL, tdb->map_size, - PROT_READ|PROT_WRITE, - MAP_SHARED | MAP_FILE, tdb->fd, 0); + if (tdb->fd != -1) { + tdb->map_ptr = (void *)mmap(NULL, tdb->map_size, + PROT_READ|PROT_WRITE, + MAP_SHARED | MAP_FILE, tdb->fd, 0); + } #endif + tdb_unlock(tdb, -1); return 0; @@ -478,37 +489,52 @@ static int tdb_new_database(TDB_CONTEXT *tdb, int hash_size) { struct tdb_header header; tdb_off offset; - int i; + int i, size = 0; tdb_off buf[16]; - /* create the header */ - memset(&header, 0, sizeof(header)); - memcpy(header.magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1); - header.version = TDB_VERSION; - header.hash_size = hash_size; - lseek(tdb->fd, 0, SEEK_SET); - ftruncate(tdb->fd, 0); - - if (write(tdb->fd, &header, sizeof(header)) != sizeof(header)) { - tdb->ecode = TDB_ERR_IO; - return -1; - } + /* create the header */ + memset(&header, 0, sizeof(header)); + memcpy(header.magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1); + header.version = TDB_VERSION; + header.hash_size = hash_size; + lseek(tdb->fd, 0, SEEK_SET); + ftruncate(tdb->fd, 0); + + if (tdb->fd != -1 && write(tdb->fd, &header, sizeof(header)) != + sizeof(header)) { + tdb->ecode = TDB_ERR_IO; + return -1; + } else size += sizeof(header); - /* the freelist and hash pointers */ - offset = 0; - memset(buf, 0, sizeof(buf)); - for (i=0;(hash_size+1)-i >= 16; i += 16) { - if (write(tdb->fd, buf, sizeof(buf)) != sizeof(buf)) { - tdb->ecode = TDB_ERR_IO; - return -1; - } - } - for (;ifd, buf, sizeof(tdb_off)) != sizeof(tdb_off)) { - tdb->ecode = TDB_ERR_IO; - return -1; - } - } + /* the freelist and hash pointers */ + offset = 0; + memset(buf, 0, sizeof(buf)); + + for (i=0;(hash_size+1)-i >= 16; i += 16) { + if (tdb->fd != -1 && write(tdb->fd, buf, sizeof(buf)) != + sizeof(buf)) { + tdb->ecode = TDB_ERR_IO; + return -1; + } else size += sizeof(buf); + } + + for (;ifd != -1 && write(tdb->fd, buf, sizeof(tdb_off)) != + sizeof(tdb_off)) { + tdb->ecode = TDB_ERR_IO; + return -1; + } else size += sizeof(tdb_off); + } + + if (tdb->fd == -1) { + tdb->map_ptr = calloc(size, 1); + tdb->map_size = size; + if (tdb->map_ptr == NULL) { + tdb->ecode = TDB_ERR_IO; + return -1; + } + memcpy(&tdb->header, &header, sizeof(header)); + } #if TDB_DEBUG printf("initialised database of hash_size %u\n", @@ -1082,6 +1108,8 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, TDB_CONTEXT tdb, *ret; struct stat st; + memset(&tdb, 0, sizeof(tdb)); + tdb.fd = -1; tdb.name = NULL; tdb.map_ptr = NULL; @@ -1092,14 +1120,14 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, if (hash_size == 0) hash_size = DEFAULT_HASH_SIZE; - memset(&tdb, 0, sizeof(tdb)); - tdb.read_only = ((open_flags & O_ACCMODE) == O_RDONLY); - tdb.fd = open(name, open_flags, mode); - if (tdb.fd == -1) { + if (name != NULL) { + tdb.fd = open(name, open_flags, mode); + if (tdb.fd == -1) { goto fail; - } + } + } /* ensure there is only one process initialising at once */ tdb_brlock(&tdb, GLOBAL_LOCK, LOCK_SET, F_WRLCK, F_SETLKW); @@ -1126,23 +1154,32 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, if (tdb_new_database(&tdb, hash_size) == -1) goto fail; lseek(tdb.fd, 0, SEEK_SET); - if (read(tdb.fd, &tdb.header, sizeof(tdb.header)) != sizeof(tdb.header)) goto fail; + if (tdb.fd != -1 && read(tdb.fd, &tdb.header, + sizeof(tdb.header)) != + sizeof(tdb.header)) + goto fail; } - fstat(tdb.fd, &st); + if (tdb.fd != -1) { + fstat(tdb.fd, &st); + + /* map the database and fill in the return structure */ + tdb.name = (char *)strdup(name); + tdb.map_size = st.st_size; + } + + tdb.locked = (int *)calloc(tdb.header.hash_size+1, + sizeof(tdb.locked[0])); + if (!tdb.locked) { + goto fail; + } - /* map the database and fill in the return structure */ - tdb.name = (char *)strdup(name); - tdb.locked = (int *)calloc(tdb.header.hash_size+1, - sizeof(tdb.locked[0])); - if (!tdb.locked) { - goto fail; - } - tdb.map_size = st.st_size; #if HAVE_MMAP - tdb.map_ptr = (void *)mmap(NULL, st.st_size, - tdb.read_only? PROT_READ : PROT_READ|PROT_WRITE, - MAP_SHARED | MAP_FILE, tdb.fd, 0); + if (tdb.fd != -1) { + tdb.map_ptr = (void *)mmap(NULL, st.st_size, + tdb.read_only? PROT_READ : PROT_READ|PROT_WRITE, + MAP_SHARED | MAP_FILE, tdb.fd, 0); + } #endif ret = (TDB_CONTEXT *)malloc(sizeof(tdb)); @@ -1159,7 +1196,7 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, return ret; fail: - if (tdb.name) free(tdb.name); + if (tdb.name) free(tdb.name); if (tdb.fd != -1) close(tdb.fd); if (tdb.map_ptr) munmap(tdb.map_ptr, tdb.map_size); @@ -1173,9 +1210,16 @@ int tdb_close(TDB_CONTEXT *tdb) if (tdb->name) free(tdb->name); if (tdb->fd != -1) close(tdb->fd); - if (tdb->map_ptr) munmap(tdb->map_ptr, tdb->map_size); if (tdb->locked) free(tdb->locked); + if (tdb->map_ptr) { + if (tdb->fd != -1) { + munmap(tdb->map_ptr, tdb->map_size); + } else { + free(tdb->map_ptr); + } + } + memset(tdb, 0, sizeof(*tdb)); free(tdb); -- cgit From d64456b5889f0ee3a8c2108c13789540bfc3d90c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 28 Feb 2000 00:37:13 +0000 Subject: Modifications to tdb_traverse() arguments to remove compile warnings. --- source/tdb/tdbtool.c | 8 +++++++- source/tdb/tdbtorture.c | 5 +++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/source/tdb/tdbtool.c b/source/tdb/tdbtool.c index 76b6259ef8f..317ad9b4fc5 100644 --- a/source/tdb/tdbtool.c +++ b/source/tdb/tdbtool.c @@ -170,6 +170,12 @@ static char *getline(char *prompt) return p?line:NULL; } +static int do_delete_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, + void *state) +{ + return tdb_delete(tdb, key); +} + int main(int argc, char *argv[]) { char *line; @@ -199,7 +205,7 @@ int main(int argc, char *argv[]) } else if (strcmp(tok,"show") == 0) { show_tdb(); } else if (strcmp(tok,"erase") == 0) { - tdb_traverse(tdb, tdb_delete, NULL); + tdb_traverse(tdb, do_delete_fn, NULL); } else if (strcmp(tok,"delete") == 0) { delete_tdb(); } else if (strcmp(tok,"dump") == 0) { diff --git a/source/tdb/tdbtorture.c b/source/tdb/tdbtorture.c index d72d7b35255..159b47f3695 100644 --- a/source/tdb/tdbtorture.c +++ b/source/tdb/tdbtorture.c @@ -74,7 +74,8 @@ static void addrec_db(void) free(d); } -static int traverse_fn(TDB_CONTEXT *db, TDB_DATA key, TDB_DATA dbuf) +static int traverse_fn(TDB_CONTEXT *db, TDB_DATA key, TDB_DATA dbuf, + void *state) { tdb_delete(db, key); return 0; @@ -97,7 +98,7 @@ int main(int argc, char *argv[]) if (fork() == 0) break; } - db = tdb_open("test.tdb", 0, TDB_CLEAR_IF_FIRST, + db = tdb_open(NULL, 0, TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT, 0600); if (!db) { fatal("db open failed"); -- cgit From 110ec9923bd2ad729d63f129514f3f1de76de9c1 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 28 Feb 2000 00:38:45 +0000 Subject: Oops - put back filename argument to tdb_open(). --- source/tdb/tdbtorture.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/tdb/tdbtorture.c b/source/tdb/tdbtorture.c index 159b47f3695..90dcc38aba1 100644 --- a/source/tdb/tdbtorture.c +++ b/source/tdb/tdbtorture.c @@ -98,7 +98,7 @@ int main(int argc, char *argv[]) if (fork() == 0) break; } - db = tdb_open(NULL, 0, TDB_CLEAR_IF_FIRST, + db = tdb_open("test.tdb", 0, TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT, 0600); if (!db) { fatal("db open failed"); -- cgit From 60ae73c257e84aa128954f0cf5cf59e7996c68d9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 28 Feb 2000 00:51:53 +0000 Subject: Makefile for tdb directory. --- source/tdb/Makefile | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 source/tdb/Makefile diff --git a/source/tdb/Makefile b/source/tdb/Makefile new file mode 100644 index 00000000000..dbc59047c74 --- /dev/null +++ b/source/tdb/Makefile @@ -0,0 +1,21 @@ +# +# Makefile for tdb directory +# + +CFLAGS = -DSTANDALONE -DTDB_DEBUG -g -DMMAP +CC = gcc +PROGS = tdbtest tdbtool tdbtorture + +default: $(PROGS) + +tdbtest: tdbtest.o tdb.o + gcc -o tdbtest tdbtest.o tdb.o -lgdbm + +tdbtool: tdbtool.o tdb.o + gcc -o tdbtool tdbtool.o tdb.o + +tdbtorture: tdbtorture.o tdb.o + gcc -o tdbtorture tdbtorture.o tdb.o + +clean: + rm -f $(PROGS) *.o *~ *% core test.db test.tdb test.gdbm -- cgit