summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2002-03-15 08:14:10 +0000
committerGerald Carter <jerry@samba.org>2002-03-15 08:14:10 +0000
commit65c007b583e2107f5ad1ba6733d3e578a143863e (patch)
treea11e1da607580d291ce74926417126ce22f34852
parentd19e06c0c620046658621fcec7c2cda9a77ceac3 (diff)
downloadsamba-65c007b583e2107f5ad1ba6733d3e578a143863e.tar.gz
samba-65c007b583e2107f5ad1ba6733d3e578a143863e.tar.bz2
samba-65c007b583e2107f5ad1ba6733d3e578a143863e.zip
syncing up printing code with SAMBA_2_2 (already done some merges
in the reverse). * add in new printer change notify code from SAMBA_2_2 * add in se_map_standard() from 2.2 in _spoolss_open_printer_ex() * sync up the _print_queue_struct in smb.h (why did someone change the user/file names in fs_user/fs_file (or vice-versa) ? ) * sync up some cli_spoolss_XXX functions (This used to be commit 5760315c1de4033fdc22684c940f18010010924f)
-rw-r--r--source3/include/rpc_secdes.h7
-rwxr-xr-xsource3/include/rpc_spoolss.h120
-rw-r--r--source3/include/smb.h4
-rw-r--r--source3/lib/util_seaccess.c25
-rw-r--r--source3/printing/lpq_parse.c72
-rw-r--r--source3/printing/nt_printing.c66
-rw-r--r--source3/printing/printing.c12
-rw-r--r--source3/rpc_client/cli_spoolss_notify.c331
-rw-r--r--source3/rpc_parse/parse_spoolss.c273
-rwxr-xr-xsource3/rpc_server/srv_spoolss.c34
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c432
-rw-r--r--source3/smbd/lanman.c8
-rw-r--r--source3/smbd/reply.c2
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, &notify_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, &notify_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(&param, 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(&param);
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;
}