diff options
-rw-r--r-- | source3/rpc_parse/parse_spoolss.c | 103 |
1 files changed, 74 insertions, 29 deletions
diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index f297e88bba..825ff23838 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -546,8 +546,29 @@ 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", &devmode->icmmethod }, + { "icmintent", &devmode->icmintent }, + { "mediatype", &devmode->mediatype }, + { "dithertype", &devmode->dithertype }, + { "reserved1", &devmode->reserved1 }, + { "reserved2", &devmode->reserved2 }, + { "panningwidth", &devmode->panningwidth }, + { "panningheight", &devmode->panningheight } + }; + + prs_debug(ps, depth, desc, "spoolss_io_devmode"); depth++; @@ -559,8 +580,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; + + /* 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)) @@ -616,45 +656,50 @@ 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 % 4) != 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; + while (available_space && (i<DM_NUM_OPTIONAL_FIELDS)) + { + 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 */ - /* 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)) + 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 (!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; } + +parse_driverextra: if (devmode->driverextra!=0) { if (UNMARSHALLING(ps)) { devmode->private=(uint8 *)prs_alloc_mem(ps, devmode->driverextra*sizeof(uint8)); |