s3-secrets: only include secrets.h when needed.
[samba.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  *  Copyright (C) Andreas Schneider            2010.
12  *
13  *  This program is free software; you can redistribute it and/or modify
14  *  it under the terms of the GNU General Public License as published by
15  *  the Free Software Foundation; either version 3 of the License, or
16  *  (at your option) any later version.
17  *
18  *  This program is distributed in the hope that it will be useful,
19  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *  GNU General Public License for more details.
22  *
23  *  You should have received a copy of the GNU General Public License
24  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
25  */
26
27 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
28    up, all the errors returned are DOS errors, not NT status codes. */
29
30 #include "includes.h"
31 #include "nt_printing.h"
32 #include "srv_spoolss_util.h"
33 #include "../librpc/gen_ndr/srv_spoolss.h"
34 #include "../librpc/gen_ndr/cli_spoolss.h"
35 #include "rpc_client/init_spoolss.h"
36 #include "librpc/gen_ndr/messaging.h"
37 #include "librpc/gen_ndr/ndr_security.h"
38 #include "registry.h"
39 #include "registry/reg_objects.h"
40 #include "include/printing.h"
41 #include "secrets.h"
42
43 /* macros stolen from s4 spoolss server */
44 #define SPOOLSS_BUFFER_UNION(fn,info,level) \
45         ((info)?ndr_size_##fn(info, level, 0):0)
46
47 #define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,info,level,count) \
48         ((info)?ndr_size_##fn##_info(mem_ctx, level, count, info):0)
49
50 #define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,info,count) \
51         ((info)?ndr_size_##fn##_info(mem_ctx, count, info):0)
52
53 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
54
55 #undef DBGC_CLASS
56 #define DBGC_CLASS DBGC_RPC_SRV
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 /* Map generic permissions to printer object specific permissions */
75
76 const struct standard_mapping printer_std_mapping = {
77         PRINTER_READ,
78         PRINTER_WRITE,
79         PRINTER_EXECUTE,
80         PRINTER_ALL_ACCESS
81 };
82
83 /* Map generic permissions to print server object specific permissions */
84
85 const struct standard_mapping printserver_std_mapping = {
86         SERVER_READ,
87         SERVER_WRITE,
88         SERVER_EXECUTE,
89         SERVER_ALL_ACCESS
90 };
91
92 /* API table for Xcv Monitor functions */
93
94 struct xcv_api_table {
95         const char *name;
96         WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
97 };
98
99 /********************************************************************
100  * Canonicalize servername.
101  ********************************************************************/
102
103 static const char *canon_servername(const char *servername)
104 {
105         const char *pservername = servername;
106         while (*pservername == '\\') {
107                 pservername++;
108         }
109         return pservername;
110 }
111
112 /* translate between internal status numbers and NT status numbers */
113 static int nt_printj_status(int v)
114 {
115         switch (v) {
116         case LPQ_QUEUED:
117                 return 0;
118         case LPQ_PAUSED:
119                 return JOB_STATUS_PAUSED;
120         case LPQ_SPOOLING:
121                 return JOB_STATUS_SPOOLING;
122         case LPQ_PRINTING:
123                 return JOB_STATUS_PRINTING;
124         case LPQ_ERROR:
125                 return JOB_STATUS_ERROR;
126         case LPQ_DELETING:
127                 return JOB_STATUS_DELETING;
128         case LPQ_OFFLINE:
129                 return JOB_STATUS_OFFLINE;
130         case LPQ_PAPEROUT:
131                 return JOB_STATUS_PAPEROUT;
132         case LPQ_PRINTED:
133                 return JOB_STATUS_PRINTED;
134         case LPQ_DELETED:
135                 return JOB_STATUS_DELETED;
136         case LPQ_BLOCKED:
137                 return JOB_STATUS_BLOCKED_DEVQ;
138         case LPQ_USER_INTERVENTION:
139                 return JOB_STATUS_USER_INTERVENTION;
140         }
141         return 0;
142 }
143
144 static int nt_printq_status(int v)
145 {
146         switch (v) {
147         case LPQ_PAUSED:
148                 return PRINTER_STATUS_PAUSED;
149         case LPQ_QUEUED:
150         case LPQ_SPOOLING:
151         case LPQ_PRINTING:
152                 return 0;
153         }
154         return 0;
155 }
156
157 /***************************************************************************
158  Disconnect from the client
159 ****************************************************************************/
160
161 static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle)
162 {
163         WERROR result;
164         NTSTATUS status;
165
166         /*
167          * Tell the specific printing tdb we no longer want messages for this printer
168          * by deregistering our PID.
169          */
170
171         if (!print_notify_deregister_pid(snum))
172                 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
173
174         /* weird if the test succeds !!! */
175         if (smb_connections==0) {
176                 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
177                 return;
178         }
179
180         status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
181                                                   handle,
182                                                   &result);
183         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
184                 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
185                         win_errstr(result)));
186
187         /* if it's the last connection, deconnect the IPC$ share */
188         if (smb_connections==1) {
189
190                 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
191                 notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */
192
193                 messaging_deregister(smbd_messaging_context(),
194                                      MSG_PRINTER_NOTIFY2, NULL);
195
196                 /* Tell the connections db we're no longer interested in
197                  * printer notify messages. */
198
199                 serverid_register_msg_flags(
200                         messaging_server_id(smbd_messaging_context()),
201                         false, FLAG_MSG_PRINT_NOTIFY);
202         }
203
204         smb_connections--;
205 }
206
207 /****************************************************************************
208  Functions to free a printer entry datastruct.
209 ****************************************************************************/
210
211 static int printer_entry_destructor(Printer_entry *Printer)
212 {
213         if (Printer->notify.client_connected == true) {
214                 int snum = -1;
215
216                 if ( Printer->printer_type == SPLHND_SERVER) {
217                         snum = -1;
218                         srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
219                 } else if (Printer->printer_type == SPLHND_PRINTER) {
220                         snum = print_queue_snum(Printer->sharename);
221                         if (snum != -1)
222                                 srv_spoolss_replycloseprinter(snum,
223                                                 &Printer->notify.client_hnd);
224                 }
225         }
226
227         Printer->notify.flags=0;
228         Printer->notify.options=0;
229         Printer->notify.localmachine[0]='\0';
230         Printer->notify.printerlocal=0;
231         TALLOC_FREE(Printer->notify.option);
232         Printer->notify.client_connected = false;
233
234         TALLOC_FREE(Printer->devmode);
235
236         /* Remove from the internal list. */
237         DLIST_REMOVE(printers_list, Printer);
238         return 0;
239 }
240
241 /****************************************************************************
242   find printer index by handle
243 ****************************************************************************/
244
245 static Printer_entry *find_printer_index_by_hnd(struct pipes_struct *p,
246                                                 struct policy_handle *hnd)
247 {
248         Printer_entry *find_printer = NULL;
249
250         if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
251                 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
252                 return NULL;
253         }
254
255         return find_printer;
256 }
257
258 /****************************************************************************
259  Close printer index by handle.
260 ****************************************************************************/
261
262 static bool close_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
263 {
264         Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
265
266         if (!Printer) {
267                 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
268                         OUR_HANDLE(hnd)));
269                 return false;
270         }
271
272         close_policy_hnd(p, hnd);
273
274         return true;
275 }
276
277 /****************************************************************************
278  Delete a printer given a handle.
279 ****************************************************************************/
280
281 static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename)
282 {
283         char *cmd = lp_deleteprinter_cmd();
284         char *command = NULL;
285         int ret;
286         SE_PRIV se_printop = SE_PRINT_OPERATOR;
287         bool is_print_op = false;
288
289         /* can't fail if we don't try */
290
291         if ( !*cmd )
292                 return WERR_OK;
293
294         command = talloc_asprintf(ctx,
295                         "%s \"%s\"",
296                         cmd, sharename);
297         if (!command) {
298                 return WERR_NOMEM;
299         }
300         if ( token )
301                 is_print_op = user_has_privileges( token, &se_printop );
302
303         DEBUG(10,("Running [%s]\n", command));
304
305         /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
306
307         if ( is_print_op )
308                 become_root();
309
310         if ( (ret = smbrun(command, NULL)) == 0 ) {
311                 /* Tell everyone we updated smb.conf. */
312                 message_send_all(smbd_messaging_context(),
313                                  MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
314         }
315
316         if ( is_print_op )
317                 unbecome_root();
318
319         /********** END SePrintOperatorPrivlege BLOCK **********/
320
321         DEBUGADD(10,("returned [%d]\n", ret));
322
323         TALLOC_FREE(command);
324
325         if (ret != 0)
326                 return WERR_BADFID; /* What to return here? */
327
328         /* go ahead and re-read the services immediately */
329         become_root();
330         reload_services(false);
331         unbecome_root();
332
333         if ( lp_servicenumber( sharename )  > 0 )
334                 return WERR_ACCESS_DENIED;
335
336         return WERR_OK;
337 }
338
339 /****************************************************************************
340  Delete a printer given a handle.
341 ****************************************************************************/
342
343 static WERROR delete_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
344 {
345         Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
346         WERROR result;
347
348         if (!Printer) {
349                 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
350                         OUR_HANDLE(hnd)));
351                 return WERR_BADFID;
352         }
353
354         /*
355          * It turns out that Windows allows delete printer on a handle
356          * opened by an admin user, then used on a pipe handle created
357          * by an anonymous user..... but they're working on security.... riiight !
358          * JRA.
359          */
360
361         if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
362                 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
363                 return WERR_ACCESS_DENIED;
364         }
365
366         /* this does not need a become root since the access check has been
367            done on the handle already */
368
369         result = winreg_delete_printer_key(p->mem_ctx, p->server_info,
370                                            Printer->sharename, "");
371         if (!W_ERROR_IS_OK(result)) {
372                 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
373                 return WERR_BADFID;
374         }
375
376         return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
377                                    Printer->sharename );
378 }
379
380 /****************************************************************************
381  Return the snum of a printer corresponding to an handle.
382 ****************************************************************************/
383
384 static bool get_printer_snum(struct pipes_struct *p, struct policy_handle *hnd,
385                              int *number, struct share_params **params)
386 {
387         Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
388
389         if (!Printer) {
390                 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
391                         OUR_HANDLE(hnd)));
392                 return false;
393         }
394
395         switch (Printer->printer_type) {
396                 case SPLHND_PRINTER:
397                         DEBUG(4,("short name:%s\n", Printer->sharename));
398                         *number = print_queue_snum(Printer->sharename);
399                         return (*number != -1);
400                 case SPLHND_SERVER:
401                         return false;
402                 default:
403                         return false;
404         }
405 }
406
407 /****************************************************************************
408  Set printer handle type.
409  Check if it's \\server or \\server\printer
410 ****************************************************************************/
411
412 static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename)
413 {
414         DEBUG(3,("Setting printer type=%s\n", handlename));
415
416         if ( strlen(handlename) < 3 ) {
417                 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
418                 return false;
419         }
420
421         /* it's a print server */
422         if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
423                 DEBUGADD(4,("Printer is a print server\n"));
424                 Printer->printer_type = SPLHND_SERVER;
425         }
426         /* it's a printer (set_printer_hnd_name() will handle port monitors */
427         else {
428                 DEBUGADD(4,("Printer is a printer\n"));
429                 Printer->printer_type = SPLHND_PRINTER;
430         }
431
432         return true;
433 }
434
435 /****************************************************************************
436  Set printer handle name..  Accept names like \\server, \\server\printer,
437  \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port"    See
438  the MSDN docs regarding OpenPrinter() for details on the XcvData() and
439  XcvDataPort() interface.
440 ****************************************************************************/
441
442 static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
443                                  struct auth_serversupplied_info *server_info,
444                                  Printer_entry *Printer,
445                                  const char *handlename)
446 {
447         int snum;
448         int n_services=lp_numservices();
449         char *aprinter;
450         const char *printername;
451         const char *servername = NULL;
452         fstring sname;
453         bool found = false;
454         struct spoolss_PrinterInfo2 *info2 = NULL;
455         WERROR result;
456
457         DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
458                 (unsigned long)strlen(handlename)));
459
460         aprinter = CONST_DISCARD(char *, handlename);
461         if ( *handlename == '\\' ) {
462                 servername = canon_servername(handlename);
463                 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
464                         *aprinter = '\0';
465                         aprinter++;
466                 }
467                 if (!is_myname_or_ipaddr(servername)) {
468                         return false;
469                 }
470
471                 fstrcpy(Printer->servername, servername);
472         }
473
474         if (Printer->printer_type == SPLHND_SERVER) {
475                 return true;
476         }
477
478         if (Printer->printer_type != SPLHND_PRINTER) {
479                 return false;
480         }
481
482         DEBUGADD(5, ("searching for [%s]\n", aprinter));
483
484         /* check for the Port Monitor Interface */
485         if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
486                 Printer->printer_type = SPLHND_PORTMON_TCP;
487                 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
488                 found = true;
489         }
490         else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
491                 Printer->printer_type = SPLHND_PORTMON_LOCAL;
492                 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
493                 found = true;
494         }
495
496         /* Search all sharenames first as this is easier than pulling
497            the printer_info_2 off of disk. Don't use find_service() since
498            that calls out to map_username() */
499
500         /* do another loop to look for printernames */
501         for (snum = 0; !found && snum < n_services; snum++) {
502                 const char *printer = lp_const_servicename(snum);
503
504                 /* no point going on if this is not a printer */
505                 if (!(lp_snum_ok(snum) && lp_print_ok(snum))) {
506                         continue;
507                 }
508
509                 /* ignore [printers] share */
510                 if (strequal(printer, "printers")) {
511                         continue;
512                 }
513
514                 fstrcpy(sname, printer);
515                 if (strequal(aprinter, printer)) {
516                         found = true;
517                         break;
518                 }
519
520                 /* no point looking up the printer object if
521                    we aren't allowing printername != sharename */
522                 if (lp_force_printername(snum)) {
523                         continue;
524                 }
525
526                 result = winreg_get_printer(mem_ctx,
527                                             server_info,
528                                             servername,
529                                             sname,
530                                             &info2);
531                 if ( !W_ERROR_IS_OK(result) ) {
532                         DEBUG(2,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
533                                  sname, win_errstr(result)));
534                         continue;
535                 }
536
537                 printername = strrchr(info2->printername, '\\');
538                 if (printername == NULL) {
539                         printername = info2->printername;
540                 } else {
541                         printername++;
542                 }
543
544                 if (strequal(printername, aprinter)) {
545                         found = true;
546                         break;
547                 }
548
549                 DEBUGADD(10, ("printername: %s\n", printername));
550
551                 TALLOC_FREE(info2);
552         }
553
554         if ( !found ) {
555                 DEBUGADD(4,("Printer not found\n"));
556                 return false;
557         }
558
559         DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
560
561         fstrcpy(Printer->sharename, sname);
562
563         return true;
564 }
565
566 /****************************************************************************
567  Find first available printer slot. creates a printer handle for you.
568  ****************************************************************************/
569
570 static bool open_printer_hnd(struct pipes_struct *p, struct policy_handle *hnd,
571                              const char *name, uint32_t access_granted)
572 {
573         Printer_entry *new_printer;
574
575         DEBUG(10,("open_printer_hnd: name [%s]\n", name));
576
577         new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
578         if (new_printer == NULL) {
579                 return false;
580         }
581         talloc_set_destructor(new_printer, printer_entry_destructor);
582
583         if (!create_policy_hnd(p, hnd, new_printer)) {
584                 TALLOC_FREE(new_printer);
585                 return false;
586         }
587
588         /* Add to the internal list. */
589         DLIST_ADD(printers_list, new_printer);
590
591         new_printer->notify.option=NULL;
592
593         if (!set_printer_hnd_printertype(new_printer, name)) {
594                 close_printer_handle(p, hnd);
595                 return false;
596         }
597
598         if (!set_printer_hnd_name(p->mem_ctx, p->server_info, new_printer, name)) {
599                 close_printer_handle(p, hnd);
600                 return false;
601         }
602
603         new_printer->access_granted = access_granted;
604
605         DEBUG(5, ("%d printer handles active\n",
606                   (int)num_pipe_handles(p)));
607
608         return true;
609 }
610
611 /***************************************************************************
612  check to see if the client motify handle is monitoring the notification
613  given by (notify_type, notify_field).
614  **************************************************************************/
615
616 static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
617                                       uint16_t notify_field)
618 {
619         return true;
620 }
621
622 static bool is_monitoring_event(Printer_entry *p, uint16_t notify_type,
623                                 uint16_t notify_field)
624 {
625         struct spoolss_NotifyOption *option = p->notify.option;
626         uint32_t i, j;
627
628         /*
629          * Flags should always be zero when the change notify
630          * is registered by the client's spooler.  A user Win32 app
631          * might use the flags though instead of the NOTIFY_OPTION_INFO
632          * --jerry
633          */
634
635         if (!option) {
636                 return false;
637         }
638
639         if (p->notify.flags)
640                 return is_monitoring_event_flags(
641                         p->notify.flags, notify_type, notify_field);
642
643         for (i = 0; i < option->count; i++) {
644
645                 /* Check match for notify_type */
646
647                 if (option->types[i].type != notify_type)
648                         continue;
649
650                 /* Check match for field */
651
652                 for (j = 0; j < option->types[i].count; j++) {
653                         if (option->types[i].fields[j].field == notify_field) {
654                                 return true;
655                         }
656                 }
657         }
658
659         DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
660                    p->servername, p->sharename, notify_type, notify_field));
661
662         return false;
663 }
664
665 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
666         _data->data.integer[0] = _integer; \
667         _data->data.integer[1] = 0;
668
669
670 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
671         _data->data.string.string = talloc_strdup(mem_ctx, _p); \
672         if (!_data->data.string.string) {\
673                 _data->data.string.size = 0; \
674         } \
675         _data->data.string.size = strlen_m_term(_p) * 2;
676
677 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
678         _data->data.devmode.devmode = _devmode;
679
680 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _sd) \
681         _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
682         if (!_data->data.sd.sd) { \
683                 _data->data.sd.sd_size = 0; \
684         } \
685         _data->data.sd.sd_size = \
686                 ndr_size_security_descriptor(_data->data.sd.sd, 0);
687
688 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
689                                    struct tm *t,
690                                    const char **pp,
691                                    uint32_t *plen)
692 {
693         struct spoolss_Time st;
694         uint32_t len = 16;
695         char *p;
696
697         if (!init_systemtime(&st, t)) {
698                 return;
699         }
700
701         p = talloc_array(mem_ctx, char, len);
702         if (!p) {
703                 return;
704         }
705
706         /*
707          * Systemtime must be linearized as a set of UINT16's.
708          * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
709          */
710
711         SSVAL(p, 0, st.year);
712         SSVAL(p, 2, st.month);
713         SSVAL(p, 4, st.day_of_week);
714         SSVAL(p, 6, st.day);
715         SSVAL(p, 8, st.hour);
716         SSVAL(p, 10, st.minute);
717         SSVAL(p, 12, st.second);
718         SSVAL(p, 14, st.millisecond);
719
720         *pp = p;
721         *plen = len;
722 }
723
724 /* Convert a notification message to a struct spoolss_Notify */
725
726 static void notify_one_value(struct spoolss_notify_msg *msg,
727                              struct spoolss_Notify *data,
728                              TALLOC_CTX *mem_ctx)
729 {
730         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
731 }
732
733 static void notify_string(struct spoolss_notify_msg *msg,
734                           struct spoolss_Notify *data,
735                           TALLOC_CTX *mem_ctx)
736 {
737         /* The length of the message includes the trailing \0 */
738
739         data->data.string.size = msg->len * 2;
740         data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
741         if (!data->data.string.string) {
742                 data->data.string.size = 0;
743                 return;
744         }
745 }
746
747 static void notify_system_time(struct spoolss_notify_msg *msg,
748                                struct spoolss_Notify *data,
749                                TALLOC_CTX *mem_ctx)
750 {
751         data->data.string.string = NULL;
752         data->data.string.size = 0;
753
754         if (msg->len != sizeof(time_t)) {
755                 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
756                           msg->len));
757                 return;
758         }
759
760         init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
761                                &data->data.string.string,
762                                &data->data.string.size);
763 }
764
765 struct notify2_message_table {
766         const char *name;
767         void (*fn)(struct spoolss_notify_msg *msg,
768                    struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
769 };
770
771 static struct notify2_message_table printer_notify_table[] = {
772         /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
773         /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
774         /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
775         /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
776         /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
777         /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
778         /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
779         /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
780         /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
781         /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
782         /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
783         /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
784         /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
785         /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
786         /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
787         /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
788         /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
789         /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
790         /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
791 };
792
793 static struct notify2_message_table job_notify_table[] = {
794         /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
795         /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
796         /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
797         /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
798         /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
799         /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
800         /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
801         /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
802         /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
803         /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
804         /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
805         /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
806         /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
807         /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
808         /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
809         /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
810         /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
811         /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
812         /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
813         /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
814         /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
815         /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
816         /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
817         /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
818 };
819
820
821 /***********************************************************************
822  Allocate talloc context for container object
823  **********************************************************************/
824
825 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
826 {
827         if ( !ctr )
828                 return;
829
830         ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
831
832         return;
833 }
834
835 /***********************************************************************
836  release all allocated memory and zero out structure
837  **********************************************************************/
838
839 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
840 {
841         if ( !ctr )
842                 return;
843
844         if ( ctr->ctx )
845                 talloc_destroy(ctr->ctx);
846
847         ZERO_STRUCTP(ctr);
848
849         return;
850 }
851
852 /***********************************************************************
853  **********************************************************************/
854
855 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
856 {
857         if ( !ctr )
858                 return NULL;
859
860         return ctr->ctx;
861 }
862
863 /***********************************************************************
864  **********************************************************************/
865
866 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
867 {
868         if ( !ctr || !ctr->msg_groups )
869                 return NULL;
870
871         if ( idx >= ctr->num_groups )
872                 return NULL;
873
874         return &ctr->msg_groups[idx];
875
876 }
877
878 /***********************************************************************
879  How many groups of change messages do we have ?
880  **********************************************************************/
881
882 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
883 {
884         if ( !ctr )
885                 return 0;
886
887         return ctr->num_groups;
888 }
889
890 /***********************************************************************
891  Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
892  **********************************************************************/
893
894 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
895 {
896         SPOOLSS_NOTIFY_MSG_GROUP        *groups = NULL;
897         SPOOLSS_NOTIFY_MSG_GROUP        *msg_grp = NULL;
898         SPOOLSS_NOTIFY_MSG              *msg_list = NULL;
899         int                             i, new_slot;
900
901         if ( !ctr || !msg )
902                 return 0;
903
904         /* loop over all groups looking for a matching printer name */
905
906         for ( i=0; i<ctr->num_groups; i++ ) {
907                 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
908                         break;
909         }
910
911         /* add a new group? */
912
913         if ( i == ctr->num_groups ) {
914                 ctr->num_groups++;
915
916                 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
917                         DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
918                         return 0;
919                 }
920                 ctr->msg_groups = groups;
921
922                 /* clear the new entry and set the printer name */
923
924                 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
925                 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
926         }
927
928         /* add the change messages; 'i' is the correct index now regardless */
929
930         msg_grp = &ctr->msg_groups[i];
931
932         msg_grp->num_msgs++;
933
934         if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
935                 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
936                 return 0;
937         }
938         msg_grp->msgs = msg_list;
939
940         new_slot = msg_grp->num_msgs-1;
941         memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
942
943         /* need to allocate own copy of data */
944
945         if ( msg->len != 0 )
946                 msg_grp->msgs[new_slot].notify.data = (char *)
947                         TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
948
949         return ctr->num_groups;
950 }
951
952 static void construct_info_data(struct spoolss_Notify *info_data,
953                                 enum spoolss_NotifyType type,
954                                 uint16_t field, int id);
955
956 /***********************************************************************
957  Send a change notication message on all handles which have a call
958  back registered
959  **********************************************************************/
960
961 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
962 {
963         Printer_entry            *p;
964         TALLOC_CTX               *mem_ctx = notify_ctr_getctx( ctr );
965         SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
966         SPOOLSS_NOTIFY_MSG       *messages;
967         int                      sending_msg_count;
968
969         if ( !msg_group ) {
970                 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
971                 return;
972         }
973
974         messages = msg_group->msgs;
975
976         if ( !messages ) {
977                 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
978                 return;
979         }
980
981         DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
982
983         /* loop over all printers */
984
985         for (p = printers_list; p; p = p->next) {
986                 struct spoolss_Notify *notifies;
987                 uint32_t count = 0;
988                 uint32_t id;
989                 int     i;
990
991                 /* Is there notification on this handle? */
992
993                 if ( !p->notify.client_connected )
994                         continue;
995
996                 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
997
998                 /* For this printer?  Print servers always receive
999                    notifications. */
1000
1001                 if ( ( p->printer_type == SPLHND_PRINTER )  &&
1002                     ( !strequal(msg_group->printername, p->sharename) ) )
1003                         continue;
1004
1005                 DEBUG(10,("Our printer\n"));
1006
1007                 /* allocate the max entries possible */
1008
1009                 notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
1010                 if (!notifies) {
1011                         return;
1012                 }
1013
1014                 /* build the array of change notifications */
1015
1016                 sending_msg_count = 0;
1017
1018                 for ( i=0; i<msg_group->num_msgs; i++ ) {
1019                         SPOOLSS_NOTIFY_MSG      *msg = &messages[i];
1020
1021                         /* Are we monitoring this event? */
1022
1023                         if (!is_monitoring_event(p, msg->type, msg->field))
1024                                 continue;
1025
1026                         sending_msg_count++;
1027
1028
1029                         DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1030                                 msg->type, msg->field, p->sharename));
1031
1032                         /*
1033                          * if the is a printer notification handle and not a job notification
1034                          * type, then set the id to 0.  Other wise just use what was specified
1035                          * in the message.
1036                          *
1037                          * When registering change notification on a print server handle
1038                          * we always need to send back the id (snum) matching the printer
1039                          * for which the change took place.  For change notify registered
1040                          * on a printer handle, this does not matter and the id should be 0.
1041                          *
1042                          * --jerry
1043                          */
1044
1045                         if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1046                                 id = 0;
1047                         else
1048                                 id = msg->id;
1049
1050
1051                         /* Convert unix jobid to smb jobid */
1052
1053                         if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1054                                 id = sysjob_to_jobid(msg->id);
1055
1056                                 if (id == -1) {
1057                                         DEBUG(3, ("no such unix jobid %d\n", msg->id));
1058                                         goto done;
1059                                 }
1060                         }
1061
1062                         construct_info_data( &notifies[count], msg->type, msg->field, id );
1063
1064                         switch(msg->type) {
1065                         case PRINTER_NOTIFY_TYPE:
1066                                 if ( printer_notify_table[msg->field].fn )
1067                                         printer_notify_table[msg->field].fn(msg, &notifies[count], mem_ctx);
1068                                 break;
1069
1070                         case JOB_NOTIFY_TYPE:
1071                                 if ( job_notify_table[msg->field].fn )
1072                                         job_notify_table[msg->field].fn(msg, &notifies[count], mem_ctx);
1073                                 break;
1074
1075                         default:
1076                                 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1077                                 goto done;
1078                         }
1079
1080                         count++;
1081                 }
1082
1083                 if ( sending_msg_count ) {
1084                         NTSTATUS status;
1085                         WERROR werr;
1086                         union spoolss_ReplyPrinterInfo info;
1087                         struct spoolss_NotifyInfo info0;
1088                         uint32_t reply_result;
1089
1090                         info0.version   = 0x2;
1091                         info0.flags     = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1092                         info0.count     = count;
1093                         info0.notifies  = notifies;
1094
1095                         info.info0 = &info0;
1096
1097                         status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
1098                                                                      &p->notify.client_hnd,
1099                                                                      p->notify.change, /* color */
1100                                                                      p->notify.flags,
1101                                                                      &reply_result,
1102                                                                      0, /* reply_type, must be 0 */
1103                                                                      info,
1104                                                                      &werr);
1105                         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1106                                 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1107                                         notify_cli_pipe->srv_name_slash,
1108                                         win_errstr(werr)));
1109                         }
1110                         switch (reply_result) {
1111                                 case 0:
1112                                         break;
1113                                 case PRINTER_NOTIFY_INFO_DISCARDED:
1114                                 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1115                                 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1116                                         break;
1117                                 default:
1118                                         break;
1119                         }
1120                 }
1121         }
1122
1123 done:
1124         DEBUG(8,("send_notify2_changes: Exit...\n"));
1125         return;
1126 }
1127
1128 /***********************************************************************
1129  **********************************************************************/
1130
1131 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1132 {
1133
1134         uint32_t tv_sec, tv_usec;
1135         size_t offset = 0;
1136
1137         /* Unpack message */
1138
1139         offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
1140                              msg->printer);
1141
1142         offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
1143                                 &tv_sec, &tv_usec,
1144                                 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1145
1146         if (msg->len == 0)
1147                 tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
1148                            &msg->notify.value[0], &msg->notify.value[1]);
1149         else
1150                 tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
1151                            &msg->len, &msg->notify.data);
1152
1153         DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1154                   msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1155
1156         tv->tv_sec = tv_sec;
1157         tv->tv_usec = tv_usec;
1158
1159         if (msg->len == 0)
1160                 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1161                           msg->notify.value[1]));
1162         else
1163                 dump_data(3, (uint8_t *)msg->notify.data, msg->len);
1164
1165         return true;
1166 }
1167
1168 /********************************************************************
1169  Receive a notify2 message list
1170  ********************************************************************/
1171
1172 static void receive_notify2_message_list(struct messaging_context *msg,
1173                                          void *private_data,
1174                                          uint32_t msg_type,
1175                                          struct server_id server_id,
1176                                          DATA_BLOB *data)
1177 {
1178         size_t                  msg_count, i;
1179         char                    *buf = (char *)data->data;
1180         char                    *msg_ptr;
1181         size_t                  msg_len;
1182         SPOOLSS_NOTIFY_MSG      notify;
1183         SPOOLSS_NOTIFY_MSG_CTR  messages;
1184         int                     num_groups;
1185
1186         if (data->length < 4) {
1187                 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1188                 return;
1189         }
1190
1191         msg_count = IVAL(buf, 0);
1192         msg_ptr = buf + 4;
1193
1194         DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1195
1196         if (msg_count == 0) {
1197                 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1198                 return;
1199         }
1200
1201         /* initialize the container */
1202
1203         ZERO_STRUCT( messages );
1204         notify_msg_ctr_init( &messages );
1205
1206         /*
1207          * build message groups for each printer identified
1208          * in a change_notify msg.  Remember that a PCN message
1209          * includes the handle returned for the srv_spoolss_replyopenprinter()
1210          * call.  Therefore messages are grouped according to printer handle.
1211          */
1212
1213         for ( i=0; i<msg_count; i++ ) {
1214                 struct timeval msg_tv;
1215
1216                 if (msg_ptr + 4 - buf > data->length) {
1217                         DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1218                         return;
1219                 }
1220
1221                 msg_len = IVAL(msg_ptr,0);
1222                 msg_ptr += 4;
1223
1224                 if (msg_ptr + msg_len - buf > data->length) {
1225                         DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1226                         return;
1227                 }
1228
1229                 /* unpack messages */
1230
1231                 ZERO_STRUCT( notify );
1232                 notify2_unpack_msg( &notify, &msg_tv, msg_ptr, msg_len );
1233                 msg_ptr += msg_len;
1234
1235                 /* add to correct list in container */
1236
1237                 notify_msg_ctr_addmsg( &messages, &notify );
1238
1239                 /* free memory that might have been allocated by notify2_unpack_msg() */
1240
1241                 if ( notify.len != 0 )
1242                         SAFE_FREE( notify.notify.data );
1243         }
1244
1245         /* process each group of messages */
1246
1247         num_groups = notify_msg_ctr_numgroups( &messages );
1248         for ( i=0; i<num_groups; i++ )
1249                 send_notify2_changes( &messages, i );
1250
1251
1252         /* cleanup */
1253
1254         DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1255                 (uint32_t)msg_count ));
1256
1257         notify_msg_ctr_destroy( &messages );
1258
1259         return;
1260 }
1261
1262 /********************************************************************
1263  Send a message to ourself about new driver being installed
1264  so we can upgrade the information for each printer bound to this
1265  driver
1266  ********************************************************************/
1267
1268 static bool srv_spoolss_drv_upgrade_printer(const char *drivername)
1269 {
1270         int len = strlen(drivername);
1271
1272         if (!len)
1273                 return false;
1274
1275         DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1276                 drivername));
1277
1278         messaging_send_buf(smbd_messaging_context(),
1279                            messaging_server_id(smbd_messaging_context()),
1280                            MSG_PRINTER_DRVUPGRADE,
1281                            (uint8_t *)drivername, len+1);
1282
1283         return true;
1284 }
1285
1286 /**********************************************************************
1287  callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1288  over all printers, upgrading ones as necessary
1289  **********************************************************************/
1290
1291 void do_drv_upgrade_printer(struct messaging_context *msg,
1292                             void *private_data,
1293                             uint32_t msg_type,
1294                             struct server_id server_id,
1295                             DATA_BLOB *data)
1296 {
1297         TALLOC_CTX *tmp_ctx;
1298         struct auth_serversupplied_info *server_info = NULL;
1299         struct spoolss_PrinterInfo2 *pinfo2;
1300         NTSTATUS status;
1301         WERROR result;
1302         const char *drivername;
1303         int snum;
1304         int n_services = lp_numservices();
1305         size_t len;
1306
1307         tmp_ctx = talloc_new(NULL);
1308         if (!tmp_ctx) return;
1309
1310         status = make_server_info_system(tmp_ctx, &server_info);
1311         if (!NT_STATUS_IS_OK(status)) {
1312                 DEBUG(0, ("do_drv_upgrade_printer: "
1313                           "Could not create system server_info\n"));
1314                 goto done;
1315         }
1316
1317         len = MIN(data->length,sizeof(drivername)-1);
1318         drivername = talloc_strndup(tmp_ctx, (const char *)data->data, len);
1319         if (!drivername) {
1320                 DEBUG(0, ("do_drv_upgrade_printer: Out of memoery ?!\n"));
1321                 goto done;
1322         }
1323
1324         DEBUG(10, ("do_drv_upgrade_printer: "
1325                    "Got message for new driver [%s]\n", drivername));
1326
1327         /* Iterate the printer list */
1328
1329         for (snum = 0; snum < n_services; snum++) {
1330                 if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
1331                         continue;
1332                 }
1333
1334                 result = winreg_get_printer(tmp_ctx, server_info, NULL,
1335                                             lp_const_servicename(snum),
1336                                             &pinfo2);
1337
1338                 if (!W_ERROR_IS_OK(result)) {
1339                         continue;
1340                 }
1341
1342                 if (!pinfo2->drivername) {
1343                         continue;
1344                 }
1345
1346                 if (strcmp(drivername, pinfo2->drivername) != 0) {
1347                         continue;
1348                 }
1349
1350                 DEBUG(6,("Updating printer [%s]\n", pinfo2->printername));
1351
1352                 /* all we care about currently is the change_id */
1353                 result = winreg_printer_update_changeid(tmp_ctx,
1354                                                         server_info,
1355                                                         pinfo2->printername);
1356
1357                 if (!W_ERROR_IS_OK(result)) {
1358                         DEBUG(3, ("do_drv_upgrade_printer: "
1359                                   "Failed to update changeid [%s]\n",
1360                                   win_errstr(result)));
1361                 }
1362         }
1363
1364         /* all done */
1365 done:
1366         talloc_free(tmp_ctx);
1367 }
1368
1369 /********************************************************************
1370  Update the cache for all printq's with a registered client
1371  connection
1372  ********************************************************************/
1373
1374 void update_monitored_printq_cache( void )
1375 {
1376         Printer_entry *printer = printers_list;
1377         int snum;
1378
1379         /* loop through all printers and update the cache where
1380            client_connected == true */
1381         while ( printer )
1382         {
1383                 if ( (printer->printer_type == SPLHND_PRINTER)
1384                         && printer->notify.client_connected )
1385                 {
1386                         snum = print_queue_snum(printer->sharename);
1387                         print_queue_status( snum, NULL, NULL );
1388                 }
1389
1390                 printer = printer->next;
1391         }
1392
1393         return;
1394 }
1395
1396 /****************************************************************
1397  _spoolss_OpenPrinter
1398 ****************************************************************/
1399
1400 WERROR _spoolss_OpenPrinter(struct pipes_struct *p,
1401                             struct spoolss_OpenPrinter *r)
1402 {
1403         struct spoolss_OpenPrinterEx e;
1404         WERROR werr;
1405
1406         ZERO_STRUCT(e.in.userlevel);
1407
1408         e.in.printername        = r->in.printername;
1409         e.in.datatype           = r->in.datatype;
1410         e.in.devmode_ctr        = r->in.devmode_ctr;
1411         e.in.access_mask        = r->in.access_mask;
1412         e.in.level              = 0;
1413
1414         e.out.handle            = r->out.handle;
1415
1416         werr = _spoolss_OpenPrinterEx(p, &e);
1417
1418         if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1419                 /* OpenPrinterEx returns this for a bad
1420                  * printer name. We must return WERR_INVALID_PRINTER_NAME
1421                  * instead.
1422                  */
1423                 werr = WERR_INVALID_PRINTER_NAME;
1424         }
1425
1426         return werr;
1427 }
1428
1429 static WERROR copy_devicemode(TALLOC_CTX *mem_ctx,
1430                               struct spoolss_DeviceMode *orig,
1431                               struct spoolss_DeviceMode **dest)
1432 {
1433         struct spoolss_DeviceMode *dm;
1434
1435         dm = talloc(mem_ctx, struct spoolss_DeviceMode);
1436         if (!dm) {
1437                 return WERR_NOMEM;
1438         }
1439
1440         /* copy all values, then duplicate strings and structs */
1441         *dm = *orig;
1442
1443         dm->devicename = talloc_strdup(dm, orig->devicename);
1444         if (!dm->devicename) {
1445                 return WERR_NOMEM;
1446         }
1447         dm->formname = talloc_strdup(dm, orig->formname);
1448         if (!dm->formname) {
1449                 return WERR_NOMEM;
1450         }
1451         if (orig->driverextra_data.data) {
1452                 dm->driverextra_data.data =
1453                         (uint8_t *) talloc_memdup(dm, orig->driverextra_data.data,
1454                                         orig->driverextra_data.length);
1455                 if (!dm->driverextra_data.data) {
1456                         return WERR_NOMEM;
1457                 }
1458         }
1459
1460         *dest = dm;
1461         return WERR_OK;
1462 }
1463
1464 /****************************************************************
1465  _spoolss_OpenPrinterEx
1466 ****************************************************************/
1467
1468 WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
1469                               struct spoolss_OpenPrinterEx *r)
1470 {
1471         int snum;
1472         Printer_entry *Printer=NULL;
1473
1474         if (!r->in.printername) {
1475                 return WERR_INVALID_PARAM;
1476         }
1477
1478         /* some sanity check because you can open a printer or a print server */
1479         /* aka: \\server\printer or \\server */
1480
1481         DEBUGADD(3,("checking name: %s\n", r->in.printername));
1482
1483         if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
1484                 DEBUG(0,("_spoolss_OpenPrinterEx: Cannot open a printer handle "
1485                         " for printer %s\n", r->in.printername));
1486                 ZERO_STRUCTP(r->out.handle);
1487                 return WERR_INVALID_PARAM;
1488         }
1489
1490         Printer = find_printer_index_by_hnd(p, r->out.handle);
1491         if ( !Printer ) {
1492                 DEBUG(0,("_spoolss_OpenPrinterEx: logic error.  Can't find printer "
1493                         "handle we created for printer %s\n", r->in.printername));
1494                 close_printer_handle(p, r->out.handle);
1495                 ZERO_STRUCTP(r->out.handle);
1496                 return WERR_INVALID_PARAM;
1497         }
1498
1499         /*
1500          * First case: the user is opening the print server:
1501          *
1502          * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1503          * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1504          *
1505          * Then both Win2k and WinNT clients try an OpenPrinterEx with
1506          * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1507          * or if the user is listed in the smb.conf printer admin parameter.
1508          *
1509          * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1510          * client view printer folder, but does not show the MSAPW.
1511          *
1512          * Note: this test needs code to check access rights here too. Jeremy
1513          * could you look at this?
1514          *
1515          * Second case: the user is opening a printer:
1516          * NT doesn't let us connect to a printer if the connecting user
1517          * doesn't have print permission.
1518          *
1519          * Third case: user is opening a Port Monitor
1520          * access checks same as opening a handle to the print server.
1521          */
1522
1523         switch (Printer->printer_type )
1524         {
1525         case SPLHND_SERVER:
1526         case SPLHND_PORTMON_TCP:
1527         case SPLHND_PORTMON_LOCAL:
1528                 /* Printserver handles use global struct... */
1529
1530                 snum = -1;
1531
1532                 /* Map standard access rights to object specific access rights */
1533
1534                 se_map_standard(&r->in.access_mask,
1535                                 &printserver_std_mapping);
1536
1537                 /* Deny any object specific bits that don't apply to print
1538                    servers (i.e printer and job specific bits) */
1539
1540                 r->in.access_mask &= SEC_MASK_SPECIFIC;
1541
1542                 if (r->in.access_mask &
1543                     ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1544                         DEBUG(3, ("access DENIED for non-printserver bits\n"));
1545                         close_printer_handle(p, r->out.handle);
1546                         ZERO_STRUCTP(r->out.handle);
1547                         return WERR_ACCESS_DENIED;
1548                 }
1549
1550                 /* Allow admin access */
1551
1552                 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1553                 {
1554                         SE_PRIV se_printop = SE_PRINT_OPERATOR;
1555
1556                         if (!lp_ms_add_printer_wizard()) {
1557                                 close_printer_handle(p, r->out.handle);
1558                                 ZERO_STRUCTP(r->out.handle);
1559                                 return WERR_ACCESS_DENIED;
1560                         }
1561
1562                         /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1563                            and not a printer admin, then fail */
1564
1565                         if ((p->server_info->utok.uid != sec_initial_uid()) &&
1566                             !user_has_privileges(p->server_info->ptok,
1567                                                  &se_printop ) &&
1568                             !token_contains_name_in_list(
1569                                     uidtoname(p->server_info->utok.uid),
1570                                     p->server_info->info3->base.domain.string,
1571                                     NULL,
1572                                     p->server_info->ptok,
1573                                     lp_printer_admin(snum))) {
1574                                 close_printer_handle(p, r->out.handle);
1575                                 ZERO_STRUCTP(r->out.handle);
1576                                 return WERR_ACCESS_DENIED;
1577                         }
1578
1579                         r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1580                 }
1581                 else
1582                 {
1583                         r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1584                 }
1585
1586                 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1587                         ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1588
1589                 /* We fall through to return WERR_OK */
1590                 break;
1591
1592         case SPLHND_PRINTER:
1593                 /* NT doesn't let us connect to a printer if the connecting user
1594                    doesn't have print permission.  */
1595
1596                 if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1597                         close_printer_handle(p, r->out.handle);
1598                         ZERO_STRUCTP(r->out.handle);
1599                         return WERR_BADFID;
1600                 }
1601
1602                 if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
1603                         r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1604                 }
1605
1606                 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1607
1608                 /* map an empty access mask to the minimum access mask */
1609                 if (r->in.access_mask == 0x0)
1610                         r->in.access_mask = PRINTER_ACCESS_USE;
1611
1612                 /*
1613                  * If we are not serving the printer driver for this printer,
1614                  * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE.  This
1615                  * will keep NT clients happy  --jerry
1616                  */
1617
1618                 if (lp_use_client_driver(snum)
1619                         && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1620                 {
1621                         r->in.access_mask = PRINTER_ACCESS_USE;
1622                 }
1623
1624                 /* check smb.conf parameters and the the sec_desc */
1625
1626                 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1627                         DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1628                         ZERO_STRUCTP(r->out.handle);
1629                         return WERR_ACCESS_DENIED;
1630                 }
1631
1632                 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1633                                    p->server_info->ptok, snum) ||
1634                     !print_access_check(p->server_info, snum,
1635                                         r->in.access_mask)) {
1636                         DEBUG(3, ("access DENIED for printer open\n"));
1637                         close_printer_handle(p, r->out.handle);
1638                         ZERO_STRUCTP(r->out.handle);
1639                         return WERR_ACCESS_DENIED;
1640                 }
1641
1642                 if ((r->in.access_mask & SEC_MASK_SPECIFIC)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1643                         DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1644                         close_printer_handle(p, r->out.handle);
1645                         ZERO_STRUCTP(r->out.handle);
1646                         return WERR_ACCESS_DENIED;
1647                 }
1648
1649                 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1650                         r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1651                 else
1652                         r->in.access_mask = PRINTER_ACCESS_USE;
1653
1654                 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1655                         ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1656
1657                 winreg_create_printer(p->mem_ctx,
1658                                       p->server_info,
1659                                       Printer->servername,
1660                                       lp_const_servicename(snum));
1661
1662                 break;
1663
1664         default:
1665                 /* sanity check to prevent programmer error */
1666                 ZERO_STRUCTP(r->out.handle);
1667                 return WERR_BADFID;
1668         }
1669
1670         Printer->access_granted = r->in.access_mask;
1671
1672         /*
1673          * If the client sent a devmode in the OpenPrinter() call, then
1674          * save it here in case we get a job submission on this handle
1675          */
1676
1677          if ((Printer->printer_type != SPLHND_SERVER) &&
1678              r->in.devmode_ctr.devmode) {
1679                 copy_devicemode(NULL, r->in.devmode_ctr.devmode,
1680                                 &Printer->devmode);
1681          }
1682
1683 #if 0   /* JERRY -- I'm doubtful this is really effective */
1684         /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1685            optimization in Windows 2000 clients  --jerry */
1686
1687         if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1688                 && (RA_WIN2K == get_remote_arch()) )
1689         {
1690                 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1691                 sys_usleep( 500000 );
1692         }
1693 #endif
1694
1695         return WERR_OK;
1696 }
1697
1698 /****************************************************************
1699  _spoolss_ClosePrinter
1700 ****************************************************************/
1701
1702 WERROR _spoolss_ClosePrinter(struct pipes_struct *p,
1703                              struct spoolss_ClosePrinter *r)
1704 {
1705         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1706
1707         if (Printer && Printer->document_started) {
1708                 struct spoolss_EndDocPrinter e;
1709
1710                 e.in.handle = r->in.handle;
1711
1712                 _spoolss_EndDocPrinter(p, &e);
1713         }
1714
1715         if (!close_printer_handle(p, r->in.handle))
1716                 return WERR_BADFID;
1717
1718         /* clear the returned printer handle.  Observed behavior
1719            from Win2k server.  Don't think this really matters.
1720            Previous code just copied the value of the closed
1721            handle.    --jerry */
1722
1723         ZERO_STRUCTP(r->out.handle);
1724
1725         return WERR_OK;
1726 }
1727
1728 /****************************************************************
1729  _spoolss_DeletePrinter
1730 ****************************************************************/
1731
1732 WERROR _spoolss_DeletePrinter(struct pipes_struct *p,
1733                               struct spoolss_DeletePrinter *r)
1734 {
1735         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1736         WERROR result;
1737         int snum;
1738
1739         if (Printer && Printer->document_started) {
1740                 struct spoolss_EndDocPrinter e;
1741
1742                 e.in.handle = r->in.handle;
1743
1744                 _spoolss_EndDocPrinter(p, &e);
1745         }
1746
1747         if (get_printer_snum(p, r->in.handle, &snum, NULL)) {
1748                 winreg_delete_printer_key(p->mem_ctx,
1749                                           p->server_info,
1750                                           lp_const_servicename(snum),
1751                                           "");
1752         }
1753
1754         result = delete_printer_handle(p, r->in.handle);
1755
1756         return result;
1757 }
1758
1759 /*******************************************************************
1760  * static function to lookup the version id corresponding to an
1761  * long architecture string
1762  ******************************************************************/
1763
1764 static const struct print_architecture_table_node archi_table[]= {
1765
1766         {"Windows 4.0",          SPL_ARCH_WIN40,        0 },
1767         {"Windows NT x86",       SPL_ARCH_W32X86,       2 },
1768         {"Windows NT R4000",     SPL_ARCH_W32MIPS,      2 },
1769         {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA,     2 },
1770         {"Windows NT PowerPC",   SPL_ARCH_W32PPC,       2 },
1771         {"Windows IA64",         SPL_ARCH_IA64,         3 },
1772         {"Windows x64",          SPL_ARCH_X64,          3 },
1773         {NULL,                   "",            -1 }
1774 };
1775
1776 static int get_version_id(const char *arch)
1777 {
1778         int i;
1779
1780         for (i=0; archi_table[i].long_archi != NULL; i++)
1781         {
1782                 if (strcmp(arch, archi_table[i].long_archi) == 0)
1783                         return (archi_table[i].version);
1784         }
1785
1786         return -1;
1787 }
1788
1789 /****************************************************************
1790  _spoolss_DeletePrinterDriver
1791 ****************************************************************/
1792
1793 WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
1794                                     struct spoolss_DeletePrinterDriver *r)
1795 {
1796
1797         struct spoolss_DriverInfo8 *info = NULL;
1798         struct spoolss_DriverInfo8 *info_win2k = NULL;
1799         int                             version;
1800         WERROR                          status;
1801         SE_PRIV                         se_printop = SE_PRINT_OPERATOR;
1802
1803         /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1804            and not a printer admin, then fail */
1805
1806         if ( (p->server_info->utok.uid != sec_initial_uid())
1807                 && !user_has_privileges(p->server_info->ptok, &se_printop )
1808                 && !token_contains_name_in_list(
1809                         uidtoname(p->server_info->utok.uid),
1810                         p->server_info->info3->base.domain.string,
1811                         NULL,
1812                         p->server_info->ptok,
1813                         lp_printer_admin(-1)) )
1814         {
1815                 return WERR_ACCESS_DENIED;
1816         }
1817
1818         /* check that we have a valid driver name first */
1819
1820         if ((version = get_version_id(r->in.architecture)) == -1)
1821                 return WERR_INVALID_ENVIRONMENT;
1822
1823         status = winreg_get_driver(p->mem_ctx, p->server_info,
1824                                    r->in.architecture, r->in.driver,
1825                                    version, &info);
1826         if (!W_ERROR_IS_OK(status)) {
1827                 /* try for Win2k driver if "Windows NT x86" */
1828
1829                 if ( version == 2 ) {
1830                         version = 3;
1831
1832                         status = winreg_get_driver(p->mem_ctx, p->server_info,
1833                                                    r->in.architecture,
1834                                                    r->in.driver,
1835                                                    version, &info);
1836                         if (!W_ERROR_IS_OK(status)) {
1837                                 status = WERR_UNKNOWN_PRINTER_DRIVER;
1838                                 goto done;
1839                         }
1840                 }
1841                 /* otherwise it was a failure */
1842                 else {
1843                         status = WERR_UNKNOWN_PRINTER_DRIVER;
1844                         goto done;
1845                 }
1846
1847         }
1848
1849         if (printer_driver_in_use(p->mem_ctx, p->server_info, info)) {
1850                 status = WERR_PRINTER_DRIVER_IN_USE;
1851                 goto done;
1852         }
1853
1854         if (version == 2) {
1855                 status = winreg_get_driver(p->mem_ctx, p->server_info,
1856                                            r->in.architecture,
1857                                            r->in.driver, 3, &info_win2k);
1858                 if (W_ERROR_IS_OK(status)) {
1859                         /* if we get to here, we now have 2 driver info structures to remove */
1860                         /* remove the Win2k driver first*/
1861
1862                         status = winreg_del_driver(p->mem_ctx,
1863                                                    p->server_info,
1864                                                    info_win2k, 3);
1865                         talloc_free(info_win2k);
1866
1867                         /* this should not have failed---if it did, report to client */
1868                         if (!W_ERROR_IS_OK(status)) {
1869                                 goto done;
1870                         }
1871                 }
1872         }
1873
1874         status = winreg_del_driver(p->mem_ctx, p->server_info, info, version);
1875
1876 done:
1877         talloc_free(info);
1878
1879         return status;
1880 }
1881
1882 /****************************************************************
1883  _spoolss_DeletePrinterDriverEx
1884 ****************************************************************/
1885
1886 WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
1887                                       struct spoolss_DeletePrinterDriverEx *r)
1888 {
1889         struct spoolss_DriverInfo8      *info = NULL;
1890         struct spoolss_DriverInfo8      *info_win2k = NULL;
1891         int                             version;
1892         bool                            delete_files;
1893         WERROR                          status;
1894         SE_PRIV                         se_printop = SE_PRINT_OPERATOR;
1895
1896         /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1897            and not a printer admin, then fail */
1898
1899         if ( (p->server_info->utok.uid != sec_initial_uid())
1900                 && !user_has_privileges(p->server_info->ptok, &se_printop )
1901                 && !token_contains_name_in_list(
1902                         uidtoname(p->server_info->utok.uid),
1903                         p->server_info->info3->base.domain.string,
1904                         NULL,
1905                         p->server_info->ptok, lp_printer_admin(-1)) )
1906         {
1907                 return WERR_ACCESS_DENIED;
1908         }
1909
1910         /* check that we have a valid driver name first */
1911         if ((version = get_version_id(r->in.architecture)) == -1) {
1912                 /* this is what NT returns */
1913                 return WERR_INVALID_ENVIRONMENT;
1914         }
1915
1916         if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
1917                 version = r->in.version;
1918
1919         status = winreg_get_driver(p->mem_ctx, p->server_info,
1920                                    r->in.architecture, r->in.driver,
1921                                    version, &info);
1922         if (!W_ERROR_IS_OK(status)) {
1923                 status = WERR_UNKNOWN_PRINTER_DRIVER;
1924
1925                 /*
1926                  * if the client asked for a specific version,
1927                  * or this is something other than Windows NT x86,
1928                  * then we've failed
1929                  */
1930
1931                 if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
1932                         goto done;
1933
1934                 /* try for Win2k driver if "Windows NT x86" */
1935
1936                 version = 3;
1937                 status = winreg_get_driver(info, p->server_info,
1938                                            r->in.architecture,
1939                                            r->in.driver,
1940                                            version, &info);
1941                 if (!W_ERROR_IS_OK(status)) {
1942                         status = WERR_UNKNOWN_PRINTER_DRIVER;
1943                         goto done;
1944                 }
1945         }
1946
1947         if (printer_driver_in_use(info, p->server_info, info)) {
1948                 status = WERR_PRINTER_DRIVER_IN_USE;
1949                 goto done;
1950         }
1951
1952         /*
1953          * we have a couple of cases to consider.
1954          * (1) Are any files in use?  If so and DPD_DELTE_ALL_FILE is set,
1955          *     then the delete should fail if **any** files overlap with
1956          *     other drivers
1957          * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
1958          *     non-overlapping files
1959          * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
1960          *     is set, the do not delete any files
1961          * Refer to MSDN docs on DeletePrinterDriverEx() for details.
1962          */
1963
1964         delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
1965
1966         /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
1967
1968         if (delete_files &&
1969             (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
1970             printer_driver_files_in_use(info, p->server_info, info)) {
1971                 /* no idea of the correct error here */
1972                 status = WERR_ACCESS_DENIED;
1973                 goto done;
1974         }
1975
1976
1977         /* also check for W32X86/3 if necessary; maybe we already have? */
1978
1979         if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION)  ) {
1980                 status = winreg_get_driver(info, p->server_info,
1981                                            r->in.architecture,
1982                                            r->in.driver, 3, &info_win2k);
1983                 if (W_ERROR_IS_OK(status)) {
1984
1985                         if (delete_files &&
1986                             (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
1987                             printer_driver_files_in_use(info, p->server_info,
1988                                                         info_win2k)) {
1989                                 /* no idea of the correct error here */
1990                                 talloc_free(info_win2k);
1991                                 status = WERR_ACCESS_DENIED;
1992                                 goto done;
1993                         }
1994
1995                         /* if we get to here, we now have 2 driver info structures to remove */
1996                         /* remove the Win2k driver first*/
1997
1998                         status = winreg_del_driver(info, p->server_info,
1999                                                    info_win2k, 3);
2000
2001                         /* this should not have failed---if it did, report to client */
2002
2003                         if (!W_ERROR_IS_OK(status)) {
2004                                 goto done;
2005                         }
2006
2007                         /*
2008                          * now delete any associated files if delete_files is
2009                          * true. Even if this part failes, we return succes
2010                          * because the driver doesn not exist any more
2011                          */
2012                         if (delete_files) {
2013                                 delete_driver_files(p->server_info,
2014                                                     info_win2k);
2015                         }
2016                 }
2017         }
2018
2019         status = winreg_del_driver(info, p->server_info, info, version);
2020         if (!W_ERROR_IS_OK(status)) {
2021                 goto done;
2022         }
2023
2024         /*
2025          * now delete any associated files if delete_files is
2026          * true. Even if this part failes, we return succes
2027          * because the driver doesn not exist any more
2028          */
2029         if (delete_files) {
2030                 delete_driver_files(p->server_info, info);
2031         }
2032
2033 done:
2034         talloc_free(info);
2035         return status;
2036 }
2037
2038
2039 /********************************************************************
2040  GetPrinterData on a printer server Handle.
2041 ********************************************************************/
2042
2043 static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2044                                             const char *value,
2045                                             enum winreg_Type *type,
2046                                             union spoolss_PrinterData *data)
2047 {
2048         DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2049
2050         if (!StrCaseCmp(value, "W3SvcInstalled")) {
2051                 *type = REG_DWORD;
2052                 data->value = 0x00;
2053                 return WERR_OK;
2054         }
2055
2056         if (!StrCaseCmp(value, "BeepEnabled")) {
2057                 *type = REG_DWORD;
2058                 data->value = 0x00;
2059                 return WERR_OK;
2060         }
2061
2062         if (!StrCaseCmp(value, "EventLog")) {
2063                 *type = REG_DWORD;
2064                 /* formally was 0x1b */
2065                 data->value = 0x00;
2066                 return WERR_OK;
2067         }
2068
2069         if (!StrCaseCmp(value, "NetPopup")) {
2070                 *type = REG_DWORD;
2071                 data->value = 0x00;
2072                 return WERR_OK;
2073         }
2074
2075         if (!StrCaseCmp(value, "MajorVersion")) {
2076                 *type = REG_DWORD;
2077
2078                 /* Windows NT 4.0 seems to not allow uploading of drivers
2079                    to a server that reports 0x3 as the MajorVersion.
2080                    need to investigate more how Win2k gets around this .
2081                    -- jerry */
2082
2083                 if (RA_WINNT == get_remote_arch()) {
2084                         data->value = 0x02;
2085                 } else {
2086                         data->value = 0x03;
2087                 }
2088
2089                 return WERR_OK;
2090         }
2091
2092         if (!StrCaseCmp(value, "MinorVersion")) {
2093                 *type = REG_DWORD;
2094                 data->value = 0x00;
2095                 return WERR_OK;
2096         }
2097
2098         /* REG_BINARY
2099          *  uint32_t size        = 0x114
2100          *  uint32_t major       = 5
2101          *  uint32_t minor       = [0|1]
2102          *  uint32_t build       = [2195|2600]
2103          *  extra unicode string = e.g. "Service Pack 3"
2104          */
2105         if (!StrCaseCmp(value, "OSVersion")) {
2106                 DATA_BLOB blob;
2107                 enum ndr_err_code ndr_err;
2108                 struct spoolss_OSVersion os;
2109
2110                 os.major                = 5;    /* Windows 2000 == 5.0 */
2111                 os.minor                = 0;
2112                 os.build                = 2195; /* build */
2113                 os.extra_string         = "";   /* leave extra string empty */
2114
2115                 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os,
2116                         (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2117                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2118                         return WERR_GENERAL_FAILURE;
2119                 }
2120
2121                 *type = REG_BINARY;
2122                 data->binary = blob;
2123
2124                 return WERR_OK;
2125         }
2126
2127
2128         if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2129                 *type = REG_SZ;
2130
2131                 data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
2132                 W_ERROR_HAVE_NO_MEMORY(data->string);
2133
2134                 return WERR_OK;
2135         }
2136
2137         if (!StrCaseCmp(value, "Architecture")) {
2138                 *type = REG_SZ;
2139                 data->string = talloc_strdup(mem_ctx,
2140                         lp_parm_const_string(GLOBAL_SECTION_SNUM, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86));
2141                 W_ERROR_HAVE_NO_MEMORY(data->string);
2142
2143                 return WERR_OK;
2144         }
2145
2146         if (!StrCaseCmp(value, "DsPresent")) {
2147                 *type = REG_DWORD;
2148
2149                 /* only show the publish check box if we are a
2150                    member of a AD domain */
2151
2152                 if (lp_security() == SEC_ADS) {
2153                         data->value = 0x01;
2154                 } else {
2155                         data->value = 0x00;
2156                 }
2157                 return WERR_OK;
2158         }
2159
2160         if (!StrCaseCmp(value, "DNSMachineName")) {
2161                 const char *hostname = get_mydnsfullname();
2162
2163                 if (!hostname) {
2164                         return WERR_BADFILE;
2165                 }
2166
2167                 *type = REG_SZ;
2168                 data->string = talloc_strdup(mem_ctx, hostname);
2169                 W_ERROR_HAVE_NO_MEMORY(data->string);
2170
2171                 return WERR_OK;
2172         }
2173
2174         *type = REG_NONE;
2175
2176         return WERR_INVALID_PARAM;
2177 }
2178
2179 /****************************************************************
2180  _spoolss_GetPrinterData
2181 ****************************************************************/
2182
2183 WERROR _spoolss_GetPrinterData(struct pipes_struct *p,
2184                                struct spoolss_GetPrinterData *r)
2185 {
2186         struct spoolss_GetPrinterDataEx r2;
2187
2188         r2.in.handle            = r->in.handle;
2189         r2.in.key_name          = "PrinterDriverData";
2190         r2.in.value_name        = r->in.value_name;
2191         r2.in.offered           = r->in.offered;
2192         r2.out.type             = r->out.type;
2193         r2.out.data             = r->out.data;
2194         r2.out.needed           = r->out.needed;
2195
2196         return _spoolss_GetPrinterDataEx(p, &r2);
2197 }
2198
2199 /*********************************************************
2200  Connect to the client machine.
2201 **********************************************************/
2202
2203 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2204                         struct sockaddr_storage *client_ss, const char *remote_machine)
2205 {
2206         NTSTATUS ret;
2207         struct cli_state *the_cli;
2208         struct sockaddr_storage rm_addr;
2209         char addr[INET6_ADDRSTRLEN];
2210
2211         if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2212                 DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
2213                         remote_machine));
2214                 if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2215                         DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2216                         return false;
2217                 }
2218                 print_sockaddr(addr, sizeof(addr), &rm_addr);
2219         } else {
2220                 rm_addr = *client_ss;
2221                 print_sockaddr(addr, sizeof(addr), &rm_addr);
2222                 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2223                         addr));
2224         }
2225
2226         if (ismyaddr((struct sockaddr *)&rm_addr)) {
2227                 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
2228                         addr));
2229                 return false;
2230         }
2231
2232         /* setup the connection */
2233         ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2234                 &rm_addr, 0, "IPC$", "IPC",
2235                 "", /* username */
2236                 "", /* domain */
2237                 "", /* password */
2238                 0, lp_client_signing(), NULL );
2239
2240         if ( !NT_STATUS_IS_OK( ret ) ) {
2241                 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2242                         remote_machine ));
2243                 return false;
2244         }
2245
2246         if ( the_cli->protocol != PROTOCOL_NT1 ) {
2247                 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2248                 cli_shutdown(the_cli);
2249                 return false;
2250         }
2251
2252         /*
2253          * Ok - we have an anonymous connection to the IPC$ share.
2254          * Now start the NT Domain stuff :-).
2255          */
2256
2257         ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
2258         if (!NT_STATUS_IS_OK(ret)) {
2259                 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2260                         remote_machine, nt_errstr(ret)));
2261                 cli_shutdown(the_cli);
2262                 return false;
2263         }
2264
2265         return true;
2266 }
2267
2268 /***************************************************************************
2269  Connect to the client.
2270 ****************************************************************************/
2271
2272 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2273                                         uint32_t localprinter, uint32_t type,
2274                                         struct policy_handle *handle,
2275                                         struct sockaddr_storage *client_ss)
2276 {
2277         WERROR result;
2278         NTSTATUS status;
2279
2280         /*
2281          * If it's the first connection, contact the client
2282          * and connect to the IPC$ share anonymously
2283          */
2284         if (smb_connections==0) {
2285                 fstring unix_printer;
2286
2287                 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2288
2289                 if ( !spoolss_connect_to_client( &notify_cli_pipe, client_ss, unix_printer ))
2290                         return false;
2291
2292                 messaging_register(smbd_messaging_context(), NULL,
2293                                    MSG_PRINTER_NOTIFY2,
2294                                    receive_notify2_message_list);
2295                 /* Tell the connections db we're now interested in printer
2296                  * notify messages. */
2297                 serverid_register_msg_flags(
2298                         messaging_server_id(smbd_messaging_context()),
2299                         true, FLAG_MSG_PRINT_NOTIFY);
2300         }
2301
2302         /*
2303          * Tell the specific printing tdb we want messages for this printer
2304          * by registering our PID.
2305          */
2306
2307         if (!print_notify_register_pid(snum))
2308                 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2309
2310         smb_connections++;
2311
2312         status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2313                                                  printer,
2314                                                  localprinter,
2315                                                  type,
2316                                                  0,
2317                                                  NULL,
2318                                                  handle,
2319                                                  &result);
2320         if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2321                 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2322                         win_errstr(result)));
2323
2324         return (W_ERROR_IS_OK(result));
2325 }
2326
2327 /****************************************************************
2328  ****************************************************************/
2329
2330 static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2331                                                              const struct spoolss_NotifyOption *r)
2332 {
2333         struct spoolss_NotifyOption *option;
2334         uint32_t i,k;
2335
2336         if (!r) {
2337                 return NULL;
2338         }
2339
2340         option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2341         if (!option) {
2342                 return NULL;
2343         }
2344
2345         *option = *r;
2346
2347         if (!option->count) {
2348                 return option;
2349         }
2350
2351         option->types = talloc_zero_array(option,
2352                 struct spoolss_NotifyOptionType, option->count);
2353         if (!option->types) {
2354                 talloc_free(option);
2355                 return NULL;
2356         }
2357
2358         for (i=0; i < option->count; i++) {
2359                 option->types[i] = r->types[i];
2360
2361                 if (option->types[i].count) {
2362                         option->types[i].fields = talloc_zero_array(option,
2363                                 union spoolss_Field, option->types[i].count);
2364                         if (!option->types[i].fields) {
2365                                 talloc_free(option);
2366                                 return NULL;
2367                         }
2368                         for (k=0; k<option->types[i].count; k++) {
2369                                 option->types[i].fields[k] =
2370                                         r->types[i].fields[k];
2371                         }
2372                 }
2373         }
2374
2375         return option;
2376 }
2377
2378 /****************************************************************
2379  * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2380  *
2381  * before replying OK: status=0 a rpc call is made to the workstation
2382  * asking ReplyOpenPrinter
2383  *
2384  * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2385  * called from api_spoolss_rffpcnex
2386 ****************************************************************/
2387
2388 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct pipes_struct *p,
2389                                                      struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2390 {
2391         int snum = -1;
2392         struct spoolss_NotifyOption *option = r->in.notify_options;
2393         struct sockaddr_storage client_ss;
2394
2395         /* store the notify value in the printer struct */
2396
2397         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
2398
2399         if (!Printer) {
2400                 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2401                         "Invalid handle (%s:%u:%u).\n",
2402                         OUR_HANDLE(r->in.handle)));
2403                 return WERR_BADFID;
2404         }
2405
2406         Printer->notify.flags           = r->in.flags;
2407         Printer->notify.options         = r->in.options;
2408         Printer->notify.printerlocal    = r->in.printer_local;
2409
2410         TALLOC_FREE(Printer->notify.option);
2411         Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2412
2413         fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2414
2415         /* Connect to the client machine and send a ReplyOpenPrinter */
2416
2417         if ( Printer->printer_type == SPLHND_SERVER)
2418                 snum = -1;
2419         else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2420                         !get_printer_snum(p, r->in.handle, &snum, NULL) )
2421                 return WERR_BADFID;
2422
2423         DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2424                 "client_address is %s\n", p->client_address));
2425
2426         if (!interpret_string_addr(&client_ss, p->client_address,
2427                                    AI_NUMERICHOST)) {
2428                 return WERR_SERVER_UNAVAILABLE;
2429         }
2430
2431         if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2432                                         Printer->notify.printerlocal, 1,
2433                                         &Printer->notify.client_hnd, &client_ss))
2434                 return WERR_SERVER_UNAVAILABLE;
2435
2436         Printer->notify.client_connected = true;
2437
2438         return WERR_OK;
2439 }
2440
2441 /*******************************************************************
2442  * fill a notify_info_data with the servername
2443  ********************************************************************/
2444
2445 static void spoolss_notify_server_name(int snum,
2446                                        struct spoolss_Notify *data,
2447                                        print_queue_struct *queue,
2448                                        struct spoolss_PrinterInfo2 *pinfo2,
2449                                        TALLOC_CTX *mem_ctx)
2450 {
2451         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->servername);
2452 }
2453
2454 /*******************************************************************
2455  * fill a notify_info_data with the printername (not including the servername).
2456  ********************************************************************/
2457
2458 static void spoolss_notify_printer_name(int snum,
2459                                         struct spoolss_Notify *data,
2460                                         print_queue_struct *queue,
2461                                         struct spoolss_PrinterInfo2 *pinfo2,
2462                                         TALLOC_CTX *mem_ctx)
2463 {
2464         /* the notify name should not contain the \\server\ part */
2465         const char *p = strrchr(pinfo2->printername, '\\');
2466
2467         if (!p) {
2468                 p = pinfo2->printername;
2469         } else {
2470                 p++;
2471         }
2472
2473         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2474 }
2475
2476 /*******************************************************************
2477  * fill a notify_info_data with the servicename
2478  ********************************************************************/
2479
2480 static void spoolss_notify_share_name(int snum,
2481                                       struct spoolss_Notify *data,
2482                                       print_queue_struct *queue,
2483                                       struct spoolss_PrinterInfo2 *pinfo2,
2484                                       TALLOC_CTX *mem_ctx)
2485 {
2486         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2487 }
2488
2489 /*******************************************************************
2490  * fill a notify_info_data with the port name
2491  ********************************************************************/
2492
2493 static void spoolss_notify_port_name(int snum,
2494                                      struct spoolss_Notify *data,
2495                                      print_queue_struct *queue,
2496                                      struct spoolss_PrinterInfo2 *pinfo2,
2497                                      TALLOC_CTX *mem_ctx)
2498 {
2499         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->portname);
2500 }
2501
2502 /*******************************************************************
2503  * fill a notify_info_data with the printername
2504  * but it doesn't exist, have to see what to do
2505  ********************************************************************/
2506
2507 static void spoolss_notify_driver_name(int snum,
2508                                        struct spoolss_Notify *data,
2509                                        print_queue_struct *queue,
2510                                        struct spoolss_PrinterInfo2 *pinfo2,
2511                                        TALLOC_CTX *mem_ctx)
2512 {
2513         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->drivername);
2514 }
2515
2516 /*******************************************************************
2517  * fill a notify_info_data with the comment
2518  ********************************************************************/
2519
2520 static void spoolss_notify_comment(int snum,
2521                                    struct spoolss_Notify *data,
2522                                    print_queue_struct *queue,
2523                                    struct spoolss_PrinterInfo2 *pinfo2,
2524                                    TALLOC_CTX *mem_ctx)
2525 {
2526         const char *p;
2527
2528         if (*pinfo2->comment == '\0') {
2529                 p = lp_comment(snum);
2530         } else {
2531                 p = pinfo2->comment;
2532         }
2533
2534         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2535 }
2536
2537 /*******************************************************************
2538  * fill a notify_info_data with the comment
2539  * location = "Room 1, floor 2, building 3"
2540  ********************************************************************/
2541
2542 static void spoolss_notify_location(int snum,
2543                                     struct spoolss_Notify *data,
2544                                     print_queue_struct *queue,
2545                                     struct spoolss_PrinterInfo2 *pinfo2,
2546                                     TALLOC_CTX *mem_ctx)
2547 {
2548         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->location);
2549 }
2550
2551 /*******************************************************************
2552  * fill a notify_info_data with the device mode
2553  * jfm:xxxx don't to it for know but that's a real problem !!!
2554  ********************************************************************/
2555
2556 static void spoolss_notify_devmode(int snum,
2557                                    struct spoolss_Notify *data,
2558                                    print_queue_struct *queue,
2559                                    struct spoolss_PrinterInfo2 *pinfo2,
2560                                    TALLOC_CTX *mem_ctx)
2561 {
2562         /* for a dummy implementation we have to zero the fields */
2563         SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2564 }
2565
2566 /*******************************************************************
2567  * fill a notify_info_data with the separator file name
2568  ********************************************************************/
2569
2570 static void spoolss_notify_sepfile(int snum,
2571                                    struct spoolss_Notify *data,
2572                                    print_queue_struct *queue,
2573                                    struct spoolss_PrinterInfo2 *pinfo2,
2574                                    TALLOC_CTX *mem_ctx)
2575 {
2576         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->sepfile);
2577 }
2578
2579 /*******************************************************************
2580  * fill a notify_info_data with the print processor
2581  * jfm:xxxx return always winprint to indicate we don't do anything to it
2582  ********************************************************************/
2583
2584 static void spoolss_notify_print_processor(int snum,
2585                                            struct spoolss_Notify *data,
2586                                            print_queue_struct *queue,
2587                                            struct spoolss_PrinterInfo2 *pinfo2,
2588                                            TALLOC_CTX *mem_ctx)
2589 {
2590         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->printprocessor);
2591 }
2592
2593 /*******************************************************************
2594  * fill a notify_info_data with the print processor options
2595  * jfm:xxxx send an empty string
2596  ********************************************************************/
2597
2598 static void spoolss_notify_parameters(int snum,
2599                                       struct spoolss_Notify *data,
2600                                       print_queue_struct *queue,
2601                                       struct spoolss_PrinterInfo2 *pinfo2,
2602                                       TALLOC_CTX *mem_ctx)
2603 {
2604         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->parameters);
2605 }
2606
2607 /*******************************************************************
2608  * fill a notify_info_data with the data type
2609  * jfm:xxxx always send RAW as data type
2610  ********************************************************************/
2611
2612 static void spoolss_notify_datatype(int snum,
2613                                     struct spoolss_Notify *data,
2614                                     print_queue_struct *queue,
2615                                     struct spoolss_PrinterInfo2 *pinfo2,
2616                                     TALLOC_CTX *mem_ctx)
2617 {
2618         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->datatype);
2619 }
2620
2621 /*******************************************************************
2622  * fill a notify_info_data with the security descriptor
2623  * jfm:xxxx send an null pointer to say no security desc
2624  * have to implement security before !
2625  ********************************************************************/
2626
2627 static void spoolss_notify_security_desc(int snum,
2628                                          struct spoolss_Notify *data,
2629                                          print_queue_struct *queue,
2630                                          struct spoolss_PrinterInfo2 *pinfo2,
2631                                          TALLOC_CTX *mem_ctx)
2632 {
2633         SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data, pinfo2->secdesc);
2634 }
2635
2636 /*******************************************************************
2637  * fill a notify_info_data with the attributes
2638  * jfm:xxxx a samba printer is always shared
2639  ********************************************************************/
2640
2641 static void spoolss_notify_attributes(int snum,
2642                                       struct spoolss_Notify *data,
2643                                       print_queue_struct *queue,
2644                                       struct spoolss_PrinterInfo2 *pinfo2,
2645                                       TALLOC_CTX *mem_ctx)
2646 {
2647         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->attributes);
2648 }
2649
2650 /*******************************************************************
2651  * fill a notify_info_data with the priority
2652  ********************************************************************/
2653
2654 static void spoolss_notify_priority(int snum,
2655                                     struct spoolss_Notify *data,
2656                                     print_queue_struct *queue,
2657                                     struct spoolss_PrinterInfo2 *pinfo2,
2658                                     TALLOC_CTX *mem_ctx)
2659 {
2660         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->priority);
2661 }
2662
2663 /*******************************************************************
2664  * fill a notify_info_data with the default priority
2665  ********************************************************************/
2666
2667 static void spoolss_notify_default_priority(int snum,
2668                                             struct spoolss_Notify *data,
2669                                             print_queue_struct *queue,
2670                                             struct spoolss_PrinterInfo2 *pinfo2,
2671                                             TALLOC_CTX *mem_ctx)
2672 {
2673         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->defaultpriority);
2674 }
2675
2676 /*******************************************************************
2677  * fill a notify_info_data with the start time
2678  ********************************************************************/
2679
2680 static void spoolss_notify_start_time(int snum,
2681                                       struct spoolss_Notify *data,
2682                                       print_queue_struct *queue,
2683                                       struct spoolss_PrinterInfo2 *pinfo2,
2684                                       TALLOC_CTX *mem_ctx)
2685 {
2686         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->starttime);
2687 }
2688
2689 /*******************************************************************
2690  * fill a notify_info_data with the until time
2691  ********************************************************************/
2692
2693 static void spoolss_notify_until_time(int snum,
2694                                       struct spoolss_Notify *data,
2695                                       print_queue_struct *queue,
2696                                       struct spoolss_PrinterInfo2 *pinfo2,
2697                                       TALLOC_CTX *mem_ctx)
2698 {
2699         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->untiltime);
2700 }
2701
2702 /*******************************************************************
2703  * fill a notify_info_data with the status
2704  ********************************************************************/
2705
2706 static void spoolss_notify_status(int snum,
2707                                   struct spoolss_Notify *data,
2708                                   print_queue_struct *queue,
2709                                   struct spoolss_PrinterInfo2 *pinfo2,
2710                                   TALLOC_CTX *mem_ctx)
2711 {
2712         print_status_struct status;
2713
2714         print_queue_length(snum, &status);
2715         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
2716 }
2717
2718 /*******************************************************************
2719  * fill a notify_info_data with the number of jobs queued
2720  ********************************************************************/
2721
2722 static void spoolss_notify_cjobs(int snum,
2723                                  struct spoolss_Notify *data,
2724                                  print_queue_struct *queue,
2725                                  struct spoolss_PrinterInfo2 *pinfo2,
2726                                  TALLOC_CTX *mem_ctx)
2727 {
2728         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
2729 }
2730
2731 /*******************************************************************
2732  * fill a notify_info_data with the average ppm
2733  ********************************************************************/
2734
2735 static void spoolss_notify_average_ppm(int snum,
2736                                        struct spoolss_Notify *data,
2737                                        print_queue_struct *queue,
2738                                        struct spoolss_PrinterInfo2 *pinfo2,
2739                                        TALLOC_CTX *mem_ctx)
2740 {
2741         /* always respond 8 pages per minutes */
2742         /* a little hard ! */
2743         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->averageppm);
2744 }
2745
2746 /*******************************************************************
2747  * fill a notify_info_data with username
2748  ********************************************************************/
2749
2750 static void spoolss_notify_username(int snum,
2751                                     struct spoolss_Notify *data,
2752                                     print_queue_struct *queue,
2753                                     struct spoolss_PrinterInfo2 *pinfo2,
2754                                     TALLOC_CTX *mem_ctx)
2755 {
2756         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
2757 }
2758
2759 /*******************************************************************
2760  * fill a notify_info_data with job status
2761  ********************************************************************/
2762
2763 static void spoolss_notify_job_status(int snum,
2764                                       struct spoolss_Notify *data,
2765                                       print_queue_struct *queue,
2766                                       struct spoolss_PrinterInfo2 *pinfo2,
2767                                       TALLOC_CTX *mem_ctx)
2768 {
2769         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
2770 }
2771
2772 /*******************************************************************
2773  * fill a notify_info_data with job name
2774  ********************************************************************/
2775
2776 static void spoolss_notify_job_name(int snum,
2777                                     struct spoolss_Notify *data,
2778                                     print_queue_struct *queue,
2779                                     struct spoolss_PrinterInfo2 *pinfo2,
2780                                     TALLOC_CTX *mem_ctx)
2781 {
2782         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
2783 }
2784
2785 /*******************************************************************
2786  * fill a notify_info_data with job status
2787  ********************************************************************/
2788
2789 static void spoolss_notify_job_status_string(int snum,
2790                                              struct spoolss_Notify *data,
2791                                              print_queue_struct *queue,
2792                                              struct spoolss_PrinterInfo2 *pinfo2,
2793                                              TALLOC_CTX *mem_ctx)
2794 {
2795         /*
2796          * Now we're returning job status codes we just return a "" here. JRA.
2797          */
2798
2799         const char *p = "";
2800
2801 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2802         p = "unknown";
2803
2804         switch (queue->status) {
2805         case LPQ_QUEUED:
2806                 p = "Queued";
2807                 break;
2808         case LPQ_PAUSED:
2809                 p = "";    /* NT provides the paused string */
2810                 break;
2811         case LPQ_SPOOLING:
2812                 p = "Spooling";
2813                 break;
2814         case LPQ_PRINTING:
2815                 p = "Printing";
2816                 break;
2817         }
2818 #endif /* NO LONGER NEEDED. */
2819
2820         SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2821 }
2822
2823 /*******************************************************************
2824  * fill a notify_info_data with job time
2825  ********************************************************************/
2826
2827 static void spoolss_notify_job_time(int snum,
2828                                     struct spoolss_Notify *data,
2829                                     print_queue_struct *queue,
2830                                     struct spoolss_PrinterInfo2 *pinfo2,
2831                                     TALLOC_CTX *mem_ctx)
2832 {
2833         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2834 }
2835
2836 /*******************************************************************
2837  * fill a notify_info_data with job size
2838  ********************************************************************/
2839
2840 static void spoolss_notify_job_size(int snum,
2841                                     struct spoolss_Notify *data,
2842                                     print_queue_struct *queue,
2843                                     struct spoolss_PrinterInfo2 *pinfo2,
2844                                     TALLOC_CTX *mem_ctx)
2845 {
2846         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
2847 }
2848
2849 /*******************************************************************
2850  * fill a notify_info_data with page info
2851  ********************************************************************/
2852 static void spoolss_notify_total_pages(int snum,
2853                                 struct spoolss_Notify *data,
2854                                 print_queue_struct *queue,
2855                                 struct spoolss_PrinterInfo2 *pinfo2,
2856                                 TALLOC_CTX *mem_ctx)
2857 {
2858         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
2859 }
2860
2861 /*******************************************************************
2862  * fill a notify_info_data with pages printed info.
2863  ********************************************************************/
2864 static void spoolss_notify_pages_printed(int snum,
2865                                 struct spoolss_Notify *data,
2866                                 print_queue_struct *queue,
2867                                 struct spoolss_PrinterInfo2 *pinfo2,
2868                                 TALLOC_CTX *mem_ctx)
2869 {
2870         /* Add code when back-end tracks this */
2871         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2872 }
2873
2874 /*******************************************************************
2875  Fill a notify_info_data with job position.
2876  ********************************************************************/
2877
2878 static void spoolss_notify_job_position(int snum,
2879                                         struct spoolss_Notify *data,
2880                                         print_queue_struct *queue,
2881                                         struct spoolss_PrinterInfo2 *pinfo2,
2882                                         TALLOC_CTX *mem_ctx)
2883 {
2884         SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
2885 }
2886
2887 /*******************************************************************
2888  Fill a notify_info_data with submitted time.
2889  ********************************************************************/
2890
2891 static void spoolss_notify_submitted_time(int snum,
2892                                           struct spoolss_Notify *data,
2893                                           print_queue_struct *queue,
2894                                           struct spoolss_PrinterInfo2 *pinfo2,
2895                                           TALLOC_CTX *mem_ctx)
2896 {
2897         data->data.string.string = NULL;
2898         data->data.string.size = 0;
2899
2900         init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
2901                                &data->data.string.string,
2902                                &data->data.string.size);
2903
2904 }
2905
2906 struct s_notify_info_data_table
2907 {
2908         enum spoolss_NotifyType type;
2909         uint16_t field;
2910         const char *name;
2911         enum spoolss_NotifyTable variable_type;
2912         void (*fn) (int snum, struct spoolss_Notify *data,
2913                     print_queue_struct *queue,
2914                     struct spoolss_PrinterInfo2 *pinfo2,
2915                     TALLOC_CTX *mem_ctx);
2916 };
2917
2918 /* A table describing the various print notification constants and
2919    whether the notification data is a pointer to a variable sized
2920    buffer, a one value uint32_t or a two value uint32_t. */
2921
2922 static const struct s_notify_info_data_table notify_info_data_table[] =
2923 {
2924 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME,         "PRINTER_NOTIFY_FIELD_SERVER_NAME",         NOTIFY_TABLE_STRING,   spoolss_notify_server_name },
2925 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME,        "PRINTER_NOTIFY_FIELD_PRINTER_NAME",        NOTIFY_TABLE_STRING,   spoolss_notify_printer_name },
2926 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME,          "PRINTER_NOTIFY_FIELD_SHARE_NAME",          NOTIFY_TABLE_STRING,   spoolss_notify_share_name },
2927 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME,           "PRINTER_NOTIFY_FIELD_PORT_NAME",           NOTIFY_TABLE_STRING,   spoolss_notify_port_name },
2928 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME,         "PRINTER_NOTIFY_FIELD_DRIVER_NAME",         NOTIFY_TABLE_STRING,   spoolss_notify_driver_name },
2929 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT,             "PRINTER_NOTIFY_FIELD_COMMENT",             NOTIFY_TABLE_STRING,   spoolss_notify_comment },
2930 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION,            "PRINTER_NOTIFY_FIELD_LOCATION",            NOTIFY_TABLE_STRING,   spoolss_notify_location },
2931 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE,             "PRINTER_NOTIFY_FIELD_DEVMODE",             NOTIFY_TABLE_DEVMODE,  spoolss_notify_devmode },
2932 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE,             "PRINTER_NOTIFY_FIELD_SEPFILE",             NOTIFY_TABLE_STRING,   spoolss_notify_sepfile },
2933 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR,     "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR",     NOTIFY_TABLE_STRING,   spoolss_notify_print_processor },
2934 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS,          "PRINTER_NOTIFY_FIELD_PARAMETERS",          NOTIFY_TABLE_STRING,   spoolss_notify_parameters },
2935 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE,            "PRINTER_NOTIFY_FIELD_DATATYPE",            NOTIFY_TABLE_STRING,   spoolss_notify_datatype },
2936 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR,   spoolss_notify_security_desc },
2937 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES,          "PRINTER_NOTIFY_FIELD_ATTRIBUTES",          NOTIFY_TABLE_DWORD,    spoolss_notify_attributes },
2938 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY,            "PRINTER_NOTIFY_FIELD_PRIORITY",            NOTIFY_TABLE_DWORD,    spoolss_notify_priority },
2939 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY,    "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY",    NOTIFY_TABLE_DWORD,    spoolss_notify_default_priority },
2940 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME,          "PRINTER_NOTIFY_FIELD_START_TIME",          NOTIFY_TABLE_DWORD,    spoolss_notify_start_time },
2941 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME,          "PRINTER_NOTIFY_FIELD_UNTIL_TIME",          NOTIFY_TABLE_DWORD,    spoolss_notify_until_time },
2942 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS,              "PRINTER_NOTIFY_FIELD_STATUS",              NOTIFY_TABLE_DWORD,    spoolss_notify_status },
2943 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING,       "PRINTER_NOTIFY_FIELD_STATUS_STRING",       NOTIFY_TABLE_STRING,   NULL },
2944 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS,               "PRINTER_NOTIFY_FIELD_CJOBS",               NOTIFY_TABLE_DWORD,    spoolss_notify_cjobs },
2945 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM,         "PRINTER_NOTIFY_FIELD_AVERAGE_PPM",         NOTIFY_TABLE_DWORD,    spoolss_notify_average_ppm },
2946 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES,         "PRINTER_NOTIFY_FIELD_TOTAL_PAGES",         NOTIFY_TABLE_DWORD,    NULL },
2947 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED,       "PRINTER_NOTIFY_FIELD_PAGES_PRINTED",       NOTIFY_TABLE_DWORD,    NULL },
2948 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES,         "PRINTER_NOTIFY_FIELD_TOTAL_BYTES",         NOTIFY_TABLE_DWORD,    NULL },
2949 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED,       "PRINTER_NOTIFY_FIELD_BYTES_PRINTED",       NOTIFY_TABLE_DWORD,    NULL },
2950 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PRINTER_NAME,            "JOB_NOTIFY_FIELD_PRINTER_NAME",            NOTIFY_TABLE_STRING,   spoolss_notify_printer_name },
2951 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_MACHINE_NAME,            "JOB_NOTIFY_FIELD_MACHINE_NAME",            NOTIFY_TABLE_STRING,   spoolss_notify_server_name },
2952 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PORT_NAME,               "JOB_NOTIFY_FIELD_PORT_NAME",               NOTIFY_TABLE_STRING,   spoolss_notify_port_name },
2953 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_USER_NAME,               "JOB_NOTIFY_FIELD_USER_NAME",               NOTIFY_TABLE_STRING,   spoolss_notify_username },
2954 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_NOTIFY_NAME,             "JOB_NOTIFY_FIELD_NOTIFY_NAME",             NOTIFY_TABLE_STRING,   spoolss_notify_username },
2955 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DATATYPE,                "JOB_NOTIFY_FIELD_DATATYPE",                NOTIFY_TABLE_STRING,   spoolss_notify_datatype },
2956 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PRINT_PROCESSOR,         "JOB_NOTIFY_FIELD_PRINT_PROCESSOR",         NOTIFY_TABLE_STRING,   spoolss_notify_print_processor },
2957 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PARAMETERS,              "JOB_NOTIFY_FIELD_PARAMETERS",              NOTIFY_TABLE_STRING,   spoolss_notify_parameters },
2958 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DRIVER_NAME,             "JOB_NOTIFY_FIELD_DRIVER_NAME",             NOTIFY_TABLE_STRING,   spoolss_notify_driver_name },
2959 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DEVMODE,                 "JOB_NOTIFY_FIELD_DEVMODE",                 NOTIFY_TABLE_DEVMODE,  spoolss_notify_devmode },
2960 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_STATUS,                  "JOB_NOTIFY_FIELD_STATUS",                  NOTIFY_TABLE_DWORD,    spoolss_notify_job_status },
2961 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_STATUS_STRING,           "JOB_NOTIFY_FIELD_STATUS_STRING",           NOTIFY_TABLE_STRING,   spoolss_notify_job_status_string },
2962 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR,     "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR",     NOTIFY_TABLE_SECURITYDESCRIPTOR,   NULL },
2963 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DOCUMENT,                "JOB_NOTIFY_FIELD_DOCUMENT",                NOTIFY_TABLE_STRING,   spoolss_notify_job_name },
2964 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PRIORITY,                "JOB_NOTIFY_FIELD_PRIORITY",                NOTIFY_TABLE_DWORD,    spoolss_notify_priority },
2965 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_POSITION,                "JOB_NOTIFY_FIELD_POSITION",                NOTIFY_TABLE_DWORD,    spoolss_notify_job_position },
2966 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_SUBMITTED,               "JOB_NOTIFY_FIELD_SUBMITTED",               NOTIFY_TABLE_TIME,     spoolss_notify_submitted_time },
2967 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_START_TIME,              "JOB_NOTIFY_FIELD_START_TIME",              NOTIFY_TABLE_DWORD,    spoolss_notify_start_time },
2968 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_UNTIL_TIME,              "JOB_NOTIFY_FIELD_UNTIL_TIME",              NOTIFY_TABLE_DWORD,    spoolss_notify_until_time },
2969 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_TIME,                    "JOB_NOTIFY_FIELD_TIME",                    NOTIFY_TABLE_DWORD,    spoolss_notify_job_time },
2970 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_TOTAL_PAGES,             "JOB_NOTIFY_FIELD_TOTAL_PAGES",             NOTIFY_TABLE_DWORD,    spoolss_notify_total_pages },
2971 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PAGES_PRINTED,           "JOB_NOTIFY_FIELD_PAGES_PRINTED",           NOTIFY_TABLE_DWORD,    spoolss_notify_pages_printed },
2972 { JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_TOTAL_BYTES,             "JOB_NOTIFY_FIELD_TOTAL_BYTES",             NOTIFY_TABLE_DWORD,    spoolss_notify_job_size },
2973 };
2974
2975 /*******************************************************************
2976  Return the variable_type of info_data structure.
2977 ********************************************************************/
2978
2979 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
2980                                                   uint16_t field)
2981 {
2982         int i=0;
2983
2984         for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
2985                 if ( (notify_info_data_table[i].type == type) &&
2986                      (notify_info_data_table[i].field == field) ) {
2987                         return notify_info_data_table[i].variable_type;
2988                 }
2989         }
2990
2991         DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
2992
2993         return 0;
2994 }
2995
2996 /****************************************************************************
2997 ****************************************************************************/
2998
2999 static bool search_notify(enum spoolss_NotifyType type,
3000                           uint16_t field,
3001                           int *value)
3002 {
3003         int i;
3004
3005         for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3006                 if (notify_info_data_table[i].type == type &&
3007                     notify_info_data_table[i].field == field &&
3008                     notify_info_data_table[i].fn != NULL) {
3009                         *value = i;
3010                         return true;
3011                 }
3012         }
3013
3014         return false;
3015 }
3016
3017 /****************************************************************************
3018 ****************************************************************************/
3019
3020 static void construct_info_data(struct spoolss_Notify *info_data,
3021                                 enum spoolss_NotifyType type,
3022                                 uint16_t field, int id)
3023 {
3024         info_data->type                 = type;
3025         info_data->field.field          = field;
3026         info_data->variable_type        = variable_type_of_notify_info_data(type, field);
3027         info_data->job_id               = id;
3028 }
3029
3030 /*******************************************************************
3031  *
3032  * fill a notify_info struct with info asked
3033  *
3034  ********************************************************************/
3035
3036 static bool construct_notify_printer_info(Printer_entry *print_hnd,
3037                                           struct spoolss_NotifyInfo *info,
3038                                           struct spoolss_PrinterInfo2 *pinfo2,
3039                                           int snum,
3040                                           const struct spoolss_NotifyOptionType *option_type,
3041                                           uint32_t id,
3042                                           TALLOC_CTX *mem_ctx)
3043 {
3044         int field_num,j;
3045         enum spoolss_NotifyType type;
3046         uint16_t field;
3047
3048         struct spoolss_Notify *current_data;
3049         print_queue_struct *queue=NULL;
3050
3051         type = option_type->type;
3052
3053         DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3054                 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3055                 option_type->count, lp_servicename(snum)));
3056
3057         for(field_num=0; field_num < option_type->count; field_num++) {
3058                 field = option_type->fields[field_num].field;
3059
3060                 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3061
3062                 if (!search_notify(type, field, &j) )
3063                         continue;
3064
3065                 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3066                                                       struct spoolss_Notify,
3067                                                       info->count + 1);
3068                 if (info->notifies == NULL) {
3069                         DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3070                         return false;
3071                 }
3072
3073                 current_data = &info->notifies[info->count];
3074
3075                 construct_info_data(current_data, type, field, id);
3076
3077                 DEBUG(10, ("construct_notify_printer_info: "
3078                            "calling [%s]  snum=%d  printername=[%s])\n",
3079                            notify_info_data_table[j].name, snum,
3080                            pinfo2->printername));
3081
3082                 notify_info_data_table[j].fn(snum, current_data, queue,
3083                                              pinfo2, mem_ctx);
3084
3085                 info->count++;
3086         }
3087
3088         return true;
3089 }
3090
3091 /*******************************************************************
3092  *
3093  * fill a notify_info struct with info asked
3094  *
3095  ********************************************************************/
3096
3097 static bool construct_notify_jobs_info(print_queue_struct *queue,
3098                                        struct spoolss_NotifyInfo *info,
3099                                        struct spoolss_PrinterInfo2 *pinfo2,
3100                                        int snum,
3101                                        const struct spoolss_NotifyOptionType *option_type,
3102                                        uint32_t id,
3103                                        TALLOC_CTX *mem_ctx)
3104 {
3105         int field_num,j;
3106         enum spoolss_NotifyType type;
3107         uint16_t field;
3108         struct spoolss_Notify *current_data;
3109
3110         DEBUG(4,("construct_notify_jobs_info\n"));
3111
3112         type = option_type->type;
3113
3114         DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3115                 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3116                 option_type->count));
3117
3118         for(field_num=0; field_num<option_type->count; field_num++) {
3119                 field = option_type->fields[field_num].field;
3120
3121                 if (!search_notify(type, field, &j) )
3122                         continue;
3123
3124                 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3125                                                       struct spoolss_Notify,
3126                                                       info->count + 1);
3127                 if (info->notifies == NULL) {
3128                         DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3129                         return false;
3130                 }
3131
3132                 current_data=&(info->notifies[info->count]);
3133
3134                 construct_info_data(current_data, type, field, id);
3135                 notify_info_data_table[j].fn(snum, current_data, queue,
3136                                              pinfo2, mem_ctx);
3137                 info->count++;
3138         }
3139
3140         return true;
3141 }
3142
3143 /*
3144  * JFM: The enumeration is not that simple, it's even non obvious.
3145  *
3146  * let's take an example: I want to monitor the PRINTER SERVER for
3147  * the printer's name and the number of jobs currently queued.
3148  * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3149  * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3150  *
3151  * I have 3 printers on the back of my server.
3152  *
3153  * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3154  * structures.
3155  *   Number     Data                    Id
3156  *      1       printer 1 name          1
3157  *      2       printer 1 cjob          1
3158  *      3       printer 2 name          2
3159  *      4       printer 2 cjob          2
3160  *      5       printer 3 name          3
3161  *      6       printer 3 name          3
3162  *
3163  * that's the print server case, the printer case is even worse.
3164  */
3165
3166 /*******************************************************************
3167  *
3168  * enumerate all printers on the printserver
3169  * fill a notify_info struct with info asked
3170  *
3171  ********************************************************************/
3172
3173 static WERROR printserver_notify_info(struct pipes_struct *p,
3174                                       struct policy_handle *hnd,
3175                                       struct spoolss_NotifyInfo *info,
3176                                       TALLOC_CTX *mem_ctx)
3177 {
3178         int snum;
3179         Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3180         int n_services=lp_numservices();
3181         int i;
3182         struct spoolss_NotifyOption *option;
3183         struct spoolss_NotifyOptionType option_type;
3184         struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3185         WERROR result;
3186
3187         DEBUG(4,("printserver_notify_info\n"));
3188
3189         if (!Printer)
3190                 return WERR_BADFID;
3191
3192         option = Printer->notify.option;
3193
3194         info->version   = 2;
3195         info->notifies  = NULL;
3196         info->count     = 0;
3197
3198         /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3199            sending a ffpcn() request first */
3200
3201         if ( !option )
3202                 return WERR_BADFID;
3203
3204         for (i=0; i<option->count; i++) {
3205                 option_type = option->types[i];
3206
3207                 if (option_type.type != PRINTER_NOTIFY_TYPE)
3208                         continue;
3209
3210                 for (snum = 0; snum < n_services; snum++) {
3211                         if (!lp_browseable(snum) ||
3212                             !lp_snum_ok(snum) ||
3213                             !lp_print_ok(snum)) {
3214                                 continue; /* skip */
3215                         }
3216
3217                         /* Maybe we should use the SYSTEM server_info here... */
3218                         result = winreg_get_printer(mem_ctx, p->server_info,
3219                                                     Printer->servername,
3220                                                     lp_servicename(snum),
3221                                                     &pinfo2);
3222                         if (!W_ERROR_IS_OK(result)) {
3223                                 DEBUG(4, ("printserver_notify_info: "
3224                                           "Failed to get printer [%s]\n",
3225                                           lp_servicename(snum)));
3226                                 continue;
3227                         }
3228
3229
3230                         construct_notify_printer_info(Printer, info,
3231                                                       pinfo2, snum,
3232                                                       &option_type, snum,
3233                                                       mem_ctx);
3234
3235                         TALLOC_FREE(pinfo2);
3236                 }
3237         }
3238
3239 #if 0
3240         /*
3241          * Debugging information, don't delete.
3242          */
3243
3244         DEBUG(1,("dumping the NOTIFY_INFO\n"));
3245         DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3246         DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3247
3248         for (i=0; i<info->count; i++) {
3249                 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3250                 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3251                 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3252         }
3253 #endif
3254
3255         return WERR_OK;
3256 }
3257
3258 /*******************************************************************
3259  *
3260  * fill a notify_info struct with info asked
3261  *
3262  ********************************************************************/
3263
3264 static WERROR printer_notify_info(struct pipes_struct *p,
3265                                   struct policy_handle *hnd,
3266                                   struct spoolss_NotifyInfo *info,
3267                                   TALLOC_CTX *mem_ctx)
3268 {
3269         int snum;
3270         Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3271         int i;
3272         uint32_t id;
3273         struct spoolss_NotifyOption *option;
3274         struct spoolss_NotifyOptionType option_type;
3275         int count,j;
3276         print_queue_struct *queue=NULL;
3277         print_status_struct status;
3278         struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3279         WERROR result;
3280
3281         DEBUG(4,("printer_notify_info\n"));
3282
3283         if (!Printer)
3284                 return WERR_BADFID;
3285
3286         option = Printer->notify.option;
3287         id = 0x0;
3288
3289         info->version   = 2;
3290         info->notifies  = NULL;
3291         info->count     = 0;
3292
3293         /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3294            sending a ffpcn() request first */
3295
3296         if ( !option )
3297                 return WERR_BADFID;
3298
3299         get_printer_snum(p, hnd, &snum, NULL);
3300
3301         /* Maybe we should use the SYSTEM server_info here... */
3302         result = winreg_get_printer(mem_ctx, p->server_info,
3303                                     Printer->servername,
3304                                     lp_servicename(snum), &pinfo2);
3305         if (!W_ERROR_IS_OK(result)) {
3306                 return WERR_BADFID;
3307         }
3308
3309         for (i=0; i<option->count; i++) {
3310                 option_type = option->types[i];
3311
3312                 switch (option_type.type) {
3313                 case PRINTER_NOTIFY_TYPE:
3314                         if (construct_notify_printer_info(Printer, info,
3315                                                           pinfo2, snum,
3316                                                           &option_type, id,
3317                                                           mem_ctx)) {
3318                                 id--;
3319                         }
3320                         break;
3321
3322                 case JOB_NOTIFY_TYPE:
3323
3324                         count = print_queue_status(snum, &queue, &status);
3325
3326                         for (j=0; j<count; j++) {
3327                                 construct_notify_jobs_info(&queue[j], info,
3328                                                            pinfo2, snum,
3329                                                            &option_type,
3330                                                            queue[j].job,
3331                                                            mem_ctx);
3332                         }
3333
3334                         SAFE_FREE(queue);
3335                         break;
3336                 }
3337         }
3338
3339         /*
3340          * Debugging information, don't delete.
3341          */
3342         /*
3343         DEBUG(1,("dumping the NOTIFY_INFO\n"));
3344         DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3345         DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3346
3347         for (i=0; i<info->count; i++) {
3348                 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3349                 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3350                 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3351         }
3352         */
3353
3354         talloc_free(pinfo2);
3355         return WERR_OK;
3356 }
3357
3358 /****************************************************************
3359  _spoolss_RouterRefreshPrinterChangeNotify
3360 ****************************************************************/
3361
3362 WERROR _spoolss_RouterRefreshPrinterChangeNotify(struct pipes_struct *p,
3363                                                  struct spoolss_RouterRefreshPrinterChangeNotify *r)
3364 {
3365         struct spoolss_NotifyInfo *info;
3366
3367         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
3368         WERROR result = WERR_BADFID;
3369
3370         /* we always have a spoolss_NotifyInfo struct */
3371         info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3372         if (!info) {
3373                 result = WERR_NOMEM;
3374                 goto done;
3375         }
3376
3377         *r->out.info = info;
3378
3379         if (!Printer) {
3380                 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3381                         "Invalid handle (%s:%u:%u).\n",
3382                         OUR_HANDLE(r->in.handle)));
3383                 goto done;
3384         }
3385
3386         DEBUG(4,("Printer type %x\n",Printer->printer_type));
3387
3388         /*
3389          *      We are now using the change value, and
3390          *      I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3391          *      I don't have a global notification system, I'm sending back all the
3392          *      informations even when _NOTHING_ has changed.
3393          */
3394
3395         /* We need to keep track of the change value to send back in
3396            RRPCN replies otherwise our updates are ignored. */
3397
3398         Printer->notify.fnpcn = true;
3399
3400         if (Printer->notify.client_connected) {
3401                 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3402                         "Saving change value in request [%x]\n",
3403                         r->in.change_low));
3404                 Printer->notify.change = r->in.change_low;
3405         }
3406
3407         /* just ignore the spoolss_NotifyOption */
3408
3409         switch (Printer->printer_type) {
3410                 case SPLHND_SERVER:
3411                         result = printserver_notify_info(p, r->in.handle,
3412                                                          info, p->mem_ctx);
3413                         break;
3414
3415                 case SPLHND_PRINTER:
3416                         result = printer_notify_info(p, r->in.handle,
3417                                                      info, p->mem_ctx);
3418                         break;
3419         }
3420
3421         Printer->notify.fnpcn = false;
3422
3423 done:
3424         return result;
3425 }
3426
3427 /********************************************************************
3428  * construct_printer_info_0
3429  * fill a printer_info_0 struct
3430  ********************************************************************/
3431
3432 static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
3433                                       struct auth_serversupplied_info *server_info,
3434                                       struct spoolss_PrinterInfo2 *info2,
3435                                       struct spoolss_PrinterInfo0 *r,
3436                                       int snum)
3437 {
3438         int count;
3439         counter_printer_0 *session_counter;
3440         struct timeval setuptime;
3441         print_status_struct status;
3442
3443         r->printername          = talloc_strdup(mem_ctx, info2->printername);
3444         W_ERROR_HAVE_NO_MEMORY(r->printername);
3445
3446         r->servername           = talloc_strdup(mem_ctx, info2->servername);
3447         W_ERROR_HAVE_NO_MEMORY(r->servername);
3448
3449         count = print_queue_length(snum, &status);
3450
3451         /* check if we already have a counter for this printer */
3452         for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3453                 if (session_counter->snum == snum)
3454                         break;
3455         }
3456
3457         /* it's the first time, add it to the list */
3458         if (session_counter == NULL) {
3459                 session_counter = SMB_MALLOC_P(counter_printer_0);
3460                 W_ERROR_HAVE_NO_MEMORY(session_counter);
3461                 ZERO_STRUCTP(session_counter);
3462                 session_counter->snum           = snum;
3463                 session_counter->counter        = 0;
3464                 DLIST_ADD(counter_list, session_counter);
3465         }
3466
3467         /* increment it */
3468         session_counter->counter++;
3469
3470         r->cjobs                        = count;
3471         r->total_jobs                   = 0;
3472         r->total_bytes                  = 0;
3473
3474         get_startup_time(&setuptime);
3475         init_systemtime(&r->time, gmtime(&setuptime.tv_sec));
3476
3477         /* JFM:
3478          * the global_counter should be stored in a TDB as it's common to all the clients
3479          * and should be zeroed on samba startup
3480          */
3481         r->global_counter               = session_counter->counter;
3482         r->total_pages                  = 0;
3483         /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3484         SSVAL(&r->version, 0, 0x0005); /* NT 5 */
3485         SSVAL(&r->version, 2, 0x0893); /* build 2195 */
3486         r->free_build                   = SPOOLSS_RELEASE_BUILD;
3487         r->spooling                     = 0;
3488         r->max_spooling                 = 0;
3489         r->session_counter              = session_counter->counter;
3490         r->num_error_out_of_paper       = 0x0;
3491         r->num_error_not_ready          = 0x0;          /* number of print failure */
3492         r->job_error                    = 0x0;
3493         r->number_of_processors         = 0x1;
3494         r->processor_type               = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
3495         r->high_part_total_bytes        = 0x0;
3496         winreg_printer_get_changeid(mem_ctx, server_info, info2->sharename, &r->change_id); /* ChangeID in milliseconds*/
3497         r->last_error                   = WERR_OK;
3498         r->status                       = nt_printq_status(status.status);
3499         r->enumerate_network_printers   = 0x0;
3500         r->c_setprinter                 = 0x0;
3501         r->processor_architecture       = 0x0;
3502         r->processor_level              = 0x6;          /* 6  ???*/
3503         r->ref_ic                       = 0;
3504         r->reserved2                    = 0;
3505         r->reserved3                    = 0;
3506
3507         return WERR_OK;
3508 }
3509
3510
3511 /********************************************************************
3512  * construct_printer_info1
3513  * fill a spoolss_PrinterInfo1 struct
3514 ********************************************************************/
3515
3516 static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
3517                                       const struct spoolss_PrinterInfo2 *info2,
3518                                       uint32_t flags,
3519                                       struct spoolss_PrinterInfo1 *r,
3520                                       int snum)
3521 {
3522         r->flags                = flags;
3523
3524         r->description          = talloc_asprintf(mem_ctx, "%s,%s,%s",
3525                                                   info2->printername,
3526                                                   info2->drivername,
3527                                                   info2->location);
3528         W_ERROR_HAVE_NO_MEMORY(r->description);
3529
3530         if (info2->comment == NULL || info2->comment[0] == '\0') {
3531                 r->comment      = talloc_strdup(mem_ctx, lp_comment(snum));
3532         } else {
3533                 r->comment      = talloc_strdup(mem_ctx, info2->comment); /* saved comment */
3534         }
3535         W_ERROR_HAVE_NO_MEMORY(r->comment);
3536
3537         r->name                 = talloc_strdup(mem_ctx, info2->printername);
3538         W_ERROR_HAVE_NO_MEMORY(r->name);
3539
3540         return WERR_OK;
3541 }
3542
3543 /********************************************************************
3544  * construct_printer_info2
3545  * fill a spoolss_PrinterInfo2 struct
3546 ********************************************************************/
3547
3548 static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
3549                                       const struct spoolss_PrinterInfo2 *info2,
3550                                       struct spoolss_PrinterInfo2 *r,
3551                                       int snum)
3552 {
3553         int count;
3554         print_status_struct status;
3555
3556         count = print_queue_length(snum, &status);
3557
3558         r->servername           = talloc_strdup(mem_ctx, info2->servername);
3559         W_ERROR_HAVE_NO_MEMORY(r->servername);
3560         r->printername          = talloc_strdup(mem_ctx, info2->printername);
3561         W_ERROR_HAVE_NO_MEMORY(r->printername);
3562         r->sharename            = talloc_strdup(mem_ctx, lp_servicename(snum));
3563         W_ERROR_HAVE_NO_MEMORY(r->sharename);
3564         r->portname             = talloc_strdup(mem_ctx, info2->portname);
3565         W_ERROR_HAVE_NO_MEMORY(r->portname);
3566         r->drivername           = talloc_strdup(mem_ctx, info2->drivername);
3567         W_ERROR_HAVE_NO_MEMORY(r->drivername);
3568
3569         if (info2->comment[0] == '\0') {
3570                 r->comment      = talloc_strdup(mem_ctx, lp_comment(snum));
3571         } else {
3572                 r->comment      = talloc_strdup(mem_ctx, info2->comment);
3573         }
3574         W_ERROR_HAVE_NO_MEMORY(r->comment);
3575
3576         r->location             = talloc_strdup(mem_ctx, info2->location);
3577         W_ERROR_HAVE_NO_MEMORY(r->location);
3578         r->sepfile              = talloc_strdup(mem_ctx, info2->sepfile);
3579         W_ERROR_HAVE_NO_MEMORY(r->sepfile);
3580         r->printprocessor       = talloc_strdup(mem_ctx, info2->printprocessor);
3581         W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
3582         r->datatype             = talloc_strdup(mem_ctx, info2->datatype);
3583         W_ERROR_HAVE_NO_MEMORY(r->datatype);
3584         r->parameters           = talloc_strdup(mem_ctx, info2->parameters);
3585         W_ERROR_HAVE_NO_MEMORY(r->parameters);
3586
3587         r->attributes           = info2->attributes;
3588
3589         r->priority             = info2->priority;
3590         r->defaultpriority      = info2->defaultpriority;
3591         r->starttime            = info2->starttime;
3592         r->untiltime            = info2->untiltime;
3593         r->status               = nt_printq_status(status.status);
3594         r->cjobs                = count;
3595         r->averageppm           = info2->averageppm;
3596
3597         copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3598         if (!r->devmode) {
3599                 DEBUG(8,("Returning NULL Devicemode!\n"));
3600         }
3601
3602         r->secdesc = NULL;
3603
3604         if (info2->secdesc != NULL) {
3605                 /* don't use talloc_steal() here unless you do a deep steal of all
3606                    the SEC_DESC members */
3607
3608                 r->secdesc      = dup_sec_desc(mem_ctx, info2->secdesc);
3609         }
3610
3611         return WERR_OK;
3612 }
3613
3614 /********************************************************************
3615  * construct_printer_info3
3616  * fill a spoolss_PrinterInfo3 struct
3617  ********************************************************************/
3618
3619 static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
3620                                       const struct spoolss_PrinterInfo2 *info2,
3621                                       struct spoolss_PrinterInfo3 *r,
3622                                       int snum)
3623 {
3624         /* These are the components of the SD we are returning. */
3625
3626         if (info2->secdesc != NULL) {
3627                 /* don't use talloc_steal() here unless you do a deep steal of all
3628                    the SEC_DESC members */
3629
3630                 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3631                 W_ERROR_HAVE_NO_MEMORY(r->secdesc);
3632         }
3633
3634         return WERR_OK;
3635 }
3636
3637 /********************************************************************
3638  * construct_printer_info4
3639  * fill a spoolss_PrinterInfo4 struct
3640  ********************************************************************/
3641
3642 static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
3643                                       const struct spoolss_PrinterInfo2 *info2,
3644                                       struct spoolss_PrinterInfo4 *r,
3645                                       int snum)
3646 {
3647         r->printername  = talloc_strdup(mem_ctx, info2->printername);
3648         W_ERROR_HAVE_NO_MEMORY(r->printername);
3649         r->servername   = talloc_strdup(mem_ctx, info2->servername);
3650         W_ERROR_HAVE_NO_MEMORY(r->servername);
3651
3652         r->attributes   = info2->attributes;
3653
3654         return WERR_OK;
3655 }
3656
3657 /********************************************************************
3658  * construct_printer_info5
3659  * fill a spoolss_PrinterInfo5 struct
3660  ********************************************************************/
3661
3662 static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
3663                                       const struct spoolss_PrinterInfo2 *info2,
3664                                       struct spoolss_PrinterInfo5 *r,
3665                                       int snum)
3666 {
3667         r->printername  = talloc_strdup(mem_ctx, info2->printername);
3668         W_ERROR_HAVE_NO_MEMORY(r->printername);
3669         r->portname     = talloc_strdup(mem_ctx, info2->portname);
3670         W_ERROR_HAVE_NO_MEMORY(r->portname);
3671
3672         r->attributes   = info2->attributes;
3673
3674         /* these two are not used by NT+ according to MSDN */
3675         r->device_not_selected_timeout          = 0x0;  /* have seen 0x3a98 */
3676         r->transmission_retry_timeout           = 0x0;  /* have seen 0xafc8 */
3677
3678         return WERR_OK;
3679 }
3680
3681 /********************************************************************
3682  * construct_printer_info_6
3683  * fill a spoolss_PrinterInfo6 struct
3684  ********************************************************************/
3685
3686 static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
3687                                       const struct spoolss_PrinterInfo2 *info2,
3688                                       struct spoolss_PrinterInfo6 *r,
3689                                       int snum)
3690 {
3691         int count;
3692         print_status_struct status;
3693
3694         count = print_queue_length(snum, &status);
3695
3696         r->status = nt_printq_status(status.status);
3697
3698         return WERR_OK;
3699 }
3700
3701 /********************************************************************
3702  * construct_printer_info7
3703  * fill a spoolss_PrinterInfo7 struct
3704  ********************************************************************/
3705
3706 static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
3707                                       Printer_entry *print_hnd,
3708                                       struct spoolss_PrinterInfo7 *r,
3709                                       int snum)
3710 {
3711         struct auth_serversupplied_info *server_info;
3712         struct GUID guid;
3713         NTSTATUS status;
3714
3715         status = make_server_info_system(mem_ctx, &server_info);
3716         if (!NT_STATUS_IS_OK(status)) {
3717                 DEBUG(0, ("construct_printer_info7: "
3718                           "Could not create system server_info\n"));
3719                 return WERR_NOMEM;
3720         }
3721
3722         if (is_printer_published(mem_ctx, server_info, print_hnd->servername,
3723                                  lp_servicename(snum), &guid, NULL)) {
3724                 r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
3725                 r->action = DSPRINT_PUBLISH;
3726         } else {
3727                 r->guid = talloc_strdup(mem_ctx, "");
3728                 r->action = DSPRINT_UNPUBLISH;
3729         }
3730         W_ERROR_HAVE_NO_MEMORY(r->guid);
3731
3732         TALLOC_FREE(server_info);
3733         return WERR_OK;
3734 }
3735
3736 /********************************************************************
3737  * construct_printer_info8
3738  * fill a spoolss_PrinterInfo8 struct
3739  ********************************************************************/
3740
3741 static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
3742                                       const struct spoolss_PrinterInfo2 *info2,
3743                                       struct spoolss_DeviceModeInfo *r,
3744                                       int snum)
3745 {
3746         copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3747         if (!r->devmode) {
3748                 DEBUG(8,("Returning NULL Devicemode!\n"));
3749         }
3750
3751         return WERR_OK;
3752 }
3753
3754
3755 /********************************************************************
3756 ********************************************************************/
3757
3758 static bool snum_is_shared_printer(int snum)
3759 {
3760         return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
3761 }
3762
3763 /********************************************************************
3764  Spoolss_enumprinters.
3765 ********************************************************************/
3766
3767 static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
3768                                            struct auth_serversupplied_info *server_info,
3769                                            uint32_t level,
3770                                            uint32_t flags,
3771                                            union spoolss_PrinterInfo **info_p,
3772                                            uint32_t *count_p)
3773 {
3774         int snum;
3775         int n_services = lp_numservices();
3776         union spoolss_PrinterInfo *info = NULL;
3777         uint32_t count = 0;
3778         WERROR result = WERR_OK;
3779
3780         *count_p = 0;
3781         *info_p = NULL;
3782
3783         for (snum = 0; snum < n_services; snum++) {
3784
3785                 const char *printer;
3786                 struct spoolss_PrinterInfo2 *info2;
3787
3788                 if (!snum_is_shared_printer(snum)) {
3789                         continue;
3790                 }
3791
3792                 printer = lp_const_servicename(snum);
3793
3794                 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
3795                         printer, snum));
3796
3797                 result = winreg_create_printer(mem_ctx,
3798                                                server_info,
3799                                                NULL,
3800                                                printer);
3801                 if (!W_ERROR_IS_OK(result)) {
3802                         goto out;
3803                 }
3804
3805                 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
3806                                             union spoolss_PrinterInfo,
3807                                             count + 1);
3808                 if (!info) {
3809                         result = WERR_NOMEM;
3810                         goto out;
3811                 }
3812
3813                 result = winreg_get_printer(mem_ctx, server_info,
3814                                             NULL, printer, &info2);
3815                 if (!W_ERROR_IS_OK(result)) {
3816                         goto out;
3817                 }
3818
3819                 switch (level) {
3820                 case 0:
3821                         result = construct_printer_info0(info, server_info, info2,
3822                                                          &info[count].info0, snum);
3823                         break;
3824                 case 1:
3825                         result = construct_printer_info1(info, info2, flags,
3826                                                          &info[count].info1, snum);
3827                         break;
3828                 case 2:
3829                         result = construct_printer_info2(info, info2,
3830                                                          &info[count].info2, snum);
3831                         break;
3832                 case 4:
3833                         result = construct_printer_info4(info, info2,
3834                                                          &info[count].info4, snum);
3835                         break;
3836                 case 5:
3837                         result = construct_printer_info5(info, info2,
3838                                                          &info[count].info5, snum);
3839                         break;
3840
3841                 default:
3842                         result = WERR_UNKNOWN_LEVEL;
3843                         goto out;
3844                 }
3845
3846                 if (!W_ERROR_IS_OK(result)) {
3847                         goto out;
3848                 }
3849
3850                 count++;
3851         }
3852
3853         *count_p = count;
3854         *info_p = info;
3855
3856  out:
3857         if (!W_ERROR_IS_OK(result)) {
3858                 TALLOC_FREE(info);
3859                 return result;
3860         }
3861
3862         *info_p = info;
3863
3864         return WERR_OK;
3865 }
3866
3867 /********************************************************************
3868  * handle enumeration of printers at level 0
3869  ********************************************************************/
3870
3871 static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
3872                                   struct auth_serversupplied_info *server_info,
3873                                   uint32_t flags,
3874                                   const char *servername,
3875                                   union spoolss_PrinterInfo **info,
3876                                   uint32_t *count)
3877 {
3878         DEBUG(4,("enum_all_printers_info_0\n"));
3879
3880         return enum_all_printers_info_level(mem_ctx, server_info, 0, flags, info, count);
3881 }
3882
3883
3884 /********************************************************************
3885 ********************************************************************/
3886
3887 static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
3888                                        struct auth_serversupplied_info *server_info,
3889                                        uint32_t flags,
3890                                        union spoolss_PrinterInfo **info,
3891                                        uint32_t *count)
3892 {
3893         DEBUG(4,("enum_all_printers_info_1\n"));
3894
3895         return enum_all_printers_info_level(mem_ctx, server_info, 1, flags, info, count);
3896 }
3897
3898 /********************************************************************
3899  enum_all_printers_info_1_local.
3900 *********************************************************************/
3901
3902 static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
3903                                              struct auth_serversupplied_info *server_info,
3904                                              union spoolss_PrinterInfo **info,
3905                                              uint32_t *count)
3906 {
3907         DEBUG(4,("enum_all_printers_info_1_local\n"));
3908
3909         return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_ICON8, info, count);
3910 }
3911
3912 /********************************************************************
3913  enum_all_printers_info_1_name.
3914 *********************************************************************/
3915
3916 static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
3917                                             struct auth_serversupplied_info *server_info,
3918                                             const char *name,
3919                                             union spoolss_PrinterInfo **info,
3920                                             uint32_t *count)
3921 {
3922         const char *s = name;
3923
3924         DEBUG(4,("enum_all_printers_info_1_name\n"));
3925
3926         if ((name[0] == '\\') && (name[1] == '\\')) {
3927                 s = name + 2;
3928         }
3929
3930         if (!is_myname_or_ipaddr(s)) {
3931                 return WERR_INVALID_NAME;
3932         }
3933
3934         return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_ICON8, info, count);
3935 }
3936
3937 /********************************************************************
3938  enum_all_printers_info_1_network.
3939 *********************************************************************/
3940
3941 static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
3942                                                struct auth_serversupplied_info *server_info,
3943                                                const char *name,
3944                                                union spoolss_PrinterInfo **info,
3945                                                uint32_t *count)
3946 {
3947         const char *s = name;
3948
3949         DEBUG(4,("enum_all_printers_info_1_network\n"));
3950
3951         /* If we respond to a enum_printers level 1 on our name with flags
3952            set to PRINTER_ENUM_REMOTE with a list of printers then these
3953            printers incorrectly appear in the APW browse list.
3954            Specifically the printers for the server appear at the workgroup
3955            level where all the other servers in the domain are
3956            listed. Windows responds to this call with a
3957            WERR_CAN_NOT_COMPLETE so we should do the same. */
3958
3959         if (name[0] == '\\' && name[1] == '\\') {
3960                  s = name + 2;
3961         }
3962
3963         if (is_myname_or_ipaddr(s)) {
3964                  return WERR_CAN_NOT_COMPLETE;
3965         }
3966
3967         return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_NAME, info, count);
3968 }
3969
3970 /********************************************************************
3971  * api_spoolss_enumprinters
3972  *
3973  * called from api_spoolss_enumprinters (see this to understand)
3974  ********************************************************************/
3975
3976 static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
3977                                        struct auth_serversupplied_info *server_info,
3978                                        union spoolss_PrinterInfo **info,
3979                                        uint32_t *count)
3980 {
3981         DEBUG(4,("enum_all_printers_info_2\n"));
3982
3983         return enum_all_printers_info_level(mem_ctx, server_info, 2, 0, info, count);
3984 }
3985
3986 /********************************************************************
3987  * handle enumeration of printers at level 1
3988  ********************************************************************/
3989
3990 static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
3991                                   struct auth_serversupplied_info *server_info,
3992                                   uint32_t flags,
3993                                   const char *name,
3994                                   union spoolss_PrinterInfo **info,
3995                                   uint32_t *count)
3996 {
3997         /* Not all the flags are equals */
3998
3999         if (flags & PRINTER_ENUM_LOCAL) {
4000                 return enum_all_printers_info_1_local(mem_ctx, server_info, info, count);
4001         }
4002
4003         if (flags & PRINTER_ENUM_NAME) {
4004                 return enum_all_printers_info_1_name(mem_ctx, server_info, name, info, count);
4005         }
4006
4007         if (flags & PRINTER_ENUM_NETWORK) {
4008                 return enum_all_printers_info_1_network(mem_ctx, server_info, name, info, count);
4009         }
4010
4011         return WERR_OK; /* NT4sp5 does that */
4012 }
4013
4014 /********************************************************************
4015  * handle enumeration of printers at level 2
4016  ********************************************************************/
4017
4018 static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
4019                                   struct auth_serversupplied_info *server_info,
4020                                   uint32_t flags,
4021                                   const char *servername,
4022                                   union spoolss_PrinterInfo **info,
4023                                   uint32_t *count)
4024 {
4025         if (flags & PRINTER_ENUM_LOCAL) {
4026                 return enum_all_printers_info_2(mem_ctx, server_info, info, count);
4027         }
4028
4029         if (flags & PRINTER_ENUM_NAME) {
4030                 if (!is_myname_or_ipaddr(canon_servername(servername))) {
4031                         return WERR_INVALID_NAME;
4032                 }
4033
4034                 return enum_all_printers_info_2(mem_ctx, server_info, info, count);
4035         }
4036
4037         if (flags & PRINTER_ENUM_REMOTE) {
4038                 return WERR_UNKNOWN_LEVEL;
4039         }
4040
4041         return WERR_OK;
4042 }
4043
4044 /********************************************************************
4045  * handle enumeration of printers at level 4
4046  ********************************************************************/
4047
4048 static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
4049                                   struct auth_serversupplied_info *server_info,
4050                                   uint32_t flags,
4051                                   const char *servername,
4052                                   union spoolss_PrinterInfo **info,
4053                                   uint32_t *count)
4054 {
4055         DEBUG(4,("enum_all_printers_info_4\n"));
4056
4057         return enum_all_printers_info_level(mem_ctx, server_info, 4, flags, info, count);
4058 }
4059
4060
4061 /********************************************************************
4062  * handle enumeration of printers at level 5
4063  ********************************************************************/
4064
4065 static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
4066                                   struct auth_serversupplied_info *server_info,
4067                                   uint32_t flags,
4068                                   const char *servername,
4069                                   union spoolss_PrinterInfo **info,
4070                                   uint32_t *count)
4071 {
4072         DEBUG(4,("enum_all_printers_info_5\n"));
4073
4074         return enum_all_printers_info_level(mem_ctx, server_info, 5, flags, info, count);
4075 }
4076
4077 /****************************************************************
4078  _spoolss_EnumPrinters
4079 ****************************************************************/
4080
4081 WERROR _spoolss_EnumPrinters(struct pipes_struct *p,
4082                              struct spoolss_EnumPrinters *r)
4083 {
4084         const char *name = NULL;
4085         WERROR result;
4086
4087         /* that's an [in out] buffer */
4088
4089         if (!r->in.buffer && (r->in.offered != 0)) {
4090                 return WERR_INVALID_PARAM;
4091         }
4092
4093         DEBUG(4,("_spoolss_EnumPrinters\n"));
4094
4095         *r->out.needed = 0;
4096         *r->out.count = 0;
4097         *r->out.info = NULL;
4098
4099         /*
4100          * Level 1:
4101          *          flags==PRINTER_ENUM_NAME
4102          *           if name=="" then enumerates all printers
4103          *           if name!="" then enumerate the printer
4104          *          flags==PRINTER_ENUM_REMOTE
4105          *          name is NULL, enumerate printers
4106          * Level 2: name!="" enumerates printers, name can't be NULL
4107          * Level 3: doesn't exist
4108          * Level 4: does a local registry lookup
4109          * Level 5: same as Level 2
4110          */
4111
4112         if (r->in.server) {
4113                 name = talloc_strdup_upper(p->mem_ctx, r->in.server);
4114                 W_ERROR_HAVE_NO_MEMORY(name);
4115         }
4116
4117         switch (r->in.level) {
4118         case 0:
4119                 result = enumprinters_level0(p->mem_ctx, p->server_info,
4120                                              r->in.flags, name,
4121                                              r->out.info, r->out.count);
4122                 break;
4123         case 1:
4124                 result = enumprinters_level1(p->mem_ctx, p->server_info,
4125                                              r->in.flags, name,
4126                                              r->out.info, r->out.count);
4127                 break;
4128         case 2:
4129                 result = enumprinters_level2(p->mem_ctx, p->server_info,
4130                                              r->in.flags, name,
4131                                              r->out.info, r->out.count);
4132                 break;
4133         case 4:
4134                 result = enumprinters_level4(p->mem_ctx, p->server_info,
4135                                              r->in.flags, name,
4136                                              r->out.info, r->out.count);
4137                 break;
4138         case 5:
4139                 result = enumprinters_level5(p->mem_ctx, p->server_info,
4140                                              r->in.flags, name,
4141                                              r->out.info, r->out.count);
4142                 break;
4143         default:
4144                 return WERR_UNKNOWN_LEVEL;
4145         }
4146
4147         if (!W_ERROR_IS_OK(result)) {
4148                 return result;
4149         }
4150
4151         *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
4152                                                      spoolss_EnumPrinters, 
4153                                                      *r->out.info, r->in.level,
4154                                                      *r->out.count);
4155         *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
4156         *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
4157
4158         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4159 }
4160
4161 /****************************************************************
4162  _spoolss_GetPrinter
4163 ****************************************************************/
4164
4165 WERROR _spoolss_GetPrinter(struct pipes_struct *p,
4166                            struct spoolss_GetPrinter *r)
4167 {
4168         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
4169         struct spoolss_PrinterInfo2 *info2 = NULL;
4170         WERROR result = WERR_OK;
4171         const char *servername = NULL;
4172         int snum;
4173
4174         /* that's an [in out] buffer */
4175
4176         if (!r->in.buffer && (r->in.offered != 0)) {
4177                 return WERR_INVALID_PARAM;
4178         }
4179
4180         *r->out.needed = 0;
4181
4182         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
4183                 return WERR_BADFID;
4184         }
4185
4186         if (Printer != NULL || Printer->servername != NULL) {
4187                 servername = Printer->servername;
4188         }
4189
4190         result = winreg_get_printer(p->mem_ctx,
4191                                     p->server_info,
4192                                     servername,
4193                                     lp_const_servicename(snum),
4194                                     &info2);
4195         if (!W_ERROR_IS_OK(result)) {
4196                 return result;
4197         }
4198
4199         switch (r->in.level) {
4200         case 0:
4201                 result = construct_printer_info0(p->mem_ctx, p->server_info,
4202                                                  info2,
4203                                                  &r->out.info->info0, snum);
4204                 break;
4205         case 1:
4206                 result = construct_printer_info1(p->mem_ctx, info2,
4207                                                  PRINTER_ENUM_ICON8,
4208                                                  &r->out.info->info1, snum);
4209                 break;
4210         case 2:
4211                 result = construct_printer_info2(p->mem_ctx, info2,
4212                                                  &r->out.info->info2, snum);
4213                 break;
4214         case 3:
4215                 result = construct_printer_info3(p->mem_ctx, info2,
4216                                                  &r->out.info->info3, snum);
4217                 break;
4218         case 4:
4219                 result = construct_printer_info4(p->mem_ctx, info2,
4220                                                  &r->out.info->info4, snum);
4221                 break;
4222         case 5:
4223                 result = construct_printer_info5(p->mem_ctx, info2,
4224                                                  &r->out.info->info5, snum);
4225                 break;
4226         case 6:
4227                 result = construct_printer_info6(p->mem_ctx, info2,
4228                                                  &r->out.info->info6, snum);
4229                 break;
4230         case 7:
4231                 result = construct_printer_info7(p->mem_ctx, Printer,
4232                                                  &r->out.info->info7, snum);
4233                 break;
4234         case 8:
4235                 result = construct_printer_info8(p->mem_ctx, info2,
4236                                                  &r->out.info->info8, snum);
4237                 break;
4238         default:
4239                 result = WERR_UNKNOWN_LEVEL;
4240                 break;
4241         }
4242
4243         if (!W_ERROR_IS_OK(result)) {
4244                 DEBUG(0, ("_spoolss_GetPrinter: failed to construct printer info level %d - %s\n",
4245                           r->in.level, win_errstr(result)));
4246                 TALLOC_FREE(r->out.info);
4247                 return result;
4248         }
4249
4250         *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo, 
4251                                                r->out.info, r->in.level);
4252         r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
4253
4254         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4255 }
4256
4257 /********************************************************************
4258  ********************************************************************/
4259
4260 #define FILL_DRIVER_STRING(mem_ctx, in, out) \
4261         do { \
4262                 if (in && strlen(in)) { \
4263                         out = talloc_strdup(mem_ctx, in); \
4264                 } else { \
4265                         out = talloc_strdup(mem_ctx, ""); \
4266                 } \
4267                 W_ERROR_HAVE_NO_MEMORY(out); \
4268         } while (0);
4269
4270 #define FILL_DRIVER_UNC_STRING(mem_ctx, server, arch, ver, in, out) \
4271         do { \
4272                 if (in && strlen(in)) { \
4273                         out = talloc_asprintf(mem_ctx, "\\\\%s\\print$\\%s\\%d\\%s", server, get_short_archi(arch), ver, in); \
4274                 } else { \
4275                         out = talloc_strdup(mem_ctx, ""); \
4276                 } \
4277                 W_ERROR_HAVE_NO_MEMORY(out); \
4278         } while (0);
4279
4280 static WERROR string_array_from_driver_info(TALLOC_CTX *mem_ctx,
4281                                                   const char **string_array,
4282                                                   const char ***presult,
4283                                                   const char *cservername,
4284                                                   const char *arch,
4285                                                   int version)
4286 {
4287         int i, num_strings = 0;
4288         const char **array = NULL;
4289
4290         if (string_array == NULL) {
4291                 return WERR_INVALID_PARAMETER;;
4292         }
4293
4294         for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
4295                 const char *str = NULL;
4296
4297                 if (cservername == NULL || arch == NULL) {
4298                         FILL_DRIVER_STRING(mem_ctx, string_array[i], str);
4299                 } else {
4300                         FILL_DRIVER_UNC_STRING(mem_ctx, cservername, arch, version, string_array[i], str);
4301                 }
4302
4303                 if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
4304                         TALLOC_FREE(array);
4305                         return WERR_NOMEM;
4306                 }
4307         }
4308
4309         if (i > 0) {
4310                 ADD_TO_ARRAY(mem_ctx, const char *, NULL,
4311                              &array, &num_strings);
4312         }
4313
4314         if (presult) {
4315                 *presult = array;
4316         }
4317
4318         return WERR_OK;
4319 }
4320
4321 /********************************************************************
4322  * fill a spoolss_DriverInfo1 struct
4323  ********************************************************************/
4324
4325 static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
4326                                         struct spoolss_DriverInfo1 *r,
4327                                         const struct spoolss_DriverInfo8 *driver,
4328                                         const char *servername)
4329 {
4330         r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4331         W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4332
4333         return WERR_OK;
4334 }
4335
4336 /********************************************************************
4337  * fill a spoolss_DriverInfo2 struct
4338  ********************************************************************/
4339
4340 static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
4341                                         struct spoolss_DriverInfo2 *r,
4342                                         const struct spoolss_DriverInfo8 *driver,
4343                                         const char *servername)
4344
4345 {
4346         const char *cservername = canon_servername(servername);
4347
4348         r->version              = driver->version;
4349
4350         r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4351         W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4352         r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
4353         W_ERROR_HAVE_NO_MEMORY(r->architecture);
4354
4355         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4356                                driver->architecture,
4357                                driver->version,
4358                                driver->driver_path,
4359                                r->driver_path);
4360
4361         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4362                                driver->architecture,
4363                                driver->version,
4364                                driver->data_file,
4365                                r->data_file);
4366
4367         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4368                                driver->architecture,
4369                                driver->version,
4370                                driver->config_file,
4371                                r->config_file);
4372
4373         return WERR_OK;
4374 }
4375
4376 /********************************************************************
4377  * fill a spoolss_DriverInfo3 struct
4378  ********************************************************************/
4379
4380 static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
4381                                         struct spoolss_DriverInfo3 *r,
4382                                         const struct spoolss_DriverInfo8 *driver,
4383                                         const char *servername)
4384 {
4385         const char *cservername = canon_servername(servername);
4386
4387         r->version              = driver->version;
4388
4389         r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4390         W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4391         r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
4392         W_ERROR_HAVE_NO_MEMORY(r->architecture);
4393
4394         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4395                                driver->architecture,
4396                                driver->version,
4397                                driver->driver_path,
4398                                r->driver_path);
4399
4400         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4401                                driver->architecture,
4402                                driver->version,
4403                                driver->data_file,
4404                                r->data_file);
4405
4406         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4407                                driver->architecture,
4408                                driver->version,
4409                                driver->config_file,
4410                                r->config_file);
4411
4412         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4413                                driver->architecture,
4414                                driver->version,
4415                                driver->help_file,
4416                                r->help_file);
4417
4418         FILL_DRIVER_STRING(mem_ctx,
4419                            driver->monitor_name,
4420                            r->monitor_name);
4421
4422         FILL_DRIVER_STRING(mem_ctx,
4423                            driver->default_datatype,
4424                            r->default_datatype);
4425
4426         return string_array_from_driver_info(mem_ctx,
4427                                              driver->dependent_files,
4428                                              &r->dependent_files,
4429                                              cservername,
4430                                              driver->architecture,
4431                                              driver->version);
4432 }
4433
4434 /********************************************************************
4435  * fill a spoolss_DriverInfo4 struct
4436  ********************************************************************/
4437
4438 static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
4439                                         struct spoolss_DriverInfo4 *r,
4440                                         const struct spoolss_DriverInfo8 *driver,
4441                                         const char *servername)
4442 {
4443         const char *cservername = canon_servername(servername);
4444         WERROR result;
4445
4446         r->version              = driver->version;
4447
4448         r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4449         W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4450         r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
4451         W_ERROR_HAVE_NO_MEMORY(r->architecture);
4452
4453         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4454                                driver->architecture,
4455                                driver->version,
4456                                driver->driver_path,
4457                                r->driver_path);
4458
4459         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4460                                driver->architecture,
4461                                driver->version,
4462                                driver->data_file,
4463                                r->data_file);
4464
4465         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4466                                driver->architecture,
4467                                driver->version,
4468                                driver->config_file,
4469                                r->config_file);
4470
4471         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4472                                driver->architecture,
4473                                driver->version,
4474                                driver->help_file,
4475                                r->help_file);
4476
4477         result = string_array_from_driver_info(mem_ctx,
4478                                                driver->dependent_files,
4479                                                &r->dependent_files,
4480                                                cservername,
4481                                                driver->architecture,
4482                                                driver->version);
4483         if (!W_ERROR_IS_OK(result)) {
4484                 return result;
4485         }
4486
4487         FILL_DRIVER_STRING(mem_ctx,
4488                            driver->monitor_name,
4489                            r->monitor_name);
4490
4491         FILL_DRIVER_STRING(mem_ctx,
4492                            driver->default_datatype,
4493                            r->default_datatype);
4494
4495
4496         result = string_array_from_driver_info(mem_ctx,
4497                                                driver->previous_names,
4498                                                &r->previous_names,
4499                                                NULL, NULL, 0);
4500
4501         return result;
4502 }
4503
4504 /********************************************************************
4505  * fill a spoolss_DriverInfo5 struct
4506  ********************************************************************/
4507
4508 static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
4509                                         struct spoolss_DriverInfo5 *r,
4510                                         const struct spoolss_DriverInfo8 *driver,
4511                                         const char *servername)
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->architecture,
4524                                driver->version,
4525                                driver->driver_path,
4526                                r->driver_path);
4527
4528         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4529                                driver->architecture,
4530                                driver->version,
4531                                driver->data_file,
4532                                r->data_file);
4533
4534         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4535                                driver->architecture,
4536                                driver->version,
4537                                driver->config_file,
4538                                r->config_file);
4539
4540         r->driver_attributes    = 0;
4541         r->config_version       = 0;
4542         r->driver_version       = 0;
4543
4544         return WERR_OK;
4545 }
4546 /********************************************************************
4547  * fill a spoolss_DriverInfo6 struct
4548  ********************************************************************/
4549
4550 static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
4551                                         struct spoolss_DriverInfo6 *r,
4552                                         const struct spoolss_DriverInfo8 *driver,
4553                                         const char *servername)
4554 {
4555         const char *cservername = canon_servername(servername);
4556         WERROR result;
4557
4558         r->version              = driver->version;
4559
4560         r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4561         W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4562         r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
4563         W_ERROR_HAVE_NO_MEMORY(r->architecture);
4564
4565         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4566                                driver->architecture,
4567                                driver->version,
4568                                driver->driver_path,
4569                                r->driver_path);
4570
4571         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4572                                driver->architecture,
4573                                driver->version,
4574                                driver->data_file,
4575                                r->data_file);
4576
4577         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4578                                driver->architecture,
4579                                driver->version,
4580                                driver->config_file,
4581                                r->config_file);
4582
4583         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4584                                driver->architecture,
4585                                driver->version,
4586                                driver->help_file,
4587                                r->help_file);
4588
4589         FILL_DRIVER_STRING(mem_ctx,
4590                            driver->monitor_name,
4591                            r->monitor_name);
4592
4593         FILL_DRIVER_STRING(mem_ctx,
4594                            driver->default_datatype,
4595                            r->default_datatype);
4596
4597         result = string_array_from_driver_info(mem_ctx,
4598                                                driver->dependent_files,
4599                                                &r->dependent_files,
4600                                                cservername,
4601                                                driver->architecture,
4602                                                driver->version);
4603         if (!W_ERROR_IS_OK(result)) {
4604                 return result;
4605         }
4606
4607         result = string_array_from_driver_info(mem_ctx,
4608                                                driver->previous_names,
4609                                                &r->previous_names,
4610                                                NULL, NULL, 0);
4611         if (!W_ERROR_IS_OK(result)) {
4612                 return result;
4613         }
4614
4615         r->driver_date          = driver->driver_date;
4616         r->driver_version       = driver->driver_version;
4617
4618         FILL_DRIVER_STRING(mem_ctx,
4619                            driver->manufacturer_name,
4620                            r->manufacturer_name);
4621         FILL_DRIVER_STRING(mem_ctx,
4622                            driver->manufacturer_url,
4623                            r->manufacturer_url);
4624         FILL_DRIVER_STRING(mem_ctx,
4625                            driver->hardware_id,
4626                            r->hardware_id);
4627         FILL_DRIVER_STRING(mem_ctx,
4628                            driver->provider,
4629                            r->provider);
4630
4631         return WERR_OK;
4632 }
4633
4634 /********************************************************************
4635  * fill a spoolss_DriverInfo8 struct
4636  ********************************************************************/
4637
4638 static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
4639                                         struct spoolss_DriverInfo8 *r,
4640                                         const struct spoolss_DriverInfo8 *driver,
4641                                         const char *servername)
4642 {
4643         const char *cservername = canon_servername(servername);
4644         WERROR result;
4645
4646         r->version              = driver->version;
4647
4648         r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4649         W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4650         r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
4651         W_ERROR_HAVE_NO_MEMORY(r->architecture);
4652
4653         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4654                                driver->architecture,
4655                                driver->version,
4656                                driver->driver_path,
4657                                r->driver_path);
4658
4659         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4660                                driver->architecture,
4661                                driver->version,
4662                                driver->data_file,
4663                                r->data_file);
4664
4665         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4666                                driver->architecture,
4667                                driver->version,
4668                                driver->config_file,
4669                                r->config_file);
4670
4671         FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4672                                driver->architecture,
4673                                driver->version,
4674                                driver->help_file,
4675                                r->help_file);
4676
4677         FILL_DRIVER_STRING(mem_ctx,
4678                            driver->monitor_name,
4679                            r->monitor_name);
4680
4681         FILL_DRIVER_STRING(mem_ctx,
4682                            driver->default_datatype,
4683                            r->default_datatype);
4684
4685         result = string_array_from_driver_info(mem_ctx,
4686                                                driver->dependent_files,
4687                                                &r->dependent_files,
4688                                                cservername,
4689                                                driver->architecture,
4690                                                driver->version);
4691         if (!W_ERROR_IS_OK(result)) {
4692                 return result;
4693         }
4694
4695         result = string_array_from_driver_info(mem_ctx,
4696                                                driver->previous_names,
4697                                                &r->previous_names,
4698                                                NULL, NULL, 0);
4699         if (!W_ERROR_IS_OK(result)) {
4700                 return result;
4701         }
4702
4703         r->driver_date          = driver->driver_date;
4704         r->driver_version       = driver->driver_version;
4705
4706         FILL_DRIVER_STRING(mem_ctx,
4707                            driver->manufacturer_name,
4708                            r->manufacturer_name);
4709         FILL_DRIVER_STRING(mem_ctx,
4710                            driver->manufacturer_url,
4711                            r->manufacturer_url);
4712         FILL_DRIVER_STRING(mem_ctx,
4713                            driver->hardware_id,
4714                            r->hardware_id);
4715         FILL_DRIVER_STRING(mem_ctx,
4716                            driver->provider,
4717                            r->provider);
4718
4719         FILL_DRIVER_STRING(mem_ctx,
4720                            driver->print_processor,
4721                            r->print_processor);
4722         FILL_DRIVER_STRING(mem_ctx,
4723                            driver->vendor_setup,
4724                            r->vendor_setup);
4725
4726         result = string_array_from_driver_info(mem_ctx,
4727                                                driver->color_profiles,
4728                                                &r->color_profiles,
4729                                                NULL, NULL, 0);
4730         if (!W_ERROR_IS_OK(result)) {
4731                 return result;
4732         }
4733
4734         FILL_DRIVER_STRING(mem_ctx,
4735                            driver->inf_path,
4736                            r->inf_path);
4737
4738         r->printer_driver_attributes    = driver->printer_driver_attributes;
4739
4740         result = string_array_from_driver_info(mem_ctx,
4741                                                driver->core_driver_dependencies,
4742                                                &r->core_driver_dependencies,
4743                                                NULL, NULL, 0);
4744         if (!W_ERROR_IS_OK(result)) {
4745                 return result;
4746         }
4747
4748         r->min_inbox_driver_ver_date    = driver->min_inbox_driver_ver_date;
4749         r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
4750
4751         return WERR_OK;
4752 }
4753
4754 #if 0 /* disabled until marshalling issues are resolved - gd */
4755 /********************************************************************
4756  ********************************************************************/
4757
4758 static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
4759                                           struct spoolss_DriverFileInfo *r,
4760                                           const char *cservername,
4761                                           const char *file_name,
4762                                           enum spoolss_DriverFileType file_type,
4763                                           uint32_t file_version)
4764 {
4765         r->file_name    = talloc_asprintf(mem_ctx, "\\\\%s%s",
4766                                           cservername, file_name);
4767         W_ERROR_HAVE_NO_MEMORY(r->file_name);
4768         r->file_type    = file_type;
4769         r->file_version = file_version;
4770
4771         return WERR_OK;
4772 }
4773
4774 /********************************************************************
4775  ********************************************************************/
4776
4777 static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
4778                                                  const struct spoolss_DriverInfo8 *driver,
4779                                                  const char *cservername,
4780                                                  struct spoolss_DriverFileInfo **info_p,
4781                                                  uint32_t *count_p)
4782 {
4783         struct spoolss_DriverFileInfo *info = NULL;
4784         uint32_t count = 0;
4785         WERROR result;
4786         uint32_t i;
4787
4788         *info_p = NULL;
4789         *count_p = 0;
4790
4791         if (strlen(driver->driver_path)) {
4792                 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4793                                             struct spoolss_DriverFileInfo,
4794                                             count + 1);
4795                 W_ERROR_HAVE_NO_MEMORY(info);
4796                 result = fill_spoolss_DriverFileInfo(info,
4797                                                      &info[count],
4798                                                      cservername,
4799                                                      driver->driver_path,
4800                                                      SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
4801                                                      0);
4802                 W_ERROR_NOT_OK_RETURN(result);
4803                 count++;
4804         }
4805
4806         if (strlen(driver->config_file)) {
4807                 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4808                                             struct spoolss_DriverFileInfo,
4809                                             count + 1);
4810                 W_ERROR_HAVE_NO_MEMORY(info);
4811                 result = fill_spoolss_DriverFileInfo(info,
4812                                                      &info[count],
4813                                                      cservername,
4814                                                      driver->config_file,
4815                                                      SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
4816                                                      0);
4817                 W_ERROR_NOT_OK_RETURN(result);
4818                 count++;
4819         }
4820
4821         if (strlen(driver->data_file)) {
4822                 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4823                                             struct spoolss_DriverFileInfo,
4824                                             count + 1);
4825                 W_ERROR_HAVE_NO_MEMORY(info);
4826                 result = fill_spoolss_DriverFileInfo(info,
4827                                                      &info[count],
4828                                                      cservername,
4829                                                      driver->data_file,
4830                                                      SPOOLSS_DRIVER_FILE_TYPE_DATA,
4831                                                      0);
4832                 W_ERROR_NOT_OK_RETURN(result);
4833                 count++;
4834         }
4835
4836         if (strlen(driver->help_file)) {
4837                 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4838                                             struct spoolss_DriverFileInfo,
4839                                             count + 1);
4840                 W_ERROR_HAVE_NO_MEMORY(info);
4841                 result = fill_spoolss_DriverFileInfo(info,
4842                                                      &info[count],
4843                                                      cservername,
4844                                                      driver->help_file,
4845                                                      SPOOLSS_DRIVER_FILE_TYPE_HELP,
4846                                                      0);
4847                 W_ERROR_NOT_OK_RETURN(result);
4848                 count++;
4849         }
4850
4851         for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
4852                 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4853                                             struct spoolss_DriverFileInfo,
4854                                             count + 1);
4855                 W_ERROR_HAVE_NO_MEMORY(info);
4856                 result = fill_spoolss_DriverFileInfo(info,
4857                                                      &info[count],
4858                                                      cservername,
4859                                                      driver->dependent_files[i],
4860                                                      SPOOLSS_DRIVER_FILE_TYPE_OTHER,
4861                                                      0);
4862                 W_ERROR_NOT_OK_RETURN(result);
4863                 count++;
4864         }
4865
4866         *info_p = info;
4867         *count_p = count;
4868
4869         return WERR_OK;
4870 }
4871
4872 /********************************************************************
4873  * fill a spoolss_DriverInfo101 struct
4874  ********************************************************************/
4875
4876 static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
4877                                           struct spoolss_DriverInfo101 *r,
4878                                           const struct spoolss_DriverInfo8 *driver,
4879                                           const char *servername)
4880 {
4881         const char *cservername = canon_servername(servername);
4882         WERROR result;
4883
4884         r->version              = driver->version;
4885
4886         r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4887         W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4888         r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
4889         W_ERROR_HAVE_NO_MEMORY(r->architecture);
4890
4891         result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
4892                                                     cservername,
4893                                                     &r->file_info,
4894                                                     &r->file_count);
4895         if (!W_ERROR_IS_OK(result)) {
4896                 return result;
4897         }
4898
4899         FILL_DRIVER_STRING(mem_ctx,
4900                            driver->monitor_name,
4901                            r->monitor_name);
4902
4903         FILL_DRIVER_STRING(mem_ctx,
4904                            driver->default_datatype,
4905                            r->default_datatype);
4906
4907         result = string_array_from_driver_info(mem_ctx,
4908                                                driver->previous_names,
4909                                                &r->previous_names,
4910                                                NULL, NULL, 0);
4911         if (!W_ERROR_IS_OK(result)) {
4912                 return result;
4913         }
4914
4915         r->driver_date          = driver->driver_date;
4916         r->driver_version       = driver->driver_version;
4917
4918         FILL_DRIVER_STRING(mem_ctx,
4919                            driver->manufacturer_name,
4920                            r->manufacturer_name);
4921         FILL_DRIVER_STRING(mem_ctx,
4922                            driver->manufacturer_url,
4923                            r->manufacturer_url);
4924         FILL_DRIVER_STRING(mem_ctx,
4925                            driver->hardware_id,
4926                            r->hardware_id);
4927         FILL_DRIVER_STRING(mem_ctx,
4928                            driver->provider,
4929                            r->provider);
4930
4931         return WERR_OK;
4932 }
4933 #endif
4934 /********************************************************************
4935  ********************************************************************/
4936
4937 static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
4938                                                   struct auth_serversupplied_info *server_info,
4939                                                   uint32_t level,
4940                                                   union spoolss_DriverInfo *r,
4941                                                   int snum,
4942                                                   const char *servername,
4943                                                   const char *architecture,
4944                                                   uint32_t version)
4945 {
4946         struct spoolss_PrinterInfo2 *pinfo2 = NULL;
4947         struct spoolss_DriverInfo8 *driver;
4948         WERROR result;
4949
4950         result = winreg_get_printer(mem_ctx,
4951                                     server_info,
4952                                     servername,
4953                                     lp_const_servicename(snum),
4954                                     &pinfo2);
4955
4956         DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
4957                 win_errstr(result)));
4958
4959         if (!W_ERROR_IS_OK(result)) {
4960                 return WERR_INVALID_PRINTER_NAME;
4961         }
4962
4963         result = winreg_get_driver(mem_ctx, server_info, architecture,
4964                                    pinfo2->drivername, version, &driver);
4965
4966         DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
4967                 win_errstr(result)));
4968
4969         if (!W_ERROR_IS_OK(result)) {
4970                 /*
4971                  * Is this a W2k client ?
4972                  */
4973
4974                 if (version < 3) {
4975                         talloc_free(pinfo2);
4976                         return WERR_UNKNOWN_PRINTER_DRIVER;
4977                 }
4978
4979                 /* Yes - try again with a WinNT driver. */
4980                 version = 2;
4981                 result = winreg_get_driver(mem_ctx, server_info, architecture,
4982                                            pinfo2->drivername,
4983                                            version, &driver);
4984                 DEBUG(8,("construct_printer_driver_level: status: %s\n",
4985                         win_errstr(result)));
4986                 if (!W_ERROR_IS_OK(result)) {
4987                         talloc_free(pinfo2);
4988                         return WERR_UNKNOWN_PRINTER_DRIVER;
4989                 }
4990         }
4991
4992         switch (level) {
4993         case 1:
4994                 result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
4995                 break;
4996         case 2:
4997                 result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
4998                 break;
4999         case 3:
5000                 result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
5001                 break;
5002         case 4:
5003                 result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
5004                 break;
5005         case 5:
5006                 result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
5007                 break;
5008         case 6:
5009                 result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
5010                 break;
5011         case 8:
5012                 result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
5013                 break;
5014 #if 0 /* disabled until marshalling issues are resolved - gd */
5015         case 101:
5016                 result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
5017                 break;
5018 #endif
5019         default:
5020                 result = WERR_UNKNOWN_LEVEL;
5021                 break;
5022         }
5023
5024         talloc_free(pinfo2);
5025         talloc_free(driver);
5026
5027         return result;
5028 }
5029
5030 /****************************************************************
5031  _spoolss_GetPrinterDriver2
5032 ****************************************************************/
5033
5034 WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p,
5035                                   struct spoolss_GetPrinterDriver2 *r)
5036 {
5037         Printer_entry *printer;
5038         WERROR result;
5039
5040         int snum;
5041
5042         /* that's an [in out] buffer */
5043
5044         if (!r->in.buffer && (r->in.offered != 0)) {
5045                 return WERR_INVALID_PARAM;
5046         }
5047
5048         DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5049
5050         if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
5051                 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5052                 return WERR_INVALID_PRINTER_NAME;
5053         }
5054
5055         *r->out.needed = 0;
5056         *r->out.server_major_version = 0;
5057         *r->out.server_minor_version = 0;
5058
5059         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5060                 return WERR_BADFID;
5061         }
5062
5063         result = construct_printer_driver_info_level(p->mem_ctx, p->server_info,
5064                                                      r->in.level, r->out.info,
5065                                                      snum, printer->servername,
5066                                                      r->in.architecture,
5067                                                      r->in.client_major_version);
5068         if (!W_ERROR_IS_OK(result)) {
5069                 TALLOC_FREE(r->out.info);
5070                 return result;
5071         }
5072
5073         *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo, 
5074                                                r->out.info, r->in.level);
5075         r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
5076
5077         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
5078 }
5079
5080
5081 /****************************************************************
5082  _spoolss_StartPagePrinter
5083 ****************************************************************/
5084
5085 WERROR _spoolss_StartPagePrinter(struct pipes_struct *p,
5086                                  struct spoolss_StartPagePrinter *r)
5087 {
5088         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5089
5090         if (!Printer) {
5091                 DEBUG(3,("_spoolss_StartPagePrinter: "
5092                         "Error in startpageprinter printer handle\n"));
5093                 return WERR_BADFID;
5094         }
5095
5096         Printer->page_started = true;
5097         return WERR_OK;
5098 }
5099
5100 /****************************************************************
5101  _spoolss_EndPagePrinter
5102 ****************************************************************/
5103
5104 WERROR _spoolss_EndPagePrinter(struct pipes_struct *p,
5105                                struct spoolss_EndPagePrinter *r)
5106 {
5107         int snum;
5108
5109         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5110
5111         if (!Printer) {
5112                 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5113                         OUR_HANDLE(r->in.handle)));
5114                 return WERR_BADFID;
5115         }
5116
5117         if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5118                 return WERR_BADFID;
5119
5120         Printer->page_started = false;
5121         print_job_endpage(snum, Printer->jobid);
5122
5123         return WERR_OK;
5124 }
5125
5126 /****************************************************************
5127  _spoolss_StartDocPrinter
5128 ****************************************************************/
5129
5130 WERROR _spoolss_StartDocPrinter(struct pipes_struct *p,
5131                                 struct spoolss_StartDocPrinter *r)
5132 {
5133         struct spoolss_DocumentInfo1 *info_1;
5134         int snum;
5135         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5136         WERROR werr;
5137
5138         if (!Printer) {
5139                 DEBUG(2,("_spoolss_StartDocPrinter: "
5140                         "Invalid handle (%s:%u:%u)\n",
5141                         OUR_HANDLE(r->in.handle)));
5142                 return WERR_BADFID;
5143         }
5144
5145         if (Printer->jobid) {
5146                 DEBUG(2, ("_spoolss_StartDocPrinter: "
5147                           "StartDocPrinter called twice! "
5148                           "(existing jobid = %d)\n", Printer->jobid));
5149                 return WERR_INVALID_HANDLE;
5150         }
5151
5152         if (r->in.level != 1) {
5153                 return WERR_UNKNOWN_LEVEL;
5154         }
5155
5156         info_1 = r->in.info.info1;
5157
5158         /*
5159          * a nice thing with NT is it doesn't listen to what you tell it.
5160          * when asked to send _only_ RAW datas, it tries to send datas
5161          * in EMF format.
5162          *
5163          * So I add checks like in NT Server ...
5164          */
5165
5166         if (info_1->datatype) {
5167                 if (strcmp(info_1->datatype, "RAW") != 0) {
5168                         *r->out.job_id = 0;
5169                         return WERR_INVALID_DATATYPE;
5170                 }
5171         }
5172
5173         /* get the share number of the printer */
5174         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5175                 return WERR_BADFID;
5176         }
5177
5178         werr = print_job_start(p->server_info, snum,
5179                                 info_1->document_name, info_1->output_file,
5180                                 Printer->devmode, &Printer->jobid);
5181
5182         /* An error occured in print_job_start() so return an appropriate
5183            NT error code. */
5184
5185         if (!W_ERROR_IS_OK(werr)) {
5186                 return werr;
5187         }
5188
5189         Printer->document_started = true;
5190         *r->out.job_id = Printer->jobid;
5191
5192         return WERR_OK;
5193 }
5194
5195 /****************************************************************
5196  _spoolss_EndDocPrinter
5197 ****************************************************************/
5198
5199 WERROR _spoolss_EndDocPrinter(struct pipes_struct *p,
5200                               struct spoolss_EndDocPrinter *r)
5201 {
5202         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5203         NTSTATUS status;
5204         int snum;
5205
5206         if (!Printer) {
5207                 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5208                         OUR_HANDLE(r->in.handle)));
5209                 return WERR_BADFID;
5210         }
5211
5212         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5213                 return WERR_BADFID;
5214         }
5215
5216         Printer->document_started = false;
5217         status = print_job_end(snum, Printer->jobid, NORMAL_CLOSE);
5218         if (!NT_STATUS_IS_OK(status)) {
5219                 DEBUG(2, ("_spoolss_EndDocPrinter: "
5220                           "print_job_end failed [%s]\n",
5221                           nt_errstr(status)));
5222         }
5223
5224         Printer->jobid = 0;
5225         return ntstatus_to_werror(status);
5226 }
5227
5228 /****************************************************************
5229  _spoolss_WritePrinter
5230 ****************************************************************/
5231
5232 WERROR _spoolss_WritePrinter(struct pipes_struct *p,
5233                              struct spoolss_WritePrinter *r)
5234 {
5235         ssize_t buffer_written;
5236         int snum;
5237         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5238
5239         if (!Printer) {
5240                 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5241                         OUR_HANDLE(r->in.handle)));
5242                 *r->out.num_written = r->in._data_size;
5243                 return WERR_BADFID;
5244         }
5245
5246         if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5247                 return WERR_BADFID;
5248
5249         /* print_job_write takes care of checking for PJOB_SMBD_SPOOLING */
5250         buffer_written = print_job_write(snum, Printer->jobid,
5251                                                    (const char *)r->in.data.data,
5252                                                    (SMB_OFF_T)-1,
5253                                                    (size_t)r->in._data_size);
5254         if (buffer_written == (ssize_t)-1) {
5255                 *r->out.num_written = 0;
5256                 if (errno == ENOSPC)
5257                         return WERR_NO_SPOOL_SPACE;
5258                 else
5259                         return WERR_ACCESS_DENIED;
5260         }
5261
5262         *r->out.num_written = r->in._data_size;
5263
5264         return WERR_OK;
5265 }
5266
5267 /********************************************************************
5268  * api_spoolss_getprinter
5269  * called from the spoolss dispatcher
5270  *
5271  ********************************************************************/
5272
5273 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
5274                               struct pipes_struct *p)
5275 {
5276         int snum;
5277         WERROR errcode = WERR_BADFUNC;
5278         Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5279
5280         if (!Printer) {
5281                 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5282                         OUR_HANDLE(handle)));
5283                 return WERR_BADFID;
5284         }
5285
5286         if (!get_printer_snum(p, handle, &snum, NULL))
5287                 return WERR_BADFID;
5288
5289         switch (command) {
5290         case SPOOLSS_PRINTER_CONTROL_PAUSE:
5291                 errcode = print_queue_pause(p->server_info, snum);
5292                 break;
5293         case SPOOLSS_PRINTER_CONTROL_RESUME:
5294         case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5295                 errcode = print_queue_resume(p->server_info, snum);
5296                 break;
5297         case SPOOLSS_PRINTER_CONTROL_PURGE:
5298                 errcode = print_queue_purge(p->server_info, snum);
5299                 break;
5300         default:
5301                 return WERR_UNKNOWN_LEVEL;
5302         }
5303
5304         return errcode;
5305 }
5306
5307
5308 /****************************************************************
5309  _spoolss_AbortPrinter
5310  * From MSDN: "Deletes printer's spool file if printer is configured
5311  * for spooling"
5312 ****************************************************************/
5313
5314 WERROR _spoolss_AbortPrinter(struct pipes_struct *p,
5315                              struct spoolss_AbortPrinter *r)
5316 {
5317         Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
5318         int             snum;
5319         WERROR          errcode = WERR_OK;
5320
5321         if (!Printer) {
5322                 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5323                         OUR_HANDLE(r->in.handle)));
5324                 return WERR_BADFID;
5325         }
5326
5327         if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5328                 return WERR_BADFID;
5329
5330         if (!Printer->document_started) {
5331                 return WERR_SPL_NO_STARTDOC;
5332         }
5333
5334         errcode = print_job_delete(p->server_info, snum, Printer->jobid);
5335
5336         return errcode;
5337 }
5338
5339 /********************************************************************
5340  * called by spoolss_api_setprinter
5341  * when updating a printer description
5342  ********************************************************************/
5343
5344 static WERROR update_printer_sec(struct policy_handle *handle,
5345                                  struct pipes_struct *p,
5346                                  struct sec_desc_buf *secdesc_ctr)
5347 {
5348         struct spoolss_security_descriptor *new_secdesc = NULL;
5349         struct spoolss_security_descriptor *old_secdesc = NULL;
5350         const char *printer;
5351         WERROR result;
5352         int snum;
5353
5354         Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5355
5356         if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5357                 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5358                          OUR_HANDLE(handle)));
5359
5360                 result = WERR_BADFID;
5361                 goto done;
5362         }
5363
5364         if (secdesc_ctr == NULL) {
5365                 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5366                 result = WERR_INVALID_PARAM;
5367                 goto done;
5368         }
5369         printer = lp_const_servicename(snum);
5370
5371         /* Check the user has permissions to change the security
5372            descriptor.  By experimentation with two NT machines, the user
5373            requires Full Access to the printer to change security
5374            information. */
5375
5376         if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5377                 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5378                 result = WERR_ACCESS_DENIED;
5379                 goto done;
5380         }
5381
5382         /* NT seems to like setting the security descriptor even though
5383            nothing may have actually changed. */
5384         result = winreg_get_printer_secdesc(p->mem_ctx,
5385                                             p->server_info,
5386                                             printer,
5387                                             &old_secdesc);
5388         if (!W_ERROR_IS_OK(result)) {
5389                 DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n"));
5390                 result = WERR_BADFID;
5391                 goto done;
5392         }
5393
5394         if (DEBUGLEVEL >= 10) {
5395                 struct security_acl *the_acl;
5396                 int i;
5397
5398                 the_acl = old_secdesc->dacl;
5399                 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5400                            printer, the_acl->num_aces));
5401
5402                 for (i = 0; i < the_acl->num_aces; i++) {
5403                         DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5404                                            &the_acl->aces[i].trustee),
5405                                   the_acl->aces[i].access_mask));
5406                 }
5407
5408                 the_acl = secdesc_ctr->sd->dacl;
5409
5410                 if (the_acl) {
5411                         DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5412                                    printer, the_acl->num_aces));
5413
5414                         for (i = 0; i < the_acl->num_aces; i++) {
5415                                 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5416                                                    &the_acl->aces[i].trustee),
5417                                            the_acl->aces[i].access_mask));
5418                         }
5419                 } else {
5420                         DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5421                 }
5422         }
5423
5424         new_secdesc = sec_desc_merge(p->mem_ctx, secdesc_ctr->sd, old_secdesc);
5425         if (new_secdesc == NULL) {
5426                 result = WERR_NOMEM;
5427                 goto done;
5428         }
5429
5430         if (security_descriptor_equal(new_secdesc, old_secdesc)) {
5431                 result = WERR_OK;
5432                 goto done;
5433         }
5434
5435         result = winreg_set_printer_secdesc(p->mem_ctx,
5436                                             p->server_info,
5437                                             printer,
5438                                             new_secdesc);
5439
5440  done:
5441         return result;
5442 }
5443
5444 /********************************************************************
5445  Canonicalize printer info from a client
5446  ********************************************************************/
5447
5448 static bool check_printer_ok(TALLOC_CTX *mem_ctx,
5449                              struct spoolss_SetPrinterInfo2 *info2,
5450                              int snum)
5451 {
5452         fstring printername;
5453         const char *p;
5454
5455         DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5456                 "portname=%s drivername=%s comment=%s location=%s\n",
5457                 info2->servername, info2->printername, info2->sharename,
5458                 info2->portname, info2->drivername, info2->comment,
5459                 info2->location));
5460
5461         /* we force some elements to "correct" values */
5462         info2->servername = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
5463         if (info2->servername == NULL) {
5464                 return false;
5465         }
5466         info2->sharename = talloc_strdup(mem_ctx, lp_const_servicename(snum));
5467         if (info2->sharename == NULL) {
5468                 return false;
5469         }
5470
5471         /* check to see if we allow printername != sharename */
5472         if (lp_force_printername(snum)) {
5473                 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5474                                         global_myname(), info2->sharename);
5475         } else {
5476                 /* make sure printername is in \\server\printername format */
5477                 fstrcpy(printername, info2->printername);
5478                 p = printername;
5479                 if ( printername[0] == '\\' && printername[1] == '\\' ) {
5480                         if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
5481                                 p++;
5482                 }
5483
5484                 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5485                                         global_myname(), p);
5486         }
5487         if (info2->printername == NULL) {
5488                 return false;
5489         }
5490
5491         info2->attributes |= PRINTER_ATTRIBUTE_SAMBA;
5492         info2->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
5493
5494         return true;
5495 }
5496
5497 /****************************************************************************
5498 ****************************************************************************/
5499
5500 static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
5501 {
5502         char *cmd = lp_addport_cmd();
5503         char *command = NULL;
5504         int ret;
5505         SE_PRIV se_printop = SE_PRINT_OPERATOR;
5506         bool is_print_op = false;
5507
5508         if ( !*cmd ) {
5509                 return WERR_ACCESS_DENIED;
5510         }
5511
5512         command = talloc_asprintf(ctx,
5513                         "%s \"%s\" \"%s\"", cmd, portname, uri );
5514         if (!command) {
5515                 return WERR_NOMEM;
5516         }
5517
5518         if ( token )
5519                 is_print_op = user_has_privileges( token, &se_printop );
5520
5521         DEBUG(10,("Running [%s]\n", command));
5522
5523         /********* BEGIN SePrintOperatorPrivilege **********/
5524
5525         if ( is_print_op )
5526                 become_root();
5527
5528         ret = smbrun(command, NULL);
5529
5530         if ( is_print_op )
5531                 unbecome_root();
5532
5533         /********* END SePrintOperatorPrivilege **********/
5534
5535         DEBUGADD(10,("returned [%d]\n", ret));
5536
5537         TALLOC_FREE(command);
5538
5539         if ( ret != 0 ) {
5540                 return WERR_ACCESS_DENIED;
5541         }
5542
5543         return WERR_OK;
5544 }
5545
5546 /****************************************************************************
5547 ****************************************************************************/
5548
5549 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
5550                       struct spoolss_SetPrinterInfo2 *info2,
5551                       const char *remote_machine)
5552 {
5553         char *cmd = lp_addprinter_cmd();
5554         char **qlines;
5555         char *command = NULL;
5556         int numlines;
5557         int ret;
5558         int fd;
5559         SE_PRIV se_printop = SE_PRINT_OPERATOR;
5560         bool is_print_op = false;
5561
5562         if (!remote_machine) {
5563                 return false;
5564         }
5565
5566         command = talloc_asprintf(ctx,
5567                         "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5568                         cmd, info2->printername, info2->sharename,
5569                         info2->portname, info2->drivername,
5570                         info2->location, info2->comment, remote_machine);
5571         if (!command) {
5572                 return false;
5573         }
5574
5575         if ( token )
5576                 is_print_op = user_has_privileges( token, &se_printop );
5577
5578         DEBUG(10,("Running [%s]\n", command));
5579
5580         /********* BEGIN SePrintOperatorPrivilege **********/
5581
5582         if ( is_print_op )
5583                 become_root();
5584
5585         if ( (ret = smbrun(command, &fd)) == 0 ) {
5586                 /* Tell everyone we updated smb.conf. */
5587                 message_send_all(smbd_messaging_context(),
5588                                  MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
5589         }
5590
5591         if ( is_print_op )
5592                 unbecome_root();
5593
5594         /********* END SePrintOperatorPrivilege **********/
5595
5596         DEBUGADD(10,("returned [%d]\n", ret));
5597
5598         TALLOC_FREE(command);
5599
5600         if ( ret != 0 ) {
5601                 if (fd != -1)
5602                         close(fd);
5603                 return false;
5604         }
5605
5606         /* reload our services immediately */
5607         become_root();
5608         reload_services(false);
5609         unbecome_root();
5610
5611         numlines = 0;
5612         /* Get lines and convert them back to dos-codepage */
5613         qlines = fd_lines_load(fd, &numlines, 0, NULL);
5614         DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5615         close(fd);
5616
5617         /* Set the portname to what the script says the portname should be. */
5618         /* but don't require anything to be return from the script exit a good error code */
5619
5620         if (numlines) {
5621                 /* Set the portname to what the script says the portname should be. */
5622                 info2->portname = talloc_strdup(ctx, qlines[0]);
5623                 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
5624         }
5625
5626         TALLOC_FREE(qlines);
5627         return true;
5628 }
5629
5630 static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
5631                                struct auth_serversupplied_info *server_info,
5632                                int snum,
5633                                struct spoolss_SetPrinterInfo2 *printer,
5634                                struct spoolss_PrinterInfo2 *old_printer)
5635 {
5636         bool force_update = (old_printer == NULL);
5637         const char *dnsdomname;
5638         const char *longname;
5639         const char *uncname;
5640         const char *spooling;
5641         DATA_BLOB buffer;
5642         WERROR result = WERR_OK;
5643
5644         if (force_update || !strequal(printer->drivername, old_printer->drivername)) {
5645                 push_reg_sz(mem_ctx, &buffer, printer->drivername);
5646                 winreg_set_printer_dataex(mem_ctx,
5647                                           server_info,
5648                                           printer->sharename,
5649                                           SPOOL_DSSPOOLER_KEY,
5650                                           SPOOL_REG_DRIVERNAME,
5651                                           REG_SZ,
5652                                           buffer.data,
5653                                           buffer.length);
5654
5655                 if (!force_update) {
5656                         DEBUG(10,("update_printer: changing driver [%s]!  Sending event!\n",
5657                                 printer->drivername));
5658
5659                         notify_printer_driver(snum, printer->drivername);
5660                 }
5661         }
5662
5663         if (force_update || !strequal(printer->comment, old_printer->comment)) {
5664                 push_reg_sz(mem_ctx, &buffer, printer->comment);
5665                 winreg_set_printer_dataex(mem_ctx,
5666                                           server_info,
5667                                           printer->sharename,
5668                                           SPOOL_DSSPOOLER_KEY,
5669                                           SPOOL_REG_DESCRIPTION,
5670                                           REG_SZ,
5671                                           buffer.data,
5672                                           buffer.length);
5673
5674                 if (!force_update) {
5675                         notify_printer_comment(snum, printer->comment);
5676                 }
5677         }
5678
5679         if (force_update || !strequal(printer->sharename, old_printer->sharename)) {
5680                 push_reg_sz(mem_ctx, &buffer, printer->sharename);
5681                 winreg_set_printer_dataex(mem_ctx,
5682                                           server_info,
5683                                           printer->sharename,
5684                                           SPOOL_DSSPOOLER_KEY,
5685                                           SPOOL_REG_PRINTSHARENAME,
5686                                           REG_SZ,
5687                                           buffer.data,
5688                                           buffer.length);
5689
5690                 if (!force_update) {
5691                         notify_printer_sharename(snum, printer->sharename);
5692                 }
5693         }
5694
5695         if (force_update || !strequal(printer->printername, old_printer->printername)) {
5696                 const char *p;
5697
5698                 p = strrchr(printer->printername, '\\' );
5699                 if (p != NULL) {
5700                         p++;
5701                 } else {
5702                         p = printer->printername;
5703                 }
5704
5705                 push_reg_sz(mem_ctx, &buffer, p);
5706                 winreg_set_printer_dataex(mem_ctx,
5707                                           server_info,
5708                                           printer->sharename,
5709                                           SPOOL_DSSPOOLER_KEY,
5710                                           SPOOL_REG_PRINTERNAME,
5711                                           REG_SZ,
5712                                           buffer.data,
5713                                           buffer.length);
5714
5715                 if (!force_update) {
5716                         notify_printer_printername(snum, p);
5717                 }
5718         }
5719
5720         if (force_update || !strequal(printer->portname, old_printer->portname)) {
5721                 push_reg_sz(mem_ctx, &buffer, printer->portname);
5722                 winreg_set_printer_dataex(mem_ctx,
5723                                           server_info,
5724                                           printer->sharename,
5725                                           SPOOL_DSSPOOLER_KEY,
5726                                           SPOOL_REG_PORTNAME,
5727                                           REG_SZ,
5728                                           buffer.data,
5729                                           buffer.length);
5730
5731                 if (!force_update) {
5732                         notify_printer_port(snum, printer->portname);
5733                 }
5734         }
5735
5736         if (force_update || !strequal(printer->location, old_printer->location)) {
5737                 push_reg_sz(mem_ctx, &buffer, printer->location);
5738                 winreg_set_printer_dataex(mem_ctx,
5739                                           server_info,
5740                                           printer->sharename,
5741                                           SPOOL_DSSPOOLER_KEY,
5742                                           SPOOL_REG_LOCATION,
5743                                           REG_SZ,
5744                                           buffer.data,
5745                                           buffer.length);
5746
5747                 if (!force_update) {
5748                         notify_printer_location(snum, printer->location);
5749                 }
5750         }
5751
5752         if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) {
5753                 push_reg_sz(mem_ctx, &buffer, printer->sepfile);
5754                 winreg_set_printer_dataex(mem_ctx,
5755                                           server_info,
5756                                           printer->sharename,
5757                                           SPOOL_DSSPOOLER_KEY,
5758                                           SPOOL_REG_PRINTSEPARATORFILE,
5759                                           REG_SZ,
5760                                           buffer.data,
5761                                           buffer.length);
5762
5763                 if (!force_update) {
5764                         notify_printer_location(snum, printer->location);
5765                 }
5766         }
5767
5768         if (force_update || printer->starttime != old_printer->starttime) {
5769                 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5770                 SIVAL(buffer.data, 0, printer->starttime);
5771                 winreg_set_printer_dataex(mem_ctx,
5772                                           server_info,
5773                                           printer->sharename,
5774                                           SPOOL_DSSPOOLER_KEY,
5775                                           SPOOL_REG_PRINTSTARTTIME,
5776                                           REG_DWORD,
5777                                           buffer.data,
5778                                           buffer.length);
5779         }
5780
5781         if (force_update || printer->untiltime != old_printer->untiltime) {
5782                 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5783                 SIVAL(buffer.data, 0, printer->untiltime);
5784                 winreg_set_printer_dataex(mem_ctx,
5785                                           server_info,
5786                                           printer->sharename,
5787                                           SPOOL_DSSPOOLER_KEY,
5788                                           SPOOL_REG_PRINTENDTIME,
5789                                           REG_DWORD,
5790                                           buffer.data,
5791                                           buffer.length);
5792         }
5793
5794         if (force_update || printer->priority != old_printer->priority) {
5795                 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5796                 SIVAL(buffer.data, 0, printer->priority);
5797                 winreg_set_printer_dataex(mem_ctx,
5798                                           server_info,
5799                                           printer->sharename,
5800                                           SPOOL_DSSPOOLER_KEY,
5801                                           SPOOL_REG_PRIORITY,
5802                                           REG_DWORD,
5803                                           buffer.data,
5804                                           buffer.length);
5805         }
5806
5807         if (force_update || printer->attributes != old_printer->attributes) {
5808                 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5809                 SIVAL(buffer.data, 0, (printer->attributes &
5810                                        PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
5811                 winreg_set_printer_dataex(mem_ctx,
5812                                           server_info,
5813                                           printer->sharename,
5814                                           SPOOL_DSSPOOLER_KEY,
5815                                           SPOOL_REG_PRINTKEEPPRINTEDJOBS,
5816                                           REG_DWORD,
5817                                           buffer.data,
5818                                           buffer.length);
5819
5820                 switch (printer->attributes & 0x3) {
5821                         case 0:
5822                                 spooling = SPOOL_REGVAL_PRINTWHILESPOOLING;
5823                                 break;
5824                         case 1:
5825                                 spooling = SPOOL_REGVAL_PRINTAFTERSPOOLED;
5826                                 break;
5827                         case 2:
5828                                 spooling = SPOOL_REGVAL_PRINTDIRECT;
5829                                 break;
5830                         default:
5831                                 spooling = "unknown";
5832                 }
5833                 push_reg_sz(mem_ctx, &buffer, spooling);
5834                 winreg_set_printer_dataex(mem_ctx,
5835                                           server_info,
5836                                           printer->sharename,
5837                                           SPOOL_DSSPOOLER_KEY,
5838                                           SPOOL_REG_PRINTSPOOLING,
5839                                           REG_SZ,
5840                                           buffer.data,
5841                                           buffer.length);
5842         }
5843
5844         push_reg_sz(mem_ctx, &buffer, global_myname());
5845         winreg_set_printer_dataex(mem_ctx,
5846                                   server_info,
5847                                   printer->sharename,
5848                                   SPOOL_DSSPOOLER_KEY,
5849                                   SPOOL_REG_SHORTSERVERNAME,
5850                                   REG_SZ,
5851                                   buffer.data,
5852                                   buffer.length);
5853
5854         dnsdomname = get_mydnsfullname();
5855         if (dnsdomname != NULL && dnsdomname[0] != '\0') {
5856                 longname = talloc_strdup(mem_ctx, dnsdomname);
5857         } else {
5858                 longname = talloc_strdup(mem_ctx, global_myname());
5859         }
5860         if (longname == NULL) {
5861                 result = WERR_NOMEM;
5862                 goto done;
5863         }
5864
5865         push_reg_sz(mem_ctx, &buffer, longname);
5866         winreg_set_printer_dataex(mem_ctx,
5867                                   server_info,
5868                                   printer->sharename,
5869                                   SPOOL_DSSPOOLER_KEY,
5870                                   SPOOL_REG_SERVERNAME,
5871                                   REG_SZ,
5872                                   buffer.data,
5873                                   buffer.length);
5874
5875         uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5876                                   global_myname(), printer->sharename);
5877         push_reg_sz(mem_ctx, &buffer, uncname);
5878         winreg_set_printer_dataex(mem_ctx,
5879                                   server_info,
5880                                   printer->sharename,
5881                                   SPOOL_DSSPOOLER_KEY,
5882                                   SPOOL_REG_UNCNAME,
5883                                   REG_SZ,
5884                                   buffer.data,
5885                                   buffer.length);
5886
5887 done:
5888         return result;
5889 }
5890
5891 /********************************************************************
5892  * Called by spoolss_api_setprinter
5893  * when updating a printer description.
5894  ********************************************************************/
5895
5896 static WERROR update_printer(struct pipes_struct *p,
5897                              struct policy_handle *handle,
5898                              struct spoolss_SetPrinterInfoCtr *info_ctr,
5899                              struct spoolss_DeviceMode *devmode)
5900 {
5901         uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
5902         struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
5903         struct spoolss_PrinterInfo2 *old_printer;
5904         Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5905         const char *servername = NULL;
5906         int snum;
5907         WERROR result = WERR_OK;
5908         TALLOC_CTX *tmp_ctx;
5909
5910         DEBUG(8,("update_printer\n"));
5911
5912         tmp_ctx = talloc_new(p->mem_ctx);
5913         if (tmp_ctx == NULL) {
5914                 return WERR_NOMEM;
5915         }
5916
5917         if (!Printer) {
5918                 result = WERR_BADFID;
5919                 goto done;
5920         }
5921
5922         if (!get_printer_snum(p, handle, &snum, NULL)) {
5923                 result = WERR_BADFID;
5924                 goto done;
5925         }
5926
5927         if (Printer != NULL || Printer->servername != NULL) {
5928                 servername = Printer->servername;
5929         }
5930
5931         result = winreg_get_printer(tmp_ctx,
5932                                     p->server_info,
5933                                     servername,
5934                                     lp_const_servicename(snum),
5935                                     &old_printer);
5936         if (!W_ERROR_IS_OK(result)) {
5937                 result = WERR_BADFID;
5938                 goto done;
5939         }
5940
5941         /* Do sanity check on the requested changes for Samba */
5942         if (!check_printer_ok(tmp_ctx, printer, snum)) {
5943                 result = WERR_INVALID_PARAM;
5944                 goto done;
5945         }
5946
5947         /* FIXME!!! If the driver has changed we really should verify that
5948            it is installed before doing much else   --jerry */
5949
5950         /* Check calling user has permission to update printer description */
5951         if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
5952                 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5953                 result = WERR_ACCESS_DENIED;
5954                 goto done;
5955         }
5956
5957         /* Call addprinter hook */
5958         /* Check changes to see if this is really needed */
5959
5960         if (*lp_addprinter_cmd() &&
5961                         (!strequal(printer->drivername, old_printer->drivername) ||
5962                          !strequal(printer->comment, old_printer->comment) ||
5963                          !strequal(printer->portname, old_printer->portname) ||
5964                          !strequal(printer->location, old_printer->location)) )
5965         {
5966                 /* add_printer_hook() will call reload_services() */
5967                 if (!add_printer_hook(tmp_ctx, p->server_info->ptok,
5968                                       printer, p->client_address) ) {
5969                         result = WERR_ACCESS_DENIED;
5970                         goto done;
5971                 }
5972         }
5973
5974         update_dsspooler(tmp_ctx,
5975                          p->server_info,
5976                          snum,
5977                          printer,
5978                          old_printer);
5979
5980         printer_mask &= ~SPOOLSS_PRINTER_INFO_SECDESC;
5981
5982         if (devmode == NULL) {
5983                 printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
5984         }
5985         result = winreg_update_printer(tmp_ctx,
5986                                        p->server_info,
5987                                        printer->sharename,
5988                                        printer_mask,
5989                                        printer,
5990                                        devmode,
5991                                        NULL);
5992
5993 done:
5994         talloc_free(tmp_ctx);
5995
5996         return result;
5997 }
5998
5999 /****************************************************************************
6000 ****************************************************************************/
6001 static WERROR publish_or_unpublish_printer(struct pipes_struct *p,
6002                                            struct policy_handle *handle,
6003                                            struct spoolss_SetPrinterInfo7 *info7)
6004 {
6005 #ifdef HAVE_ADS
6006         struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6007         WERROR result;
6008         int snum;
6009         Printer_entry *Printer;
6010
6011         if ( lp_security() != SEC_ADS ) {
6012                 return WERR_UNKNOWN_LEVEL;
6013         }
6014
6015         Printer = find_printer_index_by_hnd(p, handle);
6016
6017         DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6018
6019         if (!Printer)
6020                 return WERR_BADFID;
6021
6022         if (!get_printer_snum(p, handle, &snum, NULL))
6023                 return WERR_BADFID;
6024
6025         result = winreg_get_printer(p->mem_ctx, p->server_info,
6026                                     Printer->servername,
6027                                     lp_servicename(snum), &pinfo2);
6028         if (!W_ERROR_IS_OK(result)) {
6029                 return WERR_BADFID;
6030         }
6031
6032         nt_printer_publish(pinfo2, p->server_info, pinfo2, info7->action);
6033
6034         TALLOC_FREE(pinfo2);
6035         return WERR_OK;
6036 #else
6037         return WERR_UNKNOWN_LEVEL;
6038 #endif
6039 }
6040
6041 /********************************************************************
6042  ********************************************************************/
6043
6044 static WERROR update_printer_devmode(struct pipes_struct *p,
6045                                      struct policy_handle *handle,
6046                                      struct spoolss_DeviceMode *devmode)
6047 {
6048         int snum;
6049         Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6050         uint32_t info2_mask = SPOOLSS_PRINTER_INFO_DEVMODE;
6051
6052         DEBUG(8,("update_printer_devmode\n"));
6053
6054         if (!Printer) {
6055                 return WERR_BADFID;
6056         }
6057
6058         if (!get_printer_snum(p, handle, &snum, NULL)) {
6059                 return WERR_BADFID;
6060         }
6061
6062         /* Check calling user has permission to update printer description */
6063         if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6064                 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6065                 return WERR_ACCESS_DENIED;
6066         }
6067
6068         return winreg_update_printer(p->mem_ctx,
6069                                      p->server_info,
6070                                      lp_const_servicename(snum),
6071                                      info2_mask,
6072                                      NULL,
6073                                      devmode,
6074                                      NULL);
6075 }
6076
6077
6078 /****************************************************************
6079  _spoolss_SetPrinter
6080 ****************************************************************/
6081
6082 WERROR _spoolss_SetPrinter(struct pipes_struct *p,
6083                            struct spoolss_SetPrinter *r)
6084 {
6085         WERROR result;
6086
6087         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6088
6089         if (!Printer) {
6090                 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6091                         OUR_HANDLE(r->in.handle)));
6092                 return WERR_BADFID;
6093         }
6094
6095         /* check the level */
6096         switch (r->in.info_ctr->level) {
6097                 case 0:
6098                         return control_printer(r->in.handle, r->in.command, p);
6099                 case 2:
6100                         result = update_printer(p, r->in.handle,
6101                                                 r->in.info_ctr,
6102                                                 r->in.devmode_ctr->devmode);
6103                         if (!W_ERROR_IS_OK(result))
6104                                 return result;
6105                         if (r->in.secdesc_ctr->sd)
6106                                 result = update_printer_sec(r->in.handle, p,
6107                                                             r->in.secdesc_ctr);
6108                         return result;
6109                 case 3:
6110                         return update_printer_sec(r->in.handle, p,
6111                                                   r->in.secdesc_ctr);
6112                 case 7:
6113                         return publish_or_unpublish_printer(p, r->in.handle,
6114                                                             r->in.info_ctr->info.info7);
6115                 case 8:
6116                         return update_printer_devmode(p, r->in.handle,
6117                                                       r->in.devmode_ctr->devmode);
6118                 default:
6119                         return WERR_UNKNOWN_LEVEL;
6120         }
6121 }
6122
6123 /****************************************************************
6124  _spoolss_FindClosePrinterNotify
6125 ****************************************************************/
6126
6127 WERROR _spoolss_FindClosePrinterNotify(struct pipes_struct *p,
6128                                        struct spoolss_FindClosePrinterNotify *r)
6129 {
6130         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6131
6132         if (!Printer) {
6133                 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6134                         "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6135                 return WERR_BADFID;
6136         }
6137
6138         if (Printer->notify.client_connected == true) {
6139                 int snum = -1;
6140
6141                 if ( Printer->printer_type == SPLHND_SERVER)
6142                         snum = -1;
6143                 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6144                                 !get_printer_snum(p, r->in.handle, &snum, NULL) )
6145                         return WERR_BADFID;
6146
6147                 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6148         }
6149
6150         Printer->notify.flags=0;
6151         Printer->notify.options=0;
6152         Printer->notify.localmachine[0]='\0';
6153         Printer->notify.printerlocal=0;
6154         TALLOC_FREE(Printer->notify.option);
6155         Printer->notify.client_connected = false;
6156
6157         return WERR_OK;
6158 }
6159
6160 /****************************************************************
6161  _spoolss_AddJob
6162 ****************************************************************/
6163
6164 WERROR _spoolss_AddJob(struct pipes_struct *p,
6165                        struct spoolss_AddJob *r)
6166 {
6167         if (!r->in.buffer && (r->in.offered != 0)) {
6168                 return WERR_INVALID_PARAM;
6169         }
6170
6171         /* this is what a NT server returns for AddJob. AddJob must fail on
6172          * non-local printers */
6173
6174         if (r->in.level != 1) {
6175                 return WERR_UNKNOWN_LEVEL;
6176         }
6177
6178         return WERR_INVALID_PARAM;
6179 }
6180
6181 /****************************************************************************
6182 fill_job_info1
6183 ****************************************************************************/
6184
6185 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6186                              struct spoolss_JobInfo1 *r,
6187                              const print_queue_struct *queue,
6188                              int position, int snum,
6189                              struct spoolss_PrinterInfo2 *pinfo2)
6190 {
6191         struct tm *t;
6192
6193         t = gmtime(&queue->time);
6194
6195         r->job_id               = queue->job;
6196
6197         r->printer_name         = talloc_strdup(mem_ctx, lp_servicename(snum));
6198         W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6199         r->server_name          = talloc_strdup(mem_ctx, pinfo2->servername);
6200         W_ERROR_HAVE_NO_MEMORY(r->server_name);
6201         r->user_name            = talloc_strdup(mem_ctx, queue->fs_user);
6202         W_ERROR_HAVE_NO_MEMORY(r->user_name);
6203         r->document_name        = talloc_strdup(mem_ctx, queue->fs_file);
6204         W_ERROR_HAVE_NO_MEMORY(r->document_name);
6205         r->data_type            = talloc_strdup(mem_ctx, "RAW");
6206         W_ERROR_HAVE_NO_MEMORY(r->data_type);
6207         r->text_status          = talloc_strdup(mem_ctx, "");
6208         W_ERROR_HAVE_NO_MEMORY(r->text_status);
6209
6210         r->status               = nt_printj_status(queue->status);
6211         r->priority             = queue->priority;
6212         r->position             = position;
6213         r->total_pages          = queue->page_count;
6214         r->pages_printed        = 0; /* ??? */
6215
6216         init_systemtime(&r->submitted, t);
6217
6218         return WERR_OK;
6219 }
6220
6221 /****************************************************************************
6222 fill_job_info2
6223 ****************************************************************************/
6224
6225 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6226                              struct spoolss_JobInfo2 *r,
6227                              const print_queue_struct *queue,
6228                              int position, int snum,
6229                              struct spoolss_PrinterInfo2 *pinfo2,
6230                              struct spoolss_DeviceMode *devmode)
6231 {
6232         struct tm *t;
6233
6234         t = gmtime(&queue->time);
6235
6236         r->job_id               = queue->job;
6237
6238         r->printer_name         = talloc_strdup(mem_ctx, lp_servicename(snum));
6239         W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6240         r->server_name          = talloc_strdup(mem_ctx, pinfo2->servername);
6241         W_ERROR_HAVE_NO_MEMORY(r->server_name);
6242         r->user_name            = talloc_strdup(mem_ctx, queue->fs_user);
6243         W_ERROR_HAVE_NO_MEMORY(r->user_name);
6244         r->document_name        = talloc_strdup(mem_ctx, queue->fs_file);
6245         W_ERROR_HAVE_NO_MEMORY(r->document_name);
6246         r->notify_name          = talloc_strdup(mem_ctx, queue->fs_user);
6247         W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6248         r->data_type            = talloc_strdup(mem_ctx, "RAW");
6249         W_ERROR_HAVE_NO_MEMORY(r->data_type);
6250         r->print_processor      = talloc_strdup(mem_ctx, "winprint");
6251         W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6252         r->parameters           = talloc_strdup(mem_ctx, "");
6253         W_ERROR_HAVE_NO_MEMORY(r->parameters);
6254         r->driver_name          = talloc_strdup(mem_ctx, pinfo2->drivername);
6255         W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6256
6257         r->devmode              = devmode;
6258
6259         r->text_status          = talloc_strdup(mem_ctx, "");
6260         W_ERROR_HAVE_NO_MEMORY(r->text_status);
6261
6262         r->secdesc              = NULL;
6263
6264         r->status               = nt_printj_status(queue->status);
6265         r->priority             = queue->priority;
6266         r->position             = position;
6267         r->start_time           = 0;
6268         r->until_time           = 0;
6269         r->total_pages          = queue->page_count;
6270         r->size                 = queue->size;
6271         init_systemtime(&r->submitted, t);
6272         r->time                 = 0;
6273         r->pages_printed        = 0; /* ??? */
6274
6275         return WERR_OK;
6276 }
6277
6278 /****************************************************************************
6279 fill_job_info3
6280 ****************************************************************************/
6281
6282 static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6283                              struct spoolss_JobInfo3 *r,
6284                              const print_queue_struct *queue,
6285                              const print_queue_struct *next_queue,
6286                              int position, int snum,
6287                              struct spoolss_PrinterInfo2 *pinfo2)
6288 {
6289         r->job_id               = queue->job;
6290         r->next_job_id          = 0;
6291         if (next_queue) {
6292                 r->next_job_id  = next_queue->job;
6293         }
6294         r->reserved             = 0;
6295
6296         return WERR_OK;
6297 }
6298
6299 /****************************************************************************
6300  Enumjobs at level 1.
6301 ****************************************************************************/
6302
6303 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6304                               const print_queue_struct *queue,
6305                               uint32_t num_queues, int snum,
6306                               struct spoolss_PrinterInfo2 *pinfo2,
6307                               union spoolss_JobInfo **info_p,
6308                               uint32_t *count)
6309 {
6310         union spoolss_JobInfo *info;
6311         int i;
6312         WERROR result = WERR_OK;
6313
6314         info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6315         W_ERROR_HAVE_NO_MEMORY(info);
6316
6317         *count = num_queues;
6318
6319         for (i=0; i<*count; i++) {
6320                 result = fill_job_info1(info,
6321                                         &info[i].info1,
6322                                         &queue[i],
6323                                         i,
6324                                         snum,
6325                                         pinfo2);
6326                 if (!W_ERROR_IS_OK(result)) {
6327                         goto out;
6328                 }
6329         }
6330
6331  out:
6332         if (!W_ERROR_IS_OK(result)) {
6333                 TALLOC_FREE(info);
6334                 *count = 0;
6335                 return result;
6336         }
6337
6338         *info_p = info;
6339
6340         return WERR_OK;
6341 }
6342
6343 /****************************************************************************
6344  Enumjobs at level 2.
6345 ****************************************************************************/
6346
6347 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6348                               const print_queue_struct *queue,
6349                               uint32_t num_queues, int snum,
6350                               struct spoolss_PrinterInfo2 *pinfo2,
6351                               union spoolss_JobInfo **info_p,
6352                               uint32_t *count)
6353 {
6354         union spoolss_JobInfo *info;
6355         int i;
6356         WERROR result = WERR_OK;
6357
6358         info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6359         W_ERROR_HAVE_NO_MEMORY(info);
6360
6361         *count = num_queues;
6362
6363         for (i=0; i<*count; i++) {
6364                 struct spoolss_DeviceMode *devmode;
6365
6366                 result = spoolss_create_default_devmode(info,
6367                                                         pinfo2->printername,
6368                                                         &devmode);
6369                 if (!W_ERROR_IS_OK(result)) {
6370                         DEBUG(3, ("Can't proceed w/o a devmode!"));
6371                         goto out;
6372                 }
6373
6374                 result = fill_job_info2(info,
6375                                         &info[i].info2,
6376                                         &queue[i],
6377                                         i,
6378                                         snum,
6379                                         pinfo2,
6380                                         devmode);
6381                 if (!W_ERROR_IS_OK(result)) {
6382                         goto out;
6383                 }
6384         }
6385
6386  out:
6387         if (!W_ERROR_IS_OK(result)) {
6388                 TALLOC_FREE(info);
6389                 *count = 0;
6390                 return result;
6391         }
6392
6393         *info_p = info;
6394
6395         return WERR_OK;
6396 }
6397
6398 /****************************************************************************
6399  Enumjobs at level 3.
6400 ****************************************************************************/
6401
6402 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6403                               const print_queue_struct *queue,
6404                               uint32_t num_queues, int snum,
6405                               struct spoolss_PrinterInfo2 *pinfo2,
6406                               union spoolss_JobInfo **info_p,
6407                               uint32_t *count)
6408 {
6409         union spoolss_JobInfo *info;
6410         int i;
6411         WERROR result = WERR_OK;
6412
6413         info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6414         W_ERROR_HAVE_NO_MEMORY(info);
6415
6416         *count = num_queues;
6417
6418         for (i=0; i<*count; i++) {
6419                 const print_queue_struct *next_queue = NULL;
6420
6421                 if (i+1 < *count) {
6422                         next_queue = &queue[i+1];
6423                 }
6424
6425                 result = fill_job_info3(info,
6426                                         &info[i].info3,
6427                                         &queue[i],
6428                                         next_queue,
6429                                         i,
6430                                         snum,
6431                                         pinfo2);
6432                 if (!W_ERROR_IS_OK(result)) {
6433                         goto out;
6434                 }
6435         }
6436
6437  out:
6438         if (!W_ERROR_IS_OK(result)) {
6439                 TALLOC_FREE(info);
6440                 *count = 0;
6441                 return result;
6442         }
6443
6444         *info_p = info;
6445
6446         return WERR_OK;
6447 }
6448
6449 /****************************************************************
6450  _spoolss_EnumJobs
6451 ****************************************************************/
6452
6453 WERROR _spoolss_EnumJobs(struct pipes_struct *p,
6454                          struct spoolss_EnumJobs *r)
6455 {
6456         WERROR result;
6457         struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6458         int snum;
6459         print_status_struct prt_status;
6460         print_queue_struct *queue = NULL;
6461         uint32_t count;
6462
6463         /* that's an [in out] buffer */
6464
6465         if (!r->in.buffer && (r->in.offered != 0)) {
6466                 return WERR_INVALID_PARAM;
6467         }
6468
6469         DEBUG(4,("_spoolss_EnumJobs\n"));
6470
6471         *r->out.needed = 0;
6472         *r->out.count = 0;
6473         *r->out.info = NULL;
6474
6475         /* lookup the printer snum and tdb entry */
6476
6477         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6478                 return WERR_BADFID;
6479         }
6480
6481         result = winreg_get_printer(p->mem_ctx, p->server_info, NULL,
6482                                     lp_servicename(snum), &pinfo2);
6483         if (!W_ERROR_IS_OK(result)) {
6484                 return result;
6485         }
6486
6487         count = print_queue_status(snum, &queue, &prt_status);
6488         DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6489                 count, prt_status.status, prt_status.message));
6490
6491         if (count == 0) {
6492                 SAFE_FREE(queue);
6493                 TALLOC_FREE(pinfo2);
6494                 return WERR_OK;
6495         }
6496
6497         switch (r->in.level) {
6498         case 1:
6499                 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6500                                          pinfo2, r->out.info, r->out.count);
6501                 break;
6502         case 2:
6503                 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6504                                          pinfo2, r->out.info, r->out.count);
6505                 break;
6506         case 3:
6507                 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6508                                          pinfo2, r->out.info, r->out.count);
6509                 break;
6510         default:
6511                 result = WERR_UNKNOWN_LEVEL;
6512                 break;
6513         }
6514
6515         SAFE_FREE(queue);
6516         TALLOC_FREE(pinfo2);
6517
6518         if (!W_ERROR_IS_OK(result)) {
6519                 return result;
6520         }
6521
6522         *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6523                                                      spoolss_EnumJobs, 
6524                                                      *r->out.info, r->in.level,
6525                                                      *r->out.count);
6526         *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6527         *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6528
6529         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6530 }
6531
6532 /****************************************************************
6533  _spoolss_ScheduleJob
6534 ****************************************************************/
6535
6536 WERROR _spoolss_ScheduleJob(struct pipes_struct *p,
6537                             struct spoolss_ScheduleJob *r)
6538 {
6539         return WERR_OK;
6540 }
6541
6542 /****************************************************************
6543 ****************************************************************/
6544
6545 static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
6546                                const char *printer_name,
6547                                uint32_t job_id,
6548                                struct spoolss_SetJobInfo1 *r)
6549 {
6550         char *old_doc_name;
6551
6552         if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
6553                 return WERR_BADFID;
6554         }
6555
6556         if (strequal(old_doc_name, r->document_name)) {
6557                 return WERR_OK;
6558         }
6559
6560         if (!print_job_set_name(printer_name, job_id, r->document_name)) {
6561                 return WERR_BADFID;
6562         }
6563
6564         return WERR_OK;
6565 }
6566
6567 /****************************************************************
6568  _spoolss_SetJob
6569 ****************************************************************/
6570
6571 WERROR _spoolss_SetJob(struct pipes_struct *p,
6572                        struct spoolss_SetJob *r)
6573 {
6574         int snum;
6575         WERROR errcode = WERR_BADFUNC;
6576
6577         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6578                 return WERR_BADFID;
6579         }
6580
6581         if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6582                 return WERR_INVALID_PRINTER_NAME;
6583         }
6584
6585         switch (r->in.command) {
6586         case SPOOLSS_JOB_CONTROL_CANCEL:
6587         case SPOOLSS_JOB_CONTROL_DELETE:
6588                 errcode = print_job_delete(p->server_info,
6589                                            snum, r->in.job_id);
6590                 if (W_ERROR_EQUAL(errcode, WERR_PRINTER_HAS_JOBS_QUEUED)) {
6591                         errcode = WERR_OK;
6592                 }
6593                 break;
6594         case SPOOLSS_JOB_CONTROL_PAUSE:
6595                 if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) {
6596                         errcode = WERR_OK;
6597                 }
6598                 break;
6599         case SPOOLSS_JOB_CONTROL_RESTART:
6600         case SPOOLSS_JOB_CONTROL_RESUME:
6601                 if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) {
6602                         errcode = WERR_OK;
6603                 }
6604                 break;
6605         case 0:
6606                 errcode = WERR_OK;
6607                 break;
6608         default:
6609                 return WERR_UNKNOWN_LEVEL;
6610         }
6611
6612         if (!W_ERROR_IS_OK(errcode)) {
6613                 return errcode;
6614         }
6615
6616         if (r->in.ctr == NULL) {
6617                 return errcode;
6618         }
6619
6620         switch (r->in.ctr->level) {
6621         case 1:
6622                 errcode = spoolss_setjob_1(p->mem_ctx, lp_const_servicename(snum),
6623                                            r->in.job_id,
6624                                            r->in.ctr->info.info1);
6625                 break;
6626         case 2:
6627         case 3:
6628         case 4:
6629         default:
6630                 return WERR_UNKNOWN_LEVEL;
6631         }
6632
6633         return errcode;
6634 }
6635
6636 /****************************************************************************
6637  Enumerates all printer drivers by level and architecture.
6638 ****************************************************************************/
6639
6640 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6641                                                        struct auth_serversupplied_info *server_info,
6642                                                        const char *servername,
6643                                                        const char *architecture,
6644                                                        uint32_t level,
6645                                                        union spoolss_DriverInfo **info_p,
6646                                                        uint32_t *count_p)
6647 {
6648         int i;
6649         uint32_t version;
6650         struct spoolss_DriverInfo8 *driver;
6651         union spoolss_DriverInfo *info = NULL;
6652         uint32_t count = 0;
6653         WERROR result = WERR_OK;
6654         uint32_t num_drivers;
6655         const char **drivers;
6656
6657         *count_p = 0;
6658         *info_p = NULL;
6659
6660         for (version=0; version<DRIVER_MAX_VERSION; version++) {
6661                 result = winreg_get_driver_list(mem_ctx, server_info,
6662                                                 architecture, version,
6663                                                 &num_drivers, &drivers);
6664                 if (!W_ERROR_IS_OK(result)) {
6665                         goto out;
6666                 }
6667                 DEBUG(4, ("we have:[%d] drivers in environment"
6668                           " [%s] and version [%d]\n",
6669                           num_drivers, architecture, version));
6670
6671                 if (num_drivers != 0) {
6672                         info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6673                                                     union spoolss_DriverInfo,
6674                                                     count + num_drivers);
6675                         if (!info) {
6676                                 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6677                                         "failed to enlarge driver info buffer!\n"));
6678                                 result = WERR_NOMEM;
6679                                 goto out;
6680                         }
6681                 }
6682
6683                 for (i = 0; i < num_drivers; i++) {
6684                         DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
6685
6686                         result = winreg_get_driver(mem_ctx, server_info,
6687                                                    architecture, drivers[i],
6688                                                    version, &driver);
6689                         if (!W_ERROR_IS_OK(result)) {
6690                                 goto out;
6691                         }
6692
6693                         switch (level) {
6694                         case 1:
6695                                 result = fill_printer_driver_info1(info, &info[count+i].info1,
6696                                                                    driver, servername);
6697                                 break;
6698                         case 2:
6699                                 result = fill_printer_driver_info2(info, &info[count+i].info2,
6700                                                                    driver, servername);
6701                                 break;
6702                         case 3:
6703                                 result = fill_printer_driver_info3(info, &info[count+i].info3,
6704                                                                    driver, servername);
6705                                 break;
6706                         case 4:
6707                                 result = fill_printer_driver_info4(info, &info[count+i].info4,
6708                                                                    driver, servername);
6709                                 break;
6710                         case 5:
6711                                 result = fill_printer_driver_info5(info, &info[count+i].info5,
6712                                                                    driver, servername);
6713                                 break;
6714                         case 6:
6715                                 result = fill_printer_driver_info6(info, &info[count+i].info6,
6716                                                                    driver, servername);
6717                                 break;
6718                         case 8:
6719                                 result = fill_printer_driver_info8(info, &info[count+i].info8,
6720                                                                    driver, servername);
6721                                 break;
6722                         default:
6723                                 result = WERR_UNKNOWN_LEVEL;
6724                                 break;
6725                         }
6726
6727                         TALLOC_FREE(driver);
6728
6729                         if (!W_ERROR_IS_OK(result)) {
6730                                 goto out;
6731                         }
6732                 }
6733
6734                 count += num_drivers;
6735                 TALLOC_FREE(drivers);
6736         }
6737
6738  out:
6739         TALLOC_FREE(drivers);
6740
6741         if (!W_ERROR_IS_OK(result)) {
6742                 TALLOC_FREE(info);
6743                 return result;
6744         }
6745
6746         *info_p = info;
6747         *count_p = count;
6748
6749         return WERR_OK;
6750 }
6751
6752 /****************************************************************************
6753  Enumerates all printer drivers by level.
6754 ****************************************************************************/
6755
6756 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
6757                                        struct auth_serversupplied_info *server_info,
6758                                        const char *servername,
6759                                        const char *architecture,
6760                                        uint32_t level,
6761                                        union spoolss_DriverInfo **info_p,
6762                                        uint32_t *count_p)
6763 {
6764         uint32_t a,i;
6765         WERROR result = WERR_OK;
6766
6767         if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
6768
6769                 for (a=0; archi_table[a].long_archi != NULL; a++) {
6770
6771                         union spoolss_DriverInfo *info = NULL;
6772                         uint32_t count = 0;
6773
6774                         result = enumprinterdrivers_level_by_architecture(mem_ctx,
6775                                                                           server_info,
6776                                                                           servername,
6777                                                                           archi_table[a].long_archi,
6778                                                                           level,
6779                                                                           &info,
6780                                                                           &count);
6781                         if (!W_ERROR_IS_OK(result)) {
6782                                 continue;
6783                         }
6784
6785                         for (i=0; i < count; i++) {
6786                                 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
6787                                              info[i], info_p, count_p);
6788                         }
6789                 }
6790
6791                 return result;
6792         }
6793
6794         return enumprinterdrivers_level_by_architecture(mem_ctx,
6795                                                         server_info,
6796                                                         servername,
6797                                                         architecture,
6798                                                         level,
6799                                                         info_p,
6800                                                         count_p);
6801 }
6802
6803 /****************************************************************
6804  _spoolss_EnumPrinterDrivers
6805 ****************************************************************/
6806
6807 WERROR _spoolss_EnumPrinterDrivers(struct pipes_struct *p,
6808                                    struct spoolss_EnumPrinterDrivers *r)
6809 {
6810         const char *cservername;
6811         WERROR result;
6812
6813         /* that's an [in out] buffer */
6814
6815         if (!r->in.buffer && (r->in.offered != 0)) {
6816                 return WERR_INVALID_PARAM;
6817         }
6818
6819         DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6820
6821         *r->out.needed = 0;
6822         *r->out.count = 0;
6823         *r->out.info = NULL;
6824
6825         cservername = canon_servername(r->in.server);
6826
6827         if (!is_myname_or_ipaddr(cservername)) {
6828                 return WERR_UNKNOWN_PRINTER_DRIVER;
6829         }
6830
6831         result = enumprinterdrivers_level(p->mem_ctx,
6832                                           p->server_info,
6833                                           cservername,
6834                                           r->in.environment,
6835                                           r->in.level,
6836                                           r->out.info,
6837                                           r->out.count);
6838         if (!W_ERROR_IS_OK(result)) {
6839                 return result;
6840         }
6841
6842         *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6843                                                      spoolss_EnumPrinterDrivers, 
6844                                                      *r->out.info, r->in.level,
6845                                                      *r->out.count);
6846         *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6847         *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6848
6849         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6850 }
6851
6852 /****************************************************************
6853  _spoolss_EnumForms
6854 ****************************************************************/
6855
6856 WERROR _spoolss_EnumForms(struct pipes_struct *p,
6857                           struct spoolss_EnumForms *r)
6858 {
6859         WERROR result;
6860
6861         *r->out.count = 0;
6862         *r->out.needed = 0;
6863         *r->out.info = NULL;
6864
6865         /* that's an [in out] buffer */
6866
6867         if (!r->in.buffer && (r->in.offered != 0) ) {
6868                 return WERR_INVALID_PARAM;
6869         }
6870
6871         DEBUG(4,("_spoolss_EnumForms\n"));
6872         DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6873         DEBUGADD(5,("Info level [%d]\n",          r->in.level));
6874
6875         switch (r->in.level) {
6876         case 1:
6877                 result = winreg_printer_enumforms1(p->mem_ctx,
6878                                                    p->server_info,
6879                                                    r->out.count,
6880                                                    r->out.info);
6881                 break;
6882         default:
6883                 result = WERR_UNKNOWN_LEVEL;
6884                 break;
6885         }
6886
6887         if (!W_ERROR_IS_OK(result)) {
6888                 return result;
6889         }
6890
6891         if (*r->out.count == 0) {
6892                 return WERR_NO_MORE_ITEMS;
6893         }
6894
6895         *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6896                                                      spoolss_EnumForms, 
6897                                                      *r->out.info, r->in.level,
6898                                                      *r->out.count);
6899         *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6900         *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6901
6902         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6903 }
6904
6905 /****************************************************************
6906  _spoolss_GetForm
6907 ****************************************************************/
6908
6909 WERROR _spoolss_GetForm(struct pipes_struct *p,
6910                         struct spoolss_GetForm *r)
6911 {
6912         WERROR result;
6913
6914         /* that's an [in out] buffer */
6915
6916         if (!r->in.buffer && (r->in.offered != 0)) {
6917                 return WERR_INVALID_PARAM;
6918         }
6919
6920         DEBUG(4,("_spoolss_GetForm\n"));
6921         DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6922         DEBUGADD(5,("Info level [%d]\n",          r->in.level));
6923
6924         switch (r->in.level) {
6925         case 1:
6926                 result = winreg_printer_getform1(p->mem_ctx,
6927                                                  p->server_info,
6928                                                  r->in.form_name,
6929                                                  &r->out.info->info1);
6930                 break;
6931         default:
6932                 result = WERR_UNKNOWN_LEVEL;
6933                 break;
6934         }
6935
6936         if (!W_ERROR_IS_OK(result)) {
6937                 TALLOC_FREE(r->out.info);
6938                 return result;
6939         }
6940
6941         *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_FormInfo, 
6942                                                r->out.info, r->in.level);
6943         r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
6944
6945         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6946 }
6947
6948 /****************************************************************************
6949 ****************************************************************************/
6950
6951 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
6952                           struct spoolss_PortInfo1 *r,
6953                           const char *name)
6954 {
6955         r->port_name = talloc_strdup(mem_ctx, name);
6956         W_ERROR_HAVE_NO_MEMORY(r->port_name);
6957
6958         return WERR_OK;
6959 }
6960
6961 /****************************************************************************
6962  TODO: This probably needs distinguish between TCP/IP and Local ports
6963  somehow.
6964 ****************************************************************************/
6965
6966 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
6967                           struct spoolss_PortInfo2 *r,
6968                           const char *name)
6969 {
6970         r->port_name = talloc_strdup(mem_ctx, name);
6971         W_ERROR_HAVE_NO_MEMORY(r->port_name);
6972
6973         r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
6974         W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
6975
6976         r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
6977         W_ERROR_HAVE_NO_MEMORY(r->description);
6978
6979         r->port_type = SPOOLSS_PORT_TYPE_WRITE;
6980         r->reserved = 0;
6981
6982         return WERR_OK;
6983 }
6984
6985
6986 /****************************************************************************
6987  wrapper around the enumer ports command
6988 ****************************************************************************/
6989
6990 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
6991 {
6992         char *cmd = lp_enumports_cmd();
6993         char **qlines = NULL;
6994         char *command = NULL;
6995         int numlines;
6996         int ret;
6997         int fd;
6998
6999         *count = 0;
7000         *lines = NULL;
7001
7002         /* if no hook then just fill in the default port */
7003
7004         if ( !*cmd ) {
7005                 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7006                         return WERR_NOMEM;
7007                 }
7008                 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7009                         TALLOC_FREE(qlines);
7010                         return WERR_NOMEM;
7011                 }
7012                 qlines[1] = NULL;
7013                 numlines = 1;
7014         }
7015         else {
7016                 /* we have a valid enumport command */
7017
7018                 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7019                 if (!command) {
7020                         return WERR_NOMEM;
7021                 }
7022
7023                 DEBUG(10,("Running [%s]\n", command));
7024                 ret = smbrun(command, &fd);
7025                 DEBUG(10,("Returned [%d]\n", ret));
7026                 TALLOC_FREE(command);
7027                 if (ret != 0) {
7028                         if (fd != -1) {
7029                                 close(fd);
7030                         }
7031                         return WERR_ACCESS_DENIED;
7032                 }
7033
7034                 numlines = 0;
7035                 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7036                 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7037                 close(fd);
7038         }
7039
7040         *count = numlines;
7041         *lines = qlines;
7042
7043         return WERR_OK;
7044 }
7045
7046 /****************************************************************************
7047  enumports level 1.
7048 ****************************************************************************/
7049
7050 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7051                                 union spoolss_PortInfo **info_p,
7052                                 uint32_t *count)
7053 {
7054         union spoolss_PortInfo *info = NULL;
7055         int i=0;
7056         WERROR result = WERR_OK;
7057         char **qlines = NULL;
7058         int numlines = 0;
7059
7060         result = enumports_hook(talloc_tos(), &numlines, &qlines );
7061         if (!W_ERROR_IS_OK(result)) {
7062                 goto out;
7063         }
7064
7065         if (numlines) {
7066                 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7067                 if (!info) {
7068                         DEBUG(10,("Returning WERR_NOMEM\n"));
7069                         result = WERR_NOMEM;
7070                         goto out;
7071                 }
7072
7073                 for (i=0; i<numlines; i++) {
7074                         DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7075                         result = fill_port_1(info, &info[i].info1, qlines[i]);
7076                         if (!W_ERROR_IS_OK(result)) {
7077                                 goto out;
7078                         }
7079                 }
7080         }
7081         TALLOC_FREE(qlines);
7082
7083 out:
7084         if (!W_ERROR_IS_OK(result)) {
7085                 TALLOC_FREE(info);
7086                 TALLOC_FREE(qlines);
7087                 *count = 0;
7088                 *info_p = NULL;
7089                 return result;
7090         }
7091
7092         *info_p = info;
7093         *count = numlines;
7094
7095         return WERR_OK;
7096 }
7097
7098 /****************************************************************************
7099  enumports level 2.
7100 ****************************************************************************/
7101
7102 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7103                                 union spoolss_PortInfo **info_p,
7104                                 uint32_t *count)
7105 {
7106         union spoolss_PortInfo *info = NULL;
7107         int i=0;
7108         WERROR result = WERR_OK;
7109         char **qlines = NULL;
7110         int numlines = 0;
7111
7112         result = enumports_hook(talloc_tos(), &numlines, &qlines );
7113         if (!W_ERROR_IS_OK(result)) {
7114                 goto out;
7115         }
7116
7117         if (numlines) {
7118                 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7119                 if (!info) {
7120                         DEBUG(10,("Returning WERR_NOMEM\n"));
7121                         result = WERR_NOMEM;
7122                         goto out;
7123                 }
7124
7125                 for (i=0; i<numlines; i++) {
7126                         DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7127                         result = fill_port_2(info, &info[i].info2, qlines[i]);
7128                         if (!W_ERROR_IS_OK(result)) {
7129                                 goto out;
7130                         }
7131                 }
7132         }
7133         TALLOC_FREE(qlines);
7134
7135 out:
7136         if (!W_ERROR_IS_OK(result)) {
7137                 TALLOC_FREE(info);
7138                 TALLOC_FREE(qlines);
7139                 *count = 0;
7140                 *info_p = NULL;
7141                 return result;
7142         }
7143
7144         *info_p = info;
7145         *count = numlines;
7146
7147         return WERR_OK;
7148 }
7149
7150 /****************************************************************
7151  _spoolss_EnumPorts
7152 ****************************************************************/
7153
7154 WERROR _spoolss_EnumPorts(struct pipes_struct *p,
7155                           struct spoolss_EnumPorts *r)
7156 {
7157         WERROR result;
7158
7159         /* that's an [in out] buffer */
7160
7161         if (!r->in.buffer && (r->in.offered != 0)) {
7162                 return WERR_INVALID_PARAM;
7163         }
7164
7165         DEBUG(4,("_spoolss_EnumPorts\n"));
7166
7167         *r->out.count = 0;
7168         *r->out.needed = 0;
7169         *r->out.info = NULL;
7170
7171         switch (r->in.level) {
7172         case 1:
7173                 result = enumports_level_1(p->mem_ctx, r->out.info,
7174                                            r->out.count);
7175                 break;
7176         case 2:
7177                 result = enumports_level_2(p->mem_ctx, r->out.info,
7178                                            r->out.count);
7179                 break;
7180         default:
7181                 return WERR_UNKNOWN_LEVEL;
7182         }
7183
7184         if (!W_ERROR_IS_OK(result)) {
7185                 return result;
7186         }
7187
7188         *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7189                                                      spoolss_EnumPorts, 
7190                                                      *r->out.info, r->in.level,
7191                                                      *r->out.count);
7192         *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7193         *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7194
7195         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7196 }
7197
7198 /****************************************************************************
7199 ****************************************************************************/
7200
7201 static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p,
7202                                            const char *server,
7203                                            struct spoolss_SetPrinterInfoCtr *info_ctr,
7204                                            struct spoolss_DeviceMode *devmode,
7205                                            struct security_descriptor *secdesc,
7206                                            struct spoolss_UserLevelCtr *user_ctr,
7207                                            struct policy_handle *handle)
7208 {
7209         struct spoolss_SetPrinterInfo2 *info2 = info_ctr->info.info2;
7210         uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ALL;
7211         int     snum;
7212         WERROR err = WERR_OK;
7213
7214         /* samba does not have a concept of local, non-shared printers yet, so
7215          * make sure we always setup sharename - gd */
7216         if ((info2->sharename == NULL || info2->sharename[0] == '\0') &&
7217             (info2->printername != NULL && info2->printername[0] != '\0')) {
7218                 DEBUG(5, ("spoolss_addprinterex_level_2: "
7219                         "no sharename has been set, setting printername %s as sharename\n",
7220                         info2->printername));
7221                 info2->sharename = info2->printername;
7222         }
7223
7224         /* check to see if the printer already exists */
7225         if ((snum = print_queue_snum(info2->sharename)) != -1) {
7226                 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7227                         info2->sharename));
7228                 return WERR_PRINTER_ALREADY_EXISTS;
7229         }
7230
7231         if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
7232                 if ((snum = print_queue_snum(info2->printername)) != -1) {
7233                         DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7234                                 info2->printername));
7235                         return WERR_PRINTER_ALREADY_EXISTS;
7236                 }
7237         }
7238
7239         /* validate printer info struct */
7240         if (!info2->printername || strlen(info2->printername) == 0) {
7241                 return WERR_INVALID_PRINTER_NAME;
7242         }
7243         if (!info2->portname || strlen(info2->portname) == 0) {
7244                 return WERR_UNKNOWN_PORT;
7245         }
7246         if (!info2->drivername || strlen(info2->drivername) == 0) {
7247                 return WERR_UNKNOWN_PRINTER_DRIVER;
7248         }
7249         if (!info2->printprocessor || strlen(info2->printprocessor) == 0) {
7250                 return WERR_UNKNOWN_PRINTPROCESSOR;
7251         }
7252
7253         /* FIXME!!!  smbd should check to see if the driver is installed before
7254            trying to add a printer like this  --jerry */
7255
7256         if (*lp_addprinter_cmd() ) {
7257                 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7258                                        info2, p->client_address) ) {
7259                         return WERR_ACCESS_DENIED;
7260                 }
7261         } else {
7262                 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7263                         "smb.conf parameter \"addprinter command\" is defined. This"
7264                         "parameter must exist for this call to succeed\n",
7265                         info2->sharename ));
7266         }
7267
7268         if ((snum = print_queue_snum(info2->sharename)) == -1) {
7269                 return WERR_ACCESS_DENIED;
7270         }
7271
7272         /* you must be a printer admin to add a new printer */
7273         if (!print_access_check(p->server_info, snum, PRINTER_ACCESS_ADMINISTER)) {
7274                 return WERR_ACCESS_DENIED;
7275         }
7276
7277         /*
7278          * Do sanity check on the requested changes for Samba.
7279          */
7280
7281         if (!check_printer_ok(p->mem_ctx, info2, snum)) {
7282                 return WERR_INVALID_PARAM;
7283         }
7284
7285         if (devmode == NULL) {
7286                 info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
7287         }
7288
7289         update_dsspooler(p->mem_ctx,
7290                          p->server_info,
7291                          0,
7292                          info2,
7293                          NULL);
7294
7295         err = winreg_update_printer(p->mem_ctx,
7296                                     p->server_info,
7297                                     info2->sharename,
7298                                     info2_mask,
7299                                     info2,
7300                                     devmode,
7301                                     secdesc);
7302         if (!W_ERROR_IS_OK(err)) {
7303                 return err;
7304         }
7305
7306         if (!open_printer_hnd(p, handle, info2->printername, PRINTER_ACCESS_ADMINISTER)) {
7307                 /* Handle open failed - remove addition. */
7308                 ZERO_STRUCTP(handle);
7309                 return WERR_ACCESS_DENIED;
7310         }
7311
7312         return WERR_OK;
7313 }
7314
7315 /****************************************************************
7316  _spoolss_AddPrinterEx
7317 ****************************************************************/
7318
7319 WERROR _spoolss_AddPrinterEx(struct pipes_struct *p,
7320                              struct spoolss_AddPrinterEx *r)
7321 {
7322         switch (r->in.info_ctr->level) {
7323         case 1:
7324                 /* we don't handle yet */
7325                 /* but I know what to do ... */
7326                 return WERR_UNKNOWN_LEVEL;
7327         case 2:
7328                 return spoolss_addprinterex_level_2(p, r->in.server,
7329                                                     r->in.info_ctr,
7330                                                     r->in.devmode_ctr->devmode,
7331                                                     r->in.secdesc_ctr->sd,
7332                                                     r->in.userlevel_ctr,
7333                                                     r->out.handle);
7334         default:
7335                 return WERR_UNKNOWN_LEVEL;
7336         }
7337 }
7338
7339 /****************************************************************
7340  _spoolss_AddPrinter
7341 ****************************************************************/
7342
7343 WERROR _spoolss_AddPrinter(struct pipes_struct *p,
7344                            struct spoolss_AddPrinter *r)
7345 {
7346         struct spoolss_AddPrinterEx a;
7347         struct spoolss_UserLevelCtr userlevel_ctr;
7348
7349         ZERO_STRUCT(userlevel_ctr);
7350
7351         userlevel_ctr.level = 1;
7352
7353         a.in.server             = r->in.server;
7354         a.in.info_ctr           = r->in.info_ctr;
7355         a.in.devmode_ctr        = r->in.devmode_ctr;
7356         a.in.secdesc_ctr        = r->in.secdesc_ctr;
7357         a.in.userlevel_ctr      = &userlevel_ctr;
7358         a.out.handle            = r->out.handle;
7359
7360         return _spoolss_AddPrinterEx(p, &a);
7361 }
7362
7363 /****************************************************************
7364  _spoolss_AddPrinterDriverEx
7365 ****************************************************************/
7366
7367 WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
7368                                    struct spoolss_AddPrinterDriverEx *r)
7369 {
7370         WERROR err = WERR_OK;
7371         const char *driver_name = NULL;
7372         uint32_t version;
7373         const char *fn;
7374
7375         switch (p->opnum) {
7376                 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7377                         fn = "_spoolss_AddPrinterDriver";
7378                         break;
7379                 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7380                         fn = "_spoolss_AddPrinterDriverEx";
7381                         break;
7382                 default:
7383                         return WERR_INVALID_PARAM;
7384         }
7385
7386         /*
7387          * we only support the semantics of AddPrinterDriver()
7388          * i.e. only copy files that are newer than existing ones
7389          */
7390
7391         if (r->in.flags == 0) {
7392                 return WERR_INVALID_PARAM;
7393         }
7394
7395         if (r->in.flags != APD_COPY_NEW_FILES) {
7396                 return WERR_ACCESS_DENIED;
7397         }
7398
7399         /* FIXME */
7400         if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7401                 /* Clever hack from Martin Zielinski <mz@seh.de>
7402                  * to allow downgrade from level 8 (Vista).
7403                  */
7404                 DEBUG(0,("%s: level %d not yet implemented\n", fn,
7405                         r->in.info_ctr->level));
7406                 return WERR_UNKNOWN_LEVEL;
7407         }
7408
7409         DEBUG(5,("Cleaning driver's information\n"));
7410         err = clean_up_driver_struct(p->mem_ctx, p, r->in.info_ctr);
7411         if (!W_ERROR_IS_OK(err))
7412                 goto done;
7413
7414         DEBUG(5,("Moving driver to final destination\n"));
7415         if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7416                                                               &err)) ) {
7417                 goto done;
7418         }
7419
7420         err = winreg_add_driver(p->mem_ctx, p->server_info,
7421                                 r->in.info_ctr, &driver_name, &version);
7422         if (!W_ERROR_IS_OK(err)) {
7423                 goto done;
7424         }
7425
7426         /*
7427          * I think this is where he DrvUpgradePrinter() hook would be
7428          * be called in a driver's interface DLL on a Windows NT 4.0/2k
7429          * server.  Right now, we just need to send ourselves a message
7430          * to update each printer bound to this driver.   --jerry
7431          */
7432
7433         if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7434                 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7435                         fn, driver_name));
7436         }
7437
7438 done:
7439         return err;
7440 }
7441
7442 /****************************************************************
7443  _spoolss_AddPrinterDriver
7444 ****************************************************************/
7445
7446 WERROR _spoolss_AddPrinterDriver(struct pipes_struct *p,
7447                                  struct spoolss_AddPrinterDriver *r)
7448 {
7449         struct spoolss_AddPrinterDriverEx a;
7450
7451         switch (r->in.info_ctr->level) {
7452         case 2:
7453         case 3:
7454         case 4:
7455         case 5:
7456                 break;
7457         default:
7458                 return WERR_UNKNOWN_LEVEL;
7459         }
7460
7461         a.in.servername         = r->in.servername;
7462         a.in.info_ctr           = r->in.info_ctr;
7463         a.in.flags              = APD_COPY_NEW_FILES;
7464
7465         return _spoolss_AddPrinterDriverEx(p, &a);
7466 }
7467
7468 /****************************************************************************
7469 ****************************************************************************/
7470
7471 struct _spoolss_paths {
7472         int type;
7473         const char *share;
7474         const char *dir;
7475 };
7476
7477 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7478
7479 static const struct _spoolss_paths spoolss_paths[]= {
7480         { SPOOLSS_DRIVER_PATH,          "print$",       "DRIVERS" },
7481         { SPOOLSS_PRTPROCS_PATH,        "prnproc$",     "PRTPROCS" }
7482 };
7483
7484 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7485                                           const char *servername,
7486                                           const char *environment,
7487                                           int component,
7488                                           char **path)
7489 {
7490         const char *pservername = NULL;
7491         const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7492         const char *short_archi;
7493
7494         *path = NULL;
7495
7496         /* environment may be empty */
7497         if (environment && strlen(environment)) {
7498                 long_archi = environment;
7499         }
7500
7501         /* servername may be empty */
7502         if (servername && strlen(servername)) {
7503                 pservername = canon_servername(servername);
7504
7505                 if (!is_myname_or_ipaddr(pservername)) {
7506                         return WERR_INVALID_PARAM;
7507                 }
7508         }
7509
7510         if (!(short_archi = get_short_archi(long_archi))) {
7511                 return WERR_INVALID_ENVIRONMENT;
7512         }
7513
7514         switch (component) {
7515         case SPOOLSS_PRTPROCS_PATH:
7516         case SPOOLSS_DRIVER_PATH:
7517                 if (pservername) {
7518                         *path = talloc_asprintf(mem_ctx,
7519                                         "\\\\%s\\%s\\%s",
7520                                         pservername,
7521                                         spoolss_paths[component].share,
7522                                         short_archi);
7523                 } else {
7524                         *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7525                                         SPOOLSS_DEFAULT_SERVER_PATH,
7526                                         spoolss_paths[component].dir,
7527                                         short_archi);
7528                 }
7529                 break;
7530         default:
7531                 return WERR_INVALID_PARAM;
7532         }
7533
7534         if (!*path) {
7535                 return WERR_NOMEM;
7536         }
7537
7538         return WERR_OK;
7539 }
7540
7541 /****************************************************************************
7542 ****************************************************************************/
7543
7544 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7545                                           const char *servername,
7546                                           const char *environment,
7547                                           struct spoolss_DriverDirectoryInfo1 *r)
7548 {
7549         WERROR werr;
7550         char *path = NULL;
7551
7552         werr = compose_spoolss_server_path(mem_ctx,
7553                                            servername,
7554                                            environment,
7555                                            SPOOLSS_DRIVER_PATH,
7556                                            &path);
7557         if (!W_ERROR_IS_OK(werr)) {
7558                 return werr;
7559         }
7560
7561         DEBUG(4,("printer driver directory: [%s]\n", path));
7562
7563         r->directory_name = path;
7564
7565         return WERR_OK;
7566 }
7567
7568 /****************************************************************
7569  _spoolss_GetPrinterDriverDirectory
7570 ****************************************************************/
7571
7572 WERROR _spoolss_GetPrinterDriverDirectory(struct pipes_struct *p,
7573                                           struct spoolss_GetPrinterDriverDirectory *r)
7574 {
7575         WERROR werror;
7576
7577         /* that's an [in out] buffer */
7578
7579         if (!r->in.buffer && (r->in.offered != 0)) {
7580                 return WERR_INVALID_PARAM;
7581         }
7582
7583         DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7584                 r->in.level));
7585
7586         *r->out.needed = 0;
7587
7588         /* r->in.level is ignored */
7589
7590         werror = getprinterdriverdir_level_1(p->mem_ctx,
7591                                              r->in.server,
7592                                              r->in.environment,
7593                                              &r->out.info->info1);
7594         if (!W_ERROR_IS_OK(werror)) {
7595                 TALLOC_FREE(r->out.info);
7596                 return werror;
7597         }
7598
7599         *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo, 
7600                                                r->out.info, r->in.level);
7601         r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7602
7603         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7604 }
7605
7606 /****************************************************************
7607  _spoolss_EnumPrinterData
7608 ****************************************************************/
7609
7610 WERROR _spoolss_EnumPrinterData(struct pipes_struct *p,
7611                                 struct spoolss_EnumPrinterData *r)
7612 {
7613         WERROR result;
7614         struct spoolss_EnumPrinterDataEx r2;
7615         uint32_t count;
7616         struct spoolss_PrinterEnumValues *info, *val = NULL;
7617         uint32_t needed;
7618
7619         r2.in.handle    = r->in.handle;
7620         r2.in.key_name  = "PrinterDriverData";
7621         r2.in.offered   = 0;
7622         r2.out.count    = &count;
7623         r2.out.info     = &info;
7624         r2.out.needed   = &needed;
7625
7626         result = _spoolss_EnumPrinterDataEx(p, &r2);
7627         if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
7628                 r2.in.offered = needed;
7629                 result = _spoolss_EnumPrinterDataEx(p, &r2);
7630         }
7631         if (!W_ERROR_IS_OK(result)) {
7632                 return result;
7633         }
7634
7635         /*
7636          * The NT machine wants to know the biggest size of value and data
7637          *
7638          * cf: MSDN EnumPrinterData remark section
7639          */
7640
7641         if (!r->in.value_offered && !r->in.data_offered) {
7642                 uint32_t biggest_valuesize = 0;
7643                 uint32_t biggest_datasize = 0;
7644                 int i, name_length;
7645
7646                 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7647
7648                 for (i=0; i<count; i++) {
7649
7650                         name_length = strlen(info[i].value_name);
7651                         if (strlen(info[i].value_name) > biggest_valuesize) {
7652                                 biggest_valuesize = name_length;
7653                         }
7654
7655                         if (info[i].data_length > biggest_datasize) {
7656                                 biggest_datasize = info[i].data_length;
7657                         }
7658
7659                         DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
7660                                 biggest_datasize));
7661                 }
7662
7663                 /* the value is an UNICODE string but real_value_size is the length
7664                    in bytes including the trailing 0 */
7665
7666                 *r->out.value_needed = 2 * (1 + biggest_valuesize);
7667                 *r->out.data_needed  = biggest_datasize;
7668
7669                 DEBUG(6,("final values: [%d], [%d]\n",
7670                         *r->out.value_needed, *r->out.data_needed));
7671
7672                 return WERR_OK;
7673         }
7674
7675         if (r->in.enum_index < count) {
7676                 val = &info[r->in.enum_index];
7677         }
7678
7679         if (val == NULL) {
7680                 /* out_value should default to "" or else NT4 has
7681                    problems unmarshalling the response */
7682
7683                 if (r->in.value_offered) {
7684                         *r->out.value_needed = 1;
7685                         r->out.value_name = talloc_strdup(r, "");
7686                         if (!r->out.value_name) {
7687                                 return WERR_NOMEM;
7688                         }
7689                 } else {
7690                         r->out.value_name = NULL;
7691                         *r->out.value_needed = 0;
7692                 }
7693
7694                 /* the data is counted in bytes */
7695
7696                 *r->out.data_needed = r->in.data_offered;
7697
7698                 result = WERR_NO_MORE_ITEMS;
7699         } else {
7700                 /*
7701                  * the value is:
7702                  * - counted in bytes in the request
7703                  * - counted in UNICODE chars in the max reply
7704                  * - counted in bytes in the real size
7705                  *
7706                  * take a pause *before* coding not *during* coding
7707                  */
7708
7709                 /* name */
7710                 if (r->in.value_offered) {
7711                         r->out.value_name = talloc_strdup(r, val->value_name);
7712                         if (!r->out.value_name) {
7713                                 return WERR_NOMEM;
7714                         }
7715                         *r->out.value_needed = val->value_name_len;
7716                 } else {
7717                         r->out.value_name = NULL;
7718                         *r->out.value_needed = 0;
7719                 }
7720
7721                 /* type */
7722
7723                 *r->out.type = val->type;
7724
7725                 /* data - counted in bytes */
7726
7727                 /*
7728                  * See the section "Dynamically Typed Query Parameters"
7729                  * in MS-RPRN.
7730                  */
7731
7732                 if (r->out.data && val->data && val->data->data &&
7733                                 val->data_length && r->in.data_offered) {
7734                         memcpy(r->out.data, val->data->data,
7735                                 MIN(val->data_length,r->in.data_offered));
7736                 }
7737
7738                 *r->out.data_needed = val->data_length;
7739
7740                 result = WERR_OK;
7741         }
7742
7743         return result;
7744 }
7745
7746 /****************************************************************
7747  _spoolss_SetPrinterData
7748 ****************************************************************/
7749
7750 WERROR _spoolss_SetPrinterData(struct pipes_struct *p,
7751                                struct spoolss_SetPrinterData *r)
7752 {
7753         struct spoolss_SetPrinterDataEx r2;
7754
7755         r2.in.handle            = r->in.handle;
7756         r2.in.key_name          = "PrinterDriverData";
7757         r2.in.value_name        = r->in.value_name;
7758         r2.in.type              = r->in.type;
7759         r2.in.data              = r->in.data;
7760         r2.in.offered           = r->in.offered;
7761
7762         return _spoolss_SetPrinterDataEx(p, &r2);
7763 }
7764
7765 /****************************************************************
7766  _spoolss_ResetPrinter
7767 ****************************************************************/
7768
7769 WERROR _spoolss_ResetPrinter(struct pipes_struct *p,
7770                              struct spoolss_ResetPrinter *r)
7771 {
7772         Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
7773         int             snum;
7774
7775         DEBUG(5,("_spoolss_ResetPrinter\n"));
7776
7777         /*
7778          * All we do is to check to see if the handle and queue is valid.
7779          * This call really doesn't mean anything to us because we only
7780          * support RAW printing.   --jerry
7781          */
7782
7783         if (!Printer) {
7784                 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7785                         OUR_HANDLE(r->in.handle)));
7786                 return WERR_BADFID;
7787         }
7788
7789         if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7790                 return WERR_BADFID;
7791
7792
7793         /* blindly return success */
7794         return WERR_OK;
7795 }
7796
7797 /****************************************************************
7798  _spoolss_DeletePrinterData
7799 ****************************************************************/
7800
7801 WERROR _spoolss_DeletePrinterData(struct pipes_struct *p,
7802                                   struct spoolss_DeletePrinterData *r)
7803 {
7804         struct spoolss_DeletePrinterDataEx r2;
7805
7806         r2.in.handle            = r->in.handle;
7807         r2.in.key_name          = "PrinterDriverData";
7808         r2.in.value_name        = r->in.value_name;
7809
7810         return _spoolss_DeletePrinterDataEx(p, &r2);
7811 }
7812
7813 /****************************************************************
7814  _spoolss_AddForm
7815 ****************************************************************/
7816
7817 WERROR _spoolss_AddForm(struct pipes_struct *p,
7818                         struct spoolss_AddForm *r)
7819 {
7820         struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7821         int snum = -1;
7822         WERROR status = WERR_OK;
7823         SE_PRIV se_printop = SE_PRINT_OPERATOR;
7824
7825         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7826
7827         DEBUG(5,("_spoolss_AddForm\n"));
7828
7829         if (!Printer) {
7830                 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
7831                         OUR_HANDLE(r->in.handle)));
7832                 return WERR_BADFID;
7833         }
7834
7835         /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7836            and not a printer admin, then fail */
7837
7838         if ((p->server_info->utok.uid != sec_initial_uid()) &&
7839              !user_has_privileges(p->server_info->ptok, &se_printop) &&
7840              !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7841                                           p->server_info->info3->base.domain.string,
7842                                           NULL,
7843                                           p->server_info->ptok,
7844                                           lp_printer_admin(snum))) {
7845                 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
7846                 return WERR_ACCESS_DENIED;
7847         }
7848
7849         switch (form->flags) {
7850         case SPOOLSS_FORM_USER:
7851         case SPOOLSS_FORM_BUILTIN:
7852         case SPOOLSS_FORM_PRINTER:
7853                 break;
7854         default:
7855                 return WERR_INVALID_PARAM;
7856         }
7857
7858         status = winreg_printer_addform1(p->mem_ctx, p->server_info, form);
7859         if (!W_ERROR_IS_OK(status)) {
7860                 return status;
7861         }
7862
7863         /*
7864          * ChangeID must always be set if this is a printer
7865          */
7866         if (Printer->printer_type == SPLHND_PRINTER) {
7867                 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7868                         return WERR_BADFID;
7869                 }
7870
7871                 status = winreg_printer_update_changeid(p->mem_ctx,
7872                                                         p->server_info,
7873                                                         lp_const_servicename(snum));
7874                 if (!W_ERROR_IS_OK(status)) {
7875                         return status;
7876                 }
7877         }
7878
7879         return status;
7880 }
7881
7882 /****************************************************************
7883  _spoolss_DeleteForm
7884 ****************************************************************/
7885
7886 WERROR _spoolss_DeleteForm(struct pipes_struct *p,
7887                            struct spoolss_DeleteForm *r)
7888 {
7889         const char *form_name = r->in.form_name;
7890         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7891         int snum = -1;
7892         WERROR status = WERR_OK;
7893         SE_PRIV se_printop = SE_PRINT_OPERATOR;
7894
7895         DEBUG(5,("_spoolss_DeleteForm\n"));
7896
7897         if (!Printer) {
7898                 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
7899                         OUR_HANDLE(r->in.handle)));
7900                 return WERR_BADFID;
7901         }
7902
7903         if ((p->server_info->utok.uid != sec_initial_uid()) &&
7904              !user_has_privileges(p->server_info->ptok, &se_printop) &&
7905              !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7906                                           p->server_info->info3->base.domain.string,
7907                                           NULL,
7908                                           p->server_info->ptok,
7909                                           lp_printer_admin(snum))) {
7910                 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
7911                 return WERR_ACCESS_DENIED;
7912         }
7913
7914         status = winreg_printer_deleteform1(p->mem_ctx,
7915                                             p->server_info,
7916                                             form_name);
7917         if (!W_ERROR_IS_OK(status)) {
7918                 return status;
7919         }
7920
7921         /*
7922          * ChangeID must always be set if this is a printer
7923          */
7924         if (Printer->printer_type == SPLHND_PRINTER) {
7925                 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7926                         return WERR_BADFID;
7927                 }
7928
7929                 status = winreg_printer_update_changeid(p->mem_ctx,
7930                                                         p->server_info,
7931                                                         lp_const_servicename(snum));
7932                 if (!W_ERROR_IS_OK(status)) {
7933                         return status;
7934                 }
7935         }
7936
7937         return status;
7938 }
7939
7940 /****************************************************************
7941  _spoolss_SetForm
7942 ****************************************************************/
7943
7944 WERROR _spoolss_SetForm(struct pipes_struct *p,
7945                         struct spoolss_SetForm *r)
7946 {
7947         struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7948         const char *form_name = r->in.form_name;
7949         int snum = -1;
7950         WERROR status = WERR_OK;
7951         SE_PRIV se_printop = SE_PRINT_OPERATOR;
7952
7953         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7954
7955         DEBUG(5,("_spoolss_SetForm\n"));
7956
7957         if (!Printer) {
7958                 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
7959                         OUR_HANDLE(r->in.handle)));
7960                 return WERR_BADFID;
7961         }
7962
7963         /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7964            and not a printer admin, then fail */
7965
7966         if ((p->server_info->utok.uid != sec_initial_uid()) &&
7967              !user_has_privileges(p->server_info->ptok, &se_printop) &&
7968              !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7969                                           p->server_info->info3->base.domain.string,
7970                                           NULL,
7971                                           p->server_info->ptok,
7972                                           lp_printer_admin(snum))) {
7973                 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
7974                 return WERR_ACCESS_DENIED;
7975         }
7976
7977         status = winreg_printer_setform1(p->mem_ctx,
7978                                          p->server_info,
7979                                          form_name,
7980                                          form);
7981         if (!W_ERROR_IS_OK(status)) {
7982                 return status;
7983         }
7984
7985         /*
7986          * ChangeID must always be set if this is a printer
7987          */
7988         if (Printer->printer_type == SPLHND_PRINTER) {
7989                 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7990                         return WERR_BADFID;
7991                 }
7992
7993                 status = winreg_printer_update_changeid(p->mem_ctx,
7994                                                         p->server_info,
7995                                                         lp_const_servicename(snum));
7996                 if (!W_ERROR_IS_OK(status)) {
7997                         return status;
7998                 }
7999         }
8000
8001         return status;
8002 }
8003
8004 /****************************************************************************
8005  fill_print_processor1
8006 ****************************************************************************/
8007
8008 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8009                                     struct spoolss_PrintProcessorInfo1 *r,
8010                                     const char *print_processor_name)
8011 {
8012         r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8013         W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8014
8015         return WERR_OK;
8016 }
8017
8018 /****************************************************************************
8019  enumprintprocessors level 1.
8020 ****************************************************************************/
8021
8022 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8023                                           union spoolss_PrintProcessorInfo **info_p,
8024                                           uint32_t *count)
8025 {
8026         union spoolss_PrintProcessorInfo *info;
8027         WERROR result;
8028
8029         info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8030         W_ERROR_HAVE_NO_MEMORY(info);
8031
8032         *count = 1;
8033
8034         result = fill_print_processor1(info, &info[0].info1, "winprint");
8035         if (!W_ERROR_IS_OK(result)) {
8036                 goto out;
8037         }
8038
8039  out:
8040         if (!W_ERROR_IS_OK(result)) {
8041                 TALLOC_FREE(info);
8042                 *count = 0;
8043                 return result;
8044         }
8045
8046         *info_p = info;
8047
8048         return WERR_OK;
8049 }
8050
8051 /****************************************************************
8052  _spoolss_EnumPrintProcessors
8053 ****************************************************************/
8054
8055 WERROR _spoolss_EnumPrintProcessors(struct pipes_struct *p,
8056                                     struct spoolss_EnumPrintProcessors *r)
8057 {
8058         WERROR result;
8059
8060         /* that's an [in out] buffer */
8061
8062         if (!r->in.buffer && (r->in.offered != 0)) {
8063                 return WERR_INVALID_PARAM;
8064         }
8065
8066         DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8067
8068         /*
8069          * Enumerate the print processors ...
8070          *
8071          * Just reply with "winprint", to keep NT happy
8072          * and I can use my nice printer checker.
8073          */
8074
8075         *r->out.count = 0;
8076         *r->out.needed = 0;
8077         *r->out.info = NULL;
8078
8079         switch (r->in.level) {
8080         case 1:
8081                 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8082                                                      r->out.count);
8083                 break;
8084         default:
8085                 return WERR_UNKNOWN_LEVEL;
8086         }
8087
8088         if (!W_ERROR_IS_OK(result)) {
8089                 return result;
8090         }
8091
8092         *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8093                                                      spoolss_EnumPrintProcessors,
8094                                                      *r->out.info, r->in.level,
8095                                                      *r->out.count);
8096         *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8097         *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8098
8099         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8100 }
8101
8102 /****************************************************************************
8103  fill_printprocdatatype1
8104 ****************************************************************************/
8105
8106 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8107                                       struct spoolss_PrintProcDataTypesInfo1 *r,
8108                                       const char *name_array)
8109 {
8110         r->name_array = talloc_strdup(mem_ctx, name_array);
8111         W_ERROR_HAVE_NO_MEMORY(r->name_array);
8112
8113         return WERR_OK;
8114 }
8115
8116 /****************************************************************************
8117  enumprintprocdatatypes level 1.
8118 ****************************************************************************/
8119
8120 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8121                                              union spoolss_PrintProcDataTypesInfo **info_p,
8122                                              uint32_t *count)
8123 {
8124         WERROR result;
8125         union spoolss_PrintProcDataTypesInfo *info;
8126
8127         info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8128         W_ERROR_HAVE_NO_MEMORY(info);
8129
8130         *count = 1;
8131
8132         result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8133         if (!W_ERROR_IS_OK(result)) {
8134                 goto out;
8135         }
8136
8137  out:
8138         if (!W_ERROR_IS_OK(result)) {
8139                 TALLOC_FREE(info);
8140                 *count = 0;
8141                 return result;
8142         }
8143
8144         *info_p = info;
8145
8146         return WERR_OK;
8147 }
8148
8149 /****************************************************************
8150  _spoolss_EnumPrintProcDataTypes
8151 ****************************************************************/
8152
8153 WERROR _spoolss_EnumPrintProcDataTypes(struct pipes_struct *p,
8154                                        struct spoolss_EnumPrintProcDataTypes *r)
8155 {
8156         WERROR result;
8157
8158         /* that's an [in out] buffer */
8159
8160         if (!r->in.buffer && (r->in.offered != 0)) {
8161                 return WERR_INVALID_PARAM;
8162         }
8163
8164         DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8165
8166         *r->out.count = 0;
8167         *r->out.needed = 0;
8168         *r->out.info = NULL;
8169
8170         switch (r->in.level) {
8171         case 1:
8172                 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8173                                                         r->out.count);
8174                 break;
8175         default:
8176                 return WERR_UNKNOWN_LEVEL;
8177         }
8178
8179         *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8180                                                      spoolss_EnumPrintProcDataTypes, 
8181                                                      *r->out.info, r->in.level,
8182                                                      *r->out.count);
8183         *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8184         *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8185
8186         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8187 }
8188
8189 /****************************************************************************
8190  fill_monitor_1
8191 ****************************************************************************/
8192
8193 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8194                              struct spoolss_MonitorInfo1 *r,
8195                              const char *monitor_name)
8196 {
8197         r->monitor_name                 = talloc_strdup(mem_ctx, monitor_name);
8198         W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8199
8200         return WERR_OK;
8201 }
8202
8203 /****************************************************************************
8204  fill_monitor_2
8205 ****************************************************************************/
8206
8207 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8208                              struct spoolss_MonitorInfo2 *r,
8209                              const char *monitor_name,
8210                              const char *environment,
8211                              const char *dll_name)
8212 {
8213         r->monitor_name                 = talloc_strdup(mem_ctx, monitor_name);
8214         W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8215         r->environment                  = talloc_strdup(mem_ctx, environment);
8216         W_ERROR_HAVE_NO_MEMORY(r->environment);
8217         r->dll_name                     = talloc_strdup(mem_ctx, dll_name);
8218         W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8219
8220         return WERR_OK;
8221 }
8222
8223 /****************************************************************************
8224  enumprintmonitors level 1.
8225 ****************************************************************************/
8226
8227 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8228                                         union spoolss_MonitorInfo **info_p,
8229                                         uint32_t *count)
8230 {
8231         union spoolss_MonitorInfo *info;
8232         WERROR result = WERR_OK;
8233
8234         info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8235         W_ERROR_HAVE_NO_MEMORY(info);
8236
8237         *count = 2;
8238
8239         result = fill_monitor_1(info, &info[0].info1,
8240                                 SPL_LOCAL_PORT);
8241         if (!W_ERROR_IS_OK(result)) {
8242                 goto out;
8243         }
8244
8245         result = fill_monitor_1(info, &info[1].info1,
8246                                 SPL_TCPIP_PORT);
8247         if (!W_ERROR_IS_OK(result)) {
8248                 goto out;
8249         }
8250
8251 out:
8252         if (!W_ERROR_IS_OK(result)) {
8253                 TALLOC_FREE(info);
8254                 *count = 0;
8255                 return result;
8256         }
8257
8258         *info_p = info;
8259
8260         return WERR_OK;
8261 }
8262
8263 /****************************************************************************
8264  enumprintmonitors level 2.
8265 ****************************************************************************/
8266
8267 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8268                                         union spoolss_MonitorInfo **info_p,
8269                                         uint32_t *count)
8270 {
8271         union spoolss_MonitorInfo *info;
8272         WERROR result = WERR_OK;
8273
8274         info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8275         W_ERROR_HAVE_NO_MEMORY(info);
8276
8277         *count = 2;
8278
8279         result = fill_monitor_2(info, &info[0].info2,
8280                                 SPL_LOCAL_PORT,
8281                                 "Windows NT X86", /* FIXME */
8282                                 "localmon.dll");
8283         if (!W_ERROR_IS_OK(result)) {
8284                 goto out;
8285         }
8286
8287         result = fill_monitor_2(info, &info[1].info2,
8288                                 SPL_TCPIP_PORT,
8289                                 "Windows NT X86", /* FIXME */
8290                                 "tcpmon.dll");
8291         if (!W_ERROR_IS_OK(result)) {
8292                 goto out;
8293         }
8294
8295 out:
8296         if (!W_ERROR_IS_OK(result)) {
8297                 TALLOC_FREE(info);
8298                 *count = 0;
8299                 return result;
8300         }
8301
8302         *info_p = info;
8303
8304         return WERR_OK;
8305 }
8306
8307 /****************************************************************
8308  _spoolss_EnumMonitors
8309 ****************************************************************/
8310
8311 WERROR _spoolss_EnumMonitors(struct pipes_struct *p,
8312                              struct spoolss_EnumMonitors *r)
8313 {
8314         WERROR result;
8315
8316         /* that's an [in out] buffer */
8317
8318         if (!r->in.buffer && (r->in.offered != 0)) {
8319                 return WERR_INVALID_PARAM;
8320         }
8321
8322         DEBUG(5,("_spoolss_EnumMonitors\n"));
8323
8324         /*
8325          * Enumerate the print monitors ...
8326          *
8327          * Just reply with "Local Port", to keep NT happy
8328          * and I can use my nice printer checker.
8329          */
8330
8331         *r->out.count = 0;
8332         *r->out.needed = 0;
8333         *r->out.info = NULL;
8334
8335         switch (r->in.level) {
8336         case 1:
8337                 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8338                                                    r->out.count);
8339                 break;
8340         case 2:
8341                 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8342                                                    r->out.count);
8343                 break;
8344         default:
8345                 return WERR_UNKNOWN_LEVEL;
8346         }
8347
8348         if (!W_ERROR_IS_OK(result)) {
8349                 return result;
8350         }
8351
8352         *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8353                                                      spoolss_EnumMonitors, 
8354                                                      *r->out.info, r->in.level,
8355                                                      *r->out.count);
8356         *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8357         *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8358
8359         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8360 }
8361
8362 /****************************************************************************
8363 ****************************************************************************/
8364
8365 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8366                              const print_queue_struct *queue,
8367                              int count, int snum,
8368                              struct spoolss_PrinterInfo2 *pinfo2,
8369                              uint32_t jobid,
8370                              struct spoolss_JobInfo1 *r)
8371 {
8372         int i = 0;
8373         bool found = false;
8374
8375         for (i=0; i<count; i++) {
8376                 if (queue[i].job == (int)jobid) {
8377                         found = true;
8378                         break;
8379                 }
8380         }
8381
8382         if (found == false) {
8383                 /* NT treats not found as bad param... yet another bad choice */
8384                 return WERR_INVALID_PARAM;
8385         }
8386
8387         return fill_job_info1(mem_ctx,
8388                               r,
8389                               &queue[i],
8390                               i,
8391                               snum,
8392                               pinfo2);
8393 }
8394
8395 /****************************************************************************
8396 ****************************************************************************/
8397
8398 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8399                              const print_queue_struct *queue,
8400                              int count, int snum,
8401                              struct spoolss_PrinterInfo2 *pinfo2,
8402                              uint32_t jobid,
8403                              struct spoolss_JobInfo2 *r)
8404 {
8405         int i = 0;
8406         bool found = false;
8407         struct spoolss_DeviceMode *devmode;
8408         WERROR result;
8409
8410         for (i=0; i<count; i++) {
8411                 if (queue[i].job == (int)jobid) {
8412                         found = true;
8413                         break;
8414                 }
8415         }
8416
8417         if (found == false) {
8418                 /* NT treats not found as bad param... yet another bad
8419                    choice */
8420                 return WERR_INVALID_PARAM;
8421         }
8422
8423         /*
8424          * if the print job does not have a DEVMODE associated with it,
8425          * just use the one for the printer. A NULL devicemode is not
8426          *  a failure condition
8427          */
8428
8429         devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8430         if (!devmode) {
8431                 result = spoolss_create_default_devmode(mem_ctx,
8432                                                 pinfo2->printername,
8433                                                 &devmode);
8434                 if (!W_ERROR_IS_OK(result)) {
8435                         DEBUG(3, ("Can't proceed w/o a devmode!"));
8436                         return result;
8437                 }
8438         }
8439
8440         return fill_job_info2(mem_ctx,
8441                               r,
8442                               &queue[i],
8443                               i,
8444                               snum,
8445                               pinfo2,
8446                               devmode);
8447 }
8448
8449 /****************************************************************
8450  _spoolss_GetJob
8451 ****************************************************************/
8452
8453 WERROR _spoolss_GetJob(struct pipes_struct *p,
8454                        struct spoolss_GetJob *r)
8455 {
8456         WERROR result = WERR_OK;
8457         struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8458         int snum;
8459         int count;
8460         print_queue_struct      *queue = NULL;
8461         print_status_struct prt_status;
8462
8463         /* that's an [in out] buffer */
8464
8465         if (!r->in.buffer && (r->in.offered != 0)) {
8466                 return WERR_INVALID_PARAM;
8467         }
8468
8469         DEBUG(5,("_spoolss_GetJob\n"));
8470
8471         *r->out.needed = 0;
8472
8473         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8474                 return WERR_BADFID;
8475         }
8476
8477         result = winreg_get_printer(p->mem_ctx, p->server_info, NULL,
8478                                     lp_servicename(snum), &pinfo2);
8479         if (!W_ERROR_IS_OK(result)) {
8480                 return result;
8481         }
8482
8483         count = print_queue_status(snum, &queue, &prt_status);
8484
8485         DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8486                      count, prt_status.status, prt_status.message));
8487
8488         switch (r->in.level) {
8489         case 1:
8490                 result = getjob_level_1(p->mem_ctx,
8491                                         queue, count, snum, pinfo2,
8492                                         r->in.job_id, &r->out.info->info1);
8493                 break;
8494         case 2:
8495                 result = getjob_level_2(p->mem_ctx,
8496                                         queue, count, snum, pinfo2,
8497                                         r->in.job_id, &r->out.info->info2);
8498                 break;
8499         default:
8500                 result = WERR_UNKNOWN_LEVEL;
8501                 break;
8502         }
8503
8504         SAFE_FREE(queue);
8505         TALLOC_FREE(pinfo2);
8506
8507         if (!W_ERROR_IS_OK(result)) {
8508                 TALLOC_FREE(r->out.info);
8509                 return result;
8510         }
8511
8512         *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
8513                                                                                    r->in.level);
8514         r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8515
8516         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8517 }
8518
8519 /****************************************************************
8520  _spoolss_GetPrinterDataEx
8521 ****************************************************************/
8522
8523 WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
8524                                  struct spoolss_GetPrinterDataEx *r)
8525 {
8526
8527         Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
8528         const char *printer;
8529         int                     snum = 0;
8530         WERROR result = WERR_OK;
8531         DATA_BLOB blob;
8532         enum winreg_Type val_type;
8533         uint8_t *val_data;
8534         uint32_t val_size;
8535
8536
8537         DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8538
8539         DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8540                 r->in.key_name, r->in.value_name));
8541
8542         /* in case of problem, return some default values */
8543
8544         *r->out.needed  = 0;
8545         *r->out.type    = REG_NONE;
8546
8547         if (!Printer) {
8548                 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8549                         OUR_HANDLE(r->in.handle)));
8550                 result = WERR_BADFID;
8551                 goto done;
8552         }
8553
8554         /* Is the handle to a printer or to the server? */
8555
8556         if (Printer->printer_type == SPLHND_SERVER) {
8557
8558                 union spoolss_PrinterData data;
8559
8560                 result = getprinterdata_printer_server(p->mem_ctx,
8561                                                        r->in.value_name,
8562                                                        r->out.type,
8563                                                        &data);
8564                 if (!W_ERROR_IS_OK(result)) {
8565                         return result;
8566                 }
8567
8568                 result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8569                                                   *r->out.type, &data);
8570                 if (!W_ERROR_IS_OK(result)) {
8571                         return result;
8572                 }
8573
8574                 *r->out.needed = blob.length;
8575
8576                 if (r->in.offered >= *r->out.needed) {
8577                         memcpy(r->out.data, blob.data, blob.length);
8578                 }
8579
8580                 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8581         }
8582
8583         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8584                 return WERR_BADFID;
8585         }
8586         printer = lp_const_servicename(snum);
8587
8588         /* check to see if the keyname is valid */
8589         if (!strlen(r->in.key_name)) {
8590                 return WERR_INVALID_PARAM;
8591         }
8592
8593         /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
8594         if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8595             strequal(r->in.value_name, "ChangeId")) {
8596                 *r->out.type = REG_DWORD;
8597                 *r->out.needed = 4;
8598                 if (r->in.offered >= *r->out.needed) {
8599                         uint32_t changeid = 0;
8600
8601                         result = winreg_printer_get_changeid(p->mem_ctx,
8602                                                              p->server_info,
8603                                                              printer,
8604                                                              &changeid);
8605                         if (!W_ERROR_IS_OK(result)) {
8606                                 return result;
8607                         }
8608
8609                         SIVAL(r->out.data, 0, changeid);
8610                         result = WERR_OK;
8611                 }
8612                 goto done;
8613         }
8614
8615         result = winreg_get_printer_dataex(p->mem_ctx,
8616                                            p->server_info,
8617                                            printer,
8618                                            r->in.key_name,
8619                                            r->in.value_name,
8620                                            &val_type,
8621                                            &val_data,
8622                                            &val_size);
8623         if (!W_ERROR_IS_OK(result)) {
8624                 return result;
8625         }
8626
8627         *r->out.needed = val_size;
8628         *r->out.type = val_type;
8629
8630         if (r->in.offered >= *r->out.needed) {
8631                 memcpy(r->out.data, val_data, val_size);
8632         }
8633
8634  done:
8635         *r->out.type    = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8636         r->out.data     = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8637
8638         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8639 }
8640
8641 /****************************************************************
8642  _spoolss_SetPrinterDataEx
8643 ****************************************************************/
8644
8645 WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
8646                                  struct spoolss_SetPrinterDataEx *r)
8647 {
8648         struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8649         int                     snum = 0;
8650         WERROR                  result = WERR_OK;
8651         Printer_entry           *Printer = find_printer_index_by_hnd(p, r->in.handle);
8652         char                    *oid_string;
8653
8654         DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8655
8656         /* From MSDN documentation of SetPrinterDataEx: pass request to
8657            SetPrinterData if key is "PrinterDriverData" */
8658
8659         if (!Printer) {
8660                 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8661                         OUR_HANDLE(r->in.handle)));
8662                 return WERR_BADFID;
8663         }
8664
8665         if (Printer->printer_type == SPLHND_SERVER) {
8666                 DEBUG(10,("_spoolss_SetPrinterDataEx: "
8667                         "Not implemented for server handles yet\n"));
8668                 return WERR_INVALID_PARAM;
8669         }
8670
8671         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8672                 return WERR_BADFID;
8673         }
8674
8675         /*
8676          * Access check : NT returns "access denied" if you make a
8677          * SetPrinterData call without the necessary privildge.
8678          * we were originally returning OK if nothing changed
8679          * which made Win2k issue **a lot** of SetPrinterData
8680          * when connecting to a printer  --jerry
8681          */
8682
8683         if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8684                 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8685                         "change denied by handle access permissions\n"));
8686                 return WERR_ACCESS_DENIED;
8687         }
8688
8689         result = winreg_get_printer(Printer, p->server_info,
8690                                     Printer->servername,
8691                                     lp_servicename(snum),
8692                                     &pinfo2);
8693         if (!W_ERROR_IS_OK(result)) {
8694                 return result;
8695         }
8696
8697         /* check for OID in valuename */
8698
8699         oid_string = strchr(r->in.value_name, ',');
8700         if (oid_string) {
8701                 *oid_string = '\0';
8702                 oid_string++;
8703         }
8704
8705         /* save the registry data */
8706
8707         result = winreg_set_printer_dataex(p->mem_ctx,
8708                                            p->server_info,
8709                                            pinfo2->sharename,
8710                                            r->in.key_name,
8711                                            r->in.value_name,
8712                                            r->in.type,
8713                                            r->in.data,
8714                                            r->in.offered);
8715
8716         if (W_ERROR_IS_OK(result)) {
8717                 /* save the OID if one was specified */
8718                 if (oid_string) {
8719                         char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
8720                                 r->in.key_name, SPOOL_OID_KEY);
8721                         if (!str) {
8722                                 result = WERR_NOMEM;
8723                                 goto done;
8724                         }
8725
8726                         /*
8727                          * I'm not checking the status here on purpose.  Don't know
8728                          * if this is right, but I'm returning the status from the
8729                          * previous set_printer_dataex() call.  I have no idea if
8730                          * this is right.    --jerry
8731                          */
8732                         winreg_set_printer_dataex(p->mem_ctx,
8733                                                   p->server_info,
8734                                                   pinfo2->sharename,
8735                                                   str,
8736                                                   r->in.value_name,
8737                                                   REG_SZ,
8738                                                   (uint8_t *) oid_string,
8739                                                   strlen(oid_string) + 1);
8740                 }
8741
8742                 result = winreg_printer_update_changeid(p->mem_ctx,
8743                                                         p->server_info,
8744                                                         lp_const_servicename(snum));
8745
8746         }
8747
8748 done:
8749         talloc_free(pinfo2);
8750         return result;
8751 }
8752
8753 /****************************************************************
8754  _spoolss_DeletePrinterDataEx
8755 ****************************************************************/
8756
8757 WERROR _spoolss_DeletePrinterDataEx(struct pipes_struct *p,
8758                                     struct spoolss_DeletePrinterDataEx *r)
8759 {
8760         const char *printer;
8761         int             snum=0;
8762         WERROR          status = WERR_OK;
8763         Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
8764
8765         DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8766
8767         if (!Printer) {
8768                 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8769                         "Invalid handle (%s:%u:%u).\n",
8770                         OUR_HANDLE(r->in.handle)));
8771                 return WERR_BADFID;
8772         }
8773
8774         if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8775                 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8776                         "printer properties change denied by handle\n"));
8777                 return WERR_ACCESS_DENIED;
8778         }
8779
8780         if (!r->in.value_name || !r->in.key_name) {
8781                 return WERR_NOMEM;
8782         }
8783
8784         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8785                 return WERR_BADFID;
8786         }
8787         printer = lp_const_servicename(snum);
8788
8789         status = winreg_delete_printer_dataex(p->mem_ctx,
8790                                               p->server_info,
8791                                               printer,
8792                                               r->in.key_name,
8793                                               r->in.value_name);
8794         if (W_ERROR_IS_OK(status)) {
8795                 status = winreg_printer_update_changeid(p->mem_ctx,
8796                                                         p->server_info,
8797                                                         printer);
8798         }
8799
8800         return status;
8801 }
8802
8803 /****************************************************************
8804  _spoolss_EnumPrinterKey
8805 ****************************************************************/
8806
8807 WERROR _spoolss_EnumPrinterKey(struct pipes_struct *p,
8808                                struct spoolss_EnumPrinterKey *r)
8809 {
8810         uint32_t        num_keys;
8811         Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
8812         int             snum = 0;
8813         WERROR          result = WERR_BADFILE;
8814         const char **array = NULL;
8815         DATA_BLOB blob;
8816
8817         DEBUG(4,("_spoolss_EnumPrinterKey\n"));
8818
8819         if (!Printer) {
8820                 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
8821                         OUR_HANDLE(r->in.handle)));
8822                 return WERR_BADFID;
8823         }
8824
8825         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8826                 return WERR_BADFID;
8827         }
8828
8829         result = winreg_enum_printer_key(p->mem_ctx,
8830                                          p->server_info,
8831                                          lp_const_servicename(snum),
8832                                          r->in.key_name,
8833                                          &num_keys,
8834                                          &array);
8835         if (!W_ERROR_IS_OK(result)) {
8836                 goto done;
8837         }
8838
8839         if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
8840                 result = WERR_NOMEM;
8841                 goto done;
8842         }
8843
8844         *r->out._ndr_size = r->in.offered / 2;
8845         *r->out.needed = blob.length;
8846
8847         if (r->in.offered < *r->out.needed) {
8848                 result = WERR_MORE_DATA;
8849         } else {
8850                 result = WERR_OK;
8851                 r->out.key_buffer->string_array = array;
8852         }
8853
8854  done:
8855         if (!W_ERROR_IS_OK(result)) {
8856                 TALLOC_FREE(array);
8857                 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
8858                         *r->out.needed = 0;
8859                 }
8860         }
8861
8862         return result;
8863 }
8864
8865 /****************************************************************
8866  _spoolss_DeletePrinterKey
8867 ****************************************************************/
8868
8869 WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
8870                                  struct spoolss_DeletePrinterKey *r)
8871 {
8872         Printer_entry           *Printer = find_printer_index_by_hnd(p, r->in.handle);
8873         int                     snum=0;
8874         WERROR                  status;
8875         const char *printer;
8876
8877         DEBUG(5,("_spoolss_DeletePrinterKey\n"));
8878
8879         if (!Printer) {
8880                 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
8881                         OUR_HANDLE(r->in.handle)));
8882                 return WERR_BADFID;
8883         }
8884
8885         /* if keyname == NULL, return error */
8886         if ( !r->in.key_name )
8887                 return WERR_INVALID_PARAM;
8888
8889         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8890                 return WERR_BADFID;
8891         }
8892
8893         if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8894                 DEBUG(3, ("_spoolss_DeletePrinterKey: "
8895                         "printer properties change denied by handle\n"));
8896                 return WERR_ACCESS_DENIED;
8897         }
8898
8899         printer = lp_const_servicename(snum);
8900
8901         /* delete the key and all subkeys */
8902         status = winreg_delete_printer_key(p->mem_ctx,
8903                                            p->server_info,
8904                                            printer,
8905                                            r->in.key_name);
8906         if (W_ERROR_IS_OK(status)) {
8907                 status = winreg_printer_update_changeid(p->mem_ctx,
8908                                                         p->server_info,
8909                                                         printer);
8910         }
8911
8912         return status;
8913 }
8914
8915 /****************************************************************
8916  _spoolss_EnumPrinterDataEx
8917 ****************************************************************/
8918
8919 WERROR _spoolss_EnumPrinterDataEx(struct pipes_struct *p,
8920                                   struct spoolss_EnumPrinterDataEx *r)
8921 {
8922         uint32_t        count = 0;
8923         struct spoolss_PrinterEnumValues *info = NULL;
8924         Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
8925         int             snum;
8926         WERROR          result;
8927
8928         DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
8929
8930         *r->out.count = 0;
8931         *r->out.needed = 0;
8932         *r->out.info = NULL;
8933
8934         if (!Printer) {
8935                 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
8936                         OUR_HANDLE(r->in.handle)));
8937                 return WERR_BADFID;
8938         }
8939
8940         /*
8941          * first check for a keyname of NULL or "".  Win2k seems to send
8942          * this a lot and we should send back WERR_INVALID_PARAM
8943          * no need to spend time looking up the printer in this case.
8944          * --jerry
8945          */
8946
8947         if (!strlen(r->in.key_name)) {
8948                 result = WERR_INVALID_PARAM;
8949                 goto done;
8950         }
8951
8952         if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8953                 return WERR_BADFID;
8954         }
8955
8956         /* now look for a match on the key name */
8957         result = winreg_enum_printer_dataex(p->mem_ctx,
8958                                             p->server_info,
8959                                             lp_const_servicename(snum),
8960                                             r->in.key_name,
8961                                             &count,
8962                                             &info);
8963         if (!W_ERROR_IS_OK(result)) {
8964                 goto done;
8965         }
8966
8967 #if 0 /* FIXME - gd */
8968         /* housekeeping information in the reply */
8969
8970         /* Fix from Martin Zielinski <mz@seh.de> - ensure
8971          * the hand marshalled container size is a multiple
8972          * of 4 bytes for RPC alignment.
8973          */
8974
8975         if (needed % 4) {
8976                 needed += 4-(needed % 4);
8977         }
8978 #endif
8979         *r->out.count   = count;
8980         *r->out.info    = info;
8981
8982  done:
8983         if (!W_ERROR_IS_OK(result)) {
8984                 return result;
8985         }
8986
8987         *r->out.needed  = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
8988                                                spoolss_EnumPrinterDataEx, 
8989                                                *r->out.info,
8990                                                *r->out.count);
8991         *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8992         *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
8993
8994         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8995 }
8996
8997 /****************************************************************************
8998 ****************************************************************************/
8999
9000 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9001                                                  const char *servername,
9002                                                  const char *environment,
9003                                                  struct spoolss_PrintProcessorDirectoryInfo1 *r)
9004 {
9005         WERROR werr;
9006         char *path = NULL;
9007
9008         werr = compose_spoolss_server_path(mem_ctx,
9009                                            servername,
9010                                            environment,
9011                                            SPOOLSS_PRTPROCS_PATH,
9012                                            &path);
9013         if (!W_ERROR_IS_OK(werr)) {
9014                 return werr;
9015         }
9016
9017         DEBUG(4,("print processor directory: [%s]\n", path));
9018
9019         r->directory_name = path;
9020
9021         return WERR_OK;
9022 }
9023
9024 /****************************************************************
9025  _spoolss_GetPrintProcessorDirectory
9026 ****************************************************************/
9027
9028 WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p,
9029                                            struct spoolss_GetPrintProcessorDirectory *r)
9030 {
9031         WERROR result;
9032
9033         /* that's an [in out] buffer */
9034
9035         if (!r->in.buffer && (r->in.offered != 0)) {
9036                 return WERR_INVALID_PARAM;
9037         }
9038
9039         DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9040                 r->in.level));
9041
9042         *r->out.needed = 0;
9043
9044         /* r->in.level is ignored */
9045
9046         /* We always should reply with a local print processor directory so that
9047          * users are not forced to have a [prnproc$] share on the Samba spoolss
9048          * server - Guenther */
9049
9050         result = getprintprocessordirectory_level_1(p->mem_ctx,
9051                                                     NULL, /* r->in.server */
9052                                                     r->in.environment,
9053                                                     &r->out.info->info1);
9054         if (!W_ERROR_IS_OK(result)) {
9055                 TALLOC_FREE(r->out.info);
9056                 return result;
9057         }
9058
9059         *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
9060                                                                                    r->out.info, r->in.level);
9061         r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9062
9063         return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9064 }
9065
9066 /*******************************************************************
9067  ********************************************************************/
9068
9069 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9070                                const char *dllname)
9071 {
9072         enum ndr_err_code ndr_err;
9073         struct spoolss_MonitorUi ui;
9074
9075         ui.dll_name = dllname;
9076
9077         ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ui,
9078                        (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9079         if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9080                 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9081         }
9082         return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9083 }
9084
9085 /*******************************************************************
9086  Streams the monitor UI DLL name in UNICODE
9087 *******************************************************************/
9088
9089 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9090                                NT_USER_TOKEN *token, DATA_BLOB *in,
9091                                DATA_BLOB *out, uint32_t *needed)
9092 {
9093         const char *dllname = "tcpmonui.dll";
9094
9095         *needed = (strlen(dllname)+1) * 2;
9096
9097         if (out->length < *needed) {
9098                 return WERR_INSUFFICIENT_BUFFER;
9099         }
9100
9101         if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9102                 return WERR_NOMEM;
9103         }
9104
9105         return WERR_OK;
9106 }
9107
9108 /*******************************************************************
9109  ********************************************************************/
9110
9111 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9112                              struct spoolss_PortData1 *port1,
9113                              const DATA_BLOB *buf)
9114 {
9115         enum ndr_err_code ndr_err;
9116         ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port1,
9117                        (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9118         if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9119                 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9120         }
9121         return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9122 }
9123
9124 /*******************************************************************
9125  ********************************************************************/
9126
9127 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9128                              struct spoolss_PortData2 *port2,
9129                              const DATA_BLOB *buf)
9130 {
9131         enum ndr_err_code ndr_err;
9132         ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port2,
9133                        (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9134         if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9135                 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9136         }
9137         return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9138 }
9139
9140 /*******************************************************************
9141  Create a new TCP/IP port
9142 *******************************************************************/
9143
9144 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9145                              NT_USER_TOKEN *token, DATA_BLOB *in,
9146                              DATA_BLOB *out, uint32_t *needed)
9147 {
9148         struct spoolss_PortData1 port1;
9149         struct spoolss_PortData2 port2;
9150         char *device_uri = NULL;
9151         uint32_t version;
9152
9153         const char *portname;
9154         const char *hostaddress;
9155         const char *queue;
9156         uint32_t port_number;
9157         uint32_t protocol;
9158
9159         /* peek for spoolss_PortData version */
9160
9161         if (!in || (in->length < (128 + 4))) {
9162                 return WERR_GENERAL_FAILURE;
9163         }
9164
9165         version = IVAL(in->data, 128);
9166
9167         switch (version) {
9168                 case 1:
9169                         ZERO_STRUCT(port1);
9170
9171                         if (!pull_port_data_1(mem_ctx, &port1, in)) {
9172                                 return WERR_NOMEM;
9173                         }
9174
9175                         portname        = port1.portname;
9176                         hostaddress     = port1.hostaddress;
9177                         queue           = port1.queue;
9178                         protocol        = port1.protocol;
9179                         port_number     = port1.port_number;
9180
9181                         break;
9182                 case 2:
9183                         ZERO_STRUCT(port2);
9184
9185                         if (!pull_port_data_2(mem_ctx, &port2, in)) {
9186                                 return WERR_NOMEM;
9187                         }
9188
9189                         portname        = port2.portname;
9190                         hostaddress     = port2.hostaddress;
9191                         queue           = port2.queue;
9192                         protocol        = port2.protocol;
9193                         port_number     = port2.port_number;
9194
9195                         break;
9196                 default:
9197                         DEBUG(1,("xcvtcp_addport: "
9198                                 "unknown version of port_data: %d\n", version));
9199                         return WERR_UNKNOWN_PORT;
9200         }
9201
9202         /* create the device URI and call the add_port_hook() */
9203
9204         switch (protocol) {
9205         case PROTOCOL_RAWTCP_TYPE:
9206                 device_uri = talloc_asprintf(mem_ctx,
9207                                 "socket://%s:%d/", hostaddress,
9208                                 port_number);
9209                 break;
9210
9211         case PROTOCOL_LPR_TYPE:
9212                 device_uri = talloc_asprintf(mem_ctx,
9213                         "lpr://%s/%s", hostaddress, queue );
9214                 break;
9215
9216         default:
9217                 return WERR_UNKNOWN_PORT;
9218         }
9219
9220         if (!device_uri) {
9221                 return WERR_NOMEM;
9222         }
9223
9224         return add_port_hook(mem_ctx, token, portname, device_uri);
9225 }
9226
9227 /*******************************************************************
9228 *******************************************************************/
9229
9230 struct xcv_api_table xcvtcp_cmds[] = {
9231         { "MonitorUI",  xcvtcp_monitorui },
9232         { "AddPort",    xcvtcp_addport},
9233         { NULL,         NULL }
9234 };
9235
9236 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9237                                      NT_USER_TOKEN *token, const char *command,
9238                                      DATA_BLOB *inbuf,
9239                                      DATA_BLOB *outbuf,
9240                                      uint32_t *needed )
9241 {
9242         int i;
9243
9244         DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9245
9246         for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9247                 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9248                         return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9249         }
9250
9251         return WERR_BADFUNC;
9252 }
9253
9254 /*******************************************************************
9255 *******************************************************************/
9256 #if 0   /* don't support management using the "Local Port" monitor */
9257
9258 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9259                                  NT_USER_TOKEN *token, DATA_BLOB *in,
9260                                  DATA_BLOB *out, uint32_t *needed)
9261 {
9262         const char *dllname = "localui.dll";
9263
9264         *needed = (strlen(dllname)+1) * 2;
9265
9266         if (out->length < *needed) {
9267                 return WERR_INSUFFICIENT_BUFFER;
9268         }
9269
9270         if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9271                 return WERR_NOMEM;
9272         }
9273
9274         return WERR_OK;
9275 }
9276
9277 /*******************************************************************
9278 *******************************************************************/
9279
9280 struct xcv_api_table xcvlocal_cmds[] = {
9281         { "MonitorUI",  xcvlocal_monitorui },
9282         { NULL,         NULL }
9283 };
9284 #else
9285 struct xcv_api_table xcvlocal_cmds[] = {
9286         { NULL,         NULL }
9287 };
9288 #endif
9289
9290
9291
9292 /*******************************************************************
9293 *******************************************************************/
9294
9295 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9296                                        NT_USER_TOKEN *token, const char *command,
9297                                        DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9298                                        uint32_t *needed)
9299 {
9300         int i;
9301
9302         DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9303
9304         for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9305                 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9306                         return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9307         }
9308         return WERR_BADFUNC;
9309 }
9310
9311 /****************************************************************
9312  _spoolss_XcvData
9313 ****************************************************************/
9314
9315 WERROR _spoolss_XcvData(struct pipes_struct *p,
9316                         struct spoolss_XcvData *r)
9317 {
9318         Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9319         DATA_BLOB out_data = data_blob_null;
9320         WERROR werror;
9321
9322         if (!Printer) {
9323                 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9324                         OUR_HANDLE(r->in.handle)));
9325                 return WERR_BADFID;
9326         }
9327
9328         /* Has to be a handle to the TCP/IP port monitor */
9329
9330         if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9331                 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9332                 return WERR_BADFID;
9333         }
9334
9335         /* requires administrative access to the server */
9336
9337         if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9338                 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9339                 return WERR_ACCESS_DENIED;
9340         }
9341
9342         /* Allocate the outgoing buffer */
9343
9344         if (r->in.out_data_size) {
9345                 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9346                 if (out_data.data == NULL) {
9347                         return WERR_NOMEM;
9348                 }
9349         }
9350
9351         switch ( Printer->printer_type ) {
9352         case SPLHND_PORTMON_TCP:
9353                 werror = process_xcvtcp_command(p->mem_ctx,
9354                                                 p->server_info->ptok,
9355                                                 r->in.function_name,
9356                                                 &r->in.in_data, &out_data,
9357                                                 r->out.needed);
9358                 break;
9359         case SPLHND_PORTMON_LOCAL:
9360                 werror = process_xcvlocal_command(p->mem_ctx,
9361                                                   p->server_info->ptok,
9362                                                   r->in.function_name,
9363                                                   &r->in.in_data, &out_data,
9364                                                   r->out.needed);
9365                 break;
9366         default:
9367                 werror = WERR_INVALID_PRINT_MONITOR;
9368         }
9369
9370         if (!W_ERROR_IS_OK(werror)) {
9371                 return werror;
9372         }
9373
9374         *r->out.status_code = 0;
9375
9376         if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9377                 memcpy(r->out.out_data, out_data.data,
9378                         MIN(r->in.out_data_size, out_data.length));
9379         }
9380
9381         return WERR_OK;
9382 }
9383
9384 /****************************************************************
9385  _spoolss_AddPrintProcessor
9386 ****************************************************************/
9387
9388 WERROR _spoolss_AddPrintProcessor(struct pipes_struct *p,
9389                                   struct spoolss_AddPrintProcessor *r)
9390 {
9391         /* for now, just indicate success and ignore the add.  We'll
9392            automatically set the winprint processor for printer
9393            entries later.  Used to debug the LexMark Optra S 1855 PCL
9394            driver --jerry */
9395
9396         return WERR_OK;
9397 }
9398
9399 /****************************************************************
9400  _spoolss_AddPort
9401 ****************************************************************/
9402
9403 WERROR _spoolss_AddPort(struct pipes_struct *p,
9404                         struct spoolss_AddPort *r)
9405 {
9406         /* do what w2k3 does */
9407
9408         return WERR_NOT_SUPPORTED;
9409 }
9410
9411 /****************************************************************
9412  _spoolss_GetPrinterDriver
9413 ****************************************************************/
9414
9415 WERROR _spoolss_GetPrinterDriver(struct pipes_struct *p,
9416                                  struct spoolss_GetPrinterDriver *r)
9417 {
9418         p->rng_fault_state = true;
9419         return WERR_NOT_SUPPORTED;
9420 }
9421
9422 /****************************************************************
9423  _spoolss_ReadPrinter
9424 ****************************************************************/
9425
9426 WERROR _spoolss_ReadPrinter(struct pipes_struct *p,
9427                             struct spoolss_ReadPrinter *r)
9428 {
9429         p->rng_fault_state = true;
9430         return WERR_NOT_SUPPORTED;
9431 }
9432
9433 /****************************************************************
9434  _spoolss_WaitForPrinterChange
9435 ****************************************************************/
9436
9437 WERROR _spoolss_WaitForPrinterChange(struct pipes_struct *p,
9438                                      struct spoolss_WaitForPrinterChange *r)
9439 {
9440         p->rng_fault_state = true;
9441         return WERR_NOT_SUPPORTED;
9442 }
9443
9444 /****************************************************************
9445  _spoolss_ConfigurePort
9446 ****************************************************************/
9447
9448 WERROR _spoolss_ConfigurePort(struct pipes_struct *p,
9449                               struct spoolss_ConfigurePort *r)
9450 {
9451         p->rng_fault_state = true;
9452         return WERR_NOT_SUPPORTED;
9453 }
9454
9455 /****************************************************************
9456  _spoolss_DeletePort
9457 ****************************************************************/
9458
9459 WERROR _spoolss_DeletePort(struct pipes_struct *p,
9460                            struct spoolss_DeletePort *r)
9461 {
9462         p->rng_fault_state = true;
9463         return WERR_NOT_SUPPORTED;
9464 }
9465
9466 /****************************************************************
9467  _spoolss_CreatePrinterIC
9468 ****************************************************************/
9469
9470 WERROR _spoolss_CreatePrinterIC(struct pipes_struct *p,
9471                                 struct spoolss_CreatePrinterIC *r)
9472 {
9473         p->rng_fault_state = true;
9474         return WERR_NOT_SUPPORTED;
9475 }
9476
9477 /****************************************************************
9478  _spoolss_PlayGDIScriptOnPrinterIC
9479 ****************************************************************/
9480
9481 WERROR _spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct *p,
9482                                          struct spoolss_PlayGDIScriptOnPrinterIC *r)
9483 {
9484         p->rng_fault_state = true;
9485         return WERR_NOT_SUPPORTED;
9486 }
9487
9488 /****************************************************************
9489  _spoolss_DeletePrinterIC
9490 ****************************************************************/
9491
9492 WERROR _spoolss_DeletePrinterIC(struct pipes_struct *p,
9493                                 struct spoolss_DeletePrinterIC *r)
9494 {
9495         p->rng_fault_state = true;
9496         return WERR_NOT_SUPPORTED;
9497 }
9498
9499 /****************************************************************
9500  _spoolss_AddPrinterConnection
9501 ****************************************************************/
9502
9503 WERROR _spoolss_AddPrinterConnection(struct pipes_struct *p,
9504                                      struct spoolss_AddPrinterConnection *r)
9505 {
9506         p->rng_fault_state = true;
9507         return WERR_NOT_SUPPORTED;
9508 }
9509
9510 /****************************************************************
9511  _spoolss_DeletePrinterConnection
9512 ****************************************************************/
9513
9514 WERROR _spoolss_DeletePrinterConnection(struct pipes_struct *p,
9515                                         struct spoolss_DeletePrinterConnection *r)
9516 {
9517         p->rng_fault_state = true;
9518         return WERR_NOT_SUPPORTED;
9519 }
9520
9521 /****************************************************************
9522  _spoolss_PrinterMessageBox
9523 ****************************************************************/
9524
9525 WERROR _spoolss_PrinterMessageBox(struct pipes_struct *p,
9526                                   struct spoolss_PrinterMessageBox *r)
9527 {
9528         p->rng_fault_state = true;
9529         return WERR_NOT_SUPPORTED;
9530 }
9531
9532 /****************************************************************
9533  _spoolss_AddMonitor
9534 ****************************************************************/
9535
9536 WERROR _spoolss_AddMonitor(struct pipes_struct *p,
9537                            struct spoolss_AddMonitor *r)
9538 {
9539         p->rng_fault_state = true;
9540         return WERR_NOT_SUPPORTED;
9541 }
9542
9543 /****************************************************************
9544  _spoolss_DeleteMonitor
9545 ****************************************************************/
9546
9547 WERROR _spoolss_DeleteMonitor(struct pipes_struct *p,
9548                               struct spoolss_DeleteMonitor *r)
9549 {
9550         p->rng_fault_state = true;
9551         return WERR_NOT_SUPPORTED;
9552 }
9553
9554 /****************************************************************
9555  _spoolss_DeletePrintProcessor
9556 ****************************************************************/
9557
9558 WERROR _spoolss_DeletePrintProcessor(struct pipes_struct *p,
9559                                      struct spoolss_DeletePrintProcessor *r)
9560 {
9561         p->rng_fault_state = true;
9562         return WERR_NOT_SUPPORTED;
9563 }
9564
9565 /****************************************************************
9566  _spoolss_AddPrintProvidor
9567 ****************************************************************/
9568
9569 WERROR _spoolss_AddPrintProvidor(struct pipes_struct *p,
9570                                  struct spoolss_AddPrintProvidor *r)
9571 {
9572         p->rng_fault_state = true;
9573         return WERR_NOT_SUPPORTED;
9574 }
9575
9576 /****************************************************************
9577  _spoolss_DeletePrintProvidor
9578 ****************************************************************/
9579
9580 WERROR _spoolss_DeletePrintProvidor(struct pipes_struct *p,
9581                                     struct spoolss_DeletePrintProvidor *r)
9582 {
9583         p->rng_fault_state = true;
9584         return WERR_NOT_SUPPORTED;
9585 }
9586
9587 /****************************************************************
9588  _spoolss_FindFirstPrinterChangeNotification
9589 ****************************************************************/
9590
9591 WERROR _spoolss_FindFirstPrinterChangeNotification(struct pipes_struct *p,
9592                                                    struct spoolss_FindFirstPrinterChangeNotification *r)
9593 {
9594         p->rng_fault_state = true;
9595         return WERR_NOT_SUPPORTED;
9596 }
9597
9598 /****************************************************************
9599  _spoolss_FindNextPrinterChangeNotification
9600 ****************************************************************/
9601
9602 WERROR _spoolss_FindNextPrinterChangeNotification(struct pipes_struct *p,
9603                                                   struct spoolss_FindNextPrinterChangeNotification *r)
9604 {
9605         p->rng_fault_state = true;
9606         return WERR_NOT_SUPPORTED;
9607 }
9608
9609 /****************************************************************
9610  _spoolss_RouterFindFirstPrinterChangeNotificationOld
9611 ****************************************************************/
9612
9613 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct *p,
9614                                                             struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9615 {
9616         p->rng_fault_state = true;
9617         return WERR_NOT_SUPPORTED;
9618 }
9619
9620 /****************************************************************
9621  _spoolss_ReplyOpenPrinter
9622 ****************************************************************/
9623
9624 WERROR _spoolss_ReplyOpenPrinter(struct pipes_struct *p,
9625                                  struct spoolss_ReplyOpenPrinter *r)
9626 {
9627         p->rng_fault_state = true;
9628         return WERR_NOT_SUPPORTED;
9629 }
9630
9631 /****************************************************************
9632  _spoolss_RouterReplyPrinter
9633 ****************************************************************/
9634
9635 WERROR _spoolss_RouterReplyPrinter(struct pipes_struct *p,
9636                                    struct spoolss_RouterReplyPrinter *r)
9637 {
9638         p->rng_fault_state = true;
9639         return WERR_NOT_SUPPORTED;
9640 }
9641
9642 /****************************************************************
9643  _spoolss_ReplyClosePrinter
9644 ****************************************************************/
9645
9646 WERROR _spoolss_ReplyClosePrinter(struct pipes_struct *p,
9647                                   struct spoolss_ReplyClosePrinter *r)
9648 {
9649         p->rng_fault_state = true;
9650         return WERR_NOT_SUPPORTED;
9651 }
9652
9653 /****************************************************************
9654  _spoolss_AddPortEx
9655 ****************************************************************/
9656
9657 WERROR _spoolss_AddPortEx(struct pipes_struct *p,
9658                           struct spoolss_AddPortEx *r)
9659 {
9660         p->rng_fault_state = true;
9661         return WERR_NOT_SUPPORTED;
9662 }
9663
9664 /****************************************************************
9665  _spoolss_RouterFindFirstPrinterChangeNotification
9666 ****************************************************************/
9667
9668 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct *p,
9669                                                          struct spoolss_RouterFindFirstPrinterChangeNotification *r)
9670 {
9671         p->rng_fault_state = true;
9672         return WERR_NOT_SUPPORTED;
9673 }
9674
9675 /****************************************************************
9676  _spoolss_SpoolerInit
9677 ****************************************************************/
9678
9679 WERROR _spoolss_SpoolerInit(struct pipes_struct *p,
9680                             struct spoolss_SpoolerInit *r)
9681 {
9682         p->rng_fault_state = true;
9683         return WERR_NOT_SUPPORTED;
9684 }
9685
9686 /****************************************************************
9687  _spoolss_ResetPrinterEx
9688 ****************************************************************/
9689
9690 WERROR _spoolss_ResetPrinterEx(struct pipes_struct *p,
9691                                struct spoolss_ResetPrinterEx *r)
9692 {
9693         p->rng_fault_state = true;
9694         return WERR_NOT_SUPPORTED;
9695 }
9696
9697 /****************************************************************
9698  _spoolss_RouterReplyPrinterEx
9699 ****************************************************************/
9700
9701 WERROR _spoolss_RouterReplyPrinterEx(struct pipes_struct *p,
9702                                      struct spoolss_RouterReplyPrinterEx *r)
9703 {
9704         p->rng_fault_state = true;
9705         return WERR_NOT_SUPPORTED;
9706 }
9707
9708 /****************************************************************
9709  _spoolss_44
9710 ****************************************************************/
9711
9712 WERROR _spoolss_44(struct pipes_struct *p,
9713                    struct spoolss_44 *r)
9714 {
9715         p->rng_fault_state = true;
9716         return WERR_NOT_SUPPORTED;
9717 }
9718
9719 /****************************************************************
9720  _spoolss_47
9721 ****************************************************************/
9722
9723 WERROR _spoolss_47(struct pipes_struct *p,
9724                    struct spoolss_47 *r)
9725 {
9726         p->rng_fault_state = true;
9727         return WERR_NOT_SUPPORTED;
9728 }
9729
9730 /****************************************************************
9731  _spoolss_4a
9732 ****************************************************************/
9733
9734 WERROR _spoolss_4a(struct pipes_struct *p,
9735                    struct spoolss_4a *r)
9736 {
9737         p->rng_fault_state = true;
9738         return WERR_NOT_SUPPORTED;
9739 }
9740
9741 /****************************************************************
9742  _spoolss_4b
9743 ****************************************************************/
9744
9745 WERROR _spoolss_4b(struct pipes_struct *p,
9746                    struct spoolss_4b *r)
9747 {
9748         p->rng_fault_state = true;
9749         return WERR_NOT_SUPPORTED;
9750 }
9751
9752 /****************************************************************
9753  _spoolss_4c
9754 ****************************************************************/
9755
9756 WERROR _spoolss_4c(struct pipes_struct *p,
9757                    struct spoolss_4c *r)
9758 {
9759         p->rng_fault_state = true;
9760         return WERR_NOT_SUPPORTED;
9761 }
9762
9763 /****************************************************************
9764  _spoolss_53
9765 ****************************************************************/
9766
9767 WERROR _spoolss_53(struct pipes_struct *p,
9768                    struct spoolss_53 *r)
9769 {
9770         p->rng_fault_state = true;
9771         return WERR_NOT_SUPPORTED;
9772 }
9773
9774 /****************************************************************
9775  _spoolss_55
9776 ****************************************************************/
9777
9778 WERROR _spoolss_55(struct pipes_struct *p,
9779                    struct spoolss_55 *r)
9780 {
9781         p->rng_fault_state = true;
9782         return WERR_NOT_SUPPORTED;
9783 }
9784
9785 /****************************************************************
9786  _spoolss_56
9787 ****************************************************************/
9788
9789 WERROR _spoolss_56(struct pipes_struct *p,
9790                    struct spoolss_56 *r)
9791 {
9792         p->rng_fault_state = true;
9793         return WERR_NOT_SUPPORTED;
9794 }
9795
9796 /****************************************************************
9797  _spoolss_57
9798 ****************************************************************/
9799
9800 WERROR _spoolss_57(struct pipes_struct *p,
9801                    struct spoolss_57 *r)
9802 {
9803         p->rng_fault_state = true;
9804         return WERR_NOT_SUPPORTED;
9805 }
9806
9807 /****************************************************************
9808  _spoolss_5a
9809 ****************************************************************/
9810
9811 WERROR _spoolss_5a(struct pipes_struct *p,
9812                    struct spoolss_5a *r)
9813 {
9814         p->rng_fault_state = true;
9815         return WERR_NOT_SUPPORTED;
9816 }
9817
9818 /****************************************************************
9819  _spoolss_5b
9820 ****************************************************************/
9821
9822 WERROR _spoolss_5b(struct pipes_struct *p,
9823                    struct spoolss_5b *r)
9824 {
9825         p->rng_fault_state = true;
9826         return WERR_NOT_SUPPORTED;
9827 }
9828
9829 /****************************************************************
9830  _spoolss_5c
9831 ****************************************************************/
9832
9833 WERROR _spoolss_5c(struct pipes_struct *p,
9834                    struct spoolss_5c *r)
9835 {
9836         p->rng_fault_state = true;
9837         return WERR_NOT_SUPPORTED;
9838 }
9839
9840 /****************************************************************
9841  _spoolss_5d
9842 ****************************************************************/
9843
9844 WERROR _spoolss_5d(struct pipes_struct *p,
9845                    struct spoolss_5d *r)
9846 {
9847         p->rng_fault_state = true;
9848         return WERR_NOT_SUPPORTED;
9849 }
9850
9851 /****************************************************************
9852  _spoolss_5e
9853 ****************************************************************/
9854
9855 WERROR _spoolss_5e(struct pipes_struct *p,
9856                    struct spoolss_5e *r)
9857 {
9858         p->rng_fault_state = true;
9859         return WERR_NOT_SUPPORTED;
9860 }
9861
9862 /****************************************************************
9863  _spoolss_5f
9864 ****************************************************************/
9865
9866 WERROR _spoolss_5f(struct pipes_struct *p,
9867                    struct spoolss_5f *r)
9868 {
9869         p->rng_fault_state = true;
9870         return WERR_NOT_SUPPORTED;
9871 }
9872
9873 /****************************************************************
9874  _spoolss_60
9875 ****************************************************************/
9876
9877 WERROR _spoolss_60(struct pipes_struct *p,
9878                    struct spoolss_60 *r)
9879 {
9880         p->rng_fault_state = true;
9881         return WERR_NOT_SUPPORTED;
9882 }
9883
9884 /****************************************************************
9885  _spoolss_61
9886 ****************************************************************/
9887
9888 WERROR _spoolss_61(struct pipes_struct *p,
9889                    struct spoolss_61 *r)
9890 {
9891         p->rng_fault_state = true;
9892         return WERR_NOT_SUPPORTED;
9893 }
9894
9895 /****************************************************************
9896  _spoolss_62
9897 ****************************************************************/
9898
9899 WERROR _spoolss_62(struct pipes_struct *p,
9900                    struct spoolss_62 *r)
9901 {
9902         p->rng_fault_state = true;
9903         return WERR_NOT_SUPPORTED;
9904 }
9905
9906 /****************************************************************
9907  _spoolss_63
9908 ****************************************************************/
9909
9910 WERROR _spoolss_63(struct pipes_struct *p,
9911                    struct spoolss_63 *r)
9912 {
9913         p->rng_fault_state = true;
9914         return WERR_NOT_SUPPORTED;
9915 }
9916
9917 /****************************************************************
9918  _spoolss_64
9919 ****************************************************************/
9920
9921 WERROR _spoolss_64(struct pipes_struct *p,
9922                    struct spoolss_64 *r)
9923 {
9924         p->rng_fault_state = true;
9925         return WERR_NOT_SUPPORTED;
9926 }
9927
9928 /****************************************************************
9929  _spoolss_65
9930 ****************************************************************/
9931
9932 WERROR _spoolss_65(struct pipes_struct *p,
9933                    struct spoolss_65 *r)
9934 {
9935         p->rng_fault_state = true;
9936         return WERR_NOT_SUPPORTED;
9937 }
9938
9939 /****************************************************************
9940  _spoolss_GetCorePrinterDrivers
9941 ****************************************************************/
9942
9943 WERROR _spoolss_GetCorePrinterDrivers(struct pipes_struct *p,
9944                                       struct spoolss_GetCorePrinterDrivers *r)
9945 {
9946         p->rng_fault_state = true;
9947         return WERR_NOT_SUPPORTED;
9948 }
9949
9950 /****************************************************************
9951  _spoolss_67
9952 ****************************************************************/
9953
9954 WERROR _spoolss_67(struct pipes_struct *p,
9955                    struct spoolss_67 *r)
9956 {
9957         p->rng_fault_state = true;
9958         return WERR_NOT_SUPPORTED;
9959 }
9960
9961 /****************************************************************
9962  _spoolss_GetPrinterDriverPackagePath
9963 ****************************************************************/
9964
9965 WERROR _spoolss_GetPrinterDriverPackagePath(struct pipes_struct *p,
9966                                             struct spoolss_GetPrinterDriverPackagePath *r)
9967 {
9968         p->rng_fault_state = true;
9969         return WERR_NOT_SUPPORTED;
9970 }
9971
9972 /****************************************************************
9973  _spoolss_69
9974 ****************************************************************/
9975
9976 WERROR _spoolss_69(struct pipes_struct *p,
9977                    struct spoolss_69 *r)
9978 {
9979         p->rng_fault_state = true;
9980         return WERR_NOT_SUPPORTED;
9981 }
9982
9983 /****************************************************************
9984  _spoolss_6a
9985 ****************************************************************/
9986
9987 WERROR _spoolss_6a(struct pipes_struct *p,
9988                    struct spoolss_6a *r)
9989 {
9990         p->rng_fault_state = true;
9991         return WERR_NOT_SUPPORTED;
9992 }
9993
9994 /****************************************************************
9995  _spoolss_6b
9996 ****************************************************************/
9997
9998 WERROR _spoolss_6b(struct pipes_struct *p,
9999                    struct spoolss_6b *r)
10000 {
10001         p->rng_fault_state = true;
10002         return WERR_NOT_SUPPORTED;
10003 }
10004
10005 /****************************************************************
10006  _spoolss_6c
10007 ****************************************************************/
10008
10009 WERROR _spoolss_6c(struct pipes_struct *p,
10010                    struct spoolss_6c *r)
10011 {
10012         p->rng_fault_state = true;
10013         return WERR_NOT_SUPPORTED;
10014 }
10015
10016 /****************************************************************
10017  _spoolss_6d
10018 ****************************************************************/
10019
10020 WERROR _spoolss_6d(struct pipes_struct *p,
10021                    struct spoolss_6d *r)
10022 {
10023         p->rng_fault_state = true;
10024         return WERR_NOT_SUPPORTED;
10025 }