a5484f8974cf7c9d7f2664c46cffc054344e833a
[ira/wip.git] / source3 / 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  *  Copyright (C) Guenther Deschner            2009-2010.
11  *
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 3 of the License, or
15  *  (at your option) any later version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
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 #include "../librpc/gen_ndr/srv_spoolss.h"
31 #include "../librpc/gen_ndr/cli_spoolss.h"
32
33 /* macros stolen from s4 spoolss server */
34 #define SPOOLSS_BUFFER_UNION(fn,ic,info,level) \
35         ((info)?ndr_size_##fn(info, level, ic, 0):0)
36
37 #define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,ic,info,level,count) \
38         ((info)?ndr_size_##fn##_info(mem_ctx, ic, level, count, info):0)
39
40 #define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,ic,info,count) \
41         ((info)?ndr_size_##fn##_info(mem_ctx, ic, count, info):0)
42
43 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
44
45
46 extern userdom_struct current_user_info;
47
48 #undef DBGC_CLASS
49 #define DBGC_CLASS DBGC_RPC_SRV
50
51 #ifndef MAX_OPEN_PRINTER_EXS
52 #define MAX_OPEN_PRINTER_EXS 50
53 #endif
54
55 #define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
56 #define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
57
58 static Printer_entry *printers_list;
59
60 typedef struct _counter_printer_0 {
61         struct _counter_printer_0 *next;
62         struct _counter_printer_0 *prev;
63
64         int snum;
65         uint32_t counter;
66 } counter_printer_0;
67
68 static counter_printer_0 *counter_list;
69
70 static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
71 static uint32_t smb_connections = 0;
72
73
74 /* in printing/nt_printing.c */
75
76 extern struct standard_mapping printer_std_mapping, printserver_std_mapping;
77
78 /* API table for Xcv Monitor functions */
79
80 struct xcv_api_table {
81         const char *name;
82         WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
83 };
84
85 /********************************************************************
86  * Canonicalize servername.
87  ********************************************************************/
88
89 static const char *canon_servername(const char *servername)
90 {
91         const char *pservername = servername;
92         while (*pservername == '\\') {
93                 pservername++;
94         }
95         return pservername;
96 }
97
98 /* translate between internal status numbers and NT status numbers */
99 static int nt_printj_status(int v)
100 {
101         switch (v) {
102         case LPQ_QUEUED:
103                 return 0;
104         case LPQ_PAUSED:
105                 return JOB_STATUS_PAUSED;
106         case LPQ_SPOOLING:
107                 return JOB_STATUS_SPOOLING;
108         case LPQ_PRINTING:
109                 return JOB_STATUS_PRINTING;
110         case LPQ_ERROR:
111                 return JOB_STATUS_ERROR;
112         case LPQ_DELETING:
113                 return JOB_STATUS_DELETING;
114         case LPQ_OFFLINE:
115                 return JOB_STATUS_OFFLINE;
116         case LPQ_PAPEROUT:
117                 return JOB_STATUS_PAPEROUT;
118         case LPQ_PRINTED:
119                 return JOB_STATUS_PRINTED;
120         case LPQ_DELETED:
121                 return JOB_STATUS_DELETED;
122         case LPQ_BLOCKED:
123                 return JOB_STATUS_BLOCKED_DEVQ;
124         case LPQ_USER_INTERVENTION:
125                 return JOB_STATUS_USER_INTERVENTION;
126         }
127         return 0;
128 }
129
130 static int nt_printq_status(int v)
131 {
132         switch (v) {
133         case LPQ_PAUSED:
134                 return PRINTER_STATUS_PAUSED;
135         case LPQ_QUEUED:
136         case LPQ_SPOOLING:
137         case LPQ_PRINTING:
138                 return 0;
139         }
140         return 0;
141 }
142
143 /***************************************************************************
144  Disconnect from the client
145 ****************************************************************************/
146
147 static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle)
148 {
149         WERROR result;
150         NTSTATUS status;
151
152         /*
153          * Tell the specific printing tdb we no longer want messages for this printer
154          * by deregistering our PID.
155          */
156
157         if (!print_notify_deregister_pid(snum))
158                 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
159
160         /* weird if the test succeds !!! */
161         if (smb_connections==0) {
162                 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
163                 return;
164         }
165
166         status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
167                                                   handle,
168                                                   &result);
169         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
170                 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
171                         win_errstr(result)));
172
173         /* if it's the last connection, deconnect the IPC$ share */
174         if (smb_connections==1) {
175
176                 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
177                 notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */
178
179                 messaging_deregister(smbd_messaging_context(),
180                                      MSG_PRINTER_NOTIFY2, NULL);
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 int printer_entry_destructor(Printer_entry *Printer)
196 {
197         if (Printer->notify.client_connected == true) {
198                 int snum = -1;
199
200                 if ( Printer->printer_type == SPLHND_SERVER) {
201                         snum = -1;
202                         srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
203                 } else if (Printer->printer_type == SPLHND_PRINTER) {
204                         snum = print_queue_snum(Printer->sharename);
205                         if (snum != -1)
206                                 srv_spoolss_replycloseprinter(snum,
207                                                 &Printer->notify.client_hnd);
208                 }
209         }
210
211         Printer->notify.flags=0;
212         Printer->notify.options=0;
213         Printer->notify.localmachine[0]='\0';
214         Printer->notify.printerlocal=0;
215         TALLOC_FREE(Printer->notify.option);
216         Printer->notify.client_connected = false;
217
218         free_nt_devicemode( &Printer->nt_devmode );
219         free_a_printer( &Printer->printer_info, 2 );
220
221         /* Remove from the internal list. */
222         DLIST_REMOVE(printers_list, Printer);
223         return 0;
224 }
225
226 /****************************************************************************
227   find printer index by handle
228 ****************************************************************************/
229
230 static Printer_entry *find_printer_index_by_hnd(pipes_struct *p,
231                                                 struct policy_handle *hnd)
232 {
233         Printer_entry *find_printer = NULL;
234
235         if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
236                 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
237                 return NULL;
238         }
239
240         return find_printer;
241 }
242
243 /****************************************************************************
244  Close printer index by handle.
245 ****************************************************************************/
246
247 static bool close_printer_handle(pipes_struct *p, struct policy_handle *hnd)
248 {
249         Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
250
251         if (!Printer) {
252                 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
253                         OUR_HANDLE(hnd)));
254                 return false;
255         }
256
257         close_policy_hnd(p, hnd);
258
259         return true;
260 }
261
262 /****************************************************************************
263  Delete a printer given a handle.
264 ****************************************************************************/
265
266 static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename)
267 {
268         char *cmd = lp_deleteprinter_cmd();
269         char *command = NULL;
270         int ret;
271         SE_PRIV se_printop = SE_PRINT_OPERATOR;
272         bool is_print_op = false;
273
274         /* can't fail if we don't try */
275
276         if ( !*cmd )
277                 return WERR_OK;
278
279         command = talloc_asprintf(ctx,
280                         "%s \"%s\"",
281                         cmd, sharename);
282         if (!command) {
283                 return WERR_NOMEM;
284         }
285         if ( token )
286                 is_print_op = user_has_privileges( token, &se_printop );
287
288         DEBUG(10,("Running [%s]\n", command));
289
290         /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
291
292         if ( is_print_op )
293                 become_root();
294
295         if ( (ret = smbrun(command, NULL)) == 0 ) {
296                 /* Tell everyone we updated smb.conf. */
297                 message_send_all(smbd_messaging_context(),
298                                  MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
299         }
300
301         if ( is_print_op )
302                 unbecome_root();
303
304         /********** END SePrintOperatorPrivlege BLOCK **********/
305
306         DEBUGADD(10,("returned [%d]\n", ret));
307
308         TALLOC_FREE(command);
309
310         if (ret != 0)
311                 return WERR_BADFID; /* What to return here? */
312
313         /* go ahead and re-read the services immediately */
314         become_root();
315         reload_services(false);
316         unbecome_root();
317
318         if ( lp_servicenumber( sharename )  > 0 )
319                 return WERR_ACCESS_DENIED;
320
321         return WERR_OK;
322 }
323
324 /****************************************************************************
325  Delete a printer given a handle.
326 ****************************************************************************/
327
328 static WERROR delete_printer_handle(pipes_struct *p, struct policy_handle *hnd)
329 {
330         Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
331
332         if (!Printer) {
333                 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
334                         OUR_HANDLE(hnd)));
335                 return WERR_BADFID;
336         }
337
338         /*
339          * It turns out that Windows allows delete printer on a handle
340          * opened by an admin user, then used on a pipe handle created
341          * by an anonymous user..... but they're working on security.... riiight !
342          * JRA.
343          */
344
345         if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
346                 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
347                 return WERR_ACCESS_DENIED;
348         }
349
350         /* this does not need a become root since the access check has been
351            done on the handle already */
352
353         if (del_a_printer( Printer->sharename ) != 0) {
354                 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
355                 return WERR_BADFID;
356         }
357
358         return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
359                                    Printer->sharename );
360 }
361
362 /****************************************************************************
363  Return the snum of a printer corresponding to an handle.
364 ****************************************************************************/
365
366 static bool get_printer_snum(pipes_struct *p, struct policy_handle *hnd,
367                              int *number, struct share_params **params)
368 {
369         Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
370
371         if (!Printer) {
372                 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
373                         OUR_HANDLE(hnd)));
374                 return false;
375         }
376
377         switch (Printer->printer_type) {
378                 case SPLHND_PRINTER:
379                         DEBUG(4,("short name:%s\n", Printer->sharename));
380                         *number = print_queue_snum(Printer->sharename);
381                         return (*number != -1);
382                 case SPLHND_SERVER:
383                         return false;
384                 default:
385                         return false;
386         }
387 }
388
389 /****************************************************************************
390  Set printer handle type.
391  Check if it's \\server or \\server\printer
392 ****************************************************************************/
393
394 static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename)
395 {
396         DEBUG(3,("Setting printer type=%s\n", handlename));
397
398         if ( strlen(handlename) < 3 ) {
399                 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
400                 return false;
401         }
402
403         /* it's a print server */
404         if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
405                 DEBUGADD(4,("Printer is a print server\n"));
406                 Printer->printer_type = SPLHND_SERVER;
407         }
408         /* it's a printer (set_printer_hnd_name() will handle port monitors */
409         else {
410                 DEBUGADD(4,("Printer is a printer\n"));
411                 Printer->printer_type = SPLHND_PRINTER;
412         }
413
414         return true;
415 }
416
417 /****************************************************************************
418  Set printer handle name..  Accept names like \\server, \\server\printer,
419  \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port"    See
420  the MSDN docs regarding OpenPrinter() for details on the XcvData() and
421  XcvDataPort() interface.
422 ****************************************************************************/
423
424 static bool set_printer_hnd_name(Printer_entry *Printer, const char *handlename)
425 {
426         int snum;
427         int n_services=lp_numservices();
428         char *aprinter, *printername;
429         const char *servername;
430         fstring sname;
431         bool found = false;
432         NT_PRINTER_INFO_LEVEL *printer = NULL;
433         WERROR result;
434
435         DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
436                 (unsigned long)strlen(handlename)));
437
438         aprinter = CONST_DISCARD(char *, handlename);
439         if ( *handlename == '\\' ) {
440                 servername = canon_servername(handlename);
441                 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
442                         *aprinter = '\0';
443                         aprinter++;
444                 }
445         } else {
446                 servername = global_myname();
447         }
448
449         /* save the servername to fill in replies on this handle */
450
451         if ( !is_myname_or_ipaddr( servername ) )
452                 return false;
453
454         fstrcpy( Printer->servername, servername );
455
456         if ( Printer->printer_type == SPLHND_SERVER )
457                 return true;
458
459         if ( Printer->printer_type != SPLHND_PRINTER )
460                 return false;
461
462         DEBUGADD(5, ("searching for [%s]\n", aprinter ));
463
464         /* check for the Port Monitor Interface */
465
466         if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
467                 Printer->printer_type = SPLHND_PORTMON_TCP;
468                 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
469                 found = true;
470         }
471         else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
472                 Printer->printer_type = SPLHND_PORTMON_LOCAL;
473                 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
474                 found = true;
475         }
476
477         /* Search all sharenames first as this is easier than pulling
478            the printer_info_2 off of disk. Don't use find_service() since
479            that calls out to map_username() */
480
481         /* do another loop to look for printernames */
482
483         for (snum=0; !found && snum<n_services; snum++) {
484
485                 /* no point going on if this is not a printer */
486
487                 if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
488                         continue;
489
490                 fstrcpy(sname, lp_servicename(snum));
491                 if ( strequal( aprinter, sname ) ) {
492                         found = true;
493                         break;
494                 }
495
496                 /* no point looking up the printer object if
497                    we aren't allowing printername != sharename */
498
499                 if ( lp_force_printername(snum) )
500                         continue;
501
502                 fstrcpy(sname, lp_servicename(snum));
503
504                 printer = NULL;
505
506                 /* This call doesn't fill in the location or comment from
507                  * a CUPS server for efficiency with large numbers of printers.
508                  * JRA.
509                  */
510
511                 result = get_a_printer_search( NULL, &printer, 2, sname );
512                 if ( !W_ERROR_IS_OK(result) ) {
513                         DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
514                                 sname, win_errstr(result)));
515                         continue;
516                 }
517
518                 /* printername is always returned as \\server\printername */
519                 if ( !(printername = strchr_m(&printer->info_2->printername[2], '\\')) ) {
520                         DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
521                                 printer->info_2->printername));
522                         free_a_printer( &printer, 2);
523                         continue;
524                 }
525
526                 printername++;
527
528                 if ( strequal(printername, aprinter) ) {
529                         free_a_printer( &printer, 2);
530                         found = true;
531                         break;
532                 }
533
534                 DEBUGADD(10, ("printername: %s\n", printername));
535
536                 free_a_printer( &printer, 2);
537         }
538
539         free_a_printer( &printer, 2);
540
541         if ( !found ) {
542                 DEBUGADD(4,("Printer not found\n"));
543                 return false;
544         }
545
546         DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
547
548         fstrcpy(Printer->sharename, sname);
549
550         return true;
551 }
552
553 /****************************************************************************
554  Find first available printer slot. creates a printer handle for you.
555  ****************************************************************************/
556
557 static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd,
558                              const char *name, uint32_t access_granted)
559 {
560         Printer_entry *new_printer;
561
562         DEBUG(10,("open_printer_hnd: name [%s]\n", name));
563
564         new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
565         if (new_printer == NULL) {
566                 return false;
567         }
568         talloc_set_destructor(new_printer, printer_entry_destructor);
569
570         if (!create_policy_hnd(p, hnd, new_printer)) {
571                 TALLOC_FREE(new_printer);
572                 return false;
573         }
574
575         /* Add to the internal list. */
576         DLIST_ADD(printers_list, new_printer);
577
578         new_printer->notify.option=NULL;
579
580         if (!set_printer_hnd_printertype(new_printer, name)) {
581                 close_printer_handle(p, hnd);
582                 return false;
583         }
584
585         if (!set_printer_hnd_name(new_printer, name)) {
586                 close_printer_handle(p, hnd);
587                 return false;
588         }
589
590         new_printer->access_granted = access_granted;
591
592         DEBUG(5, ("%d printer handles active\n",
593                   (int)num_pipe_handles(p->pipe_handles)));
594
595         return true;
596 }
597
598 /***************************************************************************
599  check to see if the client motify handle is monitoring the notification
600  given by (notify_type, notify_field).
601  **************************************************************************/
602
603 static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
604                                       uint16_t notify_field)
605 {
606         return true;
607 }
608
609 static bool is_monitoring_event(Printer_entry *p, uint16_t notify_type,
610                                 uint16_t notify_field)
611 {
612         struct spoolss_NotifyOption *option = p->notify.option;
613         uint32_t i, j;
614
615         /*
616          * Flags should always be zero when the change notify
617          * is registered by the client's spooler.  A user Win32 app
618          * might use the flags though instead of the NOTIFY_OPTION_INFO
619          * --jerry
620          */
621
622         if (!option) {
623                 return false;
624         }
625
626         if (p->notify.flags)
627                 return is_monitoring_event_flags(
628                         p->notify.flags, notify_type, notify_field);
629
630         for (i = 0; i < option->count; i++) {
631
632                 /* Check match for notify_type */
633
634                 if (option->types[i].type != notify_type)
635                         continue;
636
637                 /* Check match for field */
638
639                 for (j = 0; j < option->types[i].count; j++) {
640                         if (option->types[i].fields[j].field == notify_field) {
641                                 return true;
642                         }
643                 }
644         }
645
646         DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
647                    p->servername, p->sharename, notify_type, notify_field));
648
649         return false;
650 }
651
652 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
653         _data->data.integer[0] = _integer; \
654         _data->data.integer[1] = 0;
655
656
657 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
658         _data->data.string.string = talloc_strdup(mem_ctx, _p); \
659         if (!_data->data.string.string) {\
660                 _data->data.string.size = 0; \
661         } \
662         _data->data.string.size = strlen_m_term(_p) * 2;
663
664 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
665         _data->data.devmode.devmode = _devmode;
666
667 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _size, _sd) \
668         _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
669         if (!_data->data.sd.sd) { \
670                 _data->data.sd.sd_size = 0; \
671         } \
672         _data->data.sd.sd_size = _size;
673
674 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
675                                    struct tm *t,
676                                    const char **pp,
677                                    uint32_t *plen)
678 {
679         struct spoolss_Time st;
680         uint32_t len = 16;
681         char *p;
682
683         if (!init_systemtime(&st, t)) {
684                 return;
685         }
686
687         p = talloc_array(mem_ctx, char, len);
688         if (!p) {
689                 return;
690         }
691
692         /*
693          * Systemtime must be linearized as a set of UINT16's.
694          * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
695          */
696
697         SSVAL(p, 0, st.year);
698         SSVAL(p, 2, st.month);
699         SSVAL(p, 4, st.day_of_week);
700         SSVAL(p, 6, st.day);
701         SSVAL(p, 8, st.hour);
702         SSVAL(p, 10, st.minute);
703         SSVAL(p, 12, st.second);
704         SSVAL(p, 14, st.millisecond);
705
706         *pp = p;
707         *plen = len;
708 }
709
710 /* Convert a notification message to a struct spoolss_Notify */
711
712 static void notify_one_value(struct spoolss_notify_msg *msg,
713                              struct spoolss_Notify *data,
714                              TALLOC_CTX *mem_ctx)
715 {
716         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
717 }
718
719 static void notify_string(struct spoolss_notify_msg *msg,
720                           struct spoolss_Notify *data,
721                           TALLOC_CTX *mem_ctx)
722 {
723         /* The length of the message includes the trailing \0 */
724
725         data->data.string.size = msg->len * 2;
726         data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
727         if (!data->data.string.string) {
728                 data->data.string.size = 0;
729                 return;
730         }
731 }
732
733 static void notify_system_time(struct spoolss_notify_msg *msg,
734                                struct spoolss_Notify *data,
735                                TALLOC_CTX *mem_ctx)
736 {
737         data->data.string.string = NULL;
738         data->data.string.size = 0;
739
740         if (msg->len != sizeof(time_t)) {
741                 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
742                           msg->len));
743                 return;
744         }
745
746         init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
747                                &data->data.string.string,
748                                &data->data.string.size);
749 }
750
751 struct notify2_message_table {
752         const char *name;
753         void (*fn)(struct spoolss_notify_msg *msg,
754                    struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
755 };
756
757 static struct notify2_message_table printer_notify_table[] = {
758         /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
759         /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
760         /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
761         /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
762         /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
763         /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
764         /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
765         /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
766         /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
767         /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
768         /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
769         /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
770         /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
771         /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
772         /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
773         /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
774         /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
775         /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
776         /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
777 };
778
779 static struct notify2_message_table job_notify_table[] = {
780         /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
781         /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
782         /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
783         /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
784         /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
785         /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
786         /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
787         /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
788         /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
789         /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
790         /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
791         /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
792         /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
793         /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
794         /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
795         /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
796         /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
797         /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
798         /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
799         /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
800         /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
801         /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
802         /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
803         /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
804 };
805
806
807 /***********************************************************************
808  Allocate talloc context for container object
809  **********************************************************************/
810
811 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
812 {
813         if ( !ctr )
814                 return;
815
816         ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
817
818         return;
819 }
820
821 /***********************************************************************
822  release all allocated memory and zero out structure
823  **********************************************************************/
824
825 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
826 {
827         if ( !ctr )
828                 return;
829
830         if ( ctr->ctx )
831                 talloc_destroy(ctr->ctx);
832
833         ZERO_STRUCTP(ctr);
834
835         return;
836 }
837
838 /***********************************************************************
839  **********************************************************************/
840
841 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
842 {
843         if ( !ctr )
844                 return NULL;
845
846         return ctr->ctx;
847 }
848
849 /***********************************************************************
850  **********************************************************************/
851
852 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
853 {
854         if ( !ctr || !ctr->msg_groups )
855                 return NULL;
856
857         if ( idx >= ctr->num_groups )
858                 return NULL;
859
860         return &ctr->msg_groups[idx];
861
862 }
863
864 /***********************************************************************
865  How many groups of change messages do we have ?
866  **********************************************************************/
867
868 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
869 {
870         if ( !ctr )
871                 return 0;
872
873         return ctr->num_groups;
874 }
875
876 /***********************************************************************
877  Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
878  **********************************************************************/
879
880 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
881 {
882         SPOOLSS_NOTIFY_MSG_GROUP        *groups = NULL;
883         SPOOLSS_NOTIFY_MSG_GROUP        *msg_grp = NULL;
884         SPOOLSS_NOTIFY_MSG              *msg_list = NULL;
885         int                             i, new_slot;
886
887         if ( !ctr || !msg )
888                 return 0;
889
890         /* loop over all groups looking for a matching printer name */
891
892         for ( i=0; i<ctr->num_groups; i++ ) {
893                 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
894                         break;
895         }
896
897         /* add a new group? */
898
899         if ( i == ctr->num_groups ) {
900                 ctr->num_groups++;
901
902                 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
903                         DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
904                         return 0;
905                 }
906                 ctr->msg_groups = groups;
907
908                 /* clear the new entry and set the printer name */
909
910                 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
911                 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
912         }
913
914         /* add the change messages; 'i' is the correct index now regardless */
915
916         msg_grp = &ctr->msg_groups[i];
917
918         msg_grp->num_msgs++;
919
920         if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
921                 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
922                 return 0;
923         }
924         msg_grp->msgs = msg_list;
925
926         new_slot = msg_grp->num_msgs-1;
927         memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
928
929         /* need to allocate own copy of data */
930
931         if ( msg->len != 0 )
932                 msg_grp->msgs[new_slot].notify.data = (char *)
933                         TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
934
935         return ctr->num_groups;
936 }
937
938 /***********************************************************************
939  Send a change notication message on all handles which have a call
940  back registered
941  **********************************************************************/
942
943 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
944 {
945         Printer_entry            *p;
946         TALLOC_CTX               *mem_ctx = notify_ctr_getctx( ctr );
947         SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
948         SPOOLSS_NOTIFY_MSG       *messages;
949         int                      sending_msg_count;
950
951         if ( !msg_group ) {
952                 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
953                 return;
954         }
955
956         messages = msg_group->msgs;
957
958         if ( !messages ) {
959                 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
960                 return;
961         }
962
963         DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
964
965         /* loop over all printers */
966
967         for (p = printers_list; p; p = p->next) {
968                 struct spoolss_Notify *notifies;
969                 uint32_t count = 0;
970                 uint32_t id;
971                 int     i;
972
973                 /* Is there notification on this handle? */
974
975                 if ( !p->notify.client_connected )
976                         continue;
977
978                 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
979
980                 /* For this printer?  Print servers always receive
981                    notifications. */
982
983                 if ( ( p->printer_type == SPLHND_PRINTER )  &&
984                     ( !strequal(msg_group->printername, p->sharename) ) )
985                         continue;
986
987                 DEBUG(10,("Our printer\n"));
988
989                 /* allocate the max entries possible */
990
991                 notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
992                 if (!notifies) {
993                         return;
994                 }
995
996                 /* build the array of change notifications */
997
998                 sending_msg_count = 0;
999
1000                 for ( i=0; i<msg_group->num_msgs; i++ ) {
1001                         SPOOLSS_NOTIFY_MSG      *msg = &messages[i];
1002
1003                         /* Are we monitoring this event? */
1004
1005                         if (!is_monitoring_event(p, msg->type, msg->field))
1006                                 continue;
1007
1008                         sending_msg_count++;
1009
1010
1011                         DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1012                                 msg->type, msg->field, p->sharename));
1013
1014                         /*
1015                          * if the is a printer notification handle and not a job notification
1016                          * type, then set the id to 0.  Other wise just use what was specified
1017                          * in the message.
1018                          *
1019                          * When registering change notification on a print server handle
1020                          * we always need to send back the id (snum) matching the printer
1021                          * for which the change took place.  For change notify registered
1022                          * on a printer handle, this does not matter and the id should be 0.
1023                          *
1024                          * --jerry
1025                          */
1026
1027                         if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1028                                 id = 0;
1029                         else
1030                                 id = msg->id;
1031
1032
1033                         /* Convert unix jobid to smb jobid */
1034
1035                         if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1036                                 id = sysjob_to_jobid(msg->id);
1037
1038                                 if (id == -1) {
1039                                         DEBUG(3, ("no such unix jobid %d\n", msg->id));
1040                                         goto done;
1041                                 }
1042                         }
1043
1044                         construct_info_data( &notifies[count], msg->type, msg->field, id );
1045
1046                         switch(msg->type) {
1047                         case PRINTER_NOTIFY_TYPE:
1048                                 if ( printer_notify_table[msg->field].fn )
1049                                         printer_notify_table[msg->field].fn(msg, &notifies[count], mem_ctx);
1050                                 break;
1051
1052                         case JOB_NOTIFY_TYPE:
1053                                 if ( job_notify_table[msg->field].fn )
1054                                         job_notify_table[msg->field].fn(msg, &notifies[count], mem_ctx);
1055                                 break;
1056
1057                         default:
1058                                 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1059                                 goto done;
1060                         }
1061
1062                         count++;
1063                 }
1064
1065                 if ( sending_msg_count ) {
1066                         NTSTATUS status;
1067                         WERROR werr;
1068                         union spoolss_ReplyPrinterInfo info;
1069                         struct spoolss_NotifyInfo info0;
1070                         uint32_t reply_result;
1071
1072                         info0.version   = 0x2;
1073                         info0.flags     = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1074                         info0.count     = count;
1075                         info0.notifies  = notifies;
1076
1077                         info.info0 = &info0;
1078
1079                         status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
1080                                                                      &p->notify.client_hnd,
1081                                                                      p->notify.change, /* color */
1082                                                                      p->notify.flags,
1083                                                                      &reply_result,
1084                                                                      0, /* reply_type, must be 0 */
1085                                                                      info,
1086                                                                      &werr);
1087                         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1088                                 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1089                                         notify_cli_pipe->srv_name_slash,
1090                                         win_errstr(werr)));
1091                         }
1092                         switch (reply_result) {
1093                                 case 0:
1094                                         break;
1095                                 case PRINTER_NOTIFY_INFO_DISCARDED:
1096                                 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1097                                 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1098                                         break;
1099                                 default:
1100                                         break;
1101                         }
1102                 }
1103         }
1104
1105 done:
1106         DEBUG(8,("send_notify2_changes: Exit...\n"));
1107         return;
1108 }
1109
1110 /***********************************************************************
1111  **********************************************************************/
1112
1113 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1114 {
1115
1116         uint32_t tv_sec, tv_usec;
1117         size_t offset = 0;
1118
1119         /* Unpack message */
1120
1121         offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
1122                              msg->printer);
1123
1124         offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
1125                                 &tv_sec, &tv_usec,
1126                                 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1127
1128         if (msg->len == 0)
1129                 tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
1130                            &msg->notify.value[0], &msg->notify.value[1]);
1131         else
1132                 tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
1133                            &msg->len, &msg->notify.data);
1134
1135         DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1136                   msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1137
1138         tv->tv_sec = tv_sec;
1139         tv->tv_usec = tv_usec;
1140
1141         if (msg->len == 0)
1142                 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1143                           msg->notify.value[1]));
1144         else
1145                 dump_data(3, (uint8_t *)msg->notify.data, msg->len);
1146
1147         return true;
1148 }
1149
1150 /********************************************************************
1151  Receive a notify2 message list
1152  ********************************************************************/
1153
1154 static void receive_notify2_message_list(struct messaging_context *msg,
1155                                          void *private_data,
1156                                          uint32_t msg_type,
1157                                          struct server_id server_id,
1158                                          DATA_BLOB *data)
1159 {
1160         size_t                  msg_count, i;
1161         char                    *buf = (char *)data->data;
1162         char                    *msg_ptr;
1163         size_t                  msg_len;
1164         SPOOLSS_NOTIFY_MSG      notify;
1165         SPOOLSS_NOTIFY_MSG_CTR  messages;
1166         int                     num_groups;
1167
1168         if (data->length < 4) {
1169                 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1170                 return;
1171         }
1172
1173         msg_count = IVAL(buf, 0);
1174         msg_ptr = buf + 4;
1175
1176         DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1177
1178         if (msg_count == 0) {
1179                 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1180                 return;
1181         }
1182
1183         /* initialize the container */
1184
1185         ZERO_STRUCT( messages );
1186         notify_msg_ctr_init( &messages );
1187
1188         /*
1189          * build message groups for each printer identified
1190          * in a change_notify msg.  Remember that a PCN message
1191          * includes the handle returned for the srv_spoolss_replyopenprinter()
1192          * call.  Therefore messages are grouped according to printer handle.
1193          */
1194
1195         for ( i=0; i<msg_count; i++ ) {
1196                 struct timeval msg_tv;
1197
1198                 if (msg_ptr + 4 - buf > data->length) {
1199                         DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1200                         return;
1201                 }
1202
1203                 msg_len = IVAL(msg_ptr,0);
1204                 msg_ptr += 4;
1205
1206                 if (msg_ptr + msg_len - buf > data->length) {
1207                         DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1208                         return;
1209                 }
1210
1211                 /* unpack messages */
1212
1213                 ZERO_STRUCT( notify );
1214                 notify2_unpack_msg( &notify, &msg_tv, msg_ptr, msg_len );
1215                 msg_ptr += msg_len;
1216
1217                 /* add to correct list in container */
1218
1219                 notify_msg_ctr_addmsg( &messages, &notify );
1220
1221                 /* free memory that might have been allocated by notify2_unpack_msg() */
1222
1223                 if ( notify.len != 0 )
1224                         SAFE_FREE( notify.notify.data );
1225         }
1226
1227         /* process each group of messages */
1228
1229         num_groups = notify_msg_ctr_numgroups( &messages );
1230         for ( i=0; i<num_groups; i++ )
1231                 send_notify2_changes( &messages, i );
1232
1233
1234         /* cleanup */
1235
1236         DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1237                 (uint32_t)msg_count ));
1238
1239         notify_msg_ctr_destroy( &messages );
1240
1241         return;
1242 }
1243
1244 /********************************************************************
1245  Send a message to ourself about new driver being installed
1246  so we can upgrade the information for each printer bound to this
1247  driver
1248  ********************************************************************/
1249
1250 static bool srv_spoolss_drv_upgrade_printer(const char *drivername)
1251 {
1252         int len = strlen(drivername);
1253
1254         if (!len)
1255                 return false;
1256
1257         DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1258                 drivername));
1259
1260         messaging_send_buf(smbd_messaging_context(), procid_self(),
1261                            MSG_PRINTER_DRVUPGRADE,
1262                            (uint8_t *)drivername, len+1);
1263
1264         return true;
1265 }
1266
1267 /**********************************************************************
1268  callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1269  over all printers, upgrading ones as necessary
1270  **********************************************************************/
1271
1272 void do_drv_upgrade_printer(struct messaging_context *msg,
1273                             void *private_data,
1274                             uint32_t msg_type,
1275                             struct server_id server_id,
1276                             DATA_BLOB *data)
1277 {
1278         fstring drivername;
1279         int snum;
1280         int n_services = lp_numservices();
1281         size_t len;
1282
1283         len = MIN(data->length,sizeof(drivername)-1);
1284         strncpy(drivername, (const char *)data->data, len);
1285
1286         DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername ));
1287
1288         /* Iterate the printer list */
1289
1290         for (snum=0; snum<n_services; snum++)
1291         {
1292                 if (lp_snum_ok(snum) && lp_print_ok(snum) )
1293                 {
1294                         WERROR result;
1295                         NT_PRINTER_INFO_LEVEL *printer = NULL;
1296
1297                         result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
1298                         if (!W_ERROR_IS_OK(result))
1299                                 continue;
1300
1301                         if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername))
1302                         {
1303                                 DEBUG(6,("Updating printer [%s]\n", printer->info_2->printername));
1304
1305                                 /* all we care about currently is the change_id */
1306
1307                                 result = mod_a_printer(printer, 2);
1308                                 if (!W_ERROR_IS_OK(result)) {
1309                                         DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1310                                                 win_errstr(result)));
1311                                 }
1312                         }
1313
1314                         free_a_printer(&printer, 2);
1315                 }
1316         }
1317
1318         /* all done */
1319 }
1320
1321 /********************************************************************
1322  Update the cache for all printq's with a registered client
1323  connection
1324  ********************************************************************/
1325
1326 void update_monitored_printq_cache( void )
1327 {
1328         Printer_entry *printer = printers_list;
1329         int snum;
1330
1331         /* loop through all printers and update the cache where
1332            client_connected == true */
1333         while ( printer )
1334         {
1335                 if ( (printer->printer_type == SPLHND_PRINTER)
1336                         && printer->notify.client_connected )
1337                 {
1338                         snum = print_queue_snum(printer->sharename);
1339                         print_queue_status( snum, NULL, NULL );
1340                 }
1341
1342                 printer = printer->next;
1343         }
1344
1345         return;
1346 }
1347 /********************************************************************
1348  Send a message to ourself about new driver being installed
1349  so we can upgrade the information for each printer bound to this
1350  driver
1351  ********************************************************************/
1352
1353 static bool srv_spoolss_reset_printerdata(char* drivername)
1354 {
1355         int len = strlen(drivername);
1356
1357         if (!len)
1358                 return false;
1359
1360         DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1361                 drivername));
1362
1363         messaging_send_buf(smbd_messaging_context(), procid_self(),
1364                            MSG_PRINTERDATA_INIT_RESET,
1365                            (uint8_t *)drivername, len+1);
1366
1367         return true;
1368 }
1369
1370 /**********************************************************************
1371  callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1372  over all printers, resetting printer data as neessary
1373  **********************************************************************/
1374
1375 void reset_all_printerdata(struct messaging_context *msg,
1376                            void *private_data,
1377                            uint32_t msg_type,
1378                            struct server_id server_id,
1379                            DATA_BLOB *data)
1380 {
1381         fstring drivername;
1382         int snum;
1383         int n_services = lp_numservices();
1384         size_t len;
1385
1386         len = MIN( data->length, sizeof(drivername)-1 );
1387         strncpy( drivername, (const char *)data->data, len );
1388
1389         DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername ));
1390
1391         /* Iterate the printer list */
1392
1393         for ( snum=0; snum<n_services; snum++ )
1394         {
1395                 if ( lp_snum_ok(snum) && lp_print_ok(snum) )
1396                 {
1397                         WERROR result;
1398                         NT_PRINTER_INFO_LEVEL *printer = NULL;
1399
1400                         result = get_a_printer( NULL, &printer, 2, lp_const_servicename(snum) );
1401                         if ( !W_ERROR_IS_OK(result) )
1402                                 continue;
1403
1404                         /*
1405                          * if the printer is bound to the driver,
1406                          * then reset to the new driver initdata
1407                          */
1408
1409                         if ( printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername) )
1410                         {
1411                                 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer->info_2->printername));
1412
1413                                 if ( !set_driver_init(printer, 2) ) {
1414                                         DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1415                                                 printer->info_2->printername, printer->info_2->drivername));
1416                                 }
1417
1418                                 result = mod_a_printer( printer, 2 );
1419                                 if ( !W_ERROR_IS_OK(result) ) {
1420                                         DEBUG(3,("reset_all_printerdata: mod_a_printer() failed!  (%s)\n",
1421                                                 get_dos_error_msg(result)));
1422                                 }
1423                         }
1424
1425                         free_a_printer( &printer, 2 );
1426                 }
1427         }
1428
1429         /* all done */
1430
1431         return;
1432 }
1433
1434 /****************************************************************
1435  _spoolss_OpenPrinter
1436 ****************************************************************/
1437
1438 WERROR _spoolss_OpenPrinter(pipes_struct *p,
1439                             struct spoolss_OpenPrinter *r)
1440 {
1441         struct spoolss_OpenPrinterEx e;
1442         WERROR werr;
1443
1444         ZERO_STRUCT(e.in.userlevel);
1445
1446         e.in.printername        = r->in.printername;
1447         e.in.datatype           = r->in.datatype;
1448         e.in.devmode_ctr        = r->in.devmode_ctr;
1449         e.in.access_mask        = r->in.access_mask;
1450         e.in.level              = 0;
1451
1452         e.out.handle            = r->out.handle;
1453
1454         werr = _spoolss_OpenPrinterEx(p, &e);
1455
1456         if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1457                 /* OpenPrinterEx returns this for a bad
1458                  * printer name. We must return WERR_INVALID_PRINTER_NAME
1459                  * instead.
1460                  */
1461                 werr = WERR_INVALID_PRINTER_NAME;
1462         }
1463
1464         return werr;
1465 }
1466
1467 /********************************************************************
1468  ********************************************************************/
1469
1470 bool convert_devicemode(const char *printername,
1471                         const struct spoolss_DeviceMode *devmode,
1472                         NT_DEVICEMODE **pp_nt_devmode)
1473 {
1474         NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
1475
1476         /*
1477          * Ensure nt_devmode is a valid pointer
1478          * as we will be overwriting it.
1479          */
1480
1481         if (nt_devmode == NULL) {
1482                 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1483                 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
1484                         return false;
1485         }
1486
1487         fstrcpy(nt_devmode->devicename, devmode->devicename);
1488         fstrcpy(nt_devmode->formname, devmode->formname);
1489
1490         nt_devmode->devicename[31] = '\0';
1491         nt_devmode->formname[31] = '\0';
1492
1493         nt_devmode->specversion         = devmode->specversion;
1494         nt_devmode->driverversion       = devmode->driverversion;
1495         nt_devmode->size                = devmode->size;
1496         nt_devmode->fields              = devmode->fields;
1497         nt_devmode->orientation         = devmode->orientation;
1498         nt_devmode->papersize           = devmode->papersize;
1499         nt_devmode->paperlength         = devmode->paperlength;
1500         nt_devmode->paperwidth          = devmode->paperwidth;
1501         nt_devmode->scale               = devmode->scale;
1502         nt_devmode->copies              = devmode->copies;
1503         nt_devmode->defaultsource       = devmode->defaultsource;
1504         nt_devmode->printquality        = devmode->printquality;
1505         nt_devmode->color               = devmode->color;
1506         nt_devmode->duplex              = devmode->duplex;
1507         nt_devmode->yresolution         = devmode->yresolution;
1508         nt_devmode->ttoption            = devmode->ttoption;
1509         nt_devmode->collate             = devmode->collate;
1510
1511         nt_devmode->logpixels           = devmode->logpixels;
1512         nt_devmode->bitsperpel          = devmode->bitsperpel;
1513         nt_devmode->pelswidth           = devmode->pelswidth;
1514         nt_devmode->pelsheight          = devmode->pelsheight;
1515         nt_devmode->displayflags        = devmode->displayflags;
1516         nt_devmode->displayfrequency    = devmode->displayfrequency;
1517         nt_devmode->icmmethod           = devmode->icmmethod;
1518         nt_devmode->icmintent           = devmode->icmintent;
1519         nt_devmode->mediatype           = devmode->mediatype;
1520         nt_devmode->dithertype          = devmode->dithertype;
1521         nt_devmode->reserved1           = devmode->reserved1;
1522         nt_devmode->reserved2           = devmode->reserved2;
1523         nt_devmode->panningwidth        = devmode->panningwidth;
1524         nt_devmode->panningheight       = devmode->panningheight;
1525
1526         /*
1527          * Only change private and driverextra if the incoming devmode
1528          * has a new one. JRA.
1529          */
1530
1531         if ((devmode->__driverextra_length != 0) && (devmode->driverextra_data.data != NULL)) {
1532                 SAFE_FREE(nt_devmode->nt_dev_private);
1533                 nt_devmode->driverextra = devmode->__driverextra_length;
1534                 if((nt_devmode->nt_dev_private = SMB_MALLOC_ARRAY(uint8_t, nt_devmode->driverextra)) == NULL)
1535                         return false;
1536                 memcpy(nt_devmode->nt_dev_private, devmode->driverextra_data.data, nt_devmode->driverextra);
1537         }
1538
1539         *pp_nt_devmode = nt_devmode;
1540
1541         return true;
1542 }
1543
1544 /****************************************************************
1545  _spoolss_OpenPrinterEx
1546 ****************************************************************/
1547
1548 WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
1549                               struct spoolss_OpenPrinterEx *r)
1550 {
1551         int snum;
1552         Printer_entry *Printer=NULL;
1553
1554         if (!r->in.printername) {
1555                 return WERR_INVALID_PARAM;
1556         }
1557
1558         /* some sanity check because you can open a printer or a print server */
1559         /* aka: \\server\printer or \\server */
1560
1561         DEBUGADD(3,("checking name: %s\n", r->in.printername));
1562
1563         if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
1564                 ZERO_STRUCTP(r->out.handle);
1565                 return WERR_INVALID_PARAM;
1566         }
1567
1568         Printer = find_printer_index_by_hnd(p, r->out.handle);
1569         if ( !Printer ) {
1570                 DEBUG(0,("_spoolss_OpenPrinterEx: logic error.  Can't find printer "
1571                         "handle we created for printer %s\n", r->in.printername));
1572                 close_printer_handle(p, r->out.handle);
1573                 ZERO_STRUCTP(r->out.handle);
1574                 return WERR_INVALID_PARAM;
1575         }
1576
1577         /*
1578          * First case: the user is opening the print server:
1579          *
1580          * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1581          * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1582          *
1583          * Then both Win2k and WinNT clients try an OpenPrinterEx with
1584          * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1585          * or if the user is listed in the smb.conf printer admin parameter.
1586          *
1587          * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1588          * client view printer folder, but does not show the MSAPW.
1589          *
1590          * Note: this test needs code to check access rights here too. Jeremy
1591          * could you look at this?
1592          *
1593          * Second case: the user is opening a printer:
1594          * NT doesn't let us connect to a printer if the connecting user
1595          * doesn't have print permission.
1596          *
1597          * Third case: user is opening a Port Monitor
1598          * access checks same as opening a handle to the print server.
1599          */
1600
1601         switch (Printer->printer_type )
1602         {
1603         case SPLHND_SERVER:
1604         case SPLHND_PORTMON_TCP:
1605         case SPLHND_PORTMON_LOCAL:
1606                 /* Printserver handles use global struct... */
1607
1608                 snum = -1;
1609
1610                 /* Map standard access rights to object specific access rights */
1611
1612                 se_map_standard(&r->in.access_mask,
1613                                 &printserver_std_mapping);
1614
1615                 /* Deny any object specific bits that don't apply to print
1616                    servers (i.e printer and job specific bits) */
1617
1618                 r->in.access_mask &= SPECIFIC_RIGHTS_MASK;
1619
1620                 if (r->in.access_mask &
1621                     ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1622                         DEBUG(3, ("access DENIED for non-printserver bits\n"));
1623                         close_printer_handle(p, r->out.handle);
1624                         ZERO_STRUCTP(r->out.handle);
1625                         return WERR_ACCESS_DENIED;
1626                 }
1627
1628                 /* Allow admin access */
1629
1630                 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1631                 {
1632                         SE_PRIV se_printop = SE_PRINT_OPERATOR;
1633
1634                         if (!lp_ms_add_printer_wizard()) {
1635                                 close_printer_handle(p, r->out.handle);
1636                                 ZERO_STRUCTP(r->out.handle);
1637                                 return WERR_ACCESS_DENIED;
1638                         }
1639
1640                         /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1641                            and not a printer admin, then fail */
1642
1643                         if ((p->server_info->utok.uid != sec_initial_uid()) &&
1644                             !user_has_privileges(p->server_info->ptok,
1645                                                  &se_printop ) &&
1646                             !token_contains_name_in_list(
1647                                     uidtoname(p->server_info->utok.uid),
1648                                     NULL, NULL,
1649                                     p->server_info->ptok,
1650                                     lp_printer_admin(snum))) {
1651                                 close_printer_handle(p, r->out.handle);
1652                                 ZERO_STRUCTP(r->out.handle);
1653                                 return WERR_ACCESS_DENIED;
1654                         }
1655
1656                         r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1657                 }
1658                 else
1659                 {
1660                         r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1661                 }
1662
1663                 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1664                         ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1665
1666                 /* We fall through to return WERR_OK */
1667                 break;
1668
1669         case SPLHND_PRINTER:
1670                 /* NT doesn't let us connect to a printer if the connecting user
1671                    doesn't have print permission.  */
1672
1673                 if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1674                         close_printer_handle(p, r->out.handle);
1675                         ZERO_STRUCTP(r->out.handle);
1676                         return WERR_BADFID;
1677                 }
1678
1679                 if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
1680                         r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1681                 }
1682
1683                 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1684
1685                 /* map an empty access mask to the minimum access mask */
1686                 if (r->in.access_mask == 0x0)
1687                         r->in.access_mask = PRINTER_ACCESS_USE;
1688
1689                 /*
1690                  * If we are not serving the printer driver for this printer,
1691                  * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE.  This
1692                  * will keep NT clients happy  --jerry
1693                  */
1694
1695                 if (lp_use_client_driver(snum)
1696                         && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1697                 {
1698                         r->in.access_mask = PRINTER_ACCESS_USE;
1699                 }
1700
1701                 /* check smb.conf parameters and the the sec_desc */
1702
1703                 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1704                         DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1705                         ZERO_STRUCTP(r->out.handle);
1706                         return WERR_ACCESS_DENIED;
1707                 }
1708
1709                 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1710                                    p->server_info->ptok, snum) ||
1711                     !print_access_check(p->server_info, snum,
1712                                         r->in.access_mask)) {
1713                         DEBUG(3, ("access DENIED for printer open\n"));
1714                         close_printer_handle(p, r->out.handle);
1715                         ZERO_STRUCTP(r->out.handle);
1716                         return WERR_ACCESS_DENIED;
1717                 }
1718
1719                 if ((r->in.access_mask & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1720                         DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1721                         close_printer_handle(p, r->out.handle);
1722                         ZERO_STRUCTP(r->out.handle);
1723                         return WERR_ACCESS_DENIED;
1724                 }
1725
1726                 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1727                         r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1728                 else
1729                         r->in.access_mask = PRINTER_ACCESS_USE;
1730
1731                 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1732                         ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1733
1734                 break;
1735
1736         default:
1737                 /* sanity check to prevent programmer error */
1738                 ZERO_STRUCTP(r->out.handle);
1739                 return WERR_BADFID;
1740         }
1741
1742         Printer->access_granted = r->in.access_mask;
1743
1744         /*
1745          * If the client sent a devmode in the OpenPrinter() call, then
1746          * save it here in case we get a job submission on this handle
1747          */
1748
1749          if ((Printer->printer_type != SPLHND_SERVER) &&
1750              r->in.devmode_ctr.devmode) {
1751                 convert_devicemode(Printer->sharename,
1752                                    r->in.devmode_ctr.devmode,
1753                                    &Printer->nt_devmode);
1754          }
1755
1756 #if 0   /* JERRY -- I'm doubtful this is really effective */
1757         /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1758            optimization in Windows 2000 clients  --jerry */
1759
1760         if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1761                 && (RA_WIN2K == get_remote_arch()) )
1762         {
1763                 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1764                 sys_usleep( 500000 );
1765         }
1766 #endif
1767
1768         return WERR_OK;
1769 }
1770
1771 /****************************************************************************
1772 ****************************************************************************/
1773
1774 static bool printer_info2_to_nt_printer_info2(struct spoolss_SetPrinterInfo2 *r,
1775                                               NT_PRINTER_INFO_LEVEL_2 *d)
1776 {
1777         DEBUG(7,("printer_info2_to_nt_printer_info2\n"));
1778
1779         if (!r || !d) {
1780                 return false;
1781         }
1782
1783         d->attributes           = r->attributes;
1784         d->priority             = r->priority;
1785         d->default_priority     = r->defaultpriority;
1786         d->starttime            = r->starttime;
1787         d->untiltime            = r->untiltime;
1788         d->status               = r->status;
1789         d->cjobs                = r->cjobs;
1790
1791         fstrcpy(d->servername,  r->servername);
1792         fstrcpy(d->printername, r->printername);
1793         fstrcpy(d->sharename,   r->sharename);
1794         fstrcpy(d->portname,    r->portname);
1795         fstrcpy(d->drivername,  r->drivername);
1796         slprintf(d->comment, sizeof(d->comment)-1, "%s", r->comment);
1797         fstrcpy(d->location,    r->location);
1798         fstrcpy(d->sepfile,     r->sepfile);
1799         fstrcpy(d->printprocessor, r->printprocessor);
1800         fstrcpy(d->datatype,    r->datatype);
1801         fstrcpy(d->parameters,  r->parameters);
1802
1803         return true;
1804 }
1805
1806 /****************************************************************************
1807 ****************************************************************************/
1808
1809 static bool convert_printer_info(struct spoolss_SetPrinterInfoCtr *info_ctr,
1810                                  NT_PRINTER_INFO_LEVEL *printer)
1811 {
1812         bool ret;
1813
1814         switch (info_ctr->level) {
1815         case 2:
1816                 /* allocate memory if needed.  Messy because
1817                    convert_printer_info is used to update an existing
1818                    printer or build a new one */
1819
1820                 if (!printer->info_2) {
1821                         printer->info_2 = TALLOC_ZERO_P(printer, NT_PRINTER_INFO_LEVEL_2);
1822                         if (!printer->info_2) {
1823                                 DEBUG(0,("convert_printer_info: "
1824                                         "talloc() failed!\n"));
1825                                 return false;
1826                         }
1827                 }
1828
1829                 ret = printer_info2_to_nt_printer_info2(info_ctr->info.info2,
1830                                                         printer->info_2);
1831                 printer->info_2->setuptime = time(NULL);
1832                 return ret;
1833         }
1834
1835         return false;
1836 }
1837
1838 /****************************************************************
1839  _spoolss_ClosePrinter
1840 ****************************************************************/
1841
1842 WERROR _spoolss_ClosePrinter(pipes_struct *p,
1843                              struct spoolss_ClosePrinter *r)
1844 {
1845         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1846
1847         if (Printer && Printer->document_started) {
1848                 struct spoolss_EndDocPrinter e;
1849
1850                 e.in.handle = r->in.handle;
1851
1852                 _spoolss_EndDocPrinter(p, &e);
1853         }
1854
1855         if (!close_printer_handle(p, r->in.handle))
1856                 return WERR_BADFID;
1857
1858         /* clear the returned printer handle.  Observed behavior
1859            from Win2k server.  Don't think this really matters.
1860            Previous code just copied the value of the closed
1861            handle.    --jerry */
1862
1863         ZERO_STRUCTP(r->out.handle);
1864
1865         return WERR_OK;
1866 }
1867
1868 /****************************************************************
1869  _spoolss_DeletePrinter
1870 ****************************************************************/
1871
1872 WERROR _spoolss_DeletePrinter(pipes_struct *p,
1873                               struct spoolss_DeletePrinter *r)
1874 {
1875         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1876         WERROR result;
1877
1878         if (Printer && Printer->document_started) {
1879                 struct spoolss_EndDocPrinter e;
1880
1881                 e.in.handle = r->in.handle;
1882
1883                 _spoolss_EndDocPrinter(p, &e);
1884         }
1885
1886         result = delete_printer_handle(p, r->in.handle);
1887
1888         update_c_setprinter(false);
1889
1890         return result;
1891 }
1892
1893 /*******************************************************************
1894  * static function to lookup the version id corresponding to an
1895  * long architecture string
1896  ******************************************************************/
1897
1898 static const struct print_architecture_table_node archi_table[]= {
1899
1900         {"Windows 4.0",          SPL_ARCH_WIN40,        0 },
1901         {"Windows NT x86",       SPL_ARCH_W32X86,       2 },
1902         {"Windows NT R4000",     SPL_ARCH_W32MIPS,      2 },
1903         {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA,     2 },
1904         {"Windows NT PowerPC",   SPL_ARCH_W32PPC,       2 },
1905         {"Windows IA64",         SPL_ARCH_IA64,         3 },
1906         {"Windows x64",          SPL_ARCH_X64,          3 },
1907         {NULL,                   "",            -1 }
1908 };
1909
1910 static int get_version_id(const char *arch)
1911 {
1912         int i;
1913
1914         for (i=0; archi_table[i].long_archi != NULL; i++)
1915         {
1916                 if (strcmp(arch, archi_table[i].long_archi) == 0)
1917                         return (archi_table[i].version);
1918         }
1919
1920         return -1;
1921 }
1922
1923 /****************************************************************
1924  _spoolss_DeletePrinterDriver
1925 ****************************************************************/
1926
1927 WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
1928                                     struct spoolss_DeletePrinterDriver *r)
1929 {
1930
1931         struct spoolss_DriverInfo8 *info = NULL;
1932         struct spoolss_DriverInfo8 *info_win2k = NULL;
1933         int                             version;
1934         WERROR                          status;
1935         WERROR                          status_win2k = WERR_ACCESS_DENIED;
1936         SE_PRIV                         se_printop = SE_PRINT_OPERATOR;
1937
1938         /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1939            and not a printer admin, then fail */
1940
1941         if ( (p->server_info->utok.uid != sec_initial_uid())
1942                 && !user_has_privileges(p->server_info->ptok, &se_printop )
1943                 && !token_contains_name_in_list(
1944                         uidtoname(p->server_info->utok.uid), NULL,
1945                         NULL, p->server_info->ptok,
1946                         lp_printer_admin(-1)) )
1947         {
1948                 return WERR_ACCESS_DENIED;
1949         }
1950
1951         /* check that we have a valid driver name first */
1952
1953         if ((version = get_version_id(r->in.architecture)) == -1)
1954                 return WERR_INVALID_ENVIRONMENT;
1955
1956         if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &info, r->in.driver,
1957                                                 r->in.architecture,
1958                                                 version)))
1959         {
1960                 /* try for Win2k driver if "Windows NT x86" */
1961
1962                 if ( version == 2 ) {
1963                         version = 3;
1964                         if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx,
1965                                                                 &info,
1966                                                                 r->in.driver,
1967                                                                 r->in.architecture,
1968                                                                 version))) {
1969                                 status = WERR_UNKNOWN_PRINTER_DRIVER;
1970                                 goto done;
1971                         }
1972                 }
1973                 /* otherwise it was a failure */
1974                 else {
1975                         status = WERR_UNKNOWN_PRINTER_DRIVER;
1976                         goto done;
1977                 }
1978
1979         }
1980
1981         if (printer_driver_in_use(info)) {
1982                 status = WERR_PRINTER_DRIVER_IN_USE;
1983                 goto done;
1984         }
1985
1986         if ( version == 2 )
1987         {
1988                 if (W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx,
1989                                                        &info_win2k,
1990                                                        r->in.driver,
1991                                                        r->in.architecture, 3)))
1992                 {
1993                         /* if we get to here, we now have 2 driver info structures to remove */
1994                         /* remove the Win2k driver first*/
1995
1996                         status_win2k = delete_printer_driver(
1997                                 p, info_win2k, 3, false);
1998                         free_a_printer_driver(info_win2k);
1999
2000                         /* this should not have failed---if it did, report to client */
2001                         if ( !W_ERROR_IS_OK(status_win2k) )
2002                         {
2003                                 status = status_win2k;
2004                                 goto done;
2005                         }
2006                 }
2007         }
2008
2009         status = delete_printer_driver(p, info, version, false);
2010
2011         /* if at least one of the deletes succeeded return OK */
2012
2013         if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2014                 status = WERR_OK;
2015
2016 done:
2017         free_a_printer_driver(info);
2018
2019         return status;
2020 }
2021
2022 /****************************************************************
2023  _spoolss_DeletePrinterDriverEx
2024 ****************************************************************/
2025
2026 WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
2027                                       struct spoolss_DeletePrinterDriverEx *r)
2028 {
2029         struct spoolss_DriverInfo8      *info = NULL;
2030         struct spoolss_DriverInfo8      *info_win2k = NULL;
2031         int                             version;
2032         bool                            delete_files;
2033         WERROR                          status;
2034         WERROR                          status_win2k = WERR_ACCESS_DENIED;
2035         SE_PRIV                         se_printop = SE_PRINT_OPERATOR;
2036
2037         /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2038            and not a printer admin, then fail */
2039
2040         if ( (p->server_info->utok.uid != sec_initial_uid())
2041                 && !user_has_privileges(p->server_info->ptok, &se_printop )
2042                 && !token_contains_name_in_list(
2043                         uidtoname(p->server_info->utok.uid), NULL, NULL,
2044                         p->server_info->ptok, lp_printer_admin(-1)) )
2045         {
2046                 return WERR_ACCESS_DENIED;
2047         }
2048
2049         /* check that we have a valid driver name first */
2050         if ((version = get_version_id(r->in.architecture)) == -1) {
2051                 /* this is what NT returns */
2052                 return WERR_INVALID_ENVIRONMENT;
2053         }
2054
2055         if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
2056                 version = r->in.version;
2057
2058         status = get_a_printer_driver(p->mem_ctx, &info, r->in.driver,
2059                                       r->in.architecture, version);
2060
2061         if ( !W_ERROR_IS_OK(status) )
2062         {
2063                 /*
2064                  * if the client asked for a specific version,
2065                  * or this is something other than Windows NT x86,
2066                  * then we've failed
2067                  */
2068
2069                 if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
2070                         goto done;
2071
2072                 /* try for Win2k driver if "Windows NT x86" */
2073
2074                 version = 3;
2075                 if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &info, r->in.driver,
2076                                                         r->in.architecture,
2077                                                         version))) {
2078                         status = WERR_UNKNOWN_PRINTER_DRIVER;
2079                         goto done;
2080                 }
2081         }
2082
2083         if (printer_driver_in_use(info)) {
2084                 status = WERR_PRINTER_DRIVER_IN_USE;
2085                 goto done;
2086         }
2087
2088         /*
2089          * we have a couple of cases to consider.
2090          * (1) Are any files in use?  If so and DPD_DELTE_ALL_FILE is set,
2091          *     then the delete should fail if **any** files overlap with
2092          *     other drivers
2093          * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2094          *     non-overlapping files
2095          * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2096          *     is set, the do not delete any files
2097          * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2098          */
2099
2100         delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
2101
2102         /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2103
2104         if (delete_files && printer_driver_files_in_use(info, info) & (r->in.delete_flags & DPD_DELETE_ALL_FILES)) {
2105                 /* no idea of the correct error here */
2106                 status = WERR_ACCESS_DENIED;
2107                 goto done;
2108         }
2109
2110
2111         /* also check for W32X86/3 if necessary; maybe we already have? */
2112
2113         if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION)  ) {
2114                 if (W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &info_win2k,
2115                                                        r->in.driver,
2116                                                        r->in.architecture, 3)))
2117                 {
2118
2119                         if (delete_files && printer_driver_files_in_use(info, info_win2k) & (r->in.delete_flags & DPD_DELETE_ALL_FILES) ) {
2120                                 /* no idea of the correct error here */
2121                                 free_a_printer_driver(info_win2k);
2122                                 status = WERR_ACCESS_DENIED;
2123                                 goto done;
2124                         }
2125
2126                         /* if we get to here, we now have 2 driver info structures to remove */
2127                         /* remove the Win2k driver first*/
2128
2129                         status_win2k = delete_printer_driver(
2130                                 p, info_win2k, 3, delete_files);
2131                         free_a_printer_driver(info_win2k);
2132
2133                         /* this should not have failed---if it did, report to client */
2134
2135                         if ( !W_ERROR_IS_OK(status_win2k) )
2136                                 goto done;
2137                 }
2138         }
2139
2140         status = delete_printer_driver(p, info, version, delete_files);
2141
2142         if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2143                 status = WERR_OK;
2144 done:
2145         free_a_printer_driver(info);
2146
2147         return status;
2148 }
2149
2150
2151 /****************************************************************************
2152  Internal routine for removing printerdata
2153  ***************************************************************************/
2154
2155 static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value )
2156 {
2157         return delete_printer_data( printer->info_2, key, value );
2158 }
2159
2160 /****************************************************************************
2161  Internal routine for storing printerdata
2162  ***************************************************************************/
2163
2164 WERROR set_printer_dataex(NT_PRINTER_INFO_LEVEL *printer,
2165                           const char *key, const char *value,
2166                           uint32_t type, uint8_t *data, int real_len)
2167 {
2168         /* the registry objects enforce uniqueness based on value name */
2169
2170         return add_printer_data( printer->info_2, key, value, type, data, real_len );
2171 }
2172
2173 /********************************************************************
2174  GetPrinterData on a printer server Handle.
2175 ********************************************************************/
2176
2177 static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2178                                             const char *value,
2179                                             enum winreg_Type *type,
2180                                             union spoolss_PrinterData *data)
2181 {
2182         DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2183
2184         if (!StrCaseCmp(value, "W3SvcInstalled")) {
2185                 *type = REG_DWORD;
2186                 data->value = 0x00;
2187                 return WERR_OK;
2188         }
2189
2190         if (!StrCaseCmp(value, "BeepEnabled")) {
2191                 *type = REG_DWORD;
2192                 data->value = 0x00;
2193                 return WERR_OK;
2194         }
2195
2196         if (!StrCaseCmp(value, "EventLog")) {
2197                 *type = REG_DWORD;
2198                 /* formally was 0x1b */
2199                 data->value = 0x00;
2200                 return WERR_OK;
2201         }
2202
2203         if (!StrCaseCmp(value, "NetPopup")) {
2204                 *type = REG_DWORD;
2205                 data->value = 0x00;
2206                 return WERR_OK;
2207         }
2208
2209         if (!StrCaseCmp(value, "MajorVersion")) {
2210                 *type = REG_DWORD;
2211
2212                 /* Windows NT 4.0 seems to not allow uploading of drivers
2213                    to a server that reports 0x3 as the MajorVersion.
2214                    need to investigate more how Win2k gets around this .
2215                    -- jerry */
2216
2217                 if (RA_WINNT == get_remote_arch()) {
2218                         data->value = 0x02;
2219                 } else {
2220                         data->value = 0x03;
2221                 }
2222
2223                 return WERR_OK;
2224         }
2225
2226         if (!StrCaseCmp(value, "MinorVersion")) {
2227                 *type = REG_DWORD;
2228                 data->value = 0x00;
2229                 return WERR_OK;
2230         }
2231
2232         /* REG_BINARY
2233          *  uint32_t size        = 0x114
2234          *  uint32_t major       = 5
2235          *  uint32_t minor       = [0|1]
2236          *  uint32_t build       = [2195|2600]
2237          *  extra unicode string = e.g. "Service Pack 3"
2238          */
2239         if (!StrCaseCmp(value, "OSVersion")) {
2240                 DATA_BLOB blob;
2241                 enum ndr_err_code ndr_err;
2242                 struct spoolss_OSVersion os;
2243
2244                 os.major                = 5;    /* Windows 2000 == 5.0 */
2245                 os.minor                = 0;
2246                 os.build                = 2195; /* build */
2247                 os.extra_string         = "";   /* leave extra string empty */
2248
2249                 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, &os,
2250                         (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2251                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2252                         return WERR_GENERAL_FAILURE;
2253                 }
2254
2255                 *type = REG_BINARY;
2256                 data->binary = blob;
2257
2258                 return WERR_OK;
2259         }
2260
2261
2262         if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2263                 *type = REG_SZ;
2264
2265                 data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
2266                 W_ERROR_HAVE_NO_MEMORY(data->string);
2267
2268                 return WERR_OK;
2269         }
2270
2271         if (!StrCaseCmp(value, "Architecture")) {
2272                 *type = REG_SZ;
2273                 data->string = talloc_strdup(mem_ctx,
2274                         lp_parm_const_string(GLOBAL_SECTION_SNUM, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86));
2275                 W_ERROR_HAVE_NO_MEMORY(data->string);
2276
2277                 return WERR_OK;
2278         }
2279
2280         if (!StrCaseCmp(value, "DsPresent")) {
2281                 *type = REG_DWORD;
2282
2283                 /* only show the publish check box if we are a
2284                    member of a AD domain */
2285
2286                 if (lp_security() == SEC_ADS) {
2287                         data->value = 0x01;
2288                 } else {
2289                         data->value = 0x00;
2290                 }
2291                 return WERR_OK;
2292         }
2293
2294         if (!StrCaseCmp(value, "DNSMachineName")) {
2295                 const char *hostname = get_mydnsfullname();
2296
2297                 if (!hostname) {
2298                         return WERR_BADFILE;
2299                 }
2300
2301                 *type = REG_SZ;
2302                 data->string = talloc_strdup(mem_ctx, hostname);
2303                 W_ERROR_HAVE_NO_MEMORY(data->string);
2304
2305                 return WERR_OK;
2306         }
2307
2308         *type = REG_NONE;
2309
2310         return WERR_INVALID_PARAM;
2311 }
2312
2313 /****************************************************************
2314  _spoolss_GetPrinterData
2315 ****************************************************************/
2316
2317 WERROR _spoolss_GetPrinterData(pipes_struct *p,
2318                                struct spoolss_GetPrinterData *r)
2319 {
2320         struct spoolss_GetPrinterDataEx r2;
2321
2322         r2.in.handle            = r->in.handle;
2323         r2.in.key_name          = "PrinterDriverData";
2324         r2.in.value_name        = r->in.value_name;
2325         r2.in.offered           = r->in.offered;
2326         r2.out.type             = r->out.type;
2327         r2.out.data             = r->out.data;
2328         r2.out.needed           = r->out.needed;
2329
2330         return _spoolss_GetPrinterDataEx(p, &r2);
2331 }
2332
2333 /*********************************************************
2334  Connect to the client machine.
2335 **********************************************************/
2336
2337 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2338                         struct sockaddr_storage *client_ss, const char *remote_machine)
2339 {
2340         NTSTATUS ret;
2341         struct cli_state *the_cli;
2342         struct sockaddr_storage rm_addr;
2343         char addr[INET6_ADDRSTRLEN];
2344
2345         if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2346                 DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
2347                         remote_machine));
2348                 if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2349                         DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2350                         return false;
2351                 }
2352                 print_sockaddr(addr, sizeof(addr), &rm_addr);
2353         } else {
2354                 rm_addr = *client_ss;
2355                 print_sockaddr(addr, sizeof(addr), &rm_addr);
2356                 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2357                         addr));
2358         }
2359
2360         if (ismyaddr((struct sockaddr *)&rm_addr)) {
2361                 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
2362                         addr));
2363                 return false;
2364         }
2365
2366         /* setup the connection */
2367         ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2368                 &rm_addr, 0, "IPC$", "IPC",
2369                 "", /* username */
2370                 "", /* domain */
2371                 "", /* password */
2372                 0, lp_client_signing(), NULL );
2373
2374         if ( !NT_STATUS_IS_OK( ret ) ) {
2375                 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2376                         remote_machine ));
2377                 return false;
2378         }
2379
2380         if ( the_cli->protocol != PROTOCOL_NT1 ) {
2381                 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2382                 cli_shutdown(the_cli);
2383                 return false;
2384         }
2385
2386         /*
2387          * Ok - we have an anonymous connection to the IPC$ share.
2388          * Now start the NT Domain stuff :-).
2389          */
2390
2391         ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
2392         if (!NT_STATUS_IS_OK(ret)) {
2393                 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2394                         remote_machine, nt_errstr(ret)));
2395                 cli_shutdown(the_cli);
2396                 return false;
2397         }
2398
2399         return true;
2400 }
2401
2402 /***************************************************************************
2403  Connect to the client.
2404 ****************************************************************************/
2405
2406 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2407                                         uint32_t localprinter, uint32_t type,
2408                                         struct policy_handle *handle,
2409                                         struct sockaddr_storage *client_ss)
2410 {
2411         WERROR result;
2412         NTSTATUS status;
2413
2414         /*
2415          * If it's the first connection, contact the client
2416          * and connect to the IPC$ share anonymously
2417          */
2418         if (smb_connections==0) {
2419                 fstring unix_printer;
2420
2421                 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2422
2423                 if ( !spoolss_connect_to_client( &notify_cli_pipe, client_ss, unix_printer ))
2424                         return false;
2425
2426                 messaging_register(smbd_messaging_context(), NULL,
2427                                    MSG_PRINTER_NOTIFY2,
2428                                    receive_notify2_message_list);
2429                 /* Tell the connections db we're now interested in printer
2430                  * notify messages. */
2431                 register_message_flags(true, FLAG_MSG_PRINT_NOTIFY);
2432         }
2433
2434         /*
2435          * Tell the specific printing tdb we want messages for this printer
2436          * by registering our PID.
2437          */
2438
2439         if (!print_notify_register_pid(snum))
2440                 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2441
2442         smb_connections++;
2443
2444         status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2445                                                  printer,
2446                                                  localprinter,
2447                                                  type,
2448                                                  0,
2449                                                  NULL,
2450                                                  handle,
2451                                                  &result);
2452         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2453                 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2454                         win_errstr(result)));
2455
2456         return (W_ERROR_IS_OK(result));
2457 }
2458
2459 /****************************************************************
2460  ****************************************************************/
2461
2462 static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2463                                                              const struct spoolss_NotifyOption *r)
2464 {
2465         struct spoolss_NotifyOption *option;
2466         uint32_t i,k;
2467
2468         if (!r) {
2469                 return NULL;
2470         }
2471
2472         option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2473         if (!option) {
2474                 return NULL;
2475         }
2476
2477         *option = *r;
2478
2479         if (!option->count) {
2480                 return option;
2481         }
2482
2483         option->types = talloc_zero_array(option,
2484                 struct spoolss_NotifyOptionType, option->count);
2485         if (!option->types) {
2486                 talloc_free(option);
2487                 return NULL;
2488         }
2489
2490         for (i=0; i < option->count; i++) {
2491                 option->types[i] = r->types[i];
2492
2493                 if (option->types[i].count) {
2494                         option->types[i].fields = talloc_zero_array(option,
2495                                 union spoolss_Field, option->types[i].count);
2496                         if (!option->types[i].fields) {
2497                                 talloc_free(option);
2498                                 return NULL;
2499                         }
2500                         for (k=0; k<option->types[i].count; k++) {
2501                                 option->types[i].fields[k] =
2502                                         r->types[i].fields[k];
2503                         }
2504                 }
2505         }
2506
2507         return option;
2508 }
2509
2510 /****************************************************************
2511  * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2512  *
2513  * before replying OK: status=0 a rpc call is made to the workstation
2514  * asking ReplyOpenPrinter
2515  *
2516  * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2517  * called from api_spoolss_rffpcnex
2518 ****************************************************************/
2519
2520 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
2521                                                      struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2522 {
2523         int snum = -1;
2524         struct spoolss_NotifyOption *option = r->in.notify_options;
2525         struct sockaddr_storage client_ss;
2526
2527         /* store the notify value in the printer struct */
2528
2529         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
2530
2531         if (!Printer) {
2532                 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2533                         "Invalid handle (%s:%u:%u).\n",
2534                         OUR_HANDLE(r->in.handle)));
2535                 return WERR_BADFID;
2536         }
2537
2538         Printer->notify.flags           = r->in.flags;
2539         Printer->notify.options         = r->in.options;
2540         Printer->notify.printerlocal    = r->in.printer_local;
2541
2542         TALLOC_FREE(Printer->notify.option);
2543         Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2544
2545         fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2546
2547         /* Connect to the client machine and send a ReplyOpenPrinter */
2548
2549         if ( Printer->printer_type == SPLHND_SERVER)
2550                 snum = -1;
2551         else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2552                         !get_printer_snum(p, r->in.handle, &snum, NULL) )
2553                 return WERR_BADFID;
2554
2555         DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2556                 "client_address is %s\n", p->client_address));
2557
2558         if (!interpret_string_addr(&client_ss, p->client_address,
2559                                    AI_NUMERICHOST)) {
2560                 return WERR_SERVER_UNAVAILABLE;
2561         }
2562
2563         if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2564                                         Printer->notify.printerlocal, 1,
2565                                         &Printer->notify.client_hnd, &client_ss))
2566                 return WERR_SERVER_UNAVAILABLE;
2567
2568         Printer->notify.client_connected = true;
2569
2570         return WERR_OK;
2571 }
2572
2573 /*******************************************************************
2574  * fill a notify_info_data with the servername
2575  ********************************************************************/
2576
2577 void spoolss_notify_server_name(int snum,
2578                                        struct spoolss_Notify *data,
2579                                        print_queue_struct *queue,
2580                                        NT_PRINTER_INFO_LEVEL *printer,
2581                                        TALLOC_CTX *mem_ctx)
2582 {
2583         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->servername);
2584 }
2585
2586 /*******************************************************************
2587  * fill a notify_info_data with the printername (not including the servername).
2588  ********************************************************************/
2589
2590 void spoolss_notify_printer_name(int snum,
2591                                         struct spoolss_Notify *data,
2592                                         print_queue_struct *queue,
2593                                         NT_PRINTER_INFO_LEVEL *printer,
2594                                         TALLOC_CTX *mem_ctx)
2595 {
2596         /* the notify name should not contain the \\server\ part */
2597         char *p = strrchr(printer->info_2->printername, '\\');
2598
2599         if (!p) {
2600                 p = printer->info_2->printername;
2601         } else {
2602                 p++;
2603         }
2604
2605         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2606 }
2607
2608 /*******************************************************************
2609  * fill a notify_info_data with the servicename
2610  ********************************************************************/
2611
2612 void spoolss_notify_share_name(int snum,
2613                                       struct spoolss_Notify *data,
2614                                       print_queue_struct *queue,
2615                                       NT_PRINTER_INFO_LEVEL *printer,
2616                                       TALLOC_CTX *mem_ctx)
2617 {
2618         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2619 }
2620
2621 /*******************************************************************
2622  * fill a notify_info_data with the port name
2623  ********************************************************************/
2624
2625 void spoolss_notify_port_name(int snum,
2626                                      struct spoolss_Notify *data,
2627                                      print_queue_struct *queue,
2628                                      NT_PRINTER_INFO_LEVEL *printer,
2629                                      TALLOC_CTX *mem_ctx)
2630 {
2631         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->portname);
2632 }
2633
2634 /*******************************************************************
2635  * fill a notify_info_data with the printername
2636  * but it doesn't exist, have to see what to do
2637  ********************************************************************/
2638
2639 void spoolss_notify_driver_name(int snum,
2640                                        struct spoolss_Notify *data,
2641                                        print_queue_struct *queue,
2642                                        NT_PRINTER_INFO_LEVEL *printer,
2643                                        TALLOC_CTX *mem_ctx)
2644 {
2645         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->drivername);
2646 }
2647
2648 /*******************************************************************
2649  * fill a notify_info_data with the comment
2650  ********************************************************************/
2651
2652 void spoolss_notify_comment(int snum,
2653                                    struct spoolss_Notify *data,
2654                                    print_queue_struct *queue,
2655                                    NT_PRINTER_INFO_LEVEL *printer,
2656                                    TALLOC_CTX *mem_ctx)
2657 {
2658         char *p;
2659
2660         if (*printer->info_2->comment == '\0') {
2661                 p = lp_comment(snum);
2662         } else {
2663                 p = printer->info_2->comment;
2664         }
2665
2666         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->comment);
2667 }
2668
2669 /*******************************************************************
2670  * fill a notify_info_data with the comment
2671  * location = "Room 1, floor 2, building 3"
2672  ********************************************************************/
2673
2674 void spoolss_notify_location(int snum,
2675                                     struct spoolss_Notify *data,
2676                                     print_queue_struct *queue,
2677                                     NT_PRINTER_INFO_LEVEL *printer,
2678                                     TALLOC_CTX *mem_ctx)
2679 {
2680         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->location);
2681 }
2682
2683 /*******************************************************************
2684  * fill a notify_info_data with the device mode
2685  * jfm:xxxx don't to it for know but that's a real problem !!!
2686  ********************************************************************/
2687
2688 static void spoolss_notify_devmode(int snum,
2689                                    struct spoolss_Notify *data,
2690                                    print_queue_struct *queue,
2691                                    NT_PRINTER_INFO_LEVEL *printer,
2692                                    TALLOC_CTX *mem_ctx)
2693 {
2694         /* for a dummy implementation we have to zero the fields */
2695         SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2696 }
2697
2698 /*******************************************************************
2699  * fill a notify_info_data with the separator file name
2700  ********************************************************************/
2701
2702 void spoolss_notify_sepfile(int snum,
2703                                    struct spoolss_Notify *data,
2704                                    print_queue_struct *queue,
2705                                    NT_PRINTER_INFO_LEVEL *printer,
2706                                    TALLOC_CTX *mem_ctx)
2707 {
2708         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->sepfile);
2709 }
2710
2711 /*******************************************************************
2712  * fill a notify_info_data with the print processor
2713  * jfm:xxxx return always winprint to indicate we don't do anything to it
2714  ********************************************************************/
2715
2716 void spoolss_notify_print_processor(int snum,
2717                                            struct spoolss_Notify *data,
2718                                            print_queue_struct *queue,
2719                                            NT_PRINTER_INFO_LEVEL *printer,
2720                                            TALLOC_CTX *mem_ctx)
2721 {
2722         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->printprocessor);
2723 }
2724
2725 /*******************************************************************
2726  * fill a notify_info_data with the print processor options
2727  * jfm:xxxx send an empty string
2728  ********************************************************************/
2729
2730 void spoolss_notify_parameters(int snum,
2731                                       struct spoolss_Notify *data,
2732                                       print_queue_struct *queue,
2733                                       NT_PRINTER_INFO_LEVEL *printer,
2734                                       TALLOC_CTX *mem_ctx)
2735 {
2736         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->parameters);
2737 }
2738
2739 /*******************************************************************
2740  * fill a notify_info_data with the data type
2741  * jfm:xxxx always send RAW as data type
2742  ********************************************************************/
2743
2744 void spoolss_notify_datatype(int snum,
2745                                     struct spoolss_Notify *data,
2746                                     print_queue_struct *queue,
2747                                     NT_PRINTER_INFO_LEVEL *printer,
2748                                     TALLOC_CTX *mem_ctx)
2749 {
2750         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->datatype);
2751 }
2752
2753 /*******************************************************************
2754  * fill a notify_info_data with the security descriptor
2755  * jfm:xxxx send an null pointer to say no security desc
2756  * have to implement security before !
2757  ********************************************************************/
2758
2759 static void spoolss_notify_security_desc(int snum,
2760                                          struct spoolss_Notify *data,
2761                                          print_queue_struct *queue,
2762                                          NT_PRINTER_INFO_LEVEL *printer,
2763                                          TALLOC_CTX *mem_ctx)
2764 {
2765         SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data,
2766                                           printer->info_2->secdesc_buf->sd_size,
2767                                           printer->info_2->secdesc_buf->sd);
2768 }
2769
2770 /*******************************************************************
2771  * fill a notify_info_data with the attributes
2772  * jfm:xxxx a samba printer is always shared
2773  ********************************************************************/
2774
2775 void spoolss_notify_attributes(int snum,
2776                                       struct spoolss_Notify *data,
2777                                       print_queue_struct *queue,
2778                                       NT_PRINTER_INFO_LEVEL *printer,
2779                                       TALLOC_CTX *mem_ctx)
2780 {
2781         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->attributes);
2782 }
2783
2784 /*******************************************************************
2785  * fill a notify_info_data with the priority
2786  ********************************************************************/
2787
2788 static void spoolss_notify_priority(int snum,
2789                                     struct spoolss_Notify *data,
2790                                     print_queue_struct *queue,
2791                                     NT_PRINTER_INFO_LEVEL *printer,
2792                                     TALLOC_CTX *mem_ctx)
2793 {
2794         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->priority);
2795 }
2796
2797 /*******************************************************************
2798  * fill a notify_info_data with the default priority
2799  ********************************************************************/
2800
2801 static void spoolss_notify_default_priority(int snum,
2802                                             struct spoolss_Notify *data,
2803                                             print_queue_struct *queue,
2804                                             NT_PRINTER_INFO_LEVEL *printer,
2805                                             TALLOC_CTX *mem_ctx)
2806 {
2807         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->default_priority);
2808 }
2809
2810 /*******************************************************************
2811  * fill a notify_info_data with the start time
2812  ********************************************************************/
2813
2814 static void spoolss_notify_start_time(int snum,
2815                                       struct spoolss_Notify *data,
2816                                       print_queue_struct *queue,
2817                                       NT_PRINTER_INFO_LEVEL *printer,
2818                                       TALLOC_CTX *mem_ctx)
2819 {
2820         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->starttime);
2821 }
2822
2823 /*******************************************************************
2824  * fill a notify_info_data with the until time
2825  ********************************************************************/
2826
2827 static void spoolss_notify_until_time(int snum,
2828                                       struct spoolss_Notify *data,
2829                                       print_queue_struct *queue,
2830                                       NT_PRINTER_INFO_LEVEL *printer,
2831                                       TALLOC_CTX *mem_ctx)
2832 {
2833         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->untiltime);
2834 }
2835
2836 /*******************************************************************
2837  * fill a notify_info_data with the status
2838  ********************************************************************/
2839
2840 static void spoolss_notify_status(int snum,
2841                                   struct spoolss_Notify *data,
2842                                   print_queue_struct *queue,
2843                                   NT_PRINTER_INFO_LEVEL *printer,
2844                                   TALLOC_CTX *mem_ctx)
2845 {
2846         print_status_struct status;
2847
2848         print_queue_length(snum, &status);
2849         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
2850 }
2851
2852 /*******************************************************************
2853  * fill a notify_info_data with the number of jobs queued
2854  ********************************************************************/
2855
2856 void spoolss_notify_cjobs(int snum,
2857                                  struct spoolss_Notify *data,
2858                                  print_queue_struct *queue,
2859                                  NT_PRINTER_INFO_LEVEL *printer,
2860                                  TALLOC_CTX *mem_ctx)
2861 {
2862         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
2863 }
2864
2865 /*******************************************************************
2866  * fill a notify_info_data with the average ppm
2867  ********************************************************************/
2868
2869 static void spoolss_notify_average_ppm(int snum,
2870                                        struct spoolss_Notify *data,
2871                                        print_queue_struct *queue,
2872                                        NT_PRINTER_INFO_LEVEL *printer,
2873                                        TALLOC_CTX *mem_ctx)
2874 {
2875         /* always respond 8 pages per minutes */
2876         /* a little hard ! */
2877         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->averageppm);
2878 }
2879
2880 /*******************************************************************
2881  * fill a notify_info_data with username
2882  ********************************************************************/
2883
2884 static void spoolss_notify_username(int snum,
2885                                     struct spoolss_Notify *data,
2886                                     print_queue_struct *queue,
2887                                     NT_PRINTER_INFO_LEVEL *printer,
2888                                     TALLOC_CTX *mem_ctx)
2889 {
2890         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
2891 }
2892
2893 /*******************************************************************
2894  * fill a notify_info_data with job status
2895  ********************************************************************/
2896
2897 static void spoolss_notify_job_status(int snum,
2898                                       struct spoolss_Notify *data,
2899                                       print_queue_struct *queue,
2900                                       NT_PRINTER_INFO_LEVEL *printer,
2901                                       TALLOC_CTX *mem_ctx)
2902 {
2903         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
2904 }
2905
2906 /*******************************************************************
2907  * fill a notify_info_data with job name
2908  ********************************************************************/
2909
2910 static void spoolss_notify_job_name(int snum,
2911                                     struct spoolss_Notify *data,
2912                                     print_queue_struct *queue,
2913                                     NT_PRINTER_INFO_LEVEL *printer,
2914                                     TALLOC_CTX *mem_ctx)
2915 {
2916         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
2917 }
2918
2919 /*******************************************************************
2920  * fill a notify_info_data with job status
2921  ********************************************************************/
2922
2923 static void spoolss_notify_job_status_string(int snum,
2924                                              struct spoolss_Notify *data,
2925                                              print_queue_struct *queue,
2926                                              NT_PRINTER_INFO_LEVEL *printer,
2927                                              TALLOC_CTX *mem_ctx)
2928 {
2929         /*
2930          * Now we're returning job status codes we just return a "" here. JRA.
2931          */
2932
2933         const char *p = "";
2934
2935 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2936         p = "unknown";
2937
2938         switch (queue->status) {
2939         case LPQ_QUEUED:
2940                 p = "Queued";
2941                 break;
2942         case LPQ_PAUSED:
2943                 p = "";    /* NT provides the paused string */
2944                 break;
2945         case LPQ_SPOOLING:
2946                 p = "Spooling";
2947                 break;
2948         case LPQ_PRINTING:
2949                 p = "Printing";
2950                 break;
2951         }
2952 #endif /* NO LONGER NEEDED. */
2953
2954         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2955 }
2956
2957 /*******************************************************************
2958  * fill a notify_info_data with job time
2959  ********************************************************************/
2960
2961 static void spoolss_notify_job_time(int snum,
2962                                     struct spoolss_Notify *data,
2963                                     print_queue_struct *queue,
2964                                     NT_PRINTER_INFO_LEVEL *printer,
2965                                     TALLOC_CTX *mem_ctx)
2966 {
2967         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2968 }
2969
2970 /*******************************************************************
2971  * fill a notify_info_data with job size
2972  ********************************************************************/
2973
2974 static void spoolss_notify_job_size(int snum,
2975                                     struct spoolss_Notify *data,
2976                                     print_queue_struct *queue,
2977                                     NT_PRINTER_INFO_LEVEL *printer,
2978                                     TALLOC_CTX *mem_ctx)
2979 {
2980         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
2981 }
2982
2983 /*******************************************************************
2984  * fill a notify_info_data with page info
2985  ********************************************************************/
2986 static void spoolss_notify_total_pages(int snum,
2987                                 struct spoolss_Notify *data,
2988                                 print_queue_struct *queue,
2989                                 NT_PRINTER_INFO_LEVEL *printer,
2990                                 TALLOC_CTX *mem_ctx)
2991 {
2992         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
2993 }
2994
2995 /*******************************************************************
2996  * fill a notify_info_data with pages printed info.
2997  ********************************************************************/
2998 static void spoolss_notify_pages_printed(int snum,
2999                                 struct spoolss_Notify *data,
3000                                 print_queue_struct *queue,
3001                                 NT_PRINTER_INFO_LEVEL *printer,
3002                                 TALLOC_CTX *mem_ctx)
3003 {
3004         /* Add code when back-end tracks this */
3005         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3006 }
3007
3008 /*******************************************************************
3009  Fill a notify_info_data with job position.
3010  ********************************************************************/
3011
3012 static void spoolss_notify_job_position(int snum,
3013                                         struct spoolss_Notify *data,
3014                                         print_queue_struct *queue,
3015                                         NT_PRINTER_INFO_LEVEL *printer,
3016                                         TALLOC_CTX *mem_ctx)
3017 {
3018         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
3019 }
3020
3021 /*******************************************************************
3022  Fill a notify_info_data with submitted time.
3023  ********************************************************************/
3024
3025 static void spoolss_notify_submitted_time(int snum,
3026                                           struct spoolss_Notify *data,
3027                                           print_queue_struct *queue,
3028                                           NT_PRINTER_INFO_LEVEL *printer,
3029                                           TALLOC_CTX *mem_ctx)
3030 {
3031         data->data.string.string = NULL;
3032         data->data.string.size = 0;
3033
3034         init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
3035                                &data->data.string.string,
3036                                &data->data.string.size);
3037
3038 }
3039
3040 struct s_notify_info_data_table
3041 {
3042         enum spoolss_NotifyType type;
3043         uint16_t field;
3044         const char *name;
3045         enum spoolss_NotifyTable variable_type;
3046         void (*fn) (int snum, struct spoolss_Notify *data,
3047                     print_queue_struct *queue,
3048                     NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
3049 };
3050
3051 /* A table describing the various print notification constants and
3052    whether the notification data is a pointer to a variable sized
3053    buffer, a one value uint32_t or a two value uint32_t. */
3054
3055 static const struct s_notify_info_data_table notify_info_data_table[] =
3056 {
3057 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME,         "PRINTER_NOTIFY_FIELD_SERVER_NAME",         NOTIFY_TABLE_STRING,   spoolss_notify_server_name },
3058 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME,        "PRINTER_NOTIFY_FIELD_PRINTER_NAME",        NOTIFY_TABLE_STRING,   spoolss_notify_printer_name },
3059 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME,          "PRINTER_NOTIFY_FIELD_SHARE_NAME",          NOTIFY_TABLE_STRING,   spoolss_notify_share_name },
3060 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME,           "PRINTER_NOTIFY_FIELD_PORT_NAME",           NOTIFY_TABLE_STRING,   spoolss_notify_port_name },
3061 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME,         "PRINTER_NOTIFY_FIELD_DRIVER_NAME",         NOTIFY_TABLE_STRING,   spoolss_notify_driver_name },
3062 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT,             "PRINTER_NOTIFY_FIELD_COMMENT",             NOTIFY_TABLE_STRING,   spoolss_notify_comment },
3063 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION,            "PRINTER_NOTIFY_FIELD_LOCATION",            NOTIFY_TABLE_STRING,   spoolss_notify_location },
3064 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE,             "PRINTER_NOTIFY_FIELD_DEVMODE",             NOTIFY_TABLE_DEVMODE,  spoolss_notify_devmode },
3065 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE,             "PRINTER_NOTIFY_FIELD_SEPFILE",             NOTIFY_TABLE_STRING,   spoolss_notify_sepfile },
3066 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR,     "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR",     NOTIFY_TABLE_STRING,   spoolss_notify_print_processor },
3067 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS,          "PRINTER_NOTIFY_FIELD_PARAMETERS",          NOTIFY_TABLE_STRING,   spoolss_notify_parameters },
3068 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE,            "PRINTER_NOTIFY_FIELD_DATATYPE",            NOTIFY_TABLE_STRING,   spoolss_notify_datatype },
3069 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR,   spoolss_notify_security_desc },
3070 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES,          "PRINTER_NOTIFY_FIELD_ATTRIBUTES",          NOTIFY_TABLE_DWORD,    spoolss_notify_attributes },
3071 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY,            "PRINTER_NOTIFY_FIELD_PRIORITY",            NOTIFY_TABLE_DWORD,    spoolss_notify_priority },
3072 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY,    "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY",    NOTIFY_TABLE_DWORD,    spoolss_notify_default_priority },
3073 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME,          "PRINTER_NOTIFY_FIELD_START_TIME",          NOTIFY_TABLE_DWORD,    spoolss_notify_start_time },
3074 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME,          "PRINTER_NOTIFY_FIELD_UNTIL_TIME",          NOTIFY_TABLE_DWORD,    spoolss_notify_until_time },
3075 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS,              "PRINTER_NOTIFY_FIELD_STATUS",              NOTIFY_TABLE_DWORD,    spoolss_notify_status },
3076 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING,       "PRINTER_NOTIFY_FIELD_STATUS_STRING",       NOTIFY_TABLE_STRING,   NULL },
3077 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS,               "PRINTER_NOTIFY_FIELD_CJOBS",               NOTIFY_TABLE_DWORD,    spoolss_notify_cjobs },
3078 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM,         "PRINTER_NOTIFY_FIELD_AVERAGE_PPM",         NOTIFY_TABLE_DWORD,    spoolss_notify_average_ppm },
3079 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES,         "PRINTER_NOTIFY_FIELD_TOTAL_PAGES",         NOTIFY_TABLE_DWORD,    NULL },
3080 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED,       "PRINTER_NOTIFY_FIELD_PAGES_PRINTED",       NOTIFY_TABLE_DWORD,    NULL },
3081 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES,         "PRINTER_NOTIFY_FIELD_TOTAL_BYTES",         NOTIFY_TABLE_DWORD,    NULL },
3082 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED,       "PRINTER_NOTIFY_FIELD_BYTES_PRINTED",       NOTIFY_TABLE_DWORD,    NULL },
3083 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PRINTER_NAME,            "JOB_NOTIFY_FIELD_PRINTER_NAME",            NOTIFY_TABLE_STRING,   spoolss_notify_printer_name },
3084 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_MACHINE_NAME,            "JOB_NOTIFY_FIELD_MACHINE_NAME",            NOTIFY_TABLE_STRING,   spoolss_notify_server_name },
3085 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PORT_NAME,               "JOB_NOTIFY_FIELD_PORT_NAME",               NOTIFY_TABLE_STRING,   spoolss_notify_port_name },
3086 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_USER_NAME,               "JOB_NOTIFY_FIELD_USER_NAME",               NOTIFY_TABLE_STRING,   spoolss_notify_username },
3087 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_NOTIFY_NAME,             "JOB_NOTIFY_FIELD_NOTIFY_NAME",             NOTIFY_TABLE_STRING,   spoolss_notify_username },
3088 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DATATYPE,                "JOB_NOTIFY_FIELD_DATATYPE",                NOTIFY_TABLE_STRING,   spoolss_notify_datatype },
3089 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PRINT_PROCESSOR,         "JOB_NOTIFY_FIELD_PRINT_PROCESSOR",         NOTIFY_TABLE_STRING,   spoolss_notify_print_processor },
3090 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PARAMETERS,              "JOB_NOTIFY_FIELD_PARAMETERS",              NOTIFY_TABLE_STRING,   spoolss_notify_parameters },
3091 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DRIVER_NAME,             "JOB_NOTIFY_FIELD_DRIVER_NAME",             NOTIFY_TABLE_STRING,   spoolss_notify_driver_name },
3092 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DEVMODE,                 "JOB_NOTIFY_FIELD_DEVMODE",                 NOTIFY_TABLE_DEVMODE,  spoolss_notify_devmode },
3093 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_STATUS,                  "JOB_NOTIFY_FIELD_STATUS",                  NOTIFY_TABLE_DWORD,    spoolss_notify_job_status },
3094 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_STATUS_STRING,           "JOB_NOTIFY_FIELD_STATUS_STRING",           NOTIFY_TABLE_STRING,   spoolss_notify_job_status_string },
3095 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR,     "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR",     NOTIFY_TABLE_SECURITYDESCRIPTOR,   NULL },
3096 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DOCUMENT,                "JOB_NOTIFY_FIELD_DOCUMENT",                NOTIFY_TABLE_STRING,   spoolss_notify_job_name },
3097 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PRIORITY,                "JOB_NOTIFY_FIELD_PRIORITY",                NOTIFY_TABLE_DWORD,    spoolss_notify_priority },
3098 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_POSITION,                "JOB_NOTIFY_FIELD_POSITION",                NOTIFY_TABLE_DWORD,    spoolss_notify_job_position },
3099 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_SUBMITTED,               "JOB_NOTIFY_FIELD_SUBMITTED",               NOTIFY_TABLE_TIME,     spoolss_notify_submitted_time },
3100 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_START_TIME,              "JOB_NOTIFY_FIELD_START_TIME",              NOTIFY_TABLE_DWORD,    spoolss_notify_start_time },
3101 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_UNTIL_TIME,              "JOB_NOTIFY_FIELD_UNTIL_TIME",              NOTIFY_TABLE_DWORD,    spoolss_notify_until_time },
3102 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_TIME,                    "JOB_NOTIFY_FIELD_TIME",                    NOTIFY_TABLE_DWORD,    spoolss_notify_job_time },
3103 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_TOTAL_PAGES,             "JOB_NOTIFY_FIELD_TOTAL_PAGES",             NOTIFY_TABLE_DWORD,    spoolss_notify_total_pages },
3104 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PAGES_PRINTED,           "JOB_NOTIFY_FIELD_PAGES_PRINTED",           NOTIFY_TABLE_DWORD,    spoolss_notify_pages_printed },
3105 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_TOTAL_BYTES,             "JOB_NOTIFY_FIELD_TOTAL_BYTES",             NOTIFY_TABLE_DWORD,    spoolss_notify_job_size },
3106 };
3107
3108 /*******************************************************************
3109  Return the variable_type of info_data structure.
3110 ********************************************************************/
3111
3112 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
3113                                                   uint16_t field)
3114 {
3115         int i=0;
3116
3117         for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3118                 if ( (notify_info_data_table[i].type == type) &&
3119                      (notify_info_data_table[i].field == field) ) {
3120                         return notify_info_data_table[i].variable_type;
3121                 }
3122         }
3123
3124         DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3125
3126         return 0;
3127 }
3128
3129 /****************************************************************************
3130 ****************************************************************************/
3131
3132 static bool search_notify(enum spoolss_NotifyType type,
3133                           uint16_t field,
3134                           int *value)
3135 {
3136         int i;
3137
3138         for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3139                 if (notify_info_data_table[i].type == type &&
3140                     notify_info_data_table[i].field == field &&
3141                     notify_info_data_table[i].fn != NULL) {
3142                         *value = i;
3143                         return true;
3144                 }
3145         }
3146
3147         return false;
3148 }
3149
3150 /****************************************************************************
3151 ****************************************************************************/
3152
3153 void construct_info_data(struct spoolss_Notify *info_data,
3154                          enum spoolss_NotifyType type,
3155                          uint16_t field,
3156                          int id)
3157 {
3158         info_data->type                 = type;
3159         info_data->field.field          = field;
3160         info_data->variable_type        = variable_type_of_notify_info_data(type, field);
3161         info_data->job_id               = id;
3162 }
3163
3164 /*******************************************************************
3165  *
3166  * fill a notify_info struct with info asked
3167  *
3168  ********************************************************************/
3169
3170 static bool construct_notify_printer_info(Printer_entry *print_hnd,
3171                                           struct spoolss_NotifyInfo *info,
3172                                           int snum,
3173                                           const struct spoolss_NotifyOptionType *option_type,
3174                                           uint32_t id,
3175                                           TALLOC_CTX *mem_ctx)
3176 {
3177         int field_num,j;
3178         enum spoolss_NotifyType type;
3179         uint16_t field;
3180
3181         struct spoolss_Notify *current_data;
3182         NT_PRINTER_INFO_LEVEL *printer = NULL;
3183         print_queue_struct *queue=NULL;
3184
3185         type = option_type->type;
3186
3187         DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3188                 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3189                 option_type->count, lp_servicename(snum)));
3190
3191         if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
3192                 return false;
3193
3194         for(field_num=0; field_num < option_type->count; field_num++) {
3195                 field = option_type->fields[field_num].field;
3196
3197                 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3198
3199                 if (!search_notify(type, field, &j) )
3200                         continue;
3201
3202                 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3203                                                       struct spoolss_Notify,
3204                                                       info->count + 1);
3205                 if (info->notifies == NULL) {
3206                         DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3207                         free_a_printer(&printer, 2);
3208                         return false;
3209                 }
3210
3211                 current_data = &info->notifies[info->count];
3212
3213                 construct_info_data(current_data, type, field, id);
3214
3215                 DEBUG(10,("construct_notify_printer_info: calling [%s]  snum=%d  printername=[%s])\n",
3216                                 notify_info_data_table[j].name, snum, printer->info_2->printername ));
3217
3218                 notify_info_data_table[j].fn(snum, current_data, queue,
3219                                              printer, mem_ctx);
3220
3221                 info->count++;
3222         }
3223
3224         free_a_printer(&printer, 2);
3225         return true;
3226 }
3227
3228 /*******************************************************************
3229  *
3230  * fill a notify_info struct with info asked
3231  *
3232  ********************************************************************/
3233
3234 static bool construct_notify_jobs_info(print_queue_struct *queue,
3235                                        struct spoolss_NotifyInfo *info,
3236                                        NT_PRINTER_INFO_LEVEL *printer,
3237                                        int snum,
3238                                        const struct spoolss_NotifyOptionType *option_type,
3239                                        uint32_t id,
3240                                        TALLOC_CTX *mem_ctx)
3241 {
3242         int field_num,j;
3243         enum spoolss_NotifyType type;
3244         uint16_t field;
3245         struct spoolss_Notify *current_data;
3246
3247         DEBUG(4,("construct_notify_jobs_info\n"));
3248
3249         type = option_type->type;
3250
3251         DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3252                 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3253                 option_type->count));
3254
3255         for(field_num=0; field_num<option_type->count; field_num++) {
3256                 field = option_type->fields[field_num].field;
3257
3258                 if (!search_notify(type, field, &j) )
3259                         continue;
3260
3261                 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3262                                                       struct spoolss_Notify,
3263                                                       info->count + 1);
3264                 if (info->notifies == NULL) {
3265                         DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3266                         return false;
3267                 }
3268
3269                 current_data=&(info->notifies[info->count]);
3270
3271                 construct_info_data(current_data, type, field, id);
3272                 notify_info_data_table[j].fn(snum, current_data, queue,
3273                                              printer, mem_ctx);
3274                 info->count++;
3275         }
3276
3277         return true;
3278 }
3279
3280 /*
3281  * JFM: The enumeration is not that simple, it's even non obvious.
3282  *
3283  * let's take an example: I want to monitor the PRINTER SERVER for
3284  * the printer's name and the number of jobs currently queued.
3285  * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3286  * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3287  *
3288  * I have 3 printers on the back of my server.
3289  *
3290  * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3291  * structures.
3292  *   Number     Data                    Id
3293  *      1       printer 1 name          1
3294  *      2       printer 1 cjob          1
3295  *      3       printer 2 name          2
3296  *      4       printer 2 cjob          2
3297  *      5       printer 3 name          3
3298  *      6       printer 3 name          3
3299  *
3300  * that's the print server case, the printer case is even worse.
3301  */
3302
3303 /*******************************************************************
3304  *
3305  * enumerate all printers on the printserver
3306  * fill a notify_info struct with info asked
3307  *
3308  ********************************************************************/
3309
3310 static WERROR printserver_notify_info(pipes_struct *p,
3311                                       struct policy_handle *hnd,
3312                                       struct spoolss_NotifyInfo *info,
3313                                       TALLOC_CTX *mem_ctx)
3314 {
3315         int snum;
3316         Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3317         int n_services=lp_numservices();
3318         int i;
3319         struct spoolss_NotifyOption *option;
3320         struct spoolss_NotifyOptionType option_type;
3321
3322         DEBUG(4,("printserver_notify_info\n"));
3323
3324         if (!Printer)
3325                 return WERR_BADFID;
3326
3327         option = Printer->notify.option;
3328
3329         info->version   = 2;
3330         info->notifies  = NULL;
3331         info->count     = 0;
3332
3333         /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3334            sending a ffpcn() request first */
3335
3336         if ( !option )
3337                 return WERR_BADFID;
3338
3339         for (i=0; i<option->count; i++) {
3340                 option_type = option->types[i];
3341
3342                 if (option_type.type != PRINTER_NOTIFY_TYPE)
3343                         continue;
3344
3345                 for (snum=0; snum<n_services; snum++)
3346                 {
3347                         if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3348                                 construct_notify_printer_info ( Printer, info, snum, &option_type, snum, mem_ctx );
3349                 }
3350         }
3351
3352 #if 0
3353         /*
3354          * Debugging information, don't delete.
3355          */
3356
3357         DEBUG(1,("dumping the NOTIFY_INFO\n"));
3358         DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3359         DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3360
3361         for (i=0; i<info->count; i++) {
3362                 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3363                 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3364                 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3365         }
3366 #endif
3367
3368         return WERR_OK;
3369 }
3370
3371 /*******************************************************************
3372  *
3373  * fill a notify_info struct with info asked
3374  *
3375  ********************************************************************/
3376
3377 static WERROR printer_notify_info(pipes_struct *p, struct policy_handle *hnd,
3378                                   struct spoolss_NotifyInfo *info,
3379                                   TALLOC_CTX *mem_ctx)
3380 {
3381         int snum;
3382         Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3383         int i;
3384         uint32_t id;
3385         struct spoolss_NotifyOption *option;
3386         struct spoolss_NotifyOptionType option_type;
3387         int count,j;
3388         print_queue_struct *queue=NULL;
3389         print_status_struct status;
3390
3391         DEBUG(4,("printer_notify_info\n"));
3392
3393         if (!Printer)
3394                 return WERR_BADFID;
3395
3396         option = Printer->notify.option;
3397         id = 0x0;
3398
3399         info->version   = 2;
3400         info->notifies  = NULL;
3401         info->count     = 0;
3402
3403         /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3404            sending a ffpcn() request first */
3405
3406         if ( !option )
3407                 return WERR_BADFID;
3408
3409         get_printer_snum(p, hnd, &snum, NULL);
3410
3411         for (i=0; i<option->count; i++) {
3412                 option_type = option->types[i];
3413
3414                 switch (option_type.type) {
3415                 case PRINTER_NOTIFY_TYPE:
3416                         if(construct_notify_printer_info(Printer, info, snum,
3417                                                          &option_type, id,
3418                                                          mem_ctx))
3419                                 id--;
3420                         break;
3421
3422                 case JOB_NOTIFY_TYPE: {
3423                         NT_PRINTER_INFO_LEVEL *printer = NULL;
3424
3425                         count = print_queue_status(snum, &queue, &status);
3426
3427                         if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))))
3428                                 goto done;
3429
3430                         for (j=0; j<count; j++) {
3431                                 construct_notify_jobs_info(&queue[j], info,
3432                                                            printer, snum,
3433                                                            &option_type,
3434                                                            queue[j].job,
3435                                                            mem_ctx);
3436                         }
3437
3438                         free_a_printer(&printer, 2);
3439
3440                 done:
3441                         SAFE_FREE(queue);
3442                         break;
3443                 }
3444                 }
3445         }
3446
3447         /*
3448          * Debugging information, don't delete.
3449          */
3450         /*
3451         DEBUG(1,("dumping the NOTIFY_INFO\n"));
3452         DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3453         DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3454
3455         for (i=0; i<info->count; i++) {
3456                 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3457                 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3458                 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3459         }
3460         */
3461         return WERR_OK;
3462 }
3463
3464 /****************************************************************
3465  _spoolss_RouterRefreshPrinterChangeNotify
3466 ****************************************************************/
3467
3468 WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
3469                                                  struct spoolss_RouterRefreshPrinterChangeNotify *r)
3470 {
3471         struct spoolss_NotifyInfo *info;
3472
3473         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
3474         WERROR result = WERR_BADFID;
3475
3476         /* we always have a spoolss_NotifyInfo struct */
3477         info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3478         if (!info) {
3479                 result = WERR_NOMEM;
3480                 goto done;
3481         }
3482
3483         *r->out.info = info;
3484
3485         if (!Printer) {
3486                 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3487                         "Invalid handle (%s:%u:%u).\n",
3488                         OUR_HANDLE(r->in.handle)));
3489                 goto done;
3490         }
3491
3492         DEBUG(4,("Printer type %x\n",Printer->printer_type));
3493
3494         /*
3495          *      We are now using the change value, and
3496          *      I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3497          *      I don't have a global notification system, I'm sending back all the
3498          *      informations even when _NOTHING_ has changed.
3499          */
3500
3501         /* We need to keep track of the change value to send back in
3502            RRPCN replies otherwise our updates are ignored. */
3503
3504         Printer->notify.fnpcn = true;
3505
3506         if (Printer->notify.client_connected) {
3507                 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3508                         "Saving change value in request [%x]\n",
3509                         r->in.change_low));
3510                 Printer->notify.change = r->in.change_low;
3511         }
3512
3513         /* just ignore the spoolss_NotifyOption */
3514
3515         switch (Printer->printer_type) {
3516                 case SPLHND_SERVER:
3517                         result = printserver_notify_info(p, r->in.handle,
3518                                                          info, p->mem_ctx);
3519                         break;
3520
3521                 case SPLHND_PRINTER:
3522                         result = printer_notify_info(p, r->in.handle,
3523                                                      info, p->mem_ctx);
3524                         break;
3525         }
3526
3527         Printer->notify.fnpcn = false;
3528
3529 done:
3530         return result;
3531 }
3532
3533 /********************************************************************
3534  * construct_printer_info_0
3535  * fill a printer_info_0 struct
3536  ********************************************************************/
3537
3538 static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
3539                                       const NT_PRINTER_INFO_LEVEL *ntprinter,
3540                                       struct spoolss_PrinterInfo0 *r,
3541                                       int snum)
3542 {
3543         int count;
3544         counter_printer_0 *session_counter;
3545         time_t setuptime;
3546         print_status_struct status;
3547
3548         r->printername          = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3549         W_ERROR_HAVE_NO_MEMORY(r->printername);
3550
3551         r->servername           = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
3552         W_ERROR_HAVE_NO_MEMORY(r->servername);
3553
3554         count = print_queue_length(snum, &status);
3555
3556         /* check if we already have a counter for this printer */
3557         for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3558                 if (session_counter->snum == snum)
3559                         break;
3560         }
3561
3562         /* it's the first time, add it to the list */
3563         if (session_counter == NULL) {
3564                 session_counter = SMB_MALLOC_P(counter_printer_0);
3565                 W_ERROR_HAVE_NO_MEMORY(session_counter);
3566                 ZERO_STRUCTP(session_counter);
3567                 session_counter->snum           = snum;
3568                 session_counter->counter        = 0;
3569                 DLIST_ADD(counter_list, session_counter);
3570         }
3571
3572         /* increment it */
3573         session_counter->counter++;
3574
3575         r->cjobs                        = count;
3576         r->total_jobs                   = 0;
3577         r->total_bytes                  = 0;
3578
3579         setuptime = (time_t)ntprinter->info_2->setuptime;
3580
3581         init_systemtime(&r->time, gmtime(&setuptime));
3582
3583         /* JFM:
3584          * the global_counter should be stored in a TDB as it's common to all the clients
3585          * and should be zeroed on samba startup
3586          */
3587         r->global_counter               = session_counter->counter;
3588         r->total_pages                  = 0;
3589         /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3590         r->version                      = 0x0005;       /* NT 5 */
3591         r->free_build                   = 0x0893;       /* build 2195 */
3592         r->spooling                     = 0;
3593         r->max_spooling                 = 0;
3594         r->session_counter              = session_counter->counter;
3595         r->num_error_out_of_paper       = 0x0;
3596         r->num_error_not_ready          = 0x0;          /* number of print failure */
3597         r->job_error                    = 0x0;
3598         r->number_of_processors         = 0x1;
3599         r->processor_type               = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
3600         r->high_part_total_bytes        = 0x0;
3601         r->change_id                    = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
3602         r->last_error                   = WERR_OK;
3603         r->status                       = nt_printq_status(status.status);
3604         r->enumerate_network_printers   = 0x0;
3605         r->c_setprinter                 = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
3606         r->processor_architecture       = 0x0;
3607         r->processor_level              = 0x6;          /* 6  ???*/
3608         r->ref_ic                       = 0;
3609         r->reserved2                    = 0;
3610         r->reserved3                    = 0;
3611
3612         return WERR_OK;
3613 }
3614
3615 /****************************************************************************
3616  Convert an NT_DEVICEMODE to a spoolss_DeviceMode structure.  Both pointers
3617  should be valid upon entry
3618 ****************************************************************************/
3619
3620 static WERROR convert_nt_devicemode(TALLOC_CTX *mem_ctx,
3621                                     struct spoolss_DeviceMode *r,
3622                                     const NT_DEVICEMODE *ntdevmode)
3623 {
3624         if (!r || !ntdevmode) {
3625                 return WERR_INVALID_PARAM;
3626         }
3627
3628         r->devicename           = talloc_strdup(mem_ctx, ntdevmode->devicename);
3629         W_ERROR_HAVE_NO_MEMORY(r->devicename);
3630
3631         r->specversion          = ntdevmode->specversion;
3632         r->driverversion        = ntdevmode->driverversion;
3633         r->size                 = ntdevmode->size;
3634         r->__driverextra_length = ntdevmode->driverextra;
3635         r->fields               = ntdevmode->fields;
3636
3637         r->orientation          = ntdevmode->orientation;
3638         r->papersize            = ntdevmode->papersize;
3639         r->paperlength          = ntdevmode->paperlength;
3640         r->paperwidth           = ntdevmode->paperwidth;
3641         r->scale                = ntdevmode->scale;
3642         r->copies               = ntdevmode->copies;
3643         r->defaultsource        = ntdevmode->defaultsource;
3644         r->printquality         = ntdevmode->printquality;
3645         r->color                = ntdevmode->color;
3646         r->duplex               = ntdevmode->duplex;
3647         r->yresolution          = ntdevmode->yresolution;
3648         r->ttoption             = ntdevmode->ttoption;
3649         r->collate              = ntdevmode->collate;
3650
3651         r->formname             = talloc_strdup(mem_ctx, ntdevmode->formname);
3652         W_ERROR_HAVE_NO_MEMORY(r->formname);
3653
3654         /* all 0 below are values that have not been set in the old parsing/copy
3655          * function, maybe they should... - gd */
3656
3657         r->logpixels            = 0;
3658         r->bitsperpel           = 0;
3659         r->pelswidth            = 0;
3660         r->pelsheight           = 0;
3661         r->displayflags         = 0;
3662         r->displayfrequency     = 0;
3663         r->icmmethod            = ntdevmode->icmmethod;
3664         r->icmintent            = ntdevmode->icmintent;
3665         r->mediatype            = ntdevmode->mediatype;
3666         r->dithertype           = ntdevmode->dithertype;
3667         r->reserved1            = 0;
3668         r->reserved2            = 0;
3669         r->panningwidth         = 0;
3670         r->panningheight        = 0;
3671
3672         if (ntdevmode->nt_dev_private != NULL) {
3673                 r->driverextra_data = data_blob_talloc(mem_ctx,
3674                         ntdevmode->nt_dev_private,
3675                         ntdevmode->driverextra);
3676                 W_ERROR_HAVE_NO_MEMORY(r->driverextra_data.data);
3677         }
3678
3679         return WERR_OK;
3680 }
3681
3682
3683 /****************************************************************************
3684  Create a spoolss_DeviceMode struct. Returns talloced memory.
3685 ****************************************************************************/
3686
3687 struct spoolss_DeviceMode *construct_dev_mode(TALLOC_CTX *mem_ctx,
3688                                               const char *servicename)
3689 {
3690         WERROR result;
3691         NT_PRINTER_INFO_LEVEL   *printer = NULL;
3692         struct spoolss_DeviceMode *devmode = NULL;
3693
3694         DEBUG(7,("construct_dev_mode\n"));
3695
3696         DEBUGADD(8,("getting printer characteristics\n"));
3697
3698         if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
3699                 return NULL;
3700
3701         if (!printer->info_2->devmode) {
3702                 DEBUG(5, ("BONG! There was no device mode!\n"));
3703                 goto done;
3704         }
3705
3706         devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode);
3707         if (!devmode) {
3708                 DEBUG(2,("construct_dev_mode: talloc fail.\n"));
3709                 goto done;
3710         }
3711
3712         DEBUGADD(8,("loading DEVICEMODE\n"));
3713
3714         result = convert_nt_devicemode(mem_ctx, devmode, printer->info_2->devmode);
3715         if (!W_ERROR_IS_OK(result)) {
3716                 TALLOC_FREE(devmode);
3717         }
3718
3719 done:
3720         free_a_printer(&printer,2);
3721
3722         return devmode;
3723 }
3724
3725 /********************************************************************
3726  * construct_printer_info1
3727  * fill a spoolss_PrinterInfo1 struct
3728 ********************************************************************/
3729
3730 static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
3731                                       const NT_PRINTER_INFO_LEVEL *ntprinter,
3732                                       uint32_t flags,
3733                                       struct spoolss_PrinterInfo1 *r,
3734                                       int snum)
3735 {
3736         r->flags                = flags;
3737
3738         r->description          = talloc_asprintf(mem_ctx, "%s,%s,%s",
3739                                                   ntprinter->info_2->printername,
3740                                                   ntprinter->info_2->drivername,
3741                                                   ntprinter->info_2->location);
3742         W_ERROR_HAVE_NO_MEMORY(r->description);
3743
3744         if (*ntprinter->info_2->comment == '\0') {
3745                 r->comment      = talloc_strdup(mem_ctx, lp_comment(snum));
3746         } else {
3747                 r->comment      = talloc_strdup(mem_ctx, ntprinter->info_2->comment); /* saved comment */
3748         }
3749         W_ERROR_HAVE_NO_MEMORY(r->comment);
3750
3751         r->name                 = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3752         W_ERROR_HAVE_NO_MEMORY(r->name);
3753
3754         return WERR_OK;
3755 }
3756
3757 /********************************************************************
3758  * construct_printer_info2
3759  * fill a spoolss_PrinterInfo2 struct
3760 ********************************************************************/
3761
3762 static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
3763                                       const NT_PRINTER_INFO_LEVEL *ntprinter,
3764                                       struct spoolss_PrinterInfo2 *r,
3765                                       int snum)
3766 {
3767         int count;
3768
3769         print_status_struct status;
3770
3771         count = print_queue_length(snum, &status);
3772
3773         r->servername           = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
3774         W_ERROR_HAVE_NO_MEMORY(r->servername);
3775         r->printername          = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3776         W_ERROR_HAVE_NO_MEMORY(r->printername);
3777         r->sharename            = talloc_strdup(mem_ctx, lp_servicename(snum));
3778         W_ERROR_HAVE_NO_MEMORY(r->sharename);
3779         r->portname             = talloc_strdup(mem_ctx, ntprinter->info_2->portname);
3780         W_ERROR_HAVE_NO_MEMORY(r->portname);
3781         r->drivername           = talloc_strdup(mem_ctx, ntprinter->info_2->drivername);
3782         W_ERROR_HAVE_NO_MEMORY(r->drivername);
3783
3784         if (*ntprinter->info_2->comment == '\0') {
3785                 r->comment      = talloc_strdup(mem_ctx, lp_comment(snum));
3786         } else {
3787                 r->comment      = talloc_strdup(mem_ctx, ntprinter->info_2->comment);
3788         }
3789         W_ERROR_HAVE_NO_MEMORY(r->comment);
3790
3791         r->location             = talloc_strdup(mem_ctx, ntprinter->info_2->location);
3792         W_ERROR_HAVE_NO_MEMORY(r->location);
3793         r->sepfile              = talloc_strdup(mem_ctx, ntprinter->info_2->sepfile);
3794         W_ERROR_HAVE_NO_MEMORY(r->sepfile);
3795         r->printprocessor       = talloc_strdup(mem_ctx, ntprinter->info_2->printprocessor);
3796         W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
3797         r->datatype             = talloc_strdup(mem_ctx, ntprinter->info_2->datatype);
3798         W_ERROR_HAVE_NO_MEMORY(r->datatype);
3799         r->parameters           = talloc_strdup(mem_ctx, ntprinter->info_2->parameters);
3800         W_ERROR_HAVE_NO_MEMORY(r->parameters);
3801
3802         r->attributes           = ntprinter->info_2->attributes;
3803
3804         r->priority             = ntprinter->info_2->priority;
3805         r->defaultpriority      = ntprinter->info_2->default_priority;
3806         r->starttime            = ntprinter->info_2->starttime;
3807         r->untiltime            = ntprinter->info_2->untiltime;
3808         r->status               = nt_printq_status(status.status);
3809         r->cjobs                = count;
3810         r->averageppm           = ntprinter->info_2->averageppm;
3811
3812         r->devmode = construct_dev_mode(mem_ctx, lp_const_servicename(snum));
3813         if (!r->devmode) {
3814                 DEBUG(8,("Returning NULL Devicemode!\n"));
3815         }
3816
3817         r->secdesc              = NULL;
3818
3819         if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
3820                 /* don't use talloc_steal() here unless you do a deep steal of all
3821                    the SEC_DESC members */
3822
3823                 r->secdesc      = dup_sec_desc(mem_ctx, ntprinter->info_2->secdesc_buf->sd);
3824         }
3825
3826         return WERR_OK;
3827 }
3828
3829 /********************************************************************
3830  * construct_printer_info3
3831  * fill a spoolss_PrinterInfo3 struct
3832  ********************************************************************/
3833
3834 static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
3835                                       const NT_PRINTER_INFO_LEVEL *ntprinter,
3836                                       struct spoolss_PrinterInfo3 *r,
3837                                       int snum)
3838 {
3839         /* These are the components of the SD we are returning. */
3840
3841         if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
3842                 /* don't use talloc_steal() here unless you do a deep steal of all
3843                    the SEC_DESC members */
3844
3845                 r->secdesc = dup_sec_desc(mem_ctx,
3846                                           ntprinter->info_2->secdesc_buf->sd);
3847                 W_ERROR_HAVE_NO_MEMORY(r->secdesc);
3848         }
3849
3850         return WERR_OK;
3851 }
3852
3853 /********************************************************************
3854  * construct_printer_info4
3855  * fill a spoolss_PrinterInfo4 struct
3856  ********************************************************************/
3857
3858 static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
3859                                       const NT_PRINTER_INFO_LEVEL *ntprinter,
3860                                       struct spoolss_PrinterInfo4 *r,
3861                                       int snum)
3862 {
3863         r->printername  = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3864         W_ERROR_HAVE_NO_MEMORY(r->printername);
3865         r->servername   = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
3866         W_ERROR_HAVE_NO_MEMORY(r->servername);
3867
3868         r->attributes   = ntprinter->info_2->attributes;
3869
3870         return WERR_OK;
3871 }
3872
3873 /********************************************************************
3874  * construct_printer_info5
3875  * fill a spoolss_PrinterInfo5 struct
3876  ********************************************************************/
3877
3878 static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
3879                                       const NT_PRINTER_INFO_LEVEL *ntprinter,
3880                                       struct spoolss_PrinterInfo5 *r,
3881                                       int snum)
3882 {
3883         r->printername  = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3884         W_ERROR_HAVE_NO_MEMORY(r->printername);
3885         r->portname     = talloc_strdup(mem_ctx, ntprinter->info_2->portname);
3886         W_ERROR_HAVE_NO_MEMORY(r->portname);
3887
3888         r->attributes   = ntprinter->info_2->attributes;
3889
3890         /* these two are not used by NT+ according to MSDN */
3891
3892         r->device_not_selected_timeout          = 0x0;  /* have seen 0x3a98 */
3893         r->transmission_retry_timeout           = 0x0;  /* have seen 0xafc8 */
3894
3895         return WERR_OK;
3896 }
3897
3898 /********************************************************************
3899  * construct_printer_info_6
3900  * fill a spoolss_PrinterInfo6 struct
3901  ********************************************************************/
3902
3903 static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
3904                                       const NT_PRINTER_INFO_LEVEL *ntprinter,
3905                                       struct spoolss_PrinterInfo6 *r,
3906                                       int snum)
3907 {
3908         int count;
3909         print_status_struct status;
3910
3911         count = print_queue_length(snum, &status);
3912
3913         r->status = nt_printq_status(status.status);
3914
3915         return WERR_OK;
3916 }
3917
3918 /********************************************************************
3919  * construct_printer_info7
3920  * fill a spoolss_PrinterInfo7 struct
3921  ********************************************************************/
3922
3923 static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
3924                                       Printer_entry *print_hnd,
3925                                       struct spoolss_PrinterInfo7 *r,
3926                                       int snum)
3927 {
3928         struct GUID guid;
3929
3930         if (is_printer_published(print_hnd, snum, &guid)) {
3931                 r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
3932                 r->action = DSPRINT_PUBLISH;
3933         } else {
3934                 r->guid = talloc_strdup(mem_ctx, "");
3935                 r->action = DSPRINT_UNPUBLISH;
3936         }
3937         W_ERROR_HAVE_NO_MEMORY(r->guid);
3938
3939         return WERR_OK;
3940 }
3941
3942 /********************************************************************
3943  * construct_printer_info8
3944  * fill a spoolss_PrinterInfo8 struct
3945  ********************************************************************/
3946
3947 static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
3948                                       const NT_PRINTER_INFO_LEVEL *ntprinter,
3949                                       struct spoolss_DeviceModeInfo *r,
3950                                       int snum)
3951 {
3952         r->devmode = construct_dev_mode(mem_ctx, lp_const_servicename(snum));
3953         if (!r->devmode) {
3954                 DEBUG(8,("Returning NULL Devicemode!\n"));
3955         }
3956
3957         return WERR_OK;
3958 }
3959
3960
3961 /********************************************************************
3962 ********************************************************************/
3963
3964 static bool snum_is_shared_printer(int snum)
3965 {
3966         return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
3967 }
3968
3969 /********************************************************************
3970  Spoolss_enumprinters.
3971 ********************************************************************/
3972
3973 static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
3974                                            uint32_t level,
3975                                            uint32_t flags,
3976                                            union spoolss_PrinterInfo **info_p,
3977                                            uint32_t *count_p)
3978 {
3979         int snum;
3980         int n_services = lp_numservices();
3981         union spoolss_PrinterInfo *info = NULL;
3982         uint32_t count = 0;
3983         WERROR result = WERR_OK;
3984
3985         *count_p = 0;
3986         *info_p = NULL;
3987
3988         for (snum = 0; snum < n_services; snum++) {
3989
3990                 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3991
3992                 if (!snum_is_shared_printer(snum)) {
3993                         continue;
3994                 }
3995
3996                 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
3997                         lp_servicename(snum), snum));
3998
3999                 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4000                                             union spoolss_PrinterInfo,
4001                                             count + 1);
4002                 if (!info) {
4003                         result = WERR_NOMEM;
4004                         goto out;
4005                 }
4006
4007                 result = get_a_printer(NULL, &ntprinter, 2,
4008                                        lp_const_servicename(snum));
4009                 if (!W_ERROR_IS_OK(result)) {
4010                         goto out;
4011                 }
4012
4013                 switch (level) {
4014                 case 0:
4015                         result = construct_printer_info0(info, ntprinter,
4016                                                          &info[count].info0, snum);
4017                         break;
4018                 case 1:
4019                         result = construct_printer_info1(info, ntprinter, flags,
4020                                                          &info[count].info1, snum);
4021                         break;
4022                 case 2:
4023                         result = construct_printer_info2(info, ntprinter,
4024                                                          &info[count].info2, snum);
4025                         break;
4026                 case 4:
4027                         result = construct_printer_info4(info, ntprinter,
4028                                                          &info[count].info4, snum);
4029                         break;
4030                 case 5:
4031                         result = construct_printer_info5(info, ntprinter,
4032                                                          &info[count].info5, snum);
4033                         break;
4034
4035                 default:
4036                         result = WERR_UNKNOWN_LEVEL;
4037                         free_a_printer(&ntprinter, 2);
4038                         goto out;
4039                 }
4040
4041                 free_a_printer(&ntprinter, 2);
4042                 if (!W_ERROR_IS_OK(result)) {
4043                         goto out;
4044                 }
4045
4046                 count++;
4047         }
4048
4049         *count_p = count;
4050         *info_p = info;
4051
4052  out:
4053         if (!W_ERROR_IS_OK(result)) {
4054                 TALLOC_FREE(info);
4055                 return result;
4056         }
4057
4058         *info_p = info;
4059
4060         return WERR_OK;
4061 }
4062
4063 /********************************************************************
4064  * handle enumeration of printers at level 0
4065  ********************************************************************/
4066
4067 static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
4068                                   uint32_t flags,
4069                                   const char *servername,
4070                                   union spoolss_PrinterInfo **info,
4071                                   uint32_t *count)
4072 {
4073         DEBUG(4,("enum_all_printers_info_0\n"));
4074
4075         return enum_all_printers_info_level(mem_ctx, 0, flags, info, count);
4076 }
4077
4078
4079 /********************************************************************
4080 ********************************************************************/
4081
4082 static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
4083                                        uint32_t flags,
4084                                        union spoolss_PrinterInfo **info,
4085                                        uint32_t *count)
4086 {
4087         DEBUG(4,("enum_all_printers_info_1\n"));
4088
4089         return enum_all_printers_info_level(mem_ctx, 1, flags, info, count);
4090 }
4091
4092 /********************************************************************
4093  enum_all_printers_info_1_local.
4094 *********************************************************************/
4095
4096 static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
4097                                              union spoolss_PrinterInfo **info,
4098                                              uint32_t *count)
4099 {
4100         DEBUG(4,("enum_all_printers_info_1_local\n"));
4101
4102         return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count);
4103 }
4104
4105 /********************************************************************
4106  enum_all_printers_info_1_name.
4107 *********************************************************************/
4108
4109 static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
4110                                             const char *name,
4111                                             union spoolss_PrinterInfo **info,
4112                                             uint32_t *count)
4113 {
4114         const char *s = name;
4115
4116         DEBUG(4,("enum_all_printers_info_1_name\n"));
4117
4118         if ((name[0] == '\\') && (name[1] == '\\')) {
4119                 s = name + 2;
4120         }
4121
4122         if (!is_myname_or_ipaddr(s)) {
4123                 return WERR_INVALID_NAME;
4124         }
4125
4126         return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count);
4127 }
4128
4129 /********************************************************************
4130  enum_all_printers_info_1_network.
4131 *********************************************************************/
4132
4133 static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
4134                                                const char *name,
4135                                                union spoolss_PrinterInfo **info,
4136                                                uint32_t *count)
4137 {
4138         const char *s = name;
4139
4140         DEBUG(4,("enum_all_printers_info_1_network\n"));
4141
4142         /* If we respond to a enum_printers level 1 on our name with flags
4143            set to PRINTER_ENUM_REMOTE with a list of printers then these
4144            printers incorrectly appear in the APW browse list.
4145            Specifically the printers for the server appear at the workgroup
4146            level where all the other servers in the domain are
4147            listed. Windows responds to this call with a
4148            WERR_CAN_NOT_COMPLETE so we should do the same. */
4149
4150         if (name[0] == '\\' && name[1] == '\\') {
4151                  s = name + 2;
4152         }
4153
4154         if (is_myname_or_ipaddr(s)) {
4155                  return WERR_CAN_NOT_COMPLETE;
4156         }
4157
4158         return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_NAME, info, count);
4159 }
4160
4161 /********************************************************************
4162  * api_spoolss_enumprinters
4163  *
4164  * called from api_spoolss_enumprinters (see this to understand)
4165  ********************************************************************/
4166
4167 static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
4168                                        union spoolss_PrinterInfo **info,
4169                                        uint32_t *count)
4170 {
4171         DEBUG(4,("enum_all_printers_info_2\n"));
4172
4173         return enum_all_printers_info_level(mem_ctx, 2, 0, info, count);
4174 }
4175
4176 /********************************************************************
4177  * handle enumeration of printers at level 1
4178  ********************************************************************/
4179
4180 static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
4181                                   uint32_t flags,
4182                                   const char *name,
4183                                   union spoolss_PrinterInfo **info,
4184                                   uint32_t *count)
4185 {
4186         /* Not all the flags are equals */
4187
4188         if (flags & PRINTER_ENUM_LOCAL) {
4189                 return enum_all_printers_info_1_local(mem_ctx, info, count);
4190         }
4191
4192         if (flags & PRINTER_ENUM_NAME) {
4193                 return enum_all_printers_info_1_name(mem_ctx, name, info, count);
4194         }
4195
4196         if (flags & PRINTER_ENUM_NETWORK) {
4197                 return enum_all_printers_info_1_network(mem_ctx, name, info, count);
4198         }
4199
4200         return WERR_OK; /* NT4sp5 does that */
4201 }
4202
4203 /********************************************************************
4204  * handle enumeration of printers at level 2
4205  ********************************************************************/
4206
4207 static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
4208                                   uint32_t flags,
4209                                   const char *servername,
4210                                   union spoolss_PrinterInfo **info,
4211                                   uint32_t *count)
4212 {
4213         if (flags & PRINTER_ENUM_LOCAL) {
4214                 return enum_all_printers_info_2(mem_ctx, info, count);
4215         }
4216
4217         if (flags & PRINTER_ENUM_NAME) {
4218                 if (!is_myname_or_ipaddr(canon_servername(servername))) {
4219                         return WERR_INVALID_NAME;
4220                 }
4221
4222                 return enum_all_printers_info_2(mem_ctx, info, count);
4223         }
4224
4225         if (flags & PRINTER_ENUM_REMOTE) {
4226                 return WERR_UNKNOWN_LEVEL;
4227         }
4228
4229         return WERR_OK;
4230 }
4231
4232 /********************************************************************
4233  * handle enumeration of printers at level 4
4234  ********************************************************************/
4235
4236 static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
4237                                   uint32_t flags,
4238                                   const char *servername,
4239                                   union spoolss_PrinterInfo **info,
4240                                   uint32_t *count)
4241 {
4242         DEBUG(4,("enum_all_printers_info_4\n"));
4243
4244         return enum_all_printers_info_level(mem_ctx, 4, flags, info, count);
4245 }
4246
4247
4248 /********************************************************************
4249  * handle enumeration of printers at level 5
4250  ********************************************************************/
4251
4252 static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
4253                                   uint32_t flags,
4254                                   const char *servername,
4255                                   union spoolss_PrinterInfo **info,
4256                                   uint32_t *count)
4257 {
4258         DEBUG(4,("enum_all_printers_info_5\n"));
4259
4260         return enum_all_printers_info_level(mem_ctx, 5, flags, info, count);
4261 }
4262
4263 /****************************************************************
4264  _spoolss_EnumPrinters
4265 ****************************************************************/
4266
4267 WERROR _spoolss_EnumPrinters(pipes_struct *p,
4268                              struct spoolss_EnumPrinters *r)
4269 {
4270         const char *name = NULL;
4271         WERROR result;
4272
4273         /* that's an [in out] buffer */
4274
4275         if (!r->in.buffer && (r->in.offered != 0)) {
4276                 return WERR_INVALID_PARAM;
4277         }
4278
4279         DEBUG(4,("_spoolss_EnumPrinters\n"));
4280
4281         *r->out.needed = 0;
4282         *r->out.count = 0;
4283         *r->out.info = NULL;
4284
4285         /*
4286          * Level 1:
4287          *          flags==PRINTER_ENUM_NAME
4288          *           if name=="" then enumerates all printers
4289          *           if name!="" then enumerate the printer
4290          *          flags==PRINTER_ENUM_REMOTE
4291          *          name is NULL, enumerate printers
4292          * Level 2: name!="" enumerates printers, name can't be NULL
4293          * Level 3: doesn't exist
4294          * Level 4: does a local registry lookup
4295          * Level 5: same as Level 2
4296          */
4297
4298         if (r->in.server) {
4299                 name = talloc_strdup_upper(p->mem_ctx, r->in.server);
4300                 W_ERROR_HAVE_NO_MEMORY(name);
4301         }
4302
4303         switch (r->in.level) {
4304         case 0:
4305                 result = enumprinters_level0(p->mem_ctx, r->in.flags, name,
4306                                              r->out.info, r->out.count);
4307                 break;
4308         case 1:
4309                 result = enumprinters_level1(p->mem_ctx, r->in.flags, name,
4310                                              r->out.info, r->out.count);
4311                 break;
4312         case 2:
4313                 result = enumprinters_level2(p->mem_ctx, r->in.flags, name,
4314                                              r->out.info, r->out.count);
4315                 break;
4316         case 4:
4317                 result = enumprinters_level4(p->mem_ctx, r->in.flags, name,
4318                                              r->out.info, r->out.count);
4319                 break;
4320         case 5:
4321                 result = enumprinters_level5(p->mem_ctx, r->in.flags, name,
4322                                              r->out.info, r->out.count);
4323                 break;
4324         default:
4325                 return WERR_UNKNOWN_LEVEL;
4326         }
4327
4328         if (!W_ERROR_IS_OK(result)) {
4329                 return result;
4330         }
4331
4332         *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
4333                                                      spoolss_EnumPrinters, NULL,
4334                                                      *r->out.info, r->in.level,
4335                                                      *r->out.count);
4336         *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
4337         *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
4338
4339         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4340 }
4341
4342 /****************************************************************
4343  _spoolss_GetPrinter
4344 ****************************************************************/
4345
4346 WERROR _spoolss_GetPrinter(pipes_struct *p,
4347                            struct spoolss_GetPrinter *r)
4348 {
4349         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
4350         NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4351         WERROR result = WERR_OK;
4352
4353         int snum;
4354
4355         /* that's an [in out] buffer */
4356
4357         if (!r->in.buffer && (r->in.offered != 0)) {
4358                 return WERR_INVALID_PARAM;
4359         }
4360
4361         *r->out.needed = 0;
4362
4363         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
4364                 return WERR_BADFID;
4365         }
4366
4367         result = get_a_printer(Printer, &ntprinter, 2,
4368                                lp_const_servicename(snum));
4369         if (!W_ERROR_IS_OK(result)) {
4370                 return result;
4371         }
4372
4373         switch (r->in.level) {
4374         case 0:
4375                 result = construct_printer_info0(p->mem_ctx, ntprinter,
4376                                                  &r->out.info->info0, snum);
4377                 break;
4378         case 1:
4379                 result = construct_printer_info1(p->mem_ctx, ntprinter,
4380                                                  PRINTER_ENUM_ICON8,
4381                                                  &r->out.info->info1, snum);
4382                 break;
4383         case 2:
4384                 result = construct_printer_info2(p->mem_ctx, ntprinter,
4385                                                  &r->out.info->info2, snum);
4386                 break;
4387         case 3:
4388                 result = construct_printer_info3(p->mem_ctx, ntprinter,
4389                                                  &r->out.info->info3, snum);
4390                 break;
4391         case 4:
4392                 result = construct_printer_info4(p->mem_ctx, ntprinter,
4393                                                  &r->out.info->info4, snum);
4394                 break;
4395         case 5:
4396                 result = construct_printer_info5(p->mem_ctx, ntprinter,
4397                                                  &r->out.info->info5, snum);
4398                 break;
4399         case 6:
4400                 result = construct_printer_info6(p->mem_ctx, ntprinter,
4401                                                  &r->out.info->info6, snum);
4402                 break;
4403         case 7:
4404                 result = construct_printer_info7(p->mem_ctx, Printer,
4405                                                  &r->out.info->info7, snum);
4406                 break;
4407         case 8:
4408                 result = construct_printer_info8(p->mem_ctx, ntprinter,
4409                                                  &r->out.info->info8, snum);
4410                 break;
4411         default:
4412                 result = WERR_UNKNOWN_LEVEL;
4413                 break;
4414         }
4415
4416         free_a_printer(&ntprinter, 2);
4417
4418         if (!W_ERROR_IS_OK(result)) {
4419                 TALLOC_FREE(r->out.info);
4420                 return result;
4421         }
4422
4423         *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo, NULL,
4424                                                r->out.info, r->in.level);
4425         r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
4426
4427         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4428 }
4429
4430 /********************************************************************
4431  ********************************************************************/
4432
4433 static const char **string_array_from_driver_info(TALLOC_CTX *mem_ctx,
4434                                                   const char **string_array,
4435                                                   const char *cservername)
4436 {
4437         int i, num_strings = 0;
4438         const char **array = NULL;
4439
4440         if (!string_array) {
4441                 return NULL;
4442         }
4443
4444         for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
4445
4446                 const char *str = talloc_asprintf(mem_ctx, "\\\\%s%s",
4447                                                   cservername, string_array[i]);
4448                 if (!str) {
4449                         TALLOC_FREE(array);
4450                         return NULL;
4451                 }
4452
4453
4454                 if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
4455                         TALLOC_FREE(array);
4456                         return NULL;
4457                 }
4458         }
4459
4460         if (i > 0) {
4461                 ADD_TO_ARRAY(mem_ctx, const char *, NULL,
4462                              &array, &num_strings);
4463         }
4464
4465         return array;
4466 }
4467
4468 #define FILL_DRIVER_STRING(mem_ctx, in, out) \
4469         do { \
4470                 if (in && strlen(in)) { \
4471                         out = talloc_strdup(mem_ctx, in); \
4472                         W_ERROR_HAVE_NO_MEMORY(out); \
4473                 } else { \
4474                         out = NULL; \
4475                 } \
4476         } while (0);
4477
4478 #define FILL_DRIVER_UNC_STRING(mem_ctx, server, in, out) \
4479         do { \
4480                 if (in && strlen(in)) { \
4481                         out = talloc_asprintf(mem_ctx, "\\\\%s%s", server, in); \
4482                 } else { \
4483                         out = talloc_strdup(mem_ctx, ""); \
4484                 } \
4485                 W_ERROR_HAVE_NO_MEMORY(out); \
4486         } while (0);
4487
4488 /********************************************************************
4489  * fill a spoolss_DriverInfo1 struct
4490  ********************************************************************/
4491
4492 static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
4493                                         struct spoolss_DriverInfo1 *r,
4494                                         const struct spoolss_DriverInfo8 *driver,
4495                                         const char *servername)
4496 {
4497         r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4498         W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4499
4500         return WERR_OK;
4501 }
4502
4503 /********************************************************************
4504  * fill a spoolss_DriverInfo2 struct
4505  ********************************************************************/
4506
4507 static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
4508                                         struct spoolss_DriverInfo2 *r,
4509                                         const struct spoolss_DriverInfo8 *driver,
4510                                         const char *servername)
4511
4512 {
4513         const char *cservername = canon_servername(servername);
4514
4515         r->version              = driver->version;
4516
4517         r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4518         W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4519         r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
4520         W_ERROR_HAVE_NO_MEMORY(r->architecture);
4521
4522         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4523                                driver->driver_path,
4524                                r->driver_path);
4525
4526         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4527                                driver->data_file,
4528                                r->data_file);
4529
4530         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4531                                driver->config_file,
4532                                r->config_file);
4533
4534         return WERR_OK;
4535 }
4536
4537 /********************************************************************
4538  * fill a spoolss_DriverInfo3 struct
4539  ********************************************************************/
4540
4541 static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
4542                                         struct spoolss_DriverInfo3 *r,
4543                                         const struct spoolss_DriverInfo8 *driver,
4544                                         const char *servername)
4545 {
4546         const char *cservername = canon_servername(servername);
4547
4548         r->version              = driver->version;
4549
4550         r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4551         W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4552         r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
4553         W_ERROR_HAVE_NO_MEMORY(r->architecture);
4554
4555         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4556                                driver->driver_path,
4557                                r->driver_path);
4558
4559         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4560                                driver->data_file,
4561                                r->data_file);
4562
4563         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4564                                driver->config_file,
4565                                r->config_file);
4566
4567         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4568                                driver->help_file,
4569                                r->help_file);
4570
4571         FILL_DRIVER_STRING(mem_ctx,
4572                            driver->monitor_name,
4573                            r->monitor_name);
4574
4575         FILL_DRIVER_STRING(mem_ctx,
4576                            driver->default_datatype,
4577                            r->default_datatype);
4578
4579         r->dependent_files = string_array_from_driver_info(mem_ctx,
4580                                                            driver->dependent_files,
4581                                                            cservername);
4582         return WERR_OK;
4583 }
4584
4585 /********************************************************************
4586  * fill a spoolss_DriverInfo4 struct
4587  ********************************************************************/
4588
4589 static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
4590                                         struct spoolss_DriverInfo4 *r,
4591                                         const struct spoolss_DriverInfo8 *driver,
4592                                         const char *servername)
4593 {
4594         const char *cservername = canon_servername(servername);
4595
4596         r->version              = driver->version;
4597
4598         r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4599         W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4600         r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
4601         W_ERROR_HAVE_NO_MEMORY(r->architecture);
4602
4603         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4604                                driver->driver_path,
4605                                r->driver_path);
4606
4607         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4608                                driver->data_file,
4609                                r->data_file);
4610
4611         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4612                                driver->config_file,
4613                                r->config_file);
4614
4615         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4616                                driver->help_file,
4617                                r->help_file);
4618
4619         r->dependent_files = string_array_from_driver_info(mem_ctx,
4620                                                            driver->dependent_files,
4621                                                            cservername);
4622
4623         FILL_DRIVER_STRING(mem_ctx,
4624                            driver->monitor_name,
4625                            r->monitor_name);
4626
4627         FILL_DRIVER_STRING(mem_ctx,
4628                            driver->default_datatype,
4629                            r->default_datatype);
4630
4631         r->previous_names = string_array_from_driver_info(mem_ctx,
4632                                                           driver->previous_names,
4633                                                           cservername);
4634
4635         return WERR_OK;
4636 }
4637
4638 /********************************************************************
4639  * fill a spoolss_DriverInfo5 struct
4640  ********************************************************************/
4641
4642 static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
4643                                         struct spoolss_DriverInfo5 *r,
4644                                         const struct spoolss_DriverInfo8 *driver,
4645                                         const char *servername)
4646 {
4647         const char *cservername = canon_servername(servername);
4648
4649         r->version              = driver->version;
4650
4651         r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4652         W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4653         r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
4654         W_ERROR_HAVE_NO_MEMORY(r->architecture);
4655
4656         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4657                                driver->driver_path,
4658                                r->driver_path);
4659
4660         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4661                                driver->data_file,
4662                                r->data_file);
4663
4664         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4665                                driver->config_file,
4666                                r->config_file);
4667
4668         r->driver_attributes    = 0;
4669         r->config_version       = 0;
4670         r->driver_version       = 0;
4671
4672         return WERR_OK;
4673 }
4674 /********************************************************************
4675  * fill a spoolss_DriverInfo6 struct
4676  ********************************************************************/
4677
4678 static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
4679                                         struct spoolss_DriverInfo6 *r,
4680                                         const struct spoolss_DriverInfo8 *driver,
4681                                         const char *servername)
4682 {
4683         const char *cservername = canon_servername(servername);
4684
4685         r->version              = driver->version;
4686
4687         r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4688         W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4689         r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
4690         W_ERROR_HAVE_NO_MEMORY(r->architecture);
4691
4692         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4693                                driver->driver_path,
4694                                r->driver_path);
4695
4696         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4697                                driver->data_file,
4698                                r->data_file);
4699
4700         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4701                                driver->config_file,
4702                                r->config_file);
4703
4704         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4705                                driver->help_file,
4706                                r->help_file);
4707
4708         FILL_DRIVER_STRING(mem_ctx,
4709                            driver->monitor_name,
4710                            r->monitor_name);
4711
4712         FILL_DRIVER_STRING(mem_ctx,
4713                            driver->default_datatype,
4714                            r->default_datatype);
4715
4716         r->dependent_files = string_array_from_driver_info(mem_ctx,
4717                                                            driver->dependent_files,
4718                                                            cservername);
4719         r->previous_names = string_array_from_driver_info(mem_ctx,
4720                                                           driver->previous_names,
4721                                                           cservername);
4722
4723         r->driver_date          = driver->driver_date;
4724         r->driver_version       = driver->driver_version;
4725
4726         FILL_DRIVER_STRING(mem_ctx,
4727                            driver->manufacturer_name,
4728                            r->manufacturer_name);
4729         FILL_DRIVER_STRING(mem_ctx,
4730                            driver->manufacturer_url,
4731                            r->manufacturer_url);
4732         FILL_DRIVER_STRING(mem_ctx,
4733                            driver->hardware_id,
4734                            r->hardware_id);
4735         FILL_DRIVER_STRING(mem_ctx,
4736                            driver->provider,
4737                            r->provider);
4738
4739         return WERR_OK;
4740 }
4741
4742 /********************************************************************
4743  * fill a spoolss_DriverInfo8 struct
4744  ********************************************************************/
4745
4746 static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
4747                                         struct spoolss_DriverInfo8 *r,
4748                                         const struct spoolss_DriverInfo8 *driver,
4749                                         const char *servername)
4750 {
4751         const char *cservername = canon_servername(servername);
4752
4753         r->version              = driver->version;
4754
4755         r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4756         W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4757         r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
4758         W_ERROR_HAVE_NO_MEMORY(r->architecture);
4759
4760         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4761                                driver->driver_path,
4762                                r->driver_path);
4763
4764         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4765                                driver->data_file,
4766                                r->data_file);
4767
4768         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4769                                driver->config_file,
4770                                r->config_file);
4771
4772         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4773                                driver->help_file,
4774                                r->help_file);
4775
4776         FILL_DRIVER_STRING(mem_ctx,
4777                            driver->monitor_name,
4778                            r->monitor_name);
4779
4780         FILL_DRIVER_STRING(mem_ctx,
4781                            driver->default_datatype,
4782                            r->default_datatype);
4783
4784         r->dependent_files = string_array_from_driver_info(mem_ctx,
4785                                                            driver->dependent_files,
4786                                                            cservername);
4787         r->previous_names = string_array_from_driver_info(mem_ctx,
4788                                                           driver->previous_names,
4789                                                           cservername);
4790
4791         r->driver_date          = driver->driver_date;
4792         r->driver_version       = driver->driver_version;
4793
4794         FILL_DRIVER_STRING(mem_ctx,
4795                            driver->manufacturer_name,
4796                            r->manufacturer_name);
4797         FILL_DRIVER_STRING(mem_ctx,
4798                            driver->manufacturer_url,
4799                            r->manufacturer_url);
4800         FILL_DRIVER_STRING(mem_ctx,
4801                            driver->hardware_id,
4802                            r->hardware_id);
4803         FILL_DRIVER_STRING(mem_ctx,
4804                            driver->provider,
4805                            r->provider);
4806
4807         FILL_DRIVER_STRING(mem_ctx,
4808                            driver->print_processor,
4809                            r->print_processor);
4810         FILL_DRIVER_STRING(mem_ctx,
4811                            driver->vendor_setup,
4812                            r->vendor_setup);
4813
4814         r->color_profiles = string_array_from_driver_info(mem_ctx,
4815                                                           driver->color_profiles,
4816                                                           cservername);
4817
4818         FILL_DRIVER_STRING(mem_ctx,
4819                            driver->inf_path,
4820                            r->inf_path);
4821
4822         r->printer_driver_attributes    = driver->printer_driver_attributes;
4823
4824         r->core_driver_dependencies = string_array_from_driver_info(mem_ctx,
4825                                                                     driver->core_driver_dependencies,
4826                                                                     cservername);
4827
4828         r->min_inbox_driver_ver_date    = driver->min_inbox_driver_ver_date;
4829         r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
4830
4831         return WERR_OK;
4832 }
4833
4834 #if 0 /* disabled until marshalling issues are resolved - gd */
4835 /********************************************************************
4836  ********************************************************************/
4837
4838 static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
4839                                           struct spoolss_DriverFileInfo *r,
4840                                           const char *cservername,
4841                                           const char *file_name,
4842                                           enum spoolss_DriverFileType file_type,
4843                                           uint32_t file_version)
4844 {
4845         r->file_name    = talloc_asprintf(mem_ctx, "\\\\%s%s",
4846                                           cservername, file_name);
4847         W_ERROR_HAVE_NO_MEMORY(r->file_name);
4848         r->file_type    = file_type;
4849         r->file_version = file_version;
4850
4851         return WERR_OK;
4852 }
4853
4854 /********************************************************************
4855  ********************************************************************/
4856
4857 static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
4858                                                  const struct spoolss_DriverInfo8 *driver,
4859                                                  const char *cservername,
4860                                                  struct spoolss_DriverFileInfo **info_p,
4861                                                  uint32_t *count_p)
4862 {
4863         struct spoolss_DriverFileInfo *info = NULL;
4864         uint32_t count = 0;
4865         WERROR result;
4866         uint32_t i;
4867
4868         *info_p = NULL;
4869         *count_p = 0;
4870
4871         if (strlen(driver->driver_path)) {
4872                 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4873                                             struct spoolss_DriverFileInfo,
4874                                             count + 1);
4875                 W_ERROR_HAVE_NO_MEMORY(info);
4876                 result = fill_spoolss_DriverFileInfo(info,
4877                                                      &info[count],
4878                                                      cservername,
4879                                                      driver->driver_path,
4880                                                      SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
4881                                                      0);
4882                 W_ERROR_NOT_OK_RETURN(result);
4883                 count++;
4884         }
4885
4886         if (strlen(driver->config_file)) {
4887                 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4888                                             struct spoolss_DriverFileInfo,
4889                                             count + 1);
4890                 W_ERROR_HAVE_NO_MEMORY(info);
4891                 result = fill_spoolss_DriverFileInfo(info,
4892                                                      &info[count],
4893                                                      cservername,
4894                                                      driver->config_file,
4895                                                      SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
4896                                                      0);
4897                 W_ERROR_NOT_OK_RETURN(result);
4898                 count++;
4899         }
4900
4901         if (strlen(driver->data_file)) {
4902                 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4903                                             struct spoolss_DriverFileInfo,
4904                                             count + 1);
4905                 W_ERROR_HAVE_NO_MEMORY(info);
4906                 result = fill_spoolss_DriverFileInfo(info,
4907                                                      &info[count],
4908                                                      cservername,
4909                                                      driver->data_file,
4910                                                      SPOOLSS_DRIVER_FILE_TYPE_DATA,
4911                                                      0);
4912                 W_ERROR_NOT_OK_RETURN(result);
4913                 count++;
4914         }
4915
4916         if (strlen(driver->help_file)) {
4917                 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4918                                             struct spoolss_DriverFileInfo,
4919                                             count + 1);
4920                 W_ERROR_HAVE_NO_MEMORY(info);
4921                 result = fill_spoolss_DriverFileInfo(info,
4922                                                      &info[count],
4923                                                      cservername,
4924                                                      driver->help_file,
4925                                                      SPOOLSS_DRIVER_FILE_TYPE_HELP,
4926                                                      0);
4927                 W_ERROR_NOT_OK_RETURN(result);
4928                 count++;
4929         }
4930
4931         for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
4932                 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4933                                             struct spoolss_DriverFileInfo,
4934                                             count + 1);
4935                 W_ERROR_HAVE_NO_MEMORY(info);
4936                 result = fill_spoolss_DriverFileInfo(info,
4937                                                      &info[count],
4938                                                      cservername,
4939                                                      driver->dependent_files[i],
4940                                                      SPOOLSS_DRIVER_FILE_TYPE_OTHER,
4941                                                      0);
4942                 W_ERROR_NOT_OK_RETURN(result);
4943                 count++;
4944         }
4945
4946         *info_p = info;
4947         *count_p = count;
4948
4949         return WERR_OK;
4950 }
4951
4952 /********************************************************************
4953  * fill a spoolss_DriverInfo101 struct
4954  ********************************************************************/
4955
4956 static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
4957                                           struct spoolss_DriverInfo101 *r,
4958                                           const struct spoolss_DriverInfo8 *driver,
4959                                           const char *servername)
4960 {
4961         const char *cservername = canon_servername(servername);
4962         WERROR result;
4963
4964         r->version              = driver->version;
4965
4966         r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4967         W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4968         r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
4969         W_ERROR_HAVE_NO_MEMORY(r->architecture);
4970
4971         result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
4972                                                     cservername,
4973                                                     &r->file_info,
4974                                                     &r->file_count);
4975         if (!W_ERROR_IS_OK(result)) {
4976                 return result;
4977         }
4978
4979         FILL_DRIVER_STRING(mem_ctx,
4980                            driver->monitor_name,
4981                            r->monitor_name);
4982
4983         FILL_DRIVER_STRING(mem_ctx,
4984                            driver->default_datatype,
4985                            r->default_datatype);
4986
4987         r->previous_names = string_array_from_driver_info(mem_ctx,
4988                                                           driver->previous_names,
4989                                                           cservername);
4990         r->driver_date          = driver->driver_date;
4991         r->driver_version       = driver->driver_version;
4992
4993         FILL_DRIVER_STRING(mem_ctx,
4994                            driver->manufacturer_name,
4995                            r->manufacturer_name);
4996         FILL_DRIVER_STRING(mem_ctx,
4997                            driver->manufacturer_url,
4998                            r->manufacturer_url);
4999         FILL_DRIVER_STRING(mem_ctx,
5000                            driver->hardware_id,
5001                            r->hardware_id);
5002         FILL_DRIVER_STRING(mem_ctx,
5003                            driver->provider,
5004                            r->provider);
5005
5006         return WERR_OK;
5007 }
5008 #endif
5009 /********************************************************************
5010  ********************************************************************/
5011
5012 static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
5013                                                   uint32_t level,
5014                                                   union spoolss_DriverInfo *r,
5015                                                   int snum,
5016                                                   const char *servername,
5017                                                   const char *architecture,
5018                                                   uint32_t version)
5019 {
5020         NT_PRINTER_INFO_LEVEL *printer = NULL;
5021         struct spoolss_DriverInfo8 *driver;
5022         WERROR result;
5023
5024         result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
5025
5026         DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5027                 win_errstr(result)));
5028
5029         if (!W_ERROR_IS_OK(result)) {
5030                 return WERR_INVALID_PRINTER_NAME;
5031         }
5032
5033         result = get_a_printer_driver(mem_ctx, &driver, printer->info_2->drivername,
5034                                       architecture, version);
5035
5036         DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5037                 win_errstr(result)));
5038
5039         if (!W_ERROR_IS_OK(result)) {
5040                 /*
5041                  * Is this a W2k client ?
5042                  */
5043
5044                 if (version < 3) {
5045                         free_a_printer(&printer, 2);
5046                         return WERR_UNKNOWN_PRINTER_DRIVER;
5047                 }
5048
5049                 /* Yes - try again with a WinNT driver. */
5050                 version = 2;
5051                 result = get_a_printer_driver(mem_ctx, &driver, printer->info_2->drivername,
5052                                               architecture, version);
5053                 DEBUG(8,("construct_printer_driver_level: status: %s\n",
5054                         win_errstr(result)));
5055                 if (!W_ERROR_IS_OK(result)) {
5056                         free_a_printer(&printer, 2);
5057                         return WERR_UNKNOWN_PRINTER_DRIVER;
5058                 }
5059         }
5060
5061         switch (level) {
5062         case 1:
5063                 result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
5064                 break;
5065         case 2:
5066                 result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
5067                 break;
5068         case 3:
5069                 result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
5070                 break;
5071         case 4:
5072                 result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
5073                 break;
5074         case 5:
5075                 result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
5076                 break;
5077         case 6:
5078                 result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
5079                 break;
5080         case 8:
5081                 result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
5082                 break;
5083 #if 0 /* disabled until marshalling issues are resolved - gd */
5084         case 101:
5085                 result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
5086                 break;
5087 #endif
5088         default:
5089                 result = WERR_UNKNOWN_LEVEL;
5090                 break;
5091         }
5092
5093         free_a_printer(&printer, 2);
5094         free_a_printer_driver(driver);
5095
5096         return result;
5097 }
5098
5099 /****************************************************************
5100  _spoolss_GetPrinterDriver2
5101 ****************************************************************/
5102
5103 WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
5104                                   struct spoolss_GetPrinterDriver2 *r)
5105 {
5106         Printer_entry *printer;
5107         WERROR result;
5108
5109         const char *servername;
5110         int snum;
5111
5112         /* that's an [in out] buffer */
5113
5114         if (!r->in.buffer && (r->in.offered != 0)) {
5115                 return WERR_INVALID_PARAM;
5116         }
5117
5118         DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5119
5120         if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
5121                 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5122                 return WERR_INVALID_PRINTER_NAME;
5123         }
5124
5125         *r->out.needed = 0;
5126         *r->out.server_major_version = 0;
5127         *r->out.server_minor_version = 0;
5128
5129         servername = get_server_name(printer);
5130
5131         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5132                 return WERR_BADFID;
5133         }
5134
5135         result = construct_printer_driver_info_level(p->mem_ctx, r->in.level,
5136                                                      r->out.info, snum,
5137                                                      servername,
5138                                                      r->in.architecture,
5139                                                      r->in.client_major_version);
5140         if (!W_ERROR_IS_OK(result)) {
5141                 TALLOC_FREE(r->out.info);
5142                 return result;
5143         }
5144
5145         *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo, NULL,
5146                                                r->out.info, r->in.level);
5147         r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
5148
5149         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
5150 }
5151
5152
5153 /****************************************************************
5154  _spoolss_StartPagePrinter
5155 ****************************************************************/
5156
5157 WERROR _spoolss_StartPagePrinter(pipes_struct *p,
5158                                  struct spoolss_StartPagePrinter *r)
5159 {
5160         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5161
5162         if (!Printer) {
5163                 DEBUG(3,("_spoolss_StartPagePrinter: "
5164                         "Error in startpageprinter printer handle\n"));
5165                 return WERR_BADFID;
5166         }
5167
5168         Printer->page_started = true;
5169         return WERR_OK;
5170 }
5171
5172 /****************************************************************
5173  _spoolss_EndPagePrinter
5174 ****************************************************************/
5175
5176 WERROR _spoolss_EndPagePrinter(pipes_struct *p,
5177                                struct spoolss_EndPagePrinter *r)
5178 {
5179         int snum;
5180
5181         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5182
5183         if (!Printer) {
5184                 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5185                         OUR_HANDLE(r->in.handle)));
5186                 return WERR_BADFID;
5187         }
5188
5189         if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5190                 return WERR_BADFID;
5191
5192         Printer->page_started = false;
5193         print_job_endpage(snum, Printer->jobid);
5194
5195         return WERR_OK;
5196 }
5197
5198 /****************************************************************
5199  _spoolss_StartDocPrinter
5200 ****************************************************************/
5201
5202 WERROR _spoolss_StartDocPrinter(pipes_struct *p,
5203                                 struct spoolss_StartDocPrinter *r)
5204 {
5205         struct spoolss_DocumentInfo1 *info_1;
5206         int snum;
5207         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5208
5209         if (!Printer) {
5210                 DEBUG(2,("_spoolss_StartDocPrinter: "
5211                         "Invalid handle (%s:%u:%u)\n",
5212                         OUR_HANDLE(r->in.handle)));
5213                 return WERR_BADFID;
5214         }
5215
5216         if (r->in.level != 1) {
5217                 return WERR_UNKNOWN_LEVEL;
5218         }
5219
5220         info_1 = r->in.info.info1;
5221
5222         /*
5223          * a nice thing with NT is it doesn't listen to what you tell it.
5224          * when asked to send _only_ RAW datas, it tries to send datas
5225          * in EMF format.
5226          *
5227          * So I add checks like in NT Server ...
5228          */
5229
5230         if (info_1->datatype) {
5231                 if (strcmp(info_1->datatype, "RAW") != 0) {
5232                         *r->out.job_id = 0;
5233                         return WERR_INVALID_DATATYPE;
5234                 }
5235         }
5236
5237         /* get the share number of the printer */
5238         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5239                 return WERR_BADFID;
5240         }
5241
5242         Printer->jobid = print_job_start(p->server_info, snum,
5243                                          info_1->document_name,
5244                                          Printer->nt_devmode);
5245
5246         /* An error occured in print_job_start() so return an appropriate
5247            NT error code. */
5248
5249         if (Printer->jobid == -1) {
5250                 return map_werror_from_unix(errno);
5251         }
5252
5253         Printer->document_started = true;
5254         *r->out.job_id = Printer->jobid;
5255
5256         return WERR_OK;
5257 }
5258
5259 /****************************************************************
5260  _spoolss_EndDocPrinter
5261 ****************************************************************/
5262
5263 WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5264                               struct spoolss_EndDocPrinter *r)
5265 {
5266         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5267         int snum;
5268
5269         if (!Printer) {
5270                 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5271                         OUR_HANDLE(r->in.handle)));
5272                 return WERR_BADFID;
5273         }
5274
5275         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5276                 return WERR_BADFID;
5277         }
5278
5279         Printer->document_started = false;
5280         print_job_end(snum, Printer->jobid, NORMAL_CLOSE);
5281         /* error codes unhandled so far ... */
5282
5283         return WERR_OK;
5284 }
5285
5286 /****************************************************************
5287  _spoolss_WritePrinter
5288 ****************************************************************/
5289
5290 WERROR _spoolss_WritePrinter(pipes_struct *p,
5291                              struct spoolss_WritePrinter *r)
5292 {
5293         uint32_t buffer_written;
5294         int snum;
5295         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5296
5297         if (!Printer) {
5298                 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5299                         OUR_HANDLE(r->in.handle)));
5300                 *r->out.num_written = r->in._data_size;
5301                 return WERR_BADFID;
5302         }
5303
5304         if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5305                 return WERR_BADFID;
5306
5307         buffer_written = (uint32_t)print_job_write(snum, Printer->jobid,
5308                                                    (const char *)r->in.data.data,
5309                                                    (SMB_OFF_T)-1,
5310                                                    (size_t)r->in._data_size);
5311         if (buffer_written == (uint32_t)-1) {
5312                 *r->out.num_written = 0;
5313                 if (errno == ENOSPC)
5314                         return WERR_NO_SPOOL_SPACE;
5315                 else
5316                         return WERR_ACCESS_DENIED;
5317         }
5318
5319         *r->out.num_written = r->in._data_size;
5320
5321         return WERR_OK;
5322 }
5323
5324 /********************************************************************
5325  * api_spoolss_getprinter
5326  * called from the spoolss dispatcher
5327  *
5328  ********************************************************************/
5329
5330 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
5331                               pipes_struct *p)
5332 {
5333         int snum;
5334         WERROR errcode = WERR_BADFUNC;
5335         Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5336
5337         if (!Printer) {
5338                 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5339                         OUR_HANDLE(handle)));
5340                 return WERR_BADFID;
5341         }
5342
5343         if (!get_printer_snum(p, handle, &snum, NULL))
5344                 return WERR_BADFID;
5345
5346         switch (command) {
5347         case SPOOLSS_PRINTER_CONTROL_PAUSE:
5348                 errcode = print_queue_pause(p->server_info, snum);
5349                 break;
5350         case SPOOLSS_PRINTER_CONTROL_RESUME:
5351         case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5352                 errcode = print_queue_resume(p->server_info, snum);
5353                 break;
5354         case SPOOLSS_PRINTER_CONTROL_PURGE:
5355                 errcode = print_queue_purge(p->server_info, snum);
5356                 break;
5357         default:
5358                 return WERR_UNKNOWN_LEVEL;
5359         }
5360
5361         return errcode;
5362 }
5363
5364
5365 /****************************************************************
5366  _spoolss_AbortPrinter
5367  * From MSDN: "Deletes printer's spool file if printer is configured
5368  * for spooling"
5369 ****************************************************************/
5370
5371 WERROR _spoolss_AbortPrinter(pipes_struct *p,
5372                              struct spoolss_AbortPrinter *r)
5373 {
5374         Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
5375         int             snum;
5376         WERROR          errcode = WERR_OK;
5377
5378         if (!Printer) {
5379                 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5380                         OUR_HANDLE(r->in.handle)));
5381                 return WERR_BADFID;
5382         }
5383
5384         if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5385                 return WERR_BADFID;
5386
5387         print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
5388
5389         return errcode;
5390 }
5391
5392 /********************************************************************
5393  * called by spoolss_api_setprinter
5394  * when updating a printer description
5395  ********************************************************************/
5396
5397 static WERROR update_printer_sec(struct policy_handle *handle,
5398                                  pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
5399 {
5400         SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
5401         WERROR result;
5402         int snum;
5403
5404         Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5405
5406         if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5407                 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5408                          OUR_HANDLE(handle)));
5409
5410                 result = WERR_BADFID;
5411                 goto done;
5412         }
5413
5414         if (!secdesc_ctr) {
5415                 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5416                 result = WERR_INVALID_PARAM;
5417                 goto done;
5418         }
5419
5420         /* Check the user has permissions to change the security
5421            descriptor.  By experimentation with two NT machines, the user
5422            requires Full Access to the printer to change security
5423            information. */
5424
5425         if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5426                 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5427                 result = WERR_ACCESS_DENIED;
5428                 goto done;
5429         }
5430
5431         /* NT seems to like setting the security descriptor even though
5432            nothing may have actually changed. */
5433
5434         if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) {
5435                 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
5436                 result = WERR_BADFID;
5437                 goto done;
5438         }
5439
5440         if (DEBUGLEVEL >= 10) {
5441                 SEC_ACL *the_acl;
5442                 int i;
5443
5444                 the_acl = old_secdesc_ctr->sd->dacl;
5445                 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5446                            PRINTERNAME(snum), the_acl->num_aces));
5447
5448                 for (i = 0; i < the_acl->num_aces; i++) {
5449                         DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5450                                            &the_acl->aces[i].trustee),
5451                                   the_acl->aces[i].access_mask));
5452                 }
5453
5454                 the_acl = secdesc_ctr->sd->dacl;
5455
5456                 if (the_acl) {
5457                         DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5458                                    PRINTERNAME(snum), the_acl->num_aces));
5459
5460                         for (i = 0; i < the_acl->num_aces; i++) {
5461                                 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5462                                                    &the_acl->aces[i].trustee),
5463                                            the_acl->aces[i].access_mask));
5464                         }
5465                 } else {
5466                         DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5467                 }
5468         }
5469
5470         new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
5471         if (!new_secdesc_ctr) {
5472                 result = WERR_NOMEM;
5473                 goto done;
5474         }
5475
5476         if (security_descriptor_equal(new_secdesc_ctr->sd, old_secdesc_ctr->sd)) {
5477                 result = WERR_OK;
5478                 goto done;
5479         }
5480
5481         result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
5482
5483  done:
5484
5485         return result;
5486 }
5487
5488 /********************************************************************
5489  Canonicalize printer info from a client
5490
5491  ATTN: It does not matter what we set the servername to hear
5492  since we do the necessary work in get_a_printer() to set it to
5493  the correct value based on what the client sent in the
5494  _spoolss_open_printer_ex().
5495  ********************************************************************/
5496
5497 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
5498 {
5499         fstring printername;
5500         const char *p;
5501
5502         DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5503                 "portname=%s drivername=%s comment=%s location=%s\n",
5504                 info->servername, info->printername, info->sharename,
5505                 info->portname, info->drivername, info->comment, info->location));
5506
5507         /* we force some elements to "correct" values */
5508         slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
5509         fstrcpy(info->sharename, lp_servicename(snum));
5510
5511         /* check to see if we allow printername != sharename */
5512
5513         if ( lp_force_printername(snum) ) {
5514                 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
5515                         global_myname(), info->sharename );
5516         } else {
5517
5518                 /* make sure printername is in \\server\printername format */
5519
5520                 fstrcpy( printername, info->printername );
5521                 p = printername;
5522                 if ( printername[0] == '\\' && printername[1] == '\\' ) {
5523                         if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
5524                                 p++;
5525                 }
5526
5527                 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
5528                          global_myname(), p );
5529         }
5530
5531         info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
5532         info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
5533
5534
5535
5536         return true;
5537 }
5538
5539 /****************************************************************************
5540 ****************************************************************************/
5541
5542 static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
5543 {
5544         char *cmd = lp_addport_cmd();
5545         char *command = NULL;
5546         int ret;
5547         SE_PRIV se_printop = SE_PRINT_OPERATOR;
5548         bool is_print_op = false;
5549
5550         if ( !*cmd ) {
5551                 return WERR_ACCESS_DENIED;
5552         }
5553
5554         command = talloc_asprintf(ctx,
5555                         "%s \"%s\" \"%s\"", cmd, portname, uri );
5556         if (!command) {
5557                 return WERR_NOMEM;
5558         }
5559
5560         if ( token )
5561                 is_print_op = user_has_privileges( token, &se_printop );
5562
5563         DEBUG(10,("Running [%s]\n", command));
5564
5565         /********* BEGIN SePrintOperatorPrivilege **********/
5566
5567         if ( is_print_op )
5568                 become_root();
5569
5570         ret = smbrun(command, NULL);
5571
5572         if ( is_print_op )
5573                 unbecome_root();
5574
5575         /********* END SePrintOperatorPrivilege **********/
5576
5577         DEBUGADD(10,("returned [%d]\n", ret));
5578
5579         TALLOC_FREE(command);
5580
5581         if ( ret != 0 ) {
5582                 return WERR_ACCESS_DENIED;
5583         }
5584
5585         return WERR_OK;
5586 }
5587
5588 /****************************************************************************
5589 ****************************************************************************/
5590
5591 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
5592 {
5593         char *cmd = lp_addprinter_cmd();
5594         char **qlines;
5595         char *command = NULL;
5596         int numlines;
5597         int ret;
5598         int fd;
5599         SE_PRIV se_printop = SE_PRINT_OPERATOR;
5600         bool is_print_op = false;
5601         char *remote_machine = talloc_strdup(ctx, "%m");
5602
5603         if (!remote_machine) {
5604                 return false;
5605         }
5606         remote_machine = talloc_sub_basic(ctx,
5607                                 current_user_info.smb_name,
5608                                 current_user_info.domain,
5609                                 remote_machine);
5610         if (!remote_machine) {
5611                 return false;
5612         }
5613
5614         command = talloc_asprintf(ctx,
5615                         "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5616                         cmd, printer->info_2->printername, printer->info_2->sharename,
5617                         printer->info_2->portname, printer->info_2->drivername,
5618                         printer->info_2->location, printer->info_2->comment, remote_machine);
5619         if (!command) {
5620                 return false;
5621         }
5622
5623         if ( token )
5624                 is_print_op = user_has_privileges( token, &se_printop );
5625
5626         DEBUG(10,("Running [%s]\n", command));
5627
5628         /********* BEGIN SePrintOperatorPrivilege **********/
5629
5630         if ( is_print_op )
5631                 become_root();
5632
5633         if ( (ret = smbrun(command, &fd)) == 0 ) {
5634                 /* Tell everyone we updated smb.conf. */
5635                 message_send_all(smbd_messaging_context(),
5636                                  MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
5637         }
5638
5639         if ( is_print_op )
5640                 unbecome_root();
5641
5642         /********* END SePrintOperatorPrivilege **********/
5643
5644         DEBUGADD(10,("returned [%d]\n", ret));
5645
5646         TALLOC_FREE(command);
5647         TALLOC_FREE(remote_machine);
5648
5649         if ( ret != 0 ) {
5650                 if (fd != -1)
5651                         close(fd);
5652                 return false;
5653         }
5654
5655         /* reload our services immediately */
5656         become_root();
5657         reload_services(false);
5658         unbecome_root();
5659
5660         numlines = 0;
5661         /* Get lines and convert them back to dos-codepage */
5662         qlines = fd_lines_load(fd, &numlines, 0, NULL);
5663         DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5664         close(fd);
5665
5666         /* Set the portname to what the script says the portname should be. */
5667         /* but don't require anything to be return from the script exit a good error code */
5668
5669         if (numlines) {
5670                 /* Set the portname to what the script says the portname should be. */
5671                 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
5672                 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
5673         }
5674
5675         TALLOC_FREE(qlines);
5676         return true;
5677 }
5678
5679
5680 /********************************************************************
5681  * Called by spoolss_api_setprinter
5682  * when updating a printer description.
5683  ********************************************************************/
5684
5685 static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
5686                              struct spoolss_SetPrinterInfoCtr *info_ctr,
5687                              struct spoolss_DeviceMode *devmode)
5688 {
5689         int snum;
5690         NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
5691         Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5692         WERROR result;
5693         DATA_BLOB buffer;
5694         fstring asc_buffer;
5695
5696         DEBUG(8,("update_printer\n"));
5697
5698         result = WERR_OK;
5699
5700         if (!Printer) {
5701                 result = WERR_BADFID;
5702                 goto done;
5703         }
5704
5705         if (!get_printer_snum(p, handle, &snum, NULL)) {
5706                 result = WERR_BADFID;
5707                 goto done;
5708         }
5709
5710         if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
5711             (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
5712                 result = WERR_BADFID;
5713                 goto done;
5714         }
5715
5716         DEBUGADD(8,("Converting info_2 struct\n"));
5717
5718         /*
5719          * convert_printer_info converts the incoming
5720          * info from the client and overwrites the info
5721          * just read from the tdb in the pointer 'printer'.
5722          */
5723
5724         if (!convert_printer_info(info_ctr, printer)) {
5725                 result =  WERR_NOMEM;
5726                 goto done;
5727         }
5728
5729         if (devmode) {
5730                 /* we have a valid devmode
5731                    convert it and link it*/
5732
5733                 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
5734                 if (!convert_devicemode(printer->info_2->printername, devmode,
5735                                         &printer->info_2->devmode)) {
5736                         result =  WERR_NOMEM;
5737                         goto done;
5738                 }
5739         }
5740
5741         /* Do sanity check on the requested changes for Samba */
5742
5743         if (!check_printer_ok(printer->info_2, snum)) {
5744                 result = WERR_INVALID_PARAM;
5745                 goto done;
5746         }
5747
5748         /* FIXME!!! If the driver has changed we really should verify that
5749            it is installed before doing much else   --jerry */
5750
5751         /* Check calling user has permission to update printer description */
5752
5753         if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
5754                 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5755                 result = WERR_ACCESS_DENIED;
5756                 goto done;
5757         }
5758
5759         /* Call addprinter hook */
5760         /* Check changes to see if this is really needed */
5761
5762         if ( *lp_addprinter_cmd()
5763                 && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
5764                         || !strequal(printer->info_2->comment, old_printer->info_2->comment)
5765                         || !strequal(printer->info_2->portname, old_printer->info_2->portname)
5766                         || !strequal(printer->info_2->location, old_printer->info_2->location)) )
5767         {
5768                 /* add_printer_hook() will call reload_services() */
5769
5770                 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
5771                                        printer) ) {
5772                         result = WERR_ACCESS_DENIED;
5773                         goto done;
5774                 }
5775         }
5776
5777         /*
5778          * When a *new* driver is bound to a printer, the drivername is used to
5779          * lookup previously saved driver initialization info, which is then
5780          * bound to the printer, simulating what happens in the Windows arch.
5781          */
5782         if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
5783         {
5784                 if (!set_driver_init(printer, 2))
5785                 {
5786                         DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
5787                                 printer->info_2->drivername));
5788                 }
5789
5790                 DEBUG(10,("update_printer: changing driver [%s]!  Sending event!\n",
5791                         printer->info_2->drivername));
5792
5793                 notify_printer_driver(snum, printer->info_2->drivername);
5794         }
5795
5796         /*
5797          * flag which changes actually occured.  This is a small subset of
5798          * all the possible changes.  We also have to update things in the
5799          * DsSpooler key.
5800          */
5801
5802         if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
5803                 push_reg_sz(talloc_tos(), &buffer, printer->info_2->comment);
5804                 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
5805                         REG_SZ, buffer.data, buffer.length);
5806
5807                 notify_printer_comment(snum, printer->info_2->comment);
5808         }
5809
5810         if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
5811                 push_reg_sz(talloc_tos(), &buffer, printer->info_2->sharename);
5812                 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
5813                         REG_SZ, buffer.data, buffer.length);
5814
5815                 notify_printer_sharename(snum, printer->info_2->sharename);
5816         }
5817
5818         if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
5819                 char *pname;
5820
5821                 if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
5822                         pname++;
5823                 else
5824                         pname = printer->info_2->printername;
5825
5826
5827                 push_reg_sz(talloc_tos(), &buffer, pname);
5828                 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
5829                         REG_SZ, buffer.data, buffer.length);
5830
5831                 notify_printer_printername( snum, pname );
5832         }
5833
5834         if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
5835                 push_reg_sz(talloc_tos(), &buffer, printer->info_2->portname);
5836                 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
5837                         REG_SZ, buffer.data, buffer.length);
5838
5839                 notify_printer_port(snum, printer->info_2->portname);
5840         }
5841
5842         if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
5843                 push_reg_sz(talloc_tos(), &buffer, printer->info_2->location);
5844                 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
5845                         REG_SZ, buffer.data, buffer.length);
5846
5847                 notify_printer_location(snum, printer->info_2->location);
5848         }
5849
5850         /* here we need to update some more DsSpooler keys */
5851         /* uNCName, serverName, shortServerName */
5852
5853         push_reg_sz(talloc_tos(), &buffer, global_myname());
5854         set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
5855                 REG_SZ, buffer.data, buffer.length);
5856         set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
5857                 REG_SZ, buffer.data, buffer.length);
5858
5859         slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
5860                  global_myname(), printer->info_2->sharename );
5861         push_reg_sz(talloc_tos(), &buffer, asc_buffer);
5862         set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
5863                 REG_SZ, buffer.data, buffer.length);
5864
5865         /* Update printer info */
5866         result = mod_a_printer(printer, 2);
5867
5868 done:
5869         free_a_printer(&printer, 2);
5870         free_a_printer(&old_printer, 2);
5871
5872
5873         return result;
5874 }
5875
5876 /****************************************************************************
5877 ****************************************************************************/
5878 static WERROR publish_or_unpublish_printer(pipes_struct *p,
5879                                            struct policy_handle *handle,
5880                                            struct spoolss_SetPrinterInfo7 *info7)
5881 {
5882 #ifdef HAVE_ADS
5883         int snum;
5884         Printer_entry *Printer;
5885
5886         if ( lp_security() != SEC_ADS ) {
5887                 return WERR_UNKNOWN_LEVEL;
5888         }
5889
5890         Printer = find_printer_index_by_hnd(p, handle);
5891
5892         DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
5893
5894         if (!Printer)
5895                 return WERR_BADFID;
5896
5897         if (!get_printer_snum(p, handle, &snum, NULL))
5898                 return WERR_BADFID;
5899
5900         nt_printer_publish(Printer, snum, info7->action);
5901
5902         return WERR_OK;
5903 #else
5904         return WERR_UNKNOWN_LEVEL;
5905 #endif
5906 }
5907
5908 /********************************************************************
5909  ********************************************************************/
5910
5911 static WERROR update_printer_devmode(pipes_struct *p, struct policy_handle *handle,
5912                                      struct spoolss_DeviceMode *devmode)
5913 {
5914         int snum;
5915         NT_PRINTER_INFO_LEVEL *printer = NULL;
5916         Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5917         WERROR result;
5918
5919         DEBUG(8,("update_printer_devmode\n"));
5920
5921         result = WERR_OK;
5922
5923         if (!Printer) {
5924                 result = WERR_BADFID;
5925                 goto done;
5926         }
5927
5928         if (!get_printer_snum(p, handle, &snum, NULL)) {
5929                 result = WERR_BADFID;
5930                 goto done;
5931         }
5932
5933         if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)))) {
5934                 result = WERR_BADFID;
5935                 goto done;
5936         }
5937
5938         if (devmode) {
5939                 /* we have a valid devmode
5940                    convert it and link it*/
5941
5942                 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
5943                 if (!convert_devicemode(printer->info_2->printername, devmode,
5944                                         &printer->info_2->devmode)) {
5945                         result =  WERR_NOMEM;
5946                         goto done;
5947                 }
5948         }
5949
5950         /* Check calling user has permission to update printer description */
5951
5952         if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
5953                 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5954                 result = WERR_ACCESS_DENIED;
5955                 goto done;
5956         }
5957
5958
5959         /* Update printer info */
5960         result = mod_a_printer(printer, 2);
5961
5962 done:
5963         free_a_printer(&printer, 2);
5964
5965         return result;
5966 }
5967
5968
5969 /****************************************************************
5970  _spoolss_SetPrinter
5971 ****************************************************************/
5972
5973 WERROR _spoolss_SetPrinter(pipes_struct *p,
5974                            struct spoolss_SetPrinter *r)
5975 {
5976         WERROR result;
5977
5978         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5979
5980         if (!Printer) {
5981                 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
5982                         OUR_HANDLE(r->in.handle)));
5983                 return WERR_BADFID;
5984         }
5985
5986         /* check the level */
5987         switch (r->in.info_ctr->level) {
5988                 case 0:
5989                         return control_printer(r->in.handle, r->in.command, p);
5990                 case 2:
5991                         result = update_printer(p, r->in.handle,
5992                                                 r->in.info_ctr,
5993                                                 r->in.devmode_ctr->devmode);
5994                         if (!W_ERROR_IS_OK(result))
5995                                 return result;
5996                         if (r->in.secdesc_ctr->sd)
5997                                 result = update_printer_sec(r->in.handle, p,
5998                                                             r->in.secdesc_ctr);
5999                         return result;
6000                 case 3:
6001                         return update_printer_sec(r->in.handle, p,
6002                                                   r->in.secdesc_ctr);
6003                 case 7:
6004                         return publish_or_unpublish_printer(p, r->in.handle,
6005                                                             r->in.info_ctr->info.info7);
6006                 case 8:
6007                         return update_printer_devmode(p, r->in.handle,
6008                                                       r->in.devmode_ctr->devmode);
6009                 default:
6010                         return WERR_UNKNOWN_LEVEL;
6011         }
6012 }
6013
6014 /****************************************************************
6015  _spoolss_FindClosePrinterNotify
6016 ****************************************************************/
6017
6018 WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
6019                                        struct spoolss_FindClosePrinterNotify *r)
6020 {
6021         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6022
6023         if (!Printer) {
6024                 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6025                         "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6026                 return WERR_BADFID;
6027         }
6028
6029         if (Printer->notify.client_connected == true) {
6030                 int snum = -1;
6031
6032                 if ( Printer->printer_type == SPLHND_SERVER)
6033                         snum = -1;
6034                 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6035                                 !get_printer_snum(p, r->in.handle, &snum, NULL) )
6036                         return WERR_BADFID;
6037
6038                 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6039         }
6040
6041         Printer->notify.flags=0;
6042         Printer->notify.options=0;
6043         Printer->notify.localmachine[0]='\0';
6044         Printer->notify.printerlocal=0;
6045         TALLOC_FREE(Printer->notify.option);
6046         Printer->notify.client_connected = false;
6047
6048         return WERR_OK;
6049 }
6050
6051 /****************************************************************
6052  _spoolss_AddJob
6053 ****************************************************************/
6054
6055 WERROR _spoolss_AddJob(pipes_struct *p,
6056                        struct spoolss_AddJob *r)
6057 {
6058         if (!r->in.buffer && (r->in.offered != 0)) {
6059                 return WERR_INVALID_PARAM;
6060         }
6061
6062         /* this is what a NT server returns for AddJob. AddJob must fail on
6063          * non-local printers */
6064
6065         if (r->in.level != 1) {
6066                 return WERR_UNKNOWN_LEVEL;
6067         }
6068
6069         return WERR_INVALID_PARAM;
6070 }
6071
6072 /****************************************************************************
6073 fill_job_info1
6074 ****************************************************************************/
6075
6076 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6077                              struct spoolss_JobInfo1 *r,
6078                              const print_queue_struct *queue,
6079                              int position, int snum,
6080                              const NT_PRINTER_INFO_LEVEL *ntprinter)
6081 {
6082         struct tm *t;
6083
6084         t = gmtime(&queue->time);
6085
6086         r->job_id               = queue->job;
6087
6088         r->printer_name         = talloc_strdup(mem_ctx, lp_servicename(snum));
6089         W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6090         r->server_name          = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
6091         W_ERROR_HAVE_NO_MEMORY(r->server_name);
6092         r->user_name            = talloc_strdup(mem_ctx, queue->fs_user);
6093         W_ERROR_HAVE_NO_MEMORY(r->user_name);
6094         r->document_name        = talloc_strdup(mem_ctx, queue->fs_file);
6095         W_ERROR_HAVE_NO_MEMORY(r->document_name);
6096         r->data_type            = talloc_strdup(mem_ctx, "RAW");
6097         W_ERROR_HAVE_NO_MEMORY(r->data_type);
6098         r->text_status          = talloc_strdup(mem_ctx, "");
6099         W_ERROR_HAVE_NO_MEMORY(r->text_status);
6100
6101         r->status               = nt_printj_status(queue->status);
6102         r->priority             = queue->priority;
6103         r->position             = position;
6104         r->total_pages          = queue->page_count;
6105         r->pages_printed        = 0; /* ??? */
6106
6107         init_systemtime(&r->submitted, t);
6108
6109         return WERR_OK;
6110 }
6111
6112 /****************************************************************************
6113 fill_job_info2
6114 ****************************************************************************/
6115
6116 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6117                              struct spoolss_JobInfo2 *r,
6118                              const print_queue_struct *queue,
6119                              int position, int snum,
6120                              const NT_PRINTER_INFO_LEVEL *ntprinter,
6121                              struct spoolss_DeviceMode *devmode)
6122 {
6123         struct tm *t;
6124
6125         t = gmtime(&queue->time);
6126
6127         r->job_id               = queue->job;
6128
6129         r->printer_name         = talloc_strdup(mem_ctx, lp_servicename(snum));
6130         W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6131         r->server_name          = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
6132         W_ERROR_HAVE_NO_MEMORY(r->server_name);
6133         r->user_name            = talloc_strdup(mem_ctx, queue->fs_user);
6134         W_ERROR_HAVE_NO_MEMORY(r->user_name);
6135         r->document_name        = talloc_strdup(mem_ctx, queue->fs_file);
6136         W_ERROR_HAVE_NO_MEMORY(r->document_name);
6137         r->notify_name          = talloc_strdup(mem_ctx, queue->fs_user);
6138         W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6139         r->data_type            = talloc_strdup(mem_ctx, "RAW");
6140         W_ERROR_HAVE_NO_MEMORY(r->data_type);
6141         r->print_processor      = talloc_strdup(mem_ctx, "winprint");
6142         W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6143         r->parameters           = talloc_strdup(mem_ctx, "");
6144         W_ERROR_HAVE_NO_MEMORY(r->parameters);
6145         r->driver_name          = talloc_strdup(mem_ctx, ntprinter->info_2->drivername);
6146         W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6147
6148         r->devmode              = devmode;
6149
6150         r->text_status          = talloc_strdup(mem_ctx, "");
6151         W_ERROR_HAVE_NO_MEMORY(r->text_status);
6152
6153         r->secdesc              = NULL;
6154
6155         r->status               = nt_printj_status(queue->status);
6156         r->priority             = queue->priority;
6157         r->position             = position;
6158         r->start_time           = 0;
6159         r->until_time           = 0;
6160         r->total_pages          = queue->page_count;
6161         r->size                 = queue->size;
6162         init_systemtime(&r->submitted, t);
6163         r->time                 = 0;
6164         r->pages_printed        = 0; /* ??? */
6165
6166         return WERR_OK;
6167 }
6168
6169 /****************************************************************************
6170 fill_job_info3
6171 ****************************************************************************/
6172
6173 static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6174                              struct spoolss_JobInfo3 *r,
6175                              const print_queue_struct *queue,
6176                              const print_queue_struct *next_queue,
6177                              int position, int snum,
6178                              const NT_PRINTER_INFO_LEVEL *ntprinter)
6179 {
6180         r->job_id               = queue->job;
6181         r->next_job_id          = 0;
6182         if (next_queue) {
6183                 r->next_job_id  = next_queue->job;
6184         }
6185         r->reserved             = 0;
6186
6187         return WERR_OK;
6188 }
6189
6190 /****************************************************************************
6191  Enumjobs at level 1.
6192 ****************************************************************************/
6193
6194 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6195                               const print_queue_struct *queue,
6196                               uint32_t num_queues, int snum,
6197                               const NT_PRINTER_INFO_LEVEL *ntprinter,
6198                               union spoolss_JobInfo **info_p,
6199                               uint32_t *count)
6200 {
6201         union spoolss_JobInfo *info;
6202         int i;
6203         WERROR result = WERR_OK;
6204
6205         info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6206         W_ERROR_HAVE_NO_MEMORY(info);
6207
6208         *count = num_queues;
6209
6210         for (i=0; i<*count; i++) {
6211                 result = fill_job_info1(info,
6212                                         &info[i].info1,
6213                                         &queue[i],
6214                                         i,
6215                                         snum,
6216                                         ntprinter);
6217                 if (!W_ERROR_IS_OK(result)) {
6218                         goto out;
6219                 }
6220         }
6221
6222  out:
6223         if (!W_ERROR_IS_OK(result)) {
6224                 TALLOC_FREE(info);
6225                 *count = 0;
6226                 return result;
6227         }
6228
6229         *info_p = info;
6230
6231         return WERR_OK;
6232 }
6233
6234 /****************************************************************************
6235  Enumjobs at level 2.
6236 ****************************************************************************/
6237
6238 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6239                               const print_queue_struct *queue,
6240                               uint32_t num_queues, int snum,
6241                               const NT_PRINTER_INFO_LEVEL *ntprinter,
6242                               union spoolss_JobInfo **info_p,
6243                               uint32_t *count)
6244 {
6245         union spoolss_JobInfo *info;
6246         int i;
6247         WERROR result = WERR_OK;
6248
6249         info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6250         W_ERROR_HAVE_NO_MEMORY(info);
6251
6252         *count = num_queues;
6253
6254         for (i=0; i<*count; i++) {
6255
6256                 struct spoolss_DeviceMode *devmode;
6257
6258                 devmode = construct_dev_mode(info, lp_const_servicename(snum));
6259                 if (!devmode) {
6260                         result = WERR_NOMEM;
6261                         goto out;
6262                 }
6263
6264                 result = fill_job_info2(info,
6265                                         &info[i].info2,
6266                                         &queue[i],
6267                                         i,
6268                                         snum,
6269                                         ntprinter,
6270                                         devmode);
6271                 if (!W_ERROR_IS_OK(result)) {
6272                         goto out;
6273                 }
6274         }
6275
6276  out:
6277         if (!W_ERROR_IS_OK(result)) {
6278                 TALLOC_FREE(info);
6279                 *count = 0;
6280                 return result;
6281         }
6282
6283         *info_p = info;
6284
6285         return WERR_OK;
6286 }
6287
6288 /****************************************************************************
6289  Enumjobs at level 3.
6290 ****************************************************************************/
6291
6292 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6293                               const print_queue_struct *queue,
6294                               uint32_t num_queues, int snum,
6295                               const NT_PRINTER_INFO_LEVEL *ntprinter,
6296                               union spoolss_JobInfo **info_p,
6297                               uint32_t *count)
6298 {
6299         union spoolss_JobInfo *info;
6300         int i;
6301         WERROR result = WERR_OK;
6302
6303         info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6304         W_ERROR_HAVE_NO_MEMORY(info);
6305
6306         *count = num_queues;
6307
6308         for (i=0; i<*count; i++) {
6309                 const print_queue_struct *next_queue = NULL;
6310
6311                 if (i+1 < *count) {
6312                         next_queue = &queue[i+1];
6313                 }
6314
6315                 result = fill_job_info3(info,
6316                                         &info[i].info3,
6317                                         &queue[i],
6318                                         next_queue,
6319                                         i,
6320                                         snum,
6321                                         ntprinter);
6322                 if (!W_ERROR_IS_OK(result)) {
6323                         goto out;
6324                 }
6325         }
6326
6327  out:
6328         if (!W_ERROR_IS_OK(result)) {
6329                 TALLOC_FREE(info);
6330                 *count = 0;
6331                 return result;
6332         }
6333
6334         *info_p = info;
6335
6336         return WERR_OK;
6337 }
6338
6339 /****************************************************************
6340  _spoolss_EnumJobs
6341 ****************************************************************/
6342
6343 WERROR _spoolss_EnumJobs(pipes_struct *p,
6344                          struct spoolss_EnumJobs *r)
6345 {
6346         WERROR result;
6347         NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
6348         int snum;
6349         print_status_struct prt_status;
6350         print_queue_struct *queue = NULL;
6351         uint32_t count;
6352
6353         /* that's an [in out] buffer */
6354
6355         if (!r->in.buffer && (r->in.offered != 0)) {
6356                 return WERR_INVALID_PARAM;
6357         }
6358
6359         DEBUG(4,("_spoolss_EnumJobs\n"));
6360
6361         *r->out.needed = 0;
6362         *r->out.count = 0;
6363         *r->out.info = NULL;
6364
6365         /* lookup the printer snum and tdb entry */
6366
6367         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6368                 return WERR_BADFID;
6369         }
6370
6371         result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
6372         if (!W_ERROR_IS_OK(result)) {
6373                 return result;
6374         }
6375
6376         count = print_queue_status(snum, &queue, &prt_status);
6377         DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6378                 count, prt_status.status, prt_status.message));
6379
6380         if (count == 0) {
6381                 SAFE_FREE(queue);
6382                 free_a_printer(&ntprinter, 2);
6383                 return WERR_OK;
6384         }
6385
6386         switch (r->in.level) {
6387         case 1:
6388                 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6389                                          ntprinter, r->out.info, r->out.count);
6390                 break;
6391         case 2:
6392                 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6393                                          ntprinter, r->out.info, r->out.count);
6394                 break;
6395         case 3:
6396                 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6397                                          ntprinter, r->out.info, r->out.count);
6398                 break;
6399         default:
6400                 result = WERR_UNKNOWN_LEVEL;
6401                 break;
6402         }
6403
6404         SAFE_FREE(queue);
6405         free_a_printer(&ntprinter, 2);
6406
6407         if (!W_ERROR_IS_OK(result)) {
6408                 return result;
6409         }
6410
6411         *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6412                                                      spoolss_EnumJobs, NULL,
6413                                                      *r->out.info, r->in.level,
6414                                                      *r->out.count);
6415         *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6416         *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6417
6418         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6419 }
6420
6421 /****************************************************************
6422  _spoolss_ScheduleJob
6423 ****************************************************************/
6424
6425 WERROR _spoolss_ScheduleJob(pipes_struct *p,
6426                             struct spoolss_ScheduleJob *r)
6427 {
6428         return WERR_OK;
6429 }
6430
6431 /****************************************************************
6432  _spoolss_SetJob
6433 ****************************************************************/
6434
6435 WERROR _spoolss_SetJob(pipes_struct *p,
6436                        struct spoolss_SetJob *r)
6437 {
6438         int snum;
6439         WERROR errcode = WERR_BADFUNC;
6440
6441         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6442                 return WERR_BADFID;
6443         }
6444
6445         if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6446                 return WERR_INVALID_PRINTER_NAME;
6447         }
6448
6449         switch (r->in.command) {
6450         case SPOOLSS_JOB_CONTROL_CANCEL:
6451         case SPOOLSS_JOB_CONTROL_DELETE:
6452                 if (print_job_delete(p->server_info, snum, r->in.job_id, &errcode)) {
6453                         errcode = WERR_OK;
6454                 }
6455                 break;
6456         case SPOOLSS_JOB_CONTROL_PAUSE:
6457                 if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) {
6458                         errcode = WERR_OK;
6459                 }
6460                 break;
6461         case SPOOLSS_JOB_CONTROL_RESTART:
6462         case SPOOLSS_JOB_CONTROL_RESUME:
6463                 if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) {
6464                         errcode = WERR_OK;
6465                 }
6466                 break;
6467         default:
6468                 return WERR_UNKNOWN_LEVEL;
6469         }
6470
6471         return errcode;
6472 }
6473
6474 /****************************************************************************
6475  Enumerates all printer drivers by level and architecture.
6476 ****************************************************************************/
6477
6478 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6479                                                        const char *servername,
6480                                                        const char *architecture,
6481                                                        uint32_t level,
6482                                                        union spoolss_DriverInfo **info_p,
6483                                                        uint32_t *count_p)
6484 {
6485         int i;
6486         int ndrivers;
6487         uint32_t version;
6488         fstring *list = NULL;
6489         struct spoolss_DriverInfo8 *driver;
6490         union spoolss_DriverInfo *info = NULL;
6491         uint32_t count = 0;
6492         WERROR result = WERR_OK;
6493
6494         *count_p = 0;
6495         *info_p = NULL;
6496
6497         for (version=0; version<DRIVER_MAX_VERSION; version++) {
6498                 list = NULL;
6499                 ndrivers = get_ntdrivers(&list, architecture, version);
6500                 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
6501                         ndrivers, architecture, version));
6502
6503                 if (ndrivers == -1) {
6504                         result = WERR_NOMEM;
6505                         goto out;
6506                 }
6507
6508                 if (ndrivers != 0) {
6509                         info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6510                                                     union spoolss_DriverInfo,
6511                                                     count + ndrivers);
6512                         if (!info) {
6513                                 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6514                                         "failed to enlarge driver info buffer!\n"));
6515                                 result = WERR_NOMEM;
6516                                 goto out;
6517                         }
6518                 }
6519
6520                 for (i=0; i<ndrivers; i++) {
6521                         DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
6522                         ZERO_STRUCT(driver);
6523                         result = get_a_printer_driver(mem_ctx, &driver, list[i],
6524                                                       architecture, version);
6525                         if (!W_ERROR_IS_OK(result)) {
6526                                 goto out;
6527                         }
6528
6529                         switch (level) {
6530                         case 1:
6531                                 result = fill_printer_driver_info1(info, &info[count+i].info1,
6532                                                                    driver, servername);
6533                                 break;
6534                         case 2:
6535                                 result = fill_printer_driver_info2(info, &info[count+i].info2,
6536                                                                    driver, servername);
6537                                 break;
6538                         case 3:
6539                                 result = fill_printer_driver_info3(info, &info[count+i].info3,
6540                                                                    driver, servername);
6541                                 break;
6542                         case 4:
6543                                 result = fill_printer_driver_info4(info, &info[count+i].info4,
6544                                                                    driver, servername);
6545                                 break;
6546                         case 5:
6547                                 result = fill_printer_driver_info5(info, &info[count+i].info5,
6548                                                                    driver, servername);
6549                                 break;
6550                         case 6:
6551                                 result = fill_printer_driver_info6(info, &info[count+i].info6,
6552                                                                    driver, servername);
6553                                 break;
6554                         case 8:
6555                                 result = fill_printer_driver_info8(info, &info[count+i].info8,
6556                                                                    driver, servername);
6557                                 break;
6558                         default:
6559                                 result = WERR_UNKNOWN_LEVEL;
6560                                 break;
6561                         }
6562
6563                         free_a_printer_driver(driver);
6564
6565                         if (!W_ERROR_IS_OK(result)) {
6566                                 goto out;
6567                         }
6568                 }
6569
6570                 count += ndrivers;
6571                 SAFE_FREE(list);
6572         }
6573
6574  out:
6575         SAFE_FREE(list);
6576
6577         if (!W_ERROR_IS_OK(result)) {
6578                 TALLOC_FREE(info);
6579                 return result;
6580         }
6581
6582         *info_p = info;
6583         *count_p = count;
6584
6585         return WERR_OK;
6586 }
6587
6588 /****************************************************************************
6589  Enumerates all printer drivers by level.
6590 ****************************************************************************/
6591
6592 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
6593                                        const char *servername,
6594                                        const char *architecture,
6595                                        uint32_t level,
6596                                        union spoolss_DriverInfo **info_p,
6597                                        uint32_t *count_p)
6598 {
6599         uint32_t a,i;
6600         WERROR result = WERR_OK;
6601
6602         if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
6603
6604                 for (a=0; archi_table[a].long_archi != NULL; a++) {
6605
6606                         union spoolss_DriverInfo *info = NULL;
6607                         uint32_t count = 0;
6608
6609                         result = enumprinterdrivers_level_by_architecture(mem_ctx,
6610                                                                           servername,
6611                                                                           archi_table[a].long_archi,
6612                                                                           level,
6613                                                                           &info,
6614                                                                           &count);
6615                         if (!W_ERROR_IS_OK(result)) {
6616                                 continue;
6617                         }
6618
6619                         for (i=0; i < count; i++) {
6620                                 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
6621                                              info[i], info_p, count_p);
6622                         }
6623                 }
6624
6625                 return result;
6626         }
6627
6628         return enumprinterdrivers_level_by_architecture(mem_ctx,
6629                                                         servername,
6630                                                         architecture,
6631                                                         level,
6632                                                         info_p,
6633                                                         count_p);
6634 }
6635
6636 /****************************************************************
6637  _spoolss_EnumPrinterDrivers
6638 ****************************************************************/
6639
6640 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
6641                                    struct spoolss_EnumPrinterDrivers *r)
6642 {
6643         const char *cservername;
6644         WERROR result;
6645
6646         /* that's an [in out] buffer */
6647
6648         if (!r->in.buffer && (r->in.offered != 0)) {
6649                 return WERR_INVALID_PARAM;
6650         }
6651
6652         DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6653
6654         *r->out.needed = 0;
6655         *r->out.count = 0;
6656         *r->out.info = NULL;
6657
6658         cservername = canon_servername(r->in.server);
6659
6660         if (!is_myname_or_ipaddr(cservername)) {
6661                 return WERR_UNKNOWN_PRINTER_DRIVER;
6662         }
6663
6664         result = enumprinterdrivers_level(p->mem_ctx, cservername,
6665                                           r->in.environment,
6666                                           r->in.level,
6667                                           r->out.info,
6668                                           r->out.count);
6669         if (!W_ERROR_IS_OK(result)) {
6670                 return result;
6671         }
6672
6673         *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6674                                                      spoolss_EnumPrinterDrivers, NULL,
6675                                                      *r->out.info, r->in.level,
6676                                                      *r->out.count);
6677         *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6678         *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6679
6680         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6681 }
6682
6683 /****************************************************************************
6684 ****************************************************************************/
6685
6686 static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
6687                                struct spoolss_FormInfo1 *r,
6688                                const nt_forms_struct *form)
6689 {
6690         r->form_name    = talloc_strdup(mem_ctx, form->name);
6691         W_ERROR_HAVE_NO_MEMORY(r->form_name);
6692
6693         r->flags        = form->flag;
6694         r->size.width   = form->width;
6695         r->size.height  = form->length;
6696         r->area.left    = form->left;
6697         r->area.top     = form->top;
6698         r->area.right   = form->right;
6699         r->area.bottom  = form->bottom;
6700
6701         return WERR_OK;
6702 }
6703
6704 /****************************************************************
6705  spoolss_enumforms_level1
6706 ****************************************************************/
6707
6708 static WERROR spoolss_enumforms_level1(TALLOC_CTX *mem_ctx,
6709                                        const nt_forms_struct *builtin_forms,
6710                                        uint32_t num_builtin_forms,
6711                                        const nt_forms_struct *user_forms,
6712                                        uint32_t num_user_forms,
6713                                        union spoolss_FormInfo **info_p,
6714                                        uint32_t *count)
6715 {
6716         union spoolss_FormInfo *info;
6717         WERROR result = WERR_OK;
6718         int i;
6719
6720         *count = num_builtin_forms + num_user_forms;
6721
6722         info = TALLOC_ARRAY(mem_ctx, union spoolss_FormInfo, *count);
6723         W_ERROR_HAVE_NO_MEMORY(info);
6724
6725         /* construct the list of form structures */
6726         for (i=0; i<num_builtin_forms; i++) {
6727                 DEBUGADD(6,("Filling builtin form number [%d]\n",i));
6728                 result = fill_form_info_1(info, &info[i].info1,
6729                                           &builtin_forms[i]);
6730                 if (!W_ERROR_IS_OK(result)) {
6731                         goto out;
6732                 }
6733         }
6734
6735         for (i=0; i<num_user_forms; i++) {
6736                 DEBUGADD(6,("Filling user form number [%d]\n",i));
6737                 result = fill_form_info_1(info, &info[i+num_builtin_forms].info1,
6738                                           &user_forms[i]);
6739                 if (!W_ERROR_IS_OK(result)) {
6740                         goto out;
6741                 }
6742         }
6743
6744  out:
6745         if (!W_ERROR_IS_OK(result)) {
6746                 TALLOC_FREE(info);
6747                 *count = 0;
6748                 return result;
6749         }
6750
6751         *info_p = info;
6752
6753         return WERR_OK;
6754 }
6755
6756 /****************************************************************
6757  _spoolss_EnumForms
6758 ****************************************************************/
6759
6760 WERROR _spoolss_EnumForms(pipes_struct *p,
6761                           struct spoolss_EnumForms *r)
6762 {
6763         WERROR result;
6764         nt_forms_struct *user_forms = NULL;
6765         nt_forms_struct *builtin_forms = NULL;
6766         uint32_t num_user_forms;
6767         uint32_t num_builtin_forms;
6768
6769         *r->out.count = 0;
6770         *r->out.needed = 0;
6771         *r->out.info = NULL;
6772
6773         /* that's an [in out] buffer */
6774
6775         if (!r->in.buffer && (r->in.offered != 0) ) {
6776                 return WERR_INVALID_PARAM;
6777         }
6778
6779         DEBUG(4,("_spoolss_EnumForms\n"));
6780         DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6781         DEBUGADD(5,("Info level [%d]\n",          r->in.level));
6782
6783         num_builtin_forms = get_builtin_ntforms(&builtin_forms);
6784         DEBUGADD(5,("Number of builtin forms [%d]\n", num_builtin_forms));
6785         num_user_forms = get_ntforms(&user_forms);
6786         DEBUGADD(5,("Number of user forms [%d]\n", num_user_forms));
6787
6788         if (num_user_forms + num_builtin_forms == 0) {
6789                 SAFE_FREE(builtin_forms);
6790                 SAFE_FREE(user_forms);
6791                 return WERR_NO_MORE_ITEMS;
6792         }
6793
6794         switch (r->in.level) {
6795         case 1:
6796                 result = spoolss_enumforms_level1(p->mem_ctx,
6797                                                   builtin_forms,
6798                                                   num_builtin_forms,
6799                                                   user_forms,
6800                                                   num_user_forms,
6801                                                   r->out.info,
6802                                                   r->out.count);
6803                 break;
6804         default:
6805                 result = WERR_UNKNOWN_LEVEL;
6806                 break;
6807         }
6808
6809         SAFE_FREE(user_forms);
6810         SAFE_FREE(builtin_forms);
6811
6812         if (!W_ERROR_IS_OK(result)) {
6813                 return result;
6814         }
6815
6816         *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6817                                                      spoolss_EnumForms, NULL,
6818                                                      *r->out.info, r->in.level,
6819                                                      *r->out.count);
6820         *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6821         *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6822
6823         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6824 }
6825
6826 /****************************************************************
6827 ****************************************************************/
6828
6829 static WERROR find_form_byname(const char *name,
6830                                nt_forms_struct *form)
6831 {
6832         nt_forms_struct *list = NULL;
6833         int num_forms = 0, i = 0;
6834
6835         if (get_a_builtin_ntform_by_string(name, form)) {
6836                 return WERR_OK;
6837         }
6838
6839         num_forms = get_ntforms(&list);
6840         DEBUGADD(5,("Number of forms [%d]\n", num_forms));
6841
6842         if (num_forms == 0) {
6843                 return WERR_BADFID;
6844         }
6845
6846         /* Check if the requested name is in the list of form structures */
6847         for (i = 0; i < num_forms; i++) {
6848
6849                 DEBUG(4,("checking form %s (want %s)\n", list[i].name, name));
6850
6851                 if (strequal(name, list[i].name)) {
6852                         DEBUGADD(6,("Found form %s number [%d]\n", name, i));
6853                         *form = list[i];
6854                         SAFE_FREE(list);
6855                         return WERR_OK;
6856                 }
6857         }
6858
6859         SAFE_FREE(list);
6860
6861         return WERR_BADFID;
6862 }
6863
6864 /****************************************************************
6865  _spoolss_GetForm
6866 ****************************************************************/
6867
6868 WERROR _spoolss_GetForm(pipes_struct *p,
6869                         struct spoolss_GetForm *r)
6870 {
6871         WERROR result;
6872         nt_forms_struct form;
6873
6874         /* that's an [in out] buffer */
6875
6876         if (!r->in.buffer && (r->in.offered != 0)) {
6877                 return WERR_INVALID_PARAM;
6878         }
6879
6880         DEBUG(4,("_spoolss_GetForm\n"));
6881         DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6882         DEBUGADD(5,("Info level [%d]\n",          r->in.level));
6883
6884         result = find_form_byname(r->in.form_name, &form);
6885         if (!W_ERROR_IS_OK(result)) {
6886                 TALLOC_FREE(r->out.info);
6887                 return result;
6888         }
6889
6890         switch (r->in.level) {
6891         case 1:
6892                 result = fill_form_info_1(p->mem_ctx,
6893                                           &r->out.info->info1,
6894                                           &form);
6895                 break;
6896
6897         default:
6898                 result = WERR_UNKNOWN_LEVEL;
6899                 break;
6900         }
6901
6902         if (!W_ERROR_IS_OK(result)) {
6903                 TALLOC_FREE(r->out.info);
6904                 return result;
6905         }
6906
6907         *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_FormInfo, NULL,
6908                                                r->out.info, r->in.level);
6909         r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
6910
6911         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6912 }
6913
6914 /****************************************************************************
6915 ****************************************************************************/
6916
6917 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
6918                           struct spoolss_PortInfo1 *r,
6919                           const char *name)
6920 {
6921         r->port_name = talloc_strdup(mem_ctx, name);
6922         W_ERROR_HAVE_NO_MEMORY(r->port_name);
6923
6924         return WERR_OK;
6925 }
6926
6927 /****************************************************************************
6928  TODO: This probably needs distinguish between TCP/IP and Local ports
6929  somehow.
6930 ****************************************************************************/
6931
6932 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
6933                           struct spoolss_PortInfo2 *r,
6934                           const char *name)
6935 {
6936         r->port_name = talloc_strdup(mem_ctx, name);
6937         W_ERROR_HAVE_NO_MEMORY(r->port_name);
6938
6939         r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
6940         W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
6941
6942         r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
6943         W_ERROR_HAVE_NO_MEMORY(r->description);
6944
6945         r->port_type = SPOOLSS_PORT_TYPE_WRITE;
6946         r->reserved = 0;
6947
6948         return WERR_OK;
6949 }
6950
6951
6952 /****************************************************************************
6953  wrapper around the enumer ports command
6954 ****************************************************************************/
6955
6956 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
6957 {
6958         char *cmd = lp_enumports_cmd();
6959         char **qlines = NULL;
6960         char *command = NULL;
6961         int numlines;
6962         int ret;
6963         int fd;
6964
6965         *count = 0;
6966         *lines = NULL;
6967
6968         /* if no hook then just fill in the default port */
6969
6970         if ( !*cmd ) {
6971                 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
6972                         return WERR_NOMEM;
6973                 }
6974                 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
6975                         TALLOC_FREE(qlines);
6976                         return WERR_NOMEM;
6977                 }
6978                 qlines[1] = NULL;
6979                 numlines = 1;
6980         }
6981         else {
6982                 /* we have a valid enumport command */
6983
6984                 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
6985                 if (!command) {
6986                         return WERR_NOMEM;
6987                 }
6988
6989                 DEBUG(10,("Running [%s]\n", command));
6990                 ret = smbrun(command, &fd);
6991                 DEBUG(10,("Returned [%d]\n", ret));
6992                 TALLOC_FREE(command);
6993                 if (ret != 0) {
6994                         if (fd != -1) {
6995                                 close(fd);
6996                         }
6997                         return WERR_ACCESS_DENIED;
6998                 }
6999
7000                 numlines = 0;
7001                 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7002                 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7003                 close(fd);
7004         }
7005
7006         *count = numlines;
7007         *lines = qlines;
7008
7009         return WERR_OK;
7010 }
7011
7012 /****************************************************************************
7013  enumports level 1.
7014 ****************************************************************************/
7015
7016 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7017                                 union spoolss_PortInfo **info_p,
7018                                 uint32_t *count)
7019 {
7020         union spoolss_PortInfo *info = NULL;
7021         int i=0;
7022         WERROR result = WERR_OK;
7023         char **qlines = NULL;
7024         int numlines = 0;
7025
7026         result = enumports_hook(talloc_tos(), &numlines, &qlines );
7027         if (!W_ERROR_IS_OK(result)) {
7028                 goto out;
7029         }
7030
7031         if (numlines) {
7032                 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7033                 if (!info) {
7034                         DEBUG(10,("Returning WERR_NOMEM\n"));
7035                         result = WERR_NOMEM;
7036                         goto out;
7037                 }
7038
7039                 for (i=0; i<numlines; i++) {
7040                         DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7041                         result = fill_port_1(info, &info[i].info1, qlines[i]);
7042                         if (!W_ERROR_IS_OK(result)) {
7043                                 goto out;
7044                         }
7045                 }
7046         }
7047         TALLOC_FREE(qlines);
7048
7049 out:
7050         if (!W_ERROR_IS_OK(result)) {
7051                 TALLOC_FREE(info);
7052                 TALLOC_FREE(qlines);
7053                 *count = 0;
7054                 *info_p = NULL;
7055                 return result;
7056         }
7057
7058         *info_p = info;
7059         *count = numlines;
7060
7061         return WERR_OK;
7062 }
7063
7064 /****************************************************************************
7065  enumports level 2.
7066 ****************************************************************************/
7067
7068 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7069                                 union spoolss_PortInfo **info_p,
7070                                 uint32_t *count)
7071 {
7072         union spoolss_PortInfo *info = NULL;
7073         int i=0;
7074         WERROR result = WERR_OK;
7075         char **qlines = NULL;
7076         int numlines = 0;
7077
7078         result = enumports_hook(talloc_tos(), &numlines, &qlines );
7079         if (!W_ERROR_IS_OK(result)) {
7080                 goto out;
7081         }
7082
7083         if (numlines) {
7084                 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7085                 if (!info) {
7086                         DEBUG(10,("Returning WERR_NOMEM\n"));
7087                         result = WERR_NOMEM;
7088                         goto out;
7089                 }
7090
7091                 for (i=0; i<numlines; i++) {
7092                         DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7093                         result = fill_port_2(info, &info[i].info2, qlines[i]);
7094                         if (!W_ERROR_IS_OK(result)) {
7095                                 goto out;
7096                         }
7097                 }
7098         }
7099         TALLOC_FREE(qlines);
7100
7101 out:
7102         if (!W_ERROR_IS_OK(result)) {
7103                 TALLOC_FREE(info);
7104                 TALLOC_FREE(qlines);
7105                 *count = 0;
7106                 *info_p = NULL;
7107                 return result;
7108         }
7109
7110         *info_p = info;
7111         *count = numlines;
7112
7113         return WERR_OK;
7114 }
7115
7116 /****************************************************************
7117  _spoolss_EnumPorts
7118 ****************************************************************/
7119
7120 WERROR _spoolss_EnumPorts(pipes_struct *p,
7121                           struct spoolss_EnumPorts *r)
7122 {
7123         WERROR result;
7124
7125         /* that's an [in out] buffer */
7126
7127         if (!r->in.buffer && (r->in.offered != 0)) {
7128                 return WERR_INVALID_PARAM;
7129         }
7130
7131         DEBUG(4,("_spoolss_EnumPorts\n"));
7132
7133         *r->out.count = 0;
7134         *r->out.needed = 0;
7135         *r->out.info = NULL;
7136
7137         switch (r->in.level) {
7138         case 1:
7139                 result = enumports_level_1(p->mem_ctx, r->out.info,
7140                                            r->out.count);
7141                 break;
7142         case 2:
7143                 result = enumports_level_2(p->mem_ctx, r->out.info,
7144                                            r->out.count);
7145                 break;
7146         default:
7147                 return WERR_UNKNOWN_LEVEL;
7148         }
7149
7150         if (!W_ERROR_IS_OK(result)) {
7151                 return result;
7152         }
7153
7154         *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7155                                                      spoolss_EnumPorts, NULL,
7156                                                      *r->out.info, r->in.level,
7157                                                      *r->out.count);
7158         *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7159         *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7160
7161         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7162 }
7163
7164 /****************************************************************************
7165 ****************************************************************************/
7166
7167 static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
7168                                            const char *server,
7169                                            struct spoolss_SetPrinterInfoCtr *info_ctr,
7170                                            struct spoolss_DeviceMode *devmode,
7171                                            struct security_descriptor *sec_desc,
7172                                            struct spoolss_UserLevelCtr *user_ctr,
7173                                            struct policy_handle *handle)
7174 {
7175         NT_PRINTER_INFO_LEVEL *printer = NULL;
7176         fstring name;
7177         int     snum;
7178         WERROR err = WERR_OK;
7179
7180         if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
7181                 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7182                 return WERR_NOMEM;
7183         }
7184
7185         /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7186         if (!convert_printer_info(info_ctr, printer)) {
7187                 free_a_printer(&printer, 2);
7188                 return WERR_NOMEM;
7189         }
7190
7191         /* samba does not have a concept of local, non-shared printers yet, so
7192          * make sure we always setup sharename - gd */
7193         if ((printer->info_2->sharename[0] == '\0') && (printer->info_2->printername != '\0')) {
7194                 DEBUG(5, ("spoolss_addprinterex_level_2: "
7195                         "no sharename has been set, setting printername %s as sharename\n",
7196                         printer->info_2->printername));
7197                 fstrcpy(printer->info_2->sharename, printer->info_2->printername);
7198         }
7199
7200         /* check to see if the printer already exists */
7201
7202         if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
7203                 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7204                         printer->info_2->sharename));
7205                 free_a_printer(&printer, 2);
7206                 return WERR_PRINTER_ALREADY_EXISTS;
7207         }
7208
7209         if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
7210                 if ((snum = print_queue_snum(printer->info_2->printername)) != -1) {
7211                         DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7212                                 printer->info_2->printername));
7213                         free_a_printer(&printer, 2);
7214                         return WERR_PRINTER_ALREADY_EXISTS;
7215                 }
7216         }
7217
7218         /* validate printer info struct */
7219         if (!info_ctr->info.info2->printername ||
7220             strlen(info_ctr->info.info2->printername) == 0) {
7221                 free_a_printer(&printer,2);
7222                 return WERR_INVALID_PRINTER_NAME;
7223         }
7224         if (!info_ctr->info.info2->portname ||
7225             strlen(info_ctr->info.info2->portname) == 0) {
7226                 free_a_printer(&printer,2);
7227                 return WERR_UNKNOWN_PORT;
7228         }
7229         if (!info_ctr->info.info2->drivername ||
7230             strlen(info_ctr->info.info2->drivername) == 0) {
7231                 free_a_printer(&printer,2);
7232                 return WERR_UNKNOWN_PRINTER_DRIVER;
7233         }
7234         if (!info_ctr->info.info2->printprocessor ||
7235             strlen(info_ctr->info.info2->printprocessor) == 0) {
7236                 free_a_printer(&printer,2);
7237                 return WERR_UNKNOWN_PRINTPROCESSOR;
7238         }
7239
7240         /* FIXME!!!  smbd should check to see if the driver is installed before
7241            trying to add a printer like this  --jerry */
7242
7243         if (*lp_addprinter_cmd() ) {
7244                 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7245                                        printer) ) {
7246                         free_a_printer(&printer,2);
7247                         return WERR_ACCESS_DENIED;
7248                 }
7249         } else {
7250                 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7251                         "smb.conf parameter \"addprinter command\" is defined. This"
7252                         "parameter must exist for this call to succeed\n",
7253                         printer->info_2->sharename ));
7254         }
7255
7256         /* use our primary netbios name since get_a_printer() will convert
7257            it to what the client expects on a case by case basis */
7258
7259         slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
7260              printer->info_2->sharename);
7261
7262
7263         if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
7264                 free_a_printer(&printer,2);
7265                 return WERR_ACCESS_DENIED;
7266         }
7267
7268         /* you must be a printer admin to add a new printer */
7269         if (!print_access_check(p->server_info, snum, PRINTER_ACCESS_ADMINISTER)) {
7270                 free_a_printer(&printer,2);
7271                 return WERR_ACCESS_DENIED;
7272         }
7273
7274         /*
7275          * Do sanity check on the requested changes for Samba.
7276          */
7277
7278         if (!check_printer_ok(printer->info_2, snum)) {
7279                 free_a_printer(&printer,2);
7280                 return WERR_INVALID_PARAM;
7281         }
7282
7283         /*
7284          * When a printer is created, the drivername bound to the printer is used
7285          * to lookup previously saved driver initialization info, which is then
7286          * bound to the new printer, simulating what happens in the Windows arch.
7287          */
7288
7289         if (!devmode)
7290         {
7291                 set_driver_init(printer, 2);
7292         }
7293         else
7294         {
7295                 /* A valid devmode was included, convert and link it
7296                 */
7297                 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7298
7299                 if (!convert_devicemode(printer->info_2->printername, devmode,
7300                                         &printer->info_2->devmode)) {
7301                         return  WERR_NOMEM;
7302                 }
7303         }
7304
7305         /* write the ASCII on disk */
7306         err = mod_a_printer(printer, 2);
7307         if (!W_ERROR_IS_OK(err)) {
7308                 free_a_printer(&printer,2);
7309                 return err;
7310         }
7311
7312         if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
7313                 /* Handle open failed - remove addition. */
7314                 del_a_printer(printer->info_2->sharename);
7315                 free_a_printer(&printer,2);
7316                 ZERO_STRUCTP(handle);
7317                 return WERR_ACCESS_DENIED;
7318         }
7319
7320         update_c_setprinter(false);
7321         free_a_printer(&printer,2);
7322
7323         return WERR_OK;
7324 }
7325
7326 /****************************************************************
7327  _spoolss_AddPrinterEx
7328 ****************************************************************/
7329
7330 WERROR _spoolss_AddPrinterEx(pipes_struct *p,
7331                              struct spoolss_AddPrinterEx *r)
7332 {
7333         switch (r->in.info_ctr->level) {
7334         case 1:
7335                 /* we don't handle yet */
7336                 /* but I know what to do ... */
7337                 return WERR_UNKNOWN_LEVEL;
7338         case 2:
7339                 return spoolss_addprinterex_level_2(p, r->in.server,
7340                                                     r->in.info_ctr,
7341                                                     r->in.devmode_ctr->devmode,
7342                                                     r->in.secdesc_ctr->sd,
7343                                                     r->in.userlevel_ctr,
7344                                                     r->out.handle);
7345         default:
7346                 return WERR_UNKNOWN_LEVEL;
7347         }
7348 }
7349
7350 /****************************************************************
7351  _spoolss_AddPrinter
7352 ****************************************************************/
7353
7354 WERROR _spoolss_AddPrinter(pipes_struct *p,
7355                            struct spoolss_AddPrinter *r)
7356 {
7357         struct spoolss_AddPrinterEx a;
7358         struct spoolss_UserLevelCtr userlevel_ctr;
7359
7360         ZERO_STRUCT(userlevel_ctr);
7361
7362         userlevel_ctr.level = 1;
7363
7364         a.in.server             = r->in.server;
7365         a.in.info_ctr           = r->in.info_ctr;
7366         a.in.devmode_ctr        = r->in.devmode_ctr;
7367         a.in.secdesc_ctr        = r->in.secdesc_ctr;
7368         a.in.userlevel_ctr      = &userlevel_ctr;
7369         a.out.handle            = r->out.handle;
7370
7371         return _spoolss_AddPrinterEx(p, &a);
7372 }
7373
7374 /****************************************************************
7375  _spoolss_AddPrinterDriver
7376 ****************************************************************/
7377
7378 WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
7379                                  struct spoolss_AddPrinterDriver *r)
7380 {
7381         WERROR err = WERR_OK;
7382         char *driver_name = NULL;
7383         uint32_t version;
7384         const char *fn;
7385
7386         switch (p->hdr_req.opnum) {
7387                 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7388                         fn = "_spoolss_AddPrinterDriver";
7389                         break;
7390                 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7391                         fn = "_spoolss_AddPrinterDriverEx";
7392                         break;
7393                 default:
7394                         return WERR_INVALID_PARAM;
7395         }
7396
7397
7398         /* FIXME */
7399         if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7400                 /* Clever hack from Martin Zielinski <mz@seh.de>
7401                  * to allow downgrade from level 8 (Vista).
7402                  */
7403                 DEBUG(0,("%s: level %d not yet implemented\n", fn,
7404                         r->in.info_ctr->level));
7405                 return WERR_UNKNOWN_LEVEL;
7406         }
7407
7408         DEBUG(5,("Cleaning driver's information\n"));
7409         err = clean_up_driver_struct(p, r->in.info_ctr);
7410         if (!W_ERROR_IS_OK(err))
7411                 goto done;
7412
7413         DEBUG(5,("Moving driver to final destination\n"));
7414         if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7415                                                               &err)) ) {
7416                 goto done;
7417         }
7418
7419         if (add_a_printer_driver(p->mem_ctx, r->in.info_ctr, &driver_name, &version)!=0) {
7420                 err = WERR_ACCESS_DENIED;
7421                 goto done;
7422         }
7423
7424         /*
7425          * I think this is where he DrvUpgradePrinter() hook would be
7426          * be called in a driver's interface DLL on a Windows NT 4.0/2k
7427          * server.  Right now, we just need to send ourselves a message
7428          * to update each printer bound to this driver.   --jerry
7429          */
7430
7431         if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7432                 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7433                         fn, driver_name));
7434         }
7435
7436         /*
7437          * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7438          * decide if the driver init data should be deleted. The rules are:
7439          *  1) never delete init data if it is a 9x driver, they don't use it anyway
7440          *  2) delete init data only if there is no 2k/Xp driver
7441          *  3) always delete init data
7442          * The generalized rule is always use init data from the highest order driver.
7443          * It is necessary to follow the driver install by an initialization step to
7444          * finish off this process.
7445         */
7446
7447         switch (version) {
7448                 /*
7449                  * 9x printer driver - never delete init data
7450                 */
7451                 case 0:
7452                         DEBUG(10,("%s: init data not deleted for 9x driver [%s]\n",
7453                                 fn, driver_name));
7454                         break;
7455
7456                 /*
7457                  * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7458                  * there is no 2k/Xp driver init data for this driver name.
7459                 */
7460                 case 2:
7461                 {
7462                         struct spoolss_DriverInfo8 *driver1;
7463
7464                         if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &driver1, driver_name, "Windows NT x86", 3))) {
7465                                 /*
7466                                  * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7467                                 */
7468                                 if (!del_driver_init(driver_name))
7469                                         DEBUG(6,("%s: del_driver_init(%s) Nt failed!\n",
7470                                                 fn, driver_name));
7471                         } else {
7472                                 /*
7473                                  * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7474                                 */
7475                                 free_a_printer_driver(driver1);
7476                                 DEBUG(10,("%s: init data not deleted for Nt driver [%s]\n",
7477                                         fn, driver_name));
7478                         }
7479                 }
7480                 break;
7481
7482                 /*
7483                  * 2k or Xp printer driver - always delete init data
7484                 */
7485                 case 3:
7486                         if (!del_driver_init(driver_name))
7487                                 DEBUG(6,("%s: del_driver_init(%s) 2k/Xp failed!\n",
7488                                         fn, driver_name));
7489                         break;
7490
7491                 default:
7492                         DEBUG(0,("%s: invalid level=%d\n", fn,
7493                                 r->in.info_ctr->level));
7494                         break;
7495         }
7496
7497
7498 done:
7499         return err;
7500 }
7501
7502 /****************************************************************
7503  _spoolss_AddPrinterDriverEx
7504 ****************************************************************/
7505
7506 WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
7507                                    struct spoolss_AddPrinterDriverEx *r)
7508 {
7509         struct spoolss_AddPrinterDriver a;
7510
7511         /*
7512          * we only support the semantics of AddPrinterDriver()
7513          * i.e. only copy files that are newer than existing ones
7514          */
7515
7516         if (r->in.flags != APD_COPY_NEW_FILES) {
7517                 return WERR_ACCESS_DENIED;
7518         }
7519
7520         a.in.servername         = r->in.servername;
7521         a.in.info_ctr           = r->in.info_ctr;
7522
7523         return _spoolss_AddPrinterDriver(p, &a);
7524 }
7525
7526 /****************************************************************************
7527 ****************************************************************************/
7528
7529 struct _spoolss_paths {
7530         int type;
7531         const char *share;
7532         const char *dir;
7533 };
7534
7535 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7536
7537 static const struct _spoolss_paths spoolss_paths[]= {
7538         { SPOOLSS_DRIVER_PATH,          "print$",       "DRIVERS" },
7539         { SPOOLSS_PRTPROCS_PATH,        "prnproc$",     "PRTPROCS" }
7540 };
7541
7542 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7543                                           const char *servername,
7544                                           const char *environment,
7545                                           int component,
7546                                           char **path)
7547 {
7548         const char *pservername = NULL;
7549         const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7550         const char *short_archi;
7551
7552         *path = NULL;
7553
7554         /* environment may be empty */
7555         if (environment && strlen(environment)) {
7556                 long_archi = environment;
7557         }
7558
7559         /* servername may be empty */
7560         if (servername && strlen(servername)) {
7561                 pservername = canon_servername(servername);
7562
7563                 if (!is_myname_or_ipaddr(pservername)) {
7564                         return WERR_INVALID_PARAM;
7565                 }
7566         }
7567
7568         if (!(short_archi = get_short_archi(long_archi))) {
7569                 return WERR_INVALID_ENVIRONMENT;
7570         }
7571
7572         switch (component) {
7573         case SPOOLSS_PRTPROCS_PATH:
7574         case SPOOLSS_DRIVER_PATH:
7575                 if (pservername) {
7576                         *path = talloc_asprintf(mem_ctx,
7577                                         "\\\\%s\\%s\\%s",
7578                                         pservername,
7579                                         spoolss_paths[component].share,
7580                                         short_archi);
7581                 } else {
7582                         *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7583                                         SPOOLSS_DEFAULT_SERVER_PATH,
7584                                         spoolss_paths[component].dir,
7585                                         short_archi);
7586                 }
7587                 break;
7588         default:
7589                 return WERR_INVALID_PARAM;
7590         }
7591
7592         if (!*path) {
7593                 return WERR_NOMEM;
7594         }
7595
7596         return WERR_OK;
7597 }
7598
7599 /****************************************************************************
7600 ****************************************************************************/
7601
7602 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7603                                           const char *servername,
7604                                           const char *environment,
7605                                           struct spoolss_DriverDirectoryInfo1 *r)
7606 {
7607         WERROR werr;
7608         char *path = NULL;
7609
7610         werr = compose_spoolss_server_path(mem_ctx,
7611                                            servername,
7612                                            environment,
7613                                            SPOOLSS_DRIVER_PATH,
7614                                            &path);
7615         if (!W_ERROR_IS_OK(werr)) {
7616                 return werr;
7617         }
7618
7619         DEBUG(4,("printer driver directory: [%s]\n", path));
7620
7621         r->directory_name = path;
7622
7623         return WERR_OK;
7624 }
7625
7626 /****************************************************************
7627  _spoolss_GetPrinterDriverDirectory
7628 ****************************************************************/
7629
7630 WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
7631                                           struct spoolss_GetPrinterDriverDirectory *r)
7632 {
7633         WERROR werror;
7634
7635         /* that's an [in out] buffer */
7636
7637         if (!r->in.buffer && (r->in.offered != 0)) {
7638                 return WERR_INVALID_PARAM;
7639         }
7640
7641         DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7642                 r->in.level));
7643
7644         *r->out.needed = 0;
7645
7646         /* r->in.level is ignored */
7647
7648         werror = getprinterdriverdir_level_1(p->mem_ctx,
7649                                              r->in.server,
7650                                              r->in.environment,
7651                                              &r->out.info->info1);
7652         if (!W_ERROR_IS_OK(werror)) {
7653                 TALLOC_FREE(r->out.info);
7654                 return werror;
7655         }
7656
7657         *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo, NULL,
7658                                                r->out.info, r->in.level);
7659         r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7660
7661         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7662 }
7663
7664 /****************************************************************
7665  _spoolss_EnumPrinterData
7666 ****************************************************************/
7667
7668 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
7669                                 struct spoolss_EnumPrinterData *r)
7670 {
7671         NT_PRINTER_INFO_LEVEL *printer = NULL;
7672         Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
7673         int             snum;
7674         WERROR          result;
7675         struct regval_blob      *val = NULL;
7676         NT_PRINTER_DATA *p_data;
7677         int             i, key_index, num_values;
7678         int             name_length;
7679
7680         *r->out.value_needed    = 0;
7681         *r->out.type            = REG_NONE;
7682         *r->out.data_needed     = 0;
7683
7684         DEBUG(5,("_spoolss_EnumPrinterData\n"));
7685
7686         if (!Printer) {
7687                 DEBUG(2,("_spoolss_EnumPrinterData: Invalid handle (%s:%u:%u).\n",
7688                         OUR_HANDLE(r->in.handle)));
7689                 return WERR_BADFID;
7690         }
7691
7692         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7693                 return WERR_BADFID;
7694         }
7695
7696         result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
7697         if (!W_ERROR_IS_OK(result)) {
7698                 return result;
7699         }
7700
7701         p_data = printer->info_2->data;
7702         key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
7703
7704         result = WERR_OK;
7705
7706         /*
7707          * The NT machine wants to know the biggest size of value and data
7708          *
7709          * cf: MSDN EnumPrinterData remark section
7710          */
7711
7712         if (!r->in.value_offered && !r->in.data_offered && (key_index != -1)) {
7713
7714                 uint32_t biggest_valuesize = 0;
7715                 uint32_t biggest_datasize = 0;
7716
7717                 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7718
7719                 num_values = regval_ctr_numvals( p_data->keys[key_index].values );
7720
7721                 for ( i=0; i<num_values; i++ )
7722                 {
7723                         val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
7724
7725                         name_length = strlen(val->valuename);
7726                         if ( strlen(val->valuename) > biggest_valuesize )
7727                                 biggest_valuesize = name_length;
7728
7729                         if ( val->size > biggest_datasize )
7730                                 biggest_datasize = val->size;
7731
7732                         DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
7733                                 biggest_datasize));
7734                 }
7735
7736                 /* the value is an UNICODE string but real_value_size is the length
7737                    in bytes including the trailing 0 */
7738
7739                 *r->out.value_needed = 2 * (1 + biggest_valuesize);
7740                 *r->out.data_needed  = biggest_datasize;
7741
7742                 DEBUG(6,("final values: [%d], [%d]\n",
7743                         *r->out.value_needed, *r->out.data_needed));
7744
7745                 goto done;
7746         }
7747
7748         /*
7749          * the value len is wrong in NT sp3
7750          * that's the number of bytes not the number of unicode chars
7751          */
7752
7753         if (key_index != -1) {
7754                 val = regval_ctr_specific_value(p_data->keys[key_index].values,
7755                                                 r->in.enum_index);
7756         }
7757
7758         if (!val) {
7759
7760                 /* out_value should default to "" or else NT4 has
7761                    problems unmarshalling the response */
7762
7763                 if (r->in.value_offered) {
7764                         *r->out.value_needed = 1;
7765                         r->out.value_name = talloc_strdup(r, "");
7766                         if (!r->out.value_name) {
7767                                 result = WERR_NOMEM;
7768                                 goto done;
7769                         }
7770                 } else {
7771                         r->out.value_name = NULL;
7772                         *r->out.value_needed = 0;
7773                 }
7774
7775                 /* the data is counted in bytes */
7776
7777                 *r->out.data_needed = r->in.data_offered;
7778
7779                 result = WERR_NO_MORE_ITEMS;
7780         } else {
7781                 /*
7782                  * the value is:
7783                  * - counted in bytes in the request
7784                  * - counted in UNICODE chars in the max reply
7785                  * - counted in bytes in the real size
7786                  *
7787                  * take a pause *before* coding not *during* coding
7788                  */
7789
7790                 /* name */
7791                 if (r->in.value_offered) {
7792                         r->out.value_name = talloc_strdup(r, regval_name(val));
7793                         if (!r->out.value_name) {
7794                                 result = WERR_NOMEM;
7795                                 goto done;
7796                         }
7797                         *r->out.value_needed = strlen_m(regval_name(val));
7798                 } else {
7799                         r->out.value_name = NULL;
7800                         *r->out.value_needed = 0;
7801                 }
7802
7803                 /* type */
7804
7805                 *r->out.type = regval_type(val);
7806
7807                 /* data - counted in bytes */
7808
7809                 /*
7810                  * See the section "Dynamically Typed Query Parameters"
7811                  * in MS-RPRN.
7812                  */
7813
7814                 if (r->out.data && regval_data_p(val) &&
7815                                 regval_size(val) && r->in.data_offered) {
7816                         memcpy(r->out.data, regval_data_p(val),
7817                                 MIN(regval_size(val),r->in.data_offered));
7818                 }
7819
7820                 *r->out.data_needed = regval_size(val);
7821         }
7822
7823 done:
7824         free_a_printer(&printer, 2);
7825         return result;
7826 }
7827
7828 /****************************************************************
7829  _spoolss_SetPrinterData
7830 ****************************************************************/
7831
7832 WERROR _spoolss_SetPrinterData(pipes_struct *p,
7833                                struct spoolss_SetPrinterData *r)
7834 {
7835         struct spoolss_SetPrinterDataEx r2;
7836
7837         r2.in.handle            = r->in.handle;
7838         r2.in.key_name          = "PrinterDriverData";
7839         r2.in.value_name        = r->in.value_name;
7840         r2.in.type              = r->in.type;
7841         r2.in.data              = r->in.data;
7842         r2.in._offered          = r->in._offered;
7843
7844         return _spoolss_SetPrinterDataEx(p, &r2);
7845 }
7846
7847 /****************************************************************
7848  _spoolss_ResetPrinter
7849 ****************************************************************/
7850
7851 WERROR _spoolss_ResetPrinter(pipes_struct *p,
7852                              struct spoolss_ResetPrinter *r)
7853 {
7854         Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
7855         int             snum;
7856
7857         DEBUG(5,("_spoolss_ResetPrinter\n"));
7858
7859         /*
7860          * All we do is to check to see if the handle and queue is valid.
7861          * This call really doesn't mean anything to us because we only
7862          * support RAW printing.   --jerry
7863          */
7864
7865         if (!Printer) {
7866                 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7867                         OUR_HANDLE(r->in.handle)));
7868                 return WERR_BADFID;
7869         }
7870
7871         if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7872                 return WERR_BADFID;
7873
7874
7875         /* blindly return success */
7876         return WERR_OK;
7877 }
7878
7879 /****************************************************************
7880  _spoolss_DeletePrinterData
7881 ****************************************************************/
7882
7883 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
7884                                   struct spoolss_DeletePrinterData *r)
7885 {
7886         struct spoolss_DeletePrinterDataEx r2;
7887
7888         r2.in.handle            = r->in.handle;
7889         r2.in.key_name          = "PrinterDriverData";
7890         r2.in.value_name        = r->in.value_name;
7891
7892         return _spoolss_DeletePrinterDataEx(p, &r2);
7893 }
7894
7895 /****************************************************************
7896  _spoolss_AddForm
7897 ****************************************************************/
7898
7899 WERROR _spoolss_AddForm(pipes_struct *p,
7900                         struct spoolss_AddForm *r)
7901 {
7902         struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7903         nt_forms_struct tmpForm;
7904         int snum = -1;
7905         WERROR status = WERR_OK;
7906         NT_PRINTER_INFO_LEVEL *printer = NULL;
7907         SE_PRIV se_printop = SE_PRINT_OPERATOR;
7908
7909         int count=0;
7910         nt_forms_struct *list=NULL;
7911         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7912
7913         DEBUG(5,("_spoolss_AddForm\n"));
7914
7915         if (!Printer) {
7916                 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
7917                         OUR_HANDLE(r->in.handle)));
7918                 return WERR_BADFID;
7919         }
7920
7921
7922         /* forms can be added on printer of on the print server handle */
7923
7924         if ( Printer->printer_type == SPLHND_PRINTER )
7925         {
7926                 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7927                         return WERR_BADFID;
7928
7929                 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
7930                 if (!W_ERROR_IS_OK(status))
7931                         goto done;
7932         }
7933
7934         /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7935            and not a printer admin, then fail */
7936
7937         if ((p->server_info->utok.uid != sec_initial_uid()) &&
7938              !user_has_privileges(p->server_info->ptok, &se_printop) &&
7939              !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7940                                           NULL, NULL,
7941                                           p->server_info->ptok,
7942                                           lp_printer_admin(snum))) {
7943                 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
7944                 return WERR_ACCESS_DENIED;
7945         }
7946
7947         /* can't add if builtin */
7948
7949         if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
7950                 status = WERR_FILE_EXISTS;
7951                 goto done;
7952         }
7953
7954         count = get_ntforms(&list);
7955
7956         if(!add_a_form(&list, form, &count)) {
7957                 status =  WERR_NOMEM;
7958                 goto done;
7959         }
7960
7961         become_root();
7962         write_ntforms(&list, count);
7963         unbecome_root();
7964
7965         /*
7966          * ChangeID must always be set if this is a printer
7967          */
7968
7969         if ( Printer->printer_type == SPLHND_PRINTER )
7970                 status = mod_a_printer(printer, 2);
7971
7972 done:
7973         if ( printer )
7974                 free_a_printer(&printer, 2);
7975         SAFE_FREE(list);
7976
7977         return status;
7978 }
7979
7980 /****************************************************************
7981  _spoolss_DeleteForm
7982 ****************************************************************/
7983
7984 WERROR _spoolss_DeleteForm(pipes_struct *p,
7985                            struct spoolss_DeleteForm *r)
7986 {
7987         const char *form_name = r->in.form_name;
7988         nt_forms_struct tmpForm;
7989         int count=0;
7990         nt_forms_struct *list=NULL;
7991         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7992         int snum = -1;
7993         WERROR status = WERR_OK;
7994         NT_PRINTER_INFO_LEVEL *printer = NULL;
7995         SE_PRIV se_printop = SE_PRINT_OPERATOR;
7996         bool ret = false;
7997
7998         DEBUG(5,("_spoolss_DeleteForm\n"));
7999
8000         if (!Printer) {
8001                 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8002                         OUR_HANDLE(r->in.handle)));
8003                 return WERR_BADFID;
8004         }
8005
8006         /* forms can be deleted on printer of on the print server handle */
8007
8008         if ( Printer->printer_type == SPLHND_PRINTER )
8009         {
8010                 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
8011                         return WERR_BADFID;
8012
8013                 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8014                 if (!W_ERROR_IS_OK(status))
8015                         goto done;
8016         }
8017
8018         if ((p->server_info->utok.uid != sec_initial_uid()) &&
8019              !user_has_privileges(p->server_info->ptok, &se_printop) &&
8020              !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8021                                           NULL, NULL,
8022                                           p->server_info->ptok,
8023                                           lp_printer_admin(snum))) {
8024                 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
8025                 return WERR_ACCESS_DENIED;
8026         }
8027
8028
8029         /* can't delete if builtin */
8030
8031         if (get_a_builtin_ntform_by_string(form_name,&tmpForm)) {
8032                 status = WERR_INVALID_PARAM;
8033                 goto done;
8034         }
8035
8036         count = get_ntforms(&list);
8037
8038         become_root();
8039         ret = delete_a_form(&list, form_name, &count, &status);
8040         unbecome_root();
8041         if (ret == false) {
8042                 goto done;
8043         }
8044
8045         /*
8046          * ChangeID must always be set if this is a printer
8047          */
8048
8049         if ( Printer->printer_type == SPLHND_PRINTER )
8050                 status = mod_a_printer(printer, 2);
8051
8052 done:
8053         if ( printer )
8054                 free_a_printer(&printer, 2);
8055         SAFE_FREE(list);
8056
8057         return status;
8058 }
8059
8060 /****************************************************************
8061  _spoolss_SetForm
8062 ****************************************************************/
8063
8064 WERROR _spoolss_SetForm(pipes_struct *p,
8065                         struct spoolss_SetForm *r)
8066 {
8067         struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8068         nt_forms_struct tmpForm;
8069         int snum = -1;
8070         WERROR status = WERR_OK;
8071         NT_PRINTER_INFO_LEVEL *printer = NULL;
8072         SE_PRIV se_printop = SE_PRINT_OPERATOR;
8073
8074         int count=0;
8075         nt_forms_struct *list=NULL;
8076         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8077
8078         DEBUG(5,("_spoolss_SetForm\n"));
8079
8080         if (!Printer) {
8081                 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8082                         OUR_HANDLE(r->in.handle)));
8083                 return WERR_BADFID;
8084         }
8085
8086         /* forms can be modified on printer of on the print server handle */
8087
8088         if ( Printer->printer_type == SPLHND_PRINTER )
8089         {
8090                 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
8091                         return WERR_BADFID;
8092
8093                 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8094                 if (!W_ERROR_IS_OK(status))
8095                         goto done;
8096         }
8097
8098         /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
8099            and not a printer admin, then fail */
8100
8101         if ((p->server_info->utok.uid != sec_initial_uid()) &&
8102              !user_has_privileges(p->server_info->ptok, &se_printop) &&
8103              !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8104                                           NULL, NULL,
8105                                           p->server_info->ptok,
8106                                           lp_printer_admin(snum))) {
8107                 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
8108                 return WERR_ACCESS_DENIED;
8109         }
8110
8111         /* can't set if builtin */
8112         if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8113                 status = WERR_INVALID_PARAM;
8114                 goto done;
8115         }
8116
8117         count = get_ntforms(&list);
8118         update_a_form(&list, form, count);
8119         become_root();
8120         write_ntforms(&list, count);
8121         unbecome_root();
8122
8123         /*
8124          * ChangeID must always be set if this is a printer
8125          */
8126
8127         if ( Printer->printer_type == SPLHND_PRINTER )
8128                 status = mod_a_printer(printer, 2);
8129
8130
8131 done:
8132         if ( printer )
8133                 free_a_printer(&printer, 2);
8134         SAFE_FREE(list);
8135
8136         return status;
8137 }
8138
8139 /****************************************************************************
8140  fill_print_processor1
8141 ****************************************************************************/
8142
8143 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8144                                     struct spoolss_PrintProcessorInfo1 *r,
8145                                     const char *print_processor_name)
8146 {
8147         r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8148         W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8149
8150         return WERR_OK;
8151 }
8152
8153 /****************************************************************************
8154  enumprintprocessors level 1.
8155 ****************************************************************************/
8156
8157 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8158                                           union spoolss_PrintProcessorInfo **info_p,
8159                                           uint32_t *count)
8160 {
8161         union spoolss_PrintProcessorInfo *info;
8162         WERROR result;
8163
8164         info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8165         W_ERROR_HAVE_NO_MEMORY(info);
8166
8167         *count = 1;
8168
8169         result = fill_print_processor1(info, &info[0].info1, "winprint");
8170         if (!W_ERROR_IS_OK(result)) {
8171                 goto out;
8172         }
8173
8174  out:
8175         if (!W_ERROR_IS_OK(result)) {
8176                 TALLOC_FREE(info);
8177                 *count = 0;
8178                 return result;
8179         }
8180
8181         *info_p = info;
8182
8183         return WERR_OK;
8184 }
8185
8186 /****************************************************************
8187  _spoolss_EnumPrintProcessors
8188 ****************************************************************/
8189
8190 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
8191                                     struct spoolss_EnumPrintProcessors *r)
8192 {
8193         WERROR result;
8194
8195         /* that's an [in out] buffer */
8196
8197         if (!r->in.buffer && (r->in.offered != 0)) {
8198                 return WERR_INVALID_PARAM;
8199         }
8200
8201         DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8202
8203         /*
8204          * Enumerate the print processors ...
8205          *
8206          * Just reply with "winprint", to keep NT happy
8207          * and I can use my nice printer checker.
8208          */
8209
8210         *r->out.count = 0;
8211         *r->out.needed = 0;
8212         *r->out.info = NULL;
8213
8214         switch (r->in.level) {
8215         case 1:
8216                 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8217                                                      r->out.count);
8218                 break;
8219         default:
8220                 return WERR_UNKNOWN_LEVEL;
8221         }
8222
8223         if (!W_ERROR_IS_OK(result)) {
8224                 return result;
8225         }
8226
8227         *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8228                                                      spoolss_EnumPrintProcessors, NULL,
8229                                                      *r->out.info, r->in.level,
8230                                                      *r->out.count);
8231         *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8232         *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8233
8234         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8235 }
8236
8237 /****************************************************************************
8238  fill_printprocdatatype1
8239 ****************************************************************************/
8240
8241 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8242                                       struct spoolss_PrintProcDataTypesInfo1 *r,
8243                                       const char *name_array)
8244 {
8245         r->name_array = talloc_strdup(mem_ctx, name_array);
8246         W_ERROR_HAVE_NO_MEMORY(r->name_array);
8247
8248         return WERR_OK;
8249 }
8250
8251 /****************************************************************************
8252  enumprintprocdatatypes level 1.
8253 ****************************************************************************/
8254
8255 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8256                                              union spoolss_PrintProcDataTypesInfo **info_p,
8257                                              uint32_t *count)
8258 {
8259         WERROR result;
8260         union spoolss_PrintProcDataTypesInfo *info;
8261
8262         info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8263         W_ERROR_HAVE_NO_MEMORY(info);
8264
8265         *count = 1;
8266
8267         result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8268         if (!W_ERROR_IS_OK(result)) {
8269                 goto out;
8270         }
8271
8272  out:
8273         if (!W_ERROR_IS_OK(result)) {
8274                 TALLOC_FREE(info);
8275                 *count = 0;
8276                 return result;
8277         }
8278
8279         *info_p = info;
8280
8281         return WERR_OK;
8282 }
8283
8284 /****************************************************************
8285  _spoolss_EnumPrintProcDataTypes
8286 ****************************************************************/
8287
8288 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
8289                                        struct spoolss_EnumPrintProcDataTypes *r)
8290 {
8291         WERROR result;
8292
8293         /* that's an [in out] buffer */
8294
8295         if (!r->in.buffer && (r->in.offered != 0)) {
8296                 return WERR_INVALID_PARAM;
8297         }
8298
8299         DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8300
8301         *r->out.count = 0;
8302         *r->out.needed = 0;
8303         *r->out.info = NULL;
8304
8305         switch (r->in.level) {
8306         case 1:
8307                 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8308                                                         r->out.count);
8309                 break;
8310         default:
8311                 return WERR_UNKNOWN_LEVEL;
8312         }
8313
8314         *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8315                                                      spoolss_EnumPrintProcDataTypes, NULL,
8316                                                      *r->out.info, r->in.level,
8317                                                      *r->out.count);
8318         *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8319         *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8320
8321         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8322 }
8323
8324 /****************************************************************************
8325  fill_monitor_1
8326 ****************************************************************************/
8327
8328 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8329                              struct spoolss_MonitorInfo1 *r,
8330                              const char *monitor_name)
8331 {
8332         r->monitor_name                 = talloc_strdup(mem_ctx, monitor_name);
8333         W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8334
8335         return WERR_OK;
8336 }
8337
8338 /****************************************************************************
8339  fill_monitor_2
8340 ****************************************************************************/
8341
8342 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8343                              struct spoolss_MonitorInfo2 *r,
8344                              const char *monitor_name,
8345                              const char *environment,
8346                              const char *dll_name)
8347 {
8348         r->monitor_name                 = talloc_strdup(mem_ctx, monitor_name);
8349         W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8350         r->environment                  = talloc_strdup(mem_ctx, environment);
8351         W_ERROR_HAVE_NO_MEMORY(r->environment);
8352         r->dll_name                     = talloc_strdup(mem_ctx, dll_name);
8353         W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8354
8355         return WERR_OK;
8356 }
8357
8358 /****************************************************************************
8359  enumprintmonitors level 1.
8360 ****************************************************************************/
8361
8362 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8363                                         union spoolss_MonitorInfo **info_p,
8364                                         uint32_t *count)
8365 {
8366         union spoolss_MonitorInfo *info;
8367         WERROR result = WERR_OK;
8368
8369         info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8370         W_ERROR_HAVE_NO_MEMORY(info);
8371
8372         *count = 2;
8373
8374         result = fill_monitor_1(info, &info[0].info1,
8375                                 SPL_LOCAL_PORT);
8376         if (!W_ERROR_IS_OK(result)) {
8377                 goto out;
8378         }
8379
8380         result = fill_monitor_1(info, &info[1].info1,
8381                                 SPL_TCPIP_PORT);
8382         if (!W_ERROR_IS_OK(result)) {
8383                 goto out;
8384         }
8385
8386 out:
8387         if (!W_ERROR_IS_OK(result)) {
8388                 TALLOC_FREE(info);
8389                 *count = 0;
8390                 return result;
8391         }
8392
8393         *info_p = info;
8394
8395         return WERR_OK;
8396 }
8397
8398 /****************************************************************************
8399  enumprintmonitors level 2.
8400 ****************************************************************************/
8401
8402 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8403                                         union spoolss_MonitorInfo **info_p,
8404                                         uint32_t *count)
8405 {
8406         union spoolss_MonitorInfo *info;
8407         WERROR result = WERR_OK;
8408
8409         info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8410         W_ERROR_HAVE_NO_MEMORY(info);
8411
8412         *count = 2;
8413
8414         result = fill_monitor_2(info, &info[0].info2,
8415                                 SPL_LOCAL_PORT,
8416                                 "Windows NT X86", /* FIXME */
8417                                 "localmon.dll");
8418         if (!W_ERROR_IS_OK(result)) {
8419                 goto out;
8420         }
8421
8422         result = fill_monitor_2(info, &info[1].info2,
8423                                 SPL_TCPIP_PORT,
8424                                 "Windows NT X86", /* FIXME */
8425                                 "tcpmon.dll");
8426         if (!W_ERROR_IS_OK(result)) {
8427                 goto out;
8428         }
8429
8430 out:
8431         if (!W_ERROR_IS_OK(result)) {
8432                 TALLOC_FREE(info);
8433                 *count = 0;
8434                 return result;
8435         }
8436
8437         *info_p = info;
8438
8439         return WERR_OK;
8440 }
8441
8442 /****************************************************************
8443  _spoolss_EnumMonitors
8444 ****************************************************************/
8445
8446 WERROR _spoolss_EnumMonitors(pipes_struct *p,
8447                              struct spoolss_EnumMonitors *r)
8448 {
8449         WERROR result;
8450
8451         /* that's an [in out] buffer */
8452
8453         if (!r->in.buffer && (r->in.offered != 0)) {
8454                 return WERR_INVALID_PARAM;
8455         }
8456
8457         DEBUG(5,("_spoolss_EnumMonitors\n"));
8458
8459         /*
8460          * Enumerate the print monitors ...
8461          *
8462          * Just reply with "Local Port", to keep NT happy
8463          * and I can use my nice printer checker.
8464          */
8465
8466         *r->out.count = 0;
8467         *r->out.needed = 0;
8468         *r->out.info = NULL;
8469
8470         switch (r->in.level) {
8471         case 1:
8472                 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8473                                                    r->out.count);
8474                 break;
8475         case 2:
8476                 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8477                                                    r->out.count);
8478                 break;
8479         default:
8480                 return WERR_UNKNOWN_LEVEL;
8481         }
8482
8483         if (!W_ERROR_IS_OK(result)) {
8484                 return result;
8485         }
8486
8487         *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8488                                                      spoolss_EnumMonitors, NULL,
8489                                                      *r->out.info, r->in.level,
8490                                                      *r->out.count);
8491         *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8492         *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8493
8494         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8495 }
8496
8497 /****************************************************************************
8498 ****************************************************************************/
8499
8500 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8501                              const print_queue_struct *queue,
8502                              int count, int snum,
8503                              const NT_PRINTER_INFO_LEVEL *ntprinter,
8504                              uint32_t jobid,
8505                              struct spoolss_JobInfo1 *r)
8506 {
8507         int i = 0;
8508         bool found = false;
8509
8510         for (i=0; i<count && found == false; i++) {
8511                 if (queue[i].job == (int)jobid) {
8512                         found = true;
8513                 }
8514         }
8515
8516         if (found == false) {
8517                 /* NT treats not found as bad param... yet another bad choice */
8518                 return WERR_INVALID_PARAM;
8519         }
8520
8521         return fill_job_info1(mem_ctx,
8522                               r,
8523                               &queue[i-1],
8524                               i,
8525                               snum,
8526                               ntprinter);
8527 }
8528
8529 /****************************************************************************
8530 ****************************************************************************/
8531
8532 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8533                              const print_queue_struct *queue,
8534                              int count, int snum,
8535                              const NT_PRINTER_INFO_LEVEL *ntprinter,
8536                              uint32_t jobid,
8537                              struct spoolss_JobInfo2 *r)
8538 {
8539         int i = 0;
8540         bool found = false;
8541         struct spoolss_DeviceMode *devmode;
8542         NT_DEVICEMODE *nt_devmode;
8543         WERROR result;
8544
8545         for (i=0; i<count && found == false; i++) {
8546                 if (queue[i].job == (int)jobid) {
8547                         found = true;
8548                 }
8549         }
8550
8551         if (found == false) {
8552                 /* NT treats not found as bad param... yet another bad
8553                    choice */
8554                 return WERR_INVALID_PARAM;
8555         }
8556
8557         /*
8558          * if the print job does not have a DEVMODE associated with it,
8559          * just use the one for the printer. A NULL devicemode is not
8560          *  a failure condition
8561          */
8562
8563         nt_devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8564         if (nt_devmode) {
8565                 devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode);
8566                 W_ERROR_HAVE_NO_MEMORY(devmode);
8567                 result = convert_nt_devicemode(devmode, devmode, nt_devmode);
8568                 if (!W_ERROR_IS_OK(result)) {
8569                         return result;
8570                 }
8571         } else {
8572                 devmode = construct_dev_mode(mem_ctx, lp_const_servicename(snum));
8573                 W_ERROR_HAVE_NO_MEMORY(devmode);
8574         }
8575
8576         return fill_job_info2(mem_ctx,
8577                               r,
8578                               &queue[i-1],
8579                               i,
8580                               snum,
8581                               ntprinter,
8582                               devmode);
8583 }
8584
8585 /****************************************************************
8586  _spoolss_GetJob
8587 ****************************************************************/
8588
8589 WERROR _spoolss_GetJob(pipes_struct *p,
8590                        struct spoolss_GetJob *r)
8591 {
8592         WERROR result = WERR_OK;
8593         NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
8594         int snum;
8595         int count;
8596         print_queue_struct      *queue = NULL;
8597         print_status_struct prt_status;
8598
8599         /* that's an [in out] buffer */
8600
8601         if (!r->in.buffer && (r->in.offered != 0)) {
8602                 return WERR_INVALID_PARAM;
8603         }
8604
8605         DEBUG(5,("_spoolss_GetJob\n"));
8606
8607         *r->out.needed = 0;
8608
8609         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8610                 return WERR_BADFID;
8611         }
8612
8613         result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
8614         if (!W_ERROR_IS_OK(result)) {
8615                 return result;
8616         }
8617
8618         count = print_queue_status(snum, &queue, &prt_status);
8619
8620         DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8621                      count, prt_status.status, prt_status.message));
8622
8623         switch (r->in.level) {
8624         case 1:
8625                 result = getjob_level_1(p->mem_ctx,
8626                                         queue, count, snum, ntprinter,
8627                                         r->in.job_id, &r->out.info->info1);
8628                 break;
8629         case 2:
8630                 result = getjob_level_2(p->mem_ctx,
8631                                         queue, count, snum, ntprinter,
8632                                         r->in.job_id, &r->out.info->info2);
8633                 break;
8634         default:
8635                 result = WERR_UNKNOWN_LEVEL;
8636                 break;
8637         }
8638
8639         SAFE_FREE(queue);
8640         free_a_printer(&ntprinter, 2);
8641
8642         if (!W_ERROR_IS_OK(result)) {
8643                 TALLOC_FREE(r->out.info);
8644                 return result;
8645         }
8646
8647         *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, NULL,
8648                                                r->out.info, r->in.level);
8649         r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8650
8651         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8652 }
8653
8654 /****************************************************************
8655  _spoolss_GetPrinterDataEx
8656 ****************************************************************/
8657
8658 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
8659                                  struct spoolss_GetPrinterDataEx *r)
8660 {
8661
8662         Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
8663         struct regval_blob              *val = NULL;
8664         NT_PRINTER_INFO_LEVEL   *printer = NULL;
8665         int                     snum = 0;
8666         WERROR result = WERR_OK;
8667         DATA_BLOB blob;
8668
8669         DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8670
8671         DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8672                 r->in.key_name, r->in.value_name));
8673
8674         /* in case of problem, return some default values */
8675
8676         *r->out.needed  = 0;
8677         *r->out.type    = REG_NONE;
8678
8679         if (!Printer) {
8680                 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8681                         OUR_HANDLE(r->in.handle)));
8682                 result = WERR_BADFID;
8683                 goto done;
8684         }
8685
8686         /* Is the handle to a printer or to the server? */
8687
8688         if (Printer->printer_type == SPLHND_SERVER) {
8689
8690                 result = getprinterdata_printer_server(p->mem_ctx,
8691                                                        r->in.value_name,
8692                                                        r->out.type,
8693                                                        r->out.data);
8694                 goto done;
8695         }
8696
8697         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8698                 result = WERR_BADFID;
8699                 goto done;
8700         }
8701
8702         result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
8703         if (!W_ERROR_IS_OK(result)) {
8704                 goto done;
8705         }
8706
8707         /* check to see if the keyname is valid */
8708         if (!strlen(r->in.key_name)) {
8709                 result = WERR_INVALID_PARAM;
8710                 goto done;
8711         }
8712
8713         /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
8714
8715         if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8716             strequal(r->in.value_name, "ChangeId")) {
8717                 *r->out.type = REG_DWORD;
8718                 *r->out.needed = 4;
8719                 r->out.data->value = printer->info_2->changeid;
8720                 result = WERR_OK;
8721                 goto done;
8722         }
8723
8724         if (lookup_printerkey(printer->info_2->data, r->in.key_name) == -1) {
8725                 DEBUG(4,("_spoolss_GetPrinterDataEx: "
8726                         "Invalid keyname [%s]\n", r->in.key_name ));
8727                 result = WERR_BADFILE;
8728                 goto done;
8729         }
8730
8731         val = get_printer_data(printer->info_2,
8732                                r->in.key_name, r->in.value_name);
8733         if (!val) {
8734                 result = WERR_BADFILE;
8735                 goto done;
8736         }
8737
8738         *r->out.needed = regval_size(val);
8739         *r->out.type = regval_type(val);
8740
8741         blob = data_blob_const(regval_data_p(val), regval_size(val));
8742
8743         result = pull_spoolss_PrinterData(p->mem_ctx, &blob,
8744                                           r->out.data,
8745                                           *r->out.type);
8746
8747  done:
8748         if (printer) {
8749                 free_a_printer(&printer, 2);
8750         }
8751
8752         if (!W_ERROR_IS_OK(result)) {
8753                 return result;
8754         }
8755
8756         *r->out.needed  = ndr_size_spoolss_PrinterData(r->out.data, *r->out.type, NULL, 0);
8757         *r->out.type    = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8758         r->out.data     = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8759
8760         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8761 }
8762
8763 /****************************************************************
8764  _spoolss_SetPrinterDataEx
8765 ****************************************************************/
8766
8767 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
8768                                  struct spoolss_SetPrinterDataEx *r)
8769 {
8770         NT_PRINTER_INFO_LEVEL   *printer = NULL;
8771         int                     snum = 0;
8772         WERROR                  result = WERR_OK;
8773         Printer_entry           *Printer = find_printer_index_by_hnd(p, r->in.handle);
8774         char                    *oid_string;
8775         DATA_BLOB blob;
8776
8777         DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8778
8779         /* From MSDN documentation of SetPrinterDataEx: pass request to
8780            SetPrinterData if key is "PrinterDriverData" */
8781
8782         if (!Printer) {
8783                 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8784                         OUR_HANDLE(r->in.handle)));
8785                 return WERR_BADFID;
8786         }
8787
8788         if (Printer->printer_type == SPLHND_SERVER) {
8789                 DEBUG(10,("_spoolss_SetPrinterDataEx: "
8790                         "Not implemented for server handles yet\n"));
8791                 return WERR_INVALID_PARAM;
8792         }
8793
8794         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8795                 return WERR_BADFID;
8796         }
8797
8798         /*
8799          * Access check : NT returns "access denied" if you make a
8800          * SetPrinterData call without the necessary privildge.
8801          * we were originally returning OK if nothing changed
8802          * which made Win2k issue **a lot** of SetPrinterData
8803          * when connecting to a printer  --jerry
8804          */
8805
8806         if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8807                 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8808                         "change denied by handle access permissions\n"));
8809                 return WERR_ACCESS_DENIED;
8810         }
8811
8812         result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
8813         if (!W_ERROR_IS_OK(result)) {
8814                 return result;
8815         }
8816
8817         /* check for OID in valuename */
8818
8819         oid_string = strchr(r->in.value_name, ',');
8820         if (oid_string) {
8821                 *oid_string = '\0';
8822                 oid_string++;
8823         }
8824
8825         result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8826                                           r->in.type, &r->in.data);
8827         if (!W_ERROR_IS_OK(result)) {
8828                 goto done;
8829         }
8830
8831         /*
8832          * When client side code sets a magic printer data key, detect it and save
8833          * the current printer data and the magic key's data (its the DEVMODE) for
8834          * future printer/driver initializations.
8835          */
8836         if ((r->in.type == REG_BINARY) && strequal(r->in.value_name, PHANTOM_DEVMODE_KEY)) {
8837                 /* Set devmode and printer initialization info */
8838                 result = save_driver_init(printer, 2, blob.data, blob.length);
8839
8840                 srv_spoolss_reset_printerdata(printer->info_2->drivername);
8841
8842                 goto done;
8843         }
8844
8845         /* save the registry data */
8846
8847         result = set_printer_dataex(printer, r->in.key_name, r->in.value_name,
8848                                     r->in.type, blob.data, blob.length);
8849
8850         if (W_ERROR_IS_OK(result)) {
8851                 /* save the OID if one was specified */
8852                 if (oid_string) {
8853                         char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
8854                                 r->in.key_name, SPOOL_OID_KEY);
8855                         if (!str) {
8856                                 result = WERR_NOMEM;
8857                                 goto done;
8858                         }
8859
8860                         /*
8861                          * I'm not checking the status here on purpose.  Don't know
8862                          * if this is right, but I'm returning the status from the
8863                          * previous set_printer_dataex() call.  I have no idea if
8864                          * this is right.    --jerry
8865                          */
8866
8867                         set_printer_dataex(printer, str, r->in.value_name,
8868                                            REG_SZ, (uint8_t *)oid_string,
8869                                            strlen(oid_string)+1);
8870                 }
8871
8872                 result = mod_a_printer(printer, 2);
8873         }
8874
8875  done:
8876         free_a_printer(&printer, 2);
8877
8878         return result;
8879 }
8880
8881 /****************************************************************
8882  _spoolss_DeletePrinterDataEx
8883 ****************************************************************/
8884
8885 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
8886                                     struct spoolss_DeletePrinterDataEx *r)
8887 {
8888         NT_PRINTER_INFO_LEVEL   *printer = NULL;
8889         int             snum=0;
8890         WERROR          status = WERR_OK;
8891         Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
8892
8893         DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8894
8895         if (!Printer) {
8896                 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8897                         "Invalid handle (%s:%u:%u).\n",
8898                         OUR_HANDLE(r->in.handle)));
8899                 return WERR_BADFID;
8900         }
8901
8902         if (!get_printer_snum(p, r->in.handle, &snum, NULL))
8903                 return WERR_BADFID;
8904
8905         if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8906                 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8907                         "printer properties change denied by handle\n"));
8908                 return WERR_ACCESS_DENIED;
8909         }
8910
8911         if (!r->in.value_name || !r->in.key_name) {
8912                 return WERR_NOMEM;
8913         }
8914
8915         status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8916         if (!W_ERROR_IS_OK(status))
8917                 return status;
8918
8919         status = delete_printer_dataex( printer, r->in.key_name, r->in.value_name );
8920
8921         if ( W_ERROR_IS_OK(status) )
8922                 mod_a_printer( printer, 2 );
8923
8924         free_a_printer(&printer, 2);
8925
8926         return status;
8927 }
8928
8929 /****************************************************************
8930  _spoolss_EnumPrinterKey
8931 ****************************************************************/
8932
8933 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
8934                                struct spoolss_EnumPrinterKey *r)
8935 {
8936         fstring         *keynames = NULL;
8937         int             num_keys;
8938         Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
8939         NT_PRINTER_DATA *data;
8940         NT_PRINTER_INFO_LEVEL   *printer = NULL;
8941         int             snum = 0;
8942         WERROR          result = WERR_BADFILE;
8943         int i;
8944         const char **array = NULL;
8945         DATA_BLOB blob;
8946
8947         DEBUG(4,("_spoolss_EnumPrinterKey\n"));
8948
8949         if (!Printer) {
8950                 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
8951                         OUR_HANDLE(r->in.handle)));
8952                 return WERR_BADFID;
8953         }
8954
8955         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8956                 return WERR_BADFID;
8957         }
8958
8959         result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8960         if (!W_ERROR_IS_OK(result)) {
8961                 return result;
8962         }
8963
8964         /* get the list of subkey names */
8965
8966         data = printer->info_2->data;
8967
8968         num_keys = get_printer_subkeys(data, r->in.key_name, &keynames);
8969         if (num_keys == -1) {
8970                 result = WERR_BADFILE;
8971                 goto done;
8972         }
8973
8974         array = talloc_zero_array(r->out.key_buffer, const char *, num_keys + 2);
8975         if (!array) {
8976                 result = WERR_NOMEM;
8977                 goto done;
8978         }
8979
8980         if (!num_keys) {
8981                 array[0] = talloc_strdup(array, "");
8982                 if (!array[0]) {
8983                         result = WERR_NOMEM;
8984                         goto done;
8985                 }
8986         }
8987
8988         for (i=0; i < num_keys; i++) {
8989
8990                 DEBUG(10,("_spoolss_EnumPrinterKey: adding keyname: %s\n",
8991                         keynames[i]));
8992
8993                 array[i] = talloc_strdup(array, keynames[i]);
8994                 if (!array[i]) {
8995                         result = WERR_NOMEM;
8996                         goto done;
8997                 }
8998         }
8999
9000         if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
9001                 result = WERR_NOMEM;
9002                 goto done;
9003         }
9004
9005         *r->out._ndr_size = r->in.offered / 2;
9006         *r->out.needed = blob.length;
9007
9008         if (r->in.offered < *r->out.needed) {
9009                 result = WERR_MORE_DATA;
9010         } else {
9011                 result = WERR_OK;
9012                 r->out.key_buffer->string_array = array;
9013         }
9014
9015  done:
9016         if (!W_ERROR_IS_OK(result)) {
9017                 TALLOC_FREE(array);
9018                 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
9019                         *r->out.needed = 0;
9020                 }
9021         }
9022
9023         free_a_printer(&printer, 2);
9024         SAFE_FREE(keynames);
9025
9026         return result;
9027 }
9028
9029 /****************************************************************
9030  _spoolss_DeletePrinterKey
9031 ****************************************************************/
9032
9033 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
9034                                  struct spoolss_DeletePrinterKey *r)
9035 {
9036         Printer_entry           *Printer = find_printer_index_by_hnd(p, r->in.handle);
9037         NT_PRINTER_INFO_LEVEL   *printer = NULL;
9038         int                     snum=0;
9039         WERROR                  status;
9040
9041         DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9042
9043         if (!Printer) {
9044                 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9045                         OUR_HANDLE(r->in.handle)));
9046                 return WERR_BADFID;
9047         }
9048
9049         /* if keyname == NULL, return error */
9050
9051         if ( !r->in.key_name )
9052                 return WERR_INVALID_PARAM;
9053
9054         if (!get_printer_snum(p, r->in.handle, &snum, NULL))
9055                 return WERR_BADFID;
9056
9057         if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9058                 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9059                         "printer properties change denied by handle\n"));
9060                 return WERR_ACCESS_DENIED;
9061         }
9062
9063         status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9064         if (!W_ERROR_IS_OK(status))
9065                 return status;
9066
9067         /* delete the key and all subneys */
9068
9069         status = delete_all_printer_data( printer->info_2, r->in.key_name );
9070
9071         if ( W_ERROR_IS_OK(status) )
9072                 status = mod_a_printer(printer, 2);
9073
9074         free_a_printer( &printer, 2 );
9075
9076         return status;
9077 }
9078
9079 /****************************************************************
9080 ****************************************************************/
9081
9082 static WERROR registry_value_to_printer_enum_value(TALLOC_CTX *mem_ctx,
9083                                                    struct regval_blob *v,
9084                                                    struct spoolss_PrinterEnumValues *r)
9085 {
9086         WERROR result;
9087
9088         r->data = TALLOC_ZERO_P(mem_ctx, union spoolss_PrinterData);
9089         W_ERROR_HAVE_NO_MEMORY(r->data);
9090
9091         r->value_name   = talloc_strdup(mem_ctx, regval_name(v));
9092         W_ERROR_HAVE_NO_MEMORY(r->value_name);
9093
9094         r->type         = regval_type(v);
9095         r->data_length  = regval_size(v);
9096
9097         if (r->data_length) {
9098                 DATA_BLOB blob = data_blob_const(regval_data_p(v),
9099                                                  regval_size(v));
9100                 result = pull_spoolss_PrinterData(mem_ctx, &blob,
9101                                                   r->data,
9102                                                   r->type);
9103                 if (!W_ERROR_IS_OK(result)) {
9104                         return result;
9105                 }
9106         }
9107
9108         return WERR_OK;
9109 }
9110
9111 /****************************************************************
9112  _spoolss_EnumPrinterDataEx
9113 ****************************************************************/
9114
9115 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
9116                                   struct spoolss_EnumPrinterDataEx *r)
9117 {
9118         uint32_t        count = 0;
9119         NT_PRINTER_INFO_LEVEL   *printer = NULL;
9120         struct spoolss_PrinterEnumValues *info = NULL;
9121         NT_PRINTER_DATA         *p_data;
9122         Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
9123         int             snum;
9124         WERROR          result;
9125         int             key_index;
9126         int             i;
9127
9128         DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
9129
9130         *r->out.count = 0;
9131         *r->out.needed = 0;
9132         *r->out.info = NULL;
9133
9134         if (!Printer) {
9135                 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
9136                         OUR_HANDLE(r->in.handle)));
9137                 return WERR_BADFID;
9138         }
9139
9140         /*
9141          * first check for a keyname of NULL or "".  Win2k seems to send
9142          * this a lot and we should send back WERR_INVALID_PARAM
9143          * no need to spend time looking up the printer in this case.
9144          * --jerry
9145          */
9146
9147         if (!strlen(r->in.key_name)) {
9148                 result = WERR_INVALID_PARAM;
9149                 goto done;
9150         }
9151
9152         /* get the printer off of disk */
9153
9154         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9155                 return WERR_BADFID;
9156         }
9157
9158         ZERO_STRUCT(printer);
9159         result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9160         if (!W_ERROR_IS_OK(result)) {
9161                 return result;
9162         }
9163
9164         /* now look for a match on the key name */
9165
9166         p_data = printer->info_2->data;
9167
9168         key_index = lookup_printerkey(p_data, r->in.key_name);
9169         if (key_index == -1) {
9170                 DEBUG(10,("_spoolss_EnumPrinterDataEx: Unknown keyname [%s]\n",
9171                         r->in.key_name));
9172                 result = WERR_INVALID_PARAM;
9173                 goto done;
9174         }
9175
9176         /* allocate the memory for the array of pointers -- if necessary */
9177
9178         count = regval_ctr_numvals(p_data->keys[key_index].values);
9179         if (!count) {
9180                 result = WERR_OK; /* ??? */
9181                 goto done;
9182         }
9183
9184         info = TALLOC_ZERO_ARRAY(p->mem_ctx,
9185                                  struct spoolss_PrinterEnumValues,
9186                                  count);
9187         if (!info) {
9188                 DEBUG(0,("_spoolss_EnumPrinterDataEx: talloc() failed\n"));
9189                 result = WERR_NOMEM;
9190                 goto done;
9191         }
9192
9193         /*
9194          * loop through all params and build the array to pass
9195          * back to the  client
9196          */
9197
9198         for (i=0; i < count; i++) {
9199
9200                 struct regval_blob      *val;
9201
9202                 /* lookup the registry value */
9203
9204                 val = regval_ctr_specific_value(p_data->keys[key_index].values, i);
9205
9206                 DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val)));
9207
9208                 /* copy the data */
9209
9210                 result = registry_value_to_printer_enum_value(info, val, &info[i]);
9211                 if (!W_ERROR_IS_OK(result)) {
9212                         goto done;
9213                 }
9214         }
9215
9216 #if 0 /* FIXME - gd */
9217         /* housekeeping information in the reply */
9218
9219         /* Fix from Martin Zielinski <mz@seh.de> - ensure
9220          * the hand marshalled container size is a multiple
9221          * of 4 bytes for RPC alignment.
9222          */
9223
9224         if (needed % 4) {
9225                 needed += 4-(needed % 4);
9226         }
9227 #endif
9228         *r->out.count   = count;
9229         *r->out.info    = info;
9230
9231  done:
9232
9233         if (printer) {
9234                 free_a_printer(&printer, 2);
9235         }
9236
9237         if (!W_ERROR_IS_OK(result)) {
9238                 return result;
9239         }
9240
9241         *r->out.needed  = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
9242                                                spoolss_EnumPrinterDataEx, NULL,
9243                                                *r->out.info,
9244                                                *r->out.count);
9245         *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
9246         *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
9247
9248         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
9249 }
9250
9251 /****************************************************************************
9252 ****************************************************************************/
9253
9254 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9255                                                  const char *servername,
9256                                                  const char *environment,
9257                                                  struct spoolss_PrintProcessorDirectoryInfo1 *r)
9258 {
9259         WERROR werr;
9260         char *path = NULL;
9261
9262         werr = compose_spoolss_server_path(mem_ctx,
9263                                            servername,
9264                                            environment,
9265                                            SPOOLSS_PRTPROCS_PATH,
9266                                            &path);
9267         if (!W_ERROR_IS_OK(werr)) {
9268                 return werr;
9269         }
9270
9271         DEBUG(4,("print processor directory: [%s]\n", path));
9272
9273         r->directory_name = path;
9274
9275         return WERR_OK;
9276 }
9277
9278 /****************************************************************
9279  _spoolss_GetPrintProcessorDirectory
9280 ****************************************************************/
9281
9282 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
9283                                            struct spoolss_GetPrintProcessorDirectory *r)
9284 {
9285         WERROR result;
9286
9287         /* that's an [in out] buffer */
9288
9289         if (!r->in.buffer && (r->in.offered != 0)) {
9290                 return WERR_INVALID_PARAM;
9291         }
9292
9293         DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9294                 r->in.level));
9295
9296         *r->out.needed = 0;
9297
9298         /* r->in.level is ignored */
9299
9300         /* We always should reply with a local print processor directory so that
9301          * users are not forced to have a [prnproc$] share on the Samba spoolss
9302          * server - Guenther */
9303
9304         result = getprintprocessordirectory_level_1(p->mem_ctx,
9305                                                     NULL, /* r->in.server */
9306                                                     r->in.environment,
9307                                                     &r->out.info->info1);
9308         if (!W_ERROR_IS_OK(result)) {
9309                 TALLOC_FREE(r->out.info);
9310                 return result;
9311         }
9312
9313         *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo, NULL,
9314                                                r->out.info, r->in.level);
9315         r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9316
9317         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9318 }
9319
9320 /*******************************************************************
9321  ********************************************************************/
9322
9323 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9324                                const char *dllname)
9325 {
9326         enum ndr_err_code ndr_err;
9327         struct spoolss_MonitorUi ui;
9328
9329         ui.dll_name = dllname;
9330
9331         ndr_err = ndr_push_struct_blob(buf, mem_ctx, NULL, &ui,
9332                        (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9333         if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9334                 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9335         }
9336         return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9337 }
9338
9339 /*******************************************************************
9340  Streams the monitor UI DLL name in UNICODE
9341 *******************************************************************/
9342
9343 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9344                                NT_USER_TOKEN *token, DATA_BLOB *in,
9345                                DATA_BLOB *out, uint32_t *needed)
9346 {
9347         const char *dllname = "tcpmonui.dll";
9348
9349         *needed = (strlen(dllname)+1) * 2;
9350
9351         if (out->length < *needed) {
9352                 return WERR_INSUFFICIENT_BUFFER;
9353         }
9354
9355         if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9356                 return WERR_NOMEM;
9357         }
9358
9359         return WERR_OK;
9360 }
9361
9362 /*******************************************************************
9363  ********************************************************************/
9364
9365 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9366                              struct spoolss_PortData1 *port1,
9367                              const DATA_BLOB *buf)
9368 {
9369         enum ndr_err_code ndr_err;
9370         ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port1,
9371                        (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9372         if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9373                 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9374         }
9375         return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9376 }
9377
9378 /*******************************************************************
9379  ********************************************************************/
9380
9381 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9382                              struct spoolss_PortData2 *port2,
9383                              const DATA_BLOB *buf)
9384 {
9385         enum ndr_err_code ndr_err;
9386         ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port2,
9387                        (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9388         if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9389                 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9390         }
9391         return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9392 }
9393
9394 /*******************************************************************
9395  Create a new TCP/IP port
9396 *******************************************************************/
9397
9398 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9399                              NT_USER_TOKEN *token, DATA_BLOB *in,
9400                              DATA_BLOB *out, uint32_t *needed)
9401 {
9402         struct spoolss_PortData1 port1;
9403         struct spoolss_PortData2 port2;
9404         char *device_uri = NULL;
9405         uint32_t version;
9406
9407         const char *portname;
9408         const char *hostaddress;
9409         const char *queue;
9410         uint32_t port_number;
9411         uint32_t protocol;
9412
9413         /* peek for spoolss_PortData version */
9414
9415         if (!in || (in->length < (128 + 4))) {
9416                 return WERR_GENERAL_FAILURE;
9417         }
9418
9419         version = IVAL(in->data, 128);
9420
9421         switch (version) {
9422                 case 1:
9423                         ZERO_STRUCT(port1);
9424
9425                         if (!pull_port_data_1(mem_ctx, &port1, in)) {
9426                                 return WERR_NOMEM;
9427                         }
9428
9429                         portname        = port1.portname;
9430                         hostaddress     = port1.hostaddress;
9431                         queue           = port1.queue;
9432                         protocol        = port1.protocol;
9433                         port_number     = port1.port_number;
9434
9435                         break;
9436                 case 2:
9437                         ZERO_STRUCT(port2);
9438
9439                         if (!pull_port_data_2(mem_ctx, &port2, in)) {
9440                                 return WERR_NOMEM;
9441                         }
9442
9443                         portname        = port2.portname;
9444                         hostaddress     = port2.hostaddress;
9445                         queue           = port2.queue;
9446                         protocol        = port2.protocol;
9447                         port_number     = port2.port_number;
9448
9449                         break;
9450                 default:
9451                         DEBUG(1,("xcvtcp_addport: "
9452                                 "unknown version of port_data: %d\n", version));
9453                         return WERR_UNKNOWN_PORT;
9454         }
9455
9456         /* create the device URI and call the add_port_hook() */
9457
9458         switch (protocol) {
9459         case PROTOCOL_RAWTCP_TYPE:
9460                 device_uri = talloc_asprintf(mem_ctx,
9461                                 "socket://%s:%d/", hostaddress,
9462                                 port_number);
9463                 break;
9464
9465         case PROTOCOL_LPR_TYPE:
9466                 device_uri = talloc_asprintf(mem_ctx,
9467                         "lpr://%s/%s", hostaddress, queue );
9468                 break;
9469
9470         default:
9471                 return WERR_UNKNOWN_PORT;
9472         }
9473
9474         if (!device_uri) {
9475                 return WERR_NOMEM;
9476         }
9477
9478         return add_port_hook(mem_ctx, token, portname, device_uri);
9479 }
9480
9481 /*******************************************************************
9482 *******************************************************************/
9483
9484 struct xcv_api_table xcvtcp_cmds[] = {
9485         { "MonitorUI",  xcvtcp_monitorui },
9486         { "AddPort",    xcvtcp_addport},
9487         { NULL,         NULL }
9488 };
9489
9490 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9491                                      NT_USER_TOKEN *token, const char *command,
9492                                      DATA_BLOB *inbuf,
9493                                      DATA_BLOB *outbuf,
9494                                      uint32_t *needed )
9495 {
9496         int i;
9497
9498         DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9499
9500         for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9501                 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9502                         return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9503         }
9504
9505         return WERR_BADFUNC;
9506 }
9507
9508 /*******************************************************************
9509 *******************************************************************/
9510 #if 0   /* don't support management using the "Local Port" monitor */
9511
9512 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9513                                  NT_USER_TOKEN *token, DATA_BLOB *in,
9514                                  DATA_BLOB *out, uint32_t *needed)
9515 {
9516         const char *dllname = "localui.dll";
9517
9518         *needed = (strlen(dllname)+1) * 2;
9519
9520         if (out->length < *needed) {
9521                 return WERR_INSUFFICIENT_BUFFER;
9522         }
9523
9524         if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9525                 return WERR_NOMEM;
9526         }
9527
9528         return WERR_OK;
9529 }
9530
9531 /*******************************************************************
9532 *******************************************************************/
9533
9534 struct xcv_api_table xcvlocal_cmds[] = {
9535         { "MonitorUI",  xcvlocal_monitorui },
9536         { NULL,         NULL }
9537 };
9538 #else
9539 struct xcv_api_table xcvlocal_cmds[] = {
9540         { NULL,         NULL }
9541 };
9542 #endif
9543
9544
9545
9546 /*******************************************************************
9547 *******************************************************************/
9548
9549 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9550                                        NT_USER_TOKEN *token, const char *command,
9551                                        DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9552                                        uint32_t *needed)
9553 {
9554         int i;
9555
9556         DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9557
9558         for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9559                 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9560                         return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9561         }
9562         return WERR_BADFUNC;
9563 }
9564
9565 /****************************************************************
9566  _spoolss_XcvData
9567 ****************************************************************/
9568
9569 WERROR _spoolss_XcvData(pipes_struct *p,
9570                         struct spoolss_XcvData *r)
9571 {
9572         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9573         DATA_BLOB out_data = data_blob_null;
9574         WERROR werror;
9575
9576         if (!Printer) {
9577                 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9578                         OUR_HANDLE(r->in.handle)));
9579                 return WERR_BADFID;
9580         }
9581
9582         /* Has to be a handle to the TCP/IP port monitor */
9583
9584         if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9585                 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9586                 return WERR_BADFID;
9587         }
9588
9589         /* requires administrative access to the server */
9590
9591         if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9592                 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9593                 return WERR_ACCESS_DENIED;
9594         }
9595
9596         /* Allocate the outgoing buffer */
9597
9598         if (r->in.out_data_size) {
9599                 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9600                 if (out_data.data == NULL) {
9601                         return WERR_NOMEM;
9602                 }
9603         }
9604
9605         switch ( Printer->printer_type ) {
9606         case SPLHND_PORTMON_TCP:
9607                 werror = process_xcvtcp_command(p->mem_ctx,
9608                                                 p->server_info->ptok,
9609                                                 r->in.function_name,
9610                                                 &r->in.in_data, &out_data,
9611                                                 r->out.needed);
9612                 break;
9613         case SPLHND_PORTMON_LOCAL:
9614                 werror = process_xcvlocal_command(p->mem_ctx,
9615                                                   p->server_info->ptok,
9616                                                   r->in.function_name,
9617                                                   &r->in.in_data, &out_data,
9618                                                   r->out.needed);
9619                 break;
9620         default:
9621                 werror = WERR_INVALID_PRINT_MONITOR;
9622         }
9623
9624         if (!W_ERROR_IS_OK(werror)) {
9625                 return werror;
9626         }
9627
9628         *r->out.status_code = 0;
9629
9630         if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9631                 memcpy(r->out.out_data, out_data.data,
9632                         MIN(r->in.out_data_size, out_data.length));
9633         }
9634
9635         return WERR_OK;
9636 }
9637
9638 /****************************************************************
9639  _spoolss_AddPrintProcessor
9640 ****************************************************************/
9641
9642 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
9643                                   struct spoolss_AddPrintProcessor *r)
9644 {
9645         /* for now, just indicate success and ignore the add.  We'll
9646            automatically set the winprint processor for printer
9647            entries later.  Used to debug the LexMark Optra S 1855 PCL
9648            driver --jerry */
9649
9650         return WERR_OK;
9651 }
9652
9653 /****************************************************************
9654  _spoolss_AddPort
9655 ****************************************************************/
9656
9657 WERROR _spoolss_AddPort(pipes_struct *p,
9658                         struct spoolss_AddPort *r)
9659 {
9660         /* do what w2k3 does */
9661
9662         return WERR_NOT_SUPPORTED;
9663 }
9664
9665 /****************************************************************
9666  _spoolss_GetPrinterDriver
9667 ****************************************************************/
9668
9669 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
9670                                  struct spoolss_GetPrinterDriver *r)
9671 {
9672         p->rng_fault_state = true;
9673         return WERR_NOT_SUPPORTED;
9674 }
9675
9676 /****************************************************************
9677  _spoolss_ReadPrinter
9678 ****************************************************************/
9679
9680 WERROR _spoolss_ReadPrinter(pipes_struct *p,
9681                             struct spoolss_ReadPrinter *r)
9682 {
9683         p->rng_fault_state = true;
9684         return WERR_NOT_SUPPORTED;
9685 }
9686
9687 /****************************************************************
9688  _spoolss_WaitForPrinterChange
9689 ****************************************************************/
9690
9691 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
9692                                      struct spoolss_WaitForPrinterChange *r)
9693 {
9694         p->rng_fault_state = true;
9695         return WERR_NOT_SUPPORTED;
9696 }
9697
9698 /****************************************************************
9699  _spoolss_ConfigurePort
9700 ****************************************************************/
9701
9702 WERROR _spoolss_ConfigurePort(pipes_struct *p,
9703                               struct spoolss_ConfigurePort *r)
9704 {
9705         p->rng_fault_state = true;
9706         return WERR_NOT_SUPPORTED;
9707 }
9708
9709 /****************************************************************
9710  _spoolss_DeletePort
9711 ****************************************************************/
9712
9713 WERROR _spoolss_DeletePort(pipes_struct *p,
9714                            struct spoolss_DeletePort *r)
9715 {
9716         p->rng_fault_state = true;
9717         return WERR_NOT_SUPPORTED;
9718 }
9719
9720 /****************************************************************
9721  _spoolss_CreatePrinterIC
9722 ****************************************************************/
9723
9724 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
9725                                 struct spoolss_CreatePrinterIC *r)
9726 {
9727         p->rng_fault_state = true;
9728         return WERR_NOT_SUPPORTED;
9729 }
9730
9731 /****************************************************************
9732  _spoolss_PlayGDIScriptOnPrinterIC
9733 ****************************************************************/
9734
9735 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
9736                                          struct spoolss_PlayGDIScriptOnPrinterIC *r)
9737 {
9738         p->rng_fault_state = true;
9739         return WERR_NOT_SUPPORTED;
9740 }
9741
9742 /****************************************************************
9743  _spoolss_DeletePrinterIC
9744 ****************************************************************/
9745
9746 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
9747                                 struct spoolss_DeletePrinterIC *r)
9748 {
9749         p->rng_fault_state = true;
9750         return WERR_NOT_SUPPORTED;
9751 }
9752
9753 /****************************************************************
9754  _spoolss_AddPrinterConnection
9755 ****************************************************************/
9756
9757 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
9758                                      struct spoolss_AddPrinterConnection *r)
9759 {
9760         p->rng_fault_state = true;
9761         return WERR_NOT_SUPPORTED;
9762 }
9763
9764 /****************************************************************
9765  _spoolss_DeletePrinterConnection
9766 ****************************************************************/
9767
9768 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
9769                                         struct spoolss_DeletePrinterConnection *r)
9770 {
9771         p->rng_fault_state = true;
9772         return WERR_NOT_SUPPORTED;
9773 }
9774
9775 /****************************************************************
9776  _spoolss_PrinterMessageBox
9777 ****************************************************************/
9778
9779 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
9780                                   struct spoolss_PrinterMessageBox *r)
9781 {
9782         p->rng_fault_state = true;
9783         return WERR_NOT_SUPPORTED;
9784 }
9785
9786 /****************************************************************
9787  _spoolss_AddMonitor
9788 ****************************************************************/
9789
9790 WERROR _spoolss_AddMonitor(pipes_struct *p,
9791                            struct spoolss_AddMonitor *r)
9792 {
9793         p->rng_fault_state = true;
9794         return WERR_NOT_SUPPORTED;
9795 }
9796
9797 /****************************************************************
9798  _spoolss_DeleteMonitor
9799 ****************************************************************/
9800
9801 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
9802                               struct spoolss_DeleteMonitor *r)
9803 {
9804         p->rng_fault_state = true;
9805         return WERR_NOT_SUPPORTED;
9806 }
9807
9808 /****************************************************************
9809  _spoolss_DeletePrintProcessor
9810 ****************************************************************/
9811
9812 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
9813                                      struct spoolss_DeletePrintProcessor *r)
9814 {
9815         p->rng_fault_state = true;
9816         return WERR_NOT_SUPPORTED;
9817 }
9818
9819 /****************************************************************
9820  _spoolss_AddPrintProvidor
9821 ****************************************************************/
9822
9823 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
9824                                  struct spoolss_AddPrintProvidor *r)
9825 {
9826         p->rng_fault_state = true;
9827         return WERR_NOT_SUPPORTED;
9828 }
9829
9830 /****************************************************************
9831  _spoolss_DeletePrintProvidor
9832 ****************************************************************/
9833
9834 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
9835                                     struct spoolss_DeletePrintProvidor *r)
9836 {
9837         p->rng_fault_state = true;
9838         return WERR_NOT_SUPPORTED;
9839 }
9840
9841 /****************************************************************
9842  _spoolss_FindFirstPrinterChangeNotification
9843 ****************************************************************/
9844
9845 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
9846                                                    struct spoolss_FindFirstPrinterChangeNotification *r)
9847 {
9848         p->rng_fault_state = true;
9849         return WERR_NOT_SUPPORTED;
9850 }
9851
9852 /****************************************************************
9853  _spoolss_FindNextPrinterChangeNotification
9854 ****************************************************************/
9855
9856 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
9857                                                   struct spoolss_FindNextPrinterChangeNotification *r)
9858 {
9859         p->rng_fault_state = true;
9860         return WERR_NOT_SUPPORTED;
9861 }
9862
9863 /****************************************************************
9864  _spoolss_RouterFindFirstPrinterChangeNotificationOld
9865 ****************************************************************/
9866
9867 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
9868                                                             struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9869 {
9870         p->rng_fault_state = true;
9871         return WERR_NOT_SUPPORTED;
9872 }
9873
9874 /****************************************************************
9875  _spoolss_ReplyOpenPrinter
9876 ****************************************************************/
9877
9878 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
9879                                  struct spoolss_ReplyOpenPrinter *r)
9880 {
9881         p->rng_fault_state = true;
9882         return WERR_NOT_SUPPORTED;
9883 }
9884
9885 /****************************************************************
9886  _spoolss_RouterReplyPrinter
9887 ****************************************************************/
9888
9889 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
9890                                    struct spoolss_RouterReplyPrinter *r)
9891 {
9892         p->rng_fault_state = true;
9893         return WERR_NOT_SUPPORTED;
9894 }
9895
9896 /****************************************************************
9897  _spoolss_ReplyClosePrinter
9898 ****************************************************************/
9899
9900 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
9901                                   struct spoolss_ReplyClosePrinter *r)
9902 {
9903         p->rng_fault_state = true;
9904         return WERR_NOT_SUPPORTED;
9905 }
9906
9907 /****************************************************************
9908  _spoolss_AddPortEx
9909 ****************************************************************/
9910
9911 WERROR _spoolss_AddPortEx(pipes_struct *p,
9912                           struct spoolss_AddPortEx *r)
9913 {
9914         p->rng_fault_state = true;
9915         return WERR_NOT_SUPPORTED;
9916 }
9917
9918 /****************************************************************
9919  _spoolss_RouterFindFirstPrinterChangeNotification
9920 ****************************************************************/
9921
9922 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
9923                                                          struct spoolss_RouterFindFirstPrinterChangeNotification *r)
9924 {
9925         p->rng_fault_state = true;
9926         return WERR_NOT_SUPPORTED;
9927 }
9928
9929 /****************************************************************
9930  _spoolss_SpoolerInit
9931 ****************************************************************/
9932
9933 WERROR _spoolss_SpoolerInit(pipes_struct *p,
9934                             struct spoolss_SpoolerInit *r)
9935 {
9936         p->rng_fault_state = true;
9937         return WERR_NOT_SUPPORTED;
9938 }
9939
9940 /****************************************************************
9941  _spoolss_ResetPrinterEx
9942 ****************************************************************/
9943
9944 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
9945                                struct spoolss_ResetPrinterEx *r)
9946 {
9947         p->rng_fault_state = true;
9948         return WERR_NOT_SUPPORTED;
9949 }
9950
9951 /****************************************************************
9952  _spoolss_RouterReplyPrinterEx
9953 ****************************************************************/
9954
9955 WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
9956                                      struct spoolss_RouterReplyPrinterEx *r)
9957 {
9958         p->rng_fault_state = true;
9959         return WERR_NOT_SUPPORTED;
9960 }
9961
9962 /****************************************************************
9963  _spoolss_44
9964 ****************************************************************/
9965
9966 WERROR _spoolss_44(pipes_struct *p,
9967                    struct spoolss_44 *r)
9968 {
9969         p->rng_fault_state = true;
9970         return WERR_NOT_SUPPORTED;
9971 }
9972
9973 /****************************************************************
9974  _spoolss_47
9975 ****************************************************************/
9976
9977 WERROR _spoolss_47(pipes_struct *p,
9978                    struct spoolss_47 *r)
9979 {
9980         p->rng_fault_state = true;
9981         return WERR_NOT_SUPPORTED;
9982 }
9983
9984 /****************************************************************
9985  _spoolss_4a
9986 ****************************************************************/
9987
9988 WERROR _spoolss_4a(pipes_struct *p,
9989                    struct spoolss_4a *r)
9990 {
9991         p->rng_fault_state = true;
9992         return WERR_NOT_SUPPORTED;
9993 }
9994
9995 /****************************************************************
9996  _spoolss_4b
9997 ****************************************************************/
9998
9999 WERROR _spoolss_4b(pipes_struct *p,
10000                    struct spoolss_4b *r)
10001 {
10002         p->rng_fault_state = true;
10003         return WERR_NOT_SUPPORTED;
10004 }
10005
10006 /****************************************************************
10007  _spoolss_4c
10008 ****************************************************************/
10009
10010 WERROR _spoolss_4c(pipes_struct *p,
10011                    struct spoolss_4c *r)
10012 {
10013         p->rng_fault_state = true;
10014         return WERR_NOT_SUPPORTED;
10015 }
10016
10017 /****************************************************************
10018  _spoolss_53
10019 ****************************************************************/
10020
10021 WERROR _spoolss_53(pipes_struct *p,
10022                    struct spoolss_53 *r)
10023 {
10024         p->rng_fault_state = true;
10025         return WERR_NOT_SUPPORTED;
10026 }
10027
10028 /****************************************************************
10029  _spoolss_55
10030 ****************************************************************/
10031
10032 WERROR _spoolss_55(pipes_struct *p,
10033                    struct spoolss_55 *r)
10034 {
10035         p->rng_fault_state = true;
10036         return WERR_NOT_SUPPORTED;
10037 }
10038
10039 /****************************************************************
10040  _spoolss_56
10041 ****************************************************************/
10042
10043 WERROR _spoolss_56(pipes_struct *p,
10044                    struct spoolss_56 *r)
10045 {
10046         p->rng_fault_state = true;
10047         return WERR_NOT_SUPPORTED;
10048 }
10049
10050 /****************************************************************
10051  _spoolss_57
10052 ****************************************************************/
10053
10054 WERROR _spoolss_57(pipes_struct *p,
10055                    struct spoolss_57 *r)
10056 {
10057         p->rng_fault_state = true;
10058         return WERR_NOT_SUPPORTED;
10059 }
10060
10061 /****************************************************************
10062  _spoolss_5a
10063 ****************************************************************/
10064
10065 WERROR _spoolss_5a(pipes_struct *p,
10066                    struct spoolss_5a *r)
10067 {
10068         p->rng_fault_state = true;
10069         return WERR_NOT_SUPPORTED;
10070 }
10071
10072 /****************************************************************
10073  _spoolss_5b
10074 ****************************************************************/
10075
10076 WERROR _spoolss_5b(pipes_struct *p,
10077                    struct spoolss_5b *r)
10078 {
10079         p->rng_fault_state = true;
10080         return WERR_NOT_SUPPORTED;
10081 }
10082
10083 /****************************************************************
10084  _spoolss_5c
10085 ****************************************************************/
10086
10087 WERROR _spoolss_5c(pipes_struct *p,
10088                    struct spoolss_5c *r)
10089 {
10090         p->rng_fault_state = true;
10091         return WERR_NOT_SUPPORTED;
10092 }
10093
10094 /****************************************************************
10095  _spoolss_5d
10096 ****************************************************************/
10097
10098 WERROR _spoolss_5d(pipes_struct *p,
10099                    struct spoolss_5d *r)
10100 {
10101         p->rng_fault_state = true;
10102         return WERR_NOT_SUPPORTED;
10103 }
10104
10105 /****************************************************************
10106  _spoolss_5e
10107 ****************************************************************/
10108
10109 WERROR _spoolss_5e(pipes_struct *p,
10110                    struct spoolss_5e *r)
10111 {
10112         p->rng_fault_state = true;
10113         return WERR_NOT_SUPPORTED;
10114 }
10115
10116 /****************************************************************
10117  _spoolss_5f
10118 ****************************************************************/
10119
10120 WERROR _spoolss_5f(pipes_struct *p,
10121                    struct spoolss_5f *r)
10122 {
10123         p->rng_fault_state = true;
10124         return WERR_NOT_SUPPORTED;
10125 }
10126
10127 /****************************************************************
10128  _spoolss_60
10129 ****************************************************************/
10130
10131 WERROR _spoolss_60(pipes_struct *p,
10132                    struct spoolss_60 *r)
10133 {
10134         p->rng_fault_state = true;
10135         return WERR_NOT_SUPPORTED;
10136 }
10137
10138 /****************************************************************
10139  _spoolss_61
10140 ****************************************************************/
10141
10142 WERROR _spoolss_61(pipes_struct *p,
10143                    struct spoolss_61 *r)
10144 {
10145         p->rng_fault_state = true;
10146         return WERR_NOT_SUPPORTED;
10147 }
10148
10149 /****************************************************************
10150  _spoolss_62
10151 ****************************************************************/
10152
10153 WERROR _spoolss_62(pipes_struct *p,
10154                    struct spoolss_62 *r)
10155 {
10156         p->rng_fault_state = true;
10157         return WERR_NOT_SUPPORTED;
10158 }
10159
10160 /****************************************************************
10161  _spoolss_63
10162 ****************************************************************/
10163
10164 WERROR _spoolss_63(pipes_struct *p,
10165                    struct spoolss_63 *r)
10166 {
10167         p->rng_fault_state = true;
10168         return WERR_NOT_SUPPORTED;
10169 }
10170
10171 /****************************************************************
10172  _spoolss_64
10173 ****************************************************************/
10174
10175 WERROR _spoolss_64(pipes_struct *p,
10176                    struct spoolss_64 *r)
10177 {
10178         p->rng_fault_state = true;
10179         return WERR_NOT_SUPPORTED;
10180 }
10181
10182 /****************************************************************
10183  _spoolss_65
10184 ****************************************************************/
10185
10186 WERROR _spoolss_65(pipes_struct *p,
10187                    struct spoolss_65 *r)
10188 {
10189         p->rng_fault_state = true;
10190         return WERR_NOT_SUPPORTED;
10191 }
10192
10193 /****************************************************************
10194  _spoolss_GetCorePrinterDrivers
10195 ****************************************************************/
10196
10197 WERROR _spoolss_GetCorePrinterDrivers(pipes_struct *p,
10198                                       struct spoolss_GetCorePrinterDrivers *r)
10199 {
10200         p->rng_fault_state = true;
10201         return WERR_NOT_SUPPORTED;
10202 }
10203
10204 /****************************************************************
10205  _spoolss_67
10206 ****************************************************************/
10207
10208 WERROR _spoolss_67(pipes_struct *p,
10209                    struct spoolss_67 *r)
10210 {
10211         p->rng_fault_state = true;
10212         return WERR_NOT_SUPPORTED;
10213 }
10214
10215 /****************************************************************
10216  _spoolss_GetPrinterDriverPackagePath
10217 ****************************************************************/
10218
10219 WERROR _spoolss_GetPrinterDriverPackagePath(pipes_struct *p,
10220                                             struct spoolss_GetPrinterDriverPackagePath *r)
10221 {
10222         p->rng_fault_state = true;
10223         return WERR_NOT_SUPPORTED;
10224 }
10225
10226 /****************************************************************
10227  _spoolss_69
10228 ****************************************************************/
10229
10230 WERROR _spoolss_69(pipes_struct *p,
10231                    struct spoolss_69 *r)
10232 {
10233         p->rng_fault_state = true;
10234         return WERR_NOT_SUPPORTED;
10235 }
10236
10237 /****************************************************************
10238  _spoolss_6a
10239 ****************************************************************/
10240
10241 WERROR _spoolss_6a(pipes_struct *p,
10242                    struct spoolss_6a *r)
10243 {
10244         p->rng_fault_state = true;
10245         return WERR_NOT_SUPPORTED;
10246 }
10247
10248 /****************************************************************
10249  _spoolss_6b
10250 ****************************************************************/
10251
10252 WERROR _spoolss_6b(pipes_struct *p,
10253                    struct spoolss_6b *r)
10254 {
10255         p->rng_fault_state = true;
10256         return WERR_NOT_SUPPORTED;
10257 }
10258
10259 /****************************************************************
10260  _spoolss_6c
10261 ****************************************************************/
10262
10263 WERROR _spoolss_6c(pipes_struct *p,
10264                    struct spoolss_6c *r)
10265 {
10266         p->rng_fault_state = true;
10267         return WERR_NOT_SUPPORTED;
10268 }
10269
10270 /****************************************************************
10271  _spoolss_6d
10272 ****************************************************************/
10273
10274 WERROR _spoolss_6d(pipes_struct *p,
10275                    struct spoolss_6d *r)
10276 {
10277         p->rng_fault_state = true;
10278         return WERR_NOT_SUPPORTED;
10279 }