diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/rpc_secdes.h | 7 | ||||
-rwxr-xr-x | source3/include/rpc_spoolss.h | 120 | ||||
-rw-r--r-- | source3/include/smb.h | 4 | ||||
-rw-r--r-- | source3/lib/util_seaccess.c | 25 | ||||
-rw-r--r-- | source3/printing/lpq_parse.c | 72 | ||||
-rw-r--r-- | source3/printing/nt_printing.c | 66 | ||||
-rw-r--r-- | source3/printing/printing.c | 12 | ||||
-rw-r--r-- | source3/rpc_client/cli_spoolss_notify.c | 331 | ||||
-rw-r--r-- | source3/rpc_parse/parse_spoolss.c | 273 | ||||
-rwxr-xr-x | source3/rpc_server/srv_spoolss.c | 34 | ||||
-rw-r--r-- | source3/rpc_server/srv_spoolss_nt.c | 432 | ||||
-rw-r--r-- | source3/smbd/lanman.c | 8 | ||||
-rw-r--r-- | source3/smbd/reply.c | 2 |
13 files changed, 1042 insertions, 344 deletions
diff --git a/source3/include/rpc_secdes.h b/source3/include/rpc_secdes.h index 8304530e08..e51a5fd2f8 100644 --- a/source3/include/rpc_secdes.h +++ b/source3/include/rpc_secdes.h @@ -204,4 +204,11 @@ typedef struct generic_mapping { uint32 generic_all; } GENERIC_MAPPING; +typedef struct standard_mapping { + uint32 std_read; + uint32 std_write; + uint32 std_execute; + uint32 std_all; +} STANDARD_MAPPING; + #endif /* _RPC_SECDES_H */ diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index f41a656fa6..22606b2f30 100755 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -3,8 +3,7 @@ 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, - Copyright (C) Tim Potter 2001. + 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 @@ -46,16 +45,13 @@ #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_ROUTERREPLYPRINTER 0x3b #define SPOOLSS_ADDPORTEX 0x3d #define SPOOLSS_REMOTEFINDFIRSTPRINTERCHANGENOTIFICATION0x3e #define SPOOLSS_SPOOLERINIT 0x3f #define SPOOLSS_RESETPRINTEREX 0x40 -#define SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFICATION 0x42 #define SPOOLSS_DELETEPRINTERDATAEX 0x51 #define SPOOLSS_DELETEPRINTERDRIVEREX 0x54 #define SPOOLSS_ADDPRINTERDRIVEREX 0x59 @@ -96,17 +92,15 @@ #define SPOOLSS_ENUMPORTS 0x23 #define SPOOLSS_ENUMMONITORS 0x24 #define SPOOLSS_ENUMPRINTPROCDATATYPES 0x33 +#define SPOOLSS_RESETPRINTER 0x34 #define SPOOLSS_GETPRINTERDRIVER2 0x35 -/* find close printer notification */ -#define SPOOLSS_FCPN 0x38 +#define SPOOLSS_FCPN 0x38 /* FindClosePrinterNotify */ #define SPOOLSS_REPLYOPENPRINTER 0x3a +#define SPOOLSS_ROUTERREPLYPRINTER 0x3b #define SPOOLSS_REPLYCLOSEPRINTER 0x3c -/* remote find first printer change notifyEx */ -#define SPOOLSS_RFFPCNEX 0x41 -/*SPOOLSS_ROUTERREFRESHPRINTERCHANGENOTIFICATION */ -#define SPOOLSS_RRPCN 0x42 -/* remote find next printer change notifyEx */ -#define SPOOLSS_RFNPCNEX 0x43 +#define SPOOLSS_RFFPCNEX 0x41 /* RemoteFindFirstPrinterChangeNotifyEx */ +#define SPOOLSS_RRPCN 0x42 /* RouteRefreshPrinterChangeNotification */ +#define SPOOLSS_RFNPCNEX 0x43 /* RemoteFindNextPrinterChangeNotifyEx */ #define SPOOLSS_OPENPRINTEREX 0x45 #define SPOOLSS_ADDPRINTEREX 0x46 #define SPOOLSS_ENUMPRINTERDATA 0x48 @@ -264,6 +258,8 @@ #define JOB_NOTIFY_TOTAL_BYTES 0x16 #define JOB_NOTIFY_BYTES_PRINTED 0x17 +#define PRINTER_NOTIFY_OPTIONS_REFRESH 0x01 + #define PRINTER_CHANGE_ADD_PRINTER 0x00000001 #define PRINTER_CHANGE_SET_PRINTER 0x00000002 #define PRINTER_CHANGE_DELETE_PRINTER 0x00000004 @@ -318,6 +314,34 @@ #define PRINTER_NOTIFY_INFO_DISCARDED 0x1 /* + * Set of macros for flagging what changed in the PRINTER_INFO_2 struct + * when sending messages to other smbd's + */ +#define PRINTER_MESSAGE_NULL 0x00000000 +#define PRINTER_MESSAGE_DRIVER 0x00000001 +#define PRINTER_MESSAGE_COMMENT 0x00000002 +#define PRINTER_MESSAGE_PRINTERNAME 0x00000004 +#define PRINTER_MESSAGE_LOCATION 0x00000008 +#define PRINTER_MESSAGE_DEVMODE 0x00000010 /* not curently supported */ +#define PRINTER_MESSAGE_SEPFILE 0x00000020 +#define PRINTER_MESSAGE_PRINTPROC 0x00000040 +#define PRINTER_MESSAGE_PARAMS 0x00000080 +#define PRINTER_MESSAGE_DATATYPE 0x00000100 +#define PRINTER_MESSAGE_SECDESC 0x00000200 +#define PRINTER_MESSAGE_CJOBS 0x00000400 +#define PRINTER_MESSAGE_PORT 0x00000800 +#define PRINTER_MESSAGE_SHARENAME 0x00001000 +#define PRINTER_MESSAGE_ATTRIBUTES 0x00002000 + +typedef struct printer_message_info { + uint32 low; /* PRINTER_CHANGE_XXX */ + uint32 high; /* PRINTER_CHANGE_XXX */ + fstring printer_name; + uint32 flags; /* PRINTER_MESSAGE_XXX */ +} +PRINTER_MESSAGE_INFO; + +/* * The printer attributes. * I #defined all of them (grabbed form MSDN) * I'm only using: @@ -395,6 +419,44 @@ typedef struct spool_user_ctr_info } SPOOL_USER_CTR; +/* + * various bits in the DEVICEMODE.fields member + */ + +#define DEVMODE_ORIENTATION 0x00000001 +#define DEVMODE_PAPERSIZE 0x00000002 +#define DEVMODE_PAPERLENGTH 0x00000004 +#define DEVMODE_PAPERWIDTH 0x00000008 +#define DEVMODE_SCALE 0x00000010 +#define DEVMODE_POSITION 0x00000020 +#define DEVMODE_NUP 0x00000040 +#define DEVMODE_COPIES 0x00000100 +#define DEVMODE_DEFAULTSOURCE 0x00000200 +#define DEVMODE_PRINTQUALITY 0x00000400 +#define DEVMODE_COLOR 0x00000800 +#define DEVMODE_DUPLEX 0x00001000 +#define DEVMODE_YRESOLUTION 0x00002000 +#define DEVMODE_TTOPTION 0x00004000 +#define DEVMODE_COLLATE 0x00008000 +#define DEVMODE_FORMNAME 0x00010000 +#define DEVMODE_LOGPIXELS 0x00020000 +#define DEVMODE_BITSPERPEL 0x00040000 +#define DEVMODE_PELSWIDTH 0x00080000 +#define DEVMODE_PELSHEIGHT 0x00100000 +#define DEVMODE_DISPLAYFLAGS 0x00200000 +#define DEVMODE_DISPLAYFREQUENCY 0x00400000 +#define DEVMODE_ICMMETHOD 0x00800000 +#define DEVMODE_ICMINTENT 0x01000000 +#define DEVMODE_MEDIATYPE 0x02000000 +#define DEVMODE_DITHERTYPE 0x04000000 +#define DEVMODE_PANNINGWIDTH 0x08000000 +#define DEVMODE_PANNINGHEIGHT 0x10000000 + + +/* + * Devicemode structure + */ + typedef struct devicemode { UNISTR devicename; @@ -1745,6 +1807,22 @@ typedef struct spool_r_setprinterdata } SPOOL_R_SETPRINTERDATA; +typedef struct spool_q_resetprinter +{ + POLICY_HND handle; + uint32 unknown1; + DEVMODE_CTR devmode_ctr; + +} SPOOL_Q_RESETPRINTER; + +typedef struct spool_r_resetprinter +{ + WERROR status; +} +SPOOL_R_RESETPRINTER; + + + typedef struct _form { uint32 flags; @@ -1851,6 +1929,22 @@ typedef struct spool_r_replyopenprinter } SPOOL_R_REPLYOPENPRINTER; +typedef struct spool_q_routerreplyprinter +{ + POLICY_HND handle; + uint32 condition; + uint32 unknown1; /* 0x00000001 */ + uint32 change_id; + uint8 unknown2[5]; /* 0x0000000001 */ +} +SPOOL_Q_ROUTERREPLYPRINTER; + +typedef struct spool_r_routerreplyprinter +{ + WERROR status; +} +SPOOL_R_ROUTERREPLYPRINTER; + typedef struct spool_q_replycloseprinter { POLICY_HND handle; diff --git a/source3/include/smb.h b/source3/include/smb.h index 1b6e280a4a..303b1f5efa 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -508,8 +508,8 @@ typedef struct _print_queue_struct int status; int priority; time_t time; - fstring user; - fstring file; + fstring fs_user; + fstring fs_file; } print_queue_struct; enum {LPSTAT_OK, LPSTAT_STOPPED, LPSTAT_ERROR}; diff --git a/source3/lib/util_seaccess.c b/source3/lib/util_seaccess.c index 5a934789e4..299b339ddf 100644 --- a/source3/lib/util_seaccess.c +++ b/source3/lib/util_seaccess.c @@ -193,6 +193,31 @@ void se_map_generic(uint32 *access_mask, struct generic_mapping *mapping) } } +/* Map standard access rights to object specific rights. This technique is + used to give meaning to assigning read, write, execute and all access to + objects. Each type of object has its own mapping of standard to object + specific access rights. */ + +void se_map_standard(uint32 *access_mask, struct standard_mapping *mapping) +{ + uint32 old_mask = *access_mask; + + if (*access_mask & READ_CONTROL_ACCESS) { + *access_mask &= ~READ_CONTROL_ACCESS; + *access_mask |= mapping->std_read; + } + + if (*access_mask & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS)) { + *access_mask &= ~(DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS); + *access_mask |= mapping->std_all; + } + + if (old_mask != *access_mask) { + DEBUG(10, ("se_map_standard(): mapped mask 0x%08x to 0x%08x\n", + old_mask, *access_mask)); + } +} + /***************************************************************************** Check access rights of a user against a security descriptor. Look at each ACE in the security descriptor until an access denied ACE denies diff --git a/source3/printing/lpq_parse.c b/source3/printing/lpq_parse.c index b513806473..13b87045cd 100644 --- a/source3/printing/lpq_parse.c +++ b/source3/printing/lpq_parse.c @@ -145,25 +145,25 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) buf->size = atoi(tok[TOTALTOK]); buf->status = strequal(tok[RANKTOK],"active")?LPQ_PRINTING:LPQ_QUEUED; buf->time = time(NULL); - StrnCpy(buf->user,tok[USERTOK],sizeof(buf->user)-1); - StrnCpy(buf->file,tok[FILETOK],sizeof(buf->file)-1); + StrnCpy(buf->fs_user,tok[USERTOK],sizeof(buf->fs_user)-1); + StrnCpy(buf->fs_file,tok[FILETOK],sizeof(buf->fs_file)-1); if ((FILETOK + 1) != TOTALTOK) { int bufsize; int i; - bufsize = sizeof(buf->file) - strlen(buf->file) - 1; + bufsize = sizeof(buf->fs_file) - strlen(buf->fs_file) - 1; for (i = (FILETOK + 1); i < TOTALTOK; i++) { - safe_strcat(buf->file," ",bufsize); - safe_strcat(buf->file,tok[i],bufsize - 1); - bufsize = sizeof(buf->file) - strlen(buf->file) - 1; + safe_strcat(buf->fs_file," ",bufsize); + safe_strcat(buf->fs_file,tok[i],bufsize - 1); + bufsize = sizeof(buf->fs_file) - strlen(buf->fs_file) - 1; if (bufsize <= 0) { break; } } /* Ensure null termination. */ - buf->file[sizeof(buf->file)-1] = '\0'; + buf->fs_file[sizeof(buf->fs_file)-1] = '\0'; } #ifdef PRIOTOK @@ -269,34 +269,34 @@ static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first) buf->time = LPRng_time(tokarr[LPRNG_TIMETOK]); - StrnCpy(buf->user,tokarr[LPRNG_USERTOK],sizeof(buf->user)-1); + StrnCpy(buf->fs_user,tokarr[LPRNG_USERTOK],sizeof(buf->fs_user)-1); /* The '@hostname' prevents windows from displaying the printing icon * for the current user on the taskbar. Plop in a null. */ - if ((cptr = strchr_m(buf->user,'@')) != NULL) { + if ((cptr = strchr_m(buf->fs_user,'@')) != NULL) { *cptr = '\0'; } - StrnCpy(buf->file,tokarr[LPRNG_FILETOK],sizeof(buf->file)-1); + StrnCpy(buf->fs_file,tokarr[LPRNG_FILETOK],sizeof(buf->fs_file)-1); if ((LPRNG_FILETOK + 1) != LPRNG_TOTALTOK) { int bufsize; int i; - bufsize = sizeof(buf->file) - strlen(buf->file) - 1; + bufsize = sizeof(buf->fs_file) - strlen(buf->fs_file) - 1; for (i = (LPRNG_FILETOK + 1); i < LPRNG_TOTALTOK; i++) { - safe_strcat(buf->file," ",bufsize); - safe_strcat(buf->file,tokarr[i],bufsize - 1); - bufsize = sizeof(buf->file) - strlen(buf->file) - 1; + safe_strcat(buf->fs_file," ",bufsize); + safe_strcat(buf->fs_file,tokarr[i],bufsize - 1); + bufsize = sizeof(buf->fs_file) - strlen(buf->fs_file) - 1; if (bufsize <= 0) { break; } } /* Ensure null termination. */ - buf->file[sizeof(buf->file)-1] = '\0'; + buf->fs_file[sizeof(buf->fs_file)-1] = '\0'; } return(True); @@ -359,8 +359,8 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) buf->status = strequal(tok[0],"HELD")?LPQ_PAUSED:LPQ_QUEUED; buf->priority = 0; buf->time = time(NULL); - StrnCpy(buf->user,tok[3],sizeof(buf->user)-1); - StrnCpy(buf->file,tok[2],sizeof(buf->file)-1); + StrnCpy(buf->fs_user,tok[3],sizeof(buf->fs_user)-1); + StrnCpy(buf->fs_file,tok[2],sizeof(buf->fs_file)-1); } else { @@ -393,8 +393,8 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) buf->status = strequal(tok[2],"RUNNING")?LPQ_PRINTING:LPQ_QUEUED; buf->priority = 0; buf->time = time(NULL); - StrnCpy(buf->user,tok[5],sizeof(buf->user)-1); - StrnCpy(buf->file,tok[4],sizeof(buf->file)-1); + StrnCpy(buf->fs_user,tok[5],sizeof(buf->fs_user)-1); + StrnCpy(buf->fs_file,tok[4],sizeof(buf->fs_file)-1); } @@ -455,14 +455,14 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first) fstrcpy(tok[0],"STDIN"); buf->size = atoi(tok[1]); - StrnCpy(buf->file,tok[0],sizeof(buf->file)-1); + StrnCpy(buf->fs_file,tok[0],sizeof(buf->fs_file)-1); /* fill things from header line */ buf->time = jobtime; buf->job = jobid; buf->status = jobstat; buf->priority = jobprio; - StrnCpy(buf->user,jobuser,sizeof(buf->user)-1); + StrnCpy(buf->fs_user,jobuser,sizeof(buf->fs_user)-1); return(True); } @@ -488,7 +488,7 @@ static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first) /* the 2nd, 5th & 7th column must be integer */ if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4]) || !isdigit((int)*tok[6])) return(False); jobid = atoi(tok[1]); - StrnCpy(jobuser,tok[2],sizeof(buf->user)-1); + StrnCpy(jobuser,tok[2],sizeof(buf->fs_user)-1); jobprio = atoi(tok[4]); /* process time */ @@ -578,8 +578,8 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first) buf->status = LPQ_QUEUED; buf->priority = 0; buf->time = EntryTime(tok, 4, count, 7); - StrnCpy(buf->user,tok[2],sizeof(buf->user)-1); - StrnCpy(buf->file,tok[2],sizeof(buf->file)-1); + StrnCpy(buf->fs_user,tok[2],sizeof(buf->fs_user)-1); + StrnCpy(buf->fs_file,tok[2],sizeof(buf->fs_file)-1); return(True); } @@ -639,8 +639,8 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first) buf->status = strequal(tok[3],"active")?LPQ_PRINTING:LPQ_QUEUED; buf->priority = 0; buf->time = time(NULL); - StrnCpy(buf->user,tok[1],sizeof(buf->user)-1); - StrnCpy(buf->file,tok[6],sizeof(buf->file)-1); + StrnCpy(buf->fs_user,tok[1],sizeof(buf->fs_user)-1); + StrnCpy(buf->fs_file,tok[6],sizeof(buf->fs_file)-1); return(True); } @@ -709,8 +709,8 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first) buf->status = strequal(tok[0],"active")?LPQ_PRINTING:LPQ_QUEUED; buf->priority = 0; buf->time = time(NULL); - StrnCpy(buf->user,tok[1],sizeof(buf->user)-1); - StrnCpy(buf->file,tok[6],sizeof(buf->file)-1); + StrnCpy(buf->fs_user,tok[1],sizeof(buf->fs_user)-1); + StrnCpy(buf->fs_file,tok[6],sizeof(buf->fs_file)-1); return(True); } @@ -766,8 +766,8 @@ static BOOL parse_lpq_softq(char *line,print_queue_struct *buf,BOOL first) buf->job = atoi(tok[0]); buf->size = atoi(tok[count+6]); buf->priority = atoi(tok[count+5]); - StrnCpy(buf->user,tok[count+7],sizeof(buf->user)-1); - StrnCpy(buf->file,tok[count+8],sizeof(buf->file)-1); + StrnCpy(buf->fs_user,tok[count+7],sizeof(buf->fs_user)-1); + StrnCpy(buf->fs_file,tok[count+8],sizeof(buf->fs_file)-1); buf->time = time(NULL); /* default case: take current time */ { time_t jobtime; @@ -863,8 +863,8 @@ static BOOL parse_lpq_nt(char *line,print_queue_struct *buf,BOOL first) buf->priority = 0; buf->size = atoi(parse_line.size); buf->time = time(NULL); - StrnCpy(buf->user, parse_line.owner, sizeof(buf->user)-1); - StrnCpy(buf->file, parse_line.jobname, sizeof(buf->file)-1); + StrnCpy(buf->fs_user, parse_line.owner, sizeof(buf->fs_user)-1); + StrnCpy(buf->fs_file, parse_line.jobname, sizeof(buf->fs_file)-1); if (strequal(parse_line.status, LPRNT_PRINTING)) buf->status = LPQ_PRINTING; else if (strequal(parse_line.status, LPRNT_PAUSED)) @@ -922,7 +922,7 @@ static BOOL parse_lpq_os2(char *line,print_queue_struct *buf,BOOL first) /* Get the job name */ parse_line.space2[0] = '\0'; trim_string(parse_line.jobname, NULL, " "); - StrnCpy(buf->file, parse_line.jobname, sizeof(buf->file)-1); + StrnCpy(buf->fs_file, parse_line.jobname, sizeof(buf->fs_file)-1); buf->priority = 0; buf->size = atoi(parse_line.size); @@ -940,7 +940,7 @@ static BOOL parse_lpq_os2(char *line,print_queue_struct *buf,BOOL first) !strequal(parse_line.status, LPROS2_WAITING)) return(False); - StrnCpy(buf->user, parse_line.owner, sizeof(buf->user)-1); + StrnCpy(buf->fs_user, parse_line.owner, sizeof(buf->fs_user)-1); if (strequal(parse_line.status, LPROS2_PRINTING)) buf->status = LPQ_PRINTING; else if (strequal(parse_line.status, LPROS2_PAUSED)) @@ -986,10 +986,10 @@ static BOOL parse_lpq_vlp(char *line,print_queue_struct *buf,BOOL first) buf->time = atoi(tok); break; case 4: - fstrcpy(buf->user, tok); + fstrcpy(buf->fs_user, tok); break; case 5: - fstrcpy(buf->file, tok); + fstrcpy(buf->fs_file, tok); break; } toknum++; diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 43667a674d..4cd9a0ec91 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -42,7 +42,13 @@ static TDB_CONTEXT *tdb_printers; /* used for printers files */ /* Map generic permissions to printer object specific permissions */ -struct generic_mapping printer_generic_mapping = { +GENERIC_MAPPING printer_generic_mapping = { + PRINTER_READ, + PRINTER_EXECUTE, + PRINTER_ALL_ACCESS +}; + +STANDARD_MAPPING printer_std_mapping = { PRINTER_READ, PRINTER_WRITE, PRINTER_EXECUTE, @@ -2160,10 +2166,6 @@ void free_nt_printer_param(NT_PRINTER_PARAM **param_ptr) NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename) { -/* - * should I init this ones ??? - nt_devmode->devicename -*/ char adevice[32]; NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE)); @@ -2485,11 +2487,8 @@ static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstrin snum = lp_servicenumber(sharename); slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name()); - strupper(info.servername); - slprintf(info.printername, sizeof(info.printername)-1, "\\\\%s\\", - get_called_name()); - strupper(info.printername); - fstrcat(info.printername, sharename); + slprintf(info.printername, sizeof(info.printername)-1, "\\\\%s\\%s", + get_called_name(), sharename); fstrcpy(info.sharename, sharename); fstrcpy(info.portname, SAMBA_PRINTER_PORT_NAME); fstrcpy(info.drivername, lp_printerdriver(snum)); @@ -2605,8 +2604,7 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen info.attributes |= (PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK); /* Restore the stripped strings. */ - slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", - get_called_name()); + slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name()); slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", get_called_name(), info.printername); fstrcpy(info.printername, printername); @@ -2739,8 +2737,17 @@ static uint32 rev_changeid(void) get_process_uptime(&tv); +#if 1 /* JERRY */ /* Return changeid as msec since spooler restart */ return tv.tv_sec * 1000 + tv.tv_usec / 1000; +#else + /* + * This setting seems to work well but is too untested + * to replace the above calculation. Left in for experiementation + * of the reader --jerry (Tue Mar 12 09:15:05 CST 2002) + */ + return tv.tv_sec * 10 + tv.tv_usec / 100000; +#endif } /* @@ -2857,11 +2864,44 @@ static uint32 set_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info_ptr) ZERO_STRUCT(info.devmode->devicename); fstrcpy(info.devmode->devicename, info_ptr->printername); + + /* + * NT/2k does not change out the entire DeviceMode of a printer + * when changing the driver. Only the driverextra, private, & + * driverversion fields. --jerry (Thu Mar 14 08:58:43 CST 2002) + */ + +#if 0 /* JERRY */ + /* * Bind the saved DEVMODE to the new the printer. */ free_nt_devicemode(&info_ptr->devmode); info_ptr->devmode = info.devmode; +#else + /* copy the entire devmode if we currently don't have one */ + + if (!info_ptr->devmode) { + DEBUG(10,("set_driver_init_2: Current Devmode is NULL. Copying entire Device Mode\n")); + info_ptr->devmode = info.devmode; + } + else { + /* only set the necessary fields */ + + DEBUG(10,("set_driver_init_2: Setting driverversion [0x%x] and private data [0x%x]\n", + info.devmode->driverversion, info.devmode->driverextra)); + + info_ptr->devmode->driverversion = info.devmode->driverversion; + + SAFE_FREE(info_ptr->devmode->private); + info_ptr->devmode->private = NULL; + + if (info.devmode->driverversion) + info_ptr->devmode->private = memdup(info.devmode->private, info.devmode->driverversion); + + free_nt_devicemode(&info.devmode); + } +#endif DEBUG(10,("set_driver_init_2: Set printer [%s] init DEVMODE for driver [%s]\n", info_ptr->printername, info_ptr->drivername)); @@ -3934,6 +3974,7 @@ BOOL print_time_access_check(int snum) return ok; } +#if 0 /* JERRY - not used */ /**************************************************************************** Attempt to write a default device. *****************************************************************************/ @@ -4005,3 +4046,4 @@ WERROR printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_defaul free_a_printer(&printer, 2); return result; } +#endif /* JERRY */ diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 758c855188..97eaaebcc4 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -161,8 +161,8 @@ static void print_unix_job(int snum, print_queue_struct *q) pj.spooled = True; pj.smbjob = False; fstrcpy(pj.filename, ""); - fstrcpy(pj.jobname, q->file); - fstrcpy(pj.user, q->user); + fstrcpy(pj.jobname, q->fs_file); + fstrcpy(pj.user, q->fs_user); pj.snum = snum; print_job_store(jobid, &pj); @@ -217,7 +217,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void } for (i=0;i<ts->qcount;i++) { - int qid = print_parse_jobid(ts->queue[i].file); + int qid = print_parse_jobid(ts->queue[i].fs_file); if (jobid == qid) break; } @@ -410,7 +410,7 @@ static void print_queue_update_background(int snum) fill in any system job numbers as we go */ for (i=0; i<qcount; i++) { - int jobid = print_parse_jobid(queue[i].file); + int jobid = print_parse_jobid(queue[i].fs_file); if (jobid == -1) { /* assume its a unix print job */ @@ -1140,8 +1140,8 @@ static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void * ts->queue[i].status = pjob.status; ts->queue[i].priority = 1; ts->queue[i].time = pjob.starttime; - fstrcpy(ts->queue[i].user, pjob.user); - fstrcpy(ts->queue[i].file, pjob.jobname); + fstrcpy(ts->queue[i].fs_user, pjob.user); + fstrcpy(ts->queue[i].fs_file, pjob.jobname); ts->qcount++; diff --git a/source3/rpc_client/cli_spoolss_notify.c b/source3/rpc_client/cli_spoolss_notify.c index c31d2fb387..a3e7acb1c1 100644 --- a/source3/rpc_client/cli_spoolss_notify.c +++ b/source3/rpc_client/cli_spoolss_notify.c @@ -20,11 +20,36 @@ */ #include "includes.h" +#if 0 #include "rpc_parse.h" #include "nterr.h" - +#endif extern pstring global_myname; +struct msg_info_table { + uint32 msg; + uint32 field; + char* name; + void (*construct_fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data, + print_queue_struct *queue, + NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); +}; + +struct msg_info_table msg_table[] = { +{ PRINTER_MESSAGE_DRIVER, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_MESSAGE_DRIVER", spoolss_notify_driver_name }, +{ PRINTER_MESSAGE_ATTRIBUTES, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_MESSAGE_ATTRIBUTES", spoolss_notify_attributes }, +{ PRINTER_MESSAGE_COMMENT, PRINTER_NOTIFY_COMMENT, "PRINTER_MESSAGE_COMMENT", spoolss_notify_comment }, +{ PRINTER_MESSAGE_LOCATION, PRINTER_NOTIFY_LOCATION, "PRINTER_MESSAGE_LOCATION", spoolss_notify_location }, +{ PRINTER_MESSAGE_PRINTERNAME, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_MESSAGE_PRINTERNAME", spoolss_notify_printer_name }, +{ PRINTER_MESSAGE_SHARENAME, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_MESSAGE_SHARENAME", spoolss_notify_share_name }, +{ PRINTER_MESSAGE_PORT, PRINTER_NOTIFY_PORT_NAME, "PRINTER_MESSAGE_PORT", spoolss_notify_port_name }, +{ PRINTER_MESSAGE_CJOBS, PRINTER_NOTIFY_CJOBS, "PRINTER_MESSAGE_CJOBS", spoolss_notify_cjobs }, +{ PRINTER_MESSAGE_SEPFILE, PRINTER_NOTIFY_SEPFILE, "PRINTER_MESSAGE_SEPFILE", spoolss_notify_sepfile }, +{ PRINTER_MESSAGE_PARAMS, PRINTER_NOTIFY_PARAMETERS, "PRINTER_MESSAGE_PARAMETERS", spoolss_notify_parameters }, +{ PRINTER_MESSAGE_DATATYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_MESSAGE_DATATYPE", spoolss_notify_datatype }, +{ PRINTER_MESSAGE_NULL, 0x0, "", NULL }, +}; + /********************************************************* Disconnect from the client machine. **********************************************************/ @@ -126,167 +151,313 @@ BOOL spoolss_connect_to_client( struct cli_state *cli, char *remote_machine) return True; } +/* + * SPOOLSS Client RPC's used by servers as the notification + * back channel + */ + /*************************************************************************** do a reply open printer ****************************************************************************/ -BOOL cli_spoolss_reply_open_printer(struct cli_state *cli, char *printer, uint32 localprinter, uint32 type, WERROR *status, POLICY_HND *handle) +NTSTATUS cli_spoolss_reply_open_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *printer, uint32 localprinter, uint32 type, + POLICY_HND *handle) { + NTSTATUS result; + prs_struct rbuf; prs_struct buf; SPOOL_Q_REPLYOPENPRINTER q_s; SPOOL_R_REPLYOPENPRINTER r_s; - prs_init(&buf, 1024, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL ); + prs_init(&buf, 1024, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL ); /* create and send a MSRPC command with api SPOOLSS_REPLYOPENPRINTER */ -/* - DEBUG(4,("cli_spoolss_reply_open_printer: srv:%s acct:%s sc: %d mc: %s clnt %s %x\n", - cli->srv_name_slash, cli->mach_acct, sec_chan_type, global_myname, - credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time)); -*/ + /* store the parameters */ make_spoolss_q_replyopenprinter(&q_s, printer, localprinter, type); /* turn parameters into data stream */ if(!spoolss_io_q_replyopenprinter("", &q_s, &buf, 0)) { - DEBUG(0,("cli_spoolss_reply_open_printer: Error : failed to marshall NET_Q_SRV_PWSET struct.\n")); - prs_mem_free(&buf); - prs_mem_free(&rbuf); - return False; + DEBUG(0,("cli_spoolss_reply_open_printer: Error : failed to marshall SPOOL_Q_REPLYOPENPRINTER struct.\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; } /* send the data on \PIPE\ */ if (!rpc_api_pipe_req(cli, SPOOLSS_REPLYOPENPRINTER, &buf, &rbuf)) { - prs_mem_free(&buf); - prs_mem_free(&rbuf); - return False; + result = NT_STATUS_UNSUCCESSFUL; + goto done; } - prs_mem_free(&buf); - /* turn data stream into parameters*/ if(!spoolss_io_r_replyopenprinter("", &r_s, &rbuf, 0)) { - prs_mem_free(&rbuf); - return False; + DEBUG(0,("cli_spoolss_reply_open_printer: Error : failed to unmarshall SPOOL_R_REPLYOPENPRINTER struct.\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; } - prs_mem_free(&rbuf); - memcpy(handle, &r_s.handle, sizeof(r_s.handle)); - *status=r_s.status; + result = werror_to_ntstatus(r_s.status); - return True; +done: + prs_mem_free(&buf); + prs_mem_free(&rbuf); + + return result; } /*************************************************************************** do a reply open printer ****************************************************************************/ -BOOL cli_spoolss_reply_rrpcn(struct cli_state *cli, POLICY_HND *handle, - uint32 change_low, uint32 change_high, WERROR *status) +NTSTATUS cli_spoolss_reply_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *handle) { + NTSTATUS result; prs_struct rbuf; prs_struct buf; - SPOOL_Q_REPLY_RRPCN q_s; - SPOOL_R_REPLY_RRPCN r_s; + SPOOL_Q_REPLYCLOSEPRINTER q_s; + SPOOL_R_REPLYCLOSEPRINTER r_s; prs_init(&buf, 1024, cli->mem_ctx, MARSHALL); prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL ); /* create and send a MSRPC command with api */ -/* - DEBUG(4,("cli_spoolss_reply_open_printer: srv:%s acct:%s sc: %d mc: %s clnt %s %x\n", - cli->srv_name_slash, cli->mach_acct, sec_chan_type, global_myname, - credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time)); -*/ + /* store the parameters */ - make_spoolss_q_reply_rrpcn(&q_s, handle, change_low, change_high); + make_spoolss_q_reply_closeprinter(&q_s, handle); /* turn parameters into data stream */ - if(!spoolss_io_q_reply_rrpcn("", &q_s, &buf, 0)) { - DEBUG(0,("cli_spoolss_reply_rrpcn: Error : failed to marshall SPOOL_Q_REPLY_RRPCN struct.\n")); - prs_mem_free(&buf); - prs_mem_free(&rbuf); - return False; + if(!spoolss_io_q_replycloseprinter("", &q_s, &buf, 0)) { + DEBUG(0,("cli_spoolss_reply_close_printer: Error : failed to marshall SPOOL_Q_REPLY_CLOSEPRINTER struct.\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; } /* send the data on \PIPE\ */ - if (!rpc_api_pipe_req(cli, SPOOLSS_RRPCN, &buf, &rbuf)) { - prs_mem_free(&buf); - prs_mem_free(&rbuf); - return False; + if (!rpc_api_pipe_req(cli, SPOOLSS_REPLYCLOSEPRINTER, &buf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; } - prs_mem_free(&buf); - /* turn data stream into parameters*/ - if(!spoolss_io_r_reply_rrpcn("", &r_s, &rbuf, 0)) { + if(!spoolss_io_r_replycloseprinter("", &r_s, &rbuf, 0)) { + DEBUG(0,("cli_spoolss_reply_close_printer: Error : failed to marshall SPOOL_R_REPLY_CLOSEPRINTER struct.\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + + result = werror_to_ntstatus(r_s.status); + +done: + prs_mem_free(&buf); prs_mem_free(&rbuf); - return False; + + return result; +} + + +/********************************************************************* + This SPOOLSS_ROUTERREPLYPRINTER function is used to send a change + notification event when the registration **did not** use + SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor. + Also see cli_spolss_reply_rrpcn() + *********************************************************************/ + +NTSTATUS cli_spoolss_routerreplyprinter (struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 condition, uint32 changd_id) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ROUTERREPLYPRINTER q; + SPOOL_R_ROUTERREPLYPRINTER r; + NTSTATUS result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + + /* Initialise input parameters */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + + /* write the request */ + make_spoolss_q_routerreplyprinter(&q, pol, condition, changd_id); + + /* Marshall data and send request */ + if (!spoolss_io_q_routerreplyprinter ("", &q, &qbuf, 0)) { + DEBUG(0,("cli_spoolss_routerreplyprinter: Unable to marshall SPOOL_Q_ROUTERREPLYPRINTER!\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; } + + + if (!rpc_api_pipe_req (cli, SPOOLSS_ROUTERREPLYPRINTER, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + if (!spoolss_io_r_routerreplyprinter ("", &r, &rbuf, 0)) { + DEBUG(0,("cli_spoolss_routerreplyprinter: Unable to unmarshall SPOOL_R_ROUTERREPLYPRINTER!\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + result = werror_to_ntstatus(r.status); - prs_mem_free(&rbuf); +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); - *status=r_s.status; + return result; +} - return True; + +/********************************************************************************** + Build the SPOOL_NOTIFY_INFO_DATA entries based upon the flags which have been set + *********************************************************************************/ + +static int build_notify_data (TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer, uint32 flags, + SPOOL_NOTIFY_INFO_DATA **notify_data) +{ + SPOOL_NOTIFY_INFO_DATA *data; + uint32 idx = 0; + int i = 0; + + while ((msg_table[i].msg != PRINTER_MESSAGE_NULL) && flags) + { + if (flags & msg_table[i].msg) + { + DEBUG(10,("build_notify_data: %s set on [%s][%d]\n", msg_table[i].name, + printer->info_2->printername, idx)); + if ((data=Realloc(*notify_data, (idx+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) { + DEBUG(0,("build_notify_data: Realloc() failed with size [%d]!\n", + (idx+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))); + return -1; + } + *notify_data = data; + + /* clear memory */ + memset(*notify_data+idx, 0x0, sizeof(SPOOL_NOTIFY_INFO_DATA)); + + /* + * 'id' (last param here) is undefined when type == PRINTER_NOTIFY_TYPE + * See PRINTER_NOTIFY_INFO_DATA entries in MSDN + * --jerry + */ + construct_info_data(*notify_data+idx, PRINTER_NOTIFY_TYPE, msg_table[i].field, 0x00); + + msg_table[i].construct_fn(-1, *notify_data+idx, NULL, printer, ctx); + idx++; + } + + i++; + } + + return idx; } -/*************************************************************************** - do a reply open printer -****************************************************************************/ +/********************************************************************* + This SPOOLSS_ROUTERREPLYPRINTER function is used to send a change + notification event when the registration **did** use + SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor + Also see cli_spoolss_routereplyprinter() + *********************************************************************/ -BOOL cli_spoolss_reply_close_printer(struct cli_state *cli, POLICY_HND *handle, - WERROR *status) +NTSTATUS cli_spoolss_reply_rrpcn(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *handle, PRINTER_MESSAGE_INFO *info, + NT_PRINTER_INFO_LEVEL *printer) { prs_struct rbuf; prs_struct buf; - SPOOL_Q_REPLYCLOSEPRINTER q_s; - SPOOL_R_REPLYCLOSEPRINTER r_s; + SPOOL_NOTIFY_INFO notify_info; + SPOOL_NOTIFY_INFO_DATA *notify_data = NULL; + uint32 data_len; - prs_init(&buf, 1024, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL ); + NTSTATUS result; + + SPOOL_Q_REPLY_RRPCN q_s; + SPOOL_R_REPLY_RRPCN r_s; + + if (!info) { + DEBUG(5,("cli_spoolss_reply_rrpcn: NULL printer message info pointer!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + prs_init(&buf, 1024, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL ); + + ZERO_STRUCT(notify_info); - /* create and send a MSRPC command with api */ /* - DEBUG(4,("cli_spoolss_reply_open_printer: srv:%s acct:%s sc: %d mc: %s clnt %s %x\n", - cli->srv_name_slash, cli->mach_acct, sec_chan_type, global_myname, - credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time)); + * See comments in _spoolss_setprinter() about PRINTER_CHANGE_XXX + * events. --jerry */ + DEBUG(10,("cli_spoolss_reply_rrpcn: PRINTER_MESSAGE flags = 0x%8x\n", info->flags)); + + data_len = build_notify_data(mem_ctx, printer, info->flags, ¬ify_data); + if (info->flags && (data_len == -1)) { + DEBUG(0,("cli_spoolss_reply_rrpcn: Failed to build SPOOL_NOTIFY_INFO_DATA [flags == 0x%x] for printer [%s]\n", + info->flags, info->printer_name)); + result = NT_STATUS_NO_MEMORY; + goto done; + } + notify_info.version = 0x2; + notify_info.flags = 0x00020000; /* ?? */ + notify_info.count = data_len; + notify_info.data = notify_data; + + /* create and send a MSRPC command with api */ /* store the parameters */ - make_spoolss_q_reply_closeprinter(&q_s, handle); + + make_spoolss_q_reply_rrpcn(&q_s, handle, info->low, info->high, ¬ify_info); /* turn parameters into data stream */ - if(!spoolss_io_q_replycloseprinter("", &q_s, &buf, 0)) { - DEBUG(0,("cli_spoolss_reply_close_printer: Error : failed to marshall SPOOL_Q_REPLY_CLOSEPRINTER struct.\n")); - prs_mem_free(&buf); - prs_mem_free(&rbuf); - return False; + if(!spoolss_io_q_reply_rrpcn("", &q_s, &buf, 0)) { + DEBUG(0,("cli_spoolss_reply_rrpcn: Error : failed to marshall SPOOL_Q_REPLY_RRPCN struct.\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; } /* send the data on \PIPE\ */ - if (!rpc_api_pipe_req(cli, SPOOLSS_REPLYCLOSEPRINTER, &buf, &rbuf)) { - prs_mem_free(&buf); - prs_mem_free(&rbuf); - return False; + if (!rpc_api_pipe_req(cli, SPOOLSS_RRPCN, &buf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; } - prs_mem_free(&buf); /* turn data stream into parameters*/ - if(!spoolss_io_r_replycloseprinter("", &r_s, &rbuf, 0)) { - prs_mem_free(&rbuf); - return False; + if(!spoolss_io_r_reply_rrpcn("", &r_s, &rbuf, 0)) { + DEBUG(0,("cli_spoolss_reply_rrpcn: Error : failed to unmarshall SPOOL_R_REPLY_RRPCN struct.\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + if (r_s.unknown0 == 0x00080000) { + DEBUG(8,("cli_spoolss_reply_rrpcn: I think the spooler resonded that the notification was ignored.\n")); } - prs_mem_free(&rbuf); + result = werror_to_ntstatus(r_s.status); - *status=r_s.status; +done: + prs_mem_free(&buf); + prs_mem_free(&rbuf); + /* + * The memory allocated in this array is talloc'd so we only need + * free the array here. JRA. + */ + SAFE_FREE(notify_data); - return True; + return result; } + diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index a37893db9b..17af8394d8 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -47,21 +47,21 @@ This should be moved in a more generic lib. static BOOL spoolss_io_system_time(char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime) { - if(!prs_uint16("year", ps, depth, &(systime->year))) + if(!prs_uint16("year", ps, depth, &systime->year)) return False; - if(!prs_uint16("month", ps, depth, &(systime->month))) + if(!prs_uint16("month", ps, depth, &systime->month)) return False; - if(!prs_uint16("dayofweek", ps, depth, &(systime->dayofweek))) + if(!prs_uint16("dayofweek", ps, depth, &systime->dayofweek)) return False; - if(!prs_uint16("day", ps, depth, &(systime->day))) + if(!prs_uint16("day", ps, depth, &systime->day)) return False; - if(!prs_uint16("hour", ps, depth, &(systime->hour))) + if(!prs_uint16("hour", ps, depth, &systime->hour)) return False; - if(!prs_uint16("minute", ps, depth, &(systime->minute))) + if(!prs_uint16("minute", ps, depth, &systime->minute)) return False; - if(!prs_uint16("second", ps, depth, &(systime->second))) + if(!prs_uint16("second", ps, depth, &systime->second)) return False; - if(!prs_uint16("milliseconds", ps, depth, &(systime->milliseconds))) + if(!prs_uint16("milliseconds", ps, depth, &systime->milliseconds)) return False; return True; @@ -424,8 +424,13 @@ BOOL smb_io_notify_info_data_strings(char *desc,SPOOL_NOTIFY_INFO_DATA *data, return False; } } +#if 0 /* JERRY */ + + /* Win2k does not seem to put this parse align here */ + if(!prs_align(ps)) return False; +#endif return True; } @@ -820,11 +825,8 @@ BOOL make_spoolss_q_addprinterex( create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct *******************************************************************/ -BOOL make_spoolss_printer_info_2( - TALLOC_CTX *mem_ctx, - SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, - PRINTER_INFO_2 *info -) +BOOL make_spoolss_printer_info_2(TALLOC_CTX *mem_ctx, SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2, + PRINTER_INFO_2 *info) { SPOOL_PRINTER_INFO_LEVEL_2 *inf; @@ -952,7 +954,7 @@ BOOL spoolss_io_r_open_printer_ex(char *desc, SPOOL_R_OPEN_PRINTER_EX *r_u, prs_ if (!smb_io_pol_hnd("printer handle",&(r_u->handle),ps,depth)) return False; - if (!prs_werror("status", ps, depth, &(r_u->status))) + if (!prs_werror("status code", ps, depth, &(r_u->status))) return False; return True; @@ -3648,40 +3650,28 @@ BOOL make_spoolss_q_getprinter( /******************************************************************* * init a structure. ********************************************************************/ -BOOL make_spoolss_q_setprinter( - TALLOC_CTX *mem_ctx, - SPOOL_Q_SETPRINTER *q_u, - const POLICY_HND *hnd, - uint32 level, - PRINTER_INFO_CTR *info, - uint32 command -) +BOOL make_spoolss_q_setprinter(TALLOC_CTX *mem_ctx, SPOOL_Q_SETPRINTER *q_u, + const POLICY_HND *hnd, uint32 level, PRINTER_INFO_CTR *info, + uint32 command) { SEC_DESC *secdesc; DEVICEMODE *devmode; if (q_u == NULL) - { return False; - } memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); q_u->level = level; q_u->info.level = level; q_u->info.info_ptr = (info != NULL) ? 1 : 0; - switch (level) - { + switch (level) { case 2: secdesc = info->printers_2->secdesc; devmode = info->printers_2->devmode; - /* FIXMEE!! HACK ALERT!!! --jerry */ - info->printers_2->devmode = NULL; - info->printers_2->secdesc = NULL; - make_spoolss_printer_info_2 (mem_ctx, &q_u->info.info_2, info->printers_2); -#if 0 /* JERRY TEST */ +#if 1 /* JERRY TEST */ q_u->secdesc_ctr = (SEC_DESC_BUF*)malloc(sizeof(SEC_DESC_BUF)); if (!q_u->secdesc_ctr) return False; @@ -3691,7 +3681,7 @@ BOOL make_spoolss_q_setprinter( q_u->secdesc_ctr->sec = secdesc; q_u->devmode_ctr.devmode_ptr = (devmode != NULL) ? 1 : 0; - q_u->devmode_ctr.size = sizeof(DEVICEMODE) + (3*sizeof(uint32)); + q_u->devmode_ctr.size = (devmode != NULL) ? sizeof(DEVICEMODE) + (3*sizeof(uint32)) : 0; q_u->devmode_ctr.devmode = devmode; #else q_u->secdesc_ctr = NULL; @@ -3773,13 +3763,14 @@ BOOL spoolss_io_q_setprinter(char *desc, SPOOL_Q_SETPRINTER *q_u, prs_struct *ps if (!sec_io_desc_buf(desc, &q_u->secdesc_ctr, ps, depth)) return False; } else { - uint32 dummy; + uint32 dummy = 0; /* Parse a NULL security descriptor. This should really happen inside the sec_io_desc_buf() function. */ prs_debug(ps, depth, "", "sec_io_desc_buf"); - if (!prs_uint32("size", ps, depth + 1, &dummy)) return False; + if (!prs_uint32("size", ps, depth + 1, &dummy)) + return False; if (!prs_uint32("ptr", ps, depth + 1, &dummy)) return False; } @@ -5657,6 +5648,24 @@ BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u, /******************************************************************* ********************************************************************/ +BOOL make_spoolss_q_setprinterdata(SPOOL_Q_SETPRINTERDATA *q_u, TALLOC_CTX *ctx, const POLICY_HND *hnd, + char* value, char* data) +{ + UNISTR2 tmp; + + memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); + q_u->type = REG_SZ; + init_unistr2(&q_u->value, value, strlen(value)+1); + + init_unistr2(&tmp, data, strlen(data)+1); + q_u->max_len = q_u->real_len = tmp.uni_max_len*2; + q_u->data = talloc(ctx, q_u->real_len); + memcpy(q_u->data, tmp.buffer, q_u->real_len); + + return True; +} +/******************************************************************* +********************************************************************/ BOOL spoolss_io_q_setprinterdata(char *desc, SPOOL_Q_SETPRINTERDATA *q_u, prs_struct *ps, int depth) { @@ -5722,7 +5731,43 @@ BOOL spoolss_io_r_setprinterdata(char *desc, SPOOL_R_SETPRINTERDATA *r_u, prs_st /******************************************************************* ********************************************************************/ +BOOL spoolss_io_q_resetprinter(char *desc, SPOOL_Q_RESETPRINTER *q_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_q_resetprinter"); + depth++; + + if (!prs_align(ps)) + return False; + if (!smb_io_pol_hnd("printer handle", &q_u->handle, ps, depth)) + return False; + if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1)) + return False; + + if (!spoolss_io_devmode_cont(desc, &q_u->devmode_ctr, ps, depth)) + return False; + + return True; +} + + +/******************************************************************* +********************************************************************/ +BOOL spoolss_io_r_resetprinter(char *desc, SPOOL_R_RESETPRINTER *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_resetprinter"); + depth++; + + if(!prs_align(ps)) + return False; + if(!prs_werror("status", ps, depth, &r_u->status)) + return False; + + return True; +} + +/******************************************************************* +********************************************************************/ BOOL convert_specific_param(NT_PRINTER_PARAM **param, const UNISTR2 *value, uint32 type, const uint8 *data, uint32 len) { @@ -5832,7 +5877,7 @@ BOOL spoolss_io_r_deleteform(char *desc, SPOOL_R_DELETEFORM *r_u, prs_struct *ps BOOL spoolss_io_q_addform(char *desc, SPOOL_Q_ADDFORM *q_u, prs_struct *ps, int depth) { - uint32 useless_ptr=1; + uint32 useless_ptr=0; prs_debug(ps, depth, desc, "spoolss_io_q_addform"); depth++; @@ -5877,7 +5922,7 @@ 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) { - uint32 useless_ptr=1; + uint32 useless_ptr=0; prs_debug(ps, depth, desc, "spoolss_io_q_setform"); depth++; @@ -6100,6 +6145,73 @@ BOOL spoolss_io_r_replyopenprinter(char *desc, SPOOL_R_REPLYOPENPRINTER *r_u, pr /******************************************************************* * init a structure. ********************************************************************/ +BOOL make_spoolss_q_routerreplyprinter(SPOOL_Q_ROUTERREPLYPRINTER *q_u, POLICY_HND *hnd, + uint32 condition, uint32 change_id) +{ + + memcpy(&q_u->handle, hnd, sizeof(q_u->handle)); + + q_u->condition = condition; + q_u->change_id = change_id; + + /* magic values */ + q_u->unknown1 = 0x1; + memset(q_u->unknown2, 0x0, 5); + q_u->unknown2[0] = 0x1; + + return True; +} + +/******************************************************************* + Parse a SPOOL_Q_ROUTERREPLYPRINTER structure. +********************************************************************/ +BOOL spoolss_io_q_routerreplyprinter (char *desc, SPOOL_Q_ROUTERREPLYPRINTER *q_u, prs_struct *ps, int depth) +{ + + prs_debug(ps, depth, desc, "spoolss_io_q_routerreplyprinter"); + depth++; + + if (!prs_align(ps)) + return False; + + if(!smb_io_pol_hnd("printer handle",&q_u->handle,ps,depth)) + return False; + + if (!prs_uint32("condition", ps, depth, &q_u->condition)) + return False; + + if (!prs_uint32("unknown1", ps, depth, &q_u->unknown1)) + return False; + + if (!prs_uint32("change_id", ps, depth, &q_u->change_id)) + return False; + + if (!prs_uint8s(False, "private", ps, depth, q_u->unknown2, 5)) + return False; + + return True; +} + +/******************************************************************* + Parse a SPOOL_R_ROUTERREPLYPRINTER structure. +********************************************************************/ +BOOL spoolss_io_r_routerreplyprinter (char *desc, SPOOL_R_ROUTERREPLYPRINTER *r_u, prs_struct *ps, int depth) +{ + prs_debug(ps, depth, desc, "spoolss_io_r_routerreplyprinter"); + depth++; + + if (!prs_align(ps)) + return False; + + if (!prs_werror("status", ps, depth, &r_u->status)) + return False; + + return True; +} + +/******************************************************************* + * init a structure. + ********************************************************************/ BOOL make_spoolss_q_reply_closeprinter(SPOOL_Q_REPLYCLOSEPRINTER *q_u, POLICY_HND *hnd) { @@ -6150,12 +6262,79 @@ BOOL spoolss_io_r_replycloseprinter(char *desc, SPOOL_R_REPLYCLOSEPRINTER *r_u, return True; } +#if 0 /* JERRY - not currently used but could be :-) */ + +/******************************************************************* + Deep copy a SPOOL_NOTIFY_INFO_DATA structure + ******************************************************************/ +static BOOL copy_spool_notify_info_data(SPOOL_NOTIFY_INFO_DATA *dst, + SPOOL_NOTIFY_INFO_DATA *src, int n) +{ + int i; + + memcpy(dst, src, sizeof(SPOOL_NOTIFY_INFO_DATA)*n); + + for (i=0; i<n; i++) { + int len; + uint16 *s = NULL; + + if (src->size != POINTER) + continue; + len = src->notify_data.data.length; + s = malloc(sizeof(uint16)*len); + if (s == NULL) { + DEBUG(0,("copy_spool_notify_info_data: malloc() failed!\n")); + return False; + } + + memcpy(s, src->notify_data.data.string, len*2); + dst->notify_data.data.string = s; + } + + return True; +} + +/******************************************************************* + Deep copy a SPOOL_NOTIFY_INFO structure + ******************************************************************/ +static BOOL copy_spool_notify_info(SPOOL_NOTIFY_INFO *dst, SPOOL_NOTIFY_INFO *src) +{ + if (!dst) { + DEBUG(0,("copy_spool_notify_info: NULL destination pointer!\n")); + return False; + } + + dst->version = src->version; + dst->flags = src->flags; + dst->count = src->count; + + if (dst->count) + { + dst->data = malloc(dst->count * sizeof(SPOOL_NOTIFY_INFO_DATA)); + + DEBUG(10,("copy_spool_notify_info: allocating space for [%d] PRINTER_NOTIFY_INFO_DATA entries\n", + dst->count)); + + if (dst->data == NULL) { + DEBUG(0,("copy_spool_notify_info: malloc() failed for [%d] entries!\n", + dst->count)); + return False; + } + + return (copy_spool_notify_info_data(dst->data, src->data, src->count)); + } + + return True; +} +#endif /* JERRY */ + /******************************************************************* * init a structure. ********************************************************************/ BOOL make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd, - uint32 change_low, uint32 change_high) + uint32 change_low, uint32 change_high, + SPOOL_NOTIFY_INFO *info) { if (q_u == NULL) return False; @@ -6168,11 +6347,23 @@ BOOL make_spoolss_q_reply_rrpcn(SPOOL_Q_REPLY_RRPCN *q_u, POLICY_HND *hnd, q_u->unknown0=0x0; q_u->unknown1=0x0; - q_u->info_ptr=1; + q_u->info_ptr=0xaddee11e; q_u->info.version=2; + + if (info->count) { + DEBUG(10,("make_spoolss_q_reply_rrpcn: [%d] PRINTER_NOTIFY_INFO_DATA\n", + info->count)); + q_u->info.version = info->version; + q_u->info.flags = info->flags; + q_u->info.count = info->count; + /* pointer field - be careful! */ + q_u->info.data = info->data; + } + else { q_u->info.flags=PRINTER_NOTIFY_INFO_DISCARDED; q_u->info.count=0; + } return True; } @@ -6220,7 +6411,7 @@ BOOL spoolss_io_q_reply_rrpcn(char *desc, SPOOL_Q_REPLY_RRPCN *q_u, prs_struct * BOOL spoolss_io_r_reply_rrpcn(char *desc, SPOOL_R_REPLY_RRPCN *r_u, prs_struct *ps, int depth) { - prs_debug(ps, depth, desc, "spoolss_io_r_replycloseprinter"); + prs_debug(ps, depth, desc, "spoolss_io_r_reply_rrpcn"); depth++; if (!prs_align(ps)) @@ -6473,7 +6664,8 @@ static BOOL spoolss_io_printer_enum_values_ctr(char *desc, prs_struct *ps, if (!prs_uint32("size", ps, depth, &ctr->size)) return False; - /* offset data begins at 20 bytes per structure * size_of_array. */ + /* offset data begins at 20 bytes per structure * size_of_array. + Don't forget the uint32 at the beginning */ current_offset = basic_unit * ctr->size_of_array; @@ -6499,7 +6691,6 @@ static BOOL spoolss_io_printer_enum_values_ctr(char *desc, prs_struct *ps, return False; current_offset = data_offset + ctr->values[i].data_len - basic_unit; - } /* loop #2 for writing the dynamically size objects diff --git a/source3/rpc_server/srv_spoolss.c b/source3/rpc_server/srv_spoolss.c index 3f3c6039c9..3838632021 100755 --- a/source3/rpc_server/srv_spoolss.c +++ b/source3/rpc_server/srv_spoolss.c @@ -975,7 +975,33 @@ static BOOL api_spoolss_setprinterdata(pipes_struct *p) /**************************************************************************** ****************************************************************************/ +static BOOL api_spoolss_reset_printer(pipes_struct *p) +{ + SPOOL_Q_RESETPRINTER q_u; + SPOOL_R_RESETPRINTER r_u; + prs_struct *data = &p->in_data.data; + prs_struct *rdata = &p->out_data.rdata; + + ZERO_STRUCT(q_u); + ZERO_STRUCT(r_u); + + if(!spoolss_io_q_resetprinter("", &q_u, data, 0)) { + DEBUG(0,("spoolss_io_q_setprinterdata: unable to unmarshall SPOOL_Q_SETPRINTERDATA.\n")); + return False; + } + + r_u.status = _spoolss_resetprinter(p, &q_u, &r_u); + + if(!spoolss_io_r_resetprinter("", &r_u, rdata, 0)) { + DEBUG(0,("spoolss_io_r_setprinterdata: unable to marshall SPOOL_R_RESETPRINTER.\n")); + return False; + } + + return True; +} +/**************************************************************************** +****************************************************************************/ static BOOL api_spoolss_addform(pipes_struct *p) { SPOOL_Q_ADDFORM q_u; @@ -1318,11 +1344,6 @@ static BOOL api_spoolss_enumprinterdataex(pipes_struct *p) /**************************************************************************** ****************************************************************************/ -/* Disabled because it doesn't fix the bug I am looking at but it would be - a shame to throw away the code. -tpot */ - -#if 0 - static BOOL api_spoolss_getprintprocessordirectory(pipes_struct *p) { SPOOL_Q_GETPRINTPROCESSORDIRECTORY q_u; @@ -1348,8 +1369,6 @@ static BOOL api_spoolss_getprintprocessordirectory(pipes_struct *p) return True; } -#endif - /******************************************************************* \pipe\spoolss commands ********************************************************************/ @@ -1386,6 +1405,7 @@ struct api_struct api_spoolss_cmds[] = {"SPOOLSS_GETPRINTERDRIVERDIRECTORY", SPOOLSS_GETPRINTERDRIVERDIRECTORY, api_spoolss_getprinterdriverdirectory }, {"SPOOLSS_ENUMPRINTERDATA", SPOOLSS_ENUMPRINTERDATA, api_spoolss_enumprinterdata }, {"SPOOLSS_SETPRINTERDATA", SPOOLSS_SETPRINTERDATA, api_spoolss_setprinterdata }, + {"SPOOLSS_RESETPRINTER", SPOOLSS_RESETPRINTER, api_spoolss_reset_printer }, {"SPOOLSS_DELETEPRINTERDATA", SPOOLSS_DELETEPRINTERDATA, api_spoolss_deleteprinterdata }, {"SPOOLSS_ADDFORM", SPOOLSS_ADDFORM, api_spoolss_addform }, {"SPOOLSS_DELETEFORM", SPOOLSS_DELETEFORM, api_spoolss_deleteform }, diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 3479e47f76..a6c0f9368c 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -91,6 +91,10 @@ static ubi_dlList counter_list; static struct cli_state cli; static uint32 smb_connections=0; + +/* in printing/nt_printing.c */ +extern STANDARD_MAPPING printer_std_mapping; + #define OUR_HANDLE(hnd) (((hnd)==NULL)?"NULL":(IVAL((hnd)->data5,4)==(uint32)sys_getpid()?"OURS":"OTHER")), \ ((unsigned int)IVAL((hnd)->data5,4)),((unsigned int)sys_getpid()) @@ -158,7 +162,7 @@ static void free_spool_notify_option(SPOOL_NOTIFY_OPTION **pp) static void srv_spoolss_replycloseprinter(POLICY_HND *handle) { - WERROR status; + NTSTATUS result; /* weird if the test succeds !!! */ if (smb_connections==0) { @@ -166,7 +170,9 @@ static void srv_spoolss_replycloseprinter(POLICY_HND *handle) return; } - if(!cli_spoolss_reply_close_printer(&cli, handle, &status)) + result = cli_spoolss_reply_close_printer(&cli, cli.mem_ctx, handle); + + if (!NT_STATUS_IS_OK(result)) DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed.\n")); /* if it's the last connection, deconnect the IPC$ share */ @@ -528,71 +534,233 @@ static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size) return True; } +/*************************************************************************** + Always give preference Printer_entry.notify.option over + Printer_entry.notify.flags. Return True if we should send notification + events using SPOOLSS_RRPCN. False means that we should use + SPOOLSS_ROUTERREPLYPRINTER. + **************************************************************************/ +static BOOL valid_notify_options(Printer_entry *printer) +{ + if (printer->notify.option == NULL) + return False; + + return True; +} /*************************************************************************** - Receive the notify message. -****************************************************************************/ + Simple check to see if the client motify handle is set to watch for events + represented by 'flags' + + FIXME!!!! only a stub right now --jerry + **************************************************************************/ + +static BOOL is_client_monitoring_event(Printer_entry *p, uint32 flags) +{ -static void srv_spoolss_receive_message(int msg_type, pid_t src, void *buf, size_t len) + return True; +} + +/*************************************************************************** + Server wrapper for cli_spoolss_routerreplyprinter() since the client + function can only send a single change notification at a time. + + FIXME!!! only handles one change currently (PRINTER_CHANGE_SET_PRINTER_DRIVER) + --jerry + **************************************************************************/ + +static NTSTATUS srv_spoolss_routerreplyprinter (struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, PRINTER_MESSAGE_INFO *info, + NT_PRINTER_INFO_LEVEL *printer) { - Printer_entry *find_printer; - WERROR status; - fstring printer_name; - char msg[8]; - char *buf_ptr = (char *)buf; - uint32 low, high; + NTSTATUS result; + uint32 condition = 0x0; + + if (info->flags & PRINTER_MESSAGE_DRIVER) + condition = PRINTER_CHANGE_SET_PRINTER_DRIVER; + + result = cli_spoolss_routerreplyprinter(cli, mem_ctx, pol, condition, + printer->info_2->changeid); - if (len < sizeof(msg) + 2) { - DEBUG(2,("srv_spoolss_receive_message: got incorrect message size (%u)!\n", (unsigned int)len)); - return; + return result; +} + +/*********************************************************************** + Wrapper around the decision of which RPC use to in the change + notification + **********************************************************************/ + +static NTSTATUS srv_spoolss_send_event_to_client(Printer_entry* Printer, + struct cli_state *cli, PRINTER_MESSAGE_INFO *msg, + NT_PRINTER_INFO_LEVEL *info) +{ + NTSTATUS result; + + if (valid_notify_options(Printer)) { + /* This is a single call that can send information about multiple changes */ + if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) + msg->flags |= PRINTER_MESSAGE_ATTRIBUTES; + result = cli_spoolss_reply_rrpcn(cli, cli->mem_ctx, &Printer->notify.client_hnd, + msg, info); } + else { + /* This requires that the server send an individual event notification for each change */ + result = srv_spoolss_routerreplyprinter(cli, cli->mem_ctx, &Printer->notify.client_hnd, + msg, info); + } + + return result; +} - memcpy(msg, buf_ptr, sizeof(msg)); - low = IVAL(msg,0); - high = IVAL(msg,4); - fstrcpy(printer_name, buf_ptr + sizeof(msg)); - DEBUG(10,("srv_spoolss_receive_message: Got message printer change name [%s] low=0x%x high=0x%x\n", - printer_name, (unsigned int)low, (unsigned int)high )); +/*********************************************************************** + Send a change notication message on all handles which have a call + back registered + **********************************************************************/ + +static void send_spoolss_event_notification(PRINTER_MESSAGE_INFO *msg) +{ + Printer_entry *find_printer; + NTSTATUS result; + WERROR wresult; + NT_PRINTER_INFO_LEVEL *printer = NULL; + + if (!msg) { + DEBUG(0,("send_spoolss_event_notification: NULL msg pointer!\n")); + return; + } - /* Iterate the printer list */ for(find_printer = printers_list; find_printer; find_printer = find_printer->next) { /* - * If the entry has a connected client we send the message. + * If the entry has a connected client we send the message. There should + * only be one of these normally when dealing with the NT/2k spooler. + * However, iterate over all to make sure we deal with user applications + * in addition to spooler service. + * + * While we are only maintaining a single connection to the client, + * the FindFirstPrinterChangeNotification() call is made on a printer + * handle, so "client_connected" represents the whether or not the + * client asked for change notication on this handle. + * + * --jerry */ if (find_printer->notify.client_connected==True) { - DEBUG(10,("srv_spoolss_receive_message: printerserver [%s]\n", find_printer->dev.printerservername )); - if (*printer_name && !strequal(printer_name, find_printer->dev.handlename)) { - DEBUG(10,("srv_spoolss_receive_message: ignoring message sent to %s [%s]\n", - printer_name, find_printer->dev.handlename )); + + /* does the client care about what changed? */ + + if (msg->flags && !is_client_monitoring_event(find_printer, msg->flags)) { + DEBUG(10,("send_spoolss_event_notification: Client [%s] not monitoring these events\n", + find_printer->client.machine)); continue; } - if (cli_spoolss_reply_rrpcn(&cli, &find_printer->notify.client_hnd, low, high, &status)) - DEBUG(10,("srv_spoolss_receive_message: cli_spoolss_reply_rrpcn status = 0x%x\n", - (unsigned int)W_ERROR_V(status))); + if (find_printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) + DEBUG(10,("send_spoolss_event_notification: printserver [%s]\n", find_printer->dev.printerservername )); else - DEBUG(10,("srv_spoolss_receive_message: cli_spoolss_reply_rrpcn failed\n")); + DEBUG(10,("send_spoolss_event_notification: printer [%s]\n", find_printer->dev.handlename)); + + /* + * if handle is a printer, only send if the printer_name matches. + * ...else if handle is a printerserver, send to all + */ + + if (*msg->printer_name && (find_printer->printer_type==PRINTER_HANDLE_IS_PRINTER) + && !strequal(msg->printer_name, find_printer->dev.handlename)) + { + DEBUG(10,("send_spoolss_event_notification: ignoring message sent to %s [%s]\n", + msg->printer_name, find_printer->dev.handlename )); + continue; + } + + + /* lookup the printer if we have a name if we don't already have a + valid NT_PRINTER_INFO_LEVEL structure. And yes I'm assuming we + will always have a non-empty msg.printer_name */ + + if (!printer || !printer->info_2 || strcmp(msg->printer_name, printer->info_2->printername)) + { + + if (printer) { + free_a_printer(&printer, 2); + printer = NULL; + } + + wresult = get_a_printer(&printer, 2, msg->printer_name); + if (! W_ERROR_IS_OK(wresult)) + continue; + } + + /* issue the client call */ + + result = srv_spoolss_send_event_to_client(find_printer, &cli, msg, printer); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(10,("send_spoolss_event_notification: Event notification failed [%s]\n", + get_nt_error_msg(result))); } } } + return; +} +/*************************************************************************** + Receive the notify message and decode the message. Do not send + notification if we sent this originally as that would result in + duplicates. +****************************************************************************/ + +static void srv_spoolss_receive_message(int msg_type, pid_t src, void *buf, size_t len) +{ + PRINTER_MESSAGE_INFO msg; + pid_t my_pid = sys_getpid(); + + if (len < sizeof(msg)) { + DEBUG(2,("srv_spoolss_receive_message: got incorrect message size (%u)!\n", (unsigned int)len)); + return; + } + + memcpy(&msg, buf, sizeof(PRINTER_MESSAGE_INFO)); + + if (my_pid == src) { + DEBUG(10,("srv_spoolss_receive_message: Skipping message to myself\n")); + return; + } + + DEBUG(10,("srv_spoolss_receive_message: Got message printer change [queue = %s] low=0x%x high=0x%x flags=0x%x\n", + msg.printer_name, (unsigned int)msg.low, (unsigned int)msg.high, msg.flags )); + + /* Iterate the printer list */ + + send_spoolss_event_notification(&msg); + +} + /*************************************************************************** Send a notify event. ****************************************************************************/ -static BOOL srv_spoolss_sendnotify(uint32 high, uint32 low) +static BOOL srv_spoolss_sendnotify(char* printer_name, uint32 high, uint32 low, uint32 flags) { - char msg[10]; + char msg[sizeof(PRINTER_MESSAGE_INFO)]; + PRINTER_MESSAGE_INFO info; + + ZERO_STRUCT(info); - ZERO_STRUCT(msg); - SIVAL(msg,0,low); - SIVAL(msg,4,high); - DEBUG(10,("srv_spoolss_sendnotify: printer change low=0x%x high=0x%x\n", low, high)); + info.low = low; + info.high = high; + info.flags = flags; + fstrcpy(info.printer_name, printer_name); + + memcpy(msg, &info, sizeof(PRINTER_MESSAGE_INFO)); + + DEBUG(10,("srv_spoolss_sendnotify: printer change low=0x%x high=0x%x [%s], flags=0x%x\n", + low, high, printer_name, flags)); + + message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, msg, sizeof(PRINTER_MESSAGE_INFO), + False, NULL); - message_send_all(conn_tdb_ctx(), MSG_PRINTER_NOTIFY, msg, sizeof(msg), False, NULL); return True; } @@ -707,6 +875,8 @@ Can't find printer handle we created for priunter %s\n", name )); if (!get_printer_snum(p, handle, &snum)) return WERR_BADFID; + se_map_standard(&printer_default->access_required, &printer_std_mapping); + /* map an empty access mask to the minimum access mask */ if (printer_default->access_required == 0x0) printer_default->access_required = PRINTER_ACCESS_USE; @@ -993,10 +1163,10 @@ WERROR _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL result = delete_printer_handle(p, handle); - update_c_setprinter(FALSE); + update_c_setprinter(False); if (W_ERROR_IS_OK(result)) { - srv_spoolss_sendnotify(0, PRINTER_CHANGE_DELETE_PRINTER); + srv_spoolss_sendnotify(Printer->dev.handlename, 0, PRINTER_CHANGE_DELETE_PRINTER, 0x0); } return result; @@ -1294,7 +1464,7 @@ WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uint32 type, POLICY_HND *handle) { - WERROR status; + NTSTATUS result; /* * If it's the first connection, contact the client @@ -1313,10 +1483,10 @@ static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uin smb_connections++; - if(!cli_spoolss_reply_open_printer(&cli, printer, localprinter, type, &status, handle)) - return False; + result = cli_spoolss_reply_open_printer(&cli, cli.mem_ctx, printer, localprinter, + type, handle); - return True; + return (NT_STATUS_IS_OK(result)); } /******************************************************************** @@ -1364,7 +1534,9 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE if(srv_spoolss_replyopenprinter(Printer->notify.localmachine, Printer->notify.printerlocal, 1, &Printer->notify.client_hnd)) + { Printer->notify.client_connected=True; + } return WERR_OK; } @@ -1373,7 +1545,7 @@ WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNE * fill a notify_info_data with the servername ********************************************************************/ -static void spoolss_notify_server_name(int snum, +void spoolss_notify_server_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, @@ -1401,7 +1573,7 @@ static void spoolss_notify_server_name(int snum, * fill a notify_info_data with the printername (not including the servername). ********************************************************************/ -static void spoolss_notify_printer_name(int snum, +void spoolss_notify_printer_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, @@ -1436,7 +1608,7 @@ static void spoolss_notify_printer_name(int snum, * fill a notify_info_data with the servicename ********************************************************************/ -static void spoolss_notify_share_name(int snum, +void spoolss_notify_share_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, @@ -1462,7 +1634,7 @@ static void spoolss_notify_share_name(int snum, * fill a notify_info_data with the port name ********************************************************************/ -static void spoolss_notify_port_name(int snum, +void spoolss_notify_port_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, @@ -1488,11 +1660,10 @@ static void spoolss_notify_port_name(int snum, /******************************************************************* * 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, +void spoolss_notify_driver_name(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, @@ -1517,7 +1688,7 @@ static void spoolss_notify_driver_name(int snum, * fill a notify_info_data with the comment ********************************************************************/ -static void spoolss_notify_comment(int snum, +void spoolss_notify_comment(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, @@ -1544,11 +1715,10 @@ static void spoolss_notify_comment(int snum, /******************************************************************* * 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, +void spoolss_notify_location(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, @@ -1585,11 +1755,9 @@ static void spoolss_notify_devmode(int snum, /******************************************************************* * 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, +void spoolss_notify_sepfile(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, @@ -1616,7 +1784,7 @@ static void spoolss_notify_sepfile(int snum, * jfm:xxxx return always winprint to indicate we don't do anything to it ********************************************************************/ -static void spoolss_notify_print_processor(int snum, +void spoolss_notify_print_processor(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, @@ -1643,7 +1811,7 @@ static void spoolss_notify_print_processor(int snum, * jfm:xxxx send an empty string ********************************************************************/ -static void spoolss_notify_parameters(int snum, +void spoolss_notify_parameters(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, @@ -1670,7 +1838,7 @@ static void spoolss_notify_parameters(int snum, * jfm:xxxx always send RAW as data type ********************************************************************/ -static void spoolss_notify_datatype(int snum, +void spoolss_notify_datatype(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, @@ -1713,7 +1881,7 @@ static void spoolss_notify_security_desc(int snum, * jfm:xxxx a samba printer is always shared ********************************************************************/ -static void spoolss_notify_attributes(int snum, +void spoolss_notify_attributes(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, @@ -1800,7 +1968,7 @@ static void spoolss_notify_status(int snum, * fill a notify_info_data with the number of jobs queued ********************************************************************/ -static void spoolss_notify_cjobs(int snum, +void spoolss_notify_cjobs(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_queue_struct *queue, NT_PRINTER_INFO_LEVEL *printer, @@ -1839,7 +2007,7 @@ static void spoolss_notify_username(int snum, pstring temp; uint32 len; - len = rpcstr_push(temp, queue->user, sizeof(temp)-2, STR_TERMINATE); + len = rpcstr_push(temp, queue->fs_user, sizeof(temp)-2, STR_TERMINATE); data->notify_data.data.length = len / 2 - 1; data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len); @@ -1879,7 +2047,7 @@ static void spoolss_notify_job_name(int snum, pstring temp; uint32 len; - len = rpcstr_push(temp, queue->file, sizeof(temp)-2, STR_TERMINATE); + len = rpcstr_push(temp, queue->fs_file, sizeof(temp)-2, STR_TERMINATE); data->notify_data.data.length = len / 2 - 1; data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len); @@ -2169,7 +2337,7 @@ static int search_notify(uint16 type, uint16 field, int *value) /**************************************************************************** ****************************************************************************/ -static void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id) +void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id) { info_data->type = type; info_data->field = field; @@ -2397,7 +2565,7 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY return WERR_BADFID; option=Printer->notify.option; - id=0xffffffff; + id = 0x0; info->version=2; info->data=NULL; info->count=0; @@ -2585,8 +2753,13 @@ static BOOL construct_printer_info_0(PRINTER_INFO_0 *printer, int snum) printer->global_counter = global_counter; printer->total_pages = 0; +#if 0 /* JERRY */ printer->major_version = 0x0004; /* NT 4 */ printer->build_version = 0x0565; /* build 1381 */ +#else + printer->major_version = 0x0005; /* NT 5 */ + printer->build_version = 0x0893; /* build 2195 */ +#endif printer->unknown7 = 0x1; printer->unknown8 = 0x0; printer->unknown9 = 0x0; @@ -4362,9 +4535,9 @@ static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum) /* we force some elements to "correct" values */ slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", get_called_name()); - slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s", - get_called_name(), lp_servicename(snum)); fstrcpy(info->sharename, lp_servicename(snum)); + slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s", + get_called_name(), info->sharename); info->attributes = PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK; return True; @@ -4686,10 +4859,13 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level, int snum; NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL; Printer_entry *Printer = find_printer_index_by_hnd(p, handle); + PRINTER_MESSAGE_INFO msg; WERROR result; DEBUG(8,("update_printer\n")); + ZERO_STRUCT(msg); + result = WERR_OK; if (level!=2) { @@ -4802,18 +4978,49 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level, * lookup previously saved driver initialization info, which is then * bound to the printer, simulating what happens in the Windows arch. */ - if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)) + if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)){ set_driver_init(printer, 2); + msg.flags |= PRINTER_MESSAGE_DRIVER; + } } /* Update printer info */ result = mod_a_printer(*printer, 2); + /* flag which changes actually occured. This is a small subset of + all the possible changes */ + + if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) + msg.flags |= PRINTER_MESSAGE_COMMENT; + + if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) + msg.flags |= PRINTER_MESSAGE_SHARENAME; + + if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) + msg.flags |= PRINTER_MESSAGE_PORT; + + if (!strequal(printer->info_2->location, old_printer->info_2->location)) + msg.flags |= PRINTER_MESSAGE_LOCATION; + + ZERO_STRUCT(msg); + + msg.low = PRINTER_CHANGE_ADD_PRINTER; + fstrcpy(msg.printer_name, printer->info_2->printername); + + /* only send a notify if something changed */ + if (msg.flags) + { + /* send to myself before replying to SetPrinter() */ + send_spoolss_event_notification(&msg); + + /* send to other smbd's */ + srv_spoolss_sendnotify(msg.printer_name, 0, PRINTER_CHANGE_ADD_PRINTER, msg.flags); + } + done: free_a_printer(&printer, 2); free_a_printer(&old_printer, 2); - srv_spoolss_sendnotify(0, PRINTER_CHANGE_SET_PRINTER); return result; } @@ -4910,8 +5117,8 @@ static void fill_job_info_1(JOB_INFO_1 *job_info, print_queue_struct *queue, 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->username, queue->fs_user); + init_unistr(&job_info->document, queue->fs_file); init_unistr(&job_info->datatype, "RAW"); init_unistr(&job_info->text_status, ""); job_info->status=nt_printj_status(queue->status); @@ -4945,9 +5152,9 @@ static BOOL fill_job_info_2(JOB_INFO_2 *job_info, print_queue_struct *queue, 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->username, queue->fs_user); + init_unistr(&job_info->document, queue->fs_file); + init_unistr(&job_info->notifyname, queue->fs_user); init_unistr(&job_info->datatype, "RAW"); init_unistr(&job_info->printprocessor, "winprint"); init_unistr(&job_info->parameters, ""); @@ -5070,6 +5277,7 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum, } if (!alloc_buffer_size(buffer, *needed)) { + SAFE_FREE(info); result = WERR_INSUFFICIENT_BUFFER; goto done; } @@ -6031,11 +6239,12 @@ static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_ return WERR_ACCESS_DENIED; } + srv_spoolss_sendnotify(printer->info_2->printername, 0, PRINTER_CHANGE_ADD_PRINTER, 0x0); + free_a_printer(&printer,2); update_c_setprinter(False); - srv_spoolss_sendnotify(0, PRINTER_CHANGE_ADD_PRINTER); return WERR_OK; } @@ -6128,9 +6337,7 @@ static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen pstring long_archi; pstring short_archi; DRIVER_DIRECTORY_1 *info=NULL; -#if 0 - fstring asc_name, servername; -#endif + unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1); if (get_short_archi(short_archi, long_archi)==False) @@ -6139,20 +6346,6 @@ static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL) return WERR_NOMEM; -#if 0 /* JERRY */ - /* use the name the client sent us */ - - unistr2_to_ascii(asc_name, name, sizeof(asc_name)-1); - if (asc_name[0] == '\\' && asc_name[1] == '\\') - fstrcpy(servername, asc_name); - else { - fstrcpy(servername, "\\\\"); - fstrcat(servername, asc_name); - } - - slprintf(path, sizeof(path)-1, "%s\\print$\\%s", servername, short_archi); -#endif - slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", get_called_name(), short_archi); DEBUG(4,("printer driver directory: [%s]\n", path)); @@ -6428,24 +6621,6 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP convert_specific_param(¶m, value , type, data, real_len); -#if 0 - /* JRA. W2K always changes changeid. */ - - if (get_specific_param(*printer, 2, param->value, &old_param.data, - &old_param.type, (uint32 *)&old_param.data_len)) { - - if (param->type == old_param.type && - param->data_len == old_param.data_len && - memcmp(param->data, old_param.data, - old_param.data_len) == 0) { - - DEBUG(3, ("setprinterdata hasn't changed\n")); - status = WERR_OK; - goto done; - } - } -#endif - unlink_specific_param_if_exist(printer->info_2, param); /* @@ -6470,17 +6645,18 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP free_nt_printer_param(¶m); SAFE_FREE(old_param.data); -#if 0 - /* Is this correct. JRA ? */ - srv_spoolss_sendnotify(0, PRINTER_CHANGE_SET_PRINTER); -#endif - return status; } /**************************************************************************** ****************************************************************************/ +WERROR _spoolss_resetprinter(pipes_struct *p, SPOOL_Q_RESETPRINTER *q_u, SPOOL_R_RESETPRINTER *r_u) +{ + return WERR_OK; +} + + WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_u, SPOOL_R_DELETEPRINTERDATA *r_u) { POLICY_HND *handle = &q_u->handle; @@ -7025,7 +7201,6 @@ static WERROR getjob_level_2(print_queue_struct *queue, int count, int snum, uin ret = get_a_printer(&ntprinter, 2, lp_servicename(snum)); if (!W_ERROR_IS_OK(ret)) goto done; - if (construct_dev_mode(snum) == NULL) { ret = WERR_NOMEM; goto done; @@ -7371,27 +7546,6 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_ enum_values[num_entries].value_len = (strlen(value)+1) * 2; enum_values[num_entries].type = type; -#if 0 /* JERRY - I think think was a bad assumption based on bad - offset values when I first implemented it. Commented out. - We should not be adding an extra NULL to the end of a string - just send what the client set in the first place. */ - /* - * NULL terminate REG_SZ - * FIXME!!! We should not be correctly problems in the way - * we store PrinterData here. Need to investogate - * SetPrinterData[Ex] --jerry - */ - - if (type == REG_SZ) { - /* fix alignment if the string was stored - in a bizarre fashion */ - if ((data_len % 2) == 0) - add_len = 2; - else - add_len = data_len % 2; - } -#endif - if (!(enum_values[num_entries].data=talloc_zero(p->mem_ctx, data_len+add_len))) { DEBUG(0,("talloc_realloc failed to allocate more memory for data!\n")); result = WERR_NOMEM; @@ -7433,11 +7587,6 @@ done: /**************************************************************************** ****************************************************************************/ -/* Disabled because it doesn't fix the bug I am looking at but it would be - a shame to throw away the code. -tpot */ - -#if 0 - static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, char *name) { init_unistr(&info->name, name); @@ -7515,4 +7664,3 @@ WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROC return WERR_ACCESS_DENIED; } -#endif diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index 5bf7bb89e3..a218a04962 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -445,7 +445,7 @@ static void fill_printjob_info(connection_struct *conn, int snum, int uLevel, PACKI(desc,"W",queue->job); /* uJobId */ if (uLevel == 1) { - PACKS(desc,"B21",queue->user); /* szUserName */ + PACKS(desc,"B21",queue->fs_user); /* szUserName */ PACKS(desc,"B",""); /* pad */ PACKS(desc,"B16",""); /* szNotifyName */ PACKS(desc,"B10","PM_Q_RAW"); /* szDataType */ @@ -455,17 +455,17 @@ static void fill_printjob_info(connection_struct *conn, int snum, int uLevel, PACKS(desc,"z",""); /* pszStatus */ PACKI(desc,"D",t); /* ulSubmitted */ PACKI(desc,"D",queue->size); /* ulSize */ - PACKS(desc,"z",queue->file); /* pszComment */ + PACKS(desc,"z",queue->fs_file); /* pszComment */ } if (uLevel == 2 || uLevel == 3 || uLevel == 4) { PACKI(desc,"W",queue->priority); /* uPriority */ - PACKS(desc,"z",queue->user); /* pszUserName */ + PACKS(desc,"z",queue->fs_user); /* pszUserName */ PACKI(desc,"W",n+1); /* uPosition */ PACKI(desc,"W",printj_status(queue->status)); /* fsStatus */ PACKI(desc,"D",t); /* ulSubmitted */ PACKI(desc,"D",queue->size); /* ulSize */ PACKS(desc,"z","Samba"); /* pszComment */ - PACKS(desc,"z",queue->file); /* pszDocument */ + PACKS(desc,"z",queue->fs_file); /* pszDocument */ if (uLevel == 3) { PACKS(desc,"z",""); /* pszNotifyName */ PACKS(desc,"z","PM_Q_RAW"); /* pszDataType */ diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 8f6ff9cb34..e72b6a7319 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -2605,7 +2605,7 @@ int reply_printqueue(connection_struct *conn, SSVAL(p,5, queue[i].job); SIVAL(p,7,queue[i].size); SCVAL(p,11,0); - srvstr_push(outbuf, p+12, queue[i].user, 16, STR_ASCII); + srvstr_push(outbuf, p+12, queue[i].fs_user, 16, STR_ASCII); p += 28; } |