syncing up printing code with SAMBA_2_2 (already done some merges
authorGerald Carter <jerry@samba.org>
Fri, 15 Mar 2002 08:14:10 +0000 (08:14 +0000)
committerGerald Carter <jerry@samba.org>
Fri, 15 Mar 2002 08:14:10 +0000 (08:14 +0000)
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)

13 files changed:
source3/include/rpc_secdes.h
source3/include/rpc_spoolss.h
source3/include/smb.h
source3/lib/util_seaccess.c
source3/printing/lpq_parse.c
source3/printing/nt_printing.c
source3/printing/printing.c
source3/rpc_client/cli_spoolss_notify.c
source3/rpc_parse/parse_spoolss.c
source3/rpc_server/srv_spoolss.c
source3/rpc_server/srv_spoolss_nt.c
source3/smbd/lanman.c
source3/smbd/reply.c

index 8304530e08a0a318ef70228179d7de1e4295f32b..e51a5fd2f8fc44d0584a7ed56f14ac3e72a6a44f 100644 (file)
@@ -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 */
index f41a656fa67b6ce55822d0cf283b43a3bbdb71e3..22606b2f30aa1658b751d9fe4f81d43210378e6f 100755 (executable)
@@ -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
 #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
 #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
 #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
 
 #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)
@@ -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;
index 1b6e280a4a14b8b11cf36b4a2531b9bb56604608..303b1f5efadb61517d3e0e62d006abb2bec6baa0 100644 (file)
@@ -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};
index 5a934789e4b879685e916ec3c394e392ceb5a299..299b339ddf6c47609bf992439cd905c18b3e94cc 100644 (file)
@@ -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
index b5138064739b752cee02d9bc60060cb9068974fc..13b87045cd528520c5fc6c7ae75ce33b9d937db9 100644 (file)
@@ -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++;
index 43667a674d0102bc5220d84d2acdad3665fc9636..4cd9a0ec91fc52d3820a58eeb1d9c5fbc997ca68 100644 (file)
@@ -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 */
index 758c855188a6121cfac0f33915cd4f0b885aa445..97eaaebcc4953ade79af31c96cb3cdc88253be47 100644 (file)
@@ -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++;
 
index c31d2fb387160d31f9f14db6172fa244e19cef4e..a3e7acb1c1a6d9676726cfd495f76e949cbafdc6 100644 (file)
  */
 
 #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;
 }
+
index a37893db9b9515f294599a8839daded572d79df9..17af8394d820bd715aa3d399bb72e2e77d041c4d 100644 (file)
@@ -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;
        }
@@ -5655,6 +5646,24 @@ BOOL make_spoolss_q_enumprinterdata(SPOOL_Q_ENUMPRINTERDATA *q_u,
        return True;
 }
 
+/*******************************************************************
+********************************************************************/  
+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;
+}
 /*******************************************************************
 ********************************************************************/  
 
@@ -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++;
 
@@ -6097,6 +6142,73 @@ BOOL spoolss_io_r_replyopenprinter(char *desc, SPOOL_R_REPLYOPENPRINTER *r_u, pr
        return True;            
 }
 
+/*******************************************************************
+ * 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.
  ********************************************************************/
@@ -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
index 3f3c6039c9db44f0aeaec0d95d30a496b5c86c9b..3838632021606af80075b7280f6a104c696d89fb 100755 (executable)
@@ -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                },
index 3479e47f7699259c94f9f7b38e64f28a2297a9aa..a6c0f9368c5aa9384e294c0d58e1ab87d17b8fc8 100644 (file)
@@ -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
index 5bf7bb89e393b2c76d612e7f721b856c4452e55a..a218a049629138eecd8f931860403d01ee1462fe 100644 (file)
@@ -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 */
index 8f6ff9cb341882c1e2db4d7c36ad2bdfffb2cac7..e72b6a731912121addffe9a004a5c87289057fb6 100644 (file)
@@ -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;
                }