import HEAD into svn+ssh://svn.samba.org/home/svn/samba/trunk
[metze/old/v3-2-winbind-ndr.git] / source / rpc_server / srv_spoolss_nt.c
1 /*
2  *  Unix SMB/CIFS implementation.
3  *  RPC Pipe client / server routines
4  *  Copyright (C) Andrew Tridgell              1992-2000,
5  *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6  *  Copyright (C) Jean Fran├žois Micouleau      1998-2000,
7  *  Copyright (C) Jeremy Allison               2001-2002,
8  *  Copyright (C) Gerald Carter                2000-2003,
9  *  Copyright (C) Tim Potter                   2001-2002.
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License as published by
13  *  the Free Software Foundation; either version 2 of the License, or
14  *  (at your option) any later version.
15  *
16  *  This program is distributed in the hope that it will be useful,
17  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  *  GNU General Public License for more details.
20  *
21  *  You should have received a copy of the GNU General Public License
22  *  along with this program; if not, write to the Free Software
23  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  */
25
26 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
27    up, all the errors returned are DOS errors, not NT status codes. */
28
29 #include "includes.h"
30
31 #undef DBGC_CLASS
32 #define DBGC_CLASS DBGC_RPC_SRV
33
34 #ifndef MAX_OPEN_PRINTER_EXS
35 #define MAX_OPEN_PRINTER_EXS 50
36 #endif
37
38 #define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
39 #define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
40
41
42 /* Table to map the driver version */
43 /* to OS */
44 static const char * drv_ver_to_os[] = {
45         "WIN9X",   /* driver version/cversion 0 */
46         "",        /* unused ? */
47         "WINNT",   /* driver version/cversion 2 */
48         "WIN2K",   /* driver version/cversion 3 */
49 };
50
51 static const char *get_drv_ver_to_os(int ver)
52 {
53         if (ver < 0 || ver > 3)
54                 return "";
55         return drv_ver_to_os[ver];
56 }
57
58 struct table_node {
59         const char    *long_archi;
60         const char    *short_archi;
61         int     version;
62 };
63
64 static Printer_entry *printers_list;
65
66 typedef struct _counter_printer_0 {
67         ubi_dlNode Next;
68         ubi_dlNode Prev;
69         
70         int snum;
71         uint32 counter;
72 } counter_printer_0;
73
74 static ubi_dlList counter_list;
75
76 static struct cli_state notify_cli; /* print notify back-channel */
77 static uint32 smb_connections=0;
78
79
80 /* in printing/nt_printing.c */
81
82 extern STANDARD_MAPPING printer_std_mapping, printserver_std_mapping;
83
84 #define OUR_HANDLE(hnd) (((hnd)==NULL)?"NULL":(IVAL((hnd)->data5,4)==(uint32)sys_getpid()?"OURS":"OTHER")), \
85 ((unsigned int)IVAL((hnd)->data5,4)),((unsigned int)sys_getpid())
86
87 /* translate between internal status numbers and NT status numbers */
88 static int nt_printj_status(int v)
89 {
90         switch (v) {
91         case LPQ_QUEUED:
92                 return 0;
93         case LPQ_PAUSED:
94                 return JOB_STATUS_PAUSED;
95         case LPQ_SPOOLING:
96                 return JOB_STATUS_SPOOLING;
97         case LPQ_PRINTING:
98                 return JOB_STATUS_PRINTING;
99         case LPQ_ERROR:
100                 return JOB_STATUS_ERROR;
101         case LPQ_DELETING:
102                 return JOB_STATUS_DELETING;
103         case LPQ_OFFLINE:
104                 return JOB_STATUS_OFFLINE;
105         case LPQ_PAPEROUT:
106                 return JOB_STATUS_PAPEROUT;
107         case LPQ_PRINTED:
108                 return JOB_STATUS_PRINTED;
109         case LPQ_DELETED:
110                 return JOB_STATUS_DELETED;
111         case LPQ_BLOCKED:
112                 return JOB_STATUS_BLOCKED;
113         case LPQ_USER_INTERVENTION:
114                 return JOB_STATUS_USER_INTERVENTION;
115         }
116         return 0;
117 }
118
119 static int nt_printq_status(int v)
120 {
121         switch (v) {
122         case LPQ_PAUSED:
123                 return PRINTER_STATUS_PAUSED;
124         case LPQ_QUEUED:
125         case LPQ_SPOOLING:
126         case LPQ_PRINTING:
127                 return 0;
128         }
129         return 0;
130 }
131
132 /****************************************************************************
133  Functions to handle SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
134 ****************************************************************************/
135
136 static void free_spool_notify_option(SPOOL_NOTIFY_OPTION **pp)
137 {
138         if (*pp == NULL)
139                 return;
140
141         SAFE_FREE((*pp)->ctr.type);
142         SAFE_FREE(*pp);
143 }
144
145 /***************************************************************************
146  Disconnect from the client
147 ****************************************************************************/
148
149 static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle)
150 {
151         WERROR result;
152
153         /* 
154          * Tell the specific printing tdb we no longer want messages for this printer
155          * by deregistering our PID.
156          */
157
158         if (!print_notify_deregister_pid(snum))
159                 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
160
161         /* weird if the test succeds !!! */
162         if (smb_connections==0) {
163                 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
164                 return;
165         }
166
167         result = cli_spoolss_reply_close_printer(&notify_cli, notify_cli.mem_ctx, handle);
168         
169         if (!W_ERROR_IS_OK(result))
170                 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
171                         dos_errstr(result)));
172
173         /* if it's the last connection, deconnect the IPC$ share */
174         if (smb_connections==1) {
175                 cli_nt_session_close(&notify_cli);
176                 cli_ulogoff(&notify_cli);
177                 cli_shutdown(&notify_cli);
178                 message_deregister(MSG_PRINTER_NOTIFY2);
179
180                 /* Tell the connections db we're no longer interested in
181                  * printer notify messages. */
182
183                 register_message_flags( False, FLAG_MSG_PRINTING );
184         }
185
186         smb_connections--;
187 }
188
189 /****************************************************************************
190  Functions to free a printer entry datastruct.
191 ****************************************************************************/
192
193 static void free_printer_entry(void *ptr)
194 {
195         Printer_entry *Printer = (Printer_entry *)ptr;
196
197         if (Printer->notify.client_connected==True) {
198                 int snum = -1;
199
200                 if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) {
201                         snum = -1;
202                         srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
203                 } else if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTER) {
204                         snum = print_queue_snum(Printer->dev.handlename);
205                         if (snum != -1)
206                                 srv_spoolss_replycloseprinter(snum,
207                                                 &Printer->notify.client_hnd);
208                 }
209         }
210
211         Printer->notify.flags=0;
212         Printer->notify.options=0;
213         Printer->notify.localmachine[0]='\0';
214         Printer->notify.printerlocal=0;
215         free_spool_notify_option(&Printer->notify.option);
216         Printer->notify.option=NULL;
217         Printer->notify.client_connected=False;
218         
219         free_nt_devicemode( &Printer->nt_devmode );
220         free_a_printer( &Printer->printer_info, 2 );
221         
222         talloc_destroy( Printer->ctx );
223
224         /* Remove from the internal list. */
225         DLIST_REMOVE(printers_list, Printer);
226
227         SAFE_FREE(Printer);
228 }
229
230 /****************************************************************************
231  Functions to duplicate a SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
232 ****************************************************************************/
233
234 static SPOOL_NOTIFY_OPTION *dup_spool_notify_option(SPOOL_NOTIFY_OPTION *sp)
235 {
236         SPOOL_NOTIFY_OPTION *new_sp = NULL;
237
238         if (!sp)
239                 return NULL;
240
241         new_sp = (SPOOL_NOTIFY_OPTION *)malloc(sizeof(SPOOL_NOTIFY_OPTION));
242         if (!new_sp)
243                 return NULL;
244
245         *new_sp = *sp;
246
247         if (sp->ctr.count) {
248                 new_sp->ctr.type = (SPOOL_NOTIFY_OPTION_TYPE *)memdup(sp->ctr.type, sizeof(SPOOL_NOTIFY_OPTION_TYPE) * sp->ctr.count);
249
250                 if (!new_sp->ctr.type) {
251                         SAFE_FREE(new_sp);
252                         return NULL;
253                 }
254         }
255
256         return new_sp;
257 }
258
259 /****************************************************************************
260   find printer index by handle
261 ****************************************************************************/
262
263 static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd)
264 {
265         Printer_entry *find_printer = NULL;
266
267         if(!find_policy_by_hnd(p,hnd,(void **)&find_printer)) {
268                 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
269                 return NULL;
270         }
271
272         return find_printer;
273 }
274
275 /****************************************************************************
276  look for a printer object cached on an open printer handle
277 ****************************************************************************/
278
279 WERROR find_printer_in_print_hnd_cache( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL_2 **info2, 
280                                         const char *printername )
281 {
282         Printer_entry *p;
283         
284         DEBUG(10,("find_printer_in_print_hnd_cache: printer [%s]\n", printername));
285
286         for ( p=printers_list; p; p=p->next )
287         {
288                 if ( p->printer_type==PRINTER_HANDLE_IS_PRINTER 
289                         && p->printer_info
290                         && StrCaseCmp(p->dev.handlename, printername) == 0 )
291                 {
292                         DEBUG(10,("Found printer\n"));
293                         *info2 = dup_printer_2( ctx, p->printer_info->info_2 );
294                         if ( *info2 )
295                                 return WERR_OK;
296                 }
297         }
298
299         return WERR_INVALID_PRINTER_NAME;
300 }
301
302 /****************************************************************************
303   destroy any cached printer_info_2 structures on open handles
304 ****************************************************************************/
305
306 void invalidate_printer_hnd_cache( char *printername )
307 {
308         Printer_entry *p;
309         
310         DEBUG(10,("invalidate_printer_hnd_cache: printer [%s]\n", printername));
311
312         for ( p=printers_list; p; p=p->next )
313         {
314                 if ( p->printer_type==PRINTER_HANDLE_IS_PRINTER 
315                         && StrCaseCmp(p->dev.handlename, printername)==0)
316                 {
317                         DEBUG(10,("invalidating printer_info cache for handl:\n"));
318                         free_a_printer( &p->printer_info, 2 );
319                         p->printer_info = NULL;
320                 }
321         }
322
323         return;
324 }
325 /****************************************************************************
326  Close printer index by handle.
327 ****************************************************************************/
328
329 static BOOL close_printer_handle(pipes_struct *p, POLICY_HND *hnd)
330 {
331         Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
332
333         if (!Printer) {
334                 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
335                 return False;
336         }
337
338         close_policy_hnd(p, hnd);
339
340         return True;
341 }       
342
343 /****************************************************************************
344  Delete a printer given a handle.
345 ****************************************************************************/
346
347 static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
348 {
349         Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
350
351         if (!Printer) {
352                 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
353                 return WERR_BADFID;
354         }
355
356         /* 
357          * It turns out that Windows allows delete printer on a handle
358          * opened by an admin user, then used on a pipe handle created
359          * by an anonymous user..... but they're working on security.... riiight !
360          * JRA.
361          */
362
363         if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
364                 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
365                 return WERR_ACCESS_DENIED;
366         }
367
368 #if 0
369         /* Check calling user has permission to delete printer.  Note that
370            since we set the snum parameter to -1 only administrators can
371            delete the printer.  This stops people with the Full Control
372            permission from deleting the printer. */
373
374         if (!print_access_check(NULL, -1, PRINTER_ACCESS_ADMINISTER)) {
375                 DEBUG(3, ("printer delete denied by security descriptor\n"));
376                 return WERR_ACCESS_DENIED;
377         }
378 #endif
379
380         if (del_a_printer(Printer->dev.handlename) != 0) {
381                 DEBUG(3,("Error deleting printer %s\n", Printer->dev.handlename));
382                 return WERR_BADFID;
383         }
384
385         if (*lp_deleteprinter_cmd()) {
386
387                 char *cmd = lp_deleteprinter_cmd();
388                 pstring command;
389                 int ret;
390
391                 /* Printer->dev.handlename equals portname equals sharename */
392                 slprintf(command, sizeof(command)-1, "%s \"%s\"", cmd,
393                                         Printer->dev.handlename);
394
395                 DEBUG(10,("Running [%s]\n", command));
396                 ret = smbrun(command, NULL);
397                 if (ret != 0) {
398                         return WERR_BADFID; /* What to return here? */
399                 }
400                 DEBUGADD(10,("returned [%d]\n", ret));
401
402                 /* Send SIGHUP to process group... is there a better way? */
403                 kill(0, SIGHUP);
404
405                 /* go ahead and re-read the services immediately */
406                 reload_services( False );
407
408                 if ( lp_servicenumber( Printer->dev.handlename )  < 0 )
409                         return WERR_ACCESS_DENIED;
410         }
411
412         return WERR_OK;
413 }
414
415 /****************************************************************************
416  Return the snum of a printer corresponding to an handle.
417 ****************************************************************************/
418
419 static BOOL get_printer_snum(pipes_struct *p, POLICY_HND *hnd, int *number)
420 {
421         Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
422                 
423         if (!Printer) {
424                 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
425                 return False;
426         }
427         
428         switch (Printer->printer_type) {
429         case PRINTER_HANDLE_IS_PRINTER:         
430                 DEBUG(4,("short name:%s\n", Printer->dev.handlename));                  
431                 *number = print_queue_snum(Printer->dev.handlename);
432                 return (*number != -1);
433         case PRINTER_HANDLE_IS_PRINTSERVER:
434                 return False;
435         default:
436                 return False;
437         }
438 }
439
440 /****************************************************************************
441  Set printer handle type.
442  Check if it's \\server or \\server\printer
443 ****************************************************************************/
444
445 static BOOL set_printer_hnd_printertype(Printer_entry *Printer, char *handlename)
446 {
447         DEBUG(3,("Setting printer type=%s\n", handlename));
448
449         if ( strlen(handlename) < 3 ) {
450                 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
451                 return False;
452         }
453
454         /* it's a print server */
455         if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
456                 DEBUGADD(4,("Printer is a print server\n"));
457                 Printer->printer_type = PRINTER_HANDLE_IS_PRINTSERVER;          
458         }
459         /* it's a printer */
460         else {
461                 DEBUGADD(4,("Printer is a printer\n"));
462                 Printer->printer_type = PRINTER_HANDLE_IS_PRINTER;
463         }
464
465         return True;
466 }
467
468 /****************************************************************************
469  Set printer handle name.
470 ****************************************************************************/
471
472 static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
473 {
474         int snum;
475         int n_services=lp_numservices();
476         char *aprinter;
477         fstring sname;
478         BOOL found=False;
479         
480         DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename)));
481
482         if (Printer->printer_type==PRINTER_HANDLE_IS_PRINTSERVER) {
483                 ZERO_STRUCT(Printer->dev.printerservername);
484                 strncpy(Printer->dev.printerservername, handlename, strlen(handlename));
485                 return True;
486         }
487
488         if (Printer->printer_type!=PRINTER_HANDLE_IS_PRINTER)
489                 return False;
490         
491         if (*handlename=='\\') {
492                 aprinter=strchr_m(handlename+2, '\\');
493                 aprinter++;
494         }
495         else {
496                 aprinter=handlename;
497         }
498
499         DEBUGADD(5,("searching for [%s] (len=%lu)\n", aprinter, (unsigned long)strlen(aprinter)));
500
501         /*
502          * The original code allowed smbd to store a printer name that
503          * was different from the share name.  This is not possible 
504          * anymore, so I've simplified this loop greatly.  Here
505          * we are just verifying that the printer name is a valid
506          * printer service defined in smb.conf
507          *                          --jerry [Fri Feb 15 11:17:46 CST 2002]
508          */
509
510         for (snum=0; snum<n_services; snum++) {
511
512                 if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
513                         continue;
514                 
515                 fstrcpy(sname, lp_servicename(snum));
516
517                 DEBUGADD(5,("share:%s\n",sname));
518                 
519                 if (! StrCaseCmp(sname, aprinter)) {
520                         found = True;
521                         break;
522                 }
523
524         }
525
526                 
527         if (!found) {
528                 DEBUGADD(4,("Printer not found\n"));
529                 return False;
530         }
531         
532         DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
533
534         ZERO_STRUCT(Printer->dev.handlename);
535         fstrcpy(Printer->dev.handlename, sname);
536
537         return True;
538 }
539
540 /****************************************************************************
541  Find first available printer slot. creates a printer handle for you.
542  ****************************************************************************/
543
544 static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint32 access_granted)
545 {
546         Printer_entry *new_printer;
547
548         DEBUG(10,("open_printer_hnd: name [%s]\n", name));
549
550         if((new_printer=(Printer_entry *)malloc(sizeof(Printer_entry))) == NULL)
551                 return False;
552
553         ZERO_STRUCTP(new_printer);
554         
555         if (!create_policy_hnd(p, hnd, free_printer_entry, new_printer)) {
556                 SAFE_FREE(new_printer);
557                 return False;
558         }
559         
560         /* Add to the internal list. */
561         DLIST_ADD(printers_list, new_printer);
562         
563         new_printer->notify.option=NULL;
564                                 
565         if ( !(new_printer->ctx = talloc_init("Printer Entry [%p]", hnd)) ) {
566                 DEBUG(0,("open_printer_hnd: talloc_init() failed!\n"));
567                 close_printer_handle(p, hnd);
568                 return False;
569         }
570         
571         if (!set_printer_hnd_printertype(new_printer, name)) {
572                 close_printer_handle(p, hnd);
573                 return False;
574         }
575         
576         if (!set_printer_hnd_name(new_printer, name)) {
577                 close_printer_handle(p, hnd);
578                 return False;
579         }
580
581         new_printer->access_granted = access_granted;
582
583         DEBUG(5, ("%d printer handles active\n", (int)p->pipe_handles->count ));
584
585         return True;
586 }
587
588 /****************************************************************************
589  Allocate more memory for a BUFFER.
590 ****************************************************************************/
591
592 static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
593 {
594         prs_struct *ps;
595         uint32 extra_space;
596         uint32 old_offset;
597         
598         ps= &buffer->prs;
599
600         /* damn, I'm doing the reverse operation of prs_grow() :) */
601         if (buffer_size < prs_data_size(ps))
602                 extra_space=0;
603         else    
604                 extra_space = buffer_size - prs_data_size(ps);
605
606         /*
607          * save the offset and move to the end of the buffer
608          * prs_grow() checks the extra_space against the offset
609          */
610         old_offset=prs_offset(ps);      
611         prs_set_offset(ps, prs_data_size(ps));
612         
613         if (!prs_grow(ps, extra_space))
614                 return False;
615
616         prs_set_offset(ps, old_offset);
617
618         buffer->string_at_end=prs_data_size(ps);
619
620         return True;
621 }
622
623 /***************************************************************************
624  check to see if the client motify handle is monitoring the notification
625  given by (notify_type, notify_field).
626  **************************************************************************/
627
628 static BOOL is_monitoring_event_flags(uint32 flags, uint16 notify_type,
629                                       uint16 notify_field)
630 {
631         return True;
632 }
633
634 static BOOL is_monitoring_event(Printer_entry *p, uint16 notify_type,
635                                 uint16 notify_field)
636 {
637         SPOOL_NOTIFY_OPTION *option = p->notify.option;
638         uint32 i, j;
639
640         /* 
641          * Flags should always be zero when the change notify
642          * is registered by the client's spooler.  A user Win32 app
643          * might use the flags though instead of the NOTIFY_OPTION_INFO 
644          * --jerry
645          */
646          
647         if (p->notify.flags)
648                 return is_monitoring_event_flags(
649                         p->notify.flags, notify_type, notify_field);
650
651         for (i = 0; i < option->count; i++) {
652                 
653                 /* Check match for notify_type */
654                 
655                 if (option->ctr.type[i].type != notify_type)
656                         continue;
657
658                 /* Check match for field */
659                 
660                 for (j = 0; j < option->ctr.type[i].count; j++) {
661                         if (option->ctr.type[i].fields[j] == notify_field) {
662                                 return True;
663                         }
664                 }
665         }
666         
667         DEBUG(10, ("%s is not monitoring 0x%02x/0x%02x\n",
668                    (p->printer_type == PRINTER_HANDLE_IS_PRINTER) ?
669                    p->dev.handlename : p->dev.printerservername,
670                    notify_type, notify_field));
671         
672         return False;
673 }
674
675 /* Convert a notification message to a SPOOL_NOTIFY_INFO_DATA struct */
676
677 static void notify_one_value(struct spoolss_notify_msg *msg,
678                              SPOOL_NOTIFY_INFO_DATA *data,
679                              TALLOC_CTX *mem_ctx)
680 {
681         data->notify_data.value[0] = msg->notify.value[0];
682         data->notify_data.value[1] = 0;
683 }
684
685 static void notify_string(struct spoolss_notify_msg *msg,
686                           SPOOL_NOTIFY_INFO_DATA *data,
687                           TALLOC_CTX *mem_ctx)
688 {
689         UNISTR2 unistr;
690         
691         /* The length of the message includes the trailing \0 */
692
693         init_unistr2(&unistr, msg->notify.data, UNI_STR_TERMINATE);
694
695         data->notify_data.data.length = msg->len * 2;
696         data->notify_data.data.string = (uint16 *)talloc(mem_ctx, msg->len * 2);
697
698         if (!data->notify_data.data.string) {
699                 data->notify_data.data.length = 0;
700                 return;
701         }
702         
703         memcpy(data->notify_data.data.string, unistr.buffer, msg->len * 2);
704 }
705
706 static void notify_system_time(struct spoolss_notify_msg *msg,
707                                SPOOL_NOTIFY_INFO_DATA *data,
708                                TALLOC_CTX *mem_ctx)
709 {
710         SYSTEMTIME systime;
711         prs_struct ps;
712
713         if (msg->len != sizeof(time_t)) {
714                 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
715                           msg->len));
716                 return;
717         }
718
719         if (!prs_init(&ps, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) {
720                 DEBUG(5, ("notify_system_time: prs_init() failed\n"));
721                 return;
722         }
723
724         if (!make_systemtime(&systime, gmtime((time_t *)msg->notify.data))) {
725                 DEBUG(5, ("notify_system_time: unable to make systemtime\n"));
726                 return;
727         }
728
729         if (!spoolss_io_system_time("", &ps, 0, &systime))
730                 return;
731
732         data->notify_data.data.length = prs_offset(&ps);
733         data->notify_data.data.string = talloc(mem_ctx, prs_offset(&ps));
734
735         prs_copy_all_data_out((char *)data->notify_data.data.string, &ps);
736
737         prs_mem_free(&ps);
738 }
739
740 struct notify2_message_table {
741         const char *name;
742         void (*fn)(struct spoolss_notify_msg *msg,
743                    SPOOL_NOTIFY_INFO_DATA *data, TALLOC_CTX *mem_ctx);
744 };
745
746 static struct notify2_message_table printer_notify_table[] = {
747         /* 0x00 */ { "PRINTER_NOTIFY_SERVER_NAME", notify_string },
748         /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", notify_string },
749         /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", notify_string },
750         /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", notify_string },
751         /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", notify_string },
752         /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", notify_string },
753         /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", notify_string },
754         /* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL },
755         /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", notify_string },
756         /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", notify_string },
757         /* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL },
758         /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", notify_string },
759         /* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL },
760         /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", notify_one_value },
761         /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", notify_one_value },
762         /* 0x0f */ { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL },
763         /* 0x10 */ { "PRINTER_NOTIFY_START_TIME", NULL },
764         /* 0x11 */ { "PRINTER_NOTIFY_UNTIL_TIME", NULL },
765         /* 0x12 */ { "PRINTER_NOTIFY_STATUS", notify_one_value },
766 };
767
768 static struct notify2_message_table job_notify_table[] = {
769         /* 0x00 */ { "JOB_NOTIFY_PRINTER_NAME", NULL },
770         /* 0x01 */ { "JOB_NOTIFY_MACHINE_NAME", NULL },
771         /* 0x02 */ { "JOB_NOTIFY_PORT_NAME", NULL },
772         /* 0x03 */ { "JOB_NOTIFY_USER_NAME", notify_string },
773         /* 0x04 */ { "JOB_NOTIFY_NOTIFY_NAME", NULL },
774         /* 0x05 */ { "JOB_NOTIFY_DATATYPE", NULL },
775         /* 0x06 */ { "JOB_NOTIFY_PRINT_PROCESSOR", NULL },
776         /* 0x07 */ { "JOB_NOTIFY_PARAMETERS", NULL },
777         /* 0x08 */ { "JOB_NOTIFY_DRIVER_NAME", NULL },
778         /* 0x09 */ { "JOB_NOTIFY_DEVMODE", NULL },
779         /* 0x0a */ { "JOB_NOTIFY_STATUS", notify_one_value },
780         /* 0x0b */ { "JOB_NOTIFY_STATUS_STRING", NULL },
781         /* 0x0c */ { "JOB_NOTIFY_SECURITY_DESCRIPTOR", NULL },
782         /* 0x0d */ { "JOB_NOTIFY_DOCUMENT", notify_string },
783         /* 0x0e */ { "JOB_NOTIFY_PRIORITY", NULL },
784         /* 0x0f */ { "JOB_NOTIFY_POSITION", NULL },
785         /* 0x10 */ { "JOB_NOTIFY_SUBMITTED", notify_system_time },
786         /* 0x11 */ { "JOB_NOTIFY_START_TIME", NULL },
787         /* 0x12 */ { "JOB_NOTIFY_UNTIL_TIME", NULL },
788         /* 0x13 */ { "JOB_NOTIFY_TIME", NULL },
789         /* 0x14 */ { "JOB_NOTIFY_TOTAL_PAGES", notify_one_value },
790         /* 0x15 */ { "JOB_NOTIFY_PAGES_PRINTED", NULL },
791         /* 0x16 */ { "JOB_NOTIFY_TOTAL_BYTES", notify_one_value },
792         /* 0x17 */ { "JOB_NOTIFY_BYTES_PRINTED", NULL },
793 };
794
795
796 /***********************************************************************
797  Allocate talloc context for container object
798  **********************************************************************/
799  
800 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
801 {
802         if ( !ctr )
803                 return;
804
805         ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
806                 
807         return;
808 }
809
810 /***********************************************************************
811  release all allocated memory and zero out structure
812  **********************************************************************/
813  
814 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
815 {
816         if ( !ctr )
817                 return;
818
819         if ( ctr->ctx )
820                 talloc_destroy(ctr->ctx);
821                 
822         ZERO_STRUCTP(ctr);
823                 
824         return;
825 }
826
827 /***********************************************************************
828  **********************************************************************/
829  
830 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
831 {
832         if ( !ctr )
833                 return NULL;
834                 
835         return ctr->ctx;
836 }
837
838 /***********************************************************************
839  **********************************************************************/
840  
841 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
842 {
843         if ( !ctr || !ctr->msg_groups )
844                 return NULL;
845         
846         if ( idx >= ctr->num_groups )
847                 return NULL;
848                 
849         return &ctr->msg_groups[idx];
850
851 }
852
853 /***********************************************************************
854  How many groups of change messages do we have ?
855  **********************************************************************/
856  
857 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
858 {
859         if ( !ctr )
860                 return 0;
861                 
862         return ctr->num_groups;
863 }
864
865 /***********************************************************************
866  Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
867  **********************************************************************/
868  
869 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
870 {
871         SPOOLSS_NOTIFY_MSG_GROUP        *groups = NULL;
872         SPOOLSS_NOTIFY_MSG_GROUP        *msg_grp = NULL;
873         SPOOLSS_NOTIFY_MSG              *msg_list = NULL;
874         int                             i, new_slot;
875         
876         if ( !ctr || !msg )
877                 return 0;
878         
879         /* loop over all groups looking for a matching printer name */
880         
881         for ( i=0; i<ctr->num_groups; i++ ) {
882                 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
883                         break;
884         }
885         
886         /* add a new group? */
887         
888         if ( i == ctr->num_groups ) {
889                 ctr->num_groups++;
890
891                 if ( !(groups = talloc_realloc( ctr->ctx, ctr->msg_groups, sizeof(SPOOLSS_NOTIFY_MSG_GROUP)*ctr->num_groups)) ) {
892                         DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
893                         return 0;
894                 }
895                 ctr->msg_groups = groups;
896
897                 /* clear the new entry and set the printer name */
898                 
899                 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
900                 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
901         }
902         
903         /* add the change messages; 'i' is the correct index now regardless */
904         
905         msg_grp = &ctr->msg_groups[i];
906         
907         msg_grp->num_msgs++;
908         
909         if ( !(msg_list =  talloc_realloc( ctr->ctx, msg_grp->msgs, sizeof(SPOOLSS_NOTIFY_MSG)*msg_grp->num_msgs )) ) {
910                 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
911                 return 0;
912         }
913         msg_grp->msgs = msg_list;
914         
915         new_slot = msg_grp->num_msgs-1;
916         memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
917         
918         /* need to allocate own copy of data */
919         
920         if ( msg->len != 0 ) 
921                 msg_grp->msgs[new_slot].notify.data = talloc_memdup( ctr->ctx, msg->notify.data, msg->len );
922         
923         return ctr->num_groups;
924 }
925
926 /***********************************************************************
927  Send a change notication message on all handles which have a call 
928  back registered
929  **********************************************************************/
930
931 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
932 {
933         Printer_entry            *p;
934         TALLOC_CTX               *mem_ctx = notify_ctr_getctx( ctr );
935         SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
936         SPOOLSS_NOTIFY_MSG       *messages;
937         int                      sending_msg_count;
938         
939         if ( !msg_group ) {
940                 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
941                 return;
942         }
943         
944         messages = msg_group->msgs;
945         
946         if ( !messages ) {
947                 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
948                 return;
949         }
950         
951         DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
952         
953         /* loop over all printers */
954         
955         for (p = printers_list; p; p = p->next) {
956                 SPOOL_NOTIFY_INFO_DATA *data;
957                 uint32  data_len = 0;
958                 uint32  id;
959                 int     i;
960
961                 /* Is there notification on this handle? */
962
963                 if ( !p->notify.client_connected )
964                         continue;
965
966                 DEBUG(10,("Client connected! [%s]\n", p->dev.handlename));
967
968                 /* For this printer?  Print servers always receive 
969                    notifications. */
970
971                 if ( ( p->printer_type == PRINTER_HANDLE_IS_PRINTER )  &&
972                     ( !strequal(msg_group->printername, p->dev.handlename) ) )
973                         continue;
974
975                 DEBUG(10,("Our printer\n"));
976                 
977                 /* allocate the max entries possible */
978                 
979                 data = talloc( mem_ctx, msg_group->num_msgs*sizeof(SPOOL_NOTIFY_INFO_DATA) );
980                 ZERO_STRUCTP(data);
981                 
982                 /* build the array of change notifications */
983                 
984                 sending_msg_count = 0;
985                 
986                 for ( i=0; i<msg_group->num_msgs; i++ ) {
987                         SPOOLSS_NOTIFY_MSG      *msg = &messages[i];
988                         
989                         /* Are we monitoring this event? */
990
991                         if (!is_monitoring_event(p, msg->type, msg->field))
992                                 continue;
993
994                         sending_msg_count++;
995                         
996                         
997                         DEBUG(10,("process_notify2_message: Sending message type [%x] field [%x] for printer [%s]\n",
998                                 msg->type, msg->field, p->dev.handlename));
999
1000                         /* 
1001                          * if the is a printer notification handle and not a job notification 
1002                          * type, then set the id to 0.  Other wise just use what was specified
1003                          * in the message.  
1004                          *
1005                          * When registering change notification on a print server handle 
1006                          * we always need to send back the id (snum) matching the printer
1007                          * for which the change took place.  For change notify registered
1008                          * on a printer handle, this does not matter and the id should be 0.
1009                          *
1010                          * --jerry
1011                          */
1012
1013                         if ( ( p->printer_type == PRINTER_HANDLE_IS_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1014                                 id = 0;
1015                         else
1016                                 id = msg->id;
1017
1018
1019                         /* Convert unix jobid to smb jobid */
1020
1021                         if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1022                                 id = sysjob_to_jobid(msg->id);
1023
1024                                 if (id == -1) {
1025                                         DEBUG(3, ("no such unix jobid %d\n", msg->id));
1026                                         goto done;
1027                                 }
1028                         }
1029
1030                         construct_info_data( &data[data_len], msg->type, msg->field, id );
1031
1032                         switch(msg->type) {
1033                         case PRINTER_NOTIFY_TYPE:
1034                                 if ( printer_notify_table[msg->field].fn )
1035                                         printer_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);
1036                                 break;
1037                         
1038                         case JOB_NOTIFY_TYPE:
1039                                 if ( job_notify_table[msg->field].fn )
1040                                         job_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);
1041                                 break;
1042
1043                         default:
1044                                 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1045                                 goto done;
1046                         }
1047
1048                         data_len++;
1049                 }
1050
1051                 if ( sending_msg_count ) {
1052                         cli_spoolss_rrpcn( &notify_cli, mem_ctx, &p->notify.client_hnd, 
1053                                         data_len, data, p->notify.change, 0 );
1054                 }
1055         }
1056         
1057 done:
1058         DEBUG(8,("send_notify2_changes: Exit...\n"));
1059         return;
1060 }
1061
1062 /***********************************************************************
1063  **********************************************************************/
1064
1065 static BOOL notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1066 {
1067
1068         uint32 tv_sec, tv_usec;
1069         size_t offset = 0;
1070
1071         /* Unpack message */
1072
1073         offset += tdb_unpack((char *)buf + offset, len - offset, "f",
1074                              msg->printer);
1075         
1076         offset += tdb_unpack((char *)buf + offset, len - offset, "ddddddd",
1077                                 &tv_sec, &tv_usec,
1078                                 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1079
1080         if (msg->len == 0)
1081                 tdb_unpack((char *)buf + offset, len - offset, "dd",
1082                            &msg->notify.value[0], &msg->notify.value[1]);
1083         else
1084                 tdb_unpack((char *)buf + offset, len - offset, "B", 
1085                            &msg->len, &msg->notify.data);
1086
1087         DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1088                   msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1089
1090         tv->tv_sec = tv_sec;
1091         tv->tv_usec = tv_usec;
1092
1093         if (msg->len == 0)
1094                 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1095                           msg->notify.value[1]));
1096         else
1097                 dump_data(3, msg->notify.data, msg->len);
1098
1099         return True;
1100 }
1101
1102 /********************************************************************
1103  Receive a notify2 message list
1104  ********************************************************************/
1105
1106 static void receive_notify2_message_list(int msg_type, pid_t src, void *msg, size_t len)
1107 {
1108         size_t                  msg_count, i;
1109         char                    *buf = (char *)msg;
1110         char                    *msg_ptr;
1111         size_t                  msg_len;
1112         SPOOLSS_NOTIFY_MSG      notify;
1113         SPOOLSS_NOTIFY_MSG_CTR  messages;
1114         int                     num_groups;
1115
1116         if (len < 4) {
1117                 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1118                 return;
1119         }
1120         
1121         msg_count = IVAL(buf, 0);
1122         msg_ptr = buf + 4;
1123
1124         DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1125
1126         if (msg_count == 0) {
1127                 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1128                 return;
1129         }
1130
1131         /* initialize the container */
1132         
1133         ZERO_STRUCT( messages );
1134         notify_msg_ctr_init( &messages );
1135         
1136         /* 
1137          * build message groups for each printer identified
1138          * in a change_notify msg.  Remember that a PCN message
1139          * includes the handle returned for the srv_spoolss_replyopenprinter()
1140          * call.  Therefore messages are grouped according to printer handle.
1141          */
1142          
1143         for ( i=0; i<msg_count; i++ ) {
1144                 struct timeval msg_tv;
1145
1146                 if (msg_ptr + 4 - buf > len) {
1147                         DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1148                         return;
1149                 }
1150
1151                 msg_len = IVAL(msg_ptr,0);
1152                 msg_ptr += 4;
1153
1154                 if (msg_ptr + msg_len - buf > len) {
1155                         DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1156                         return;
1157                 }
1158                 
1159                 /* unpack messages */
1160                 
1161                 ZERO_STRUCT( notify );
1162                 notify2_unpack_msg( &notify, &msg_tv, msg_ptr, msg_len );
1163                 msg_ptr += msg_len;
1164                 
1165                 /* add to correct list in container */
1166                 
1167                 notify_msg_ctr_addmsg( &messages, &notify );
1168                 
1169                 /* free memory that might have been allocated by notify2_unpack_msg() */
1170                 
1171                 if ( notify.len != 0 )
1172                         SAFE_FREE( notify.notify.data );
1173         }
1174         
1175         /* process each group of messages */
1176         
1177         num_groups = notify_msg_ctr_numgroups( &messages );
1178         for ( i=0; i<num_groups; i++ )
1179                 send_notify2_changes( &messages, i );
1180         
1181         
1182         /* cleanup */
1183                 
1184         DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32)msg_count ));
1185                 
1186         notify_msg_ctr_destroy( &messages );
1187         
1188         return;
1189 }
1190
1191 /********************************************************************
1192  Send a message to ourself about new driver being installed
1193  so we can upgrade the information for each printer bound to this
1194  driver
1195  ********************************************************************/
1196  
1197 static BOOL srv_spoolss_drv_upgrade_printer(char* drivername)
1198 {
1199         int len = strlen(drivername);
1200         
1201         if (!len)
1202                 return False;
1203
1204         DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1205                 drivername));
1206                 
1207         message_send_pid(sys_getpid(), MSG_PRINTER_DRVUPGRADE, drivername, len+1, False);
1208
1209         return True;
1210 }
1211
1212 /**********************************************************************
1213  callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1214  over all printers, upgrading ones as necessary 
1215  **********************************************************************/
1216  
1217 void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len)
1218 {
1219         fstring drivername;
1220         int snum;
1221         int n_services = lp_numservices();
1222         
1223         len = MIN(len,sizeof(drivername)-1);
1224         strncpy(drivername, buf, len);
1225         
1226         DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername ));
1227
1228         /* Iterate the printer list */
1229         
1230         for (snum=0; snum<n_services; snum++)
1231         {
1232                 if (lp_snum_ok(snum) && lp_print_ok(snum) ) 
1233                 {
1234                         WERROR result;
1235                         NT_PRINTER_INFO_LEVEL *printer = NULL;
1236                         
1237                         result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
1238                         if (!W_ERROR_IS_OK(result))
1239                                 continue;
1240                                 
1241                         if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername)) 
1242                         {
1243                                 DEBUG(6,("Updating printer [%s]\n", printer->info_2->printername));
1244                                 
1245                                 /* all we care about currently is the change_id */
1246                                 
1247                                 result = mod_a_printer(*printer, 2);
1248                                 if (!W_ERROR_IS_OK(result)) {
1249                                         DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n", 
1250                                                 dos_errstr(result)));
1251                                 }
1252                         }
1253                         
1254                         free_a_printer(&printer, 2);                    
1255                 }
1256         }
1257         
1258         /* all done */  
1259 }
1260
1261 /********************************************************************
1262  Update the cache for all printq's with a registered client 
1263  connection
1264  ********************************************************************/
1265
1266 void update_monitored_printq_cache( void )
1267 {
1268         Printer_entry *printer = printers_list;
1269         int snum;
1270         
1271         /* loop through all printers and update the cache where 
1272            client_connected == True */
1273         while ( printer ) 
1274         {
1275                 if ( (printer->printer_type == PRINTER_HANDLE_IS_PRINTER) 
1276                         && printer->notify.client_connected ) 
1277                 {
1278                         snum = print_queue_snum(printer->dev.handlename);
1279                         print_queue_status( snum, NULL, NULL );
1280                 }
1281                 
1282                 printer = printer->next;
1283         }
1284         
1285         return;
1286 }
1287 /********************************************************************
1288  Send a message to ourself about new driver being installed
1289  so we can upgrade the information for each printer bound to this
1290  driver
1291  ********************************************************************/
1292  
1293 static BOOL srv_spoolss_reset_printerdata(char* drivername)
1294 {
1295         int len = strlen(drivername);
1296         
1297         if (!len)
1298                 return False;
1299
1300         DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1301                 drivername));
1302                 
1303         message_send_pid(sys_getpid(), MSG_PRINTERDATA_INIT_RESET, drivername, len+1, False);
1304
1305         return True;
1306 }
1307
1308 /**********************************************************************
1309  callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1310  over all printers, resetting printer data as neessary 
1311  **********************************************************************/
1312  
1313 void reset_all_printerdata(int msg_type, pid_t src, void *buf, size_t len)
1314 {
1315         fstring drivername;
1316         int snum;
1317         int n_services = lp_numservices();
1318         
1319         len = MIN( len, sizeof(drivername)-1 );
1320         strncpy( drivername, buf, len );
1321         
1322         DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername ));
1323
1324         /* Iterate the printer list */
1325         
1326         for ( snum=0; snum<n_services; snum++ )
1327         {
1328                 if ( lp_snum_ok(snum) && lp_print_ok(snum) ) 
1329                 {
1330                         WERROR result;
1331                         NT_PRINTER_INFO_LEVEL *printer = NULL;
1332                         
1333                         result = get_a_printer( NULL, &printer, 2, lp_const_servicename(snum) );
1334                         if ( !W_ERROR_IS_OK(result) )
1335                                 continue;
1336                                 
1337                         /* 
1338                          * if the printer is bound to the driver, 
1339                          * then reset to the new driver initdata 
1340                          */
1341                         
1342                         if ( printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername) ) 
1343                         {
1344                                 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer->info_2->printername));
1345                                 
1346                                 if ( !set_driver_init(printer, 2) ) {
1347                                         DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1348                                                 printer->info_2->printername, printer->info_2->drivername));
1349                                 }       
1350                                 
1351                                 result = mod_a_printer( *printer, 2 );
1352                                 if ( !W_ERROR_IS_OK(result) ) {
1353                                         DEBUG(3,("reset_all_printerdata: mod_a_printer() failed!  (%s)\n", 
1354                                                 get_dos_error_msg(result)));
1355                                 }
1356                         }
1357                         
1358                         free_a_printer( &printer, 2 );
1359                 }
1360         }
1361         
1362         /* all done */  
1363         
1364         return;
1365 }
1366
1367 /********************************************************************
1368  Copy routines used by convert_to_openprinterex()
1369  *******************************************************************/
1370
1371 static DEVICEMODE* dup_devicemode(TALLOC_CTX *ctx, DEVICEMODE *devmode)
1372 {
1373         DEVICEMODE *d;
1374         int len;
1375
1376         if (!devmode)
1377                 return NULL;
1378                 
1379         DEBUG (8,("dup_devmode\n"));
1380         
1381         /* bulk copy first */
1382         
1383         d = talloc_memdup(ctx, devmode, sizeof(DEVICEMODE));
1384         if (!d)
1385                 return NULL;
1386                 
1387         /* dup the pointer members separately */
1388         
1389         len = unistrlen(devmode->devicename.buffer);
1390         if (len != -1) {
1391                 d->devicename.buffer = talloc(ctx, len*2);
1392                 if (unistrcpy(d->devicename.buffer, devmode->devicename.buffer) != len)
1393                         return NULL;
1394         }
1395                 
1396
1397         len = unistrlen(devmode->formname.buffer);
1398         if (len != -1) {
1399                 d->devicename.buffer = talloc(ctx, len*2);
1400                 if (unistrcpy(d->formname.buffer, devmode->formname.buffer) != len)
1401                         return NULL;
1402         }
1403
1404         d->private = talloc_memdup(ctx, devmode->private, devmode->driverextra);
1405         
1406         return d;
1407 }
1408
1409 static void copy_devmode_ctr(TALLOC_CTX *ctx, DEVMODE_CTR *new_ctr, DEVMODE_CTR *ctr)
1410 {
1411         if (!new_ctr || !ctr)
1412                 return;
1413                 
1414         DEBUG(8,("copy_devmode_ctr\n"));
1415         
1416         new_ctr->size = ctr->size;
1417         new_ctr->devmode_ptr = ctr->devmode_ptr;
1418         
1419         if(ctr->devmode_ptr)
1420                 new_ctr->devmode = dup_devicemode(ctx, ctr->devmode);
1421 }
1422
1423 static void copy_printer_default(TALLOC_CTX *ctx, PRINTER_DEFAULT *new_def, PRINTER_DEFAULT *def)
1424 {
1425         if (!new_def || !def)
1426                 return;
1427         
1428         DEBUG(8,("copy_printer_defaults\n"));
1429         
1430         new_def->datatype_ptr = def->datatype_ptr;
1431         
1432         if (def->datatype_ptr)
1433                 copy_unistr2(&new_def->datatype, &def->datatype);
1434         
1435         copy_devmode_ctr(ctx, &new_def->devmode_cont, &def->devmode_cont);
1436         
1437         new_def->access_required = def->access_required;
1438 }
1439
1440 /********************************************************************
1441  * Convert a SPOOL_Q_OPEN_PRINTER structure to a 
1442  * SPOOL_Q_OPEN_PRINTER_EX structure
1443  ********************************************************************/
1444
1445 static void convert_to_openprinterex(TALLOC_CTX *ctx, SPOOL_Q_OPEN_PRINTER_EX *q_u_ex, SPOOL_Q_OPEN_PRINTER *q_u)
1446 {
1447         if (!q_u_ex || !q_u)
1448                 return;
1449
1450         DEBUG(8,("convert_to_openprinterex\n"));
1451                                 
1452         q_u_ex->printername_ptr = q_u->printername_ptr;
1453         
1454         if (q_u->printername_ptr)
1455                 copy_unistr2(&q_u_ex->printername, &q_u->printername);
1456         
1457         copy_printer_default(ctx, &q_u_ex->printer_default, &q_u->printer_default);
1458 }
1459
1460 /********************************************************************
1461  * spoolss_open_printer
1462  *
1463  * called from the spoolss dispatcher
1464  ********************************************************************/
1465
1466 WERROR _spoolss_open_printer(pipes_struct *p, SPOOL_Q_OPEN_PRINTER *q_u, SPOOL_R_OPEN_PRINTER *r_u)
1467 {
1468         SPOOL_Q_OPEN_PRINTER_EX q_u_ex;
1469         SPOOL_R_OPEN_PRINTER_EX r_u_ex;
1470         
1471         if (!q_u || !r_u)
1472                 return WERR_NOMEM;
1473         
1474         ZERO_STRUCT(q_u_ex);
1475         ZERO_STRUCT(r_u_ex);
1476         
1477         /* convert the OpenPrinter() call to OpenPrinterEx() */
1478         
1479         convert_to_openprinterex(p->mem_ctx, &q_u_ex, q_u);
1480         
1481         r_u_ex.status = _spoolss_open_printer_ex(p, &q_u_ex, &r_u_ex);
1482         
1483         /* convert back to OpenPrinter() */
1484         
1485         memcpy(r_u, &r_u_ex, sizeof(*r_u));
1486         
1487         return r_u->status;
1488 }
1489
1490 /********************************************************************
1491  * spoolss_open_printer
1492  *
1493  * If the openprinterex rpc call contains a devmode,
1494  * it's a per-user one. This per-user devmode is derivated
1495  * from the global devmode. Openprinterex() contains a per-user 
1496  * devmode for when you do EMF printing and spooling.
1497  * In the EMF case, the NT workstation is only doing half the job
1498  * of rendering the page. The other half is done by running the printer
1499  * driver on the server.
1500  * The EMF file doesn't contain the page description (paper size, orientation, ...).
1501  * The EMF file only contains what is to be printed on the page.
1502  * So in order for the server to know how to print, the NT client sends
1503  * a devicemode attached to the openprinterex call.
1504  * But this devicemode is short lived, it's only valid for the current print job.
1505  *
1506  * If Samba would have supported EMF spooling, this devicemode would
1507  * have been attached to the handle, to sent it to the driver to correctly
1508  * rasterize the EMF file.
1509  *
1510  * As Samba only supports RAW spooling, we only receive a ready-to-print file,
1511  * we just act as a pass-thru between windows and the printer.
1512  *
1513  * In order to know that Samba supports only RAW spooling, NT has to call
1514  * getprinter() at level 2 (attribute field) or NT has to call startdoc()
1515  * and until NT sends a RAW job, we refuse it.
1516  *
1517  * But to call getprinter() or startdoc(), you first need a valid handle,
1518  * and to get an handle you have to call openprintex(). Hence why you have
1519  * a devicemode in the openprinterex() call.
1520  *
1521  *
1522  * Differences between NT4 and NT 2000.
1523  * NT4:
1524  * ---
1525  * On NT4, you only have a global devicemode. This global devicemode can be changed
1526  * by the administrator (or by a user with enough privs). Everytime a user
1527  * wants to print, the devicemode is resetted to the default. In Word, everytime
1528  * you print, the printer's characteristics are always reset to the global devicemode.
1529  *
1530  * NT 2000:
1531  * -------
1532  * In W2K, there is the notion of per-user devicemode. The first time you use
1533  * a printer, a per-user devicemode is build from the global devicemode.
1534  * If you change your per-user devicemode, it is saved in the registry, under the
1535  * H_KEY_CURRENT_KEY sub_tree. So that everytime you print, you have your default
1536  * printer preferences available.
1537  *
1538  * To change the per-user devicemode: it's the "Printing Preferences ..." button
1539  * on the General Tab of the printer properties windows.
1540  *
1541  * To change the global devicemode: it's the "Printing Defaults..." button
1542  * on the Advanced Tab of the printer properties window.
1543  *
1544  * JFM.
1545  ********************************************************************/
1546
1547 WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u)
1548 {
1549         UNISTR2                 *printername = NULL;
1550         PRINTER_DEFAULT         *printer_default = &q_u->printer_default;
1551         POLICY_HND              *handle = &r_u->handle;
1552
1553         fstring name;
1554         int snum;
1555         struct current_user user;
1556         Printer_entry *Printer=NULL;
1557
1558         if (q_u->printername_ptr != 0)
1559                 printername = &q_u->printername;
1560
1561         if (printername == NULL)
1562                 return WERR_INVALID_PRINTER_NAME;
1563
1564         /* some sanity check because you can open a printer or a print server */
1565         /* aka: \\server\printer or \\server */
1566         unistr2_to_ascii(name, printername, sizeof(name)-1);
1567
1568         DEBUGADD(3,("checking name: %s\n",name));
1569
1570         if (!open_printer_hnd(p, handle, name, 0))
1571                 return WERR_INVALID_PRINTER_NAME;
1572         
1573         Printer=find_printer_index_by_hnd(p, handle);
1574         if (!Printer) {
1575                 DEBUG(0,(" _spoolss_open_printer_ex: logic error. \
1576 Can't find printer handle we created for printer %s\n", name ));
1577                 close_printer_handle(p,handle);
1578                 return WERR_INVALID_PRINTER_NAME;
1579         }
1580
1581         get_current_user(&user, p);
1582
1583         /*
1584          * First case: the user is opening the print server:
1585          *
1586          * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1587          * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1588          *
1589          * Then both Win2k and WinNT clients try an OpenPrinterEx with
1590          * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1591          * or if the user is listed in the smb.conf printer admin parameter.
1592          *
1593          * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1594          * client view printer folder, but does not show the MSAPW.
1595          *
1596          * Note: this test needs code to check access rights here too. Jeremy
1597          * could you look at this?
1598          * 
1599          * Second case: the user is opening a printer:
1600          * NT doesn't let us connect to a printer if the connecting user
1601          * doesn't have print permission.
1602          */
1603
1604         if (Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER) 
1605         {
1606                 /* Printserver handles use global struct... */
1607
1608                 snum = -1;
1609
1610                 /* Map standard access rights to object specific access rights */
1611                 
1612                 se_map_standard(&printer_default->access_required, 
1613                                 &printserver_std_mapping);
1614         
1615                 /* Deny any object specific bits that don't apply to print
1616                    servers (i.e printer and job specific bits) */
1617
1618                 printer_default->access_required &= SPECIFIC_RIGHTS_MASK;
1619
1620                 if (printer_default->access_required &
1621                     ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1622                         DEBUG(3, ("access DENIED for non-printserver bits"));
1623                         close_printer_handle(p, handle);
1624                         return WERR_ACCESS_DENIED;
1625                 }
1626
1627                 /* Allow admin access */
1628
1629                 if ( printer_default->access_required & SERVER_ACCESS_ADMINISTER ) 
1630                 {
1631                         if (!lp_ms_add_printer_wizard()) {
1632                                 close_printer_handle(p, handle);
1633                                 return WERR_ACCESS_DENIED;
1634                         }
1635
1636                         /* if the user is not root and not a printer admin, then fail */
1637                         
1638                         if ( user.uid != 0
1639                              && !user_in_list(uidtoname(user.uid), lp_printer_admin(snum), user.groups, user.ngroups) )
1640                         {
1641                                 close_printer_handle(p, handle);
1642                                 return WERR_ACCESS_DENIED;
1643                         }
1644                         
1645                         printer_default->access_required = SERVER_ACCESS_ADMINISTER;
1646                 }
1647                 else
1648                 {
1649                         printer_default->access_required = SERVER_ACCESS_ENUMERATE;
1650                 }
1651
1652                 DEBUG(4,("Setting print server access = %s\n", (printer_default->access_required == SERVER_ACCESS_ADMINISTER) 
1653                         ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1654                         
1655                 /* We fall through to return WERR_OK */
1656                 
1657         }
1658         else
1659         {
1660                 /* NT doesn't let us connect to a printer if the connecting user
1661                    doesn't have print permission.  */
1662
1663                 if (!get_printer_snum(p, handle, &snum)) {
1664                         close_printer_handle(p, handle);
1665                         return WERR_BADFID;
1666                 }
1667
1668                 se_map_standard(&printer_default->access_required, &printer_std_mapping);
1669                 
1670                 /* map an empty access mask to the minimum access mask */
1671                 if (printer_default->access_required == 0x0)
1672                         printer_default->access_required = PRINTER_ACCESS_USE;
1673
1674                 /*
1675                  * If we are not serving the printer driver for this printer,
1676                  * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE.  This
1677                  * will keep NT clients happy  --jerry  
1678                  */
1679                  
1680                 if (lp_use_client_driver(snum) 
1681                         && (printer_default->access_required & PRINTER_ACCESS_ADMINISTER))
1682                 {
1683                         printer_default->access_required = PRINTER_ACCESS_USE;
1684                 }
1685
1686                 /* check smb.conf parameters and the the sec_desc */
1687                 
1688                 if (!user_ok(uidtoname(user.uid), snum, user.groups, user.ngroups) || !print_access_check(&user, snum, printer_default->access_required)) {
1689                         DEBUG(3, ("access DENIED for printer open\n"));
1690                         close_printer_handle(p, handle);
1691                         return WERR_ACCESS_DENIED;
1692                 }
1693
1694                 if ((printer_default->access_required & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1695                         DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1696                         close_printer_handle(p, handle);
1697                         return WERR_ACCESS_DENIED;
1698                 }
1699
1700                 if (printer_default->access_required & PRINTER_ACCESS_ADMINISTER)
1701                         printer_default->access_required = PRINTER_ACCESS_ADMINISTER;
1702                 else
1703                         printer_default->access_required = PRINTER_ACCESS_USE;
1704
1705                 DEBUG(4,("Setting printer access = %s\n", (printer_default->access_required == PRINTER_ACCESS_ADMINISTER) 
1706                         ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1707
1708         }
1709         
1710         Printer->access_granted = printer_default->access_required;
1711         
1712         /* 
1713          * If the client sent a devmode in the OpenPrinter() call, then
1714          * save it here in case we get a job submission on this handle
1715          */
1716         
1717          if ( (Printer->printer_type != PRINTER_HANDLE_IS_PRINTSERVER)
1718                 && q_u->printer_default.devmode_cont.devmode_ptr )
1719          { 
1720                 convert_devicemode( Printer->dev.handlename, q_u->printer_default.devmode_cont.devmode,
1721                         &Printer->nt_devmode );
1722          }
1723
1724         /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN 
1725            optimization in Windows 2000 clients  --jerry */
1726
1727         if ( (printer_default->access_required == PRINTER_ACCESS_ADMINISTER) 
1728                 && (RA_WIN2K == get_remote_arch()) )
1729         {
1730                 DEBUG(10,("_spoolss_open_printer_ex: Enabling LAN/WAN hack for Win2k clients.\n"));
1731                 sys_usleep( 500000 );
1732         }
1733
1734         return WERR_OK;
1735 }
1736
1737 /****************************************************************************
1738 ****************************************************************************/
1739
1740 static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
1741                                 NT_PRINTER_INFO_LEVEL *printer, uint32 level)
1742 {
1743         BOOL ret = True;
1744
1745         switch (level) {
1746                 case 2:
1747                         ret = uni_2_asc_printer_info_2(uni->info_2, &printer->info_2);
1748                         break;
1749                 default:
1750                         break;
1751         }
1752
1753         return ret;
1754 }
1755
1756 static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
1757                                         NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level)
1758 {
1759         BOOL result = True;
1760
1761         switch (level) {
1762                 case 3:
1763                         printer->info_3=NULL;
1764                         if (!uni_2_asc_printer_driver_3(uni->info_3, &printer->info_3))
1765                                 result = False;
1766                         break;
1767                 case 6:
1768                         printer->info_6=NULL;
1769                         if (!uni_2_asc_printer_driver_6(uni->info_6, &printer->info_6))
1770                                 result = False;
1771                         break;
1772                 default:
1773                         break;
1774         }
1775
1776         return result;
1777 }
1778
1779 BOOL convert_devicemode(const char *printername, const DEVICEMODE *devmode,
1780                                 NT_DEVICEMODE **pp_nt_devmode)
1781 {
1782         NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
1783
1784         /*
1785          * Ensure nt_devmode is a valid pointer
1786          * as we will be overwriting it.
1787          */
1788                 
1789         if (nt_devmode == NULL) {
1790                 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1791                 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
1792                         return False;
1793         }
1794
1795         rpcstr_pull(nt_devmode->devicename,devmode->devicename.buffer, 31, -1, 0);
1796         rpcstr_pull(nt_devmode->formname,devmode->formname.buffer, 31, -1, 0);
1797
1798         nt_devmode->specversion=devmode->specversion;
1799         nt_devmode->driverversion=devmode->driverversion;
1800         nt_devmode->size=devmode->size;
1801         nt_devmode->fields=devmode->fields;
1802         nt_devmode->orientation=devmode->orientation;
1803         nt_devmode->papersize=devmode->papersize;
1804         nt_devmode->paperlength=devmode->paperlength;
1805         nt_devmode->paperwidth=devmode->paperwidth;
1806         nt_devmode->scale=devmode->scale;
1807         nt_devmode->copies=devmode->copies;
1808         nt_devmode->defaultsource=devmode->defaultsource;
1809         nt_devmode->printquality=devmode->printquality;
1810         nt_devmode->color=devmode->color;
1811         nt_devmode->duplex=devmode->duplex;
1812         nt_devmode->yresolution=devmode->yresolution;
1813         nt_devmode->ttoption=devmode->ttoption;
1814         nt_devmode->collate=devmode->collate;
1815
1816         nt_devmode->logpixels=devmode->logpixels;
1817         nt_devmode->bitsperpel=devmode->bitsperpel;
1818         nt_devmode->pelswidth=devmode->pelswidth;
1819         nt_devmode->pelsheight=devmode->pelsheight;
1820         nt_devmode->displayflags=devmode->displayflags;
1821         nt_devmode->displayfrequency=devmode->displayfrequency;
1822         nt_devmode->icmmethod=devmode->icmmethod;
1823         nt_devmode->icmintent=devmode->icmintent;
1824         nt_devmode->mediatype=devmode->mediatype;
1825         nt_devmode->dithertype=devmode->dithertype;
1826         nt_devmode->reserved1=devmode->reserved1;
1827         nt_devmode->reserved2=devmode->reserved2;
1828         nt_devmode->panningwidth=devmode->panningwidth;
1829         nt_devmode->panningheight=devmode->panningheight;
1830
1831         /*
1832          * Only change private and driverextra if the incoming devmode
1833          * has a new one. JRA.
1834          */
1835
1836         if ((devmode->driverextra != 0) && (devmode->private != NULL)) {
1837                 SAFE_FREE(nt_devmode->private);
1838                 nt_devmode->driverextra=devmode->driverextra;
1839                 if((nt_devmode->private=(uint8 *)malloc(nt_devmode->driverextra * sizeof(uint8))) == NULL)
1840                         return False;
1841                 memcpy(nt_devmode->private, devmode->private, nt_devmode->driverextra);
1842         }
1843
1844         *pp_nt_devmode = nt_devmode;
1845
1846         return True;
1847 }
1848
1849 /********************************************************************
1850  * _spoolss_enddocprinter_internal.
1851  ********************************************************************/
1852
1853 static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle)
1854 {
1855         Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1856         int snum;
1857
1858         if (!Printer) {
1859                 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
1860                 return WERR_BADFID;
1861         }
1862         
1863         if (!get_printer_snum(p, handle, &snum))
1864                 return WERR_BADFID;
1865
1866         Printer->document_started=False;
1867         print_job_end(snum, Printer->jobid,True);
1868         /* error codes unhandled so far ... */
1869
1870         return WERR_OK;
1871 }
1872
1873 /********************************************************************
1874  * api_spoolss_closeprinter
1875  ********************************************************************/
1876
1877 WERROR _spoolss_closeprinter(pipes_struct *p, SPOOL_Q_CLOSEPRINTER *q_u, SPOOL_R_CLOSEPRINTER *r_u)
1878 {
1879         POLICY_HND *handle = &q_u->handle;
1880
1881         Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1882
1883         if (Printer && Printer->document_started)
1884                 _spoolss_enddocprinter_internal(p, handle);          /* print job was not closed */
1885
1886         if (!close_printer_handle(p, handle))
1887                 return WERR_BADFID;     
1888                 
1889         /* clear the returned printer handle.  Observed behavior 
1890            from Win2k server.  Don't think this really matters.
1891            Previous code just copied the value of the closed
1892            handle.    --jerry */
1893
1894         memset(&r_u->handle, '\0', sizeof(r_u->handle));
1895
1896         return WERR_OK;
1897 }
1898
1899 /********************************************************************
1900  * api_spoolss_deleteprinter
1901
1902  ********************************************************************/
1903
1904 WERROR _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL_R_DELETEPRINTER *r_u)
1905 {
1906         POLICY_HND *handle = &q_u->handle;
1907         Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1908         WERROR result;
1909
1910         if (Printer && Printer->document_started)
1911                 _spoolss_enddocprinter_internal(p, handle);  /* print job was not closed */
1912
1913         memcpy(&r_u->handle, &q_u->handle, sizeof(r_u->handle));
1914
1915         result = delete_printer_handle(p, handle);
1916
1917         update_c_setprinter(False);
1918
1919         return result;
1920 }
1921
1922 /*******************************************************************
1923  * static function to lookup the version id corresponding to an
1924  * long architecture string
1925  ******************************************************************/
1926
1927 static int get_version_id (char * arch)
1928 {
1929         int i;
1930         struct table_node archi_table[]= {
1931  
1932                 {"Windows 4.0",          "WIN40",       0 },
1933                 {"Windows NT x86",       "W32X86",      2 },
1934                 {"Windows NT R4000",     "W32MIPS",     2 },    
1935                 {"Windows NT Alpha_AXP", "W32ALPHA",    2 },
1936                 {"Windows NT PowerPC",   "W32PPC",      2 },
1937                 {NULL,                   "",            -1 }
1938         };
1939  
1940         for (i=0; archi_table[i].long_archi != NULL; i++)
1941         {
1942                 if (strcmp(arch, archi_table[i].long_archi) == 0)
1943                         return (archi_table[i].version);
1944         }
1945         
1946         return -1;
1947 }
1948
1949 /********************************************************************
1950  * _spoolss_deleteprinterdriver
1951  ********************************************************************/
1952
1953 WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u, SPOOL_R_DELETEPRINTERDRIVER *r_u)
1954 {
1955         fstring                         driver;
1956         fstring                         arch;
1957         NT_PRINTER_DRIVER_INFO_LEVEL    info;
1958         NT_PRINTER_DRIVER_INFO_LEVEL    info_win2k;
1959         int                             version;
1960         struct current_user             user;
1961         WERROR                          status;
1962         WERROR                          status_win2k = WERR_ACCESS_DENIED;
1963         
1964         get_current_user(&user, p);
1965          
1966         unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 );
1967         unistr2_to_ascii(arch,   &q_u->arch,   sizeof(arch)-1   );
1968         
1969         /* check that we have a valid driver name first */
1970         
1971         if ((version=get_version_id(arch)) == -1) 
1972                 return WERR_INVALID_ENVIRONMENT;
1973                                 
1974         ZERO_STRUCT(info);
1975         ZERO_STRUCT(info_win2k);
1976         
1977         if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) 
1978         {
1979                 /* try for Win2k driver if "Windows NT x86" */
1980                 
1981                 if ( version == 2 ) {
1982                         version = 3;
1983                         if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
1984                                 status = WERR_UNKNOWN_PRINTER_DRIVER;
1985                                 goto done;
1986                         }
1987                 }
1988                 /* otherwise it was a failure */
1989                 else {
1990                         status = WERR_UNKNOWN_PRINTER_DRIVER;
1991                         goto done;
1992                 }
1993                 
1994         }
1995         
1996         if (printer_driver_in_use(info.info_3)) {
1997                 status = WERR_PRINTER_DRIVER_IN_USE;
1998                 goto done;
1999         }
2000         
2001         if ( version == 2 )
2002         {               
2003                 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
2004                 {
2005                         /* if we get to here, we now have 2 driver info structures to remove */
2006                         /* remove the Win2k driver first*/
2007                 
2008                         status_win2k = delete_printer_driver(info_win2k.info_3, &user, 3, False );
2009                         free_a_printer_driver( info_win2k, 3 );
2010                 
2011                         /* this should not have failed---if it did, report to client */
2012                         if ( !W_ERROR_IS_OK(status_win2k) )
2013                                 goto done;
2014                 }
2015         }
2016         
2017         status = delete_printer_driver(info.info_3, &user, version, False);
2018         
2019         /* if at least one of the deletes succeeded return OK */
2020         
2021         if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2022                 status = WERR_OK;
2023         
2024 done:
2025         free_a_printer_driver( info, 3 );
2026
2027         return status;
2028 }
2029
2030 /********************************************************************
2031  * spoolss_deleteprinterdriverex
2032  ********************************************************************/
2033
2034 WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, SPOOL_R_DELETEPRINTERDRIVEREX *r_u)
2035 {
2036         fstring                         driver;
2037         fstring                         arch;
2038         NT_PRINTER_DRIVER_INFO_LEVEL    info;
2039         NT_PRINTER_DRIVER_INFO_LEVEL    info_win2k;
2040         int                             version;
2041         uint32                          flags = q_u->delete_flags;
2042         BOOL                            delete_files;
2043         struct current_user             user;
2044         WERROR                          status;
2045         WERROR                          status_win2k = WERR_ACCESS_DENIED;
2046         
2047         get_current_user(&user, p);
2048         
2049         unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 );
2050         unistr2_to_ascii(arch,   &q_u->arch,   sizeof(arch)-1   );
2051
2052         /* check that we have a valid driver name first */
2053         if ((version=get_version_id(arch)) == -1) {
2054                 /* this is what NT returns */
2055                 return WERR_INVALID_ENVIRONMENT;
2056         }
2057         
2058         if ( flags & DPD_DELETE_SPECIFIC_VERSION )
2059                 version = q_u->version;
2060                 
2061         ZERO_STRUCT(info);
2062         ZERO_STRUCT(info_win2k);
2063                 
2064         status = get_a_printer_driver(&info, 3, driver, arch, version);
2065         
2066         if ( !W_ERROR_IS_OK(status) ) 
2067         {
2068                 /* 
2069                  * if the client asked for a specific version, 
2070                  * or this is something other than Windows NT x86,
2071                  * then we've failed 
2072                  */
2073                 
2074                 if ( (flags&DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
2075                         goto done;
2076                         
2077                 /* try for Win2k driver if "Windows NT x86" */
2078                 
2079                 version = 3;
2080                 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
2081                         status = WERR_UNKNOWN_PRINTER_DRIVER;
2082                         goto done;
2083                 }
2084         }
2085                 
2086         if ( printer_driver_in_use(info.info_3) ) {
2087                 status = WERR_PRINTER_DRIVER_IN_USE;
2088                 goto done;
2089         }
2090         
2091         /* 
2092          * we have a couple of cases to consider. 
2093          * (1) Are any files in use?  If so and DPD_DELTE_ALL_FILE is set,
2094          *     then the delete should fail if **any** files overlap with 
2095          *     other drivers 
2096          * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2097          *     non-overlapping files 
2098          * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2099          *     is set, the do not delete any files
2100          * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2101          */
2102         
2103         delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
2104         
2105         /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2106                 
2107         if ( delete_files && printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2108                 /* no idea of the correct error here */
2109                 status = WERR_ACCESS_DENIED;    
2110                 goto done;
2111         }
2112
2113                         
2114         /* also check for W32X86/3 if necessary; maybe we already have? */
2115                 
2116         if ( (version == 2) && ((flags&DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION)  ) {
2117                 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3))) 
2118                 {
2119                         
2120                         if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2121                                 /* no idea of the correct error here */
2122                                 free_a_printer_driver( info_win2k, 3 );
2123                                 status = WERR_ACCESS_DENIED;    
2124                                 goto done;
2125                         }
2126                 
2127                         /* if we get to here, we now have 2 driver info structures to remove */
2128                         /* remove the Win2k driver first*/
2129                 
2130                         status_win2k = delete_printer_driver(info_win2k.info_3, &user, 3, delete_files);
2131                         free_a_printer_driver( info_win2k, 3 );
2132                                 
2133                         /* this should not have failed---if it did, report to client */
2134                                 
2135                         if ( !W_ERROR_IS_OK(status_win2k) )
2136                                 goto done;
2137                 }
2138         }
2139
2140         status = delete_printer_driver(info.info_3, &user, version, delete_files);
2141
2142         if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2143                 status = WERR_OK;
2144 done:
2145         free_a_printer_driver( info, 3 );
2146         
2147         return status;
2148 }
2149
2150
2151 /****************************************************************************
2152  Internal routine for retreiving printerdata
2153  ***************************************************************************/
2154
2155 static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer, 
2156                                   const char *key, const char *value, uint32 *type, uint8 **data, 
2157                                   uint32 *needed, uint32 in_size  )
2158 {
2159         REGISTRY_VALUE          *val;
2160         int                     size, data_len;
2161         
2162         if ( !(val = get_printer_data( printer->info_2, key, value)) )
2163                 return WERR_BADFILE;
2164         
2165         *type = regval_type( val );
2166
2167         DEBUG(5,("get_printer_dataex: allocating %d\n", in_size));
2168
2169         size = regval_size( val );
2170         
2171         /* copy the min(in_size, len) */
2172         
2173         if ( in_size ) {
2174                 data_len = (size > in_size) ? in_size : size*sizeof(uint8);
2175                 
2176                 /* special case for 0 length values */
2177                 if ( data_len ) {
2178                         if ( (*data  = (uint8 *)talloc_memdup(ctx, regval_data_p(val), data_len)) == NULL )
2179                                 return WERR_NOMEM;
2180                 }
2181                 else {
2182                         if ( (*data  = (uint8 *)talloc_zero(ctx, in_size)) == NULL )
2183                                 return WERR_NOMEM;
2184                 }
2185         }
2186         else
2187                 *data = NULL;
2188
2189         *needed = size;
2190         
2191         DEBUG(5,("get_printer_dataex: copy done\n"));
2192
2193         return WERR_OK;
2194 }
2195
2196 /****************************************************************************
2197  Internal routine for removing printerdata
2198  ***************************************************************************/
2199
2200 static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value )
2201 {
2202         return delete_printer_data( printer->info_2, key, value );
2203 }
2204
2205 /****************************************************************************
2206  Internal routine for storing printerdata
2207  ***************************************************************************/
2208
2209 static WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value, 
2210                                   uint32 type, uint8 *data, int real_len  )
2211 {
2212         delete_printer_data( printer->info_2, key, value );
2213         
2214         return add_printer_data( printer->info_2, key, value, type, data, real_len );
2215 }
2216
2217 /********************************************************************
2218  GetPrinterData on a printer server Handle.
2219 ********************************************************************/
2220
2221 static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
2222 {               
2223         int i;
2224         
2225         DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2226                 
2227         if (!StrCaseCmp(value, "W3SvcInstalled")) {
2228                 *type = 0x4;
2229                 if((*data = (uint8 *)talloc_zero(ctx, 4*sizeof(uint8) )) == NULL)
2230                         return WERR_NOMEM;
2231                 *needed = 0x4;
2232                 return WERR_OK;
2233         }
2234
2235         if (!StrCaseCmp(value, "BeepEnabled")) {
2236                 *type = 0x4;
2237                 if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
2238                         return WERR_NOMEM;
2239                 SIVAL(*data, 0, 0x00);
2240                 *needed = 0x4;                  
2241                 return WERR_OK;
2242         }
2243
2244         if (!StrCaseCmp(value, "EventLog")) {
2245                 *type = 0x4;
2246                 if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
2247                         return WERR_NOMEM;
2248                 /* formally was 0x1b */
2249                 SIVAL(*data, 0, 0x0);
2250                 *needed = 0x4;                  
2251                 return WERR_OK;
2252         }
2253
2254         if (!StrCaseCmp(value, "NetPopup")) {
2255                 *type = 0x4;
2256                 if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
2257                         return WERR_NOMEM;
2258                 SIVAL(*data, 0, 0x00);
2259                 *needed = 0x4;
2260                 return WERR_OK;
2261         }
2262
2263         if (!StrCaseCmp(value, "MajorVersion")) {
2264                 *type = 0x4;
2265                 if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
2266                         return WERR_NOMEM;
2267
2268                 /* Windows NT 4.0 seems to not allow uploading of drivers
2269                    to a server that reports 0x3 as the MajorVersion.
2270                    need to investigate more how Win2k gets around this .
2271                    -- jerry */
2272
2273                 if ( RA_WINNT == get_remote_arch() )
2274                         SIVAL(*data, 0, 2);
2275                 else
2276                         SIVAL(*data, 0, 3);
2277                 
2278                 *needed = 0x4;
2279                 return WERR_OK;
2280         }
2281
2282         if (!StrCaseCmp(value, "MinorVersion")) {
2283                 *type = 0x4;
2284                 if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
2285                         return WERR_NOMEM;
2286                 SIVAL(*data, 0, 0);
2287                 *needed = 0x4;
2288                 return WERR_OK;
2289         }
2290
2291         /* REG_BINARY
2292          *  uint32 size          = 0x114
2293          *  uint32 major         = 5
2294          *  uint32 minor         = [0|1]
2295          *  uint32 build         = [2195|2600]
2296          *  extra unicode string = e.g. "Service Pack 3"
2297          */
2298         if (!StrCaseCmp(value, "OSVersion")) {
2299                 *type = 0x3;
2300                 *needed = 0x114;
2301
2302                 if((*data = (uint8 *)talloc(ctx, (*needed)*sizeof(uint8) )) == NULL)
2303                         return WERR_NOMEM;
2304                 ZERO_STRUCTP( *data );
2305                 
2306                 SIVAL(*data, 0, *needed);       /* size */
2307                 SIVAL(*data, 4, 5);             /* Windows 2000 == 5.0 */
2308                 SIVAL(*data, 8, 0);
2309                 SIVAL(*data, 12, 2195);         /* build */
2310                 
2311                 /* leave extra string empty */
2312                 
2313                 return WERR_OK;
2314         }
2315
2316
2317         if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2318                 const char *string="C:\\PRINTERS";
2319                 *type = 0x1;                    
2320                 *needed = 2*(strlen(string)+1);         
2321                 if((*data  = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
2322                         return WERR_NOMEM;
2323                 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2324                 
2325                 /* it's done by hand ready to go on the wire */
2326                 for (i=0; i<strlen(string); i++) {
2327                         (*data)[2*i]=string[i];
2328                         (*data)[2*i+1]='\0';
2329                 }                       
2330                 return WERR_OK;
2331         }
2332
2333         if (!StrCaseCmp(value, "Architecture")) {                       
2334                 const char *string="Windows NT x86";
2335                 *type = 0x1;                    
2336                 *needed = 2*(strlen(string)+1); 
2337                 if((*data  = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
2338                         return WERR_NOMEM;
2339                 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2340                 for (i=0; i<strlen(string); i++) {
2341                         (*data)[2*i]=string[i];
2342                         (*data)[2*i+1]='\0';
2343                 }                       
2344                 return WERR_OK;
2345         }
2346
2347         if (!StrCaseCmp(value, "DsPresent")) {
2348                 *type = 0x4;
2349                 if((*data = (uint8 *)talloc(ctx, 4*sizeof(uint8) )) == NULL)
2350                         return WERR_NOMEM;
2351                 SIVAL(*data, 0, 0x01);
2352                 *needed = 0x4;
2353                 return WERR_OK;
2354         }
2355
2356         if (!StrCaseCmp(value, "DNSMachineName")) {                     
2357                 pstring hostname;
2358                 
2359                 if (!get_mydnsfullname(hostname))
2360                         return WERR_BADFILE;
2361                 *type = 0x1;                    
2362                 *needed = 2*(strlen(hostname)+1);       
2363                 if((*data  = (uint8 *)talloc(ctx, ((*needed > in_size) ? *needed:in_size) *sizeof(uint8))) == NULL)
2364                         return WERR_NOMEM;
2365                 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2366                 for (i=0; i<strlen(hostname); i++) {
2367                         (*data)[2*i]=hostname[i];
2368                         (*data)[2*i+1]='\0';
2369                 }                       
2370                 return WERR_OK;
2371         }
2372
2373
2374         return WERR_BADFILE;
2375 }
2376
2377 /********************************************************************
2378  * spoolss_getprinterdata
2379  ********************************************************************/
2380
2381 WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u)
2382 {
2383         POLICY_HND      *handle = &q_u->handle;
2384         UNISTR2         *valuename = &q_u->valuename;
2385         uint32          in_size = q_u->size;
2386         uint32          *type = &r_u->type;
2387         uint32          *out_size = &r_u->size;
2388         uint8           **data = &r_u->data;
2389         uint32          *needed = &r_u->needed;
2390         WERROR          status;
2391         fstring         value;
2392         Printer_entry   *Printer = find_printer_index_by_hnd(p, handle);
2393         NT_PRINTER_INFO_LEVEL   *printer = NULL;
2394         int             snum = 0;
2395         
2396         /*
2397          * Reminder: when it's a string, the length is in BYTES
2398          * even if UNICODE is negociated.
2399          *
2400          * JFM, 4/19/1999
2401          */
2402
2403         *out_size = in_size;
2404
2405         /* in case of problem, return some default values */
2406         
2407         *needed = 0;
2408         *type   = 0;
2409         
2410         DEBUG(4,("_spoolss_getprinterdata\n"));
2411         
2412         if ( !Printer ) {
2413                 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2414                 status = WERR_BADFID;
2415                 goto done;
2416         }
2417         
2418         unistr2_to_ascii(value, valuename, sizeof(value)-1);
2419         
2420         if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER )
2421                 status = getprinterdata_printer_server( p->mem_ctx, value, type, data, needed, *out_size );
2422         else
2423         {
2424                 if ( !get_printer_snum(p,handle, &snum) ) {
2425                         status = WERR_BADFID;
2426                         goto done;
2427                 }
2428
2429                 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
2430                 if ( !W_ERROR_IS_OK(status) )
2431                         goto done;
2432
2433                 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
2434
2435                 if ( strequal(value, "ChangeId") ) {
2436                         *type = REG_DWORD;
2437                         *needed = sizeof(uint32);
2438                         if ( (*data = (uint8*)talloc(p->mem_ctx, sizeof(uint32))) == NULL) {
2439                                 status = WERR_NOMEM;
2440                                 goto done;
2441                         }
2442                         SIVAL( *data, 0, printer->info_2->changeid );
2443                         status = WERR_OK;
2444                 }
2445                 else
2446                         status = get_printer_dataex( p->mem_ctx, printer, SPOOL_PRINTERDATA_KEY, value, type, data, needed, *out_size );
2447         }
2448
2449         if (*needed > *out_size)
2450                 status = WERR_MORE_DATA;
2451         
2452 done:
2453         if ( !W_ERROR_IS_OK(status) ) 
2454         {
2455                 DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status),*out_size));
2456                 
2457                 /* reply this param doesn't exist */
2458                 
2459                 if ( *out_size ) {
2460                         if((*data=(uint8 *)talloc_zero(p->mem_ctx, *out_size*sizeof(uint8))) == NULL) {
2461                                 if ( printer ) 
2462                                         free_a_printer( &printer, 2 );
2463                                 return WERR_NOMEM;
2464                 } 
2465                 } 
2466                 else {
2467                         *data = NULL;
2468                 }
2469         }
2470         
2471         /* cleanup & exit */
2472
2473         if ( printer )
2474                 free_a_printer( &printer, 2 );
2475         
2476         return status;
2477 }
2478
2479 /*********************************************************
2480  Connect to the client machine.
2481 **********************************************************/
2482
2483 static BOOL spoolss_connect_to_client(struct cli_state *the_cli, 
2484                         struct in_addr *client_ip, const char *remote_machine)
2485 {
2486         ZERO_STRUCTP(the_cli);
2487         
2488         if(cli_initialise(the_cli) == NULL) {
2489                 DEBUG(0,("spoolss_connect_to_client: unable to initialize client connection.\n"));
2490                 return False;
2491         }
2492         
2493         if ( is_zero_ip(*client_ip) ) {
2494                 if(!resolve_name( remote_machine, &the_cli->dest_ip, 0x20)) {
2495                         DEBUG(0,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2496                         cli_shutdown(the_cli);
2497                 return False;
2498                 }
2499
2500                 if (ismyip(the_cli->dest_ip)) {
2501                         DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
2502                         cli_shutdown(the_cli);
2503                         return False;
2504                 }
2505         }
2506         else {
2507                 the_cli->dest_ip.s_addr = client_ip->s_addr;
2508                 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2509                         inet_ntoa(*client_ip) ));
2510         }
2511
2512         if (!cli_connect(the_cli, remote_machine, &the_cli->dest_ip)) {
2513                 DEBUG(0,("spoolss_connect_to_client: unable to connect to SMB server on machine %s. Error was : %s.\n", remote_machine, cli_errstr(the_cli) ));
2514                 cli_shutdown(the_cli);
2515                 return False;
2516         }
2517   
2518         if (!attempt_netbios_session_request(the_cli, global_myname(), remote_machine, &the_cli->dest_ip)) {
2519                 DEBUG(0,("spoolss_connect_to_client: machine %s rejected the NetBIOS session request.\n", 
2520                         remote_machine));
2521                 cli_shutdown(the_cli);
2522                 return False;
2523         }
2524
2525         the_cli->protocol = PROTOCOL_NT1;
2526         cli_setup_signing_state(the_cli, lp_client_signing());
2527   
2528         if (!cli_negprot(the_cli)) {
2529                 DEBUG(0,("spoolss_connect_to_client: machine %s rejected the negotiate protocol. Error was : %s.\n", remote_machine, cli_errstr(the_cli) ));
2530                 cli_shutdown(the_cli);
2531                 return False;
2532         }
2533
2534         if (the_cli->protocol != PROTOCOL_NT1) {
2535                 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2536                 cli_shutdown(the_cli);
2537                 return False;
2538         }
2539     
2540         /*
2541          * Do an anonymous session setup.
2542          */
2543     
2544         if (!cli_session_setup(the_cli, "", "", 0, "", 0, "")) {
2545                 DEBUG(0,("spoolss_connect_to_client: machine %s rejected the session setup. Error was : %s.\n", remote_machine, cli_errstr(the_cli) ));
2546                 cli_shutdown(the_cli);
2547                 return False;
2548         }
2549     
2550         if (!(the_cli->sec_mode & 1)) {
2551                 DEBUG(0,("spoolss_connect_to_client: machine %s isn't in user level security mode\n", remote_machine));
2552                 cli_shutdown(the_cli);
2553                 return False;
2554         }
2555     
2556         if (!cli_send_tconX(the_cli, "IPC$", "IPC", "", 1)) {
2557                 DEBUG(0,("spoolss_connect_to_client: machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", remote_machine, cli_errstr(the_cli) ));
2558                 cli_shutdown(the_cli);
2559                 return False;
2560         }
2561
2562         /*
2563          * Ok - we have an anonymous connection to the IPC$ share.
2564          * Now start the NT Domain stuff :-).
2565          */
2566
2567         if(cli_nt_session_open(the_cli, PI_SPOOLSS) == False) {
2568                 DEBUG(0,("spoolss_connect_to_client: unable to open the domain client session to machine %s. Error was : %s.\n", remote_machine, cli_errstr(the_cli)));
2569                 cli_nt_session_close(the_cli);
2570                 cli_ulogoff(the_cli);
2571                 cli_shutdown(the_cli);
2572                 return False;
2573         } 
2574
2575         return True;
2576 }
2577
2578 /***************************************************************************
2579  Connect to the client.
2580 ****************************************************************************/
2581
2582 static BOOL srv_spoolss_replyopenprinter(int snum, const char *printer, 
2583                                         uint32 localprinter, uint32 type, 
2584                                         POLICY_HND *handle, struct in_addr *client_ip)
2585 {
2586         WERROR result;
2587
2588         /*
2589          * If it's the first connection, contact the client
2590          * and connect to the IPC$ share anonymously
2591          */
2592         if (smb_connections==0) {
2593                 fstring unix_printer;
2594
2595                 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2596
2597                 ZERO_STRUCT(notify_cli);
2598
2599                 if(!spoolss_connect_to_client(&notify_cli, client_ip, unix_printer))
2600                         return False;
2601                         
2602                 message_register(MSG_PRINTER_NOTIFY2, receive_notify2_message_list);
2603                 /* Tell the connections db we're now interested in printer
2604                  * notify messages. */
2605                 register_message_flags( True, FLAG_MSG_PRINTING );
2606         }
2607
2608         /* 
2609          * Tell the specific printing tdb we want messages for this printer
2610          * by registering our PID.
2611          */
2612
2613         if (!print_notify_register_pid(snum))
2614                 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2615
2616         smb_connections++;
2617
2618         result = cli_spoolss_reply_open_printer(&notify_cli, notify_cli.mem_ctx, printer, localprinter, 
2619                         type, handle);
2620                         
2621         if (!W_ERROR_IS_OK(result))
2622                 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2623                         dos_errstr(result)));
2624
2625         return (W_ERROR_IS_OK(result)); 
2626 }
2627
2628 /********************************************************************
2629  * _spoolss_rffpcnex
2630  * ReplyFindFirstPrinterChangeNotifyEx
2631  *
2632  * before replying OK: status=0 a rpc call is made to the workstation
2633  * asking ReplyOpenPrinter 
2634  *
2635  * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2636  * called from api_spoolss_rffpcnex
2637  ********************************************************************/
2638
2639 WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u)
2640 {
2641         POLICY_HND *handle = &q_u->handle;
2642         uint32 flags = q_u->flags;
2643         uint32 options = q_u->options;
2644         UNISTR2 *localmachine = &q_u->localmachine;
2645         uint32 printerlocal = q_u->printerlocal;
2646         int snum = -1;
2647         SPOOL_NOTIFY_OPTION *option = q_u->option;
2648         struct in_addr client_ip;
2649
2650         /* store the notify value in the printer struct */
2651
2652         Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2653
2654         if (!Printer) {
2655                 DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2656                 return WERR_BADFID;
2657         }
2658
2659         Printer->notify.flags=flags;
2660         Printer->notify.options=options;
2661         Printer->notify.printerlocal=printerlocal;
2662
2663         if (Printer->notify.option)
2664                 free_spool_notify_option(&Printer->notify.option);
2665
2666         Printer->notify.option=dup_spool_notify_option(option);
2667
2668         unistr2_to_ascii(Printer->notify.localmachine, localmachine, 
2669                        sizeof(Printer->notify.localmachine)-1);
2670
2671         /* Connect to the client machine and send a ReplyOpenPrinter */
2672
2673         if ( Printer->printer_type == PRINTER_HANDLE_IS_PRINTSERVER)
2674                 snum = -1;
2675         else if ( (Printer->printer_type == PRINTER_HANDLE_IS_PRINTER) &&
2676                         !get_printer_snum(p, handle, &snum) )
2677                 return WERR_BADFID;
2678                 
2679         client_ip.s_addr = inet_addr(p->conn->client_address);
2680
2681         if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2682                                         Printer->notify.printerlocal, 1,
2683                                         &Printer->notify.client_hnd, &client_ip))
2684                 return WERR_SERVER_UNAVAILABLE;
2685
2686         Printer->notify.client_connected=True;
2687
2688         return WERR_OK;
2689 }
2690
2691 /*******************************************************************
2692  * fill a notify_info_data with the servername
2693  ********************************************************************/
2694
2695 void spoolss_notify_server_name(int snum, 
2696                                        SPOOL_NOTIFY_INFO_DATA *data, 
2697                                        print_queue_struct *queue,
2698                                        NT_PRINTER_INFO_LEVEL *printer,
2699                                        TALLOC_CTX *mem_ctx) 
2700 {
2701         pstring temp_name, temp;
2702         uint32 len;
2703
2704         slprintf(temp_name, sizeof(temp_name)-1, "\\\\%s", get_called_name());
2705
2706         len = rpcstr_push(temp, temp_name, sizeof(temp)-2, STR_TERMINATE);
2707
2708         data->notify_data.data.length = len;
2709         data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
2710
2711         if (!data->notify_data.data.string) {
2712                 data->notify_data.data.length = 0;
2713                 return;
2714         }
2715         
2716         memcpy(data->notify_data.data.string, temp, len);
2717 }
2718
2719 /*******************************************************************
2720  * fill a notify_info_data with the printername (not including the servername).
2721  ********************************************************************/
2722
2723 void spoolss_notify_printer_name(int snum, 
2724                                         SPOOL_NOTIFY_INFO_DATA *data, 
2725                                         print_queue_struct *queue,
2726                                         NT_PRINTER_INFO_LEVEL *printer,
2727                                         TALLOC_CTX *mem_ctx)
2728 {
2729         pstring temp;
2730         uint32 len;
2731                 
2732         /* the notify name should not contain the \\server\ part */
2733         char *p = strrchr(printer->info_2->printername, '\\');
2734
2735         if (!p) {
2736                 p = printer->info_2->printername;
2737         } else {
2738                 p++;
2739         }
2740
2741         len = rpcstr_push(temp, p, sizeof(temp)-2, STR_TERMINATE);
2742
2743         data->notify_data.data.length = len;
2744         data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
2745         
2746         if (!data->notify_data.data.string) {
2747                 data->notify_data.data.length = 0;
2748                 return;
2749         }
2750         
2751         memcpy(data->notify_data.data.string, temp, len);
2752 }
2753
2754 /*******************************************************************
2755  * fill a notify_info_data with the servicename
2756  ********************************************************************/
2757
2758 void spoolss_notify_share_name(int snum, 
2759                                       SPOOL_NOTIFY_INFO_DATA *data, 
2760                                       print_queue_struct *queue,
2761                                       NT_PRINTER_INFO_LEVEL *printer,
2762                                       TALLOC_CTX *mem_ctx)
2763 {
2764         pstring temp;
2765         uint32 len;
2766
2767         len = rpcstr_push(temp, lp_servicename(snum), sizeof(temp)-2, STR_TERMINATE);
2768
2769         data->notify_data.data.length = len;
2770         data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
2771         
2772         if (!data->notify_data.data.string) {
2773                 data->notify_data.data.length = 0;
2774                 return;
2775         }
2776         
2777         memcpy(data->notify_data.data.string, temp, len);
2778 }
2779
2780 /*******************************************************************
2781  * fill a notify_info_data with the port name
2782  ********************************************************************/
2783
2784 void spoolss_notify_port_name(int snum, 
2785                                      SPOOL_NOTIFY_INFO_DATA *data, 
2786                                      print_queue_struct *queue,
2787                                      NT_PRINTER_INFO_LEVEL *printer,
2788                                      TALLOC_CTX *mem_ctx)
2789 {
2790         pstring temp;
2791         uint32 len;
2792
2793         /* even if it's strange, that's consistant in all the code */
2794
2795         len = rpcstr_push(temp, printer->info_2->portname, sizeof(temp)-2, STR_TERMINATE);
2796
2797         data->notify_data.data.length = len;
2798         data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
2799         
2800         if (!data->notify_data.data.string) {
2801                 data->notify_data.data.length = 0;
2802                 return;
2803         }
2804         
2805         memcpy(data->notify_data.data.string, temp, len);
2806 }
2807
2808 /*******************************************************************
2809  * fill a notify_info_data with the printername
2810  * but it doesn't exist, have to see what to do
2811  ********************************************************************/
2812
2813 void spoolss_notify_driver_name(int snum, 
2814                                        SPOOL_NOTIFY_INFO_DATA *data,
2815                                        print_queue_struct *queue,
2816                                        NT_PRINTER_INFO_LEVEL *printer,
2817                                        TALLOC_CTX *mem_ctx)
2818 {
2819         pstring temp;
2820         uint32 len;
2821
2822         len = rpcstr_push(temp, printer->info_2->drivername, sizeof(temp)-2, STR_TERMINATE);
2823
2824         data->notify_data.data.length = len;
2825         data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
2826         
2827         if (!data->notify_data.data.string) {
2828                 data->notify_data.data.length = 0;
2829                 return;
2830         }
2831         
2832         memcpy(data->notify_data.data.string, temp, len);
2833 }
2834
2835 /*******************************************************************
2836  * fill a notify_info_data with the comment
2837  ********************************************************************/
2838
2839 void spoolss_notify_comment(int snum, 
2840                                    SPOOL_NOTIFY_INFO_DATA *data,
2841                                    print_queue_struct *queue,
2842                                    NT_PRINTER_INFO_LEVEL *printer,
2843                                    TALLOC_CTX *mem_ctx)
2844 {
2845         pstring temp;
2846         uint32 len;
2847
2848         if (*printer->info_2->comment == '\0')
2849                 len = rpcstr_push(temp, lp_comment(snum), sizeof(temp)-2, STR_TERMINATE);
2850         else
2851                 len = rpcstr_push(temp, printer->info_2->comment, sizeof(temp)-2, STR_TERMINATE);
2852
2853         data->notify_data.data.length = len;
2854         data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
2855         
2856         if (!data->notify_data.data.string) {
2857                 data->notify_data.data.length = 0;
2858                 return;
2859         }
2860         
2861         memcpy(data->notify_data.data.string, temp, len);
2862 }
2863
2864 /*******************************************************************
2865  * fill a notify_info_data with the comment
2866  * location = "Room 1, floor 2, building 3"
2867  ********************************************************************/
2868
2869 void spoolss_notify_location(int snum, 
2870                                     SPOOL_NOTIFY_INFO_DATA *data,
2871                                     print_queue_struct *queue,
2872                                     NT_PRINTER_INFO_LEVEL *printer,
2873                                     TALLOC_CTX *mem_ctx)
2874 {
2875         pstring temp;
2876         uint32 len;
2877
2878         len = rpcstr_push(temp, printer->info_2->location,sizeof(temp)-2, STR_TERMINATE);
2879
2880         data->notify_data.data.length = len;
2881         data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
2882         
2883         if (!data->notify_data.data.string) {
2884                 data->notify_data.data.length = 0;
2885                 return;
2886         }
2887         
2888         memcpy(data->notify_data.data.string, temp, len);
2889 }
2890
2891 /*******************************************************************
2892  * fill a notify_info_data with the device mode
2893  * jfm:xxxx don't to it for know but that's a real problem !!!
2894  ********************************************************************/
2895
2896 static void spoolss_notify_devmode(int snum, 
2897                                    SPOOL_NOTIFY_INFO_DATA *data,
2898                                    print_queue_struct *queue,
2899                                    NT_PRINTER_INFO_LEVEL *printer,
2900                                    TALLOC_CTX *mem_ctx)
2901 {
2902 }
2903
2904 /*******************************************************************
2905  * fill a notify_info_data with the separator file name
2906  ********************************************************************/
2907
2908 void spoolss_notify_sepfile(int snum, 
2909                                    SPOOL_NOTIFY_INFO_DATA *data, 
2910                                    print_queue_struct *queue,
2911                                    NT_PRINTER_INFO_LEVEL *printer,
2912                                    TALLOC_CTX *mem_ctx)
2913 {
2914         pstring temp;
2915         uint32 len;
2916
2917         len = rpcstr_push(temp, printer->info_2->sepfile, sizeof(temp)-2, STR_TERMINATE);
2918
2919         data->notify_data.data.length = len;
2920         data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
2921         
2922         if (!data->notify_data.data.string) {
2923                 data->notify_data.data.length = 0;
2924                 return;
2925         }
2926         
2927         memcpy(data->notify_data.data.string, temp, len);
2928 }
2929
2930 /*******************************************************************
2931  * fill a notify_info_data with the print processor
2932  * jfm:xxxx return always winprint to indicate we don't do anything to it
2933  ********************************************************************/
2934
2935 void spoolss_notify_print_processor(int snum, 
2936                                            SPOOL_NOTIFY_INFO_DATA *data,
2937                                            print_queue_struct *queue,
2938                                            NT_PRINTER_INFO_LEVEL *printer,
2939                                            TALLOC_CTX *mem_ctx)
2940 {
2941         pstring temp;
2942         uint32 len;
2943
2944         len = rpcstr_push(temp,  printer->info_2->printprocessor, sizeof(temp)-2, STR_TERMINATE);
2945
2946         data->notify_data.data.length = len;
2947         data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
2948         
2949         if (!data->notify_data.data.string) {
2950                 data->notify_data.data.length = 0;
2951                 return;
2952         }
2953         
2954         memcpy(data->notify_data.data.string, temp, len);
2955 }
2956
2957 /*******************************************************************
2958  * fill a notify_info_data with the print processor options
2959  * jfm:xxxx send an empty string
2960  ********************************************************************/
2961
2962 void spoolss_notify_parameters(int snum, 
2963                                       SPOOL_NOTIFY_INFO_DATA *data,
2964                                       print_queue_struct *queue,
2965                                       NT_PRINTER_INFO_LEVEL *printer,
2966                                       TALLOC_CTX *mem_ctx)
2967 {
2968         pstring temp;
2969         uint32 len;
2970
2971         len = rpcstr_push(temp,  printer->info_2->parameters, sizeof(temp)-2, STR_TERMINATE);
2972
2973         data->notify_data.data.length = len;
2974         data->notify_data.data.string = (uint16 *)talloc(mem_ctx, len);
2975         
2976         if (!data->notify_data.data.string) {
2977                 data->notify_data.data.length = 0;
2978                 return;
2979         }
2980         
2981         memcpy(data->notify_data.data.string, temp, len);
2982 }
2983
2984 /*******************************************************************
2985  * fill&nb