summaryrefslogtreecommitdiffstats
path: root/source/rpc_parse/parse_spoolss.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/rpc_parse/parse_spoolss.c')
-rw-r--r--source/rpc_parse/parse_spoolss.c225
1 files changed, 158 insertions, 67 deletions
diff --git a/source/rpc_parse/parse_spoolss.c b/source/rpc_parse/parse_spoolss.c
index a47b9f5b60c..dcf28c2d675 100644
--- a/source/rpc_parse/parse_spoolss.c
+++ b/source/rpc_parse/parse_spoolss.c
@@ -544,8 +544,40 @@ static BOOL spool_io_user_level(char *desc, SPOOL_USER_CTR *q_u, prs_struct *ps,
* on reading allocate memory for the private member
********************************************************************/
+#define DM_NUM_OPTIONAL_FIELDS 8
+
BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmode)
{
+ uint32 available_space; /* size of the device mode left to parse */
+ /* only important on unmarshalling */
+ int i = 0;
+
+ struct optional_fields {
+ fstring name;
+ uint32* field;
+ } opt_fields[DM_NUM_OPTIONAL_FIELDS] = {
+ { "icmmethod", NULL },
+ { "icmintent", NULL },
+ { "mediatype", NULL },
+ { "dithertype", NULL },
+ { "reserved1", NULL },
+ { "reserved2", NULL },
+ { "panningwidth", NULL },
+ { "panningheight", NULL }
+ };
+
+ /* assign at run time to keep non-gcc vompilers happy */
+
+ opt_fields[0].field = &devmode->icmmethod;
+ opt_fields[1].field = &devmode->icmintent;
+ opt_fields[2].field = &devmode->mediatype;
+ opt_fields[3].field = &devmode->dithertype;
+ opt_fields[4].field = &devmode->reserved1;
+ opt_fields[5].field = &devmode->reserved2;
+ opt_fields[6].field = &devmode->panningwidth;
+ opt_fields[7].field = &devmode->panningheight;
+
+
prs_debug(ps, depth, desc, "spoolss_io_devmode");
depth++;
@@ -557,8 +589,27 @@ BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmo
if (!prs_uint16uni(True,"devicename", ps, depth, devmode->devicename.buffer, 32))
return False;
+
if (!prs_uint16("specversion", ps, depth, &devmode->specversion))
- return False;
+ return False;
+
+ /* Sanity Check - look for unknown specversions, but don't fail if we see one.
+ Let the size determine that */
+
+ switch (devmode->specversion) {
+ case 0x0320:
+ case 0x0400:
+ case 0x0401:
+ break;
+
+ default:
+ DEBUG(0,("spoolss_io_devmode: Unknown specversion in devicemode [0x%x]\n",
+ devmode->specversion));
+ DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
+ break;
+ }
+
+
if (!prs_uint16("driverversion", ps, depth, &devmode->driverversion))
return False;
if (!prs_uint16("size", ps, depth, &devmode->size))
@@ -614,44 +665,49 @@ BOOL spoolss_io_devmode(char *desc, prs_struct *ps, int depth, DEVICEMODE *devmo
return False;
if (!prs_uint32("displayfrequency", ps, depth, &devmode->displayfrequency))
return False;
-
+ /*
+ * every device mode I've ever seen on the wire at least has up
+ * to the displayfrequency field. --jerry (05-09-2002)
+ */
+
+ /* add uint32's + uint16's + two UNICODE strings */
+
+ available_space = devmode->size - (sizeof(uint32)*6 + sizeof(uint16)*18 + sizeof(uint16)*64);
+
+ /* Sanity check - we only have uint32's left tp parse */
+
+ if ( available_space && ((available_space % sizeof(uint32)) != 0) ) {
+ DEBUG(0,("spoolss_io_devmode: available_space [%d] no in multiple of 4 bytes (size = %d)!\n",
+ available_space, devmode->size));
+ DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
+ return False;
+ }
+
/*
* Conditional parsing. Assume that the DeviceMode has been
* zero'd by the caller.
*/
- switch(devmode->specversion) {
-
- /* Used by spooler when issuing OpenPrinter() calls. NT 3.5x? */
- case 0x0320:
- break;
-
- /* See the comments on the DEVMODE in the msdn GDI documentation */
- case 0x0400:
- case 0x0401:
- 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;
- break;
- /* log an error if we see something else */
- default:
- DEBUG(0,("spoolss_io_devmode: Unknown specversion [0x%x]!\n", devmode->specversion));
- DEBUG(0,("spoolss_io_devmode: Please report to samba-technical@samba.org\n"));
- break;
+ while ((available_space > 0) && (i < DM_NUM_OPTIONAL_FIELDS))
+ {
+ DEBUG(10, ("spoolss_io_devmode: [%d] bytes left to parse in devmode\n", available_space));
+ if (!prs_uint32(opt_fields[i].name, ps, depth, opt_fields[i].field))
+ return False;
+ available_space -= sizeof(uint32);
+ i++;
+ }
+
+ /* Sanity Check - we should no available space at this point unless
+ MS changes the device mode structure */
+
+ if (available_space) {
+ DEBUG(0,("spoolss_io_devmode: I've parsed all I know and there is still stuff left|\n"));
+ DEBUG(0,("spoolss_io_devmode: available_space = [%d], devmode_size = [%d]!\n",
+ available_space, devmode->size));
+ DEBUG(0,("spoolss_io_devmode: please report to samba-technical@samba.org!\n"));
+ return False;
}
+
if (devmode->driverextra!=0) {
if (UNMARSHALLING(ps)) {
@@ -2225,7 +2281,9 @@ BOOL smb_io_printer_info_1(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_1 *info,
BOOL smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info, int depth)
{
prs_struct *ps=&buffer->prs;
-
+ uint32 dm_offset, sd_offset, current_offset;
+ uint32 dummy_value = 0;
+
prs_debug(ps, depth, desc, "smb_io_printer_info_2");
depth++;
@@ -2246,10 +2304,11 @@ BOOL smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info,
if (!smb_io_relstr("location", buffer, depth, &info->location))
return False;
- /* NT parses the DEVMODE at the end of the struct */
- if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
+ /* save current offset and wind forwared by a uint32 */
+ dm_offset = prs_offset(ps);
+ if (!prs_uint32("devmode", ps, depth, &dummy_value))
return False;
-
+
if (!smb_io_relstr("sepfile", buffer, depth, &info->sepfile))
return False;
if (!smb_io_relstr("printprocessor", buffer, depth, &info->printprocessor))
@@ -2259,8 +2318,30 @@ BOOL smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *info,
if (!smb_io_relstr("parameters", buffer, depth, &info->parameters))
return False;
+ /* save current offset for the sec_desc */
+ sd_offset = prs_offset(ps);
+ if (!prs_uint32("sec_desc", ps, depth, &dummy_value))
+ return False;
+
+
+ /* save current location so we can pick back up here */
+ current_offset = prs_offset(ps);
+
+ /* parse the devmode */
+ if (!prs_set_offset(ps, dm_offset))
+ return False;
+ if (!smb_io_reldevmode("devmode", buffer, depth, &info->devmode))
+ return False;
+
+ /* parse the sec_desc */
+ if (!prs_set_offset(ps, sd_offset))
+ return False;
if (!smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
return False;
+
+ /* pick up where we left off */
+ if (!prs_set_offset(ps, current_offset))
+ return False;
if (!prs_uint32("attributes", ps, depth, &info->attributes))
return False;
@@ -3034,10 +3115,10 @@ return the size required by a struct in the stream
uint32 spoolss_size_printer_info_2(PRINTER_INFO_2 *info)
{
- uint32 size=0;
+ uint32 size=0;
size += 4;
- /* JRA !!!! TESTME - WHAT ABOUT prs_align.... !!! */
+
size += sec_desc_size( info->secdesc );
size+=size_of_device_mode( info->devmode );
@@ -3063,6 +3144,16 @@ 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 );
+
+ /*
+ * add any adjustments for alignment. This is
+ * not optimal since we could be calling this
+ * function from a loop (e.g. enumprinters), but
+ * it is easier to maintain the calculation here and
+ * not place the burden on the caller to remember. --jerry
+ */
+ size += size % 4;
+
return size;
}
@@ -5171,14 +5262,14 @@ BOOL uni_2_asc_printer_driver_3(SPOOL_PRINTER_DRIVER_INFO_LEVEL_3 *uni,
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);
+ unistr2_to_dos(d->name, &uni->name, sizeof(d->name)-1);
+ unistr2_to_dos(d->environment, &uni->environment, sizeof(d->environment)-1);
+ unistr2_to_dos(d->driverpath, &uni->driverpath, sizeof(d->driverpath)-1);
+ unistr2_to_dos(d->datafile, &uni->datafile, sizeof(d->datafile)-1);
+ unistr2_to_dos(d->configfile, &uni->configfile, sizeof(d->configfile)-1);
+ unistr2_to_dos(d->helpfile, &uni->helpfile, sizeof(d->helpfile)-1);
+ unistr2_to_dos(d->monitorname, &uni->monitorname, sizeof(d->monitorname)-1);
+ unistr2_to_dos(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
DEBUGADD(8,( "version: %d\n", d->cversion));
DEBUGADD(8,( "name: %s\n", d->name));
@@ -5218,14 +5309,14 @@ BOOL uni_2_asc_printer_driver_6(SPOOL_PRINTER_DRIVER_INFO_LEVEL_6 *uni,
d->version=uni->version;
- 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);
+ unistr2_to_dos(d->name, &uni->name, sizeof(d->name)-1);
+ unistr2_to_dos(d->environment, &uni->environment, sizeof(d->environment)-1);
+ unistr2_to_dos(d->driverpath, &uni->driverpath, sizeof(d->driverpath)-1);
+ unistr2_to_dos(d->datafile, &uni->datafile, sizeof(d->datafile)-1);
+ unistr2_to_dos(d->configfile, &uni->configfile, sizeof(d->configfile)-1);
+ unistr2_to_dos(d->helpfile, &uni->helpfile, sizeof(d->helpfile)-1);
+ unistr2_to_dos(d->monitorname, &uni->monitorname, sizeof(d->monitorname)-1);
+ unistr2_to_dos(d->defaultdatatype, &uni->defaultdatatype, sizeof(d->defaultdatatype)-1);
DEBUGADD(8,( "version: %d\n", d->version));
DEBUGADD(8,( "name: %s\n", d->name));
@@ -5283,17 +5374,17 @@ BOOL uni_2_asc_printer_info_2(const SPOOL_PRINTER_INFO_LEVEL_2 *uni,
d->status=uni->status;
d->cjobs=uni->cjobs;
- unistr2_to_ascii(d->servername, &uni->servername, sizeof(d->servername)-1);
- unistr2_to_ascii(d->printername, &uni->printername, sizeof(d->printername)-1);
- unistr2_to_ascii(d->sharename, &uni->sharename, sizeof(d->sharename)-1);
- unistr2_to_ascii(d->portname, &uni->portname, sizeof(d->portname)-1);
- unistr2_to_ascii(d->drivername, &uni->drivername, sizeof(d->drivername)-1);
- unistr2_to_ascii(d->comment, &uni->comment, sizeof(d->comment)-1);
- unistr2_to_ascii(d->location, &uni->location, sizeof(d->location)-1);
- unistr2_to_ascii(d->sepfile, &uni->sepfile, sizeof(d->sepfile)-1);
- unistr2_to_ascii(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)-1);
- unistr2_to_ascii(d->datatype, &uni->datatype, sizeof(d->datatype)-1);
- unistr2_to_ascii(d->parameters, &uni->parameters, sizeof(d->parameters)-1);
+ unistr2_to_dos(d->servername, &uni->servername, sizeof(d->servername)-1);
+ unistr2_to_dos(d->printername, &uni->printername, sizeof(d->printername)-1);
+ unistr2_to_dos(d->sharename, &uni->sharename, sizeof(d->sharename)-1);
+ unistr2_to_dos(d->portname, &uni->portname, sizeof(d->portname)-1);
+ unistr2_to_dos(d->drivername, &uni->drivername, sizeof(d->drivername)-1);
+ unistr2_to_dos(d->comment, &uni->comment, sizeof(d->comment)-1);
+ unistr2_to_dos(d->location, &uni->location, sizeof(d->location)-1);
+ unistr2_to_dos(d->sepfile, &uni->sepfile, sizeof(d->sepfile)-1);
+ unistr2_to_dos(d->printprocessor, &uni->printprocessor, sizeof(d->printprocessor)-1);
+ unistr2_to_dos(d->datatype, &uni->datatype, sizeof(d->datatype)-1);
+ unistr2_to_dos(d->parameters, &uni->parameters, sizeof(d->parameters)-1);
return True;
}
@@ -5859,7 +5950,7 @@ BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value,
memset((char *)*param, '\0', sizeof(NT_PRINTER_PARAM));
DEBUGADD(6,("Allocated a new PARAM struct\n"));
}
- unistr2_to_ascii((*param)->value, value, sizeof((*param)->value)-1);
+ unistr2_to_dos((*param)->value, value, sizeof((*param)->value)-1);
(*param)->type = type;
/* le champ data n'est pas NULL termine */