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