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 "libsmb/namequery.h"
32 #include "ntdomain.h"
33 #include "nt_printing.h"
34 #include "srv_spoolss_util.h"
35 #include "../librpc/gen_ndr/srv_spoolss.h"
36 #include "../librpc/gen_ndr/ndr_spoolss_c.h"
37 #include "rpc_client/init_spoolss.h"
38 #include "rpc_client/cli_pipe.h"
39 #include "../libcli/security/security.h"
40 #include "librpc/gen_ndr/ndr_security.h"
41 #include "registry.h"
42 #include "include/printing.h"
43 #include "secrets.h"
44 #include "../librpc/gen_ndr/netlogon.h"
45 #include "rpc_misc.h"
46 #include "printing/notify.h"
47 #include "serverid.h"
48 #include "../libcli/registry/util_reg.h"
49 #include "smbd/smbd.h"
50 #include "smbd/globals.h"
51 #include "auth.h"
52 #include "messages.h"
53 #include "rpc_server/spoolss/srv_spoolss_nt.h"
54 #include "util_tdb.h"
55 #include "libsmb/libsmb.h"
56 #include "printing/printer_list.h"
57 #include "../lib/tsocket/tsocket.h"
58 #include "rpc_client/cli_winreg_spoolss.h"
59 #include "../libcli/smb/smbXcli_base.h"
60 #include "rpc_server/spoolss/srv_spoolss_handle.h"
61 #include "lib/gencache.h"
62
63 /* macros stolen from s4 spoolss server */
64 #define SPOOLSS_BUFFER_UNION(fn,info,level) \
65 ((info)?ndr_size_##fn(info, level, 0):0)
66
67 #define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,info,level,count) \
68 ((info)?ndr_size_##fn##_info(mem_ctx, level, count, info):0)
69
70 #define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,info,count) \
71 ((info)?ndr_size_##fn##_info(mem_ctx, count, info):0)
72
73 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
74
75 #undef DBGC_CLASS
76 #define DBGC_CLASS DBGC_RPC_SRV
77
78 #ifndef MAX_OPEN_PRINTER_EXS
79 #define MAX_OPEN_PRINTER_EXS 50
80 #endif
81
82 #define GLOBAL_SPOOLSS_OS_MAJOR_DEFAULT 5
83 #define GLOBAL_SPOOLSS_OS_MINOR_DEFAULT 2
84 #define GLOBAL_SPOOLSS_OS_BUILD_DEFAULT 3790
85 #define GLOBAL_SPOOLSS_ARCHITECTURE SPOOLSS_ARCHITECTURE_x64
86
87 static struct printer_handle *printers_list;
88
89 struct printer_session_counter {
90 struct printer_session_counter *next;
91 struct printer_session_counter *prev;
92
93 int snum;
94 uint32_t counter;
95 };
96
97 static struct printer_session_counter *counter_list;
98
99 struct notify_back_channel {
100 struct notify_back_channel *prev, *next;
101
102 /* associated client */
103 struct sockaddr_storage client_address;
104
105 /* print notify back-channel pipe handle*/
106 struct rpc_pipe_client *cli_pipe;
107 struct cli_state *cli;
108 uint32_t active_connections;
109 };
110
111 static struct notify_back_channel *back_channels;
112
113 /* Map generic permissions to printer object specific permissions */
114
115 const struct standard_mapping printer_std_mapping = {
116 PRINTER_READ,
117 PRINTER_WRITE,
118 PRINTER_EXECUTE,
119 PRINTER_ALL_ACCESS
120 };
121
122 /* Map generic permissions to print server object specific permissions */
123
124 const struct standard_mapping printserver_std_mapping = {
125 SERVER_READ,
126 SERVER_WRITE,
127 SERVER_EXECUTE,
128 SERVER_ALL_ACCESS
129 };
130
131 /* API table for Xcv Monitor functions */
132
133 struct xcv_api_table {
134 const char *name;
135 WERROR(*fn) (TALLOC_CTX *mem_ctx, struct security_token *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
136 };
137
138 static void prune_printername_cache(void);
139
140 /********************************************************************
141 * Canonicalize servername.
142 ********************************************************************/
143
canon_servername(const char * servername)144 static const char *canon_servername(const char *servername)
145 {
146 const char *pservername = servername;
147
148 if (servername == NULL) {
149 return "";
150 }
151
152 while (*pservername == '\\') {
153 pservername++;
154 }
155 return pservername;
156 }
157
158 /* translate between internal status numbers and NT status numbers */
nt_printj_status(int v)159 static int nt_printj_status(int v)
160 {
161 switch (v) {
162 case LPQ_QUEUED:
163 return 0;
164 case LPQ_PAUSED:
165 return JOB_STATUS_PAUSED;
166 case LPQ_SPOOLING:
167 return JOB_STATUS_SPOOLING;
168 case LPQ_PRINTING:
169 return JOB_STATUS_PRINTING;
170 case LPQ_ERROR:
171 return JOB_STATUS_ERROR;
172 case LPQ_DELETING:
173 return JOB_STATUS_DELETING;
174 case LPQ_OFFLINE:
175 return JOB_STATUS_OFFLINE;
176 case LPQ_PAPEROUT:
177 return JOB_STATUS_PAPEROUT;
178 case LPQ_PRINTED:
179 return JOB_STATUS_PRINTED;
180 case LPQ_DELETED:
181 return JOB_STATUS_DELETED;
182 case LPQ_BLOCKED:
183 return JOB_STATUS_BLOCKED_DEVQ;
184 case LPQ_USER_INTERVENTION:
185 return JOB_STATUS_USER_INTERVENTION;
186 }
187 return 0;
188 }
189
nt_printq_status(int v)190 static int nt_printq_status(int v)
191 {
192 switch (v) {
193 case LPQ_PAUSED:
194 return PRINTER_STATUS_PAUSED;
195 case LPQ_QUEUED:
196 case LPQ_SPOOLING:
197 case LPQ_PRINTING:
198 return 0;
199 }
200 return 0;
201 }
202
203 /***************************************************************************
204 Disconnect from the client
205 ****************************************************************************/
206
srv_spoolss_replycloseprinter(int snum,struct printer_handle * prn_hnd)207 static void srv_spoolss_replycloseprinter(int snum,
208 struct printer_handle *prn_hnd)
209 {
210 WERROR result;
211 NTSTATUS status;
212
213 /*
214 * Tell the specific printing tdb we no longer want messages for this printer
215 * by deregistering our PID.
216 */
217
218 if (!print_notify_deregister_pid(snum)) {
219 DEBUG(0, ("Failed to register our pid for printer %s\n",
220 lp_const_servicename(snum)));
221 }
222
223 /* weird if the test succeeds !!! */
224 if (prn_hnd->notify.cli_chan == NULL ||
225 prn_hnd->notify.cli_chan->cli_pipe == NULL ||
226 prn_hnd->notify.cli_chan->cli_pipe->binding_handle == NULL ||
227 prn_hnd->notify.cli_chan->active_connections == 0) {
228 DEBUG(0, ("Trying to close unexisting backchannel!\n"));
229 DLIST_REMOVE(back_channels, prn_hnd->notify.cli_chan);
230 TALLOC_FREE(prn_hnd->notify.cli_chan);
231 return;
232 }
233
234 status = dcerpc_spoolss_ReplyClosePrinter(
235 prn_hnd->notify.cli_chan->cli_pipe->binding_handle,
236 talloc_tos(),
237 &prn_hnd->notify.cli_hnd,
238 &result);
239 if (!NT_STATUS_IS_OK(status)) {
240 DEBUG(0, ("dcerpc_spoolss_ReplyClosePrinter failed [%s].\n",
241 nt_errstr(status)));
242 result = ntstatus_to_werror(status);
243 } else if (!W_ERROR_IS_OK(result)) {
244 DEBUG(0, ("reply_close_printer failed [%s].\n",
245 win_errstr(result)));
246 }
247
248 /* if it's the last connection, deconnect the IPC$ share */
249 if (prn_hnd->notify.cli_chan->active_connections == 1) {
250
251 cli_shutdown(prn_hnd->notify.cli_chan->cli);
252 DLIST_REMOVE(back_channels, prn_hnd->notify.cli_chan);
253 TALLOC_FREE(prn_hnd->notify.cli_chan);
254
255 if (prn_hnd->notify.msg_ctx != NULL) {
256 messaging_deregister(prn_hnd->notify.msg_ctx,
257 MSG_PRINTER_NOTIFY2, NULL);
258 }
259 }
260
261 if (prn_hnd->notify.cli_chan) {
262 prn_hnd->notify.cli_chan->active_connections--;
263 prn_hnd->notify.cli_chan = NULL;
264 }
265 }
266
267 /****************************************************************************
268 Functions to free a printer entry datastruct.
269 ****************************************************************************/
270
printer_entry_destructor(struct printer_handle * Printer)271 static int printer_entry_destructor(struct printer_handle *Printer)
272 {
273 if (Printer->notify.cli_chan != NULL &&
274 Printer->notify.cli_chan->active_connections > 0) {
275 int snum = -1;
276
277 switch(Printer->printer_type) {
278 case SPLHND_SERVER:
279 srv_spoolss_replycloseprinter(snum, Printer);
280 break;
281
282 case SPLHND_PRINTER:
283 snum = print_queue_snum(Printer->sharename);
284 if (snum != -1) {
285 srv_spoolss_replycloseprinter(snum, Printer);
286 }
287 break;
288 default:
289 break;
290 }
291 }
292
293 Printer->notify.flags=0;
294 Printer->notify.options=0;
295 Printer->notify.localmachine[0]='\0';
296 Printer->notify.printerlocal=0;
297 TALLOC_FREE(Printer->notify.option);
298 TALLOC_FREE(Printer->devmode);
299
300 /* Remove from the internal list. */
301 DLIST_REMOVE(printers_list, Printer);
302 return 0;
303 }
304
305 /****************************************************************************
306 find printer index by handle
307 ****************************************************************************/
308
find_printer_index_by_hnd(struct pipes_struct * p,struct policy_handle * hnd)309 static struct printer_handle *find_printer_index_by_hnd(struct pipes_struct *p,
310 struct policy_handle *hnd)
311 {
312 struct printer_handle *find_printer = NULL;
313
314 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
315 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
316 return NULL;
317 }
318
319 return find_printer;
320 }
321
322 /****************************************************************************
323 Close printer index by handle.
324 ****************************************************************************/
325
close_printer_handle(struct pipes_struct * p,struct policy_handle * hnd)326 static bool close_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
327 {
328 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
329
330 if (!Printer) {
331 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
332 OUR_HANDLE(hnd)));
333 return false;
334 }
335
336 close_policy_hnd(p, hnd);
337
338 return true;
339 }
340
341 /****************************************************************************
342 Delete a printer given a handle.
343 ****************************************************************************/
344
delete_printer_hook(TALLOC_CTX * ctx,struct security_token * token,const char * sharename,struct messaging_context * msg_ctx)345 static WERROR delete_printer_hook(TALLOC_CTX *ctx, struct security_token *token,
346 const char *sharename,
347 struct messaging_context *msg_ctx)
348 {
349 const struct loadparm_substitution *lp_sub =
350 loadparm_s3_global_substitution();
351 char *cmd = lp_deleteprinter_command(talloc_tos(), lp_sub);
352 char *command = NULL;
353 int ret;
354 bool is_print_op = false;
355
356 /* can't fail if we don't try */
357
358 if ( !*cmd )
359 return WERR_OK;
360
361 command = talloc_asprintf(ctx,
362 "%s \"%s\"",
363 cmd, sharename);
364 if (!command) {
365 return WERR_NOT_ENOUGH_MEMORY;
366 }
367 if ( token )
368 is_print_op = security_token_has_privilege(token, SEC_PRIV_PRINT_OPERATOR);
369
370 DEBUG(10,("Running [%s]\n", command));
371
372 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
373
374 if ( is_print_op )
375 become_root();
376
377 ret = smbrun(command, NULL, NULL);
378 if (ret == 0) {
379 /* Tell everyone we updated smb.conf. */
380 messaging_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0);
381 }
382
383 if ( is_print_op )
384 unbecome_root();
385
386 /********** END SePrintOperatorPrivlege BLOCK **********/
387
388 DEBUGADD(10,("returned [%d]\n", ret));
389
390 TALLOC_FREE(command);
391
392 if (ret != 0)
393 return WERR_INVALID_HANDLE; /* What to return here? */
394
395 return WERR_OK;
396 }
397
398 /****************************************************************************
399 Delete a printer given a handle.
400 ****************************************************************************/
401
delete_printer_handle(struct pipes_struct * p,struct policy_handle * hnd)402 static WERROR delete_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
403 {
404 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
405 WERROR result;
406
407 if (!Printer) {
408 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
409 OUR_HANDLE(hnd)));
410 return WERR_INVALID_HANDLE;
411 }
412
413 /*
414 * It turns out that Windows allows delete printer on a handle
415 * opened by an admin user, then used on a pipe handle created
416 * by an anonymous user..... but they're working on security.... riiight !
417 * JRA.
418 */
419
420 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
421 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
422 return WERR_ACCESS_DENIED;
423 }
424
425 /* this does not need a become root since the access check has been
426 done on the handle already */
427
428 result = winreg_delete_printer_key_internal(p->mem_ctx,
429 get_session_info_system(),
430 p->msg_ctx,
431 Printer->sharename,
432 "");
433 if (!W_ERROR_IS_OK(result)) {
434 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
435 return WERR_INVALID_HANDLE;
436 }
437
438 result = delete_printer_hook(p->mem_ctx, p->session_info->security_token,
439 Printer->sharename, p->msg_ctx);
440 if (!W_ERROR_IS_OK(result)) {
441 return result;
442 }
443 prune_printername_cache();
444 return WERR_OK;
445 }
446
447 /****************************************************************************
448 Return the snum of a printer corresponding to an handle.
449 ****************************************************************************/
450
get_printer_snum(struct pipes_struct * p,struct policy_handle * hnd,int * number,struct share_params ** params)451 static bool get_printer_snum(struct pipes_struct *p, struct policy_handle *hnd,
452 int *number, struct share_params **params)
453 {
454 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
455
456 if (!Printer) {
457 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
458 OUR_HANDLE(hnd)));
459 return false;
460 }
461
462 switch (Printer->printer_type) {
463 case SPLHND_PRINTER:
464 DEBUG(4,("short name:%s\n", Printer->sharename));
465 *number = print_queue_snum(Printer->sharename);
466 return (*number != -1);
467 case SPLHND_SERVER:
468 return false;
469 default:
470 return false;
471 }
472 }
473
474 /****************************************************************************
475 Set printer handle type.
476 Check if it's \\server or \\server\printer
477 ****************************************************************************/
478
set_printer_hnd_printertype(struct printer_handle * Printer,const char * handlename)479 static bool set_printer_hnd_printertype(struct printer_handle *Printer, const char *handlename)
480 {
481 DEBUG(3,("Setting printer type=%s\n", handlename));
482
483 /* it's a print server */
484 if (handlename && *handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
485 DEBUGADD(4,("Printer is a print server\n"));
486 Printer->printer_type = SPLHND_SERVER;
487 }
488 /* it's a printer (set_printer_hnd_name() will handle port monitors */
489 else {
490 DEBUGADD(4,("Printer is a printer\n"));
491 Printer->printer_type = SPLHND_PRINTER;
492 }
493
494 return true;
495 }
496
prune_printername_cache_fn(const char * key,const char * value,time_t timeout,void * private_data)497 static void prune_printername_cache_fn(const char *key, const char *value,
498 time_t timeout, void *private_data)
499 {
500 gencache_del(key);
501 }
502
prune_printername_cache(void)503 static void prune_printername_cache(void)
504 {
505 gencache_iterate(prune_printername_cache_fn, NULL, "PRINTERNAME/*");
506 }
507
508 /****************************************************************************
509 Set printer handle name.. Accept names like \\server, \\server\printer,
510 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
511 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
512 XcvDataPort() interface.
513 ****************************************************************************/
514
set_printer_hnd_name(TALLOC_CTX * mem_ctx,const struct auth_session_info * session_info,struct messaging_context * msg_ctx,struct printer_handle * Printer,const char * handlename)515 static WERROR set_printer_hnd_name(TALLOC_CTX *mem_ctx,
516 const struct auth_session_info *session_info,
517 struct messaging_context *msg_ctx,
518 struct printer_handle *Printer,
519 const char *handlename)
520 {
521 int snum;
522 int n_services=lp_numservices();
523 char *aprinter;
524 const char *printername;
525 const char *servername = NULL;
526 fstring sname;
527 bool found = false;
528 struct spoolss_PrinterInfo2 *info2 = NULL;
529 WERROR result;
530 char *p;
531
532 /*
533 * Hopefully nobody names his printers like this. Maybe \ or ,
534 * are illegal in printer names even?
535 */
536 const char printer_not_found[] = "Printer \\, !@#$%^&*( not found";
537 char *cache_key;
538 char *tmp;
539
540 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
541 (unsigned long)strlen(handlename)));
542
543 aprinter = discard_const_p(char, handlename);
544 if ( *handlename == '\\' ) {
545 servername = canon_servername(handlename);
546 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
547 *aprinter = '\0';
548 aprinter++;
549 }
550 if (!is_myname_or_ipaddr(servername)) {
551 return WERR_INVALID_PRINTER_NAME;
552 }
553 Printer->servername = talloc_asprintf(Printer, "\\\\%s", servername);
554 if (Printer->servername == NULL) {
555 return WERR_NOT_ENOUGH_MEMORY;
556 }
557 }
558
559 if (Printer->printer_type == SPLHND_SERVER) {
560 return WERR_OK;
561 }
562
563 if (Printer->printer_type != SPLHND_PRINTER) {
564 return WERR_INVALID_HANDLE;
565 }
566
567 DEBUGADD(5, ("searching for [%s]\n", aprinter));
568
569 p = strchr(aprinter, ',');
570 if (p != NULL) {
571 char *p2 = p;
572 p++;
573 if (*p == ' ') {
574 p++;
575 }
576 if (strncmp(p, "DrvConvert", strlen("DrvConvert")) == 0) {
577 *p2 = '\0';
578 } else if (strncmp(p, "LocalOnly", strlen("LocalOnly")) == 0) {
579 *p2 = '\0';
580 }
581 }
582
583 if (p) {
584 DEBUGADD(5, ("stripped handlename: [%s]\n", aprinter));
585 }
586
587 /* check for the Port Monitor Interface */
588 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
589 Printer->printer_type = SPLHND_PORTMON_TCP;
590 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
591 found = true;
592 }
593 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
594 Printer->printer_type = SPLHND_PORTMON_LOCAL;
595 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
596 found = true;
597 }
598
599 cache_key = talloc_asprintf(talloc_tos(), "PRINTERNAME/%s", aprinter);
600 if (cache_key == NULL) {
601 return WERR_NOT_ENOUGH_MEMORY;
602 }
603
604 /*
605 * With hundreds of printers, the "for" loop iterating all
606 * shares can be quite expensive, as it is done on every
607 * OpenPrinter. The loop maps "aprinter" to "sname", the
608 * result of which we cache in gencache.
609 */
610 if (gencache_get(cache_key, talloc_tos(), &tmp, NULL)) {
611 found = (strcmp(tmp, printer_not_found) != 0);
612 if (!found) {
613 DEBUG(4, ("Printer %s not found\n", aprinter));
614 TALLOC_FREE(tmp);
615 return WERR_INVALID_PRINTER_NAME;
616 }
617 fstrcpy(sname, tmp);
618 TALLOC_FREE(tmp);
619 }
620
621 /* Search all sharenames first as this is easier than pulling
622 the printer_info_2 off of disk. Don't use find_service() since
623 that calls out to map_username() */
624
625 /* do another loop to look for printernames */
626 for (snum = 0; !found && snum < n_services; snum++) {
627 const char *printer = lp_const_servicename(snum);
628
629 /* no point going on if this is not a printer */
630 if (!(lp_snum_ok(snum) && lp_printable(snum))) {
631 continue;
632 }
633
634 /* ignore [printers] share */
635 if (strequal(printer, "printers")) {
636 continue;
637 }
638
639 fstrcpy(sname, printer);
640 if (strequal(aprinter, printer)) {
641 found = true;
642 break;
643 }
644
645 /* no point looking up the printer object if
646 we aren't allowing printername != sharename */
647 if (lp_force_printername(snum)) {
648 continue;
649 }
650
651 result = winreg_get_printer_internal(mem_ctx,
652 session_info,
653 msg_ctx,
654 sname,
655 &info2);
656 if ( !W_ERROR_IS_OK(result) ) {
657 DEBUG(2,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
658 sname, win_errstr(result)));
659 continue;
660 }
661
662 printername = strrchr(info2->printername, '\\');
663 if (printername == NULL) {
664 printername = info2->printername;
665 } else {
666 printername++;
667 }
668
669 if (strequal(printername, aprinter)) {
670 found = true;
671 break;
672 }
673
674 DEBUGADD(10, ("printername: %s\n", printername));
675
676 TALLOC_FREE(info2);
677 }
678
679 if (!found) {
680 gencache_set(cache_key, printer_not_found,
681 time(NULL) + 300);
682 TALLOC_FREE(cache_key);
683 DEBUGADD(4,("Printer not found\n"));
684 return WERR_INVALID_PRINTER_NAME;
685 }
686
687 gencache_set(cache_key, sname, time(NULL) + 300);
688 TALLOC_FREE(cache_key);
689
690 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
691
692 strlcpy(Printer->sharename, sname, sizeof(Printer->sharename));
693
694 return WERR_OK;
695 }
696
697 /****************************************************************************
698 Find first available printer slot. creates a printer handle for you.
699 ****************************************************************************/
700
open_printer_hnd(struct pipes_struct * p,struct policy_handle * hnd,const char * name,uint32_t access_granted)701 static WERROR open_printer_hnd(struct pipes_struct *p,
702 struct policy_handle *hnd,
703 const char *name,
704 uint32_t access_granted)
705 {
706 struct printer_handle *new_printer;
707 WERROR result;
708
709 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
710
711 new_printer = talloc_zero(p->mem_ctx, struct printer_handle);
712 if (new_printer == NULL) {
713 return WERR_NOT_ENOUGH_MEMORY;
714 }
715 talloc_set_destructor(new_printer, printer_entry_destructor);
716
717 /* This also steals the printer_handle on the policy_handle */
718 if (!create_policy_hnd(p, hnd, 0, new_printer)) {
719 TALLOC_FREE(new_printer);
720 return WERR_INVALID_HANDLE;
721 }
722
723 /* Add to the internal list. */
724 DLIST_ADD(printers_list, new_printer);
725
726 new_printer->notify.option=NULL;
727
728 if (!set_printer_hnd_printertype(new_printer, name)) {
729 close_printer_handle(p, hnd);
730 return WERR_INVALID_HANDLE;
731 }
732
733 result = set_printer_hnd_name(p->mem_ctx,
734 get_session_info_system(),
735 p->msg_ctx,
736 new_printer, name);
737 if (!W_ERROR_IS_OK(result)) {
738 close_printer_handle(p, hnd);
739 return result;
740 }
741
742 new_printer->access_granted = access_granted;
743
744 DEBUG(5, ("%d printer handles active\n",
745 (int)num_pipe_handles(p)));
746
747 return WERR_OK;
748 }
749
750 /***************************************************************************
751 check to see if the client motify handle is monitoring the notification
752 given by (notify_type, notify_field).
753 **************************************************************************/
754
is_monitoring_event_flags(uint32_t flags,uint16_t notify_type,uint16_t notify_field)755 static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
756 uint16_t notify_field)
757 {
758 return true;
759 }
760
is_monitoring_event(struct printer_handle * p,uint16_t notify_type,uint16_t notify_field)761 static bool is_monitoring_event(struct printer_handle *p, uint16_t notify_type,
762 uint16_t notify_field)
763 {
764 struct spoolss_NotifyOption *option = p->notify.option;
765 uint32_t i, j;
766
767 /*
768 * Flags should always be zero when the change notify
769 * is registered by the client's spooler. A user Win32 app
770 * might use the flags though instead of the NOTIFY_OPTION_INFO
771 * --jerry
772 */
773
774 if (!option) {
775 return false;
776 }
777
778 if (p->notify.flags)
779 return is_monitoring_event_flags(
780 p->notify.flags, notify_type, notify_field);
781
782 for (i = 0; i < option->count; i++) {
783
784 /* Check match for notify_type */
785
786 if (option->types[i].type != notify_type)
787 continue;
788
789 /* Check match for field */
790
791 for (j = 0; j < option->types[i].count; j++) {
792 if (option->types[i].fields[j].field == notify_field) {
793 return true;
794 }
795 }
796 }
797
798 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
799 p->servername, p->sharename, notify_type, notify_field));
800
801 return false;
802 }
803
804 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
805 _data->data.integer[0] = _integer; \
806 _data->data.integer[1] = 0;
807
808
809 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
810 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
811 if (!_data->data.string.string) {\
812 _data->data.string.size = 0; \
813 } \
814 _data->data.string.size = strlen_m_term(_p) * 2;
815
816 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
817 _data->data.devmode.devmode = _devmode;
818
init_systemtime_buffer(TALLOC_CTX * mem_ctx,struct tm * t,const char ** pp,uint32_t * plen)819 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
820 struct tm *t,
821 const char **pp,
822 uint32_t *plen)
823 {
824 struct spoolss_Time st;
825 uint32_t len = 16;
826 char *p;
827
828 if (!init_systemtime(&st, t)) {
829 return;
830 }
831
832 p = talloc_array(mem_ctx, char, len);
833 if (!p) {
834 return;
835 }
836
837 /*
838 * Systemtime must be linearized as a set of UINT16's.
839 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
840 */
841
842 SSVAL(p, 0, st.year);
843 SSVAL(p, 2, st.month);
844 SSVAL(p, 4, st.day_of_week);
845 SSVAL(p, 6, st.day);
846 SSVAL(p, 8, st.hour);
847 SSVAL(p, 10, st.minute);
848 SSVAL(p, 12, st.second);
849 SSVAL(p, 14, st.millisecond);
850
851 *pp = p;
852 *plen = len;
853 }
854
855 /* Convert a notification message to a struct spoolss_Notify */
856
notify_one_value(struct spoolss_notify_msg * msg,struct spoolss_Notify * data,TALLOC_CTX * mem_ctx)857 static void notify_one_value(struct spoolss_notify_msg *msg,
858 struct spoolss_Notify *data,
859 TALLOC_CTX *mem_ctx)
860 {
861 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
862 }
863
notify_string(struct spoolss_notify_msg * msg,struct spoolss_Notify * data,TALLOC_CTX * mem_ctx)864 static void notify_string(struct spoolss_notify_msg *msg,
865 struct spoolss_Notify *data,
866 TALLOC_CTX *mem_ctx)
867 {
868 /* The length of the message includes the trailing \0 */
869
870 data->data.string.size = msg->len * 2;
871 data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
872 if (!data->data.string.string) {
873 data->data.string.size = 0;
874 return;
875 }
876 }
877
notify_system_time(struct spoolss_notify_msg * msg,struct spoolss_Notify * data,TALLOC_CTX * mem_ctx)878 static void notify_system_time(struct spoolss_notify_msg *msg,
879 struct spoolss_Notify *data,
880 TALLOC_CTX *mem_ctx)
881 {
882 data->data.string.string = NULL;
883 data->data.string.size = 0;
884
885 if (msg->len != sizeof(time_t)) {
886 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
887 msg->len));
888 return;
889 }
890
891 init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
892 &data->data.string.string,
893 &data->data.string.size);
894 }
895
896 struct notify2_message_table {
897 const char *name;
898 void (*fn)(struct spoolss_notify_msg *msg,
899 struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
900 };
901
902 static struct notify2_message_table printer_notify_table[] = {
903 /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
904 /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
905 /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
906 /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
907 /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
908 /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
909 /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
910 /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
911 /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
912 /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
913 /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
914 /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
915 /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
916 /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
917 /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
918 /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
919 /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
920 /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
921 /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
922 };
923
924 static struct notify2_message_table job_notify_table[] = {
925 /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
926 /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
927 /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
928 /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
929 /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
930 /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
931 /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
932 /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
933 /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
934 /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
935 /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
936 /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
937 /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
938 /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
939 /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
940 /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
941 /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
942 /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
943 /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
944 /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
945 /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
946 /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
947 /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
948 /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
949 };
950
951
952 /***********************************************************************
953 Allocate talloc context for container object
954 **********************************************************************/
955
notify_msg_ctr_init(SPOOLSS_NOTIFY_MSG_CTR * ctr)956 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
957 {
958 if ( !ctr )
959 return;
960
961 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
962
963 return;
964 }
965
966 /***********************************************************************
967 release all allocated memory and zero out structure
968 **********************************************************************/
969
notify_msg_ctr_destroy(SPOOLSS_NOTIFY_MSG_CTR * ctr)970 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
971 {
972 if ( !ctr )
973 return;
974
975 if ( ctr->ctx )
976 talloc_destroy(ctr->ctx);
977
978 ZERO_STRUCTP(ctr);
979
980 return;
981 }
982
983 /***********************************************************************
984 **********************************************************************/
985
notify_ctr_getctx(SPOOLSS_NOTIFY_MSG_CTR * ctr)986 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
987 {
988 if ( !ctr )
989 return NULL;
990
991 return ctr->ctx;
992 }
993
994 /***********************************************************************
995 **********************************************************************/
996
notify_ctr_getgroup(SPOOLSS_NOTIFY_MSG_CTR * ctr,uint32_t idx)997 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
998 {
999 if ( !ctr || !ctr->msg_groups )
1000 return NULL;
1001
1002 if ( idx >= ctr->num_groups )
1003 return NULL;
1004
1005 return &ctr->msg_groups[idx];
1006
1007 }
1008
1009 /***********************************************************************
1010 How many groups of change messages do we have ?
1011 **********************************************************************/
1012
notify_msg_ctr_numgroups(SPOOLSS_NOTIFY_MSG_CTR * ctr)1013 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
1014 {
1015 if ( !ctr )
1016 return 0;
1017
1018 return ctr->num_groups;
1019 }
1020
1021 /***********************************************************************
1022 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
1023 **********************************************************************/
1024
notify_msg_ctr_addmsg(SPOOLSS_NOTIFY_MSG_CTR * ctr,SPOOLSS_NOTIFY_MSG * msg)1025 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
1026 {
1027 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
1028 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
1029 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
1030 int i, new_slot;
1031
1032 if ( !ctr || !msg )
1033 return 0;
1034
1035 /* loop over all groups looking for a matching printer name */
1036
1037 for ( i=0; i<ctr->num_groups; i++ ) {
1038 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
1039 break;
1040 }
1041
1042 /* add a new group? */
1043
1044 if ( i == ctr->num_groups ) {
1045 ctr->num_groups++;
1046
1047 if ( !(groups = talloc_realloc( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
1048 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
1049 return 0;
1050 }
1051 ctr->msg_groups = groups;
1052
1053 /* clear the new entry and set the printer name */
1054
1055 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
1056 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
1057 }
1058
1059 /* add the change messages; 'i' is the correct index now regardless */
1060
1061 msg_grp = &ctr->msg_groups[i];
1062
1063 msg_grp->num_msgs++;
1064
1065 if ( !(msg_list = talloc_realloc( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
1066 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
1067 return 0;
1068 }
1069 msg_grp->msgs = msg_list;
1070
1071 new_slot = msg_grp->num_msgs-1;
1072 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
1073
1074 /* need to allocate own copy of data */
1075
1076 if ( msg->len != 0 )
1077 msg_grp->msgs[new_slot].notify.data = (char *)
1078 talloc_memdup( ctr->ctx, msg->notify.data, msg->len );
1079
1080 return ctr->num_groups;
1081 }
1082
1083 static void construct_info_data(struct spoolss_Notify *info_data,
1084 enum spoolss_NotifyType type,
1085 uint16_t field, int id);
1086
1087 /***********************************************************************
1088 Send a change notication message on all handles which have a call
1089 back registered
1090 **********************************************************************/
1091
build_notify2_messages(TALLOC_CTX * mem_ctx,struct printer_handle * prn_hnd,SPOOLSS_NOTIFY_MSG * messages,uint32_t num_msgs,struct spoolss_Notify ** _notifies,size_t * _count)1092 static int build_notify2_messages(TALLOC_CTX *mem_ctx,
1093 struct printer_handle *prn_hnd,
1094 SPOOLSS_NOTIFY_MSG *messages,
1095 uint32_t num_msgs,
1096 struct spoolss_Notify **_notifies,
1097 size_t *_count)
1098 {
1099 struct spoolss_Notify *notifies;
1100 SPOOLSS_NOTIFY_MSG *msg;
1101 size_t count = 0;
1102 uint32_t id;
1103 uint32_t i;
1104
1105 notifies = talloc_zero_array(mem_ctx,
1106 struct spoolss_Notify, num_msgs);
1107 if (!notifies) {
1108 return ENOMEM;
1109 }
1110
1111 for (i = 0; i < num_msgs; i++) {
1112
1113 msg = &messages[i];
1114
1115 /* Are we monitoring this event? */
1116
1117 if (!is_monitoring_event(prn_hnd, msg->type, msg->field)) {
1118 continue;
1119 }
1120
1121 DEBUG(10, ("Sending message type [0x%x] field [0x%2x] "
1122 "for printer [%s]\n",
1123 msg->type, msg->field, prn_hnd->sharename));
1124
1125 /*
1126 * if the is a printer notification handle and not a job
1127 * notification type, then set the id to 0.
1128 * Otherwise just use what was specified in the message.
1129 *
1130 * When registering change notification on a print server
1131 * handle we always need to send back the id (snum) matching
1132 * the printer for which the change took place.
1133 * For change notify registered on a printer handle,
1134 * this does not matter and the id should be 0.
1135 *
1136 * --jerry
1137 */
1138
1139 if ((msg->type == PRINTER_NOTIFY_TYPE) &&
1140 (prn_hnd->printer_type == SPLHND_PRINTER)) {
1141 id = 0;
1142 } else {
1143 id = msg->id;
1144 }
1145
1146 /* Convert unix jobid to smb jobid */
1147
1148 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1149 id = sysjob_to_jobid(msg->id);
1150
1151 if (id == -1) {
1152 DEBUG(3, ("no such unix jobid %d\n",
1153 msg->id));
1154 continue;
1155 }
1156 }
1157
1158 construct_info_data(¬ifies[count],
1159 msg->type, msg->field, id);
1160
1161 switch(msg->type) {
1162 case PRINTER_NOTIFY_TYPE:
1163 if (printer_notify_table[msg->field].fn) {
1164 printer_notify_table[msg->field].fn(msg,
1165 ¬ifies[count], mem_ctx);
1166 }
1167 break;
1168
1169 case JOB_NOTIFY_TYPE:
1170 if (job_notify_table[msg->field].fn) {
1171 job_notify_table[msg->field].fn(msg,
1172 ¬ifies[count], mem_ctx);
1173 }
1174 break;
1175
1176 default:
1177 DEBUG(5, ("Unknown notification type %d\n",
1178 msg->type));
1179 continue;
1180 }
1181
1182 count++;
1183 }
1184
1185 *_notifies = notifies;
1186 *_count = count;
1187
1188 return 0;
1189 }
1190
send_notify2_printer(TALLOC_CTX * mem_ctx,struct printer_handle * prn_hnd,SPOOLSS_NOTIFY_MSG_GROUP * msg_group)1191 static int send_notify2_printer(TALLOC_CTX *mem_ctx,
1192 struct printer_handle *prn_hnd,
1193 SPOOLSS_NOTIFY_MSG_GROUP *msg_group)
1194 {
1195 struct spoolss_Notify *notifies;
1196 size_t count = 0;
1197 union spoolss_ReplyPrinterInfo info;
1198 struct spoolss_NotifyInfo info0;
1199 uint32_t reply_result;
1200 NTSTATUS status;
1201 WERROR werr;
1202 int ret;
1203
1204 /* Is there notification on this handle? */
1205 if (prn_hnd->notify.cli_chan == NULL ||
1206 prn_hnd->notify.cli_chan->cli_pipe == NULL ||
1207 prn_hnd->notify.cli_chan->cli_pipe->binding_handle == NULL ||
1208 prn_hnd->notify.cli_chan->active_connections == 0) {
1209 return 0;
1210 }
1211
1212 DEBUG(10, ("Client connected! [\\\\%s\\%s]\n",
1213 prn_hnd->servername, prn_hnd->sharename));
1214
1215 /* For this printer? Print servers always receive notifications. */
1216 if ((prn_hnd->printer_type == SPLHND_PRINTER) &&
1217 (!strequal(msg_group->printername, prn_hnd->sharename))) {
1218 return 0;
1219 }
1220
1221 DEBUG(10,("Our printer\n"));
1222
1223 /* build the array of change notifications */
1224 ret = build_notify2_messages(mem_ctx, prn_hnd,
1225 msg_group->msgs,
1226 msg_group->num_msgs,
1227 ¬ifies, &count);
1228 if (ret) {
1229 return ret;
1230 }
1231
1232 info0.version = 0x2;
1233 info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1234 info0.count = count;
1235 info0.notifies = notifies;
1236
1237 info.info0 = &info0;
1238
1239 status = dcerpc_spoolss_RouterReplyPrinterEx(
1240 prn_hnd->notify.cli_chan->cli_pipe->binding_handle,
1241 mem_ctx,
1242 &prn_hnd->notify.cli_hnd,
1243 prn_hnd->notify.change, /* color */
1244 prn_hnd->notify.flags,
1245 &reply_result,
1246 0, /* reply_type, must be 0 */
1247 info, &werr);
1248 if (!NT_STATUS_IS_OK(status)) {
1249 DEBUG(1, ("dcerpc_spoolss_RouterReplyPrinterEx to client: %s "
1250 "failed: %s\n",
1251 prn_hnd->notify.cli_chan->cli_pipe->srv_name_slash,
1252 nt_errstr(status)));
1253 werr = ntstatus_to_werror(status);
1254 } else if (!W_ERROR_IS_OK(werr)) {
1255 DEBUG(1, ("RouterReplyPrinterEx to client: %s "
1256 "failed: %s\n",
1257 prn_hnd->notify.cli_chan->cli_pipe->srv_name_slash,
1258 win_errstr(werr)));
1259 }
1260 switch (reply_result) {
1261 case 0:
1262 break;
1263 case PRINTER_NOTIFY_INFO_DISCARDED:
1264 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1265 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1266 break;
1267 default:
1268 break;
1269 }
1270
1271 return 0;
1272 }
1273
send_notify2_changes(SPOOLSS_NOTIFY_MSG_CTR * ctr,uint32_t idx)1274 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
1275 {
1276 struct printer_handle *p;
1277 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
1278 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
1279 int ret;
1280
1281 if ( !msg_group ) {
1282 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
1283 return;
1284 }
1285
1286 if (!msg_group->msgs) {
1287 DEBUG(5, ("send_notify2_changes() called with no messages!\n"));
1288 return;
1289 }
1290
1291 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
1292
1293 /* loop over all printers */
1294
1295 for (p = printers_list; p; p = p->next) {
1296 ret = send_notify2_printer(mem_ctx, p, msg_group);
1297 if (ret) {
1298 goto done;
1299 }
1300 }
1301
1302 done:
1303 DEBUG(8,("send_notify2_changes: Exit...\n"));
1304 return;
1305 }
1306
1307 /***********************************************************************
1308 **********************************************************************/
1309
notify2_unpack_msg(SPOOLSS_NOTIFY_MSG * msg,struct timeval * tv,void * buf,size_t len)1310 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1311 {
1312
1313 uint32_t tv_sec, tv_usec;
1314 size_t offset = 0;
1315
1316 /* Unpack message */
1317
1318 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
1319 msg->printer);
1320
1321 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
1322 &tv_sec, &tv_usec,
1323 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1324
1325 if (msg->len == 0)
1326 tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
1327 &msg->notify.value[0], &msg->notify.value[1]);
1328 else
1329 tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
1330 &msg->len, &msg->notify.data);
1331
1332 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1333 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1334
1335 tv->tv_sec = tv_sec;
1336 tv->tv_usec = tv_usec;
1337
1338 if (msg->len == 0)
1339 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1340 msg->notify.value[1]));
1341 else
1342 dump_data(3, (uint8_t *)msg->notify.data, msg->len);
1343
1344 return true;
1345 }
1346
1347 /********************************************************************
1348 Receive a notify2 message list
1349 ********************************************************************/
1350
receive_notify2_message_list(struct messaging_context * msg,void * private_data,uint32_t msg_type,struct server_id server_id,DATA_BLOB * data)1351 static void receive_notify2_message_list(struct messaging_context *msg,
1352 void *private_data,
1353 uint32_t msg_type,
1354 struct server_id server_id,
1355 DATA_BLOB *data)
1356 {
1357 size_t msg_count, i;
1358 char *buf = (char *)data->data;
1359 char *msg_ptr;
1360 size_t msg_len;
1361 SPOOLSS_NOTIFY_MSG notify;
1362 SPOOLSS_NOTIFY_MSG_CTR messages;
1363 int num_groups;
1364
1365 if (data->length < 4) {
1366 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1367 return;
1368 }
1369
1370 msg_count = IVAL(buf, 0);
1371 msg_ptr = buf + 4;
1372
1373 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1374
1375 if (msg_count == 0) {
1376 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1377 return;
1378 }
1379
1380 /* initialize the container */
1381
1382 ZERO_STRUCT( messages );
1383 notify_msg_ctr_init( &messages );
1384
1385 /*
1386 * build message groups for each printer identified
1387 * in a change_notify msg. Remember that a PCN message
1388 * includes the handle returned for the srv_spoolss_replyopenprinter()
1389 * call. Therefore messages are grouped according to printer handle.
1390 */
1391
1392 for ( i=0; i<msg_count; i++ ) {
1393 struct timeval msg_tv;
1394
1395 if (msg_ptr + 4 - buf > data->length) {
1396 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1397 return;
1398 }
1399
1400 msg_len = IVAL(msg_ptr,0);
1401 msg_ptr += 4;
1402
1403 if (msg_ptr + msg_len - buf > data->length) {
1404 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1405 return;
1406 }
1407
1408 /* unpack messages */
1409
1410 ZERO_STRUCT( notify );
1411 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1412 msg_ptr += msg_len;
1413
1414 /* add to correct list in container */
1415
1416 notify_msg_ctr_addmsg( &messages, ¬ify );
1417
1418 /* free memory that might have been allocated by notify2_unpack_msg() */
1419
1420 if ( notify.len != 0 )
1421 SAFE_FREE( notify.notify.data );
1422 }
1423
1424 /* process each group of messages */
1425
1426 num_groups = notify_msg_ctr_numgroups( &messages );
1427 for ( i=0; i<num_groups; i++ )
1428 send_notify2_changes( &messages, i );
1429
1430
1431 /* cleanup */
1432
1433 DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1434 (uint32_t)msg_count ));
1435
1436 notify_msg_ctr_destroy( &messages );
1437
1438 return;
1439 }
1440
1441 /********************************************************************
1442 Send a message to ourself about new driver being installed
1443 so we can upgrade the information for each printer bound to this
1444 driver
1445 ********************************************************************/
1446
srv_spoolss_drv_upgrade_printer(const char * drivername,struct messaging_context * msg_ctx)1447 static bool srv_spoolss_drv_upgrade_printer(const char *drivername,
1448 struct messaging_context *msg_ctx)
1449 {
1450 int len = strlen(drivername);
1451
1452 if (!len)
1453 return false;
1454
1455 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1456 drivername));
1457
1458 messaging_send_buf(msg_ctx, messaging_server_id(msg_ctx),
1459 MSG_PRINTER_DRVUPGRADE,
1460 (const uint8_t *)drivername, len+1);
1461
1462 return true;
1463 }
1464
srv_spoolss_cleanup(void)1465 void srv_spoolss_cleanup(void)
1466 {
1467 struct printer_session_counter *session_counter;
1468
1469 for (session_counter = counter_list;
1470 session_counter != NULL;
1471 session_counter = counter_list) {
1472 DLIST_REMOVE(counter_list, session_counter);
1473 TALLOC_FREE(session_counter);
1474 }
1475 }
1476
1477 /**********************************************************************
1478 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1479 over all printers, upgrading ones as necessary
1480 This is now *ONLY* called inside the background lpq updater. JRA.
1481 **********************************************************************/
1482
do_drv_upgrade_printer(struct messaging_context * msg,void * private_data,uint32_t msg_type,struct server_id server_id,DATA_BLOB * data)1483 void do_drv_upgrade_printer(struct messaging_context *msg,
1484 void *private_data,
1485 uint32_t msg_type,
1486 struct server_id server_id,
1487 DATA_BLOB *data)
1488 {
1489 TALLOC_CTX *tmp_ctx;
1490 const struct auth_session_info *session_info = get_session_info_system();
1491 struct spoolss_PrinterInfo2 *pinfo2;
1492 WERROR result;
1493 const char *drivername;
1494 int snum;
1495 int n_services = lp_numservices();
1496 struct dcerpc_binding_handle *b = NULL;
1497
1498 tmp_ctx = talloc_new(NULL);
1499 if (!tmp_ctx) return;
1500
1501 drivername = talloc_strndup(tmp_ctx, (const char *)data->data, data->length);
1502 if (!drivername) {
1503 DEBUG(0, ("do_drv_upgrade_printer: Out of memoery ?!\n"));
1504 goto done;
1505 }
1506
1507 DEBUG(10, ("do_drv_upgrade_printer: "
1508 "Got message for new driver [%s]\n", drivername));
1509
1510 /* Iterate the printer list */
1511
1512 for (snum = 0; snum < n_services; snum++) {
1513 if (!lp_snum_ok(snum) || !lp_printable(snum)) {
1514 continue;
1515 }
1516
1517 /* ignore [printers] share */
1518 if (strequal(lp_const_servicename(snum), "printers")) {
1519 continue;
1520 }
1521
1522 if (b == NULL) {
1523 result = winreg_printer_binding_handle(tmp_ctx,
1524 session_info,
1525 msg,
1526 &b);
1527 if (!W_ERROR_IS_OK(result)) {
1528 break;
1529 }
1530 }
1531
1532 result = winreg_get_printer(tmp_ctx, b,
1533 lp_const_servicename(snum),
1534 &pinfo2);
1535
1536 if (!W_ERROR_IS_OK(result)) {
1537 continue;
1538 }
1539
1540 if (!pinfo2->drivername) {
1541 continue;
1542 }
1543
1544 if (strcmp(drivername, pinfo2->drivername) != 0) {
1545 continue;
1546 }
1547
1548 DEBUG(6,("Updating printer [%s]\n", pinfo2->printername));
1549
1550 /* all we care about currently is the change_id */
1551 result = winreg_printer_update_changeid(tmp_ctx, b,
1552 pinfo2->printername);
1553
1554 if (!W_ERROR_IS_OK(result)) {
1555 DEBUG(3, ("do_drv_upgrade_printer: "
1556 "Failed to update changeid [%s]\n",
1557 win_errstr(result)));
1558 }
1559 }
1560
1561 /* all done */
1562 done:
1563 talloc_free(tmp_ctx);
1564 }
1565
1566 /********************************************************************
1567 Update the cache for all printq's with a registered client
1568 connection
1569 ********************************************************************/
1570
update_monitored_printq_cache(struct messaging_context * msg_ctx)1571 void update_monitored_printq_cache(struct messaging_context *msg_ctx)
1572 {
1573 struct printer_handle *printer = printers_list;
1574 int snum;
1575
1576 /* loop through all printers and update the cache where
1577 a client is connected */
1578 while (printer) {
1579 if ((printer->printer_type == SPLHND_PRINTER) &&
1580 ((printer->notify.cli_chan != NULL) &&
1581 (printer->notify.cli_chan->active_connections > 0))) {
1582 snum = print_queue_snum(printer->sharename);
1583 print_queue_status(msg_ctx, snum, NULL, NULL);
1584 }
1585
1586 printer = printer->next;
1587 }
1588
1589 return;
1590 }
1591
1592 /****************************************************************
1593 _spoolss_OpenPrinter
1594 ****************************************************************/
1595
_spoolss_OpenPrinter(struct pipes_struct * p,struct spoolss_OpenPrinter * r)1596 WERROR _spoolss_OpenPrinter(struct pipes_struct *p,
1597 struct spoolss_OpenPrinter *r)
1598 {
1599 struct spoolss_OpenPrinterEx e;
1600 struct spoolss_UserLevel1 level1;
1601 WERROR werr;
1602
1603 ZERO_STRUCT(level1);
1604
1605 e.in.printername = r->in.printername;
1606 e.in.datatype = r->in.datatype;
1607 e.in.devmode_ctr = r->in.devmode_ctr;
1608 e.in.access_mask = r->in.access_mask;
1609 e.in.userlevel_ctr.level = 1;
1610 e.in.userlevel_ctr.user_info.level1 = &level1;
1611
1612 e.out.handle = r->out.handle;
1613
1614 werr = _spoolss_OpenPrinterEx(p, &e);
1615
1616 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAMETER)) {
1617 /* OpenPrinterEx returns this for a bad
1618 * printer name. We must return WERR_INVALID_PRINTER_NAME
1619 * instead.
1620 */
1621 werr = WERR_INVALID_PRINTER_NAME;
1622 }
1623
1624 return werr;
1625 }
1626
copy_devicemode(TALLOC_CTX * mem_ctx,struct spoolss_DeviceMode * orig,struct spoolss_DeviceMode ** dest)1627 static WERROR copy_devicemode(TALLOC_CTX *mem_ctx,
1628 struct spoolss_DeviceMode *orig,
1629 struct spoolss_DeviceMode **dest)
1630 {
1631 struct spoolss_DeviceMode *dm;
1632
1633 dm = talloc(mem_ctx, struct spoolss_DeviceMode);
1634 if (!dm) {
1635 return WERR_NOT_ENOUGH_MEMORY;
1636 }
1637
1638 /* copy all values, then duplicate strings and structs */
1639 *dm = *orig;
1640
1641 dm->devicename = talloc_strdup(dm, orig->devicename);
1642 if (!dm->devicename) {
1643 return WERR_NOT_ENOUGH_MEMORY;
1644 }
1645 dm->formname = talloc_strdup(dm, orig->formname);
1646 if (!dm->formname) {
1647 return WERR_NOT_ENOUGH_MEMORY;
1648 }
1649 if (orig->driverextra_data.data) {
1650 dm->driverextra_data.data =
1651 (uint8_t *) talloc_memdup(dm, orig->driverextra_data.data,
1652 orig->driverextra_data.length);
1653 if (!dm->driverextra_data.data) {
1654 return WERR_NOT_ENOUGH_MEMORY;
1655 }
1656 }
1657
1658 *dest = dm;
1659 return WERR_OK;
1660 }
1661
1662 /****************************************************************
1663 _spoolss_OpenPrinterEx
1664 ****************************************************************/
1665
_spoolss_OpenPrinterEx(struct pipes_struct * p,struct spoolss_OpenPrinterEx * r)1666 WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
1667 struct spoolss_OpenPrinterEx *r)
1668 {
1669 int snum;
1670 char *raddr;
1671 char *rhost;
1672 struct printer_handle *Printer=NULL;
1673 WERROR result;
1674 int rc;
1675
1676 if (!r->in.printername) {
1677 return WERR_INVALID_PARAMETER;
1678 }
1679
1680 if (!*r->in.printername) {
1681 return WERR_INVALID_PARAMETER;
1682 }
1683
1684 if (r->in.userlevel_ctr.level > 3) {
1685 return WERR_INVALID_PARAMETER;
1686 }
1687 if ((r->in.userlevel_ctr.level == 1 && !r->in.userlevel_ctr.user_info.level1) ||
1688 (r->in.userlevel_ctr.level == 2 && !r->in.userlevel_ctr.user_info.level2) ||
1689 (r->in.userlevel_ctr.level == 3 && !r->in.userlevel_ctr.user_info.level3)) {
1690 return WERR_INVALID_PARAMETER;
1691 }
1692
1693 /*
1694 * The printcap printer share inventory is updated on client
1695 * enumeration. For clients that do not perform enumeration prior to
1696 * access, such as cupssmbadd, we reinitialise the printer share
1697 * inventory on open as well.
1698 */
1699 become_root();
1700 delete_and_reload_printers();
1701 unbecome_root();
1702
1703 /* some sanity check because you can open a printer or a print server */
1704 /* aka: \\server\printer or \\server */
1705
1706 DEBUGADD(3,("checking name: %s\n", r->in.printername));
1707
1708 result = open_printer_hnd(p, r->out.handle, r->in.printername, 0);
1709 if (!W_ERROR_IS_OK(result)) {
1710 DEBUG(3,("_spoolss_OpenPrinterEx: Cannot open a printer handle "
1711 "for printer %s\n", r->in.printername));
1712 ZERO_STRUCTP(r->out.handle);
1713 return result;
1714 }
1715
1716 Printer = find_printer_index_by_hnd(p, r->out.handle);
1717 if ( !Printer ) {
1718 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1719 "handle we created for printer %s\n", r->in.printername));
1720 close_printer_handle(p, r->out.handle);
1721 ZERO_STRUCTP(r->out.handle);
1722 return WERR_INVALID_PARAMETER;
1723 }
1724
1725 /*
1726 * First case: the user is opening the print server:
1727 *
1728 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1729 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1730 *
1731 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1732 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1733 * or if the user is listed in the smb.conf printer admin parameter.
1734 *
1735 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1736 * client view printer folder, but does not show the MSAPW.
1737 *
1738 * Note: this test needs code to check access rights here too. Jeremy
1739 * could you look at this?
1740 *
1741 * Second case: the user is opening a printer:
1742 * NT doesn't let us connect to a printer if the connecting user
1743 * doesn't have print permission.
1744 *
1745 * Third case: user is opening a Port Monitor
1746 * access checks same as opening a handle to the print server.
1747 */
1748
1749 switch (Printer->printer_type )
1750 {
1751 case SPLHND_SERVER:
1752 case SPLHND_PORTMON_TCP:
1753 case SPLHND_PORTMON_LOCAL:
1754 /* Printserver handles use global struct... */
1755
1756 snum = -1;
1757
1758 if (r->in.access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
1759 r->in.access_mask |= SERVER_ACCESS_ADMINISTER;
1760 r->in.access_mask |= SERVER_ACCESS_ENUMERATE;
1761 }
1762
1763 /* Map standard access rights to object specific access rights */
1764
1765 se_map_standard(&r->in.access_mask,
1766 &printserver_std_mapping);
1767
1768 /* Deny any object specific bits that don't apply to print
1769 servers (i.e printer and job specific bits) */
1770
1771 r->in.access_mask &= SEC_MASK_SPECIFIC;
1772
1773 if (r->in.access_mask &
1774 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1775 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1776 close_printer_handle(p, r->out.handle);
1777 ZERO_STRUCTP(r->out.handle);
1778 return WERR_ACCESS_DENIED;
1779 }
1780
1781 /* Allow admin access */
1782
1783 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1784 {
1785 if (!lp_show_add_printer_wizard()) {
1786 close_printer_handle(p, r->out.handle);
1787 ZERO_STRUCTP(r->out.handle);
1788 return WERR_ACCESS_DENIED;
1789 }
1790
1791 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1792 and not a printer admin, then fail */
1793
1794 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
1795 !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_PRINT_OPERATOR) &&
1796 !nt_token_check_sid(&global_sid_Builtin_Print_Operators,
1797 p->session_info->security_token)) {
1798 close_printer_handle(p, r->out.handle);
1799 ZERO_STRUCTP(r->out.handle);
1800 DEBUG(3,("access DENIED as user is not root, "
1801 "has no printoperator privilege and is "
1802 "not a member of the printoperator builtin group\n"));
1803 return WERR_ACCESS_DENIED;
1804 }
1805
1806 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1807 }
1808 else
1809 {
1810 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1811 }
1812
1813 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1814 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1815
1816 break;
1817
1818 case SPLHND_PRINTER:
1819 /* NT doesn't let us connect to a printer if the connecting user
1820 doesn't have print permission. */
1821
1822 if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1823 close_printer_handle(p, r->out.handle);
1824 ZERO_STRUCTP(r->out.handle);
1825 return WERR_INVALID_HANDLE;
1826 }
1827
1828 if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
1829 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1830 }
1831
1832 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1833
1834 /* map an empty access mask to the minimum access mask */
1835 if (r->in.access_mask == 0x0)
1836 r->in.access_mask = PRINTER_ACCESS_USE;
1837
1838 /*
1839 * If we are not serving the printer driver for this printer,
1840 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1841 * will keep NT clients happy --jerry
1842 */
1843
1844 if (lp_use_client_driver(snum)
1845 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1846 {
1847 r->in.access_mask = PRINTER_ACCESS_USE;
1848 }
1849
1850 /* check smb.conf parameters and the the sec_desc */
1851 raddr = tsocket_address_inet_addr_string(p->remote_address,
1852 p->mem_ctx);
1853 if (raddr == NULL) {
1854 return WERR_NOT_ENOUGH_MEMORY;
1855 }
1856
1857 rc = get_remote_hostname(p->remote_address,
1858 &rhost,
1859 p->mem_ctx);
1860 if (rc < 0) {
1861 return WERR_NOT_ENOUGH_MEMORY;
1862 }
1863 if (strequal(rhost, "UNKNOWN")) {
1864 rhost = raddr;
1865 }
1866
1867 if (!allow_access(lp_hosts_deny(snum), lp_hosts_allow(snum),
1868 rhost, raddr)) {
1869 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1870 ZERO_STRUCTP(r->out.handle);
1871 return WERR_ACCESS_DENIED;
1872 }
1873
1874 if (!user_ok_token(p->session_info->unix_info->unix_name,
1875 p->session_info->info->domain_name,
1876 p->session_info->security_token, snum) ||
1877 !W_ERROR_IS_OK(print_access_check(p->session_info,
1878 p->msg_ctx,
1879 snum,
1880 r->in.access_mask))) {
1881 DEBUG(3, ("access DENIED for printer open\n"));
1882 close_printer_handle(p, r->out.handle);
1883 ZERO_STRUCTP(r->out.handle);
1884 return WERR_ACCESS_DENIED;
1885 }
1886
1887 if ((r->in.access_mask & SEC_MASK_SPECIFIC)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1888 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1889 close_printer_handle(p, r->out.handle);
1890 ZERO_STRUCTP(r->out.handle);
1891 return WERR_ACCESS_DENIED;
1892 }
1893
1894 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1895 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1896 else
1897 r->in.access_mask = PRINTER_ACCESS_USE;
1898
1899 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1900 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1901
1902 winreg_create_printer_internal(p->mem_ctx,
1903 get_session_info_system(),
1904 p->msg_ctx,
1905 lp_const_servicename(snum));
1906
1907 break;
1908
1909 default:
1910 /* sanity check to prevent programmer error */
1911 ZERO_STRUCTP(r->out.handle);
1912 return WERR_INVALID_HANDLE;
1913 }
1914
1915 Printer->access_granted = r->in.access_mask;
1916
1917 /*
1918 * If the client sent a devmode in the OpenPrinter() call, then
1919 * save it here in case we get a job submission on this handle
1920 */
1921
1922 if ((Printer->printer_type != SPLHND_SERVER)
1923 && (r->in.devmode_ctr.devmode != NULL)) {
1924 copy_devicemode(NULL, r->in.devmode_ctr.devmode,
1925 &Printer->devmode);
1926 }
1927
1928 return WERR_OK;
1929 }
1930
1931 /****************************************************************
1932 _spoolss_ClosePrinter
1933 ****************************************************************/
1934
_spoolss_ClosePrinter(struct pipes_struct * p,struct spoolss_ClosePrinter * r)1935 WERROR _spoolss_ClosePrinter(struct pipes_struct *p,
1936 struct spoolss_ClosePrinter *r)
1937 {
1938 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
1939
1940 if (Printer && Printer->document_started) {
1941 struct spoolss_EndDocPrinter e;
1942
1943 e.in.handle = r->in.handle;
1944
1945 _spoolss_EndDocPrinter(p, &e);
1946 }
1947
1948 if (!close_printer_handle(p, r->in.handle))
1949 return WERR_INVALID_HANDLE;
1950
1951 /* clear the returned printer handle. Observed behavior
1952 from Win2k server. Don't think this really matters.
1953 Previous code just copied the value of the closed
1954 handle. --jerry */
1955
1956 ZERO_STRUCTP(r->out.handle);
1957
1958 return WERR_OK;
1959 }
1960
1961 /****************************************************************
1962 _spoolss_DeletePrinter
1963 ****************************************************************/
1964
_spoolss_DeletePrinter(struct pipes_struct * p,struct spoolss_DeletePrinter * r)1965 WERROR _spoolss_DeletePrinter(struct pipes_struct *p,
1966 struct spoolss_DeletePrinter *r)
1967 {
1968 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
1969 WERROR result;
1970 int snum;
1971
1972 if (Printer && Printer->document_started) {
1973 struct spoolss_EndDocPrinter e;
1974
1975 e.in.handle = r->in.handle;
1976
1977 _spoolss_EndDocPrinter(p, &e);
1978 }
1979
1980 if (get_printer_snum(p, r->in.handle, &snum, NULL)) {
1981 winreg_delete_printer_key_internal(p->mem_ctx,
1982 get_session_info_system(),
1983 p->msg_ctx,
1984 lp_const_servicename(snum),
1985 "");
1986 }
1987
1988 result = delete_printer_handle(p, r->in.handle);
1989
1990 return result;
1991 }
1992
1993 /*******************************************************************
1994 * static function to lookup the version id corresponding to an
1995 * long architecture string
1996 ******************************************************************/
1997
1998 static const struct print_architecture_table_node archi_table[]= {
1999
2000 {"Windows 4.0", SPL_ARCH_WIN40, 0 },
2001 {"Windows NT x86", SPL_ARCH_W32X86, 2 },
2002 {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
2003 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
2004 {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
2005 {"Windows IA64", SPL_ARCH_IA64, 3 },
2006 {"Windows x64", SPL_ARCH_X64, 3 },
2007 {NULL, "", -1 }
2008 };
2009
2010 static const int drv_cversion[] = {SPOOLSS_DRIVER_VERSION_9X,
2011 SPOOLSS_DRIVER_VERSION_NT35,
2012 SPOOLSS_DRIVER_VERSION_NT4,
2013 SPOOLSS_DRIVER_VERSION_200X,
2014 -1};
2015
get_version_id(const char * arch)2016 static int get_version_id(const char *arch)
2017 {
2018 int i;
2019
2020 for (i=0; archi_table[i].long_archi != NULL; i++)
2021 {
2022 if (strcmp(arch, archi_table[i].long_archi) == 0)
2023 return (archi_table[i].version);
2024 }
2025
2026 return -1;
2027 }
2028
2029 /****************************************************************
2030 _spoolss_DeletePrinterDriver
2031 ****************************************************************/
2032
_spoolss_DeletePrinterDriver(struct pipes_struct * p,struct spoolss_DeletePrinterDriver * r)2033 WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
2034 struct spoolss_DeletePrinterDriver *r)
2035 {
2036
2037 struct spoolss_DriverInfo8 *info = NULL;
2038 int version;
2039 WERROR status;
2040 struct dcerpc_binding_handle *b;
2041 TALLOC_CTX *tmp_ctx = NULL;
2042 int i;
2043 bool found;
2044
2045 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2046 and not a printer admin, then fail */
2047
2048 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
2049 !security_token_has_privilege(p->session_info->security_token,
2050 SEC_PRIV_PRINT_OPERATOR)) {
2051 return WERR_ACCESS_DENIED;
2052 }
2053
2054 if (r->in.architecture == NULL || r->in.driver == NULL) {
2055 return WERR_INVALID_ENVIRONMENT;
2056 }
2057
2058 /* check that we have a valid driver name first */
2059
2060 if ((version = get_version_id(r->in.architecture)) == -1) {
2061 return WERR_INVALID_ENVIRONMENT;
2062 }
2063
2064 tmp_ctx = talloc_new(p->mem_ctx);
2065 if (!tmp_ctx) {
2066 return WERR_NOT_ENOUGH_MEMORY;
2067 }
2068
2069 status = winreg_printer_binding_handle(tmp_ctx,
2070 get_session_info_system(),
2071 p->msg_ctx,
2072 &b);
2073 if (!W_ERROR_IS_OK(status)) {
2074 goto done;
2075 }
2076
2077 for (found = false, i = 0; drv_cversion[i] >= 0; i++) {
2078 status = winreg_get_driver(tmp_ctx, b,
2079 r->in.architecture, r->in.driver,
2080 drv_cversion[i], &info);
2081 if (!W_ERROR_IS_OK(status)) {
2082 DEBUG(5, ("skipping del of driver with version %d\n",
2083 drv_cversion[i]));
2084 continue;
2085 }
2086 found = true;
2087
2088 if (printer_driver_in_use(tmp_ctx, b, info)) {
2089 status = WERR_PRINTER_DRIVER_IN_USE;
2090 goto done;
2091 }
2092
2093 status = winreg_del_driver(tmp_ctx, b, info, drv_cversion[i]);
2094 if (!W_ERROR_IS_OK(status)) {
2095 DEBUG(0, ("failed del of driver with version %d\n",
2096 drv_cversion[i]));
2097 goto done;
2098 }
2099 }
2100 if (found == false) {
2101 DEBUG(0, ("driver %s not found for deletion\n", r->in.driver));
2102 status = WERR_UNKNOWN_PRINTER_DRIVER;
2103 } else {
2104 status = WERR_OK;
2105 }
2106
2107 done:
2108 talloc_free(tmp_ctx);
2109
2110 return status;
2111 }
2112
spoolss_dpd_version(TALLOC_CTX * mem_ctx,struct pipes_struct * p,struct spoolss_DeletePrinterDriverEx * r,struct dcerpc_binding_handle * b,struct spoolss_DriverInfo8 * info)2113 static WERROR spoolss_dpd_version(TALLOC_CTX *mem_ctx,
2114 struct pipes_struct *p,
2115 struct spoolss_DeletePrinterDriverEx *r,
2116 struct dcerpc_binding_handle *b,
2117 struct spoolss_DriverInfo8 *info)
2118 {
2119 WERROR status;
2120 bool delete_files;
2121
2122 if (printer_driver_in_use(mem_ctx, b, info)) {
2123 status = WERR_PRINTER_DRIVER_IN_USE;
2124 goto done;
2125 }
2126
2127 /*
2128 * we have a couple of cases to consider.
2129 * (1) Are any files in use? If so and DPD_DELETE_ALL_FILES is set,
2130 * then the delete should fail if **any** files overlap with
2131 * other drivers
2132 * (2) If DPD_DELETE_UNUSED_FILES is set, then delete all
2133 * non-overlapping files
2134 * (3) If neither DPD_DELETE_ALL_FILES nor DPD_DELETE_UNUSED_FILES
2135 * are set, then do not delete any files
2136 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2137 */
2138
2139 delete_files = r->in.delete_flags
2140 & (DPD_DELETE_ALL_FILES | DPD_DELETE_UNUSED_FILES);
2141
2142
2143 if (delete_files) {
2144 bool in_use = printer_driver_files_in_use(mem_ctx, b, info);
2145 if (in_use && (r->in.delete_flags & DPD_DELETE_ALL_FILES)) {
2146 status = WERR_PRINTER_DRIVER_IN_USE;
2147 goto done;
2148 }
2149 /*
2150 * printer_driver_files_in_use() has trimmed overlapping files
2151 * from info so they are not removed on DPD_DELETE_UNUSED_FILES
2152 */
2153 }
2154
2155
2156 status = winreg_del_driver(mem_ctx, b, info, info->version);
2157 if (!W_ERROR_IS_OK(status)) {
2158 goto done;
2159 }
2160
2161 /*
2162 * now delete any associated files if delete_files is
2163 * true. Even if this part failes, we return succes
2164 * because the driver doesn not exist any more
2165 */
2166 if (delete_files) {
2167 delete_driver_files(p->session_info, info);
2168 }
2169
2170 done:
2171 return status;
2172 }
2173
2174 /****************************************************************
2175 _spoolss_DeletePrinterDriverEx
2176 ****************************************************************/
2177
_spoolss_DeletePrinterDriverEx(struct pipes_struct * p,struct spoolss_DeletePrinterDriverEx * r)2178 WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
2179 struct spoolss_DeletePrinterDriverEx *r)
2180 {
2181 struct spoolss_DriverInfo8 *info = NULL;
2182 WERROR status;
2183 struct dcerpc_binding_handle *b;
2184 TALLOC_CTX *tmp_ctx = NULL;
2185 int i;
2186 bool found;
2187
2188 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2189 and not a printer admin, then fail */
2190
2191 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
2192 !security_token_has_privilege(p->session_info->security_token,
2193 SEC_PRIV_PRINT_OPERATOR)) {
2194 return WERR_ACCESS_DENIED;
2195 }
2196
2197 if (r->in.architecture == NULL || r->in.driver == NULL) {
2198 return WERR_INVALID_ENVIRONMENT;
2199 }
2200
2201 /* check that we have a valid driver name first */
2202 if (get_version_id(r->in.architecture) == -1) {
2203 /* this is what NT returns */
2204 return WERR_INVALID_ENVIRONMENT;
2205 }
2206
2207 tmp_ctx = talloc_new(p->mem_ctx);
2208 if (!tmp_ctx) {
2209 return WERR_NOT_ENOUGH_MEMORY;
2210 }
2211
2212 status = winreg_printer_binding_handle(tmp_ctx,
2213 get_session_info_system(),
2214 p->msg_ctx,
2215 &b);
2216 if (!W_ERROR_IS_OK(status)) {
2217 goto done;
2218 }
2219
2220 for (found = false, i = 0; drv_cversion[i] >= 0; i++) {
2221 if ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
2222 && (drv_cversion[i] != r->in.version)) {
2223 continue;
2224 }
2225
2226 /* check if a driver with this version exists before delete */
2227 status = winreg_get_driver(tmp_ctx, b,
2228 r->in.architecture, r->in.driver,
2229 drv_cversion[i], &info);
2230 if (!W_ERROR_IS_OK(status)) {
2231 DEBUG(5, ("skipping del of driver with version %d\n",
2232 drv_cversion[i]));
2233 continue;
2234 }
2235 found = true;
2236
2237 status = spoolss_dpd_version(tmp_ctx, p, r, b, info);
2238 if (!W_ERROR_IS_OK(status)) {
2239 DEBUG(0, ("failed to delete driver with version %d\n",
2240 drv_cversion[i]));
2241 goto done;
2242 }
2243 }
2244 if (found == false) {
2245 DEBUG(0, ("driver %s not found for deletion\n", r->in.driver));
2246 status = WERR_UNKNOWN_PRINTER_DRIVER;
2247 } else {
2248 status = WERR_OK;
2249 }
2250
2251 done:
2252 talloc_free(tmp_ctx);
2253 return status;
2254 }
2255
2256
2257 /********************************************************************
2258 GetPrinterData on a printer server Handle.
2259 ********************************************************************/
2260
getprinterdata_printer_server(TALLOC_CTX * mem_ctx,const char * value,enum winreg_Type * type,union spoolss_PrinterData * data)2261 static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2262 const char *value,
2263 enum winreg_Type *type,
2264 union spoolss_PrinterData *data)
2265 {
2266 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2267
2268 if (!strcasecmp_m(value, "W3SvcInstalled")) {
2269 *type = REG_DWORD;
2270 SIVAL(&data->value, 0, 0x00);
2271 return WERR_OK;
2272 }
2273
2274 if (!strcasecmp_m(value, "BeepEnabled")) {
2275 *type = REG_DWORD;
2276 SIVAL(&data->value, 0, 0x00);
2277 return WERR_OK;
2278 }
2279
2280 if (!strcasecmp_m(value, "EventLog")) {
2281 *type = REG_DWORD;
2282 /* formally was 0x1b */
2283 SIVAL(&data->value, 0, 0x00);
2284 return WERR_OK;
2285 }
2286
2287 if (!strcasecmp_m(value, "NetPopup")) {
2288 *type = REG_DWORD;
2289 SIVAL(&data->value, 0, 0x00);
2290 return WERR_OK;
2291 }
2292
2293 if (!strcasecmp_m(value, "MajorVersion")) {
2294 *type = REG_DWORD;
2295
2296 /* Windows NT 4.0 seems to not allow uploading of drivers
2297 to a server that reports 0x3 as the MajorVersion.
2298 need to investigate more how Win2k gets around this .
2299 -- jerry */
2300
2301 if (RA_WINNT == get_remote_arch()) {
2302 SIVAL(&data->value, 0, 0x02);
2303 } else {
2304 SIVAL(&data->value, 0, 0x03);
2305 }
2306
2307 return WERR_OK;
2308 }
2309
2310 if (!strcasecmp_m(value, "MinorVersion")) {
2311 *type = REG_DWORD;
2312 SIVAL(&data->value, 0, 0x00);
2313 return WERR_OK;
2314 }
2315
2316 /* REG_BINARY
2317 * uint32_t size = 0x114
2318 * uint32_t major = 5
2319 * uint32_t minor = [0|1]
2320 * uint32_t build = [2195|2600]
2321 * extra unicode string = e.g. "Service Pack 3"
2322 */
2323 if (!strcasecmp_m(value, "OSVersion")) {
2324 DATA_BLOB blob;
2325 enum ndr_err_code ndr_err;
2326 struct spoolss_OSVersion os;
2327
2328 /*
2329 * Set the default OSVersion to:
2330 *
2331 * Windows Server 2003R2 SP2 (5.2.3790)
2332 *
2333 * used to be Windows 2000 (5.0.2195)
2334 */
2335 os.major = lp_parm_int(GLOBAL_SECTION_SNUM,
2336 "spoolss", "os_major",
2337 GLOBAL_SPOOLSS_OS_MAJOR_DEFAULT);
2338 os.minor = lp_parm_int(GLOBAL_SECTION_SNUM,
2339 "spoolss", "os_minor",
2340 GLOBAL_SPOOLSS_OS_MINOR_DEFAULT);
2341 os.build = lp_parm_int(GLOBAL_SECTION_SNUM,
2342 "spoolss", "os_build",
2343 GLOBAL_SPOOLSS_OS_BUILD_DEFAULT);
2344 os.extra_string = ""; /* leave extra string empty */
2345
2346 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os,
2347 (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2348 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2349 return WERR_GEN_FAILURE;
2350 }
2351
2352 if (DEBUGLEVEL >= 10) {
2353 NDR_PRINT_DEBUG(spoolss_OSVersion, &os);
2354 }
2355
2356 *type = REG_BINARY;
2357 data->binary = blob;
2358
2359 return WERR_OK;
2360 }
2361
2362
2363 if (!strcasecmp_m(value, "DefaultSpoolDirectory")) {
2364 *type = REG_SZ;
2365
2366 data->string = talloc_strdup(mem_ctx, SPOOLSS_DEFAULT_SERVER_PATH);
2367 W_ERROR_HAVE_NO_MEMORY(data->string);
2368
2369 return WERR_OK;
2370 }
2371
2372 if (!strcasecmp_m(value, "Architecture")) {
2373 *type = REG_SZ;
2374 data->string = talloc_strdup(mem_ctx,
2375 lp_parm_const_string(GLOBAL_SECTION_SNUM, "spoolss", "architecture", GLOBAL_SPOOLSS_ARCHITECTURE));
2376 W_ERROR_HAVE_NO_MEMORY(data->string);
2377
2378 return WERR_OK;
2379 }
2380
2381 if (!strcasecmp_m(value, "DsPresent")) {
2382 *type = REG_DWORD;
2383
2384 /* only show the publish check box if we are a
2385 member of a AD domain */
2386
2387 if (lp_security() == SEC_ADS) {
2388 SIVAL(&data->value, 0, 0x01);
2389 } else {
2390 SIVAL(&data->value, 0, 0x00);
2391 }
2392 return WERR_OK;
2393 }
2394
2395 if (!strcasecmp_m(value, "DNSMachineName")) {
2396 const char *hostname = get_mydnsfullname();
2397
2398 if (!hostname) {
2399 return WERR_FILE_NOT_FOUND;
2400 }
2401
2402 *type = REG_SZ;
2403 data->string = talloc_strdup(mem_ctx, hostname);
2404 W_ERROR_HAVE_NO_MEMORY(data->string);
2405
2406 return WERR_OK;
2407 }
2408
2409 *type = REG_NONE;
2410
2411 return WERR_INVALID_PARAMETER;
2412 }
2413
2414 /****************************************************************
2415 _spoolss_GetPrinterData
2416 ****************************************************************/
2417
_spoolss_GetPrinterData(struct pipes_struct * p,struct spoolss_GetPrinterData * r)2418 WERROR _spoolss_GetPrinterData(struct pipes_struct *p,
2419 struct spoolss_GetPrinterData *r)
2420 {
2421 struct spoolss_GetPrinterDataEx r2;
2422
2423 r2.in.handle = r->in.handle;
2424 r2.in.key_name = "PrinterDriverData";
2425 r2.in.value_name = r->in.value_name;
2426 r2.in.offered = r->in.offered;
2427 r2.out.type = r->out.type;
2428 r2.out.data = r->out.data;
2429 r2.out.needed = r->out.needed;
2430
2431 return _spoolss_GetPrinterDataEx(p, &r2);
2432 }
2433
2434 /*********************************************************
2435 Connect to the client machine.
2436 **********************************************************/
2437
spoolss_connect_to_client(struct rpc_pipe_client ** pp_pipe,struct cli_state ** pp_cli,struct sockaddr_storage * client_ss,const char * remote_machine)2438 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, struct cli_state **pp_cli,
2439 struct sockaddr_storage *client_ss, const char *remote_machine)
2440 {
2441 NTSTATUS ret;
2442 struct sockaddr_storage rm_addr;
2443 char addr[INET6_ADDRSTRLEN];
2444
2445 if ( is_zero_addr(client_ss) ) {
2446 DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
2447 remote_machine));
2448 if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2449 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2450 return false;
2451 }
2452 print_sockaddr(addr, sizeof(addr), &rm_addr);
2453 } else {
2454 rm_addr = *client_ss;
2455 print_sockaddr(addr, sizeof(addr), &rm_addr);
2456 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2457 addr));
2458 }
2459
2460 if (ismyaddr((struct sockaddr *)(void *)&rm_addr)) {
2461 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
2462 addr));
2463 return false;
2464 }
2465
2466 /* setup the connection */
2467 ret = cli_full_connection( pp_cli, lp_netbios_name(), remote_machine,
2468 &rm_addr, 0, "IPC$", "IPC",
2469 "", /* username */
2470 "", /* domain */
2471 "", /* password */
2472 0, lp_client_signing());
2473
2474 if ( !NT_STATUS_IS_OK( ret ) ) {
2475 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2476 remote_machine ));
2477 return false;
2478 }
2479
2480 if ( smbXcli_conn_protocol((*pp_cli)->conn) < PROTOCOL_NT1 ) {
2481 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2482 cli_shutdown(*pp_cli);
2483 return false;
2484 }
2485
2486 /*
2487 * Ok - we have an anonymous connection to the IPC$ share.
2488 * Now start the NT Domain stuff :-).
2489 */
2490
2491 ret = cli_rpc_pipe_open_noauth(*pp_cli, &ndr_table_spoolss, pp_pipe);
2492 if (!NT_STATUS_IS_OK(ret)) {
2493 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2494 remote_machine, nt_errstr(ret)));
2495 cli_shutdown(*pp_cli);
2496 return false;
2497 }
2498
2499 return true;
2500 }
2501
2502 /***************************************************************************
2503 Connect to the client.
2504 ****************************************************************************/
2505
srv_spoolss_replyopenprinter(int snum,const char * printer,uint32_t localprinter,enum winreg_Type type,struct policy_handle * handle,struct notify_back_channel ** _chan,struct sockaddr_storage * client_ss,struct messaging_context * msg_ctx)2506 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2507 uint32_t localprinter,
2508 enum winreg_Type type,
2509 struct policy_handle *handle,
2510 struct notify_back_channel **_chan,
2511 struct sockaddr_storage *client_ss,
2512 struct messaging_context *msg_ctx)
2513 {
2514 WERROR result;
2515 NTSTATUS status;
2516 struct notify_back_channel *chan;
2517
2518 for (chan = back_channels; chan; chan = chan->next) {
2519 if (memcmp(&chan->client_address, client_ss,
2520 sizeof(struct sockaddr_storage)) == 0) {
2521 break;
2522 }
2523 }
2524
2525 /*
2526 * If it's the first connection, contact the client
2527 * and connect to the IPC$ share anonymously
2528 */
2529 if (!chan) {
2530 fstring unix_printer;
2531
2532 /* the +2 is to strip the leading 2 backslashs */
2533 fstrcpy(unix_printer, printer + 2);
2534
2535 chan = talloc_zero(NULL, struct notify_back_channel);
2536 if (!chan) {
2537 return false;
2538 }
2539 chan->client_address = *client_ss;
2540
2541 if (!spoolss_connect_to_client(&chan->cli_pipe, &chan->cli, client_ss, unix_printer)) {
2542 TALLOC_FREE(chan);
2543 return false;
2544 }
2545
2546 DLIST_ADD(back_channels, chan);
2547
2548 messaging_register(msg_ctx, NULL, MSG_PRINTER_NOTIFY2,
2549 receive_notify2_message_list);
2550 }
2551
2552 if (chan->cli_pipe == NULL ||
2553 chan->cli_pipe->binding_handle == NULL) {
2554 DEBUG(0, ("srv_spoolss_replyopenprinter: error - "
2555 "NULL %s for printer %s\n",
2556 chan->cli_pipe == NULL ?
2557 "chan->cli_pipe" : "chan->cli_pipe->binding_handle",
2558 printer));
2559 return false;
2560 }
2561
2562 /*
2563 * Tell the specific printing tdb we want messages for this printer
2564 * by registering our PID.
2565 */
2566
2567 if (!print_notify_register_pid(snum)) {
2568 DEBUG(0, ("Failed to register our pid for printer %s\n",
2569 printer));
2570 }
2571
2572 status = dcerpc_spoolss_ReplyOpenPrinter(chan->cli_pipe->binding_handle,
2573 talloc_tos(),
2574 printer,
2575 localprinter,
2576 type,
2577 0,
2578 NULL,
2579 handle,
2580 &result);
2581 if (!NT_STATUS_IS_OK(status)) {
2582 DEBUG(5, ("dcerpc_spoolss_ReplyOpenPrinter returned [%s]\n", nt_errstr(status)));
2583 result = ntstatus_to_werror(status);
2584 } else if (!W_ERROR_IS_OK(result)) {
2585 DEBUG(5, ("ReplyOpenPrinter returned [%s]\n", win_errstr(result)));
2586 }
2587
2588 chan->active_connections++;
2589 *_chan = chan;
2590
2591 return (W_ERROR_IS_OK(result));
2592 }
2593
2594 /****************************************************************
2595 ****************************************************************/
2596
dup_spoolss_NotifyOption(TALLOC_CTX * mem_ctx,const struct spoolss_NotifyOption * r)2597 static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2598 const struct spoolss_NotifyOption *r)
2599 {
2600 struct spoolss_NotifyOption *option;
2601 uint32_t i,k;
2602
2603 if (!r) {
2604 return NULL;
2605 }
2606
2607 option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2608 if (!option) {
2609 return NULL;
2610 }
2611
2612 *option = *r;
2613
2614 if (!option->count) {
2615 return option;
2616 }
2617
2618 option->types = talloc_zero_array(option,
2619 struct spoolss_NotifyOptionType, option->count);
2620 if (!option->types) {
2621 talloc_free(option);
2622 return NULL;
2623 }
2624
2625 for (i=0; i < option->count; i++) {
2626 option->types[i] = r->types[i];
2627
2628 if (option->types[i].count) {
2629 option->types[i].fields = talloc_zero_array(option,
2630 union spoolss_Field, option->types[i].count);
2631 if (!option->types[i].fields) {
2632 talloc_free(option);
2633 return NULL;
2634 }
2635 for (k=0; k<option->types[i].count; k++) {
2636 option->types[i].fields[k] =
2637 r->types[i].fields[k];
2638 }
2639 }
2640 }
2641
2642 return option;
2643 }
2644
2645 /****************************************************************
2646 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2647 *
2648 * before replying OK: status=0 a rpc call is made to the workstation
2649 * asking ReplyOpenPrinter
2650 *
2651 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2652 * called from api_spoolss_rffpcnex
2653 ****************************************************************/
2654
_spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct pipes_struct * p,struct spoolss_RemoteFindFirstPrinterChangeNotifyEx * r)2655 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct pipes_struct *p,
2656 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2657 {
2658 int snum = -1;
2659 struct spoolss_NotifyOption *option = r->in.notify_options;
2660 struct sockaddr_storage client_ss;
2661 ssize_t client_len;
2662
2663 /* store the notify value in the printer struct */
2664
2665 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
2666
2667 if (!Printer) {
2668 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2669 "Invalid handle (%s:%u:%u).\n",
2670 OUR_HANDLE(r->in.handle)));
2671 return WERR_INVALID_HANDLE;
2672 }
2673
2674 Printer->notify.flags = r->in.flags;
2675 Printer->notify.options = r->in.options;
2676 Printer->notify.printerlocal = r->in.printer_local;
2677 Printer->notify.msg_ctx = p->msg_ctx;
2678
2679 TALLOC_FREE(Printer->notify.option);
2680 Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2681
2682 fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2683
2684 /* Connect to the client machine and send a ReplyOpenPrinter */
2685
2686 if ( Printer->printer_type == SPLHND_SERVER)
2687 snum = -1;
2688 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2689 !get_printer_snum(p, r->in.handle, &snum, NULL) )
2690 return WERR_INVALID_HANDLE;
2691
2692 DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2693 "remote_address is %s\n",
2694 tsocket_address_string(p->remote_address, p->mem_ctx)));
2695
2696 if (!lp_print_notify_backchannel(snum)) {
2697 DEBUG(10, ("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2698 "backchannel disabled\n"));
2699 return WERR_RPC_S_SERVER_UNAVAILABLE;
2700 }
2701
2702 client_len = tsocket_address_bsd_sockaddr(p->remote_address,
2703 (struct sockaddr *) &client_ss,
2704 sizeof(struct sockaddr_storage));
2705 if (client_len < 0) {
2706 return WERR_NOT_ENOUGH_MEMORY;
2707 }
2708
2709 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2710 Printer->notify.printerlocal, REG_SZ,
2711 &Printer->notify.cli_hnd,
2712 &Printer->notify.cli_chan,
2713 &client_ss, p->msg_ctx)) {
2714 return WERR_RPC_S_SERVER_UNAVAILABLE;
2715 }
2716
2717 return WERR_OK;
2718 }
2719
2720 /*******************************************************************
2721 * fill a notify_info_data with the servername
2722 ********************************************************************/
2723
spoolss_notify_server_name(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)2724 static void spoolss_notify_server_name(struct messaging_context *msg_ctx,
2725 int snum,
2726 struct spoolss_Notify *data,
2727 print_queue_struct *queue,
2728 struct spoolss_PrinterInfo2 *pinfo2,
2729 TALLOC_CTX *mem_ctx)
2730 {
2731 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->servername);
2732 }
2733
2734 /*******************************************************************
2735 * fill a notify_info_data with the printername (not including the servername).
2736 ********************************************************************/
2737
spoolss_notify_printer_name(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)2738 static void spoolss_notify_printer_name(struct messaging_context *msg_ctx,
2739 int snum,
2740 struct spoolss_Notify *data,
2741 print_queue_struct *queue,
2742 struct spoolss_PrinterInfo2 *pinfo2,
2743 TALLOC_CTX *mem_ctx)
2744 {
2745 /* the notify name should not contain the \\server\ part */
2746 const char *p = strrchr(pinfo2->printername, '\\');
2747
2748 if (!p) {
2749 p = pinfo2->printername;
2750 } else {
2751 p++;
2752 }
2753
2754 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2755 }
2756
2757 /*******************************************************************
2758 * fill a notify_info_data with the servicename
2759 ********************************************************************/
2760
spoolss_notify_share_name(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)2761 static void spoolss_notify_share_name(struct messaging_context *msg_ctx,
2762 int snum,
2763 struct spoolss_Notify *data,
2764 print_queue_struct *queue,
2765 struct spoolss_PrinterInfo2 *pinfo2,
2766 TALLOC_CTX *mem_ctx)
2767 {
2768 const struct loadparm_substitution *lp_sub =
2769 loadparm_s3_global_substitution();
2770
2771 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(talloc_tos(), lp_sub, snum));
2772 }
2773
2774 /*******************************************************************
2775 * fill a notify_info_data with the port name
2776 ********************************************************************/
2777
spoolss_notify_port_name(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)2778 static void spoolss_notify_port_name(struct messaging_context *msg_ctx,
2779 int snum,
2780 struct spoolss_Notify *data,
2781 print_queue_struct *queue,
2782 struct spoolss_PrinterInfo2 *pinfo2,
2783 TALLOC_CTX *mem_ctx)
2784 {
2785 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->portname);
2786 }
2787
2788 /*******************************************************************
2789 * fill a notify_info_data with the printername
2790 * but it doesn't exist, have to see what to do
2791 ********************************************************************/
2792
spoolss_notify_driver_name(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)2793 static void spoolss_notify_driver_name(struct messaging_context *msg_ctx,
2794 int snum,
2795 struct spoolss_Notify *data,
2796 print_queue_struct *queue,
2797 struct spoolss_PrinterInfo2 *pinfo2,
2798 TALLOC_CTX *mem_ctx)
2799 {
2800 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->drivername);
2801 }
2802
2803 /*******************************************************************
2804 * fill a notify_info_data with the comment
2805 ********************************************************************/
2806
spoolss_notify_comment(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)2807 static void spoolss_notify_comment(struct messaging_context *msg_ctx,
2808 int snum,
2809 struct spoolss_Notify *data,
2810 print_queue_struct *queue,
2811 struct spoolss_PrinterInfo2 *pinfo2,
2812 TALLOC_CTX *mem_ctx)
2813 {
2814 const struct loadparm_substitution *lp_sub =
2815 loadparm_s3_global_substitution();
2816 const char *p;
2817
2818 if (*pinfo2->comment == '\0') {
2819 p = lp_comment(talloc_tos(), lp_sub, snum);
2820 } else {
2821 p = pinfo2->comment;
2822 }
2823
2824 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2825 }
2826
2827 /*******************************************************************
2828 * fill a notify_info_data with the comment
2829 * location = "Room 1, floor 2, building 3"
2830 ********************************************************************/
2831
spoolss_notify_location(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)2832 static void spoolss_notify_location(struct messaging_context *msg_ctx,
2833 int snum,
2834 struct spoolss_Notify *data,
2835 print_queue_struct *queue,
2836 struct spoolss_PrinterInfo2 *pinfo2,
2837 TALLOC_CTX *mem_ctx)
2838 {
2839 const char *loc = pinfo2->location;
2840 NTSTATUS status;
2841
2842 status = printer_list_get_printer(mem_ctx,
2843 pinfo2->sharename,
2844 NULL,
2845 &loc,
2846 NULL);
2847 if (NT_STATUS_IS_OK(status)) {
2848 if (loc == NULL) {
2849 loc = pinfo2->location;
2850 }
2851 }
2852
2853 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, loc);
2854 }
2855
2856 /*******************************************************************
2857 * fill a notify_info_data with the device mode
2858 * jfm:xxxx don't to it for know but that's a real problem !!!
2859 ********************************************************************/
2860
spoolss_notify_devmode(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)2861 static void spoolss_notify_devmode(struct messaging_context *msg_ctx,
2862 int snum,
2863 struct spoolss_Notify *data,
2864 print_queue_struct *queue,
2865 struct spoolss_PrinterInfo2 *pinfo2,
2866 TALLOC_CTX *mem_ctx)
2867 {
2868 /* for a dummy implementation we have to zero the fields */
2869 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2870 }
2871
2872 /*******************************************************************
2873 * fill a notify_info_data with the separator file name
2874 ********************************************************************/
2875
spoolss_notify_sepfile(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)2876 static void spoolss_notify_sepfile(struct messaging_context *msg_ctx,
2877 int snum,
2878 struct spoolss_Notify *data,
2879 print_queue_struct *queue,
2880 struct spoolss_PrinterInfo2 *pinfo2,
2881 TALLOC_CTX *mem_ctx)
2882 {
2883 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->sepfile);
2884 }
2885
2886 /*******************************************************************
2887 * fill a notify_info_data with the print processor
2888 * jfm:xxxx return always winprint to indicate we don't do anything to it
2889 ********************************************************************/
2890
spoolss_notify_print_processor(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)2891 static void spoolss_notify_print_processor(struct messaging_context *msg_ctx,
2892 int snum,
2893 struct spoolss_Notify *data,
2894 print_queue_struct *queue,
2895 struct spoolss_PrinterInfo2 *pinfo2,
2896 TALLOC_CTX *mem_ctx)
2897 {
2898 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->printprocessor);
2899 }
2900
2901 /*******************************************************************
2902 * fill a notify_info_data with the print processor options
2903 * jfm:xxxx send an empty string
2904 ********************************************************************/
2905
spoolss_notify_parameters(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)2906 static void spoolss_notify_parameters(struct messaging_context *msg_ctx,
2907 int snum,
2908 struct spoolss_Notify *data,
2909 print_queue_struct *queue,
2910 struct spoolss_PrinterInfo2 *pinfo2,
2911 TALLOC_CTX *mem_ctx)
2912 {
2913 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->parameters);
2914 }
2915
2916 /*******************************************************************
2917 * fill a notify_info_data with the data type
2918 * jfm:xxxx always send RAW as data type
2919 ********************************************************************/
2920
spoolss_notify_datatype(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)2921 static void spoolss_notify_datatype(struct messaging_context *msg_ctx,
2922 int snum,
2923 struct spoolss_Notify *data,
2924 print_queue_struct *queue,
2925 struct spoolss_PrinterInfo2 *pinfo2,
2926 TALLOC_CTX *mem_ctx)
2927 {
2928 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->datatype);
2929 }
2930
2931 /*******************************************************************
2932 * fill a notify_info_data with the security descriptor
2933 * jfm:xxxx send an null pointer to say no security desc
2934 * have to implement security before !
2935 ********************************************************************/
2936
spoolss_notify_security_desc(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)2937 static void spoolss_notify_security_desc(struct messaging_context *msg_ctx,
2938 int snum,
2939 struct spoolss_Notify *data,
2940 print_queue_struct *queue,
2941 struct spoolss_PrinterInfo2 *pinfo2,
2942 TALLOC_CTX *mem_ctx)
2943 {
2944 if (pinfo2->secdesc == NULL) {
2945 data->data.sd.sd = NULL;
2946 } else {
2947 data->data.sd.sd = security_descriptor_copy(mem_ctx,
2948 pinfo2->secdesc);
2949 }
2950 data->data.sd.sd_size = ndr_size_security_descriptor(data->data.sd.sd,
2951 0);
2952 }
2953
2954 /*******************************************************************
2955 * fill a notify_info_data with the attributes
2956 * jfm:xxxx a samba printer is always shared
2957 ********************************************************************/
2958
spoolss_notify_attributes(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)2959 static void spoolss_notify_attributes(struct messaging_context *msg_ctx,
2960 int snum,
2961 struct spoolss_Notify *data,
2962 print_queue_struct *queue,
2963 struct spoolss_PrinterInfo2 *pinfo2,
2964 TALLOC_CTX *mem_ctx)
2965 {
2966 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->attributes);
2967 }
2968
2969 /*******************************************************************
2970 * fill a notify_info_data with the priority
2971 ********************************************************************/
2972
spoolss_notify_priority(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)2973 static void spoolss_notify_priority(struct messaging_context *msg_ctx,
2974 int snum,
2975 struct spoolss_Notify *data,
2976 print_queue_struct *queue,
2977 struct spoolss_PrinterInfo2 *pinfo2,
2978 TALLOC_CTX *mem_ctx)
2979 {
2980 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->priority);
2981 }
2982
2983 /*******************************************************************
2984 * fill a notify_info_data with the default priority
2985 ********************************************************************/
2986
spoolss_notify_default_priority(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)2987 static void spoolss_notify_default_priority(struct messaging_context *msg_ctx,
2988 int snum,
2989 struct spoolss_Notify *data,
2990 print_queue_struct *queue,
2991 struct spoolss_PrinterInfo2 *pinfo2,
2992 TALLOC_CTX *mem_ctx)
2993 {
2994 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->defaultpriority);
2995 }
2996
2997 /*******************************************************************
2998 * fill a notify_info_data with the start time
2999 ********************************************************************/
3000
spoolss_notify_start_time(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)3001 static void spoolss_notify_start_time(struct messaging_context *msg_ctx,
3002 int snum,
3003 struct spoolss_Notify *data,
3004 print_queue_struct *queue,
3005 struct spoolss_PrinterInfo2 *pinfo2,
3006 TALLOC_CTX *mem_ctx)
3007 {
3008 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->starttime);
3009 }
3010
3011 /*******************************************************************
3012 * fill a notify_info_data with the until time
3013 ********************************************************************/
3014
spoolss_notify_until_time(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)3015 static void spoolss_notify_until_time(struct messaging_context *msg_ctx,
3016 int snum,
3017 struct spoolss_Notify *data,
3018 print_queue_struct *queue,
3019 struct spoolss_PrinterInfo2 *pinfo2,
3020 TALLOC_CTX *mem_ctx)
3021 {
3022 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->untiltime);
3023 }
3024
3025 /*******************************************************************
3026 * fill a notify_info_data with the status
3027 ********************************************************************/
3028
spoolss_notify_status(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)3029 static void spoolss_notify_status(struct messaging_context *msg_ctx,
3030 int snum,
3031 struct spoolss_Notify *data,
3032 print_queue_struct *queue,
3033 struct spoolss_PrinterInfo2 *pinfo2,
3034 TALLOC_CTX *mem_ctx)
3035 {
3036 print_status_struct status;
3037
3038 print_queue_length(msg_ctx, snum, &status);
3039 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
3040 }
3041
3042 /*******************************************************************
3043 * fill a notify_info_data with the number of jobs queued
3044 ********************************************************************/
3045
spoolss_notify_cjobs(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)3046 static void spoolss_notify_cjobs(struct messaging_context *msg_ctx,
3047 int snum,
3048 struct spoolss_Notify *data,
3049 print_queue_struct *queue,
3050 struct spoolss_PrinterInfo2 *pinfo2,
3051 TALLOC_CTX *mem_ctx)
3052 {
3053 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(
3054 data, print_queue_length(msg_ctx, snum, NULL));
3055 }
3056
3057 /*******************************************************************
3058 * fill a notify_info_data with the average ppm
3059 ********************************************************************/
3060
spoolss_notify_average_ppm(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)3061 static void spoolss_notify_average_ppm(struct messaging_context *msg_ctx,
3062 int snum,
3063 struct spoolss_Notify *data,
3064 print_queue_struct *queue,
3065 struct spoolss_PrinterInfo2 *pinfo2,
3066 TALLOC_CTX *mem_ctx)
3067 {
3068 /* always respond 8 pages per minutes */
3069 /* a little hard ! */
3070 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->averageppm);
3071 }
3072
3073 /*******************************************************************
3074 * fill a notify_info_data with username
3075 ********************************************************************/
3076
spoolss_notify_username(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)3077 static void spoolss_notify_username(struct messaging_context *msg_ctx,
3078 int snum,
3079 struct spoolss_Notify *data,
3080 print_queue_struct *queue,
3081 struct spoolss_PrinterInfo2 *pinfo2,
3082 TALLOC_CTX *mem_ctx)
3083 {
3084 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
3085 }
3086
3087 /*******************************************************************
3088 * fill a notify_info_data with job status
3089 ********************************************************************/
3090
spoolss_notify_job_status(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)3091 static void spoolss_notify_job_status(struct messaging_context *msg_ctx,
3092 int snum,
3093 struct spoolss_Notify *data,
3094 print_queue_struct *queue,
3095 struct spoolss_PrinterInfo2 *pinfo2,
3096 TALLOC_CTX *mem_ctx)
3097 {
3098 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
3099 }
3100
3101 /*******************************************************************
3102 * fill a notify_info_data with job name
3103 ********************************************************************/
3104
spoolss_notify_job_name(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)3105 static void spoolss_notify_job_name(struct messaging_context *msg_ctx,
3106 int snum,
3107 struct spoolss_Notify *data,
3108 print_queue_struct *queue,
3109 struct spoolss_PrinterInfo2 *pinfo2,
3110 TALLOC_CTX *mem_ctx)
3111 {
3112 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
3113 }
3114
3115 /*******************************************************************
3116 * fill a notify_info_data with job status
3117 ********************************************************************/
3118
spoolss_notify_job_status_string(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)3119 static void spoolss_notify_job_status_string(struct messaging_context *msg_ctx,
3120 int snum,
3121 struct spoolss_Notify *data,
3122 print_queue_struct *queue,
3123 struct spoolss_PrinterInfo2 *pinfo2,
3124 TALLOC_CTX *mem_ctx)
3125 {
3126 /*
3127 * Now we're returning job status codes we just return a "" here. JRA.
3128 */
3129
3130 const char *p = "";
3131
3132 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
3133 p = "unknown";
3134
3135 switch (queue->status) {
3136 case LPQ_QUEUED:
3137 p = "Queued";
3138 break;
3139 case LPQ_PAUSED:
3140 p = ""; /* NT provides the paused string */
3141 break;
3142 case LPQ_SPOOLING:
3143 p = "Spooling";
3144 break;
3145 case LPQ_PRINTING:
3146 p = "Printing";
3147 break;
3148 }
3149 #endif /* NO LONGER NEEDED. */
3150
3151 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
3152 }
3153
3154 /*******************************************************************
3155 * fill a notify_info_data with job time
3156 ********************************************************************/
3157
spoolss_notify_job_time(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)3158 static void spoolss_notify_job_time(struct messaging_context *msg_ctx,
3159 int snum,
3160 struct spoolss_Notify *data,
3161 print_queue_struct *queue,
3162 struct spoolss_PrinterInfo2 *pinfo2,
3163 TALLOC_CTX *mem_ctx)
3164 {
3165 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3166 }
3167
3168 /*******************************************************************
3169 * fill a notify_info_data with job size
3170 ********************************************************************/
3171
spoolss_notify_job_size(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)3172 static void spoolss_notify_job_size(struct messaging_context *msg_ctx,
3173 int snum,
3174 struct spoolss_Notify *data,
3175 print_queue_struct *queue,
3176 struct spoolss_PrinterInfo2 *pinfo2,
3177 TALLOC_CTX *mem_ctx)
3178 {
3179 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
3180 }
3181
3182 /*******************************************************************
3183 * fill a notify_info_data with page info
3184 ********************************************************************/
spoolss_notify_total_pages(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)3185 static void spoolss_notify_total_pages(struct messaging_context *msg_ctx,
3186 int snum,
3187 struct spoolss_Notify *data,
3188 print_queue_struct *queue,
3189 struct spoolss_PrinterInfo2 *pinfo2,
3190 TALLOC_CTX *mem_ctx)
3191 {
3192 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
3193 }
3194
3195 /*******************************************************************
3196 * fill a notify_info_data with pages printed info.
3197 ********************************************************************/
spoolss_notify_pages_printed(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)3198 static void spoolss_notify_pages_printed(struct messaging_context *msg_ctx,
3199 int snum,
3200 struct spoolss_Notify *data,
3201 print_queue_struct *queue,
3202 struct spoolss_PrinterInfo2 *pinfo2,
3203 TALLOC_CTX *mem_ctx)
3204 {
3205 /* Add code when back-end tracks this */
3206 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3207 }
3208
3209 /*******************************************************************
3210 Fill a notify_info_data with job position.
3211 ********************************************************************/
3212
spoolss_notify_job_position(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)3213 static void spoolss_notify_job_position(struct messaging_context *msg_ctx,
3214 int snum,
3215 struct spoolss_Notify *data,
3216 print_queue_struct *queue,
3217 struct spoolss_PrinterInfo2 *pinfo2,
3218 TALLOC_CTX *mem_ctx)
3219 {
3220 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->sysjob);
3221 }
3222
3223 /*******************************************************************
3224 Fill a notify_info_data with submitted time.
3225 ********************************************************************/
3226
spoolss_notify_submitted_time(struct messaging_context * msg_ctx,int snum,struct spoolss_Notify * data,print_queue_struct * queue,struct spoolss_PrinterInfo2 * pinfo2,TALLOC_CTX * mem_ctx)3227 static void spoolss_notify_submitted_time(struct messaging_context *msg_ctx,
3228 int snum,
3229 struct spoolss_Notify *data,
3230 print_queue_struct *queue,
3231 struct spoolss_PrinterInfo2 *pinfo2,
3232 TALLOC_CTX *mem_ctx)
3233 {
3234 data->data.string.string = NULL;
3235 data->data.string.size = 0;
3236
3237 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
3238 &data->data.string.string,
3239 &data->data.string.size);
3240
3241 }
3242
3243 struct s_notify_info_data_table
3244 {
3245 enum spoolss_NotifyType type;
3246 uint16_t field;
3247 const char *name;
3248 enum spoolss_NotifyTable variable_type;
3249 void (*fn) (struct messaging_context *msg_ctx,
3250 int snum, struct spoolss_Notify *data,
3251 print_queue_struct *queue,
3252 struct spoolss_PrinterInfo2 *pinfo2,
3253 TALLOC_CTX *mem_ctx);
3254 };
3255
3256 /* A table describing the various print notification constants and
3257 whether the notification data is a pointer to a variable sized
3258 buffer, a one value uint32_t or a two value uint32_t. */
3259
3260 static const struct s_notify_info_data_table notify_info_data_table[] =
3261 {
3262 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3263 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3264 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
3265 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3266 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3267 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
3268 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
3269 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3270 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
3271 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3272 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3273 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3274 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
3275 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
3276 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3277 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
3278 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3279 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3280 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
3281 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
3282 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
3283 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
3284 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
3285 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3286 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
3287 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3288 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINTER_NAME, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3289 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_MACHINE_NAME, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3290 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PORT_NAME, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3291 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3292 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_NOTIFY_NAME, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3293 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DATATYPE, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3294 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINT_PROCESSOR, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3295 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PARAMETERS, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3296 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DRIVER_NAME, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3297 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DEVMODE, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3298 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
3299 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS_STRING, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
3300 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
3301 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
3302 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRIORITY, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3303 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_POSITION, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
3304 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
3305 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_START_TIME, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3306 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_UNTIL_TIME, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3307 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TIME, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
3308 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_PAGES, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
3309 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PAGES_PRINTED, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
3310 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_BYTES, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
3311 };
3312
3313 /*******************************************************************
3314 Return the variable_type of info_data structure.
3315 ********************************************************************/
3316
variable_type_of_notify_info_data(enum spoolss_NotifyType type,uint16_t field)3317 static enum spoolss_NotifyTable variable_type_of_notify_info_data(enum spoolss_NotifyType type,
3318 uint16_t field)
3319 {
3320 int i=0;
3321
3322 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3323 if ( (notify_info_data_table[i].type == type) &&
3324 (notify_info_data_table[i].field == field) ) {
3325 return notify_info_data_table[i].variable_type;
3326 }
3327 }
3328
3329 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3330
3331 return (enum spoolss_NotifyTable) 0;
3332 }
3333
3334 /****************************************************************************
3335 ****************************************************************************/
3336
search_notify(enum spoolss_NotifyType type,uint16_t field,int * value)3337 static bool search_notify(enum spoolss_NotifyType type,
3338 uint16_t field,
3339 int *value)
3340 {
3341 int i;
3342
3343 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3344 if (notify_info_data_table[i].type == type &&
3345 notify_info_data_table[i].field == field &&
3346 notify_info_data_table[i].fn != NULL) {
3347 *value = i;
3348 return true;
3349 }
3350 }
3351
3352 return false;
3353 }
3354
3355 /****************************************************************************
3356 ****************************************************************************/
3357
construct_info_data(struct spoolss_Notify * info_data,enum spoolss_NotifyType type,uint16_t field,int id)3358 static void construct_info_data(struct spoolss_Notify *info_data,
3359 enum spoolss_NotifyType type,
3360 uint16_t field, int id)
3361 {
3362 info_data->type = type;
3363 info_data->field.field = field;
3364 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3365 info_data->job_id = id;
3366 }
3367
3368 /*******************************************************************
3369 *
3370 * fill a notify_info struct with info asked
3371 *
3372 ********************************************************************/
3373
construct_notify_printer_info(struct messaging_context * msg_ctx,struct printer_handle * print_hnd,struct spoolss_NotifyInfo * info,struct spoolss_PrinterInfo2 * pinfo2,int snum,const struct spoolss_NotifyOptionType * option_type,uint32_t id,TALLOC_CTX * mem_ctx)3374 static bool construct_notify_printer_info(struct messaging_context *msg_ctx,
3375 struct printer_handle *print_hnd,
3376 struct spoolss_NotifyInfo *info,
3377 struct spoolss_PrinterInfo2 *pinfo2,
3378 int snum,
3379 const struct spoolss_NotifyOptionType *option_type,
3380 uint32_t id,
3381 TALLOC_CTX *mem_ctx)
3382 {
3383 const struct loadparm_substitution *lp_sub =
3384 loadparm_s3_global_substitution();
3385 int field_num,j;
3386 enum spoolss_NotifyType type;
3387 uint16_t field;
3388
3389 struct spoolss_Notify *current_data;
3390
3391 type = option_type->type;
3392
3393 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3394 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3395 option_type->count, lp_servicename(talloc_tos(), lp_sub, snum)));
3396
3397 for(field_num=0; field_num < option_type->count; field_num++) {
3398 field = option_type->fields[field_num].field;
3399
3400 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3401
3402 if (!search_notify(type, field, &j) )
3403 continue;
3404
3405 info->notifies = talloc_realloc(info, info->notifies,
3406 struct spoolss_Notify,
3407 info->count + 1);
3408 if (info->notifies == NULL) {
3409 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3410 return false;
3411 }
3412
3413 current_data = &info->notifies[info->count];
3414
3415 construct_info_data(current_data, type, field, id);
3416
3417 DEBUG(10, ("construct_notify_printer_info: "
3418 "calling [%s] snum=%d printername=[%s])\n",
3419 notify_info_data_table[j].name, snum,
3420 pinfo2->printername));
3421
3422 notify_info_data_table[j].fn(msg_ctx, snum, current_data,
3423 NULL, pinfo2, mem_ctx);
3424
3425 info->count++;
3426 }
3427
3428 return true;
3429 }
3430
3431 /*******************************************************************
3432 *
3433 * fill a notify_info struct with info asked
3434 *
3435 ********************************************************************/
3436
construct_notify_jobs_info(struct messaging_context * msg_ctx,print_queue_struct * queue,struct spoolss_NotifyInfo * info,struct spoolss_PrinterInfo2 * pinfo2,int snum,const struct spoolss_NotifyOptionType * option_type,uint32_t id,TALLOC_CTX * mem_ctx)3437 static bool construct_notify_jobs_info(struct messaging_context *msg_ctx,
3438 print_queue_struct *queue,
3439 struct spoolss_NotifyInfo *info,
3440 struct spoolss_PrinterInfo2 *pinfo2,
3441 int snum,
3442 const struct spoolss_NotifyOptionType *option_type,
3443 uint32_t id,
3444 TALLOC_CTX *mem_ctx)
3445 {
3446 int field_num,j;
3447 enum spoolss_NotifyType type;
3448 uint16_t field;
3449 struct spoolss_Notify *current_data;
3450
3451 DEBUG(4,("construct_notify_jobs_info\n"));
3452
3453 type = option_type->type;
3454
3455 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3456 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3457 option_type->count));
3458
3459 for(field_num=0; field_num<option_type->count; field_num++) {
3460 field = option_type->fields[field_num].field;
3461
3462 if (!search_notify(type, field, &j) )
3463 continue;
3464
3465 info->notifies = talloc_realloc(info, info->notifies,
3466 struct spoolss_Notify,
3467 info->count + 1);
3468 if (info->notifies == NULL) {
3469 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3470 return false;
3471 }
3472
3473 current_data=&(info->notifies[info->count]);
3474
3475 construct_info_data(current_data, type, field, id);
3476 notify_info_data_table[j].fn(msg_ctx, snum, current_data,
3477 queue, pinfo2, mem_ctx);
3478 info->count++;
3479 }
3480
3481 return true;
3482 }
3483
3484 /*
3485 * JFM: The enumeration is not that simple, it's even non obvious.
3486 *
3487 * let's take an example: I want to monitor the PRINTER SERVER for
3488 * the printer's name and the number of jobs currently queued.
3489 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3490 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3491 *
3492 * I have 3 printers on the back of my server.
3493 *
3494 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3495 * structures.
3496 * Number Data Id
3497 * 1 printer 1 name 1
3498 * 2 printer 1 cjob 1
3499 * 3 printer 2 name 2
3500 * 4 printer 2 cjob 2
3501 * 5 printer 3 name 3
3502 * 6 printer 3 name 3
3503 *
3504 * that's the print server case, the printer case is even worse.
3505 */
3506
3507 /*******************************************************************
3508 *
3509 * enumerate all printers on the printserver
3510 * fill a notify_info struct with info asked
3511 *
3512 ********************************************************************/
3513
printserver_notify_info(struct pipes_struct * p,struct policy_handle * hnd,struct spoolss_NotifyInfo * info,TALLOC_CTX * mem_ctx)3514 static WERROR printserver_notify_info(struct pipes_struct *p,
3515 struct policy_handle *hnd,
3516 struct spoolss_NotifyInfo *info,
3517 TALLOC_CTX *mem_ctx)
3518 {
3519 const struct loadparm_substitution *lp_sub =
3520 loadparm_s3_global_substitution();
3521 int snum;
3522 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
3523 int n_services=lp_numservices();
3524 int i;
3525 struct spoolss_NotifyOption *option;
3526 struct spoolss_NotifyOptionType option_type;
3527 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3528 WERROR result;
3529
3530 DEBUG(4,("printserver_notify_info\n"));
3531
3532 if (!Printer)
3533 return WERR_INVALID_HANDLE;
3534
3535 option = Printer->notify.option;
3536
3537 info->version = 2;
3538 info->notifies = NULL;
3539 info->count = 0;
3540
3541 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3542 sending a ffpcn() request first */
3543
3544 if ( !option )
3545 return WERR_INVALID_HANDLE;
3546
3547 for (i=0; i<option->count; i++) {
3548 option_type = option->types[i];
3549
3550 if (option_type.type != PRINTER_NOTIFY_TYPE)
3551 continue;
3552
3553 for (snum = 0; snum < n_services; snum++) {
3554 if (!lp_browseable(snum) ||
3555 !lp_snum_ok(snum) ||
3556 !lp_printable(snum)) {
3557 continue; /* skip */
3558 }
3559
3560 /* Maybe we should use the SYSTEM session_info here... */
3561 result = winreg_get_printer_internal(mem_ctx,
3562 get_session_info_system(),
3563 p->msg_ctx,
3564 lp_servicename(talloc_tos(), lp_sub, snum),
3565 &pinfo2);
3566 if (!W_ERROR_IS_OK(result)) {
3567 DEBUG(4, ("printserver_notify_info: "
3568 "Failed to get printer [%s]\n",
3569 lp_servicename(talloc_tos(), lp_sub, snum)));
3570 continue;
3571 }
3572
3573
3574 construct_notify_printer_info(p->msg_ctx,
3575 Printer, info,
3576 pinfo2, snum,
3577 &option_type, snum,
3578 mem_ctx);
3579
3580 TALLOC_FREE(pinfo2);
3581 }
3582 }
3583
3584 #if 0
3585 /*
3586 * Debugging information, don't delete.
3587 */
3588
3589 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3590 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3591 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3592
3593 for (i=0; i<info->count; i++) {
3594 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3595 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3596 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3597 }
3598 #endif
3599
3600 return WERR_OK;
3601 }
3602
3603 /*******************************************************************
3604 *
3605 * fill a notify_info struct with info asked
3606 *
3607 ********************************************************************/
3608
printer_notify_info(struct pipes_struct * p,struct policy_handle * hnd,struct spoolss_NotifyInfo * info,TALLOC_CTX * mem_ctx)3609 static WERROR printer_notify_info(struct pipes_struct *p,
3610 struct policy_handle *hnd,
3611 struct spoolss_NotifyInfo *info,
3612 TALLOC_CTX *mem_ctx)
3613 {
3614 const struct loadparm_substitution *lp_sub =
3615 loadparm_s3_global_substitution();
3616 int snum;
3617 struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
3618 int i;
3619 uint32_t id;
3620 struct spoolss_NotifyOption *option;
3621 struct spoolss_NotifyOptionType option_type;
3622 int count,j;
3623 print_queue_struct *queue=NULL;
3624 print_status_struct status;
3625 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3626 WERROR result;
3627 struct tdb_print_db *pdb;
3628
3629 DEBUG(4,("printer_notify_info\n"));
3630
3631 if (!Printer)
3632 return WERR_INVALID_HANDLE;
3633
3634 option = Printer->notify.option;
3635 id = 0x0;
3636
3637 info->version = 2;
3638 info->notifies = NULL;
3639 info->count = 0;
3640
3641 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3642 sending a ffpcn() request first */
3643
3644 if ( !option )
3645 return WERR_INVALID_HANDLE;
3646
3647 if (!get_printer_snum(p, hnd, &snum, NULL)) {
3648 return WERR_INVALID_HANDLE;
3649 }
3650
3651 pdb = get_print_db_byname(Printer->sharename);
3652 if (pdb == NULL) {
3653 return WERR_INVALID_HANDLE;
3654 }
3655
3656 /* Maybe we should use the SYSTEM session_info here... */
3657 result = winreg_get_printer_internal(mem_ctx,
3658 get_session_info_system(),
3659 p->msg_ctx,
3660 lp_servicename(talloc_tos(), lp_sub, snum), &pinfo2);
3661 if (!W_ERROR_IS_OK(result)) {
3662 result = WERR_INVALID_HANDLE;
3663 goto err_pdb_drop;
3664 }
3665
3666 /*
3667 * When sending a PRINTER_NOTIFY_FIELD_SERVER_NAME we should send the
3668 * correct servername.
3669 */
3670 pinfo2->servername = talloc_strdup(pinfo2, Printer->servername);
3671 if (pinfo2->servername == NULL) {
3672 result = WERR_NOT_ENOUGH_MEMORY;
3673 goto err_pdb_drop;
3674 }
3675
3676 for (i = 0; i < option->count; i++) {
3677 option_type = option->types[i];
3678
3679 switch (option_type.type) {
3680 case PRINTER_NOTIFY_TYPE:
3681 if (construct_notify_printer_info(p->msg_ctx,
3682 Printer, info,
3683 pinfo2, snum,
3684 &option_type, id,
3685 mem_ctx)) {
3686 id--;
3687 }
3688 break;
3689
3690 case JOB_NOTIFY_TYPE:
3691
3692 count = print_queue_status(p->msg_ctx, snum, &queue,
3693 &status);
3694
3695 for (j = 0; j < count; j++) {
3696 uint32_t jobid;
3697 jobid = sysjob_to_jobid_pdb(pdb,
3698 queue[j].sysjob);
3699 if (jobid == (uint32_t)-1) {
3700 DEBUG(2, ("ignoring untracked job %d\n",
3701 queue[j].sysjob));
3702 continue;
3703 }
3704 /* FIXME check return value */
3705 construct_notify_jobs_info(p->msg_ctx,
3706 &queue[j], info,
3707 pinfo2, snum,
3708 &option_type,
3709 jobid,
3710 mem_ctx);
3711 }
3712
3713 SAFE_FREE(queue);
3714 break;
3715 }
3716 }
3717
3718 /*
3719 * Debugging information, don't delete.
3720 */
3721 /*
3722 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3723 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3724 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3725
3726 for (i=0; i<info->count; i++) {
3727 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3728 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3729 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3730 }
3731 */
3732
3733 talloc_free(pinfo2);
3734 result = WERR_OK;
3735 err_pdb_drop:
3736 release_print_db(pdb);
3737 return result;
3738 }
3739
3740 /****************************************************************
3741 _spoolss_RouterRefreshPrinterChangeNotify
3742 ****************************************************************/
3743
_spoolss_RouterRefreshPrinterChangeNotify(struct pipes_struct * p,struct spoolss_RouterRefreshPrinterChangeNotify * r)3744 WERROR _spoolss_RouterRefreshPrinterChangeNotify(struct pipes_struct *p,
3745 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3746 {
3747 struct spoolss_NotifyInfo *info;
3748
3749 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
3750 WERROR result = WERR_INVALID_HANDLE;
3751
3752 /* we always have a spoolss_NotifyInfo struct */
3753 info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3754 if (!info) {
3755 result = WERR_NOT_ENOUGH_MEMORY;
3756 goto done;
3757 }
3758
3759 *r->out.info = info;
3760
3761 if (!Printer) {
3762 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3763 "Invalid handle (%s:%u:%u).\n",
3764 OUR_HANDLE(r->in.handle)));
3765 goto done;
3766 }
3767
3768 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3769
3770 /*
3771 * We are now using the change value, and
3772 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3773 * I don't have a global notification system, I'm sending back all the
3774 * information even when _NOTHING_ has changed.
3775 */
3776
3777 /* We need to keep track of the change value to send back in
3778 RRPCN replies otherwise our updates are ignored. */
3779
3780 Printer->notify.fnpcn = true;
3781
3782 if (Printer->notify.cli_chan != NULL &&
3783 Printer->notify.cli_chan->active_connections > 0) {
3784 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3785 "Saving change value in request [%x]\n",
3786 r->in.change_low));
3787 Printer->notify.change = r->in.change_low;
3788 }
3789
3790 /* just ignore the spoolss_NotifyOption */
3791
3792 switch (Printer->printer_type) {
3793 case SPLHND_SERVER:
3794 result = printserver_notify_info(p, r->in.handle,
3795 info, p->mem_ctx);
3796 break;
3797
3798 case SPLHND_PRINTER:
3799 result = printer_notify_info(p, r->in.handle,
3800 info, p->mem_ctx);
3801 break;
3802 }
3803
3804 Printer->notify.fnpcn = false;
3805
3806 done:
3807 return result;
3808 }
3809
3810 /********************************************************************
3811 ********************************************************************/
3812
create_printername(TALLOC_CTX * mem_ctx,const char * servername,const char * printername,const char ** printername_p)3813 static WERROR create_printername(TALLOC_CTX *mem_ctx,
3814 const char *servername,
3815 const char *printername,
3816 const char **printername_p)
3817 {
3818 /* FIXME: add lp_force_printername() */
3819
3820 if (servername == NULL) {
3821 *printername_p = talloc_strdup(mem_ctx, printername);
3822 W_ERROR_HAVE_NO_MEMORY(*printername_p);
3823 return WERR_OK;
3824 }
3825
3826 if (servername[0] == '\\' && servername[1] == '\\') {
3827 servername += 2;
3828 }
3829
3830 *printername_p = talloc_asprintf(mem_ctx, "\\\\%s\\%s", servername, printername);
3831 W_ERROR_HAVE_NO_MEMORY(*printername_p);
3832
3833 return WERR_OK;
3834 }
3835
3836 /********************************************************************
3837 ********************************************************************/
3838
compose_devicemode_devicename(struct spoolss_DeviceMode * dm,const char * printername)3839 static void compose_devicemode_devicename(struct spoolss_DeviceMode *dm,
3840 const char *printername)
3841 {
3842 if (dm == NULL) {
3843 return;
3844 }
3845
3846 dm->devicename = talloc_strndup(dm, printername,
3847 MIN(strlen(printername), 31));
3848 }
3849
3850 /********************************************************************
3851 * construct_printer_info_0
3852 * fill a printer_info_0 struct
3853 ********************************************************************/
3854
construct_printer_info0(TALLOC_CTX * mem_ctx,const struct auth_session_info * session_info,struct messaging_context * msg_ctx,struct spoolss_PrinterInfo2 * info2,const char * servername,struct spoolss_PrinterInfo0 * r,int snum)3855 static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
3856 const struct auth_session_info *session_info,
3857 struct messaging_context *msg_ctx,
3858 struct spoolss_PrinterInfo2 *info2,
3859 const char *servername,
3860 struct spoolss_PrinterInfo0 *r,
3861 int snum)
3862 {
3863 int count;
3864 struct printer_session_counter *session_counter;
3865 struct timeval setuptime;
3866 print_status_struct status;
3867 WERROR result;
3868 int os_major, os_minor, os_build;
3869 const char *architecture;
3870 uint32_t processor_architecture, processor_type;
3871
3872 result = create_printername(mem_ctx, servername, info2->printername, &r->printername);
3873 if (!W_ERROR_IS_OK(result)) {
3874 return result;
3875 }
3876
3877 if (servername) {
3878 r->servername = talloc_strdup(mem_ctx, servername);
3879 W_ERROR_HAVE_NO_MEMORY(r->servername);
3880 } else {
3881 r->servername = NULL;
3882 }
3883
3884 count = print_queue_length(msg_ctx, snum, &status);
3885
3886 /* check if we already have a counter for this printer */
3887 for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3888 if (session_counter->snum == snum)
3889 break;
3890 }
3891
3892 /* it's the first time, add it to the list */
3893 if (session_counter == NULL) {
3894 session_counter = talloc_zero(counter_list, struct printer_session_counter);
3895 W_ERROR_HAVE_NO_MEMORY(session_counter);
3896 session_counter->snum = snum;
3897 session_counter->counter = 0;
3898 DLIST_ADD(counter_list, session_counter);
3899 }
3900
3901 /* increment it */
3902 session_counter->counter++;
3903
3904 r->cjobs = count;
3905 r->total_jobs = 0;
3906 r->total_bytes = 0;
3907
3908 get_startup_time(&setuptime);
3909 init_systemtime(&r->time, gmtime(&setuptime.tv_sec));
3910
3911 /* JFM:
3912 * the global_counter should be stored in a TDB as it's common to all the clients
3913 * and should be zeroed on samba startup
3914 */
3915 r->global_counter = session_counter->counter;
3916 r->total_pages = 0;
3917
3918 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3919 os_major = lp_parm_int(GLOBAL_SECTION_SNUM,
3920 "spoolss", "os_major",
3921 GLOBAL_SPOOLSS_OS_MAJOR_DEFAULT);
3922 os_minor = lp_parm_int(GLOBAL_SECTION_SNUM,
3923 "spoolss", "os_minor",
3924 GLOBAL_SPOOLSS_OS_MINOR_DEFAULT);
3925 os_build = lp_parm_int(GLOBAL_SECTION_SNUM,
3926 "spoolss", "os_build",
3927 GLOBAL_SPOOLSS_OS_BUILD_DEFAULT);
3928
3929 SCVAL(&r->version, 0, os_major);
3930 SCVAL(&r->version, 1, os_minor);
3931 SSVAL(&r->version, 2, os_build);
3932
3933 architecture = lp_parm_const_string(GLOBAL_SECTION_SNUM,
3934 "spoolss",
3935 "architecture",
3936 GLOBAL_SPOOLSS_ARCHITECTURE);
3937
3938 if (strequal(architecture, SPOOLSS_ARCHITECTURE_x64)) {
3939 processor_architecture = PROCESSOR_ARCHITECTURE_AMD64;
3940 processor_type = PROCESSOR_AMD_X8664;
3941 } else {
3942 processor_architecture = PROCESSOR_ARCHITECTURE_INTEL;
3943 processor_type = PROCESSOR_INTEL_PENTIUM;
3944 }
3945
3946 r->free_build = SPOOLSS_RELEASE_BUILD;
3947 r->spooling = 0;
3948 r->max_spooling = 0;
3949 r->session_counter = session_counter->counter;
3950 r->num_error_out_of_paper = 0x0;
3951 r->num_error_not_ready = 0x0; /* number of print failure */
3952 r->job_error = 0x0;
3953 r->number_of_processors = 0x1;
3954 r->processor_type = processor_type;
3955 r->high_part_total_bytes = 0x0;
3956
3957 /* ChangeID in milliseconds*/
3958 winreg_printer_get_changeid_internal(mem_ctx, session_info, msg_ctx,
3959 info2->sharename, &r->change_id);
3960
3961 r->last_error = WERR_OK;
3962 r->status = nt_printq_status(status.status);
3963 r->enumerate_network_printers = 0x0;
3964 r->c_setprinter = 0x0;
3965 r->processor_architecture = processor_architecture;
3966 r->processor_level = 0x6; /* 6 ???*/
3967 r->ref_ic = 0;
3968 r->reserved2 = 0;
3969 r->reserved3 = 0;
3970
3971 return WERR_OK;
3972 }
3973
3974
3975 /********************************************************************
3976 * construct_printer_info1
3977 * fill a spoolss_PrinterInfo1 struct
3978 ********************************************************************/
3979
construct_printer_info1(TALLOC_CTX * mem_ctx,const struct spoolss_PrinterInfo2 * info2,uint32_t flags,const char * servername,struct spoolss_PrinterInfo1 * r,int snum)3980 static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
3981 const struct spoolss_PrinterInfo2 *info2,
3982 uint32_t flags,
3983 const char *servername,
3984 struct spoolss_PrinterInfo1 *r,
3985 int snum)
3986 {
3987 const struct loadparm_substitution *lp_sub =
3988 loadparm_s3_global_substitution();
3989 WERROR result;
3990
3991 r->flags = flags;
3992
3993 if (info2->comment == NULL || info2->comment[0] == '\0') {
3994 r->comment = lp_comment(mem_ctx, lp_sub, snum);
3995 } else {
3996 r->comment = talloc_strdup(mem_ctx, info2->comment); /* saved comment */
3997 }
3998 W_ERROR_HAVE_NO_MEMORY(r->comment);
3999
4000 result = create_printername(mem_ctx, servername, info2->printername, &r->name);
4001 if (!W_ERROR_IS_OK(result)) {
4002 return result;
4003 }
4004
4005 r->description = talloc_asprintf(mem_ctx, "%s,%s,%s",
4006 r->name,
4007 info2->drivername,
4008 r->comment);
4009 W_ERROR_HAVE_NO_MEMORY(r->description);
4010
4011 return WERR_OK;
4012 }
4013
4014 /********************************************************************
4015 * construct_printer_info2
4016 * fill a spoolss_PrinterInfo2 struct
4017 ********************************************************************/
4018
construct_printer_info2(TALLOC_CTX * mem_ctx,struct messaging_context * msg_ctx,const struct spoolss_PrinterInfo2 * info2,const char * servername,struct spoolss_PrinterInfo2 * r,int snum)4019 static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
4020 struct messaging_context *msg_ctx,
4021 const struct spoolss_PrinterInfo2 *info2,
4022 const char *servername,
4023 struct spoolss_PrinterInfo2 *r,
4024 int snum)
4025 {
4026 const struct loadparm_substitution *lp_sub =
4027 loadparm_s3_global_substitution();
4028 int count;
4029 print_status_struct status;
4030 WERROR result;
4031
4032 count = print_queue_length(msg_ctx, snum, &status);
4033
4034 if (servername) {
4035 r->servername = talloc_strdup(mem_ctx, servername);
4036 W_ERROR_HAVE_NO_MEMORY(r->servername);
4037 } else {
4038 r->servername = NULL;
4039 }
4040
4041 result = create_printername(mem_ctx, servername, info2->printername, &r->printername);
4042 if (!W_ERROR_IS_OK(result)) {
4043 return result;
4044 }
4045
4046 r->sharename = lp_servicename(mem_ctx, lp_sub, snum);
4047 W_ERROR_HAVE_NO_MEMORY(r->sharename);
4048 r->portname = talloc_strdup(mem_ctx, info2->portname);
4049 W_ERROR_HAVE_NO_MEMORY(r->portname);
4050 r->drivername = talloc_strdup(mem_ctx, info2->drivername);
4051 W_ERROR_HAVE_NO_MEMORY(r->drivername);
4052
4053 if (info2->comment[0] == '\0') {
4054 r->comment = lp_comment(mem_ctx, lp_sub, snum);
4055 } else {
4056 r->comment = talloc_strdup(mem_ctx, info2->comment);
4057 }
4058 W_ERROR_HAVE_NO_MEMORY(r->comment);
4059
4060 r->location = talloc_strdup(mem_ctx, info2->location);
4061 if (info2->location[0] == '\0') {
4062 const char *loc = NULL;
4063 NTSTATUS nt_status;
4064
4065 nt_status = printer_list_get_printer(mem_ctx,
4066 info2->sharename,
4067 NULL,
4068 &loc,
4069 NULL);
4070 if (NT_STATUS_IS_OK(nt_status)) {
4071 if (loc != NULL) {
4072 r->location = talloc_strdup(mem_ctx, loc);
4073 }
4074 }
4075 }
4076 W_ERROR_HAVE_NO_MEMORY(r->location);
4077
4078 r->sepfile = talloc_strdup(mem_ctx, info2->sepfile);
4079 W_ERROR_HAVE_NO_MEMORY(r->sepfile);
4080 r->printprocessor = talloc_strdup(mem_ctx, info2->printprocessor);
4081 W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
4082 r->datatype = talloc_strdup(mem_ctx, info2->datatype);
4083 W_ERROR_HAVE_NO_MEMORY(r->datatype);
4084 r->parameters = talloc_strdup(mem_ctx, info2->parameters);
4085 W_ERROR_HAVE_NO_MEMORY(r->parameters);
4086
4087 r->attributes = info2->attributes;
4088
4089 r->priority = info2->priority;
4090 r->defaultpriority = info2->defaultpriority;
4091 r->starttime = info2->starttime;
4092 r->untiltime = info2->untiltime;
4093 r->status = nt_printq_status(status.status);
4094 r->cjobs = count;
4095 r->averageppm = info2->averageppm;
4096
4097 if (info2->devmode != NULL) {
4098 result = copy_devicemode(mem_ctx,
4099 info2->devmode,
4100 &r->devmode);
4101 if (!W_ERROR_IS_OK(result)) {
4102 return result;
4103 }
4104 } else if (lp_default_devmode(snum)) {
4105 result = spoolss_create_default_devmode(mem_ctx,
4106 info2->printername,
4107 &r->devmode);
4108 if (!W_ERROR_IS_OK(result)) {
4109 return result;
4110 }
4111 } else {
4112 r->devmode = NULL;
4113 DEBUG(8,("Returning NULL Devicemode!\n"));
4114 }
4115
4116 compose_devicemode_devicename(r->devmode, r->printername);
4117
4118 r->secdesc = NULL;
4119
4120 if (info2->secdesc != NULL) {
4121 /* don't use talloc_steal() here unless you do a deep steal of all
4122 the SEC_DESC members */
4123
4124 r->secdesc = security_descriptor_copy(mem_ctx, info2->secdesc);
4125 if (r->secdesc == NULL) {
4126 return WERR_NOT_ENOUGH_MEMORY;
4127 }
4128 }
4129
4130 return WERR_OK;
4131 }
4132
4133 /********************************************************************
4134 * construct_printer_info3
4135 * fill a spoolss_PrinterInfo3 struct
4136 ********************************************************************/
4137
construct_printer_info3(TALLOC_CTX * mem_ctx,const struct spoolss_PrinterInfo2 * info2,const char * servername,struct spoolss_PrinterInfo3 * r,int snum)4138 static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
4139 const struct spoolss_PrinterInfo2 *info2,
4140 const char *servername,
4141 struct spoolss_PrinterInfo3 *r,
4142 int snum)
4143 {
4144 /* These are the components of the SD we are returning. */
4145
4146 if (info2->secdesc != NULL) {
4147 /* don't use talloc_steal() here unless you do a deep steal of all
4148 the SEC_DESC members */
4149
4150 r->secdesc = security_descriptor_copy(mem_ctx, info2->secdesc);
4151 if (r->secdesc == NULL) {
4152 return WERR_NOT_ENOUGH_MEMORY;
4153 }
4154 }
4155
4156 return WERR_OK;
4157 }
4158
4159 /********************************************************************
4160 * construct_printer_info4
4161 * fill a spoolss_PrinterInfo4 struct
4162 ********************************************************************/
4163
construct_printer_info4(TALLOC_CTX * mem_ctx,const struct spoolss_PrinterInfo2 * info2,const char * servername,struct spoolss_PrinterInfo4 * r,int snum)4164 static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
4165 const struct spoolss_PrinterInfo2 *info2,
4166 const char *servername,
4167 struct spoolss_PrinterInfo4 *r,
4168 int snum)
4169 {
4170 WERROR result;
4171
4172 result = create_printername(mem_ctx, servername, info2->printername, &r->printername);
4173 if (!W_ERROR_IS_OK(result)) {
4174 return result;
4175 }
4176
4177 if (servername) {
4178 r->servername = talloc_strdup(mem_ctx, servername);
4179 W_ERROR_HAVE_NO_MEMORY(r->servername);
4180 } else {
4181 r->servername = NULL;
4182 }
4183
4184 r->attributes = info2->attributes;
4185
4186 return WERR_OK;
4187 }
4188
4189 /********************************************************************
4190 * construct_printer_info5
4191 * fill a spoolss_PrinterInfo5 struct
4192 ********************************************************************/
4193
construct_printer_info5(TALLOC_CTX * mem_ctx,const struct spoolss_PrinterInfo2 * info2,const char * servername,struct spoolss_PrinterInfo5 * r,int snum)4194 static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
4195 const struct spoolss_PrinterInfo2 *info2,
4196 const char *servername,
4197 struct spoolss_PrinterInfo5 *r,
4198 int snum)
4199 {
4200 WERROR result;
4201
4202 result = create_printername(mem_ctx, servername, info2->printername, &r->printername);
4203 if (!W_ERROR_IS_OK(result)) {
4204 return result;
4205 }
4206
4207 r->portname = talloc_strdup(mem_ctx, info2->portname);
4208 W_ERROR_HAVE_NO_MEMORY(r->portname);
4209
4210 r->attributes = info2->attributes;
4211
4212 /*
4213 * These two are not used by NT+ according to MSDN. However the values
4214 * we saw on Windows Server 2012 and 2016 are always set to the 0xafc8.
4215 */
4216 r->device_not_selected_timeout = 0xafc8; /* 45 sec */
4217 r->transmission_retry_timeout = 0xafc8; /* 45 sec */
4218
4219 return WERR_OK;
4220 }
4221
4222 /********************************************************************
4223 * construct_printer_info_6
4224 * fill a spoolss_PrinterInfo6 struct
4225 ********************************************************************/
4226
construct_printer_info6(TALLOC_CTX * mem_ctx,struct messaging_context * msg_ctx,const struct spoolss_PrinterInfo2 * info2,const char * servername,struct spoolss_PrinterInfo6 * r,int snum)4227 static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
4228 struct messaging_context *msg_ctx,
4229 const struct spoolss_PrinterInfo2 *info2,
4230 const char *servername,
4231 struct spoolss_PrinterInfo6 *r,
4232 int snum)
4233 {
4234 print_status_struct status;
4235
4236 print_queue_length(msg_ctx, snum, &status);
4237
4238 r->status = nt_printq_status(status.status);
4239
4240 return WERR_OK;
4241 }
4242
4243 /********************************************************************
4244 * construct_printer_info7
4245 * fill a spoolss_PrinterInfo7 struct
4246 ********************************************************************/
4247
construct_printer_info7(TALLOC_CTX * mem_ctx,struct messaging_context * msg_ctx,const char * servername,struct spoolss_PrinterInfo7 * r,int snum)4248 static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
4249 struct messaging_context *msg_ctx,
4250 const char *servername,
4251 struct spoolss_PrinterInfo7 *r,
4252 int snum)
4253 {
4254 const struct loadparm_substitution *lp_sub =
4255 loadparm_s3_global_substitution();
4256 const struct auth_session_info *session_info;
4257 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
4258 char *printer;
4259 WERROR werr;
4260 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
4261 if (tmp_ctx == NULL) {
4262 return WERR_NOT_ENOUGH_MEMORY;
4263 }
4264
4265 session_info = get_session_info_system();
4266 SMB_ASSERT(session_info != NULL);
4267
4268 printer = lp_servicename(tmp_ctx, lp_sub, snum);
4269 if (printer == NULL) {
4270 DEBUG(0, ("invalid printer snum %d\n", snum));
4271 werr = WERR_INVALID_PARAMETER;
4272 goto out_tmp_free;
4273 }
4274
4275 if (is_printer_published(tmp_ctx, session_info, msg_ctx,
4276 servername, printer, &pinfo2)) {
4277 struct GUID guid;
4278 char *guidstr;
4279 werr = nt_printer_guid_get(tmp_ctx, session_info, msg_ctx,
4280 printer, &guid);
4281 if (!W_ERROR_IS_OK(werr)) {
4282 /*
4283 * If we do not have a GUID entry in the registry, then
4284 * try to retrieve it from AD and store it now.
4285 */
4286 werr = nt_printer_guid_retrieve(tmp_ctx, printer,
4287 &guid);
4288 if (!W_ERROR_IS_OK(werr)) {
4289 DBG_NOTICE("Failed to retrieve GUID for "
4290 "printer [%s] from AD - %s\n",
4291 printer,
4292 win_errstr(werr));
4293 if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) {
4294 /*
4295 * If we did not find it in AD, then it
4296 * is unpublished and we should reflect
4297 * this in the registry and return
4298 * success.
4299 */
4300 DBG_WARNING("Unpublish printer [%s]\n",
4301 pinfo2->sharename);
4302 nt_printer_publish(tmp_ctx,
4303 session_info,
4304 msg_ctx,
4305 pinfo2,
4306 DSPRINT_UNPUBLISH);
4307 r->guid = talloc_strdup(mem_ctx, "");
4308 r->action = DSPRINT_UNPUBLISH;
4309
4310 if (r->guid == NULL) {
4311 werr = WERR_NOT_ENOUGH_MEMORY;
4312 } else {
4313 werr = WERR_OK;
4314 }
4315 }
4316 goto out_tmp_free;
4317 }
4318
4319 werr = nt_printer_guid_store(msg_ctx, printer, guid);
4320 if (!W_ERROR_IS_OK(werr)) {
4321 DEBUG(3, ("failed to store printer %s guid\n",
4322 printer));
4323 }
4324 }
4325
4326 /* [MS-RPRN] section 2.2: must use curly-braced GUIDs */
4327 guidstr = GUID_string2(mem_ctx, &guid);
4328 if (guidstr == NULL) {
4329 werr = WERR_NOT_ENOUGH_MEMORY;
4330 goto out_tmp_free;
4331 }
4332 /* Convert GUID string to uppercase otherwise printers
4333 * are pruned */
4334 r->guid = talloc_strdup_upper(mem_ctx, guidstr);
4335 r->action = DSPRINT_PUBLISH;
4336
4337 TALLOC_FREE(guidstr);
4338 } else {
4339 r->guid = talloc_strdup(mem_ctx, "");
4340 r->action = DSPRINT_UNPUBLISH;
4341 }
4342 if (r->guid == NULL) {
4343 werr = WERR_NOT_ENOUGH_MEMORY;
4344 goto out_tmp_free;
4345 }
4346
4347 werr = WERR_OK;
4348 out_tmp_free:
4349 talloc_free(tmp_ctx);
4350 return werr;
4351 }
4352
4353 /********************************************************************
4354 * construct_printer_info8
4355 * fill a spoolss_PrinterInfo8 struct
4356 ********************************************************************/
4357
construct_printer_info8(TALLOC_CTX * mem_ctx,const struct spoolss_PrinterInfo2 * info2,const char * servername,struct spoolss_DeviceModeInfo * r,int snum)4358 static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
4359 const struct spoolss_PrinterInfo2 *info2,
4360 const char *servername,
4361 struct spoolss_DeviceModeInfo *r,
4362 int snum)
4363 {
4364 WERROR result;
4365 const char *printername;
4366
4367 result = create_printername(mem_ctx, servername, info2->printername, &printername);
4368 if (!W_ERROR_IS_OK(result)) {
4369 return result;
4370 }
4371
4372 if (info2->devmode != NULL) {
4373 result = copy_devicemode(mem_ctx,
4374 info2->devmode,
4375 &r->devmode);
4376 if (!W_ERROR_IS_OK(result)) {
4377 return result;
4378 }
4379 } else if (lp_default_devmode(snum)) {
4380 result = spoolss_create_default_devmode(mem_ctx,
4381 info2->printername,
4382 &r->devmode);
4383 if (!W_ERROR_IS_OK(result)) {
4384 return result;
4385 }
4386 } else {
4387 r->devmode = NULL;
4388 DEBUG(8,("Returning NULL Devicemode!\n"));
4389 }
4390
4391 compose_devicemode_devicename(r->devmode, printername);
4392
4393 return WERR_OK;
4394 }
4395
4396 /********************************************************************
4397 Spoolss_enumprinters.
4398 ********************************************************************/
4399
enum_all_printers_info_level(TALLOC_CTX * mem_ctx,const struct auth_session_info * session_info,struct messaging_context * msg_ctx,const char * servername,uint32_t level,uint32_t flags,union spoolss_PrinterInfo ** info_p,uint32_t * count_p)4400 static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
4401 const struct auth_session_info *session_info,
4402 struct messaging_context *msg_ctx,
4403 const char *servername,
4404 uint32_t level,
4405 uint32_t flags,
4406 union spoolss_PrinterInfo **info_p,
4407 uint32_t *count_p)
4408 {
4409 int snum;
4410 int n_services;
4411 union spoolss_PrinterInfo *info = NULL;
4412 uint32_t count = 0;
4413 WERROR result = WERR_OK;
4414 struct dcerpc_binding_handle *b = NULL;
4415 TALLOC_CTX *tmp_ctx = NULL;
4416
4417 tmp_ctx = talloc_new(mem_ctx);
4418 if (!tmp_ctx) {
4419 return WERR_NOT_ENOUGH_MEMORY;
4420 }
4421
4422 /*
4423 * printer shares are updated on client enumeration. The background
4424 * printer process updates printer_list.tdb at regular intervals.
4425 */
4426 become_root();
4427 delete_and_reload_printers();
4428 unbecome_root();
4429
4430 n_services = lp_numservices();
4431 *count_p = 0;
4432 *info_p = NULL;
4433
4434 for (snum = 0; snum < n_services; snum++) {
4435
4436 const char *printer;
4437 struct spoolss_PrinterInfo2 *info2;
4438
4439 if (!snum_is_shared_printer(snum)) {
4440 continue;
4441 }
4442
4443 printer = lp_const_servicename(snum);
4444
4445 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
4446 printer, snum));
4447
4448 if (b == NULL) {
4449 result = winreg_printer_binding_handle(tmp_ctx,
4450 session_info,
4451 msg_ctx,
4452 &b);
4453 if (!W_ERROR_IS_OK(result)) {
4454 goto out;
4455 }
4456 }
4457
4458 result = winreg_create_printer(tmp_ctx, b,
4459 printer);
4460 if (!W_ERROR_IS_OK(result)) {
4461 goto out;
4462 }
4463
4464 info = talloc_realloc(tmp_ctx, info,
4465 union spoolss_PrinterInfo,
4466 count + 1);
4467 if (!info) {
4468 result = WERR_NOT_ENOUGH_MEMORY;
4469 goto out;
4470 }
4471
4472 result = winreg_get_printer(tmp_ctx, b,
4473 printer, &info2);
4474 if (!W_ERROR_IS_OK(result)) {
4475 goto out;
4476 }
4477
4478 switch (level) {
4479 case 0:
4480 result = construct_printer_info0(info, session_info,
4481 msg_ctx, info2,
4482 servername,
4483 &info[count].info0, snum);
4484 break;
4485 case 1:
4486 result = construct_printer_info1(info, info2, flags,
4487 servername,
4488 &info[count].info1, snum);
4489 break;
4490 case 2:
4491 result = construct_printer_info2(info, msg_ctx, info2,
4492 servername,
4493 &info[count].info2, snum);
4494 break;
4495 case 4:
4496 result = construct_printer_info4(info, info2,
4497 servername,
4498 &info[count].info4, snum);
4499 break;
4500 case 5:
4501 result = construct_printer_info5(info, info2,
4502 servername,
4503 &info[count].info5, snum);
4504 break;
4505
4506 default:
4507 result = WERR_INVALID_LEVEL;
4508 goto out;
4509 }
4510
4511 if (!W_ERROR_IS_OK(result)) {
4512 goto out;
4513 }
4514
4515 count++;
4516 }
4517
4518 out:
4519 if (W_ERROR_IS_OK(result)) {
4520 *info_p = talloc_move(mem_ctx, &info);
4521 *count_p = count;
4522 }
4523
4524 talloc_free(tmp_ctx);
4525
4526 return result;
4527 }
4528
4529 /********************************************************************
4530 * handle enumeration of printers at level 0
4531 ********************************************************************/
4532
enumprinters_level0(TALLOC_CTX * mem_ctx,const struct auth_session_info * session_info,struct messaging_context * msg_ctx,uint32_t flags,const char * servername,union spoolss_PrinterInfo ** info,uint32_t * count)4533 static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
4534 const struct auth_session_info *session_info,
4535 struct messaging_context *msg_ctx,
4536 uint32_t flags,
4537 const char *servername,
4538 union spoolss_PrinterInfo **info,
4539 uint32_t *count)
4540 {
4541 DEBUG(4,("enum_all_printers_info_0\n"));
4542
4543 return enum_all_printers_info_level(mem_ctx, session_info, msg_ctx,
4544 servername, 0, flags, info, count);
4545 }
4546
4547
4548 /********************************************************************
4549 ********************************************************************/
4550
enum_all_printers_info_1(TALLOC_CTX * mem_ctx,const struct auth_session_info * session_info,struct messaging_context * msg_ctx,const char * servername,uint32_t flags,union spoolss_PrinterInfo ** info,uint32_t * count)4551 static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
4552 const struct auth_session_info *session_info,
4553 struct messaging_context *msg_ctx,
4554 const char *servername,
4555 uint32_t flags,
4556 union spoolss_PrinterInfo **info,
4557 uint32_t *count)
4558 {
4559 DEBUG(4,("enum_all_printers_info_1\n"));
4560
4561 return enum_all_printers_info_level(mem_ctx, session_info, msg_ctx,
4562 servername, 1, flags, info, count);
4563 }
4564
4565 /********************************************************************
4566 enum_all_printers_info_1_local.
4567 *********************************************************************/
4568
enum_all_printers_info_1_local(TALLOC_CTX * mem_ctx,const struct auth_session_info * session_info,struct messaging_context * msg_ctx,const char * servername,union spoolss_PrinterInfo ** info,uint32_t * count)4569 static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
4570 const struct auth_session_info *session_info,
4571 struct messaging_context *msg_ctx,
4572 const char *servername,
4573 union spoolss_PrinterInfo **info,
4574 uint32_t *count)
4575 {
4576 DEBUG(4,("enum_all_printers_info_1_local\n"));
4577
4578 return enum_all_printers_info_1(mem_ctx, session_info, msg_ctx,
4579 servername, PRINTER_ENUM_ICON8, info, count);
4580 }
4581
4582 /********************************************************************
4583 enum_all_printers_info_1_name.
4584 *********************************************************************/
4585
enum_all_printers_info_1_name(TALLOC_CTX * mem_ctx,const struct auth_session_info * session_info,struct messaging_context * msg_ctx,const char * servername,union spoolss_PrinterInfo ** info,uint32_t * count)4586 static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
4587 const struct auth_session_info *session_info,
4588 struct messaging_context *msg_ctx,
4589 const char *servername,
4590 union spoolss_PrinterInfo **info,
4591 uint32_t *count)
4592 {
4593 const char *s = servername;
4594
4595 DEBUG(4,("enum_all_printers_info_1_name\n"));
4596
4597 if (servername != NULL &&
4598 (servername[0] == '\\') && (servername[1] == '\\')) {
4599 s = servername + 2;
4600 }
4601
4602 if (!is_myname_or_ipaddr(s)) {
4603 return WERR_INVALID_NAME;
4604 }
4605
4606 return enum_all_printers_info_1(mem_ctx, session_info, msg_ctx,
4607 servername, PRINTER_ENUM_ICON8, info, count);
4608 }
4609
4610 /********************************************************************
4611 enum_all_printers_info_1_network.
4612 *********************************************************************/
4613
enum_all_printers_info_1_network(TALLOC_CTX * mem_ctx,const struct auth_session_info * session_info,struct messaging_context * msg_ctx,const char * servername,union spoolss_PrinterInfo ** info,uint32_t * count)4614 static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
4615 const struct auth_session_info *session_info,
4616 struct messaging_context *msg_ctx,
4617 const char *servername,
4618 union spoolss_PrinterInfo **info,
4619 uint32_t *count)
4620 {
4621 const char *s = servername;
4622
4623 DEBUG(4,("enum_all_printers_info_1_network\n"));
4624
4625 /* If we respond to a enum_printers level 1 on our name with flags
4626 set to PRINTER_ENUM_REMOTE with a list of printers then these
4627 printers incorrectly appear in the APW browse list.
4628 Specifically the printers for the server appear at the workgroup
4629 level where all the other servers in the domain are
4630 listed. Windows responds to this call with a
4631 WERR_CAN_NOT_COMPLETE so we should do the same. */
4632
4633 if (servername != NULL &&
4634 (servername[0] == '\\') && (servername[1] == '\\')) {
4635 s = servername + 2;
4636 }
4637
4638 if (is_myname_or_ipaddr(s)) {
4639 return WERR_CAN_NOT_COMPLETE;
4640 }
4641
4642 return enum_all_printers_info_1(mem_ctx, session_info, msg_ctx,
4643 servername, PRINTER_ENUM_NAME, info, count);
4644 }
4645
4646 /********************************************************************
4647 * api_spoolss_enumprinters
4648 *
4649 * called from api_spoolss_enumprinters (see this to understand)
4650 ********************************************************************/
4651
enum_all_printers_info_2(TALLOC_CTX * mem_ctx,const struct auth_session_info * session_info,struct messaging_context * msg_ctx,const char * servername,union spoolss_PrinterInfo ** info,uint32_t * count)4652 static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
4653 const struct auth_session_info *session_info,
4654 struct messaging_context *msg_ctx,
4655 const char *servername,
4656 union spoolss_PrinterInfo **info,
4657 uint32_t *count)
4658 {
4659 DEBUG(4,("enum_all_printers_info_2\n"));
4660
4661 return enum_all_printers_info_level(mem_ctx, session_info, msg_ctx,
4662 servername, 2, 0, info, count);
4663 }
4664
4665 /********************************************************************
4666 * handle enumeration of printers at level 1
4667 ********************************************************************/
4668
enumprinters_level1(TALLOC_CTX * mem_ctx,const struct auth_session_info * session_info,struct messaging_context * msg_ctx,uint32_t flags,const char * servername,union spoolss_PrinterInfo ** info,uint32_t * count)4669 static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
4670 const struct auth_session_info *session_info,
4671 struct messaging_context *msg_ctx,
4672 uint32_t flags,
4673 const char *servername,
4674 union spoolss_PrinterInfo **info,
4675 uint32_t *count)
4676 {
4677 /* Not all the flags are equals */
4678
4679 if (flags & PRINTER_ENUM_LOCAL) {
4680 return enum_all_printers_info_1_local(mem_ctx, session_info,
4681 msg_ctx, servername, info, count);
4682 }
4683
4684 if (flags & PRINTER_ENUM_NAME) {
4685 return enum_all_printers_info_1_name(mem_ctx, session_info,
4686 msg_ctx, servername, info,
4687 count);
4688 }
4689
4690 if (flags & PRINTER_ENUM_NETWORK) {
4691 return enum_all_printers_info_1_network(mem_ctx, session_info,
4692 msg_ctx, servername, info,
4693 count);
4694 }
4695
4696 return WERR_OK; /* NT4sp5 does that */
4697 }
4698
4699 /********************************************************************
4700 * handle enumeration of printers at level 2
4701 ********************************************************************/
4702
enumprinters_level2(TALLOC_CTX * mem_ctx,const struct auth_session_info * session_info,struct messaging_context * msg_ctx,uint32_t flags,const char * servername,union spoolss_PrinterInfo ** info,uint32_t * count)4703 static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
4704 const struct auth_session_info *session_info,
4705 struct messaging_context *msg_ctx,
4706 uint32_t flags,
4707 const char *servername,
4708 union spoolss_PrinterInfo **info,
4709 uint32_t *count)
4710 {
4711 if (flags & PRINTER_ENUM_LOCAL) {
4712
4713 return enum_all_printers_info_2(mem_ctx, session_info, msg_ctx,
4714 servername,
4715 info, count);
4716 }
4717
4718 if (flags & PRINTER_ENUM_NAME) {
4719 if (servername && !is_myname_or_ipaddr(canon_servername(servername))) {
4720 return WERR_INVALID_NAME;
4721 }
4722
4723 return enum_all_printers_info_2(mem_ctx, session_info, msg_ctx,
4724 servername,
4725 info, count);
4726 }
4727
4728 if (flags & PRINTER_ENUM_REMOTE) {
4729 return WERR_INVALID_LEVEL;
4730 }
4731
4732 return WERR_OK;
4733 }
4734
4735 /********************************************************************
4736 * handle enumeration of printers at level 4
4737 ********************************************************************/
4738
enumprinters_level4(TALLOC_CTX * mem_ctx,const struct auth_session_info * session_info,struct messaging_context * msg_ctx,uint32_t flags,const char * servername,union spoolss_PrinterInfo ** info,uint32_t * count)4739 static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
4740 const struct auth_session_info *session_info,
4741 struct messaging_context *msg_ctx,
4742 uint32_t flags,
4743 const char *servername,
4744 union spoolss_PrinterInfo **info,
4745 uint32_t *count)
4746 {
4747 DEBUG(4,("enum_all_printers_info_4\n"));
4748
4749 return enum_all_printers_info_level(mem_ctx, session_info, msg_ctx,
4750 servername, 4, flags, info, count);
4751 }
4752
4753
4754 /********************************************************************
4755 * handle enumeration of printers at level 5
4756 ********************************************************************/
4757
enumprinters_level5(TALLOC_CTX * mem_ctx,const struct auth_session_info * session_info,struct messaging_context * msg_ctx,uint32_t flags,const char * servername,union spoolss_PrinterInfo ** info,uint32_t * count)4758 static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
4759 const struct auth_session_info *session_info,
4760 struct messaging_context *msg_ctx,
4761 uint32_t flags,
4762 const char *servername,
4763 union spoolss_PrinterInfo **info,
4764 uint32_t *count)
4765 {
4766 DEBUG(4,("enum_all_printers_info_5\n"));
4767
4768 return enum_all_printers_info_level(mem_ctx, session_info, msg_ctx,
4769 servername, 5, flags, info, count);
4770 }
4771
4772 /****************************************************************
4773 _spoolss_EnumPrinters
4774 ****************************************************************/
4775
_spoolss_EnumPrinters(struct pipes_struct * p,struct spoolss_EnumPrinters * r)4776 WERROR _spoolss_EnumPrinters(struct pipes_struct *p,
4777 struct spoolss_EnumPrinters *r)
4778 {
4779 const struct auth_session_info *session_info = get_session_info_system();
4780 WERROR result;
4781
4782 /* that's an [in out] buffer */
4783
4784 if (!r->in.buffer && (r->in.offered != 0)) {
4785 return WERR_INVALID_PARAMETER;
4786 }
4787
4788 DEBUG(4,("_spoolss_EnumPrinters\n"));
4789
4790 *r->out.needed = 0;
4791 *r->out.count = 0;
4792 *r->out.info = NULL;
4793
4794 /*
4795 * Level 1:
4796 * flags==PRINTER_ENUM_NAME
4797 * if name=="" then enumerates all printers
4798 * if name!="" then enumerate the printer
4799 * flags==PRINTER_ENUM_REMOTE
4800 * name is NULL, enumerate printers
4801 * Level 2: name!="" enumerates printers, name can't be NULL
4802 * Level 3: doesn't exist
4803 * Level 4: does a local registry lookup
4804 * Level 5: same as Level 2
4805 */
4806
4807 if (r->in.server && r->in.server[0] == '\0') {
4808 r->in.server = NULL;
4809 }
4810
4811 switch (r->in.level) {
4812 case 0:
4813 result = enumprinters_level0(p->mem_ctx, session_info,
4814 p->msg_ctx, r->in.flags,
4815 r->in.server,
4816 r->out.info, r->out.count);
4817 break;
4818 case 1:
4819 result = enumprinters_level1(p->mem_ctx, session_info,
4820 p->msg_ctx, r->in.flags,
4821 r->in.server,
4822 r->out.info, r->out.count);
4823 break;
4824 case 2:
4825 result = enumprinters_level2(p->mem_ctx, session_info,
4826 p->msg_ctx, r->in.flags,
4827 r->in.server,
4828 r->out.info, r->out.count);
4829 break;
4830 case 4:
4831 result = enumprinters_level4(p->mem_ctx, session_info,
4832 p->msg_ctx, r->in.flags,
4833 r->in.server,
4834 r->out.info, r->out.count);
4835 break;
4836 case 5:
4837 result = enumprinters_level5(p->mem_ctx, session_info,
4838 p->msg_ctx, r->in.flags,
4839 r->in.server,
4840 r->out.info, r->out.count);
4841 break;
4842 default:
4843 return WERR_INVALID_LEVEL;
4844 }
4845
4846 if (!W_ERROR_IS_OK(result)) {
4847 return result;
4848 }
4849
4850 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
4851 spoolss_EnumPrinters,
4852 *r->out.info, r->in.level,
4853 *r->out.count);
4854 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
4855 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
4856
4857 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4858 }
4859
4860 /****************************************************************
4861 _spoolss_GetPrinter
4862 ****************************************************************/
4863
_spoolss_GetPrinter(struct pipes_struct * p,struct spoolss_GetPrinter * r)4864 WERROR _spoolss_GetPrinter(struct pipes_struct *p,
4865 struct spoolss_GetPrinter *r)
4866 {
4867 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
4868 struct spoolss_PrinterInfo2 *info2 = NULL;
4869 WERROR result = WERR_OK;
4870 int snum;
4871
4872 /* that's an [in out] buffer */
4873
4874 if (!r->in.buffer && (r->in.offered != 0)) {
4875 result = WERR_INVALID_PARAMETER;
4876 goto err_info_free;
4877 }
4878
4879 *r->out.needed = 0;
4880
4881 if (Printer == NULL) {
4882 result = WERR_INVALID_HANDLE;
4883 goto err_info_free;
4884 }
4885
4886 if (Printer->printer_type == SPLHND_SERVER) {
4887
4888 struct dcerpc_binding_handle *b;
4889
4890 if (r->in.level != 3) {
4891 result = WERR_INVALID_LEVEL;
4892 goto err_info_free;
4893 }
4894
4895 result = winreg_printer_binding_handle(p->mem_ctx,
4896 get_session_info_system(),
4897 p->msg_ctx,
4898 &b);
4899 if (!W_ERROR_IS_OK(result)) {
4900 goto err_info_free;
4901 }
4902
4903 result = winreg_get_printserver_secdesc(p->mem_ctx,
4904 b,
4905 &r->out.info->info3.secdesc);
4906 if (!W_ERROR_IS_OK(result)) {
4907 goto err_info_free;
4908 }
4909
4910 goto done;
4911 }
4912
4913 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
4914 result = WERR_INVALID_HANDLE;
4915 goto err_info_free;
4916 }
4917
4918 result = winreg_get_printer_internal(p->mem_ctx,
4919 get_session_info_system(),
4920 p->msg_ctx,
4921 lp_const_servicename(snum),
4922 &info2);
4923 if (!W_ERROR_IS_OK(result)) {
4924 goto err_info_free;
4925 }
4926
4927 switch (r->in.level) {
4928 case 0:
4929 result = construct_printer_info0(p->mem_ctx,
4930 get_session_info_system(),
4931 p->msg_ctx,
4932 info2,
4933 Printer->servername,
4934 &r->out.info->info0,
4935 snum);
4936 break;
4937 case 1:
4938 result = construct_printer_info1(p->mem_ctx, info2,
4939 PRINTER_ENUM_ICON8,
4940 Printer->servername,
4941 &r->out.info->info1, snum);
4942 break;
4943 case 2:
4944 result = construct_printer_info2(p->mem_ctx, p->msg_ctx, info2,
4945 Printer->servername,
4946 &r->out.info->info2, snum);
4947 break;
4948 case 3:
4949 result = construct_printer_info3(p->mem_ctx, info2,
4950 Printer->servername,
4951 &r->out.info->info3, snum);
4952 break;
4953 case 4:
4954 result = construct_printer_info4(p->mem_ctx, info2,
4955 Printer->servername,
4956 &r->out.info->info4, snum);
4957 break;
4958 case 5:
4959 result = construct_printer_info5(p->mem_ctx, info2,
4960 Printer->servername,
4961 &r->out.info->info5, snum);
4962 break;
4963 case 6:
4964 result = construct_printer_info6(p->mem_ctx, p->msg_ctx, info2,
4965 Printer->servername,
4966 &r->out.info->info6, snum);
4967 break;
4968 case 7:
4969 result = construct_printer_info7(p->mem_ctx, p->msg_ctx,
4970 Printer->servername,
4971 &r->out.info->info7, snum);
4972 break;
4973 case 8:
4974 result = construct_printer_info8(p->mem_ctx, info2,
4975 Printer->servername,
4976 &r->out.info->info8, snum);
4977 break;
4978 default:
4979 result = WERR_INVALID_LEVEL;
4980 break;
4981 }
4982 TALLOC_FREE(info2);
4983
4984 if (!W_ERROR_IS_OK(result)) {
4985 DEBUG(0, ("_spoolss_GetPrinter: failed to construct printer info level %d - %s\n",
4986 r->in.level, win_errstr(result)));
4987 goto err_info_free;
4988 }
4989 done:
4990 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo,
4991 r->out.info, r->in.level);
4992 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
4993
4994 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4995
4996 err_info_free:
4997 TALLOC_FREE(r->out.info);
4998 return result;
4999 }
5000
5001 /********************************************************************
5002 ********************************************************************/
5003
5004 #define FILL_DRIVER_STRING(mem_ctx, in, out) \
5005 do { \
5006 if (in && strlen(in)) { \
5007 out = talloc_strdup(mem_ctx, in); \
5008 } else { \
5009 out = talloc_strdup(mem_ctx, ""); \
5010 } \
5011 W_ERROR_HAVE_NO_MEMORY(out); \
5012 } while (0);
5013
5014 #define FILL_DRIVER_UNC_STRING(mem_ctx, server, arch, ver, in, out) \
5015 do { \
5016 if (in && strlen(in)) { \
5017 out = talloc_asprintf(mem_ctx, "\\\\%s\\print$\\%s\\%d\\%s", server, get_short_archi(arch), ver, in); \
5018 } else { \
5019 out = talloc_strdup(mem_ctx, ""); \
5020 } \
5021 W_ERROR_HAVE_NO_MEMORY(out); \
5022 } while (0);
5023
string_array_from_driver_info(TALLOC_CTX * mem_ctx,const char ** string_array,const char *** presult,const char * cservername,const char * arch,int version)5024 static WERROR string_array_from_driver_info(TALLOC_CTX *mem_ctx,
5025 const char **string_array,
5026 const char ***presult,
5027 const char *cservername,
5028 const char *arch,
5029 int version)
5030 {
5031 size_t i;
5032 size_t num_strings = 0;
5033 const char **array = NULL;
5034
5035 if (string_array == NULL) {
5036 return WERR_INVALID_PARAMETER;
5037 }
5038
5039 for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
5040 const char *str = NULL;
5041
5042 if (cservername == NULL || arch == NULL) {
5043 FILL_DRIVER_STRING(mem_ctx, string_array[i], str);
5044 } else {
5045 FILL_DRIVER_UNC_STRING(mem_ctx, cservername, arch, version, string_array[i], str);
5046 }
5047
5048 if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
5049 TALLOC_FREE(array);
5050 return WERR_NOT_ENOUGH_MEMORY;
5051 }
5052 }
5053
5054 if (i > 0) {
5055 ADD_TO_ARRAY(mem_ctx, const char *, NULL,
5056 &array, &num_strings);
5057 }
5058
5059 if (presult != NULL) {
5060 *presult = array;
5061 } else {
5062 talloc_free(array);
5063 }
5064
5065 return WERR_OK;
5066 }
5067
5068 /********************************************************************
5069 * fill a spoolss_DriverInfo1 struct
5070 ********************************************************************/
5071
fill_printer_driver_info1(TALLOC_CTX * mem_ctx,struct spoolss_DriverInfo1 * r,const struct spoolss_DriverInfo8 * driver,const char * servername)5072 static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
5073 struct spoolss_DriverInfo1 *r,
5074 const struct spoolss_DriverInfo8 *driver,
5075 const char *servername)
5076 {
5077 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
5078 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
5079
5080 return WERR_OK;
5081 }
5082
5083 /********************************************************************
5084 * fill a spoolss_DriverInfo2 struct
5085 ********************************************************************/
5086
fill_printer_driver_info2(TALLOC_CTX * mem_ctx,struct spoolss_DriverInfo2 * r,const struct spoolss_DriverInfo8 * driver,const char * servername)5087 static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
5088 struct spoolss_DriverInfo2 *r,
5089 const struct spoolss_DriverInfo8 *driver,
5090 const char *servername)
5091
5092 {
5093 const char *cservername = canon_servername(servername);
5094
5095 r->version = driver->version;
5096
5097 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
5098 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
5099 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
5100 W_ERROR_HAVE_NO_MEMORY(r->architecture);
5101
5102 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5103 driver->architecture,
5104 driver->version,
5105 driver->driver_path,
5106 r->driver_path);
5107
5108 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5109 driver->architecture,
5110 driver->version,
5111 driver->data_file,
5112 r->data_file);
5113
5114 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5115 driver->architecture,
5116 driver->version,
5117 driver->config_file,
5118 r->config_file);
5119
5120 return WERR_OK;
5121 }
5122
5123 /********************************************************************
5124 * fill a spoolss_DriverInfo3 struct
5125 ********************************************************************/
5126
fill_printer_driver_info3(TALLOC_CTX * mem_ctx,struct spoolss_DriverInfo3 * r,const struct spoolss_DriverInfo8 * driver,const char * servername)5127 static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
5128 struct spoolss_DriverInfo3 *r,
5129 const struct spoolss_DriverInfo8 *driver,
5130 const char *servername)
5131 {
5132 const char *cservername = canon_servername(servername);
5133
5134 r->version = driver->version;
5135
5136 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
5137 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
5138 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
5139 W_ERROR_HAVE_NO_MEMORY(r->architecture);
5140
5141 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5142 driver->architecture,
5143 driver->version,
5144 driver->driver_path,
5145 r->driver_path);
5146
5147 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5148 driver->architecture,
5149 driver->version,
5150 driver->data_file,
5151 r->data_file);
5152
5153 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5154 driver->architecture,
5155 driver->version,
5156 driver->config_file,
5157 r->config_file);
5158
5159 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5160 driver->architecture,
5161 driver->version,
5162 driver->help_file,
5163 r->help_file);
5164
5165 FILL_DRIVER_STRING(mem_ctx,
5166 driver->monitor_name,
5167 r->monitor_name);
5168
5169 FILL_DRIVER_STRING(mem_ctx,
5170 driver->default_datatype,
5171 r->default_datatype);
5172
5173 return string_array_from_driver_info(mem_ctx,
5174 driver->dependent_files,
5175 &r->dependent_files,
5176 cservername,
5177 driver->architecture,
5178 driver->version);
5179 }
5180
5181 /********************************************************************
5182 * fill a spoolss_DriverInfo4 struct
5183 ********************************************************************/
5184
fill_printer_driver_info4(TALLOC_CTX * mem_ctx,struct spoolss_DriverInfo4 * r,const struct spoolss_DriverInfo8 * driver,const char * servername)5185 static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
5186 struct spoolss_DriverInfo4 *r,
5187 const struct spoolss_DriverInfo8 *driver,
5188 const char *servername)
5189 {
5190 const char *cservername = canon_servername(servername);
5191 WERROR result;
5192
5193 r->version = driver->version;
5194
5195 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
5196 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
5197 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
5198 W_ERROR_HAVE_NO_MEMORY(r->architecture);
5199
5200 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5201 driver->architecture,
5202 driver->version,
5203 driver->driver_path,
5204 r->driver_path);
5205
5206 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5207 driver->architecture,
5208 driver->version,
5209 driver->data_file,
5210 r->data_file);
5211
5212 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5213 driver->architecture,
5214 driver->version,
5215 driver->config_file,
5216 r->config_file);
5217
5218 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5219 driver->architecture,
5220 driver->version,
5221 driver->help_file,
5222 r->help_file);
5223
5224 result = string_array_from_driver_info(mem_ctx,
5225 driver->dependent_files,
5226 &r->dependent_files,
5227 cservername,
5228 driver->architecture,
5229 driver->version);
5230 if (!W_ERROR_IS_OK(result)) {
5231 return result;
5232 }
5233
5234 FILL_DRIVER_STRING(mem_ctx,
5235 driver->monitor_name,
5236 r->monitor_name);
5237
5238 FILL_DRIVER_STRING(mem_ctx,
5239 driver->default_datatype,
5240 r->default_datatype);
5241
5242
5243 result = string_array_from_driver_info(mem_ctx,
5244 driver->previous_names,
5245 &r->previous_names,
5246 NULL, NULL, 0);
5247
5248 return result;
5249 }
5250
5251 /********************************************************************
5252 * fill a spoolss_DriverInfo5 struct
5253 ********************************************************************/
5254
fill_printer_driver_info5(TALLOC_CTX * mem_ctx,struct spoolss_DriverInfo5 * r,const struct spoolss_DriverInfo8 * driver,const char * servername)5255 static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
5256 struct spoolss_DriverInfo5 *r,
5257 const struct spoolss_DriverInfo8 *driver,
5258 const char *servername)
5259 {
5260 const char *cservername = canon_servername(servername);
5261
5262 r->version = driver->version;
5263
5264 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
5265 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
5266 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
5267 W_ERROR_HAVE_NO_MEMORY(r->architecture);
5268
5269 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5270 driver->architecture,
5271 driver->version,
5272 driver->driver_path,
5273 r->driver_path);
5274
5275 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5276 driver->architecture,
5277 driver->version,
5278 driver->data_file,
5279 r->data_file);
5280
5281 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5282 driver->architecture,
5283 driver->version,
5284 driver->config_file,
5285 r->config_file);
5286
5287 r->driver_attributes = 0;
5288 r->config_version = 0;
5289 r->driver_version = 0;
5290
5291 return WERR_OK;
5292 }
5293 /********************************************************************
5294 * fill a spoolss_DriverInfo6 struct
5295 ********************************************************************/
5296
fill_printer_driver_info6(TALLOC_CTX * mem_ctx,struct spoolss_DriverInfo6 * r,const struct spoolss_DriverInfo8 * driver,const char * servername)5297 static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
5298 struct spoolss_DriverInfo6 *r,
5299 const struct spoolss_DriverInfo8 *driver,
5300 const char *servername)
5301 {
5302 const char *cservername = canon_servername(servername);
5303 WERROR result;
5304
5305 r->version = driver->version;
5306
5307 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
5308 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
5309 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
5310 W_ERROR_HAVE_NO_MEMORY(r->architecture);
5311
5312 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5313 driver->architecture,
5314 driver->version,
5315 driver->driver_path,
5316 r->driver_path);
5317
5318 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5319 driver->architecture,
5320 driver->version,
5321 driver->data_file,
5322 r->data_file);
5323
5324 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5325 driver->architecture,
5326 driver->version,
5327 driver->config_file,
5328 r->config_file);
5329
5330 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5331 driver->architecture,
5332 driver->version,
5333 driver->help_file,
5334 r->help_file);
5335
5336 FILL_DRIVER_STRING(mem_ctx,
5337 driver->monitor_name,
5338 r->monitor_name);
5339
5340 FILL_DRIVER_STRING(mem_ctx,
5341 driver->default_datatype,
5342 r->default_datatype);
5343
5344 result = string_array_from_driver_info(mem_ctx,
5345 driver->dependent_files,
5346 &r->dependent_files,
5347 cservername,
5348 driver->architecture,
5349 driver->version);
5350 if (!W_ERROR_IS_OK(result)) {
5351 return result;
5352 }
5353
5354 result = string_array_from_driver_info(mem_ctx,
5355 driver->previous_names,
5356 &r->previous_names,
5357 NULL, NULL, 0);
5358 if (!W_ERROR_IS_OK(result)) {
5359 return result;
5360 }
5361
5362 r->driver_date = driver->driver_date;
5363 r->driver_version = driver->driver_version;
5364
5365 FILL_DRIVER_STRING(mem_ctx,
5366 driver->manufacturer_name,
5367 r->manufacturer_name);
5368 FILL_DRIVER_STRING(mem_ctx,
5369 driver->manufacturer_url,
5370 r->manufacturer_url);
5371 FILL_DRIVER_STRING(mem_ctx,
5372 driver->hardware_id,
5373 r->hardware_id);
5374 FILL_DRIVER_STRING(mem_ctx,
5375 driver->provider,
5376 r->provider);
5377
5378 return WERR_OK;
5379 }
5380
5381 /********************************************************************
5382 * fill a spoolss_DriverInfo8 struct
5383 ********************************************************************/
5384
fill_printer_driver_info8(TALLOC_CTX * mem_ctx,struct spoolss_DriverInfo8 * r,const struct spoolss_DriverInfo8 * driver,const char * servername)5385 static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
5386 struct spoolss_DriverInfo8 *r,
5387 const struct spoolss_DriverInfo8 *driver,
5388 const char *servername)
5389 {
5390 const char *cservername = canon_servername(servername);
5391 WERROR result;
5392
5393 r->version = driver->version;
5394
5395 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
5396 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
5397 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
5398 W_ERROR_HAVE_NO_MEMORY(r->architecture);
5399
5400 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5401 driver->architecture,
5402 driver->version,
5403 driver->driver_path,
5404 r->driver_path);
5405
5406 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5407 driver->architecture,
5408 driver->version,
5409 driver->data_file,
5410 r->data_file);
5411
5412 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5413 driver->architecture,
5414 driver->version,
5415 driver->config_file,
5416 r->config_file);
5417
5418 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
5419 driver->architecture,
5420 driver->version,
5421 driver->help_file,
5422 r->help_file);
5423
5424 FILL_DRIVER_STRING(mem_ctx,
5425 driver->monitor_name,
5426 r->monitor_name);
5427
5428 FILL_DRIVER_STRING(mem_ctx,
5429 driver->default_datatype,
5430 r->default_datatype);
5431
5432 result = string_array_from_driver_info(mem_ctx,
5433 driver->dependent_files,
5434 &r->dependent_files,
5435 cservername,
5436 driver->architecture,
5437 driver->version);
5438 if (!W_ERROR_IS_OK(result)) {
5439 return result;
5440 }
5441
5442 result = string_array_from_driver_info(mem_ctx,
5443 driver->previous_names,
5444 &r->previous_names,
5445 NULL, NULL, 0);
5446 if (!W_ERROR_IS_OK(result)) {
5447 return result;
5448 }
5449
5450 r->driver_date = driver->driver_date;
5451 r->driver_version = driver->driver_version;
5452
5453 FILL_DRIVER_STRING(mem_ctx,
5454 driver->manufacturer_name,
5455 r->manufacturer_name);
5456 FILL_DRIVER_STRING(mem_ctx,
5457 driver->manufacturer_url,
5458 r->manufacturer_url);
5459 FILL_DRIVER_STRING(mem_ctx,
5460 driver->hardware_id,
5461 r->hardware_id);
5462 FILL_DRIVER_STRING(mem_ctx,
5463 driver->provider,
5464 r->provider);
5465
5466 FILL_DRIVER_STRING(mem_ctx,
5467 driver->print_processor,
5468 r->print_processor);
5469 FILL_DRIVER_STRING(mem_ctx,
5470 driver->vendor_setup,
5471 r->vendor_setup);
5472
5473 result = string_array_from_driver_info(mem_ctx,
5474 driver->color_profiles,
5475 &r->color_profiles,
5476 NULL, NULL, 0);
5477 if (!W_ERROR_IS_OK(result)) {
5478 return result;
5479 }
5480
5481 FILL_DRIVER_STRING(mem_ctx,
5482 driver->inf_path,
5483 r->inf_path);
5484
5485 r->printer_driver_attributes = driver->printer_driver_attributes;
5486
5487 result = string_array_from_driver_info(mem_ctx,
5488 driver->core_driver_dependencies,
5489 &r->core_driver_dependencies,
5490 NULL, NULL, 0);
5491 if (!W_ERROR_IS_OK(result)) {
5492 return result;
5493 }
5494
5495 r->min_inbox_driver_ver_date = driver->min_inbox_driver_ver_date;
5496 r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
5497
5498 return WERR_OK;
5499 }
5500
5501 #if 0 /* disabled until marshalling issues are resolved - gd */
5502 /********************************************************************
5503 ********************************************************************/
5504
5505 static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
5506 struct spoolss_DriverFileInfo *r,
5507 const char *cservername,
5508 const char *file_name,
5509 enum spoolss_DriverFileType file_type,
5510 uint32_t file_version)
5511 {
5512 r->file_name = talloc_asprintf(mem_ctx, "\\\\%s%s",
5513 cservername, file_name);
5514 W_ERROR_HAVE_NO_MEMORY(r->file_name);
5515 r->file_type = file_type;
5516 r->file_version = file_version;
5517
5518 return WERR_OK;
5519 }
5520
5521 /********************************************************************
5522 ********************************************************************/
5523
5524 static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
5525 const struct spoolss_DriverInfo8 *driver,
5526 const char *cservername,
5527 struct spoolss_DriverFileInfo **info_p,
5528 uint32_t *count_p)
5529 {
5530 struct spoolss_DriverFileInfo *info = NULL;
5531 uint32_t count = 0;
5532 WERROR result;
5533 uint32_t i;
5534
5535 *info_p = NULL;
5536 *count_p = 0;
5537
5538 if (strlen(driver->driver_path)) {
5539 info = talloc_realloc(mem_ctx, info,
5540 struct spoolss_DriverFileInfo,
5541 count + 1);
5542 W_ERROR_HAVE_NO_MEMORY(info);
5543 result = fill_spoolss_DriverFileInfo(info,
5544 &info[count],
5545 cservername,
5546 driver->driver_path,
5547 SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
5548 0);
5549 W_ERROR_NOT_OK_RETURN(result);
5550 count++;
5551 }
5552
5553 if (strlen(driver->config_file)) {
5554 info = talloc_realloc(mem_ctx, info,
5555 struct spoolss_DriverFileInfo,
5556 count + 1);
5557 W_ERROR_HAVE_NO_MEMORY(info);
5558 result = fill_spoolss_DriverFileInfo(info,
5559 &info[count],
5560 cservername,
5561 driver->config_file,
5562 SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
5563 0);
5564 W_ERROR_NOT_OK_RETURN(result);
5565 count++;
5566 }
5567
5568 if (strlen(driver->data_file)) {
5569 info = talloc_realloc(mem_ctx, info,
5570 struct spoolss_DriverFileInfo,
5571 count + 1);
5572 W_ERROR_HAVE_NO_MEMORY(info);
5573 result = fill_spoolss_DriverFileInfo(info,
5574 &info[count],
5575 cservername,
5576 driver->data_file,
5577 SPOOLSS_DRIVER_FILE_TYPE_DATA,
5578 0);
5579 W_ERROR_NOT_OK_RETURN(result);
5580 count++;
5581 }
5582
5583 if (strlen(driver->help_file)) {
5584 info = talloc_realloc(mem_ctx, info,
5585 struct spoolss_DriverFileInfo,
5586 count + 1);
5587 W_ERROR_HAVE_NO_MEMORY(info);
5588 result = fill_spoolss_DriverFileInfo(info,
5589 &info[count],
5590 cservername,
5591 driver->help_file,
5592 SPOOLSS_DRIVER_FILE_TYPE_HELP,
5593 0);
5594 W_ERROR_NOT_OK_RETURN(result);
5595 count++;
5596 }
5597
5598 for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
5599 info = talloc_realloc(mem_ctx, info,
5600 struct spoolss_DriverFileInfo,
5601 count + 1);
5602 W_ERROR_HAVE_NO_MEMORY(info);
5603 result = fill_spoolss_DriverFileInfo(info,
5604 &info[count],
5605 cservername,
5606 driver->dependent_files[i],
5607 SPOOLSS_DRIVER_FILE_TYPE_OTHER,
5608 0);
5609 W_ERROR_NOT_OK_RETURN(result);
5610 count++;
5611 }
5612
5613 *info_p = info;
5614 *count_p = count;
5615
5616 return WERR_OK;
5617 }
5618
5619 /********************************************************************
5620 * fill a spoolss_DriverInfo101 struct
5621 ********************************************************************/
5622
5623 static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
5624 struct spoolss_DriverInfo101 *r,
5625 const struct spoolss_DriverInfo8 *driver,
5626 const char *servername)
5627 {
5628 const char *cservername = canon_servername(servername);
5629 WERROR result;
5630
5631 r->version = driver->version;
5632
5633 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
5634 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
5635 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
5636 W_ERROR_HAVE_NO_MEMORY(r->architecture);
5637
5638 result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
5639 cservername,
5640 &r->file_info,
5641 &r->file_count);
5642 if (!W_ERROR_IS_OK(result)) {
5643 return result;
5644 }
5645
5646 FILL_DRIVER_STRING(mem_ctx,
5647 driver->monitor_name,
5648 r->monitor_name);
5649
5650 FILL_DRIVER_STRING(mem_ctx,
5651 driver->default_datatype,
5652 r->default_datatype);
5653
5654 result = string_array_from_driver_info(mem_ctx,
5655 driver->previous_names,
5656 &r->previous_names,
5657 NULL, NULL, 0);
5658 if (!W_ERROR_IS_OK(result)) {
5659 return result;
5660 }
5661
5662 r->driver_date = driver->driver_date;
5663 r->driver_version = driver->driver_version;
5664
5665 FILL_DRIVER_STRING(mem_ctx,
5666 driver->manufacturer_name,
5667 r->manufacturer_name);
5668 FILL_DRIVER_STRING(mem_ctx,
5669 driver->manufacturer_url,
5670 r->manufacturer_url);
5671 FILL_DRIVER_STRING(mem_ctx,
5672 driver->hardware_id,
5673 r->hardware_id);
5674 FILL_DRIVER_STRING(mem_ctx,
5675 driver->provider,
5676 r->provider);
5677
5678 return WERR_OK;
5679 }
5680 #endif
5681 /********************************************************************
5682 ********************************************************************/
5683
construct_printer_driver_info_level(TALLOC_CTX * mem_ctx,const struct auth_session_info * session_info,struct messaging_context * msg_ctx,uint32_t level,union spoolss_DriverInfo * r,int snum,const char * servername,const char * architecture,uint32_t version)5684 static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
5685 const struct auth_session_info *session_info,
5686 struct messaging_context *msg_ctx,
5687 uint32_t level,
5688 union spoolss_DriverInfo *r,
5689 int snum,
5690 const char *servername,
5691 const char *architecture,
5692 uint32_t version)
5693 {
5694 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
5695 struct spoolss_DriverInfo8 *driver;
5696 WERROR result;
5697 struct dcerpc_binding_handle *b;
5698 TALLOC_CTX *tmp_ctx = NULL;
5699
5700 if (level == 101) {
5701 return WERR_INVALID_LEVEL;
5702 }
5703
5704 tmp_ctx = talloc_new(mem_ctx);
5705 if (!tmp_ctx) {
5706 return WERR_NOT_ENOUGH_MEMORY;
5707 }
5708
5709 result = winreg_printer_binding_handle(tmp_ctx,
5710 session_info,
5711 msg_ctx,
5712 &b);
5713 if (!W_ERROR_IS_OK(result)) {
5714 goto done;
5715 }
5716
5717 result = winreg_get_printer(tmp_ctx, b,
5718 lp_const_servicename(snum),
5719 &pinfo2);
5720 if (!W_ERROR_IS_OK(result)) {
5721 DBG_ERR("Failed to get printer info2 for [%s]: %s\n",
5722 lp_const_servicename(snum), win_errstr(result));
5723 result = WERR_INVALID_PRINTER_NAME;
5724 goto done;
5725 }
5726
5727 if (pinfo2->drivername == NULL || pinfo2->drivername[0] == '\0') {
5728 return WERR_UNKNOWN_PRINTER_DRIVER;
5729 }
5730
5731 DBG_INFO("Construct printer driver [%s] for [%s]\n",
5732 pinfo2->drivername,
5733 pinfo2->sharename);
5734
5735 result = winreg_get_driver(tmp_ctx, b,
5736 architecture,
5737 pinfo2->drivername, version, &driver);
5738
5739 DBG_INFO("winreg_get_driver() status: %s\n",
5740 win_errstr(result));
5741
5742 if (!W_ERROR_IS_OK(result)) {
5743 /*
5744 * Is this a W2k client ?
5745 */
5746
5747 if (version < 3) {
5748 result = WERR_UNKNOWN_PRINTER_DRIVER;
5749 goto done;
5750 }
5751
5752 /* Yes - try again with a WinNT driver. */
5753 version = 2;
5754 result = winreg_get_driver(tmp_ctx, b,
5755 architecture,
5756 pinfo2->drivername,
5757 version, &driver);
5758 DEBUG(8,("construct_printer_driver_level: status: %s\n",
5759 win_errstr(result)));
5760 if (!W_ERROR_IS_OK(result)) {
5761 result = WERR_UNKNOWN_PRINTER_DRIVER;
5762 goto done;
5763 }
5764 }
5765
5766 /* these are allocated on mem_ctx and not tmp_ctx because they are
5767 * the 'return value' and need to utlive this call */
5768 switch (level) {
5769 case 1:
5770 result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
5771 break;
5772 case 2:
5773 result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
5774 break;
5775 case 3:
5776 result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
5777 break;
5778 case 4:
5779 result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
5780 break;
5781 case 5:
5782 result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
5783 break;
5784 case 6:
5785 result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
5786 break;
5787 case 8:
5788 result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
5789 break;
5790 #if 0 /* disabled until marshalling issues are resolved - gd */
5791 case 101:
5792 result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
5793 break;
5794 #endif
5795 default:
5796 result = WERR_INVALID_LEVEL;
5797 break;
5798 }
5799
5800 done:
5801 talloc_free(tmp_ctx);
5802 return result;
5803 }
5804
5805 /****************************************************************
5806 _spoolss_GetPrinterDriver2
5807 ****************************************************************/
5808
_spoolss_GetPrinterDriver2(struct pipes_struct * p,struct spoolss_GetPrinterDriver2 * r)5809 WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p,
5810 struct spoolss_GetPrinterDriver2 *r)
5811 {
5812 struct printer_handle *printer;
5813 WERROR result;
5814 uint32_t version = r->in.client_major_version;
5815
5816 int snum;
5817
5818 /* that's an [in out] buffer */
5819
5820 if (!r->in.buffer && (r->in.offered != 0)) {
5821 result = WERR_INVALID_PARAMETER;
5822 goto err_info_free;
5823 }
5824
5825 DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5826
5827 if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
5828 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5829 result = WERR_INVALID_PRINTER_NAME;
5830 goto err_info_free;
5831 }
5832
5833 *r->out.needed = 0;
5834 *r->out.server_major_version = 0;
5835 *r->out.server_minor_version = 0;
5836
5837 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5838 result = WERR_INVALID_HANDLE;
5839 goto err_info_free;
5840 }
5841
5842 if (r->in.client_major_version == SPOOLSS_DRIVER_VERSION_2012) {
5843 DEBUG(3,("_spoolss_GetPrinterDriver2: v4 driver requested, "
5844 "downgrading to v3\n"));
5845 version = SPOOLSS_DRIVER_VERSION_200X;
5846 }
5847
5848 result = construct_printer_driver_info_level(p->mem_ctx,
5849 get_session_info_system(),
5850 p->msg_ctx,
5851 r->in.level, r->out.info,
5852 snum, printer->servername,
5853 r->in.architecture,
5854 version);
5855 if (!W_ERROR_IS_OK(result)) {
5856 goto err_info_free;
5857 }
5858
5859 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo,
5860 r->out.info, r->in.level);
5861 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
5862
5863 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
5864
5865 err_info_free:
5866 TALLOC_FREE(r->out.info);
5867 return result;
5868 }
5869
5870
5871 /****************************************************************
5872 _spoolss_StartPagePrinter
5873 ****************************************************************/
5874
_spoolss_StartPagePrinter(struct pipes_struct * p,struct spoolss_StartPagePrinter * r)5875 WERROR _spoolss_StartPagePrinter(struct pipes_struct *p,
5876 struct spoolss_StartPagePrinter *r)
5877 {
5878 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5879
5880 if (!Printer) {
5881 DEBUG(3,("_spoolss_StartPagePrinter: "
5882 "Error in startpageprinter printer handle\n"));
5883 return WERR_INVALID_HANDLE;
5884 }
5885
5886 Printer->page_started = true;
5887 return WERR_OK;
5888 }
5889
5890 /****************************************************************
5891 _spoolss_EndPagePrinter
5892 ****************************************************************/
5893
_spoolss_EndPagePrinter(struct pipes_struct * p,struct spoolss_EndPagePrinter * r)5894 WERROR _spoolss_EndPagePrinter(struct pipes_struct *p,
5895 struct spoolss_EndPagePrinter *r)
5896 {
5897 int snum;
5898
5899 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5900
5901 if (!Printer) {
5902 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5903 OUR_HANDLE(r->in.handle)));
5904 return WERR_INVALID_HANDLE;
5905 }
5906
5907 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5908 return WERR_INVALID_HANDLE;
5909
5910 Printer->page_started = false;
5911 print_job_endpage(p->msg_ctx, snum, Printer->jobid);
5912
5913 return WERR_OK;
5914 }
5915
5916 /****************************************************************
5917 _spoolss_StartDocPrinter
5918 ****************************************************************/
5919
_spoolss_StartDocPrinter(struct pipes_struct * p,struct spoolss_StartDocPrinter * r)5920 WERROR _spoolss_StartDocPrinter(struct pipes_struct *p,
5921 struct spoolss_StartDocPrinter *r)
5922 {
5923 struct spoolss_DocumentInfo1 *info_1;
5924 int snum;
5925 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
5926 WERROR werr;
5927 char *rhost;
5928 int rc;
5929
5930 if (!Printer) {
5931 DEBUG(2,("_spoolss_StartDocPrinter: "
5932 "Invalid handle (%s:%u:%u)\n",
5933 OUR_HANDLE(r->in.handle)));
5934 return WERR_INVALID_HANDLE;
5935 }
5936
5937 if (Printer->jobid) {
5938 DEBUG(2, ("_spoolss_StartDocPrinter: "
5939 "StartDocPrinter called twice! "
5940 "(existing jobid = %d)\n", Printer->jobid));
5941 return WERR_INVALID_HANDLE;
5942 }
5943
5944 if (r->in.info_ctr->level != 1) {
5945 return WERR_INVALID_LEVEL;
5946 }
5947
5948 info_1 = r->in.info_ctr->info.info1;
5949
5950 /*
5951 * a nice thing with NT is it doesn't listen to what you tell it.
5952 * when asked to send _only_ RAW datas, it tries to send datas
5953 * in EMF format.
5954 *
5955 * So I add checks like in NT Server ...
5956 */
5957
5958 if (info_1->datatype) {
5959 /*
5960 * The v4 driver model used in Windows 8 declares print jobs
5961 * intended to bypass the XPS processing layer by setting
5962 * datatype to "XPS_PASS" instead of "RAW".
5963 */
5964 if ((strcmp(info_1->datatype, "RAW") != 0)
5965 && (strcmp(info_1->datatype, "XPS_PASS") != 0)) {
5966 *r->out.job_id = 0;
5967 return WERR_INVALID_DATATYPE;
5968 }
5969 }
5970
5971 /* get the share number of the printer */
5972 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5973 return WERR_INVALID_HANDLE;
5974 }
5975
5976 rc = get_remote_hostname(p->remote_address,
5977 &rhost,
5978 p->mem_ctx);
5979 if (rc < 0) {
5980 return WERR_NOT_ENOUGH_MEMORY;
5981 }
5982 if (strequal(rhost,"UNKNOWN")) {
5983 rhost = tsocket_address_inet_addr_string(p->remote_address,
5984 p->mem_ctx);
5985 if (rhost == NULL) {
5986 return WERR_NOT_ENOUGH_MEMORY;
5987 }
5988 }
5989
5990 werr = print_job_start(p->session_info,
5991 p->msg_ctx,
5992 rhost,
5993 snum,
5994 info_1->document_name,
5995 info_1->output_file,
5996 Printer->devmode,
5997 &Printer->jobid);
5998
5999 /* An error occurred in print_job_start() so return an appropriate
6000 NT error code. */
6001
6002 if (!W_ERROR_IS_OK(werr)) {
6003 return werr;
6004 }
6005
6006 Printer->document_started = true;
6007 *r->out.job_id = Printer->jobid;
6008
6009 return WERR_OK;
6010 }
6011
6012 /****************************************************************
6013 _spoolss_EndDocPrinter
6014 ****************************************************************/
6015
_spoolss_EndDocPrinter(struct pipes_struct * p,struct spoolss_EndDocPrinter * r)6016 WERROR _spoolss_EndDocPrinter(struct pipes_struct *p,
6017 struct spoolss_EndDocPrinter *r)
6018 {
6019 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
6020 NTSTATUS status;
6021 int snum;
6022
6023 if (!Printer) {
6024 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
6025 OUR_HANDLE(r->in.handle)));
6026 return WERR_INVALID_HANDLE;
6027 }
6028
6029 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6030 return WERR_INVALID_HANDLE;
6031 }
6032
6033 Printer->document_started = false;
6034 status = print_job_end(p->msg_ctx, snum, Printer->jobid, NORMAL_CLOSE);
6035 if (!NT_STATUS_IS_OK(status)) {
6036 DEBUG(2, ("_spoolss_EndDocPrinter: "
6037 "print_job_end failed [%s]\n",
6038 nt_errstr(status)));
6039 }
6040
6041 Printer->jobid = 0;
6042 return ntstatus_to_werror(status);
6043 }
6044
6045 /****************************************************************
6046 _spoolss_WritePrinter
6047 ****************************************************************/
6048
_spoolss_WritePrinter(struct pipes_struct * p,struct spoolss_WritePrinter * r)6049 WERROR _spoolss_WritePrinter(struct pipes_struct *p,
6050 struct spoolss_WritePrinter *r)
6051 {
6052 ssize_t buffer_written;
6053 int snum;
6054 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
6055
6056 if (!Printer) {
6057 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
6058 OUR_HANDLE(r->in.handle)));
6059 *r->out.num_written = r->in._data_size;
6060 return WERR_INVALID_HANDLE;
6061 }
6062
6063 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
6064 return WERR_INVALID_HANDLE;
6065
6066 /* print_job_write takes care of checking for PJOB_SMBD_SPOOLING */
6067 buffer_written = print_job_write(global_event_context(),p->msg_ctx,
6068 snum, Printer->jobid,
6069 (const char *)r->in.data.data,
6070 (size_t)r->in._data_size);
6071 if (buffer_written == (ssize_t)-1) {
6072 *r->out.num_written = 0;
6073 if (errno == ENOSPC)
6074 return WERR_NO_SPOOL_SPACE;
6075 else
6076 return WERR_ACCESS_DENIED;
6077 }
6078
6079 *r->out.num_written = r->in._data_size;
6080
6081 return WERR_OK;
6082 }
6083
6084 /********************************************************************
6085 * api_spoolss_getprinter
6086 * called from the spoolss dispatcher
6087 *
6088 ********************************************************************/
6089
control_printer(struct policy_handle * handle,uint32_t command,struct pipes_struct * p)6090 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
6091 struct pipes_struct *p)
6092 {
6093 const struct auth_session_info *session_info = p->session_info;
6094 int snum;
6095 WERROR errcode = WERR_INVALID_FUNCTION;
6096 struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
6097
6098 if (!Printer) {
6099 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
6100 OUR_HANDLE(handle)));
6101 return WERR_INVALID_HANDLE;
6102 }
6103
6104 if (!get_printer_snum(p, handle, &snum, NULL))
6105 return WERR_INVALID_HANDLE;
6106
6107 switch (command) {
6108 case SPOOLSS_PRINTER_CONTROL_PAUSE:
6109 errcode = print_queue_pause(session_info, p->msg_ctx, snum);
6110 break;
6111 case SPOOLSS_PRINTER_CONTROL_RESUME:
6112 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
6113 errcode = print_queue_resume(session_info, p->msg_ctx, snum);
6114 break;
6115 case SPOOLSS_PRINTER_CONTROL_PURGE:
6116 errcode = print_queue_purge(session_info, p->msg_ctx, snum);
6117 break;
6118 default:
6119 return WERR_INVALID_LEVEL;
6120 }
6121
6122 return errcode;
6123 }
6124
6125
6126 /****************************************************************
6127 _spoolss_AbortPrinter
6128 * From MSDN: "Deletes printer's spool file if printer is configured
6129 * for spooling"
6130 ****************************************************************/
6131
_spoolss_AbortPrinter(struct pipes_struct * p,struct spoolss_AbortPrinter * r)6132 WERROR _spoolss_AbortPrinter(struct pipes_struct *p,
6133 struct spoolss_AbortPrinter *r)
6134 {
6135 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
6136 int snum;
6137 WERROR errcode = WERR_OK;
6138
6139 if (!Printer) {
6140 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
6141 OUR_HANDLE(r->in.handle)));
6142 return WERR_INVALID_HANDLE;
6143 }
6144
6145 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
6146 return WERR_INVALID_HANDLE;
6147
6148 if (!Printer->document_started) {
6149 return WERR_SPL_NO_STARTDOC;
6150 }
6151
6152 errcode = print_job_delete(p->session_info,
6153 p->msg_ctx,
6154 snum,
6155 Printer->jobid);
6156
6157 return errcode;
6158 }
6159
6160 /********************************************************************
6161 * called by spoolss_api_setprinter
6162 * when updating a printer description
6163 ********************************************************************/
6164
update_printer_sec(struct policy_handle * handle,struct pipes_struct * p,struct sec_desc_buf * secdesc_ctr)6165 static WERROR update_printer_sec(struct policy_handle *handle,
6166 struct pipes_struct *p,
6167 struct sec_desc_buf *secdesc_ctr)
6168 {
6169 struct spoolss_security_descriptor *new_secdesc = NULL;
6170 struct spoolss_security_descriptor *old_secdesc = NULL;
6171 const char *printer = NULL;
6172 WERROR result;
6173 int snum = -1;
6174 struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
6175 struct dcerpc_binding_handle *b;
6176 TALLOC_CTX *tmp_ctx = NULL;
6177 bool ok = false;
6178
6179 if (!Printer) {
6180 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
6181 OUR_HANDLE(handle)));
6182
6183 result = WERR_INVALID_HANDLE;
6184 goto done;
6185 }
6186
6187 if (secdesc_ctr == NULL) {
6188 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
6189 result = WERR_INVALID_PARAMETER;
6190 goto done;
6191 }
6192
6193 switch (Printer->printer_type) {
6194 case SPLHND_SERVER:
6195 break;
6196 case SPLHND_PRINTER:
6197 if (!get_printer_snum(p, handle, &snum, NULL)) {
6198 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
6199 OUR_HANDLE(handle)));
6200 result = WERR_INVALID_HANDLE;
6201 goto done;
6202 }
6203 printer = lp_const_servicename(snum);
6204 break;
6205 default:
6206 break;
6207 }
6208
6209 /* Check the user has permissions to change the security
6210 descriptor. By experimentation with two NT machines, the user
6211 requires Full Access to the printer to change security
6212 information. */
6213
6214 switch (Printer->printer_type) {
6215 case SPLHND_SERVER:
6216 ok = Printer->access_granted == SERVER_ACCESS_ADMINISTER;
6217 break;
6218 case SPLHND_PRINTER:
6219 ok = Printer->access_granted == PRINTER_ACCESS_ADMINISTER;
6220 break;
6221 default:
6222 break;
6223 }
6224
6225 if (!ok) {
6226 DEBUG(4,("update_printer_sec: updated denied by printer permissions "
6227 "(access_granted: 0x%08x)\n", Printer->access_granted));
6228 result = WERR_ACCESS_DENIED;
6229 goto done;
6230 }
6231
6232 tmp_ctx = talloc_new(p->mem_ctx);
6233 if (!tmp_ctx) {
6234 return WERR_NOT_ENOUGH_MEMORY;
6235 }
6236
6237 result = winreg_printer_binding_handle(tmp_ctx,
6238 get_session_info_system(),
6239 p->msg_ctx,
6240 &b);
6241 if (!W_ERROR_IS_OK(result)) {
6242 goto done;
6243 }
6244
6245 /* NT seems to like setting the security descriptor even though
6246 nothing may have actually changed. */
6247
6248 if (printer != NULL) {
6249 result = winreg_get_printer_secdesc(tmp_ctx, b,
6250 printer,
6251 &old_secdesc);
6252 } else {
6253 result = winreg_get_printserver_secdesc(tmp_ctx, b,
6254 &old_secdesc);
6255 }
6256 if (!W_ERROR_IS_OK(result)) {
6257 DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc_internal() failed\n"));
6258 result = WERR_INVALID_HANDLE;
6259 goto done;
6260 }
6261
6262 if (DEBUGLEVEL >= 10) {
6263 struct dom_sid_buf buf;
6264 struct security_acl *the_acl;
6265 int i;
6266
6267 the_acl = old_secdesc->dacl;
6268 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
6269 printer, the_acl->num_aces));
6270
6271 for (i = 0; i < the_acl->num_aces; i++) {
6272 DEBUG(10, ("%s 0x%08x\n",
6273 dom_sid_str_buf(
6274 &the_acl->aces[i].trustee,
6275 &buf),
6276 the_acl->aces[i].access_mask));
6277 }
6278
6279 the_acl = secdesc_ctr->sd->dacl;
6280
6281 if (the_acl) {
6282 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
6283 printer, the_acl->num_aces));
6284
6285 for (i = 0; i < the_acl->num_aces; i++) {
6286 DEBUG(10, ("%s 0x%08x\n",
6287 dom_sid_str_buf(
6288 &the_acl->aces[i].trustee,
6289 &buf),
6290 the_acl->aces[i].access_mask));
6291 }
6292 } else {
6293 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
6294 }
6295 }
6296
6297 new_secdesc = sec_desc_merge(tmp_ctx, secdesc_ctr->sd, old_secdesc);
6298 if (new_secdesc == NULL) {
6299 result = WERR_NOT_ENOUGH_MEMORY;
6300 goto done;
6301 }
6302
6303 if (security_descriptor_equal(new_secdesc, old_secdesc)) {
6304 result = WERR_OK;
6305 goto done;
6306 }
6307
6308 if (printer != NULL) {
6309 result = winreg_set_printer_secdesc(tmp_ctx, b,
6310 printer,
6311 new_secdesc);
6312 } else {
6313 result = winreg_set_printserver_secdesc(tmp_ctx, b,
6314 new_secdesc);
6315 }
6316
6317 done:
6318 talloc_free(tmp_ctx);
6319 return result;
6320 }
6321
6322 /********************************************************************
6323 Canonicalize printer info from a client
6324 ********************************************************************/
6325
check_printer_ok(TALLOC_CTX * mem_ctx,struct spoolss_SetPrinterInfo2 * info2,int snum)6326 static bool check_printer_ok(TALLOC_CTX *mem_ctx,
6327 struct spoolss_SetPrinterInfo2 *info2,
6328 int snum)
6329 {
6330 fstring printername;
6331 const char *p;
6332
6333 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
6334 "portname=%s drivername=%s comment=%s location=%s\n",
6335 info2->servername, info2->printername, info2->sharename,
6336 info2->portname, info2->drivername, info2->comment,
6337 info2->location));
6338
6339 /* we force some elements to "correct" values */
6340 info2->servername = talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name());
6341 if (info2->servername == NULL) {
6342 return false;
6343 }
6344 info2->sharename = talloc_strdup(mem_ctx, lp_const_servicename(snum));
6345 if (info2->sharename == NULL) {
6346 return false;
6347 }
6348
6349 /* check to see if we allow printername != sharename */
6350 if (lp_force_printername(snum)) {
6351 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
6352 lp_netbios_name(), info2->sharename);
6353 } else {
6354 /* make sure printername is in \\server\printername format */
6355 fstrcpy(printername, info2->printername);
6356 p = printername;
6357 if ( printername[0] == '\\' && printername[1] == '\\' ) {
6358 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
6359 p++;
6360 }
6361
6362 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
6363 lp_netbios_name(), p);
6364 }
6365 if (info2->printername == NULL) {
6366 return false;
6367 }
6368
6369 info2->attributes |= PRINTER_ATTRIBUTE_SAMBA;
6370 info2->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
6371
6372 return true;
6373 }
6374
6375 /****************************************************************************
6376 ****************************************************************************/
6377
add_port_hook(TALLOC_CTX * ctx,struct security_token * token,const char * portname,const char * uri)6378 static WERROR add_port_hook(TALLOC_CTX *ctx, struct security_token *token, const char *portname, const char *uri)
6379 {
6380 const struct loadparm_substitution *lp_sub =
6381 loadparm_s3_global_substitution();
6382 char *cmd = lp_addport_command(talloc_tos(), lp_sub);
6383 char *command = NULL;
6384 int ret;
6385 bool is_print_op = false;
6386
6387 if ( !*cmd ) {
6388 return WERR_ACCESS_DENIED;
6389 }
6390
6391 command = talloc_asprintf(ctx,
6392 "%s \"%s\" \"%s\"", cmd, portname, uri );
6393 if (!command) {
6394 return WERR_NOT_ENOUGH_MEMORY;
6395 }
6396
6397 if ( token )
6398 is_print_op = security_token_has_privilege(token, SEC_PRIV_PRINT_OPERATOR);
6399
6400 DEBUG(10,("Running [%s]\n", command));
6401
6402 /********* BEGIN SePrintOperatorPrivilege **********/
6403
6404 if ( is_print_op )
6405 become_root();
6406
6407 ret = smbrun(command, NULL, NULL);
6408
6409 if ( is_print_op )
6410 unbecome_root();
6411
6412 /********* END SePrintOperatorPrivilege **********/
6413
6414 DEBUGADD(10,("returned [%d]\n", ret));
6415
6416 TALLOC_FREE(command);
6417
6418 if ( ret != 0 ) {
6419 return WERR_ACCESS_DENIED;
6420 }
6421
6422 return WERR_OK;
6423 }
6424
6425 /****************************************************************************
6426 ****************************************************************************/
6427
spoolss_conn_snum_used(struct smbd_server_connection * sconn,int snum)6428 static bool spoolss_conn_snum_used(struct smbd_server_connection *sconn,
6429 int snum)
6430 {
6431 /*
6432 * As we do not know if we are embedded in the file server process
6433 * or not, we have to pretend that all shares are in use.
6434 */
6435 return true;
6436 }
6437
add_printer_hook(TALLOC_CTX * ctx,struct security_token * token,struct spoolss_SetPrinterInfo2 * info2,const char * remote_machine,struct messaging_context * msg_ctx)6438 static bool add_printer_hook(TALLOC_CTX *ctx, struct security_token *token,
6439 struct spoolss_SetPrinterInfo2 *info2,
6440 const char *remote_machine,
6441 struct messaging_context *msg_ctx)
6442 {
6443 const struct loadparm_substitution *lp_sub =
6444 loadparm_s3_global_substitution();
6445 char *cmd = lp_addprinter_command(talloc_tos(), lp_sub);
6446 char **qlines;
6447 char *command = NULL;
6448 int numlines;
6449 int ret;
6450 int fd;
6451 bool is_print_op = false;
6452
6453 if (!remote_machine) {
6454 return false;
6455 }
6456
6457 command = talloc_asprintf(ctx,
6458 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6459 cmd, info2->printername, info2->sharename,
6460 info2->portname, info2->drivername,
6461 info2->location, info2->comment, remote_machine);
6462 if (!command) {
6463 return false;
6464 }
6465
6466 if ( token )
6467 is_print_op = security_token_has_privilege(token, SEC_PRIV_PRINT_OPERATOR);
6468
6469 DEBUG(10,("Running [%s]\n", command));
6470
6471 /********* BEGIN SePrintOperatorPrivilege **********/
6472
6473 if ( is_print_op )
6474 become_root();
6475
6476 ret = smbrun(command, &fd, NULL);
6477 if (ret == 0) {
6478 /* Tell everyone we updated smb.conf. */
6479 messaging_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0);
6480 }
6481
6482 if ( is_print_op )
6483 unbecome_root();
6484
6485 /********* END SePrintOperatorPrivilege **********/
6486
6487 DEBUGADD(10,("returned [%d]\n", ret));
6488
6489 TALLOC_FREE(command);
6490
6491 if ( ret != 0 ) {
6492 if (fd != -1)
6493 close(fd);
6494 return false;
6495 }
6496
6497 /* reload our services immediately */
6498 become_root();
6499 reload_services(NULL, spoolss_conn_snum_used, false);
6500 unbecome_root();
6501
6502 numlines = 0;
6503 /* Get lines and convert them back to dos-codepage */
6504 qlines = fd_lines_load(fd, &numlines, 0, NULL);
6505 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
6506 close(fd);
6507
6508 /* Set the portname to what the script says the portname should be. */
6509 /* but don't require anything to be return from the script exit a good error code */
6510
6511 if (numlines) {
6512 /* Set the portname to what the script says the portname should be. */
6513 info2->portname = talloc_strdup(ctx, qlines[0]);
6514 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
6515 }
6516
6517 TALLOC_FREE(qlines);
6518 return true;
6519 }
6520
update_dsspooler(TALLOC_CTX * mem_ctx,const struct auth_session_info * session_info,struct messaging_context * msg_ctx,int snum,struct spoolss_SetPrinterInfo2 * printer,struct spoolss_PrinterInfo2 * old_printer)6521 static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
6522 const struct auth_session_info *session_info,
6523 struct messaging_context *msg_ctx,
6524 int snum,
6525 struct spoolss_SetPrinterInfo2 *printer,
6526 struct spoolss_PrinterInfo2 *old_printer)
6527 {
6528 bool force_update = (old_printer == NULL);
6529 const char *dnsdomname;
6530 const char *longname;
6531 const char *uncname;
6532 const char *spooling;
6533 DATA_BLOB buffer;
6534 WERROR result = WERR_OK;
6535 struct dcerpc_binding_handle *b;
6536 TALLOC_CTX *tmp_ctx;
6537 bool ok;
6538
6539 tmp_ctx = talloc_new(mem_ctx);
6540 if (!tmp_ctx) {
6541 return WERR_NOT_ENOUGH_MEMORY;
6542 }
6543
6544 result = winreg_printer_binding_handle(tmp_ctx,
6545 session_info,
6546 msg_ctx,
6547 &b);
6548 if (!W_ERROR_IS_OK(result)) {
6549 goto done;
6550 }
6551
6552 if (printer->drivername != NULL &&
6553 (force_update ||
6554 !strequal(printer->drivername, old_printer->drivername))) {
6555 ok = push_reg_sz(tmp_ctx, &buffer, printer->drivername);
6556 if (!ok) {
6557 DEBUG(0, ("%s data corrupted\n", SPOOL_REG_DRIVERNAME));
6558 result = WERR_INVALID_DATA;
6559 goto done;
6560 }
6561 result = winreg_set_printer_dataex(tmp_ctx, b,
6562 printer->sharename,
6563 SPOOL_DSSPOOLER_KEY,
6564 SPOOL_REG_DRIVERNAME,
6565 REG_SZ,
6566 buffer.data,
6567 buffer.length);
6568 if (!W_ERROR_IS_OK(result)) {
6569 DEBUG(0, ("Failed to set %s\n", SPOOL_REG_DRIVERNAME));
6570 goto done;
6571 }
6572
6573 if (!force_update) {
6574 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6575 printer->drivername));
6576
6577 notify_printer_driver(global_event_context(), msg_ctx,
6578 snum, printer->drivername ?
6579 printer->drivername : "");
6580 }
6581 }
6582
6583 if (printer->comment != NULL &&
6584 (force_update ||
6585 !strequal(printer->comment, old_printer->comment))) {
6586 ok = push_reg_sz(tmp_ctx, &buffer, printer->comment);
6587 if (!ok) {
6588 DEBUG(0, ("comment data corrupted\n"));
6589 result = WERR_INVALID_DATA;
6590 goto done;
6591 }
6592 result = winreg_set_printer_dataex(tmp_ctx, b,
6593 printer->sharename,
6594 SPOOL_DSSPOOLER_KEY,
6595 SPOOL_REG_DESCRIPTION,
6596 REG_SZ,
6597 buffer.data,
6598 buffer.length);
6599 if (!W_ERROR_IS_OK(result)) {
6600 DEBUG(0, ("Failed to set %s\n", SPOOL_REG_DESCRIPTION));
6601 goto done;
6602 }
6603
6604 if (!force_update) {
6605 notify_printer_comment(global_event_context(), msg_ctx,
6606 snum, printer->comment ?
6607 printer->comment : "");
6608 }
6609 }
6610
6611 if (printer->sharename != NULL &&
6612 (force_update ||
6613 !strequal(printer->sharename, old_printer->sharename))) {
6614 ok = push_reg_sz(tmp_ctx, &buffer, printer->sharename);
6615 if (!ok) {
6616 DEBUG(0, ("sharename data corrupted\n"));
6617 result = WERR_INVALID_DATA;
6618 goto done;
6619 }
6620 result = winreg_set_printer_dataex(tmp_ctx, b,
6621 printer->sharename,
6622 SPOOL_DSSPOOLER_KEY,
6623 SPOOL_REG_PRINTSHARENAME,
6624 REG_SZ,
6625 buffer.data,
6626 buffer.length);
6627 if (!W_ERROR_IS_OK(result)) {
6628 DEBUG(0, ("Failed to set %s\n", SPOOL_REG_PRINTSHARENAME));
6629 goto done;
6630 }
6631
6632 if (!force_update) {
6633 notify_printer_sharename(global_event_context(),
6634 msg_ctx,
6635 snum, printer->sharename ?
6636 printer->sharename : "");
6637 }
6638
6639 /* name change, purge any cache entries for the old */
6640 prune_printername_cache();
6641 }
6642
6643 if (printer->printername != NULL &&
6644 (force_update ||
6645 !strequal(printer->printername, old_printer->printername))) {
6646 const char *p;
6647
6648 p = strrchr(printer->printername, '\\' );
6649 if (p != NULL) {
6650 p++;
6651 } else {
6652 p = printer->printername;
6653 }
6654
6655 ok = push_reg_sz(tmp_ctx, &buffer, p);
6656 if (!ok) {
6657 DEBUG(0, ("printername data corrupted\n"));
6658 result = WERR_INVALID_DATA;
6659 goto done;
6660 }
6661 result = winreg_set_printer_dataex(tmp_ctx, b,
6662 printer->sharename,
6663 SPOOL_DSSPOOLER_KEY,
6664 SPOOL_REG_PRINTERNAME,
6665 REG_SZ,
6666 buffer.data,
6667 buffer.length);
6668 if (!W_ERROR_IS_OK(result)) {
6669 DEBUG(0, ("Failed to set %s\n", SPOOL_REG_PRINTSHARENAME));
6670 goto done;
6671 }
6672
6673 if (!force_update) {
6674 notify_printer_printername(global_event_context(),
6675 msg_ctx, snum, p ? p : "");
6676 }
6677
6678 /* name change, purge any cache entries for the old */
6679 prune_printername_cache();
6680 }
6681
6682 if (printer->portname != NULL &&
6683 (force_update ||
6684 !strequal(printer->portname, old_printer->portname))) {
6685 ok = push_reg_sz(tmp_ctx, &buffer, printer->portname);
6686 if (!ok) {
6687 DEBUG(0, ("portname data corrupted\n"));
6688 result = WERR_INVALID_DATA;
6689 goto done;
6690 }
6691 result = winreg_set_printer_dataex(tmp_ctx, b,
6692 printer->sharename,
6693 SPOOL_DSSPOOLER_KEY,
6694 SPOOL_REG_PORTNAME,
6695 REG_SZ,
6696 buffer.data,
6697 buffer.length);
6698 if (!W_ERROR_IS_OK(result)) {
6699 DEBUG(0, ("Failed to set %s\n", SPOOL_REG_PORTNAME));
6700 goto done;
6701 }
6702
6703 if (!force_update) {
6704 notify_printer_port(global_event_context(),
6705 msg_ctx, snum, printer->portname ?
6706 printer->portname : "");
6707 }
6708 }
6709
6710 if (printer->location != NULL &&
6711 (force_update ||
6712 !strequal(printer->location, old_printer->location))) {
6713 ok = push_reg_sz(tmp_ctx, &buffer, printer->location);
6714 if (!ok) {
6715 DEBUG(0, ("location data corrupted\n"));
6716 result = WERR_INVALID_DATA;
6717 goto done;
6718 }
6719 result = winreg_set_printer_dataex(tmp_ctx, b,
6720 printer->sharename,
6721 SPOOL_DSSPOOLER_KEY,
6722 SPOOL_REG_LOCATION,
6723 REG_SZ,
6724 buffer.data,
6725 buffer.length);
6726 if (!W_ERROR_IS_OK(result)) {
6727 DEBUG(0, ("Failed to set %s\n", SPOOL_REG_LOCATION));
6728 goto done;
6729 }
6730
6731 if (!force_update) {
6732 notify_printer_location(global_event_context(),
6733 msg_ctx, snum,
6734 printer->location ?
6735 printer->location : "");
6736 }
6737 }
6738
6739 if (printer->sepfile != NULL &&
6740 (force_update ||
6741 !strequal(printer->sepfile, old_printer->sepfile))) {
6742 ok = push_reg_sz(tmp_ctx, &buffer, printer->sepfile);
6743 if (!ok) {
6744 DEBUG(0, ("sepfile data corrupted\n"));
6745 result = WERR_INVALID_DATA;
6746 goto done;
6747 }
6748 result = winreg_set_printer_dataex(tmp_ctx, b,
6749 printer->sharename,
6750 SPOOL_DSSPOOLER_KEY,
6751 SPOOL_REG_PRINTSEPARATORFILE,
6752 REG_SZ,
6753 buffer.data,
6754 buffer.length);
6755 if (!W_ERROR_IS_OK(result)) {
6756 DEBUG(0, ("Failed to set %s\n", SPOOL_REG_PRINTSEPARATORFILE));
6757 goto done;
6758 }
6759
6760 if (!force_update) {
6761 notify_printer_sepfile(global_event_context(),
6762 msg_ctx, snum,
6763 printer->sepfile ?
6764 printer->sepfile : "");
6765 }
6766 }
6767
6768 if (printer->starttime != 0 &&
6769 (force_update ||
6770 printer->starttime != old_printer->starttime)) {
6771 buffer = data_blob_talloc(tmp_ctx, NULL, 4);
6772 SIVAL(buffer.data, 0, printer->starttime);
6773 result = winreg_set_printer_dataex(tmp_ctx, b,
6774 printer->sharename,
6775 SPOOL_DSSPOOLER_KEY,
6776 SPOOL_REG_PRINTSTARTTIME,
6777 REG_DWORD,
6778 buffer.data,
6779 buffer.length);
6780 if (!W_ERROR_IS_OK(result)) {
6781 DEBUG(0, ("Failed to set %s\n", SPOOL_REG_PRINTSTARTTIME));
6782 goto done;
6783 }
6784 }
6785
6786 if (printer->untiltime != 0 &&
6787 (force_update ||
6788 printer->untiltime != old_printer->untiltime)) {
6789 buffer = data_blob_talloc(tmp_ctx, NULL, 4);
6790 SIVAL(buffer.data, 0, printer->untiltime);
6791 result = winreg_set_printer_dataex(tmp_ctx, b,
6792 printer->sharename,
6793 SPOOL_DSSPOOLER_KEY,
6794 SPOOL_REG_PRINTENDTIME,
6795 REG_DWORD,
6796 buffer.data,
6797 buffer.length);
6798 if (!W_ERROR_IS_OK(result)) {
6799 DEBUG(0, ("Failed to set %s\n", SPOOL_REG_PRINTENDTIME));
6800 goto done;
6801 }
6802 }
6803
6804 if (force_update || printer->priority != old_printer->priority) {
6805 buffer = data_blob_talloc(tmp_ctx, NULL, 4);
6806 SIVAL(buffer.data, 0, printer->priority);
6807 result = winreg_set_printer_dataex(tmp_ctx, b,
6808 printer->sharename,
6809 SPOOL_DSSPOOLER_KEY,
6810 SPOOL_REG_PRIORITY,
6811 REG_DWORD,
6812 buffer.data,
6813 buffer.length);
6814 if (!W_ERROR_IS_OK(result)) {
6815 DEBUG(0, ("Failed to set %s\n", SPOOL_REG_PRINTENDTIME));
6816 goto done;
6817 }
6818 }
6819
6820 if (force_update || printer->attributes != old_printer->attributes) {
6821 buffer = data_blob_talloc(tmp_ctx, NULL, 4);
6822 SIVAL(buffer.data, 0, (printer->attributes &
6823 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
6824 result = winreg_set_printer_dataex(tmp_ctx, b,
6825 printer->sharename,
6826 SPOOL_DSSPOOLER_KEY,
6827 SPOOL_REG_PRINTKEEPPRINTEDJOBS,
6828 REG_DWORD,
6829 buffer.data,
6830 buffer.length);
6831 if (!W_ERROR_IS_OK(result)) {
6832 DEBUG(0, ("Failed to set %s\n", SPOOL_REG_PRINTENDTIME));
6833 goto done;
6834 }
6835
6836 switch (printer->attributes & 0x3) {
6837 case 0:
6838 spooling = SPOOL_REGVAL_PRINTWHILESPOOLING;
6839 break;
6840 case 1:
6841 spooling = SPOOL_REGVAL_PRINTAFTERSPOOLED;
6842 break;
6843 case 2:
6844 spooling = SPOOL_REGVAL_PRINTDIRECT;
6845 break;
6846 default:
6847 spooling = "unknown";
6848 }
6849 ok = push_reg_sz(tmp_ctx, &buffer, spooling);
6850 if (!ok) {
6851 DEBUG(0, ("printSpooling data corrupted\n"));
6852 result = WERR_INVALID_DATA;
6853 goto done;
6854 }
6855 winreg_set_printer_dataex(tmp_ctx, b,
6856 printer->sharename,
6857 SPOOL_DSSPOOLER_KEY,
6858 SPOOL_REG_PRINTSPOOLING,
6859 REG_SZ,
6860 buffer.data,
6861 buffer.length);
6862 }
6863
6864 ok = push_reg_sz(tmp_ctx, &buffer, lp_netbios_name());
6865 if (!ok) {
6866 DEBUG(0, ("shortServerName data corrupted\n"));
6867 result = WERR_INVALID_DATA;
6868 goto done;
6869 }
6870 result = winreg_set_printer_dataex(tmp_ctx, b,
6871 printer->sharename,
6872 SPOOL_DSSPOOLER_KEY,
6873 SPOOL_REG_SHORTSERVERNAME,
6874 REG_SZ,
6875 buffer.data,
6876 buffer.length);
6877 if (!W_ERROR_IS_OK(result)) {
6878 DEBUG(0, ("Failed to set %s\n", SPOOL_REG_SHORTSERVERNAME));
6879 goto done;
6880 }
6881
6882 dnsdomname = get_mydnsfullname();
6883 if (dnsdomname != NULL && dnsdomname[0] != '\0') {
6884 longname = talloc_strdup(tmp_ctx, dnsdomname);
6885 } else {
6886 longname = talloc_strdup(tmp_ctx, lp_netbios_name());
6887 }
6888 if (longname == NULL) {
6889 result = WERR_NOT_ENOUGH_MEMORY;
6890 goto done;
6891 }
6892
6893 ok = push_reg_sz(tmp_ctx, &buffer, longname);
6894 if (!ok) {
6895 DEBUG(0, ("longname data corrupted\n"));
6896 result = WERR_INVALID_DATA;
6897 goto done;
6898 }
6899 result = winreg_set_printer_dataex(tmp_ctx, b,
6900 printer->sharename,
6901 SPOOL_DSSPOOLER_KEY,
6902 SPOOL_REG_SERVERNAME,
6903 REG_SZ,
6904 buffer.data,
6905 buffer.length);
6906 if (!W_ERROR_IS_OK(result)) {
6907 DEBUG(0, ("Failed to set %s\n", SPOOL_REG_SERVERNAME));
6908 goto done;
6909 }
6910
6911 uncname = talloc_asprintf(tmp_ctx, "\\\\%s\\%s",
6912 lp_netbios_name(), printer->sharename);
6913 ok = push_reg_sz(tmp_ctx, &buffer, uncname);
6914 if (!ok) {
6915 DEBUG(0, ("uncName data corrupted\n"));
6916 result = WERR_INVALID_DATA;
6917 goto done;
6918 }
6919 result = winreg_set_printer_dataex(tmp_ctx, b,
6920 printer->sharename,
6921 SPOOL_DSSPOOLER_KEY,
6922 SPOOL_REG_UNCNAME,
6923 REG_SZ,
6924 buffer.data,
6925 buffer.length);
6926 if (!W_ERROR_IS_OK(result)) {
6927 DEBUG(0, ("Failed to set %s\n", SPOOL_REG_UNCNAME));
6928 goto done;
6929 }
6930
6931 done:
6932 talloc_free(tmp_ctx);
6933 return result;
6934 }
6935
6936 /********************************************************************
6937 * Called by spoolss_api_setprinter
6938 * when updating a printer description.
6939 ********************************************************************/
6940
update_printer(struct pipes_struct * p,struct policy_handle * handle,struct spoolss_SetPrinterInfoCtr * info_ctr,struct spoolss_DeviceMode * devmode)6941 static WERROR update_printer(struct pipes_struct *p,
6942 struct policy_handle *handle,
6943 struct spoolss_SetPrinterInfoCtr *info_ctr,
6944 struct spoolss_DeviceMode *devmode)
6945 {
6946 uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
6947 struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
6948 struct spoolss_PrinterInfo2 *old_printer;
6949 struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
6950 const struct loadparm_substitution *lp_sub =
6951 loadparm_s3_global_substitution();
6952 int snum;
6953 WERROR result = WERR_OK;
6954 TALLOC_CTX *tmp_ctx;
6955 struct dcerpc_binding_handle *b;
6956
6957 DEBUG(8,("update_printer\n"));
6958
6959 tmp_ctx = talloc_new(p->mem_ctx);
6960 if (tmp_ctx == NULL) {
6961 return WERR_NOT_ENOUGH_MEMORY;
6962 }
6963
6964 if (!Printer) {
6965 result = WERR_INVALID_HANDLE;
6966 goto done;
6967 }
6968
6969 if (!get_printer_snum(p, handle, &snum, NULL)) {
6970 result = WERR_INVALID_HANDLE;
6971 goto done;
6972 }
6973
6974 result = winreg_printer_binding_handle(tmp_ctx,
6975 get_session_info_system(),
6976 p->msg_ctx,
6977 &b);
6978 if (!W_ERROR_IS_OK(result)) {
6979 goto done;
6980 }
6981
6982 result = winreg_get_printer(tmp_ctx, b,
6983 lp_const_servicename(snum),
6984 &old_printer);
6985 if (!W_ERROR_IS_OK(result)) {
6986 result = WERR_INVALID_HANDLE;
6987 goto done;
6988 }
6989
6990 /* Do sanity check on the requested changes for Samba */
6991 if (!check_printer_ok(tmp_ctx, printer, snum)) {
6992 result = WERR_INVALID_PARAMETER;
6993 goto done;
6994 }
6995
6996 /* FIXME!!! If the driver has changed we really should verify that
6997 it is installed before doing much else --jerry */
6998
6999 /* Check calling user has permission to update printer description */
7000 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
7001 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
7002 result = WERR_ACCESS_DENIED;
7003 goto done;
7004 }
7005
7006 /* Call addprinter hook */
7007 /* Check changes to see if this is really needed */
7008
7009 if (*lp_addprinter_command(talloc_tos(), lp_sub) &&
7010 (!strequal(printer->drivername, old_printer->drivername) ||
7011 !strequal(printer->comment, old_printer->comment) ||
7012 !strequal(printer->portname, old_printer->portname) ||
7013 !strequal(printer->location, old_printer->location)) )
7014 {
7015 char *raddr;
7016
7017 raddr = tsocket_address_inet_addr_string(p->remote_address,
7018 p->mem_ctx);
7019 if (raddr == NULL) {
7020 return WERR_NOT_ENOUGH_MEMORY;
7021 }
7022
7023 /* add_printer_hook() will call reload_services() */
7024 if (!add_printer_hook(tmp_ctx, p->session_info->security_token,
7025 printer, raddr,
7026 p->msg_ctx)) {
7027 result = WERR_ACCESS_DENIED;
7028 goto done;
7029 }
7030 }
7031
7032 result = update_dsspooler(tmp_ctx,
7033 get_session_info_system(),
7034 p->msg_ctx,
7035 snum,
7036 printer,
7037 old_printer);
7038 if (!W_ERROR_IS_OK(result)) {
7039 goto done;
7040 }
7041
7042 printer_mask &= ~SPOOLSS_PRINTER_INFO_SECDESC;
7043
7044 if (devmode == NULL) {
7045 printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
7046 }
7047 result = winreg_update_printer(tmp_ctx, b,
7048 printer->sharename,
7049 printer_mask,
7050 printer,
7051 devmode,
7052 NULL);
7053
7054 done:
7055 talloc_free(tmp_ctx);
7056
7057 return result;
7058 }
7059
7060 /****************************************************************************
7061 ****************************************************************************/
publish_or_unpublish_printer(struct pipes_struct * p,struct policy_handle * handle,struct spoolss_SetPrinterInfo7 * info7)7062 static WERROR publish_or_unpublish_printer(struct pipes_struct *p,
7063 struct policy_handle *handle,
7064 struct spoolss_SetPrinterInfo7 *info7)
7065 {
7066 #ifdef HAVE_ADS
7067 const struct loadparm_substitution *lp_sub =
7068 loadparm_s3_global_substitution();
7069 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
7070 WERROR result;
7071 int snum;
7072 struct printer_handle *Printer;
7073
7074 if ( lp_security() != SEC_ADS ) {
7075 return WERR_INVALID_LEVEL;
7076 }
7077
7078 Printer = find_printer_index_by_hnd(p, handle);
7079
7080 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
7081
7082 if (!Printer)
7083 return WERR_INVALID_HANDLE;
7084
7085 if (!get_printer_snum(p, handle, &snum, NULL))
7086 return WERR_INVALID_HANDLE;
7087
7088 result = winreg_get_printer_internal(p->mem_ctx,
7089 get_session_info_system(),
7090 p->msg_ctx,
7091 lp_servicename(talloc_tos(), lp_sub, snum),
7092 &pinfo2);
7093 if (!W_ERROR_IS_OK(result)) {
7094 return WERR_INVALID_HANDLE;
7095 }
7096
7097 nt_printer_publish(pinfo2,
7098 get_session_info_system(),
7099 p->msg_ctx,
7100 pinfo2,
7101 info7->action);
7102
7103 TALLOC_FREE(pinfo2);
7104 return WERR_OK;
7105 #else
7106 return WERR_INVALID_LEVEL;
7107 #endif
7108 }
7109
7110 /********************************************************************
7111 ********************************************************************/
7112
update_printer_devmode(struct pipes_struct * p,struct policy_handle * handle,struct spoolss_DeviceMode * devmode)7113 static WERROR update_printer_devmode(struct pipes_struct *p,
7114 struct policy_handle *handle,
7115 struct spoolss_DeviceMode *devmode)
7116 {
7117 int snum;
7118 struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
7119 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_DEVMODE;
7120
7121 DEBUG(8,("update_printer_devmode\n"));
7122
7123 if (!Printer) {
7124 return WERR_INVALID_HANDLE;
7125 }
7126
7127 if (!get_printer_snum(p, handle, &snum, NULL)) {
7128 return WERR_INVALID_HANDLE;
7129 }
7130
7131 /* Check calling user has permission to update printer description */
7132 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
7133 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
7134 return WERR_ACCESS_DENIED;
7135 }
7136
7137 return winreg_update_printer_internal(p->mem_ctx,
7138 get_session_info_system(),
7139 p->msg_ctx,
7140 lp_const_servicename(snum),
7141 info2_mask,
7142 NULL,
7143 devmode,
7144 NULL);
7145 }
7146
7147
7148 /****************************************************************
7149 _spoolss_SetPrinter
7150 ****************************************************************/
7151
_spoolss_SetPrinter(struct pipes_struct * p,struct spoolss_SetPrinter * r)7152 WERROR _spoolss_SetPrinter(struct pipes_struct *p,
7153 struct spoolss_SetPrinter *r)
7154 {
7155 WERROR result;
7156
7157 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
7158
7159 if (!Printer) {
7160 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
7161 OUR_HANDLE(r->in.handle)));
7162 return WERR_INVALID_HANDLE;
7163 }
7164
7165 /* check the level */
7166 switch (r->in.info_ctr->level) {
7167 case 0:
7168 return control_printer(r->in.handle, r->in.command, p);
7169 case 2:
7170 result = update_printer(p, r->in.handle,
7171 r->in.info_ctr,
7172 r->in.devmode_ctr->devmode);
7173 if (!W_ERROR_IS_OK(result))
7174 return result;
7175 if (r->in.secdesc_ctr->sd)
7176 result = update_printer_sec(r->in.handle, p,
7177 r->in.secdesc_ctr);
7178 return result;
7179 case 3:
7180 return update_printer_sec(r->in.handle, p,
7181 r->in.secdesc_ctr);
7182 case 4: {
7183 struct spoolss_PrinterInfo2 *old_printer;
7184 struct spoolss_SetPrinterInfo2 *set_old_printer;
7185 struct spoolss_SetPrinterInfoCtr *info_ctr;
7186 struct dcerpc_binding_handle *b;
7187 int snum;
7188 TALLOC_CTX *tmp_ctx;
7189
7190 tmp_ctx = talloc_new(p->mem_ctx);
7191 if (tmp_ctx == NULL) {
7192 return WERR_NOT_ENOUGH_MEMORY;
7193 }
7194
7195 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7196 TALLOC_FREE(tmp_ctx);
7197 return WERR_INVALID_HANDLE;
7198 }
7199
7200 result = winreg_printer_binding_handle(tmp_ctx,
7201 get_session_info_system(),
7202 p->msg_ctx,
7203 &b);
7204 if (!W_ERROR_IS_OK(result)) {
7205 TALLOC_FREE(tmp_ctx);
7206 return result;
7207 }
7208
7209 result = winreg_get_printer(tmp_ctx, b,
7210 lp_const_servicename(snum),
7211 &old_printer);
7212 if (!W_ERROR_IS_OK(result)) {
7213 TALLOC_FREE(tmp_ctx);
7214 return WERR_INVALID_HANDLE;
7215 }
7216
7217 old_printer->servername = talloc_strdup(tmp_ctx, r->in.info_ctr->info.info4->servername);
7218 if (old_printer->servername == NULL) {
7219 TALLOC_FREE(tmp_ctx);
7220 return WERR_NOT_ENOUGH_MEMORY;
7221 }
7222
7223 old_printer->printername = talloc_strdup(tmp_ctx, r->in.info_ctr->info.info4->printername);
7224 if (old_printer->printername == NULL) {
7225 TALLOC_FREE(tmp_ctx);
7226 return WERR_NOT_ENOUGH_MEMORY;
7227 }
7228
7229 old_printer->attributes = r->in.info_ctr->info.info4->attributes;
7230
7231 set_old_printer = talloc_zero(tmp_ctx, struct spoolss_SetPrinterInfo2);
7232 if (set_old_printer == NULL) {
7233 TALLOC_FREE(tmp_ctx);
7234 return WERR_NOT_ENOUGH_MEMORY;
7235 }
7236
7237 spoolss_printerinfo2_to_setprinterinfo2(old_printer, set_old_printer);
7238
7239 info_ctr = talloc_zero(tmp_ctx, struct spoolss_SetPrinterInfoCtr);
7240 if (info_ctr == NULL) {
7241 TALLOC_FREE(tmp_ctx);
7242 return WERR_NOT_ENOUGH_MEMORY;
7243 }
7244
7245 info_ctr->level = 2;
7246 info_ctr->info.info2 = set_old_printer;
7247
7248 result = update_printer(p, r->in.handle,
7249 info_ctr,
7250 r->in.devmode_ctr->devmode);
7251
7252 if (!W_ERROR_IS_OK(result)) {
7253 TALLOC_FREE(tmp_ctx);
7254 return result;
7255 }
7256
7257 if (r->in.secdesc_ctr->sd) {
7258 result = update_printer_sec(r->in.handle, p,
7259 r->in.secdesc_ctr);
7260 }
7261
7262 TALLOC_FREE(tmp_ctx);
7263 return result;
7264 }
7265 case 7:
7266 return publish_or_unpublish_printer(p, r->in.handle,
7267 r->in.info_ctr->info.info7);
7268 case 8:
7269 return update_printer_devmode(p, r->in.handle,
7270 r->in.devmode_ctr->devmode);
7271 default:
7272 return WERR_INVALID_LEVEL;
7273 }
7274 }
7275
7276 /****************************************************************
7277 _spoolss_FindClosePrinterNotify
7278 ****************************************************************/
7279
_spoolss_FindClosePrinterNotify(struct pipes_struct * p,struct spoolss_FindClosePrinterNotify * r)7280 WERROR _spoolss_FindClosePrinterNotify(struct pipes_struct *p,
7281 struct spoolss_FindClosePrinterNotify *r)
7282 {
7283 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
7284
7285 if (!Printer) {
7286 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
7287 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
7288 return WERR_INVALID_HANDLE;
7289 }
7290
7291 if (Printer->notify.cli_chan != NULL &&
7292 Printer->notify.cli_chan->active_connections > 0) {
7293 int snum = -1;
7294
7295 if (Printer->printer_type == SPLHND_PRINTER) {
7296 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7297 return WERR_INVALID_HANDLE;
7298 }
7299 }
7300
7301 srv_spoolss_replycloseprinter(snum, Printer);
7302 }
7303
7304 Printer->notify.flags=0;
7305 Printer->notify.options=0;
7306 Printer->notify.localmachine[0]='\0';
7307 Printer->notify.printerlocal=0;
7308 TALLOC_FREE(Printer->notify.option);
7309
7310 return WERR_OK;
7311 }
7312
7313 /****************************************************************
7314 _spoolss_AddJob
7315 ****************************************************************/
7316
_spoolss_AddJob(struct pipes_struct * p,struct spoolss_AddJob * r)7317 WERROR _spoolss_AddJob(struct pipes_struct *p,
7318 struct spoolss_AddJob *r)
7319 {
7320 if (!r->in.buffer && (r->in.offered != 0)) {
7321 return WERR_INVALID_PARAMETER;
7322 }
7323
7324 /* this is what a NT server returns for AddJob. AddJob must fail on
7325 * non-local printers */
7326
7327 if (r->in.level != 1) {
7328 return WERR_INVALID_LEVEL;
7329 }
7330
7331 return WERR_INVALID_PARAMETER;
7332 }
7333
7334 /****************************************************************************
7335 fill_job_info1
7336 ****************************************************************************/
7337
fill_job_info1(TALLOC_CTX * mem_ctx,struct spoolss_JobInfo1 * r,const print_queue_struct * queue,uint32_t jobid,int position,int snum,struct spoolss_PrinterInfo2 * pinfo2)7338 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
7339 struct spoolss_JobInfo1 *r,
7340 const print_queue_struct *queue,
7341 uint32_t jobid,
7342 int position, int snum,
7343 struct spoolss_PrinterInfo2 *pinfo2)
7344 {
7345 const struct loadparm_substitution *lp_sub =
7346 loadparm_s3_global_substitution();
7347 struct tm *t;
7348
7349 t = gmtime(&queue->time);
7350
7351 r->job_id = jobid;
7352
7353 r->printer_name = lp_servicename(mem_ctx, lp_sub, snum);
7354 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
7355 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
7356 W_ERROR_HAVE_NO_MEMORY(r->server_name);
7357 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
7358 W_ERROR_HAVE_NO_MEMORY(r->user_name);
7359 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
7360 W_ERROR_HAVE_NO_MEMORY(r->document_name);
7361 r->data_type = talloc_strdup(mem_ctx, "RAW");
7362 W_ERROR_HAVE_NO_MEMORY(r->data_type);
7363 r->text_status = talloc_strdup(mem_ctx, "");
7364 W_ERROR_HAVE_NO_MEMORY(r->text_status);
7365
7366 r->status = nt_printj_status(queue->status);
7367 r->priority = queue->priority;
7368 r->position = position;
7369 r->total_pages = queue->page_count;
7370 r->pages_printed = 0; /* ??? */
7371
7372 init_systemtime(&r->submitted, t);
7373
7374 return WERR_OK;
7375 }
7376
7377 /****************************************************************************
7378 fill_job_info2
7379 ****************************************************************************/
7380
fill_job_info2(TALLOC_CTX * mem_ctx,struct spoolss_JobInfo2 * r,const print_queue_struct * queue,uint32_t jobid,int position,int snum,struct spoolss_PrinterInfo2 * pinfo2,struct spoolss_DeviceMode * devmode)7381 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
7382 struct spoolss_JobInfo2 *r,
7383 const print_queue_struct *queue,
7384 uint32_t jobid,
7385 int position, int snum,
7386 struct spoolss_PrinterInfo2 *pinfo2,
7387 struct spoolss_DeviceMode *devmode)
7388 {
7389 const struct loadparm_substitution *lp_sub =
7390 loadparm_s3_global_substitution();
7391 struct tm *t;
7392
7393 t = gmtime(&queue->time);
7394
7395 r->job_id = jobid;
7396
7397 r->printer_name = lp_servicename(mem_ctx, lp_sub, snum);
7398 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
7399 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
7400 W_ERROR_HAVE_NO_MEMORY(r->server_name);
7401 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
7402 W_ERROR_HAVE_NO_MEMORY(r->user_name);
7403 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
7404 W_ERROR_HAVE_NO_MEMORY(r->document_name);
7405 r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
7406 W_ERROR_HAVE_NO_MEMORY(r->notify_name);
7407 r->data_type = talloc_strdup(mem_ctx, "RAW");
7408 W_ERROR_HAVE_NO_MEMORY(r->data_type);
7409 r->print_processor = talloc_strdup(mem_ctx, "winprint");
7410 W_ERROR_HAVE_NO_MEMORY(r->print_processor);
7411 r->parameters = talloc_strdup(mem_ctx, "");
7412 W_ERROR_HAVE_NO_MEMORY(r->parameters);
7413 r->driver_name = talloc_strdup(mem_ctx, pinfo2->drivername);
7414 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
7415
7416 r->devmode = devmode;
7417
7418 r->text_status = talloc_strdup(mem_ctx, "");
7419 W_ERROR_HAVE_NO_MEMORY(r->text_status);
7420
7421 r->secdesc = NULL;
7422
7423 r->status = nt_printj_status(queue->status);
7424 r->priority = queue->priority;
7425 r->position = position;
7426 r->start_time = 0;
7427 r->until_time = 0;
7428 r->total_pages = queue->page_count;
7429 r->size = queue->size;
7430 init_systemtime(&r->submitted, t);
7431 r->time = 0;
7432 r->pages_printed = 0; /* ??? */
7433
7434 return WERR_OK;
7435 }
7436
7437 /****************************************************************************
7438 Enumjobs at level 1.
7439 ****************************************************************************/
7440
enumjobs_level1(TALLOC_CTX * mem_ctx,const print_queue_struct * queue,uint32_t num_queues,int snum,struct spoolss_PrinterInfo2 * pinfo2,union spoolss_JobInfo ** info_p,uint32_t * count)7441 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
7442 const print_queue_struct *queue,
7443 uint32_t num_queues, int snum,
7444 struct spoolss_PrinterInfo2 *pinfo2,
7445 union spoolss_JobInfo **info_p,
7446 uint32_t *count)
7447 {
7448 union spoolss_JobInfo *info;
7449 int i;
7450 WERROR result = WERR_OK;
7451 uint32_t num_filled;
7452 struct tdb_print_db *pdb;
7453
7454 info = talloc_array(mem_ctx, union spoolss_JobInfo, num_queues);
7455 if (info == NULL) {
7456 result = WERR_NOT_ENOUGH_MEMORY;
7457 goto err_out;
7458 }
7459
7460 pdb = get_print_db_byname(pinfo2->sharename);
7461 if (pdb == NULL) {
7462 result = WERR_INVALID_PARAMETER;
7463 goto err_info_free;
7464 }
7465
7466 num_filled = 0;
7467 for (i = 0; i < num_queues; i++) {
7468 uint32_t jobid = sysjob_to_jobid_pdb(pdb, queue[i].sysjob);
7469 if (jobid == (uint32_t)-1) {
7470 DEBUG(4, ("skipping sysjob %d\n", queue[i].sysjob));
7471 continue;
7472 }
7473
7474 result = fill_job_info1(info,
7475 &info[num_filled].info1,
7476 &queue[i],
7477 jobid,
7478 i,
7479 snum,
7480 pinfo2);
7481 if (!W_ERROR_IS_OK(result)) {
7482 goto err_pdb_drop;
7483 }
7484
7485 num_filled++;
7486 }
7487
7488 release_print_db(pdb);
7489 *info_p = info;
7490 *count = num_filled;
7491
7492 return WERR_OK;
7493
7494 err_pdb_drop:
7495 release_print_db(pdb);
7496 err_info_free:
7497 TALLOC_FREE(info);
7498 err_out:
7499 *count = 0;
7500 return result;
7501 }
7502
7503 /****************************************************************************
7504 Enumjobs at level 2.
7505 ****************************************************************************/
7506
enumjobs_level2(TALLOC_CTX * mem_ctx,const print_queue_struct * queue,uint32_t num_queues,int snum,struct spoolss_PrinterInfo2 * pinfo2,union spoolss_JobInfo ** info_p,uint32_t * count)7507 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
7508 const print_queue_struct *queue,
7509 uint32_t num_queues, int snum,
7510 struct spoolss_PrinterInfo2 *pinfo2,
7511 union spoolss_JobInfo **info_p,
7512 uint32_t *count)
7513 {
7514 union spoolss_JobInfo *info;
7515 int i;
7516 WERROR result = WERR_OK;
7517 uint32_t num_filled;
7518 struct tdb_print_db *pdb;
7519
7520 info = talloc_array(mem_ctx, union spoolss_JobInfo, num_queues);
7521 if (info == NULL) {
7522 result = WERR_NOT_ENOUGH_MEMORY;
7523 goto err_out;
7524 }
7525
7526 pdb = get_print_db_byname(pinfo2->sharename);
7527 if (pdb == NULL) {
7528 result = WERR_INVALID_PARAMETER;
7529 goto err_info_free;
7530 }
7531
7532 num_filled = 0;
7533 for (i = 0; i< num_queues; i++) {
7534 struct spoolss_DeviceMode *devmode;
7535 uint32_t jobid = sysjob_to_jobid_pdb(pdb, queue[i].sysjob);
7536 if (jobid == (uint32_t)-1) {
7537 DEBUG(4, ("skipping sysjob %d\n", queue[i].sysjob));
7538 continue;
7539 }
7540
7541 result = spoolss_create_default_devmode(info,
7542 pinfo2->printername,
7543 &devmode);
7544 if (!W_ERROR_IS_OK(result)) {
7545 DEBUG(3, ("Can't proceed w/o a devmode!"));
7546 goto err_pdb_drop;
7547 }
7548
7549 result = fill_job_info2(info,
7550 &info[num_filled].info2,
7551 &queue[i],
7552 jobid,
7553 i,
7554 snum,
7555 pinfo2,
7556 devmode);
7557 if (!W_ERROR_IS_OK(result)) {
7558 goto err_pdb_drop;
7559 }
7560 num_filled++;
7561 }
7562
7563 release_print_db(pdb);
7564 *info_p = info;
7565 *count = num_filled;
7566
7567 return WERR_OK;
7568
7569 err_pdb_drop:
7570 release_print_db(pdb);
7571 err_info_free:
7572 TALLOC_FREE(info);
7573 err_out:
7574 *count = 0;
7575 return result;
7576 }
7577
7578 /****************************************************************************
7579 Enumjobs at level 3.
7580 ****************************************************************************/
7581
enumjobs_level3(TALLOC_CTX * mem_ctx,const print_queue_struct * queue,uint32_t num_queues,int snum,struct spoolss_PrinterInfo2 * pinfo2,union spoolss_JobInfo ** info_p,uint32_t * count)7582 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
7583 const print_queue_struct *queue,
7584 uint32_t num_queues, int snum,
7585 struct spoolss_PrinterInfo2 *pinfo2,
7586 union spoolss_JobInfo **info_p,
7587 uint32_t *count)
7588 {
7589 union spoolss_JobInfo *info;
7590 int i;
7591 WERROR result = WERR_OK;
7592 uint32_t num_filled;
7593 struct tdb_print_db *pdb;
7594
7595 info = talloc_array(mem_ctx, union spoolss_JobInfo, num_queues);
7596 if (info == NULL) {
7597 result = WERR_NOT_ENOUGH_MEMORY;
7598 goto err_out;
7599 }
7600
7601 pdb = get_print_db_byname(pinfo2->sharename);
7602 if (pdb == NULL) {
7603 result = WERR_INVALID_PARAMETER;
7604 goto err_info_free;
7605 }
7606
7607 num_filled = 0;
7608 for (i = 0; i < num_queues; i++) {
7609 uint32_t jobid = sysjob_to_jobid_pdb(pdb, queue[i].sysjob);
7610 if (jobid == (uint32_t)-1) {
7611 DEBUG(4, ("skipping sysjob %d\n", queue[i].sysjob));
7612 continue;
7613 }
7614
7615 info[num_filled].info3.job_id = jobid;
7616 /* next_job_id is overwritten on next iteration */
7617 info[num_filled].info3.next_job_id = 0;
7618 info[num_filled].info3.reserved = 0;
7619
7620 if (num_filled > 0) {
7621 info[num_filled - 1].info3.next_job_id = jobid;
7622 }
7623 num_filled++;
7624 }
7625
7626 release_print_db(pdb);
7627 *info_p = info;
7628 *count = num_filled;
7629
7630 return WERR_OK;
7631
7632 err_info_free:
7633 TALLOC_FREE(info);
7634 err_out:
7635 *count = 0;
7636 return result;
7637 }
7638
7639 /****************************************************************
7640 _spoolss_EnumJobs
7641 ****************************************************************/
7642
_spoolss_EnumJobs(struct pipes_struct * p,struct spoolss_EnumJobs * r)7643 WERROR _spoolss_EnumJobs(struct pipes_struct *p,
7644 struct spoolss_EnumJobs *r)
7645 {
7646 WERROR result;
7647 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
7648 int snum;
7649 print_status_struct prt_status;
7650 print_queue_struct *queue = NULL;
7651 uint32_t count;
7652
7653 /* that's an [in out] buffer */
7654
7655 if (!r->in.buffer && (r->in.offered != 0)) {
7656 return WERR_INVALID_PARAMETER;
7657 }
7658
7659 if ((r->in.level != 1) && (r->in.level != 2) && (r->in.level != 3)) {
7660 DEBUG(4, ("EnumJobs level %d not supported\n", r->in.level));
7661 return WERR_INVALID_LEVEL;
7662 }
7663
7664 DEBUG(4,("_spoolss_EnumJobs\n"));
7665
7666 *r->out.needed = 0;
7667 *r->out.count = 0;
7668 *r->out.info = NULL;
7669
7670 /* lookup the printer snum and tdb entry */
7671
7672 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7673 return WERR_INVALID_HANDLE;
7674 }
7675
7676 result = winreg_get_printer_internal(p->mem_ctx,
7677 get_session_info_system(),
7678 p->msg_ctx,
7679 lp_const_servicename(snum),
7680 &pinfo2);
7681 if (!W_ERROR_IS_OK(result)) {
7682 return result;
7683 }
7684
7685 count = print_queue_status(p->msg_ctx, snum, &queue, &prt_status);
7686 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
7687 count, prt_status.status, prt_status.message));
7688
7689 if (count == 0) {
7690 SAFE_FREE(queue);
7691 TALLOC_FREE(pinfo2);
7692 return WERR_OK;
7693 }
7694
7695 switch (r->in.level) {
7696 case 1:
7697 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
7698 pinfo2, r->out.info, r->out.count);
7699 break;
7700 case 2:
7701 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
7702 pinfo2, r->out.info, r->out.count);
7703 break;
7704 case 3:
7705 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
7706 pinfo2, r->out.info, r->out.count);
7707 break;
7708 default:
7709 SMB_ASSERT(false); /* level checked on entry */
7710 break;
7711 }
7712
7713 SAFE_FREE(queue);
7714 TALLOC_FREE(pinfo2);
7715
7716 if (!W_ERROR_IS_OK(result)) {
7717 return result;
7718 }
7719
7720 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7721 spoolss_EnumJobs,
7722 *r->out.info, r->in.level,
7723 *r->out.count);
7724 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7725 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7726
7727 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7728 }
7729
7730 /****************************************************************
7731 _spoolss_ScheduleJob
7732 ****************************************************************/
7733
_spoolss_ScheduleJob(struct pipes_struct * p,struct spoolss_ScheduleJob * r)7734 WERROR _spoolss_ScheduleJob(struct pipes_struct *p,
7735 struct spoolss_ScheduleJob *r)
7736 {
7737 return WERR_OK;
7738 }
7739
7740 /****************************************************************
7741 ****************************************************************/
7742
spoolss_setjob_1(TALLOC_CTX * mem_ctx,struct messaging_context * msg_ctx,const char * printer_name,uint32_t job_id,struct spoolss_SetJobInfo1 * r)7743 static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
7744 struct messaging_context *msg_ctx,
7745 const char *printer_name,
7746 uint32_t job_id,
7747 struct spoolss_SetJobInfo1 *r)
7748 {
7749 char *old_doc_name;
7750
7751 if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
7752 return WERR_INVALID_HANDLE;
7753 }
7754
7755 if (strequal(old_doc_name, r->document_name)) {
7756 return WERR_OK;
7757 }
7758
7759 if (!print_job_set_name(global_event_context(), msg_ctx,
7760 printer_name, job_id, r->document_name)) {
7761 return WERR_INVALID_HANDLE;
7762 }
7763
7764 return WERR_OK;
7765 }
7766
7767 /****************************************************************
7768 _spoolss_SetJob
7769 ****************************************************************/
7770
_spoolss_SetJob(struct pipes_struct * p,struct spoolss_SetJob * r)7771 WERROR _spoolss_SetJob(struct pipes_struct *p,
7772 struct spoolss_SetJob *r)
7773 {
7774 const struct auth_session_info *session_info = p->session_info;
7775 int snum;
7776 WERROR errcode = WERR_INVALID_FUNCTION;
7777
7778 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7779 return WERR_INVALID_HANDLE;
7780 }
7781
7782 if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
7783 return WERR_INVALID_PRINTER_NAME;
7784 }
7785
7786 switch (r->in.command) {
7787 case SPOOLSS_JOB_CONTROL_CANCEL:
7788 case SPOOLSS_JOB_CONTROL_DELETE:
7789 errcode = print_job_delete(session_info, p->msg_ctx,
7790 snum, r->in.job_id);
7791 if (W_ERROR_EQUAL(errcode, WERR_PRINTER_HAS_JOBS_QUEUED)) {
7792 errcode = WERR_OK;
7793 }
7794 break;
7795 case SPOOLSS_JOB_CONTROL_PAUSE:
7796 errcode = print_job_pause(session_info, p->msg_ctx,
7797 snum, r->in.job_id);
7798 break;
7799 case SPOOLSS_JOB_CONTROL_RESTART:
7800 case SPOOLSS_JOB_CONTROL_RESUME:
7801 errcode = print_job_resume(session_info, p->msg_ctx,
7802 snum, r->in.job_id);
7803 break;
7804 case SPOOLSS_JOB_CONTROL_NOOP:
7805 errcode = WERR_OK;
7806 break;
7807 default:
7808 return WERR_INVALID_LEVEL;
7809 }
7810
7811 if (!W_ERROR_IS_OK(errcode)) {
7812 return errcode;
7813 }
7814
7815 if (r->in.ctr == NULL) {
7816 return errcode;
7817 }
7818
7819 switch (r->in.ctr->level) {
7820 case 1:
7821 errcode = spoolss_setjob_1(p->mem_ctx, p->msg_ctx,
7822 lp_const_servicename(snum),
7823 r->in.job_id,
7824 r->in.ctr->info.info1);
7825 break;
7826 case 2:
7827 case 3:
7828 case 4:
7829 default:
7830 return WERR_INVALID_LEVEL;
7831 }
7832
7833 return errcode;
7834 }
7835
7836 /****************************************************************************
7837 Enumerates all printer drivers by level and architecture.
7838 ****************************************************************************/
7839
enumprinterdrivers_level_by_architecture(TALLOC_CTX * mem_ctx,const struct auth_session_info * session_info,struct messaging_context * msg_ctx,const char * servername,const char * architecture,uint32_t level,union spoolss_DriverInfo ** info_p,uint32_t * count_p)7840 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
7841 const struct auth_session_info *session_info,
7842 struct messaging_context *msg_ctx,
7843 const char *servername,
7844 const char *architecture,
7845 uint32_t level,
7846 union spoolss_DriverInfo **info_p,
7847 uint32_t *count_p)
7848 {
7849 int i;
7850 uint32_t version;
7851 struct spoolss_DriverInfo8 *driver;
7852 union spoolss_DriverInfo *info = NULL;
7853 uint32_t count = 0;
7854 WERROR result = WERR_OK;
7855 uint32_t num_drivers;
7856 const char **drivers;
7857 struct dcerpc_binding_handle *b;
7858 TALLOC_CTX *tmp_ctx = NULL;
7859
7860 *count_p = 0;
7861 *info_p = NULL;
7862
7863 tmp_ctx = talloc_new(mem_ctx);
7864 if (!tmp_ctx) {
7865 return WERR_NOT_ENOUGH_MEMORY;
7866 }
7867
7868 result = winreg_printer_binding_handle(tmp_ctx,
7869 session_info,
7870 msg_ctx,
7871 &b);
7872 if (!W_ERROR_IS_OK(result)) {
7873 goto out;
7874 }
7875
7876 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7877 result = winreg_get_driver_list(tmp_ctx, b,
7878 architecture, version,
7879 &num_drivers, &drivers);
7880 if (!W_ERROR_IS_OK(result)) {
7881 goto out;
7882 }
7883 DEBUG(4, ("we have:[%d] drivers in environment"
7884 " [%s] and version [%d]\n",
7885 num_drivers, architecture, version));
7886
7887 if (num_drivers != 0) {
7888 info = talloc_realloc(tmp_ctx, info,
7889 union spoolss_DriverInfo,
7890 count + num_drivers);
7891 if (!info) {
7892 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
7893 "failed to enlarge driver info buffer!\n"));
7894 result = WERR_NOT_ENOUGH_MEMORY;
7895 goto out;
7896 }
7897 }
7898
7899 for (i = 0; i < num_drivers; i++) {
7900 DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
7901
7902 result = winreg_get_driver(tmp_ctx, b,
7903 architecture, drivers[i],
7904 version, &driver);
7905 if (!W_ERROR_IS_OK(result)) {
7906 goto out;
7907 }
7908
7909 switch (level) {
7910 case 1:
7911 result = fill_printer_driver_info1(info, &info[count+i].info1,
7912 driver, servername);
7913 break;
7914 case 2:
7915 result = fill_printer_driver_info2(info, &info[count+i].info2,
7916 driver, servername);
7917 break;
7918 case 3:
7919 result = fill_printer_driver_info3(info, &info[count+i].info3,
7920 driver, servername);
7921 break;
7922 case 4:
7923 result = fill_printer_driver_info4(info, &info[count+i].info4,
7924 driver, servername);
7925 break;
7926 case 5:
7927 result = fill_printer_driver_info5(info, &info[count+i].info5,
7928 driver, servername);
7929 break;
7930 case 6:
7931 result = fill_printer_driver_info6(info, &info[count+i].info6,
7932 driver, servername);
7933 break;
7934 case 8:
7935 result = fill_printer_driver_info8(info, &info[count+i].info8,
7936 driver, servername);
7937 break;
7938 default:
7939 result = WERR_INVALID_LEVEL;
7940 break;
7941 }
7942
7943 TALLOC_FREE(driver);
7944
7945 if (!W_ERROR_IS_OK(result)) {
7946 goto out;
7947 }
7948 }
7949
7950 count += num_drivers;
7951 TALLOC_FREE(drivers);
7952 }
7953
7954 out:
7955 if (W_ERROR_IS_OK(result)) {
7956 *info_p = talloc_move(mem_ctx, &info);
7957 *count_p = count;
7958 }
7959
7960 talloc_free(tmp_ctx);
7961 return result;
7962 }
7963
7964 /****************************************************************************
7965 Enumerates all printer drivers by level.
7966 ****************************************************************************/
7967
enumprinterdrivers_level(TALLOC_CTX * mem_ctx,const struct auth_session_info * session_info,struct messaging_context * msg_ctx,const char * servername,const char * architecture,uint32_t level,union spoolss_DriverInfo ** info_p,uint32_t * count_p)7968 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
7969 const struct auth_session_info *session_info,
7970 struct messaging_context *msg_ctx,
7971 const char *servername,
7972 const char *architecture,
7973 uint32_t level,
7974 union spoolss_DriverInfo **info_p,
7975 uint32_t *count_p)
7976 {
7977 uint32_t a,i;
7978 WERROR result = WERR_OK;
7979
7980 if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
7981
7982 for (a=0; archi_table[a].long_archi != NULL; a++) {
7983
7984 union spoolss_DriverInfo *info = NULL;
7985 uint32_t count = 0;
7986
7987 result = enumprinterdrivers_level_by_architecture(mem_ctx,
7988 session_info,
7989 msg_ctx,
7990 servername,
7991 archi_table[a].long_archi,
7992 level,
7993 &info,
7994 &count);
7995 if (!W_ERROR_IS_OK(result)) {
7996 continue;
7997 }
7998
7999 for (i=0; i < count; i++) {
8000 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
8001 info[i], info_p, count_p);
8002 }
8003 }
8004
8005 return result;
8006 }
8007
8008 return enumprinterdrivers_level_by_architecture(mem_ctx,
8009 session_info,
8010 msg_ctx,
8011 servername,
8012 architecture,
8013 level,
8014 info_p,
8015 count_p);
8016 }
8017
8018 /****************************************************************
8019 _spoolss_EnumPrinterDrivers
8020 ****************************************************************/
8021
_spoolss_EnumPrinterDrivers(struct pipes_struct * p,struct spoolss_EnumPrinterDrivers * r)8022 WERROR _spoolss_EnumPrinterDrivers(struct pipes_struct *p,
8023 struct spoolss_EnumPrinterDrivers *r)
8024 {
8025 const char *cservername;
8026 WERROR result;
8027
8028 /* that's an [in out] buffer */
8029
8030 if (!r->in.buffer && (r->in.offered != 0)) {
8031 return WERR_INVALID_PARAMETER;
8032 }
8033
8034 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
8035
8036 *r->out.needed = 0;
8037 *r->out.count = 0;
8038 *r->out.info = NULL;
8039
8040 cservername = canon_servername(r->in.server);
8041
8042 if (!is_myname_or_ipaddr(cservername)) {
8043 return WERR_UNKNOWN_PRINTER_DRIVER;
8044 }
8045
8046 result = enumprinterdrivers_level(p->mem_ctx,
8047 get_session_info_system(),
8048 p->msg_ctx,
8049 cservername,
8050 r->in.environment,
8051 r->in.level,
8052 r->out.info,
8053 r->out.count);
8054 if (!W_ERROR_IS_OK(result)) {
8055 return result;
8056 }
8057
8058 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8059 spoolss_EnumPrinterDrivers,
8060 *r->out.info, r->in.level,
8061 *r->out.count);
8062 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8063 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8064
8065 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8066 }
8067
8068 /****************************************************************
8069 _spoolss_EnumForms
8070 ****************************************************************/
8071
_spoolss_EnumForms(struct pipes_struct * p,struct spoolss_EnumForms * r)8072 WERROR _spoolss_EnumForms(struct pipes_struct *p,
8073 struct spoolss_EnumForms *r)
8074 {
8075 WERROR result;
8076
8077 *r->out.count = 0;
8078 *r->out.needed = 0;
8079 *r->out.info = NULL;
8080
8081 /* that's an [in out] buffer */
8082
8083 if (!r->in.buffer && (r->in.offered != 0) ) {
8084 return WERR_INVALID_PARAMETER;
8085 }
8086
8087 DEBUG(4,("_spoolss_EnumForms\n"));
8088 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
8089 DEBUGADD(5,("Info level [%d]\n", r->in.level));
8090
8091 switch (r->in.level) {
8092 case 1:
8093 result = winreg_printer_enumforms1_internal(p->mem_ctx,
8094 get_session_info_system(),
8095 p->msg_ctx,
8096 r->out.count,
8097 r->out.info);
8098 break;
8099 default:
8100 result = WERR_INVALID_LEVEL;
8101 break;
8102 }
8103
8104 if (!W_ERROR_IS_OK(result)) {
8105 return result;
8106 }
8107
8108 if (*r->out.count == 0) {
8109 return WERR_NO_MORE_ITEMS;
8110 }
8111
8112 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8113 spoolss_EnumForms,
8114 *r->out.info, r->in.level,
8115 *r->out.count);
8116 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8117 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8118
8119 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8120 }
8121
8122 /****************************************************************
8123 _spoolss_GetForm
8124 ****************************************************************/
8125
_spoolss_GetForm(struct pipes_struct * p,struct spoolss_GetForm * r)8126 WERROR _spoolss_GetForm(struct pipes_struct *p,
8127 struct spoolss_GetForm *r)
8128 {
8129 WERROR result;
8130
8131 /* that's an [in out] buffer */
8132
8133 if (!r->in.buffer && (r->in.offered != 0)) {
8134 TALLOC_FREE(r->out.info);
8135 return WERR_INVALID_PARAMETER;
8136 }
8137
8138 DEBUG(4,("_spoolss_GetForm\n"));
8139 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
8140 DEBUGADD(5,("Info level [%d]\n", r->in.level));
8141
8142 switch (r->in.level) {
8143 case 1:
8144 result = winreg_printer_getform1_internal(p->mem_ctx,
8145 get_session_info_system(),
8146 p->msg_ctx,
8147 r->in.form_name,
8148 &r->out.info->info1);
8149 break;
8150 default:
8151 result = WERR_INVALID_LEVEL;
8152 break;
8153 }
8154
8155 if (!W_ERROR_IS_OK(result)) {
8156 TALLOC_FREE(r->out.info);
8157 return result;
8158 }
8159
8160 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo,
8161 r->out.info, r->in.level);
8162 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8163
8164 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8165 }
8166
8167 /****************************************************************************
8168 ****************************************************************************/
8169
fill_port_1(TALLOC_CTX * mem_ctx,struct spoolss_PortInfo1 * r,const char * name)8170 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
8171 struct spoolss_PortInfo1 *r,
8172 const char *name)
8173 {
8174 r->port_name = talloc_strdup(mem_ctx, name);
8175 W_ERROR_HAVE_NO_MEMORY(r->port_name);
8176
8177 return WERR_OK;
8178 }
8179
8180 /****************************************************************************
8181 TODO: This probably needs distinguish between TCP/IP and Local ports
8182 somehow.
8183 ****************************************************************************/
8184
fill_port_2(TALLOC_CTX * mem_ctx,struct spoolss_PortInfo2 * r,const char * name)8185 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
8186 struct spoolss_PortInfo2 *r,
8187 const char *name)
8188 {
8189 r->port_name = talloc_strdup(mem_ctx, name);
8190 W_ERROR_HAVE_NO_MEMORY(r->port_name);
8191
8192 r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
8193 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8194
8195 r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
8196 W_ERROR_HAVE_NO_MEMORY(r->description);
8197
8198 r->port_type = SPOOLSS_PORT_TYPE_WRITE;
8199 r->reserved = 0;
8200
8201 return WERR_OK;
8202 }
8203
8204
8205 /****************************************************************************
8206 wrapper around the enumer ports command
8207 ****************************************************************************/
8208
enumports_hook(TALLOC_CTX * ctx,int * count,char *** lines)8209 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
8210 {
8211 const struct loadparm_substitution *lp_sub =
8212 loadparm_s3_global_substitution();
8213 char *cmd = lp_enumports_command(talloc_tos(), lp_sub);
8214 char **qlines = NULL;
8215 char *command = NULL;
8216 int numlines;
8217 int ret;
8218 int fd;
8219
8220 *count = 0;
8221 *lines = NULL;
8222
8223 /* if no hook then just fill in the default port */
8224
8225 if ( !*cmd ) {
8226 if (!(qlines = talloc_array( NULL, char*, 2 ))) {
8227 return WERR_NOT_ENOUGH_MEMORY;
8228 }
8229 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
8230 TALLOC_FREE(qlines);
8231 return WERR_NOT_ENOUGH_MEMORY;
8232 }
8233 qlines[1] = NULL;
8234 numlines = 1;
8235 }
8236 else {
8237 /* we have a valid enumport command */
8238
8239 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
8240 if (!command) {
8241 return WERR_NOT_ENOUGH_MEMORY;
8242 }
8243
8244 DEBUG(10,("Running [%s]\n", command));
8245 ret = smbrun(command, &fd, NULL);
8246 DEBUG(10,("Returned [%d]\n", ret));
8247 TALLOC_FREE(command);
8248 if (ret != 0) {
8249 if (fd != -1) {
8250 close(fd);
8251 }
8252 return WERR_ACCESS_DENIED;
8253 }
8254
8255 numlines = 0;
8256 qlines = fd_lines_load(fd, &numlines, 0, NULL);
8257 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
8258 close(fd);
8259 }
8260
8261 *count = numlines;
8262 *lines = qlines;
8263
8264 return WERR_OK;
8265 }
8266
8267 /****************************************************************************
8268 enumports level 1.
8269 ****************************************************************************/
8270
enumports_level_1(TALLOC_CTX * mem_ctx,union spoolss_PortInfo ** info_p,uint32_t * count)8271 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
8272 union spoolss_PortInfo **info_p,
8273 uint32_t *count)
8274 {
8275 union spoolss_PortInfo *info = NULL;
8276 int i=0;
8277 WERROR result = WERR_OK;
8278 char **qlines = NULL;
8279 int numlines = 0;
8280
8281 result = enumports_hook(talloc_tos(), &numlines, &qlines );
8282 if (!W_ERROR_IS_OK(result)) {
8283 goto out;
8284 }
8285
8286 if (numlines) {
8287 info = talloc_array(mem_ctx, union spoolss_PortInfo, numlines);
8288 if (!info) {
8289 DEBUG(10,("Returning WERR_NOT_ENOUGH_MEMORY\n"));
8290 result = WERR_NOT_ENOUGH_MEMORY;
8291 goto out;
8292 }
8293
8294 for (i=0; i<numlines; i++) {
8295 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
8296 result = fill_port_1(info, &info[i].info1, qlines[i]);
8297 if (!W_ERROR_IS_OK(result)) {
8298 goto out;
8299 }
8300 }
8301 }
8302 TALLOC_FREE(qlines);
8303
8304 out:
8305 if (!W_ERROR_IS_OK(result)) {
8306 TALLOC_FREE(info);
8307 TALLOC_FREE(qlines);
8308 *count = 0;
8309 *info_p = NULL;
8310 return result;
8311 }
8312
8313 *info_p = info;
8314 *count = numlines;
8315
8316 return WERR_OK;
8317 }
8318
8319 /****************************************************************************
8320 enumports level 2.
8321 ****************************************************************************/
8322
enumports_level_2(TALLOC_CTX * mem_ctx,union spoolss_PortInfo ** info_p,uint32_t * count)8323 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
8324 union spoolss_PortInfo **info_p,
8325 uint32_t *count)
8326 {
8327 union spoolss_PortInfo *info = NULL;
8328 int i=0;
8329 WERROR result = WERR_OK;
8330 char **qlines = NULL;
8331 int numlines = 0;
8332
8333 result = enumports_hook(talloc_tos(), &numlines, &qlines );
8334 if (!W_ERROR_IS_OK(result)) {
8335 goto out;
8336 }
8337
8338 if (numlines) {
8339 info = talloc_array(mem_ctx, union spoolss_PortInfo, numlines);
8340 if (!info) {
8341 DEBUG(10,("Returning WERR_NOT_ENOUGH_MEMORY\n"));
8342 result = WERR_NOT_ENOUGH_MEMORY;
8343 goto out;
8344 }
8345
8346 for (i=0; i<numlines; i++) {
8347 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
8348 result = fill_port_2(info, &info[i].info2, qlines[i]);
8349 if (!W_ERROR_IS_OK(result)) {
8350 goto out;
8351 }
8352 }
8353 }
8354 TALLOC_FREE(qlines);
8355
8356 out:
8357 if (!W_ERROR_IS_OK(result)) {
8358 TALLOC_FREE(info);
8359 TALLOC_FREE(qlines);
8360 *count = 0;
8361 *info_p = NULL;
8362 return result;
8363 }
8364
8365 *info_p = info;
8366 *count = numlines;
8367
8368 return WERR_OK;
8369 }
8370
8371 /****************************************************************
8372 _spoolss_EnumPorts
8373 ****************************************************************/
8374
_spoolss_EnumPorts(struct pipes_struct * p,struct spoolss_EnumPorts * r)8375 WERROR _spoolss_EnumPorts(struct pipes_struct *p,
8376 struct spoolss_EnumPorts *r)
8377 {
8378 WERROR result;
8379
8380 /* that's an [in out] buffer */
8381
8382 if (!r->in.buffer && (r->in.offered != 0)) {
8383 return WERR_INVALID_PARAMETER;
8384 }
8385
8386 DEBUG(4,("_spoolss_EnumPorts\n"));
8387
8388 *r->out.count = 0;
8389 *r->out.needed = 0;
8390 *r->out.info = NULL;
8391
8392 switch (r->in.level) {
8393 case 1:
8394 result = enumports_level_1(p->mem_ctx, r->out.info,
8395 r->out.count);
8396 break;
8397 case 2:
8398 result = enumports_level_2(p->mem_ctx, r->out.info,
8399 r->out.count);
8400 break;
8401 default:
8402 return WERR_INVALID_LEVEL;
8403 }
8404
8405 if (!W_ERROR_IS_OK(result)) {
8406 return result;
8407 }
8408
8409 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8410 spoolss_EnumPorts,
8411 *r->out.info, r->in.level,
8412 *r->out.count);
8413 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8414 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8415
8416 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8417 }
8418
8419 /****************************************************************************
8420 ****************************************************************************/
8421
spoolss_addprinterex_level_2(struct pipes_struct * p,const char * server,struct spoolss_SetPrinterInfoCtr * info_ctr,struct spoolss_DeviceMode * devmode,struct security_descriptor * secdesc,struct spoolss_UserLevelCtr * user_ctr,struct policy_handle * handle)8422 static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p,
8423 const char *server,
8424 struct spoolss_SetPrinterInfoCtr *info_ctr,
8425 struct spoolss_DeviceMode *devmode,
8426 struct security_descriptor *secdesc,
8427 struct spoolss_UserLevelCtr *user_ctr,
8428 struct policy_handle *handle)
8429 {
8430 struct spoolss_SetPrinterInfo2 *info2 = info_ctr->info.info2;
8431 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ALL;
8432 const struct loadparm_substitution *lp_sub =
8433 loadparm_s3_global_substitution();
8434 int snum;
8435 WERROR err = WERR_OK;
8436
8437 /* samba does not have a concept of local, non-shared printers yet, so
8438 * make sure we always setup sharename - gd */
8439 if ((info2->sharename == NULL || info2->sharename[0] == '\0') &&
8440 (info2->printername != NULL && info2->printername[0] != '\0')) {
8441 DEBUG(5, ("spoolss_addprinterex_level_2: "
8442 "no sharename has been set, setting printername %s as sharename\n",
8443 info2->printername));
8444 info2->sharename = info2->printername;
8445 }
8446
8447 /* check to see if the printer already exists */
8448 if ((snum = print_queue_snum(info2->sharename)) != -1) {
8449 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
8450 info2->sharename));
8451 return WERR_PRINTER_ALREADY_EXISTS;
8452 }
8453
8454 if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
8455 if ((snum = print_queue_snum(info2->printername)) != -1) {
8456 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
8457 info2->printername));
8458 return WERR_PRINTER_ALREADY_EXISTS;
8459 }
8460 }
8461
8462 /* validate printer info struct */
8463 if (!info2->printername || strlen(info2->printername) == 0) {
8464 return WERR_INVALID_PRINTER_NAME;
8465 }
8466 if (!info2->portname || strlen(info2->portname) == 0) {
8467 return WERR_UNKNOWN_PORT;
8468 }
8469 if (!info2->drivername || strlen(info2->drivername) == 0) {
8470 return WERR_UNKNOWN_PRINTER_DRIVER;
8471 }
8472 if (!info2->printprocessor || strlen(info2->printprocessor) == 0) {
8473 return WERR_UNKNOWN_PRINTPROCESSOR;
8474 }
8475
8476 /* FIXME!!! smbd should check to see if the driver is installed before
8477 trying to add a printer like this --jerry */
8478
8479 if (*lp_addprinter_command(talloc_tos(), lp_sub) ) {
8480 char *raddr;
8481
8482 raddr = tsocket_address_inet_addr_string(p->remote_address,
8483 p->mem_ctx);
8484 if (raddr == NULL) {
8485 return WERR_NOT_ENOUGH_MEMORY;
8486 }
8487
8488 if ( !add_printer_hook(p->mem_ctx, p->session_info->security_token,
8489 info2, raddr,
8490 p->msg_ctx) ) {
8491 return WERR_ACCESS_DENIED;
8492 }
8493 } else {
8494 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no "
8495 "smb.conf parameter \"addprinter command\" is defined. This "
8496 "parameter must exist for this call to succeed\n",
8497 info2->sharename ));
8498 }
8499
8500 if ((snum = print_queue_snum(info2->sharename)) == -1) {
8501 return WERR_ACCESS_DENIED;
8502 }
8503
8504 /* you must be a printer admin to add a new printer */
8505 if (!W_ERROR_IS_OK(print_access_check(p->session_info,
8506 p->msg_ctx,
8507 snum,
8508 PRINTER_ACCESS_ADMINISTER))) {
8509 return WERR_ACCESS_DENIED;
8510 }
8511
8512 /*
8513 * Do sanity check on the requested changes for Samba.
8514 */
8515
8516 if (!check_printer_ok(p->mem_ctx, info2, snum)) {
8517 return WERR_INVALID_PARAMETER;
8518 }
8519
8520 if (devmode == NULL) {
8521 info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
8522 }
8523
8524 err = update_dsspooler(p->mem_ctx,
8525 get_session_info_system(),
8526 p->msg_ctx,
8527 0,
8528 info2,
8529 NULL);
8530 if (!W_ERROR_IS_OK(err)) {
8531 return err;
8532 }
8533
8534 err = winreg_update_printer_internal(p->mem_ctx,
8535 get_session_info_system(),
8536 p->msg_ctx,
8537 info2->sharename,
8538 info2_mask,
8539 info2,
8540 devmode,
8541 secdesc);
8542 if (!W_ERROR_IS_OK(err)) {
8543 return err;
8544 }
8545
8546 err = open_printer_hnd(p, handle, info2->printername, PRINTER_ACCESS_ADMINISTER);
8547 if (!W_ERROR_IS_OK(err)) {
8548 /* Handle open failed - remove addition. */
8549 ZERO_STRUCTP(handle);
8550 return err;
8551 }
8552
8553 return WERR_OK;
8554 }
8555
8556 /****************************************************************
8557 _spoolss_AddPrinterEx
8558 ****************************************************************/
8559
_spoolss_AddPrinterEx(struct pipes_struct * p,struct spoolss_AddPrinterEx * r)8560 WERROR _spoolss_AddPrinterEx(struct pipes_struct *p,
8561 struct spoolss_AddPrinterEx *r)
8562 {
8563 switch (r->in.info_ctr->level) {
8564 case 1:
8565 /* we don't handle yet */
8566 /* but I know what to do ... */
8567 return WERR_INVALID_LEVEL;
8568 case 2:
8569 return spoolss_addprinterex_level_2(p, r->in.server,
8570 r->in.info_ctr,
8571 r->in.devmode_ctr->devmode,
8572 r->in.secdesc_ctr->sd,
8573 r->in.userlevel_ctr,
8574 r->out.handle);
8575 default:
8576 return WERR_INVALID_LEVEL;
8577 }
8578 }
8579
8580 /****************************************************************
8581 _spoolss_AddPrinter
8582 ****************************************************************/
8583
_spoolss_AddPrinter(struct pipes_struct * p,struct spoolss_AddPrinter * r)8584 WERROR _spoolss_AddPrinter(struct pipes_struct *p,
8585 struct spoolss_AddPrinter *r)
8586 {
8587 struct spoolss_AddPrinterEx a;
8588 struct spoolss_UserLevelCtr userlevel_ctr;
8589
8590 ZERO_STRUCT(userlevel_ctr);
8591
8592 userlevel_ctr.level = 1;
8593
8594 a.in.server = r->in.server;
8595 a.in.info_ctr = r->in.info_ctr;
8596 a.in.devmode_ctr = r->in.devmode_ctr;
8597 a.in.secdesc_ctr = r->in.secdesc_ctr;
8598 a.in.userlevel_ctr = &userlevel_ctr;
8599 a.out.handle = r->out.handle;
8600
8601 return _spoolss_AddPrinterEx(p, &a);
8602 }
8603
8604 /****************************************************************
8605 _spoolss_AddPrinterDriverEx
8606 ****************************************************************/
8607
_spoolss_AddPrinterDriverEx(struct pipes_struct * p,struct spoolss_AddPrinterDriverEx * r)8608 WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
8609 struct spoolss_AddPrinterDriverEx *r)
8610 {
8611 WERROR err = WERR_OK;
8612 const char *driver_name = NULL;
8613 const char *driver_directory = NULL;
8614 uint32_t version;
8615
8616 /*
8617 * we only support the semantics of AddPrinterDriver()
8618 * i.e. only copy files that are newer than existing ones
8619 */
8620
8621 if (r->in.flags == 0) {
8622 return WERR_INVALID_PARAMETER;
8623 }
8624
8625 if (!(r->in.flags & APD_COPY_ALL_FILES) &&
8626 !(r->in.flags & APD_COPY_NEW_FILES)) {
8627 return WERR_ACCESS_DENIED;
8628 }
8629
8630 /* FIXME */
8631 if (r->in.info_ctr->level != 3 &&
8632 r->in.info_ctr->level != 6 &&
8633 r->in.info_ctr->level != 8) {
8634 DEBUG(0,("%s: level %d not yet implemented\n", __func__,
8635 r->in.info_ctr->level));
8636 return WERR_INVALID_LEVEL;
8637 }
8638
8639 DEBUG(5,("Cleaning driver's information\n"));
8640 err = clean_up_driver_struct(p->mem_ctx,
8641 p->session_info,
8642 r->in.info_ctr,
8643 r->in.flags,
8644 &driver_directory);
8645 if (!W_ERROR_IS_OK(err)) {
8646 DBG_ERR("clean_up_driver_struct failed - %s\n",
8647 win_errstr(err));
8648 goto done;
8649 }
8650
8651 DEBUG(5,("Moving driver to final destination\n"));
8652 err = move_driver_to_download_area(p->session_info,
8653 r->in.info_ctr,
8654 driver_directory);
8655 if (!W_ERROR_IS_OK(err)) {
8656 DBG_ERR("move_driver_to_download_area failed - %s\n",
8657 win_errstr(err));
8658 goto done;
8659 }
8660
8661 err = winreg_add_driver_internal(p->mem_ctx,
8662 get_session_info_system(),
8663 p->msg_ctx,
8664 r->in.info_ctr,
8665 &driver_name,
8666 &version);
8667 if (!W_ERROR_IS_OK(err)) {
8668 DBG_ERR("winreg_add_driver_internal failed - %s\n",
8669 win_errstr(err));
8670 goto done;
8671 }
8672
8673 /*
8674 * I think this is where he DrvUpgradePrinter() hook would be
8675 * be called in a driver's interface DLL on a Windows NT 4.0/2k
8676 * server. Right now, we just need to send ourselves a message
8677 * to update each printer bound to this driver. --jerry
8678 */
8679
8680 if (!srv_spoolss_drv_upgrade_printer(driver_name, p->msg_ctx)) {
8681 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
8682 __func__, driver_name));
8683 }
8684
8685 done:
8686 return err;
8687 }
8688
8689 /****************************************************************
8690 _spoolss_AddPrinterDriver
8691 ****************************************************************/
8692
_spoolss_AddPrinterDriver(struct pipes_struct * p,struct spoolss_AddPrinterDriver * r)8693 WERROR _spoolss_AddPrinterDriver(struct pipes_struct *p,
8694 struct spoolss_AddPrinterDriver *r)
8695 {
8696 struct spoolss_AddPrinterDriverEx a;
8697
8698 switch (r->in.info_ctr->level) {
8699 case 2:
8700 case 3:
8701 case 4:
8702 case 5:
8703 break;
8704 default:
8705 return WERR_INVALID_LEVEL;
8706 }
8707
8708 a.in.servername = r->in.servername;
8709 a.in.info_ctr = r->in.info_ctr;
8710 a.in.flags = APD_COPY_NEW_FILES;
8711
8712 return _spoolss_AddPrinterDriverEx(p, &a);
8713 }
8714
8715 /****************************************************************************
8716 ****************************************************************************/
8717
8718 struct _spoolss_paths {
8719 int type;
8720 const char *share;
8721 const char *dir;
8722 };
8723
8724 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
8725
8726 static const struct _spoolss_paths spoolss_paths[]= {
8727 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
8728 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
8729 };
8730
compose_spoolss_server_path(TALLOC_CTX * mem_ctx,const char * servername,const char * environment,int component,char ** path)8731 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
8732 const char *servername,
8733 const char *environment,
8734 int component,
8735 char **path)
8736 {
8737 const char *pservername = NULL;
8738 const char *long_archi;
8739 const char *short_archi;
8740
8741 *path = NULL;
8742
8743 /* environment may be empty */
8744 if (environment && strlen(environment)) {
8745 long_archi = environment;
8746 } else {
8747 long_archi = lp_parm_const_string(GLOBAL_SECTION_SNUM,
8748 "spoolss", "architecture",
8749 GLOBAL_SPOOLSS_ARCHITECTURE);
8750 }
8751
8752 /* servername may be empty */
8753 if (servername && strlen(servername)) {
8754 pservername = canon_servername(servername);
8755
8756 if (!is_myname_or_ipaddr(pservername)) {
8757 return WERR_INVALID_PARAMETER;
8758 }
8759 }
8760
8761 if (!(short_archi = get_short_archi(long_archi))) {
8762 return WERR_INVALID_ENVIRONMENT;
8763 }
8764
8765 switch (component) {
8766 case SPOOLSS_PRTPROCS_PATH:
8767 case SPOOLSS_DRIVER_PATH:
8768 if (pservername) {
8769 *path = talloc_asprintf(mem_ctx,
8770 "\\\\%s\\%s\\%s",
8771 pservername,
8772 spoolss_paths[component].share,
8773 short_archi);
8774 } else {
8775 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
8776 SPOOLSS_DEFAULT_SERVER_PATH,
8777 spoolss_paths[component].dir,
8778 short_archi);
8779 }
8780 break;
8781 default:
8782 return WERR_INVALID_PARAMETER;
8783 }
8784
8785 if (!*path) {
8786 return WERR_NOT_ENOUGH_MEMORY;
8787 }
8788
8789 return WERR_OK;
8790 }
8791
8792 /****************************************************************************
8793 ****************************************************************************/
8794
getprinterdriverdir_level_1(TALLOC_CTX * mem_ctx,const char * servername,const char * environment,struct spoolss_DriverDirectoryInfo1 * r)8795 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
8796 const char *servername,
8797 const char *environment,
8798 struct spoolss_DriverDirectoryInfo1 *r)
8799 {
8800 WERROR werr;
8801 char *path = NULL;
8802
8803 werr = compose_spoolss_server_path(mem_ctx,
8804 servername,
8805 environment,
8806 SPOOLSS_DRIVER_PATH,
8807 &path);
8808 if (!W_ERROR_IS_OK(werr)) {
8809 return werr;
8810 }
8811
8812 DEBUG(4,("printer driver directory: [%s]\n", path));
8813
8814 r->directory_name = path;
8815
8816 return WERR_OK;
8817 }
8818
8819 /****************************************************************
8820 _spoolss_GetPrinterDriverDirectory
8821 ****************************************************************/
8822
_spoolss_GetPrinterDriverDirectory(struct pipes_struct * p,struct spoolss_GetPrinterDriverDirectory * r)8823 WERROR _spoolss_GetPrinterDriverDirectory(struct pipes_struct *p,
8824 struct spoolss_GetPrinterDriverDirectory *r)
8825 {
8826 WERROR werror;
8827
8828 /* that's an [in out] buffer */
8829
8830 if (!r->in.buffer && (r->in.offered != 0)) {
8831 TALLOC_FREE(r->out.info);
8832 return WERR_INVALID_PARAMETER;
8833 }
8834
8835 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
8836 r->in.level));
8837
8838 *r->out.needed = 0;
8839
8840 /* r->in.level is ignored */
8841
8842 werror = getprinterdriverdir_level_1(p->mem_ctx,
8843 r->in.server,
8844 r->in.environment,
8845 &r->out.info->info1);
8846 if (!W_ERROR_IS_OK(werror)) {
8847 TALLOC_FREE(r->out.info);
8848 return werror;
8849 }
8850
8851 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo,
8852 r->out.info, r->in.level);
8853 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8854
8855 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8856 }
8857
8858 /****************************************************************
8859 _spoolss_EnumPrinterData
8860 ****************************************************************/
8861
_spoolss_EnumPrinterData(struct pipes_struct * p,struct spoolss_EnumPrinterData * r)8862 WERROR _spoolss_EnumPrinterData(struct pipes_struct *p,
8863 struct spoolss_EnumPrinterData *r)
8864 {
8865 WERROR result;
8866 struct spoolss_EnumPrinterDataEx r2;
8867 uint32_t count;
8868 struct spoolss_PrinterEnumValues *info, *val = NULL;
8869 uint32_t needed;
8870
8871 r2.in.handle = r->in.handle;
8872 r2.in.key_name = "PrinterDriverData";
8873 r2.in.offered = 0;
8874 r2.out.count = &count;
8875 r2.out.info = &info;
8876 r2.out.needed = &needed;
8877
8878 result = _spoolss_EnumPrinterDataEx(p, &r2);
8879 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
8880 r2.in.offered = needed;
8881 result = _spoolss_EnumPrinterDataEx(p, &r2);
8882 }
8883 if (!W_ERROR_IS_OK(result)) {
8884 return result;
8885 }
8886
8887 /*
8888 * The NT machine wants to know the biggest size of value and data
8889 *
8890 * cf: MSDN EnumPrinterData remark section
8891 */
8892
8893 if (!r->in.value_offered && !r->in.data_offered) {
8894 uint32_t biggest_valuesize = 0;
8895 uint32_t biggest_datasize = 0;
8896 int i, name_length;
8897
8898 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8899
8900 for (i=0; i<count; i++) {
8901
8902 name_length = strlen(info[i].value_name);
8903 if (strlen(info[i].value_name) > biggest_valuesize) {
8904 biggest_valuesize = name_length;
8905 }
8906
8907 if (info[i].data_length > biggest_datasize) {
8908 biggest_datasize = info[i].data_length;
8909 }
8910
8911 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
8912 biggest_datasize));
8913 }
8914
8915 /* the value is an UNICODE string but real_value_size is the length
8916 in bytes including the trailing 0 */
8917
8918 *r->out.value_needed = 2 * (1 + biggest_valuesize);
8919 *r->out.data_needed = biggest_datasize;
8920
8921 DEBUG(6,("final values: [%d], [%d]\n",
8922 *r->out.value_needed, *r->out.data_needed));
8923
8924 return WERR_OK;
8925 }
8926
8927 if (r->in.enum_index < count) {
8928 val = &info[r->in.enum_index];
8929 }
8930
8931 if (val == NULL) {
8932 /* out_value should default to "" or else NT4 has
8933 problems unmarshalling the response */
8934
8935 if (r->in.value_offered) {
8936 *r->out.value_needed = 1;
8937 r->out.value_name = talloc_strdup(r, "");
8938 if (!r->out.value_name) {
8939 return WERR_NOT_ENOUGH_MEMORY;
8940 }
8941 } else {
8942 r->out.value_name = NULL;
8943 *r->out.value_needed = 0;
8944 }
8945
8946 /* the data is counted in bytes */
8947
8948 *r->out.data_needed = r->in.data_offered;
8949
8950 result = WERR_NO_MORE_ITEMS;
8951 } else {
8952 /*
8953 * the value is:
8954 * - counted in bytes in the request
8955 * - counted in UNICODE chars in the max reply
8956 * - counted in bytes in the real size
8957 *
8958 * take a pause *before* coding not *during* coding
8959 */
8960
8961 /* name */
8962 if (r->in.value_offered) {
8963 r->out.value_name = talloc_strdup(r, val->value_name);
8964 if (!r->out.value_name) {
8965 return WERR_NOT_ENOUGH_MEMORY;
8966 }
8967 *r->out.value_needed = val->value_name_len;
8968 } else {
8969 r->out.value_name = NULL;
8970 *r->out.value_needed = 0;
8971 }
8972
8973 /* type */
8974
8975 *r->out.type = val->type;
8976
8977 /* data - counted in bytes */
8978
8979 /*
8980 * See the section "Dynamically Typed Query Parameters"
8981 * in MS-RPRN.
8982 */
8983
8984 if (r->out.data && val->data && val->data->data &&
8985 val->data_length && r->in.data_offered) {
8986 memcpy(r->out.data, val->data->data,
8987 MIN(val->data_length,r->in.data_offered));
8988 }
8989
8990 *r->out.data_needed = val->data_length;
8991
8992 result = WERR_OK;
8993 }
8994
8995 return result;
8996 }
8997
8998 /****************************************************************
8999 _spoolss_SetPrinterData
9000 ****************************************************************/
9001
_spoolss_SetPrinterData(struct pipes_struct * p,struct spoolss_SetPrinterData * r)9002 WERROR _spoolss_SetPrinterData(struct pipes_struct *p,
9003 struct spoolss_SetPrinterData *r)
9004 {
9005 struct spoolss_SetPrinterDataEx r2;
9006
9007 r2.in.handle = r->in.handle;
9008 r2.in.key_name = "PrinterDriverData";
9009 r2.in.value_name = r->in.value_name;
9010 r2.in.type = r->in.type;
9011 r2.in.data = r->in.data;
9012 r2.in.offered = r->in.offered;
9013
9014 return _spoolss_SetPrinterDataEx(p, &r2);
9015 }
9016
9017 /****************************************************************
9018 _spoolss_ResetPrinter
9019 ****************************************************************/
9020
_spoolss_ResetPrinter(struct pipes_struct * p,struct spoolss_ResetPrinter * r)9021 WERROR _spoolss_ResetPrinter(struct pipes_struct *p,
9022 struct spoolss_ResetPrinter *r)
9023 {
9024 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9025 int snum;
9026
9027 DEBUG(5,("_spoolss_ResetPrinter\n"));
9028
9029 /*
9030 * All we do is to check to see if the handle and queue is valid.
9031 * This call really doesn't mean anything to us because we only
9032 * support RAW printing. --jerry
9033 */
9034
9035 if (!Printer) {
9036 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
9037 OUR_HANDLE(r->in.handle)));
9038 return WERR_INVALID_HANDLE;
9039 }
9040
9041 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
9042 return WERR_INVALID_HANDLE;
9043
9044
9045 /* blindly return success */
9046 return WERR_OK;
9047 }
9048
9049 /****************************************************************
9050 _spoolss_DeletePrinterData
9051 ****************************************************************/
9052
_spoolss_DeletePrinterData(struct pipes_struct * p,struct spoolss_DeletePrinterData * r)9053 WERROR _spoolss_DeletePrinterData(struct pipes_struct *p,
9054 struct spoolss_DeletePrinterData *r)
9055 {
9056 struct spoolss_DeletePrinterDataEx r2;
9057
9058 r2.in.handle = r->in.handle;
9059 r2.in.key_name = "PrinterDriverData";
9060 r2.in.value_name = r->in.value_name;
9061
9062 return _spoolss_DeletePrinterDataEx(p, &r2);
9063 }
9064
9065 /****************************************************************
9066 _spoolss_AddForm
9067 ****************************************************************/
9068
_spoolss_AddForm(struct pipes_struct * p,struct spoolss_AddForm * r)9069 WERROR _spoolss_AddForm(struct pipes_struct *p,
9070 struct spoolss_AddForm *r)
9071 {
9072 struct spoolss_AddFormInfo1 *form;
9073 int snum = -1;
9074 WERROR status = WERR_OK;
9075 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9076 struct dcerpc_binding_handle *b;
9077 TALLOC_CTX *tmp_ctx = NULL;
9078
9079 DEBUG(5,("_spoolss_AddForm\n"));
9080
9081 if (!Printer) {
9082 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
9083 OUR_HANDLE(r->in.handle)));
9084 return WERR_INVALID_HANDLE;
9085 }
9086
9087 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
9088 and not a printer admin, then fail */
9089
9090 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
9091 !security_token_has_privilege(p->session_info->security_token,
9092 SEC_PRIV_PRINT_OPERATOR)) {
9093 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
9094 return WERR_ACCESS_DENIED;
9095 }
9096
9097 if (r->in.info_ctr->level != 1) {
9098 return WERR_INVALID_LEVEL;
9099 }
9100
9101 form = r->in.info_ctr->info.info1;
9102 if (!form) {
9103 return WERR_INVALID_PARAMETER;
9104 }
9105
9106 switch (form->flags) {
9107 case SPOOLSS_FORM_USER:
9108 case SPOOLSS_FORM_BUILTIN:
9109 case SPOOLSS_FORM_PRINTER:
9110 break;
9111 default:
9112 return WERR_INVALID_PARAMETER;
9113 }
9114
9115 tmp_ctx = talloc_new(p->mem_ctx);
9116 if (!tmp_ctx) {
9117 return WERR_NOT_ENOUGH_MEMORY;
9118 }
9119
9120 status = winreg_printer_binding_handle(tmp_ctx,
9121 get_session_info_system(),
9122 p->msg_ctx,
9123 &b);
9124 if (!W_ERROR_IS_OK(status)) {
9125 goto done;
9126 }
9127
9128 status = winreg_printer_addform1(tmp_ctx, b, form);
9129 if (!W_ERROR_IS_OK(status)) {
9130 goto done;
9131 }
9132
9133 /*
9134 * ChangeID must always be set if this is a printer
9135 */
9136 if (Printer->printer_type == SPLHND_PRINTER) {
9137 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9138 status = WERR_INVALID_HANDLE;
9139 goto done;
9140 }
9141
9142 status = winreg_printer_update_changeid(tmp_ctx, b,
9143 lp_const_servicename(snum));
9144 }
9145
9146 done:
9147 talloc_free(tmp_ctx);
9148 return status;
9149 }
9150
9151 /****************************************************************
9152 _spoolss_DeleteForm
9153 ****************************************************************/
9154
_spoolss_DeleteForm(struct pipes_struct * p,struct spoolss_DeleteForm * r)9155 WERROR _spoolss_DeleteForm(struct pipes_struct *p,
9156 struct spoolss_DeleteForm *r)
9157 {
9158 const char *form_name = r->in.form_name;
9159 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9160 int snum = -1;
9161 WERROR status = WERR_OK;
9162 struct dcerpc_binding_handle *b;
9163 TALLOC_CTX *tmp_ctx = NULL;
9164
9165 DEBUG(5,("_spoolss_DeleteForm\n"));
9166
9167 if (!Printer) {
9168 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
9169 OUR_HANDLE(r->in.handle)));
9170 return WERR_INVALID_HANDLE;
9171 }
9172
9173 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
9174 !security_token_has_privilege(p->session_info->security_token,
9175 SEC_PRIV_PRINT_OPERATOR)) {
9176 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
9177 return WERR_ACCESS_DENIED;
9178 }
9179
9180 tmp_ctx = talloc_new(p->mem_ctx);
9181 if (!tmp_ctx) {
9182 return WERR_NOT_ENOUGH_MEMORY;
9183 }
9184
9185 status = winreg_printer_binding_handle(tmp_ctx,
9186 get_session_info_system(),
9187 p->msg_ctx,
9188 &b);
9189 if (!W_ERROR_IS_OK(status)) {
9190 goto done;
9191 }
9192
9193 status = winreg_printer_deleteform1(tmp_ctx, b, form_name);
9194 if (!W_ERROR_IS_OK(status)) {
9195 goto done;
9196 }
9197
9198 /*
9199 * ChangeID must always be set if this is a printer
9200 */
9201 if (Printer->printer_type == SPLHND_PRINTER) {
9202 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9203 status = WERR_INVALID_HANDLE;
9204 goto done;
9205 }
9206
9207 status = winreg_printer_update_changeid(tmp_ctx, b,
9208 lp_const_servicename(snum));
9209 }
9210
9211 done:
9212 talloc_free(tmp_ctx);
9213 return status;
9214 }
9215
9216 /****************************************************************
9217 _spoolss_SetForm
9218 ****************************************************************/
9219
_spoolss_SetForm(struct pipes_struct * p,struct spoolss_SetForm * r)9220 WERROR _spoolss_SetForm(struct pipes_struct *p,
9221 struct spoolss_SetForm *r)
9222 {
9223 struct spoolss_AddFormInfo1 *form;
9224 const char *form_name = r->in.form_name;
9225 int snum = -1;
9226 WERROR status = WERR_OK;
9227 struct dcerpc_binding_handle *b;
9228 TALLOC_CTX *tmp_ctx = NULL;
9229
9230 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9231
9232 DEBUG(5,("_spoolss_SetForm\n"));
9233
9234 if (!Printer) {
9235 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
9236 OUR_HANDLE(r->in.handle)));
9237 return WERR_INVALID_HANDLE;
9238 }
9239
9240 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
9241 and not a printer admin, then fail */
9242
9243 if ((p->session_info->unix_token->uid != sec_initial_uid()) &&
9244 !security_token_has_privilege(p->session_info->security_token,
9245 SEC_PRIV_PRINT_OPERATOR)) {
9246 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
9247 return WERR_ACCESS_DENIED;
9248 }
9249
9250 if (r->in.info_ctr->level != 1) {
9251 return WERR_INVALID_LEVEL;
9252 }
9253
9254 form = r->in.info_ctr->info.info1;
9255 if (!form) {
9256 return WERR_INVALID_PARAMETER;
9257 }
9258
9259 tmp_ctx = talloc_new(p->mem_ctx);
9260 if (!tmp_ctx) {
9261 return WERR_NOT_ENOUGH_MEMORY;
9262 }
9263
9264 status = winreg_printer_binding_handle(tmp_ctx,
9265 get_session_info_system(),
9266 p->msg_ctx,
9267 &b);
9268 if (!W_ERROR_IS_OK(status)) {
9269 goto done;
9270 }
9271
9272 status = winreg_printer_setform1(tmp_ctx, b,
9273 form_name,
9274 form);
9275 if (!W_ERROR_IS_OK(status)) {
9276 goto done;
9277 }
9278
9279 /*
9280 * ChangeID must always be set if this is a printer
9281 */
9282 if (Printer->printer_type == SPLHND_PRINTER) {
9283 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9284 status = WERR_INVALID_HANDLE;
9285 goto done;
9286 }
9287
9288 status = winreg_printer_update_changeid(tmp_ctx, b,
9289 lp_const_servicename(snum));
9290 }
9291
9292 done:
9293 talloc_free(tmp_ctx);
9294 return status;
9295 }
9296
9297 /****************************************************************************
9298 fill_print_processor1
9299 ****************************************************************************/
9300
fill_print_processor1(TALLOC_CTX * mem_ctx,struct spoolss_PrintProcessorInfo1 * r,const char * print_processor_name)9301 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
9302 struct spoolss_PrintProcessorInfo1 *r,
9303 const char *print_processor_name)
9304 {
9305 r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
9306 W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
9307
9308 return WERR_OK;
9309 }
9310
9311 /****************************************************************************
9312 enumprintprocessors level 1.
9313 ****************************************************************************/
9314
enumprintprocessors_level_1(TALLOC_CTX * mem_ctx,union spoolss_PrintProcessorInfo ** info_p,uint32_t * count)9315 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
9316 union spoolss_PrintProcessorInfo **info_p,
9317 uint32_t *count)
9318 {
9319 union spoolss_PrintProcessorInfo *info;
9320 WERROR result;
9321
9322 info = talloc_array(mem_ctx, union spoolss_PrintProcessorInfo, 1);
9323 W_ERROR_HAVE_NO_MEMORY(info);
9324
9325 *count = 1;
9326
9327 result = fill_print_processor1(info, &info[0].info1, "winprint");
9328 if (!W_ERROR_IS_OK(result)) {
9329 goto out;
9330 }
9331
9332 out:
9333 if (!W_ERROR_IS_OK(result)) {
9334 TALLOC_FREE(info);
9335 *count = 0;
9336 return result;
9337 }
9338
9339 *info_p = info;
9340
9341 return WERR_OK;
9342 }
9343
9344 /****************************************************************
9345 _spoolss_EnumPrintProcessors
9346 ****************************************************************/
9347
_spoolss_EnumPrintProcessors(struct pipes_struct * p,struct spoolss_EnumPrintProcessors * r)9348 WERROR _spoolss_EnumPrintProcessors(struct pipes_struct *p,
9349 struct spoolss_EnumPrintProcessors *r)
9350 {
9351 WERROR result;
9352
9353 /* that's an [in out] buffer */
9354
9355 if (!r->in.buffer && (r->in.offered != 0)) {
9356 return WERR_INVALID_PARAMETER;
9357 }
9358
9359 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
9360
9361 /*
9362 * Enumerate the print processors ...
9363 *
9364 * Just reply with "winprint", to keep NT happy
9365 * and I can use my nice printer checker.
9366 */
9367
9368 *r->out.count = 0;
9369 *r->out.needed = 0;
9370 *r->out.info = NULL;
9371
9372 if (!get_short_archi(r->in.environment)) {
9373 return WERR_INVALID_ENVIRONMENT;
9374 }
9375
9376 switch (r->in.level) {
9377 case 1:
9378 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
9379 r->out.count);
9380 break;
9381 default:
9382 return WERR_INVALID_LEVEL;
9383 }
9384
9385 if (!W_ERROR_IS_OK(result)) {
9386 return result;
9387 }
9388
9389 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
9390 spoolss_EnumPrintProcessors,
9391 *r->out.info, r->in.level,
9392 *r->out.count);
9393 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
9394 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
9395
9396 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9397 }
9398
9399 /****************************************************************************
9400 fill_printprocdatatype1
9401 ****************************************************************************/
9402
fill_printprocdatatype1(TALLOC_CTX * mem_ctx,struct spoolss_PrintProcDataTypesInfo1 * r,const char * name_array)9403 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
9404 struct spoolss_PrintProcDataTypesInfo1 *r,
9405 const char *name_array)
9406 {
9407 r->name_array = talloc_strdup(mem_ctx, name_array);
9408 W_ERROR_HAVE_NO_MEMORY(r->name_array);
9409
9410 return WERR_OK;
9411 }
9412
9413 /****************************************************************************
9414 enumprintprocdatatypes level 1.
9415 ****************************************************************************/
9416
enumprintprocdatatypes_level_1(TALLOC_CTX * mem_ctx,union spoolss_PrintProcDataTypesInfo ** info_p,uint32_t * count)9417 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
9418 union spoolss_PrintProcDataTypesInfo **info_p,
9419 uint32_t *count)
9420 {
9421 WERROR result;
9422 union spoolss_PrintProcDataTypesInfo *info;
9423
9424 info = talloc_array(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
9425 W_ERROR_HAVE_NO_MEMORY(info);
9426
9427 *count = 1;
9428
9429 result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
9430 if (!W_ERROR_IS_OK(result)) {
9431 goto out;
9432 }
9433
9434 out:
9435 if (!W_ERROR_IS_OK(result)) {
9436 TALLOC_FREE(info);
9437 *count = 0;
9438 return result;
9439 }
9440
9441 *info_p = info;
9442
9443 return WERR_OK;
9444 }
9445
9446 /****************************************************************
9447 _spoolss_EnumPrintProcessorDataTypes
9448 ****************************************************************/
9449
_spoolss_EnumPrintProcessorDataTypes(struct pipes_struct * p,struct spoolss_EnumPrintProcessorDataTypes * r)9450 WERROR _spoolss_EnumPrintProcessorDataTypes(struct pipes_struct *p,
9451 struct spoolss_EnumPrintProcessorDataTypes *r)
9452 {
9453 WERROR result;
9454
9455 /* that's an [in out] buffer */
9456
9457 if (!r->in.buffer && (r->in.offered != 0)) {
9458 return WERR_INVALID_PARAMETER;
9459 }
9460
9461 DEBUG(5,("_spoolss_EnumPrintProcessorDataTypes\n"));
9462
9463 *r->out.count = 0;
9464 *r->out.needed = 0;
9465 *r->out.info = NULL;
9466
9467 if (r->in.print_processor_name == NULL ||
9468 !strequal(r->in.print_processor_name, "winprint")) {
9469 return WERR_UNKNOWN_PRINTPROCESSOR;
9470 }
9471
9472 switch (r->in.level) {
9473 case 1:
9474 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
9475 r->out.count);
9476 break;
9477 default:
9478 return WERR_INVALID_LEVEL;
9479 }
9480
9481 if (!W_ERROR_IS_OK(result)) {
9482 return result;
9483 }
9484
9485 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
9486 spoolss_EnumPrintProcessorDataTypes,
9487 *r->out.info, r->in.level,
9488 *r->out.count);
9489 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
9490 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
9491
9492 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9493 }
9494
9495 /****************************************************************************
9496 fill_monitor_1
9497 ****************************************************************************/
9498
fill_monitor_1(TALLOC_CTX * mem_ctx,struct spoolss_MonitorInfo1 * r,const char * monitor_name)9499 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
9500 struct spoolss_MonitorInfo1 *r,
9501 const char *monitor_name)
9502 {
9503 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
9504 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
9505
9506 return WERR_OK;
9507 }
9508
9509 /****************************************************************************
9510 fill_monitor_2
9511 ****************************************************************************/
9512
fill_monitor_2(TALLOC_CTX * mem_ctx,struct spoolss_MonitorInfo2 * r,const char * monitor_name,const char * environment,const char * dll_name)9513 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
9514 struct spoolss_MonitorInfo2 *r,
9515 const char *monitor_name,
9516 const char *environment,
9517 const char *dll_name)
9518 {
9519 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
9520 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
9521 r->environment = talloc_strdup(mem_ctx, environment);
9522 W_ERROR_HAVE_NO_MEMORY(r->environment);
9523 r->dll_name = talloc_strdup(mem_ctx, dll_name);
9524 W_ERROR_HAVE_NO_MEMORY(r->dll_name);
9525
9526 return WERR_OK;
9527 }
9528
9529 /****************************************************************************
9530 enumprintmonitors level 1.
9531 ****************************************************************************/
9532
enumprintmonitors_level_1(TALLOC_CTX * mem_ctx,union spoolss_MonitorInfo ** info_p,uint32_t * count)9533 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
9534 union spoolss_MonitorInfo **info_p,
9535 uint32_t *count)
9536 {
9537 union spoolss_MonitorInfo *info;
9538 WERROR result = WERR_OK;
9539
9540 info = talloc_array(mem_ctx, union spoolss_MonitorInfo, 2);
9541 W_ERROR_HAVE_NO_MEMORY(info);
9542
9543 *count = 2;
9544
9545 result = fill_monitor_1(info, &info[0].info1,
9546 SPL_LOCAL_PORT);
9547 if (!W_ERROR_IS_OK(result)) {
9548 goto out;
9549 }
9550
9551 result = fill_monitor_1(info, &info[1].info1,
9552 SPL_TCPIP_PORT);
9553 if (!W_ERROR_IS_OK(result)) {
9554 goto out;
9555 }
9556
9557 out:
9558 if (!W_ERROR_IS_OK(result)) {
9559 TALLOC_FREE(info);
9560 *count = 0;
9561 return result;
9562 }
9563
9564 *info_p = info;
9565
9566 return WERR_OK;
9567 }
9568
9569 /****************************************************************************
9570 enumprintmonitors level 2.
9571 ****************************************************************************/
9572
enumprintmonitors_level_2(TALLOC_CTX * mem_ctx,union spoolss_MonitorInfo ** info_p,uint32_t * count)9573 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
9574 union spoolss_MonitorInfo **info_p,
9575 uint32_t *count)
9576 {
9577 union spoolss_MonitorInfo *info;
9578 WERROR result = WERR_OK;
9579 const char *architecture;
9580
9581 info = talloc_array(mem_ctx, union spoolss_MonitorInfo, 2);
9582 W_ERROR_HAVE_NO_MEMORY(info);
9583
9584 *count = 2;
9585
9586 architecture = lp_parm_const_string(GLOBAL_SECTION_SNUM,
9587 "spoolss",
9588 "architecture",
9589 GLOBAL_SPOOLSS_ARCHITECTURE);
9590
9591 result = fill_monitor_2(info, &info[0].info2,
9592 SPL_LOCAL_PORT,
9593 architecture,
9594 "localmon.dll");
9595 if (!W_ERROR_IS_OK(result)) {
9596 goto out;
9597 }
9598
9599 result = fill_monitor_2(info, &info[1].info2,
9600 SPL_TCPIP_PORT,
9601 architecture,
9602 "tcpmon.dll");
9603 if (!W_ERROR_IS_OK(result)) {
9604 goto out;
9605 }
9606
9607 out:
9608 if (!W_ERROR_IS_OK(result)) {
9609 TALLOC_FREE(info);
9610 *count = 0;
9611 return result;
9612 }
9613
9614 *info_p = info;
9615
9616 return WERR_OK;
9617 }
9618
9619 /****************************************************************
9620 _spoolss_EnumMonitors
9621 ****************************************************************/
9622
_spoolss_EnumMonitors(struct pipes_struct * p,struct spoolss_EnumMonitors * r)9623 WERROR _spoolss_EnumMonitors(struct pipes_struct *p,
9624 struct spoolss_EnumMonitors *r)
9625 {
9626 WERROR result;
9627
9628 /* that's an [in out] buffer */
9629
9630 if (!r->in.buffer && (r->in.offered != 0)) {
9631 return WERR_INVALID_PARAMETER;
9632 }
9633
9634 DEBUG(5,("_spoolss_EnumMonitors\n"));
9635
9636 /*
9637 * Enumerate the print monitors ...
9638 *
9639 * Just reply with "Local Port", to keep NT happy
9640 * and I can use my nice printer checker.
9641 */
9642
9643 *r->out.count = 0;
9644 *r->out.needed = 0;
9645 *r->out.info = NULL;
9646
9647 switch (r->in.level) {
9648 case 1:
9649 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
9650 r->out.count);
9651 break;
9652 case 2:
9653 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
9654 r->out.count);
9655 break;
9656 default:
9657 return WERR_INVALID_LEVEL;
9658 }
9659
9660 if (!W_ERROR_IS_OK(result)) {
9661 return result;
9662 }
9663
9664 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
9665 spoolss_EnumMonitors,
9666 *r->out.info, r->in.level,
9667 *r->out.count);
9668 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
9669 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
9670
9671 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9672 }
9673
9674 /****************************************************************************
9675 ****************************************************************************/
9676
getjob_level_1(TALLOC_CTX * mem_ctx,const print_queue_struct * queue,int count,int snum,struct spoolss_PrinterInfo2 * pinfo2,uint32_t jobid,int sysjob,struct spoolss_JobInfo1 * r)9677 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
9678 const print_queue_struct *queue,
9679 int count, int snum,
9680 struct spoolss_PrinterInfo2 *pinfo2,
9681 uint32_t jobid,
9682 int sysjob,
9683 struct spoolss_JobInfo1 *r)
9684 {
9685 int i = 0;
9686 bool found = false;
9687
9688 for (i=0; i<count; i++) {
9689 if (queue[i].sysjob == sysjob) {
9690 found = true;
9691 break;
9692 }
9693 }
9694
9695 if (found == false) {
9696 /* NT treats not found as bad param... yet another bad choice */
9697 return WERR_INVALID_PARAMETER;
9698 }
9699
9700 return fill_job_info1(mem_ctx,
9701 r,
9702 &queue[i],
9703 jobid,
9704 i,
9705 snum,
9706 pinfo2);
9707 }
9708
9709 /****************************************************************************
9710 ****************************************************************************/
9711
getjob_level_2(TALLOC_CTX * mem_ctx,const print_queue_struct * queue,int count,int snum,struct spoolss_PrinterInfo2 * pinfo2,uint32_t jobid,int sysjob,struct spoolss_JobInfo2 * r)9712 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
9713 const print_queue_struct *queue,
9714 int count, int snum,
9715 struct spoolss_PrinterInfo2 *pinfo2,
9716 uint32_t jobid,
9717 int sysjob,
9718 struct spoolss_JobInfo2 *r)
9719 {
9720 int i = 0;
9721 bool found = false;
9722 struct spoolss_DeviceMode *devmode;
9723 WERROR result;
9724
9725 for (i=0; i<count; i++) {
9726 if (queue[i].sysjob == sysjob) {
9727 found = true;
9728 break;
9729 }
9730 }
9731
9732 if (found == false) {
9733 /* NT treats not found as bad param... yet another bad
9734 choice */
9735 return WERR_INVALID_PARAMETER;
9736 }
9737
9738 /*
9739 * if the print job does not have a DEVMODE associated with it,
9740 * just use the one for the printer. A NULL devicemode is not
9741 * a failure condition
9742 */
9743
9744 devmode = print_job_devmode(mem_ctx, lp_const_servicename(snum), jobid);
9745 if (!devmode) {
9746 result = spoolss_create_default_devmode(mem_ctx,
9747 pinfo2->printername,
9748 &devmode);
9749 if (!W_ERROR_IS_OK(result)) {
9750 DEBUG(3, ("Can't proceed w/o a devmode!"));
9751 return result;
9752 }
9753 }
9754
9755 return fill_job_info2(mem_ctx,
9756 r,
9757 &queue[i],
9758 jobid,
9759 i,
9760 snum,
9761 pinfo2,
9762 devmode);
9763 }
9764
9765 /****************************************************************
9766 _spoolss_GetJob
9767 ****************************************************************/
9768
_spoolss_GetJob(struct pipes_struct * p,struct spoolss_GetJob * r)9769 WERROR _spoolss_GetJob(struct pipes_struct *p,
9770 struct spoolss_GetJob *r)
9771 {
9772 WERROR result = WERR_OK;
9773 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
9774 const char *svc_name;
9775 int sysjob;
9776 int snum;
9777 int count;
9778 struct tdb_print_db *pdb;
9779 print_queue_struct *queue = NULL;
9780 print_status_struct prt_status;
9781
9782 /* that's an [in out] buffer */
9783
9784 if (!r->in.buffer && (r->in.offered != 0)) {
9785 result = WERR_INVALID_PARAMETER;
9786 goto err_jinfo_free;
9787 }
9788
9789 DEBUG(5,("_spoolss_GetJob\n"));
9790
9791 *r->out.needed = 0;
9792
9793 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9794 result = WERR_INVALID_HANDLE;
9795 goto err_jinfo_free;
9796 }
9797
9798 svc_name = lp_const_servicename(snum);
9799 if (svc_name == NULL) {
9800 result = WERR_INVALID_PARAMETER;
9801 goto err_jinfo_free;
9802 }
9803
9804 result = winreg_get_printer_internal(p->mem_ctx,
9805 get_session_info_system(),
9806 p->msg_ctx,
9807 svc_name,
9808 &pinfo2);
9809 if (!W_ERROR_IS_OK(result)) {
9810 goto err_jinfo_free;
9811 }
9812
9813 pdb = get_print_db_byname(svc_name);
9814 if (pdb == NULL) {
9815 DEBUG(3, ("failed to get print db for svc %s\n", svc_name));
9816 result = WERR_INVALID_PARAMETER;
9817 goto err_pinfo_free;
9818 }
9819
9820 sysjob = jobid_to_sysjob_pdb(pdb, r->in.job_id);
9821 release_print_db(pdb);
9822 if (sysjob == -1) {
9823 DEBUG(3, ("no sysjob for spoolss jobid %u\n", r->in.job_id));
9824 result = WERR_INVALID_PARAMETER;
9825 goto err_pinfo_free;
9826 }
9827
9828 count = print_queue_status(p->msg_ctx, snum, &queue, &prt_status);
9829
9830 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9831 count, prt_status.status, prt_status.message));
9832
9833 switch (r->in.level) {
9834 case 1:
9835 result = getjob_level_1(p->mem_ctx,
9836 queue, count, snum, pinfo2,
9837 r->in.job_id, sysjob,
9838 &r->out.info->info1);
9839 break;
9840 case 2:
9841 result = getjob_level_2(p->mem_ctx,
9842 queue, count, snum, pinfo2,
9843 r->in.job_id, sysjob,
9844 &r->out.info->info2);
9845 break;
9846 default:
9847 result = WERR_INVALID_LEVEL;
9848 break;
9849 }
9850
9851 SAFE_FREE(queue);
9852 TALLOC_FREE(pinfo2);
9853
9854 if (!W_ERROR_IS_OK(result)) {
9855 goto err_jinfo_free;
9856 }
9857
9858 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
9859 r->in.level);
9860 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9861
9862 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9863
9864 err_pinfo_free:
9865 TALLOC_FREE(pinfo2);
9866 err_jinfo_free:
9867 TALLOC_FREE(r->out.info);
9868 return result;
9869 }
9870
9871 /****************************************************************
9872 _spoolss_GetPrinterDataEx
9873 ****************************************************************/
9874
_spoolss_GetPrinterDataEx(struct pipes_struct * p,struct spoolss_GetPrinterDataEx * r)9875 WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
9876 struct spoolss_GetPrinterDataEx *r)
9877 {
9878
9879 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
9880 const char *printer;
9881 int snum = 0;
9882 WERROR result = WERR_OK;
9883 DATA_BLOB blob;
9884 enum winreg_Type val_type = REG_NONE;
9885 uint8_t *val_data = NULL;
9886 uint32_t val_size = 0;
9887 struct dcerpc_binding_handle *b;
9888 TALLOC_CTX *tmp_ctx;
9889
9890 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
9891
9892 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
9893 r->in.key_name, r->in.value_name));
9894
9895 /* in case of problem, return some default values */
9896
9897 *r->out.needed = 0;
9898 *r->out.type = REG_NONE;
9899
9900 tmp_ctx = talloc_new(p->mem_ctx);
9901 if (!tmp_ctx) {
9902 return WERR_NOT_ENOUGH_MEMORY;
9903 }
9904
9905 if (!Printer) {
9906 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
9907 OUR_HANDLE(r->in.handle)));
9908 result = WERR_INVALID_HANDLE;
9909 goto done;
9910 }
9911
9912 /* Is the handle to a printer or to the server? */
9913
9914 if (Printer->printer_type == SPLHND_SERVER) {
9915
9916 union spoolss_PrinterData data;
9917
9918 result = getprinterdata_printer_server(tmp_ctx,
9919 r->in.value_name,
9920 r->out.type,
9921 &data);
9922 if (!W_ERROR_IS_OK(result)) {
9923 goto done;
9924 }
9925
9926 result = push_spoolss_PrinterData(tmp_ctx, &blob,
9927 *r->out.type, &data);
9928 if (!W_ERROR_IS_OK(result)) {
9929 goto done;
9930 }
9931
9932 *r->out.needed = blob.length;
9933
9934 if (r->in.offered >= *r->out.needed) {
9935 memcpy(r->out.data, blob.data, blob.length);
9936 }
9937
9938 result = WERR_OK;
9939 goto done;
9940 }
9941
9942 /* check to see if the keyname is valid */
9943 if (!strlen(r->in.key_name)) {
9944 result = WERR_INVALID_PARAMETER;
9945 goto done;
9946 }
9947
9948 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9949 result = WERR_INVALID_HANDLE;
9950 goto done;
9951 }
9952 printer = lp_const_servicename(snum);
9953
9954 result = winreg_printer_binding_handle(tmp_ctx,
9955 get_session_info_system(),
9956 p->msg_ctx,
9957 &b);
9958 if (!W_ERROR_IS_OK(result)) {
9959 goto done;
9960 }
9961
9962 /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
9963 if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
9964 strequal(r->in.value_name, "ChangeId")) {
9965 *r->out.type = REG_DWORD;
9966 *r->out.needed = 4;
9967 if (r->in.offered >= *r->out.needed) {
9968 uint32_t changeid = 0;
9969
9970 result = winreg_printer_get_changeid(tmp_ctx, b,
9971 printer,
9972 &changeid);
9973 if (!W_ERROR_IS_OK(result)) {
9974 goto done;
9975 }
9976
9977 SIVAL(r->out.data, 0, changeid);
9978 result = WERR_OK;
9979 }
9980 goto done;
9981 }
9982
9983 result = winreg_get_printer_dataex(tmp_ctx, b,
9984 printer,
9985 r->in.key_name,
9986 r->in.value_name,
9987 &val_type,
9988 &val_data,
9989 &val_size);
9990 if (!W_ERROR_IS_OK(result)) {
9991 goto done;
9992 }
9993
9994 *r->out.needed = val_size;
9995 *r->out.type = val_type;
9996
9997 if (r->in.offered >= *r->out.needed) {
9998 memcpy(r->out.data, val_data, val_size);
9999 }
10000
10001 done:
10002 /* NOTE: do not replace type when returning WERR_MORE_DATA */
10003
10004 if (W_ERROR_IS_OK(result)) {
10005 result = SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
10006 }
10007
10008 talloc_free(tmp_ctx);
10009 return result;
10010 }
10011
10012 /****************************************************************
10013 _spoolss_SetPrinterDataEx
10014 ****************************************************************/
10015
_spoolss_SetPrinterDataEx(struct pipes_struct * p,struct spoolss_SetPrinterDataEx * r)10016 WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
10017 struct spoolss_SetPrinterDataEx *r)
10018 {
10019 const struct loadparm_substitution *lp_sub =
10020 loadparm_s3_global_substitution();
10021 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
10022 int snum = 0;
10023 WERROR result = WERR_OK;
10024 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
10025 char *oid_string;
10026 struct dcerpc_binding_handle *b;
10027 TALLOC_CTX *tmp_ctx;
10028
10029 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
10030
10031 /* From MSDN documentation of SetPrinterDataEx: pass request to
10032 SetPrinterData if key is "PrinterDriverData" */
10033
10034 if (!Printer) {
10035 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
10036 OUR_HANDLE(r->in.handle)));
10037 return WERR_INVALID_HANDLE;
10038 }
10039
10040 if (Printer->printer_type == SPLHND_SERVER) {
10041 DEBUG(10,("_spoolss_SetPrinterDataEx: "
10042 "Not implemented for server handles yet\n"));
10043 return WERR_INVALID_PARAMETER;
10044 }
10045
10046 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
10047 return WERR_INVALID_HANDLE;
10048 }
10049
10050 /*
10051 * Access check : NT returns "access denied" if you make a
10052 * SetPrinterData call without the necessary privildge.
10053 * we were originally returning OK if nothing changed
10054 * which made Win2k issue **a lot** of SetPrinterData
10055 * when connecting to a printer --jerry
10056 */
10057
10058 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
10059 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
10060 "change denied by handle access permissions\n"));
10061 return WERR_ACCESS_DENIED;
10062 }
10063
10064 tmp_ctx = talloc_new(p->mem_ctx);
10065 if (!tmp_ctx) {
10066 return WERR_NOT_ENOUGH_MEMORY;
10067 }
10068
10069 result = winreg_printer_binding_handle(tmp_ctx,
10070 get_session_info_system(),
10071 p->msg_ctx,
10072 &b);
10073 if (!W_ERROR_IS_OK(result)) {
10074 goto done;
10075 }
10076
10077 result = winreg_get_printer(tmp_ctx, b,
10078 lp_servicename(talloc_tos(), lp_sub, snum),
10079 &pinfo2);
10080 if (!W_ERROR_IS_OK(result)) {
10081 goto done;
10082 }
10083
10084 /* check for OID in valuename */
10085
10086 oid_string = strchr(r->in.value_name, ',');
10087 if (oid_string) {
10088 *oid_string = '\0';
10089 oid_string++;
10090 }
10091
10092 /* save the registry data */
10093
10094 result = winreg_set_printer_dataex(tmp_ctx, b,
10095 pinfo2->sharename,
10096 r->in.key_name,
10097 r->in.value_name,
10098 r->in.type,
10099 r->in.data,
10100 r->in.offered);
10101
10102 if (W_ERROR_IS_OK(result)) {
10103 /* save the OID if one was specified */
10104 if (oid_string) {
10105 char *str = talloc_asprintf(tmp_ctx, "%s\\%s",
10106 r->in.key_name, SPOOL_OID_KEY);
10107 if (!str) {
10108 result = WERR_NOT_ENOUGH_MEMORY;
10109 goto done;
10110 }
10111
10112 /*
10113 * I'm not checking the status here on purpose. Don't know
10114 * if this is right, but I'm returning the status from the
10115 * previous set_printer_dataex() call. I have no idea if
10116 * this is right. --jerry
10117 */
10118 winreg_set_printer_dataex(tmp_ctx, b,
10119 pinfo2->sharename,
10120 str,
10121 r->in.value_name,
10122 REG_SZ,
10123 (uint8_t *) oid_string,
10124 strlen(oid_string) + 1);
10125 }
10126
10127 result = winreg_printer_update_changeid(tmp_ctx, b,
10128 lp_const_servicename(snum));
10129
10130 }
10131
10132 done:
10133 talloc_free(tmp_ctx);
10134 return result;
10135 }
10136
10137 /****************************************************************
10138 _spoolss_DeletePrinterDataEx
10139 ****************************************************************/
10140
_spoolss_DeletePrinterDataEx(struct pipes_struct * p,struct spoolss_DeletePrinterDataEx * r)10141 WERROR _spoolss_DeletePrinterDataEx(struct pipes_struct *p,
10142 struct spoolss_DeletePrinterDataEx *r)
10143 {
10144 const char *printer;
10145 int snum=0;
10146 WERROR status = WERR_OK;
10147 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
10148
10149 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
10150
10151 if (!Printer) {
10152 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
10153 "Invalid handle (%s:%u:%u).\n",
10154 OUR_HANDLE(r->in.handle)));
10155 return WERR_INVALID_HANDLE;
10156 }
10157
10158 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
10159 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
10160 "printer properties change denied by handle\n"));
10161 return WERR_ACCESS_DENIED;
10162 }
10163
10164 if (!r->in.value_name || !r->in.key_name) {
10165 return WERR_NOT_ENOUGH_MEMORY;
10166 }
10167
10168 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
10169 return WERR_INVALID_HANDLE;
10170 }
10171 printer = lp_const_servicename(snum);
10172
10173 status = winreg_delete_printer_dataex_internal(p->mem_ctx,
10174 get_session_info_system(),
10175 p->msg_ctx,
10176 printer,
10177 r->in.key_name,
10178 r->in.value_name);
10179 if (W_ERROR_IS_OK(status)) {
10180 status = winreg_printer_update_changeid_internal(p->mem_ctx,
10181 get_session_info_system(),
10182 p->msg_ctx,
10183 printer);
10184 }
10185
10186 return status;
10187 }
10188
10189 /****************************************************************
10190 _spoolss_EnumPrinterKey
10191 ****************************************************************/
10192
_spoolss_EnumPrinterKey(struct pipes_struct * p,struct spoolss_EnumPrinterKey * r)10193 WERROR _spoolss_EnumPrinterKey(struct pipes_struct *p,
10194 struct spoolss_EnumPrinterKey *r)
10195 {
10196 uint32_t num_keys;
10197 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
10198 int snum = 0;
10199 WERROR result = WERR_FILE_NOT_FOUND;
10200 const char **array = NULL;
10201 DATA_BLOB blob;
10202
10203 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
10204
10205 if (!Printer) {
10206 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
10207 OUR_HANDLE(r->in.handle)));
10208 return WERR_INVALID_HANDLE;
10209 }
10210
10211 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
10212 return WERR_INVALID_HANDLE;
10213 }
10214
10215 result = winreg_enum_printer_key_internal(p->mem_ctx,
10216 get_session_info_system(),
10217 p->msg_ctx,
10218 lp_const_servicename(snum),
10219 r->in.key_name,
10220 &num_keys,
10221 &array);
10222 if (!W_ERROR_IS_OK(result)) {
10223 goto done;
10224 }
10225
10226 if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
10227 result = WERR_NOT_ENOUGH_MEMORY;
10228 goto done;
10229 }
10230
10231 *r->out._ndr_size = r->in.offered / 2;
10232 *r->out.needed = blob.length;
10233
10234 if (r->in.offered < *r->out.needed) {
10235 result = WERR_MORE_DATA;
10236 } else {
10237 result = WERR_OK;
10238 r->out.key_buffer->string_array = array;
10239 }
10240
10241 done:
10242 if (!W_ERROR_IS_OK(result)) {
10243 TALLOC_FREE(array);
10244 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
10245 *r->out.needed = 0;
10246 }
10247 }
10248
10249 return result;
10250 }
10251
10252 /****************************************************************
10253 _spoolss_DeletePrinterKey
10254 ****************************************************************/
10255
_spoolss_DeletePrinterKey(struct pipes_struct * p,struct spoolss_DeletePrinterKey * r)10256 WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
10257 struct spoolss_DeletePrinterKey *r)
10258 {
10259 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
10260 int snum=0;
10261 WERROR status;
10262 const char *printer;
10263 struct dcerpc_binding_handle *b;
10264 TALLOC_CTX *tmp_ctx;
10265
10266 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
10267
10268 if (!Printer) {
10269 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
10270 OUR_HANDLE(r->in.handle)));
10271 return WERR_INVALID_HANDLE;
10272 }
10273
10274 /* if keyname == NULL, return error */
10275 if ( !r->in.key_name )
10276 return WERR_INVALID_PARAMETER;
10277
10278 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
10279 return WERR_INVALID_HANDLE;
10280 }
10281
10282 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
10283 DEBUG(3, ("_spoolss_DeletePrinterKey: "
10284 "printer properties change denied by handle\n"));
10285 return WERR_ACCESS_DENIED;
10286 }
10287
10288 printer = lp_const_servicename(snum);
10289
10290 tmp_ctx = talloc_new(p->mem_ctx);
10291 if (!tmp_ctx) {
10292 return WERR_NOT_ENOUGH_MEMORY;
10293 }
10294
10295 status = winreg_printer_binding_handle(tmp_ctx,
10296 get_session_info_system(),
10297 p->msg_ctx,
10298 &b);
10299 if (!W_ERROR_IS_OK(status)) {
10300 goto done;
10301 }
10302
10303 /* delete the key and all subkeys */
10304 status = winreg_delete_printer_key(tmp_ctx, b,
10305 printer,
10306 r->in.key_name);
10307 if (W_ERROR_IS_OK(status)) {
10308 status = winreg_printer_update_changeid(tmp_ctx, b,
10309 printer);
10310 }
10311
10312 done:
10313 talloc_free(tmp_ctx);
10314 return status;
10315 }
10316
10317 /****************************************************************
10318 _spoolss_EnumPrinterDataEx
10319 ****************************************************************/
10320
_spoolss_EnumPrinterDataEx(struct pipes_struct * p,struct spoolss_EnumPrinterDataEx * r)10321 WERROR _spoolss_EnumPrinterDataEx(struct pipes_struct *p,
10322 struct spoolss_EnumPrinterDataEx *r)
10323 {
10324 uint32_t count = 0;
10325 struct spoolss_PrinterEnumValues *info = NULL;
10326 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
10327 int snum;
10328 WERROR result;
10329
10330 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
10331
10332 *r->out.count = 0;
10333 *r->out.needed = 0;
10334 *r->out.info = NULL;
10335
10336 if (!Printer) {
10337 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
10338 OUR_HANDLE(r->in.handle)));
10339 return WERR_INVALID_HANDLE;
10340 }
10341
10342 /*
10343 * first check for a keyname of NULL or "". Win2k seems to send
10344 * this a lot and we should send back WERR_INVALID_PARAMETER
10345 * no need to spend time looking up the printer in this case.
10346 * --jerry
10347 */
10348
10349 if (!strlen(r->in.key_name)) {
10350 result = WERR_INVALID_PARAMETER;
10351 goto done;
10352 }
10353
10354 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
10355 return WERR_INVALID_HANDLE;
10356 }
10357
10358 /* now look for a match on the key name */
10359 result = winreg_enum_printer_dataex_internal(p->mem_ctx,
10360 get_session_info_system(),
10361 p->msg_ctx,
10362 lp_const_servicename(snum),
10363 r->in.key_name,
10364 &count,
10365 &info);
10366 if (!W_ERROR_IS_OK(result)) {
10367 goto done;
10368 }
10369
10370 #if 0 /* FIXME - gd */
10371 /* housekeeping information in the reply */
10372
10373 /* Fix from Martin Zielinski <mz@seh.de> - ensure
10374 * the hand marshalled container size is a multiple
10375 * of 4 bytes for RPC alignment.
10376 */
10377
10378 if (needed % 4) {
10379 needed += 4-(needed % 4);
10380 }
10381 #endif
10382 *r->out.count = count;
10383 *r->out.info = info;
10384
10385 done:
10386 if (!W_ERROR_IS_OK(result)) {
10387 return result;
10388 }
10389
10390 *r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
10391 spoolss_EnumPrinterDataEx,
10392 *r->out.info,
10393 *r->out.count);
10394 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
10395 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
10396
10397 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
10398 }
10399
10400 /****************************************************************************
10401 ****************************************************************************/
10402
getprintprocessordirectory_level_1(TALLOC_CTX * mem_ctx,const char * servername,const char * environment,struct spoolss_PrintProcessorDirectoryInfo1 * r)10403 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
10404 const char *servername,
10405 const char *environment,
10406 struct spoolss_PrintProcessorDirectoryInfo1 *r)
10407 {
10408 WERROR werr;
10409 char *path = NULL;
10410
10411 werr = compose_spoolss_server_path(mem_ctx,
10412 servername,
10413 environment,
10414 SPOOLSS_PRTPROCS_PATH,
10415 &path);
10416 if (!W_ERROR_IS_OK(werr)) {
10417 return werr;
10418 }
10419
10420 DEBUG(4,("print processor directory: [%s]\n", path));
10421
10422 r->directory_name = path;
10423
10424 return WERR_OK;
10425 }
10426
10427 /****************************************************************
10428 _spoolss_GetPrintProcessorDirectory
10429 ****************************************************************/
10430
_spoolss_GetPrintProcessorDirectory(struct pipes_struct * p,struct spoolss_GetPrintProcessorDirectory * r)10431 WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p,
10432 struct spoolss_GetPrintProcessorDirectory *r)
10433 {
10434 WERROR result;
10435 char *prnproc_share = NULL;
10436 bool prnproc_share_exists = false;
10437 int snum;
10438
10439 /* that's an [in out] buffer */
10440
10441 if (!r->in.buffer && (r->in.offered != 0)) {
10442 result = WERR_INVALID_PARAMETER;
10443 goto err_info_free;
10444 }
10445
10446 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
10447 r->in.level));
10448
10449 *r->out.needed = 0;
10450
10451 /* r->in.level is ignored */
10452
10453 /* We always should reply with a local print processor directory so that
10454 * users are not forced to have a [prnproc$] share on the Samba spoolss
10455 * server, if users decide to do so, lets announce it though - Guenther */
10456
10457 snum = find_service(talloc_tos(), "prnproc$", &prnproc_share);
10458 if (!prnproc_share) {
10459 result = WERR_NOT_ENOUGH_MEMORY;
10460 goto err_info_free;
10461 }
10462 if (snum != -1) {
10463 prnproc_share_exists = true;
10464 }
10465
10466 result = getprintprocessordirectory_level_1(p->mem_ctx,
10467 prnproc_share_exists ? r->in.server : NULL,
10468 r->in.environment,
10469 &r->out.info->info1);
10470 if (!W_ERROR_IS_OK(result)) {
10471 goto err_info_free;
10472 }
10473
10474 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
10475 r->out.info, r->in.level);
10476 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
10477
10478 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
10479
10480 err_info_free:
10481 TALLOC_FREE(r->out.info);
10482 return result;
10483 }
10484
10485 /*******************************************************************
10486 ********************************************************************/
10487
push_monitorui_buf(TALLOC_CTX * mem_ctx,DATA_BLOB * buf,const char * dllname)10488 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
10489 const char *dllname)
10490 {
10491 enum ndr_err_code ndr_err;
10492 struct spoolss_MonitorUi ui;
10493
10494 ui.dll_name = dllname;
10495
10496 ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ui,
10497 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
10498 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
10499 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
10500 }
10501 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
10502 }
10503
10504 /*******************************************************************
10505 Streams the monitor UI DLL name in UNICODE
10506 *******************************************************************/
10507
xcvtcp_monitorui(TALLOC_CTX * mem_ctx,struct security_token * token,DATA_BLOB * in,DATA_BLOB * out,uint32_t * needed)10508 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
10509 struct security_token *token, DATA_BLOB *in,
10510 DATA_BLOB *out, uint32_t *needed)
10511 {
10512 const char *dllname = "tcpmonui.dll";
10513
10514 *needed = (strlen(dllname)+1) * 2;
10515
10516 if (out->length < *needed) {
10517 return WERR_INSUFFICIENT_BUFFER;
10518 }
10519
10520 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
10521 return WERR_NOT_ENOUGH_MEMORY;
10522 }
10523
10524 return WERR_OK;
10525 }
10526
10527 /*******************************************************************
10528 ********************************************************************/
10529
pull_port_data_1(TALLOC_CTX * mem_ctx,struct spoolss_PortData1 * port1,const DATA_BLOB * buf)10530 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
10531 struct spoolss_PortData1 *port1,
10532 const DATA_BLOB *buf)
10533 {
10534 enum ndr_err_code ndr_err;
10535 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port1,
10536 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
10537 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
10538 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
10539 }
10540 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
10541 }
10542
10543 /*******************************************************************
10544 ********************************************************************/
10545
pull_port_data_2(TALLOC_CTX * mem_ctx,struct spoolss_PortData2 * port2,const DATA_BLOB * buf)10546 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
10547 struct spoolss_PortData2 *port2,
10548 const DATA_BLOB *buf)
10549 {
10550 enum ndr_err_code ndr_err;
10551 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port2,
10552 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
10553 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
10554 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
10555 }
10556 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
10557 }
10558
10559 /*******************************************************************
10560 Create a new TCP/IP port
10561 *******************************************************************/
10562
xcvtcp_addport(TALLOC_CTX * mem_ctx,struct security_token * token,DATA_BLOB * in,DATA_BLOB * out,uint32_t * needed)10563 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
10564 struct security_token *token, DATA_BLOB *in,
10565 DATA_BLOB *out, uint32_t *needed)
10566 {
10567 struct spoolss_PortData1 port1;
10568 struct spoolss_PortData2 port2;
10569 char *device_uri = NULL;
10570 uint32_t version;
10571
10572 const char *portname;
10573 const char *hostaddress;
10574 const char *queue;
10575 uint32_t port_number;
10576 uint32_t protocol;
10577
10578 /* peek for spoolss_PortData version */
10579
10580 if (!in || (in->length < (128 + 4))) {
10581 return WERR_GEN_FAILURE;
10582 }
10583
10584 version = IVAL(in->data, 128);
10585
10586 switch (version) {
10587 case 1:
10588 ZERO_STRUCT(port1);
10589
10590 if (!pull_port_data_1(mem_ctx, &port1, in)) {
10591 return WERR_NOT_ENOUGH_MEMORY;
10592 }
10593
10594 portname = port1.portname;
10595 hostaddress = port1.hostaddress;
10596 queue = port1.queue;
10597 protocol = port1.protocol;
10598 port_number = port1.port_number;
10599
10600 break;
10601 case 2:
10602 ZERO_STRUCT(port2);
10603
10604 if (!pull_port_data_2(mem_ctx, &port2, in)) {
10605 return WERR_NOT_ENOUGH_MEMORY;
10606 }
10607
10608 portname = port2.portname;
10609 hostaddress = port2.hostaddress;
10610 queue = port2.queue;
10611 protocol = port2.protocol;
10612 port_number = port2.port_number;
10613
10614 break;
10615 default:
10616 DEBUG(1,("xcvtcp_addport: "
10617 "unknown version of port_data: %d\n", version));
10618 return WERR_UNKNOWN_PORT;
10619 }
10620
10621 /* create the device URI and call the add_port_hook() */
10622
10623 switch (protocol) {
10624 case PROTOCOL_RAWTCP_TYPE:
10625 device_uri = talloc_asprintf(mem_ctx,
10626 "socket://%s:%d/", hostaddress,
10627 port_number);
10628 break;
10629
10630 case PROTOCOL_LPR_TYPE:
10631 device_uri = talloc_asprintf(mem_ctx,
10632 "lpr://%s/%s", hostaddress, queue );
10633 break;
10634
10635 default:
10636 return WERR_UNKNOWN_PORT;
10637 }
10638
10639 if (!device_uri) {
10640 return WERR_NOT_ENOUGH_MEMORY;
10641 }
10642
10643 return add_port_hook(mem_ctx, token, portname, device_uri);
10644 }
10645
10646 /*******************************************************************
10647 *******************************************************************/
10648
10649 struct xcv_api_table xcvtcp_cmds[] = {
10650 { "MonitorUI", xcvtcp_monitorui },
10651 { "AddPort", xcvtcp_addport},
10652 { NULL, NULL }
10653 };
10654
process_xcvtcp_command(TALLOC_CTX * mem_ctx,struct security_token * token,const char * command,DATA_BLOB * inbuf,DATA_BLOB * outbuf,uint32_t * needed)10655 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
10656 struct security_token *token, const char *command,
10657 DATA_BLOB *inbuf,
10658 DATA_BLOB *outbuf,
10659 uint32_t *needed )
10660 {
10661 int i;
10662
10663 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
10664
10665 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
10666 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
10667 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
10668 }
10669
10670 return WERR_INVALID_FUNCTION;
10671 }
10672
10673 /*******************************************************************
10674 *******************************************************************/
10675 #if 0 /* don't support management using the "Local Port" monitor */
10676
10677 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
10678 struct security_token *token, DATA_BLOB *in,
10679 DATA_BLOB *out, uint32_t *needed)
10680 {
10681 const char *dllname = "localui.dll";
10682
10683 *needed = (strlen(dllname)+1) * 2;
10684
10685 if (out->length < *needed) {
10686 return WERR_INSUFFICIENT_BUFFER;
10687 }
10688
10689 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
10690 return WERR_NOT_ENOUGH_MEMORY;
10691 }
10692
10693 return WERR_OK;
10694 }
10695
10696 /*******************************************************************
10697 *******************************************************************/
10698
10699 struct xcv_api_table xcvlocal_cmds[] = {
10700 { "MonitorUI", xcvlocal_monitorui },
10701 { NULL, NULL }
10702 };
10703 #else
10704 struct xcv_api_table xcvlocal_cmds[] = {
10705 { NULL, NULL }
10706 };
10707 #endif
10708
10709
10710
10711 /*******************************************************************
10712 *******************************************************************/
10713
process_xcvlocal_command(TALLOC_CTX * mem_ctx,struct security_token * token,const char * command,DATA_BLOB * inbuf,DATA_BLOB * outbuf,uint32_t * needed)10714 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
10715 struct security_token *token, const char *command,
10716 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
10717 uint32_t *needed)
10718 {
10719 int i;
10720
10721 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
10722
10723 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
10724 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
10725 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
10726 }
10727 return WERR_INVALID_FUNCTION;
10728 }
10729
10730 /****************************************************************
10731 _spoolss_XcvData
10732 ****************************************************************/
10733
_spoolss_XcvData(struct pipes_struct * p,struct spoolss_XcvData * r)10734 WERROR _spoolss_XcvData(struct pipes_struct *p,
10735 struct spoolss_XcvData *r)
10736 {
10737 struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
10738 DATA_BLOB out_data = data_blob_null;
10739 WERROR werror;
10740
10741 if (!Printer) {
10742 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
10743 OUR_HANDLE(r->in.handle)));
10744 return WERR_INVALID_HANDLE;
10745 }
10746
10747 /* Has to be a handle to the TCP/IP port monitor */
10748
10749 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
10750 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
10751 return WERR_INVALID_HANDLE;
10752 }
10753
10754 /* requires administrative access to the server */
10755
10756 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
10757 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
10758 return WERR_ACCESS_DENIED;
10759 }
10760
10761 /* Allocate the outgoing buffer */
10762
10763 if (r->in.out_data_size) {
10764 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
10765 if (out_data.data == NULL) {
10766 return WERR_NOT_ENOUGH_MEMORY;
10767 }
10768 }
10769
10770 switch ( Printer->printer_type ) {
10771 case SPLHND_PORTMON_TCP:
10772 werror = process_xcvtcp_command(p->mem_ctx,
10773 p->session_info->security_token,
10774 r->in.function_name,
10775 &r->in.in_data, &out_data,
10776 r->out.needed);
10777 break;
10778 case SPLHND_PORTMON_LOCAL:
10779 werror = process_xcvlocal_command(p->mem_ctx,
10780 p->session_info->security_token,
10781 r->in.function_name,
10782 &r->in.in_data, &out_data,
10783 r->out.needed);
10784 break;
10785 default:
10786 werror = WERR_INVALID_PRINT_MONITOR;
10787 }
10788
10789 if (!W_ERROR_IS_OK(werror)) {
10790 return werror;
10791 }
10792
10793 *r->out.status_code = 0;
10794
10795 if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
10796 memcpy(r->out.out_data, out_data.data,
10797 MIN(r->in.out_data_size, out_data.length));
10798 }
10799
10800 return WERR_OK;
10801 }
10802
10803 /****************************************************************
10804 _spoolss_AddPrintProcessor
10805 ****************************************************************/
10806
_spoolss_AddPrintProcessor(struct pipes_struct * p,struct spoolss_AddPrintProcessor * r)10807 WERROR _spoolss_AddPrintProcessor(struct pipes_struct *p,
10808 struct spoolss_AddPrintProcessor *r)
10809 {
10810 /* for now, just indicate success and ignore the add. We'll
10811 automatically set the winprint processor for printer
10812 entries later. Used to debug the LexMark Optra S 1855 PCL
10813 driver --jerry */
10814
10815 return WERR_OK;
10816 }
10817
10818 /****************************************************************
10819 _spoolss_AddPort
10820 ****************************************************************/
10821
_spoolss_AddPort(struct pipes_struct * p,struct spoolss_AddPort * r)10822 WERROR _spoolss_AddPort(struct pipes_struct *p,
10823 struct spoolss_AddPort *r)
10824 {
10825 /* do what w2k3 does */
10826
10827 return WERR_NOT_SUPPORTED;
10828 }
10829
10830 /****************************************************************
10831 _spoolss_GetPrinterDriver
10832 ****************************************************************/
10833
_spoolss_GetPrinterDriver(struct pipes_struct * p,struct spoolss_GetPrinterDriver * r)10834 WERROR _spoolss_GetPrinterDriver(struct pipes_struct *p,
10835 struct spoolss_GetPrinterDriver *r)
10836 {
10837 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
10838 return WERR_NOT_SUPPORTED;
10839 }
10840
10841 /****************************************************************
10842 _spoolss_ReadPrinter
10843 ****************************************************************/
10844
_spoolss_ReadPrinter(struct pipes_struct * p,struct spoolss_ReadPrinter * r)10845 WERROR _spoolss_ReadPrinter(struct pipes_struct *p,
10846 struct spoolss_ReadPrinter *r)
10847 {
10848 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
10849 return WERR_NOT_SUPPORTED;
10850 }
10851
10852 /****************************************************************
10853 _spoolss_WaitForPrinterChange
10854 ****************************************************************/
10855
_spoolss_WaitForPrinterChange(struct pipes_struct * p,struct spoolss_WaitForPrinterChange * r)10856 WERROR _spoolss_WaitForPrinterChange(struct pipes_struct *p,
10857 struct spoolss_WaitForPrinterChange *r)
10858 {
10859 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
10860 return WERR_NOT_SUPPORTED;
10861 }
10862
10863 /****************************************************************
10864 _spoolss_ConfigurePort
10865 ****************************************************************/
10866
_spoolss_ConfigurePort(struct pipes_struct * p,struct spoolss_ConfigurePort * r)10867 WERROR _spoolss_ConfigurePort(struct pipes_struct *p,
10868 struct spoolss_ConfigurePort *r)
10869 {
10870 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
10871 return WERR_NOT_SUPPORTED;
10872 }
10873
10874 /****************************************************************
10875 _spoolss_DeletePort
10876 ****************************************************************/
10877
_spoolss_DeletePort(struct pipes_struct * p,struct spoolss_DeletePort * r)10878 WERROR _spoolss_DeletePort(struct pipes_struct *p,
10879 struct spoolss_DeletePort *r)
10880 {
10881 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
10882 return WERR_NOT_SUPPORTED;
10883 }
10884
10885 /****************************************************************
10886 _spoolss_CreatePrinterIC
10887 ****************************************************************/
10888
_spoolss_CreatePrinterIC(struct pipes_struct * p,struct spoolss_CreatePrinterIC * r)10889 WERROR _spoolss_CreatePrinterIC(struct pipes_struct *p,
10890 struct spoolss_CreatePrinterIC *r)
10891 {
10892 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
10893 return WERR_NOT_SUPPORTED;
10894 }
10895
10896 /****************************************************************
10897 _spoolss_PlayGDIScriptOnPrinterIC
10898 ****************************************************************/
10899
_spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct * p,struct spoolss_PlayGDIScriptOnPrinterIC * r)10900 WERROR _spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct *p,
10901 struct spoolss_PlayGDIScriptOnPrinterIC *r)
10902 {
10903 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
10904 return WERR_NOT_SUPPORTED;
10905 }
10906
10907 /****************************************************************
10908 _spoolss_DeletePrinterIC
10909 ****************************************************************/
10910
_spoolss_DeletePrinterIC(struct pipes_struct * p,struct spoolss_DeletePrinterIC * r)10911 WERROR _spoolss_DeletePrinterIC(struct pipes_struct *p,
10912 struct spoolss_DeletePrinterIC *r)
10913 {
10914 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
10915 return WERR_NOT_SUPPORTED;
10916 }
10917
10918 /****************************************************************
10919 _spoolss_AddPrinterConnection
10920 ****************************************************************/
10921
_spoolss_AddPrinterConnection(struct pipes_struct * p,struct spoolss_AddPrinterConnection * r)10922 WERROR _spoolss_AddPrinterConnection(struct pipes_struct *p,
10923 struct spoolss_AddPrinterConnection *r)
10924 {
10925 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
10926 return WERR_NOT_SUPPORTED;
10927 }
10928
10929 /****************************************************************
10930 _spoolss_DeletePrinterConnection
10931 ****************************************************************/
10932
_spoolss_DeletePrinterConnection(struct pipes_struct * p,struct spoolss_DeletePrinterConnection * r)10933 WERROR _spoolss_DeletePrinterConnection(struct pipes_struct *p,
10934 struct spoolss_DeletePrinterConnection *r)
10935 {
10936 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
10937 return WERR_NOT_SUPPORTED;
10938 }
10939
10940 /****************************************************************
10941 _spoolss_PrinterMessageBox
10942 ****************************************************************/
10943
_spoolss_PrinterMessageBox(struct pipes_struct * p,struct spoolss_PrinterMessageBox * r)10944 WERROR _spoolss_PrinterMessageBox(struct pipes_struct *p,
10945 struct spoolss_PrinterMessageBox *r)
10946 {
10947 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
10948 return WERR_NOT_SUPPORTED;
10949 }
10950
10951 /****************************************************************
10952 _spoolss_AddMonitor
10953 ****************************************************************/
10954
_spoolss_AddMonitor(struct pipes_struct * p,struct spoolss_AddMonitor * r)10955 WERROR _spoolss_AddMonitor(struct pipes_struct *p,
10956 struct spoolss_AddMonitor *r)
10957 {
10958 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
10959 return WERR_NOT_SUPPORTED;
10960 }
10961
10962 /****************************************************************
10963 _spoolss_DeleteMonitor
10964 ****************************************************************/
10965
_spoolss_DeleteMonitor(struct pipes_struct * p,struct spoolss_DeleteMonitor * r)10966 WERROR _spoolss_DeleteMonitor(struct pipes_struct *p,
10967 struct spoolss_DeleteMonitor *r)
10968 {
10969 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
10970 return WERR_NOT_SUPPORTED;
10971 }
10972
10973 /****************************************************************
10974 _spoolss_DeletePrintProcessor
10975 ****************************************************************/
10976
_spoolss_DeletePrintProcessor(struct pipes_struct * p,struct spoolss_DeletePrintProcessor * r)10977 WERROR _spoolss_DeletePrintProcessor(struct pipes_struct *p,
10978 struct spoolss_DeletePrintProcessor *r)
10979 {
10980 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
10981 return WERR_NOT_SUPPORTED;
10982 }
10983
10984 /****************************************************************
10985 _spoolss_AddPrintProvidor
10986 ****************************************************************/
10987
_spoolss_AddPrintProvidor(struct pipes_struct * p,struct spoolss_AddPrintProvidor * r)10988 WERROR _spoolss_AddPrintProvidor(struct pipes_struct *p,
10989 struct spoolss_AddPrintProvidor *r)
10990 {
10991 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
10992 return WERR_NOT_SUPPORTED;
10993 }
10994
10995 /****************************************************************
10996 _spoolss_DeletePrintProvidor
10997 ****************************************************************/
10998
_spoolss_DeletePrintProvidor(struct pipes_struct * p,struct spoolss_DeletePrintProvidor * r)10999 WERROR _spoolss_DeletePrintProvidor(struct pipes_struct *p,
11000 struct spoolss_DeletePrintProvidor *r)
11001 {
11002 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11003 return WERR_NOT_SUPPORTED;
11004 }
11005
11006 /****************************************************************
11007 _spoolss_FindFirstPrinterChangeNotification
11008 ****************************************************************/
11009
_spoolss_FindFirstPrinterChangeNotification(struct pipes_struct * p,struct spoolss_FindFirstPrinterChangeNotification * r)11010 WERROR _spoolss_FindFirstPrinterChangeNotification(struct pipes_struct *p,
11011 struct spoolss_FindFirstPrinterChangeNotification *r)
11012 {
11013 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11014 return WERR_NOT_SUPPORTED;
11015 }
11016
11017 /****************************************************************
11018 _spoolss_FindNextPrinterChangeNotification
11019 ****************************************************************/
11020
_spoolss_FindNextPrinterChangeNotification(struct pipes_struct * p,struct spoolss_FindNextPrinterChangeNotification * r)11021 WERROR _spoolss_FindNextPrinterChangeNotification(struct pipes_struct *p,
11022 struct spoolss_FindNextPrinterChangeNotification *r)
11023 {
11024 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11025 return WERR_NOT_SUPPORTED;
11026 }
11027
11028 /****************************************************************
11029 _spoolss_RouterFindFirstPrinterChangeNotificationOld
11030 ****************************************************************/
11031
_spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct * p,struct spoolss_RouterFindFirstPrinterChangeNotificationOld * r)11032 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct *p,
11033 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
11034 {
11035 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11036 return WERR_NOT_SUPPORTED;
11037 }
11038
11039 /****************************************************************
11040 _spoolss_ReplyOpenPrinter
11041 ****************************************************************/
11042
_spoolss_ReplyOpenPrinter(struct pipes_struct * p,struct spoolss_ReplyOpenPrinter * r)11043 WERROR _spoolss_ReplyOpenPrinter(struct pipes_struct *p,
11044 struct spoolss_ReplyOpenPrinter *r)
11045 {
11046 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11047 return WERR_NOT_SUPPORTED;
11048 }
11049
11050 /****************************************************************
11051 _spoolss_RouterReplyPrinter
11052 ****************************************************************/
11053
_spoolss_RouterReplyPrinter(struct pipes_struct * p,struct spoolss_RouterReplyPrinter * r)11054 WERROR _spoolss_RouterReplyPrinter(struct pipes_struct *p,
11055 struct spoolss_RouterReplyPrinter *r)
11056 {
11057 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11058 return WERR_NOT_SUPPORTED;
11059 }
11060
11061 /****************************************************************
11062 _spoolss_ReplyClosePrinter
11063 ****************************************************************/
11064
_spoolss_ReplyClosePrinter(struct pipes_struct * p,struct spoolss_ReplyClosePrinter * r)11065 WERROR _spoolss_ReplyClosePrinter(struct pipes_struct *p,
11066 struct spoolss_ReplyClosePrinter *r)
11067 {
11068 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11069 return WERR_NOT_SUPPORTED;
11070 }
11071
11072 /****************************************************************
11073 _spoolss_AddPortEx
11074 ****************************************************************/
11075
_spoolss_AddPortEx(struct pipes_struct * p,struct spoolss_AddPortEx * r)11076 WERROR _spoolss_AddPortEx(struct pipes_struct *p,
11077 struct spoolss_AddPortEx *r)
11078 {
11079 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11080 return WERR_NOT_SUPPORTED;
11081 }
11082
11083 /****************************************************************
11084 _spoolss_RouterFindFirstPrinterChangeNotification
11085 ****************************************************************/
11086
_spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct * p,struct spoolss_RouterFindFirstPrinterChangeNotification * r)11087 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct *p,
11088 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
11089 {
11090 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11091 return WERR_NOT_SUPPORTED;
11092 }
11093
11094 /****************************************************************
11095 _spoolss_SpoolerInit
11096 ****************************************************************/
11097
_spoolss_SpoolerInit(struct pipes_struct * p,struct spoolss_SpoolerInit * r)11098 WERROR _spoolss_SpoolerInit(struct pipes_struct *p,
11099 struct spoolss_SpoolerInit *r)
11100 {
11101 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11102 return WERR_NOT_SUPPORTED;
11103 }
11104
11105 /****************************************************************
11106 _spoolss_ResetPrinterEx
11107 ****************************************************************/
11108
_spoolss_ResetPrinterEx(struct pipes_struct * p,struct spoolss_ResetPrinterEx * r)11109 WERROR _spoolss_ResetPrinterEx(struct pipes_struct *p,
11110 struct spoolss_ResetPrinterEx *r)
11111 {
11112 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11113 return WERR_NOT_SUPPORTED;
11114 }
11115
11116 /****************************************************************
11117 _spoolss_RouterReplyPrinterEx
11118 ****************************************************************/
11119
_spoolss_RouterReplyPrinterEx(struct pipes_struct * p,struct spoolss_RouterReplyPrinterEx * r)11120 WERROR _spoolss_RouterReplyPrinterEx(struct pipes_struct *p,
11121 struct spoolss_RouterReplyPrinterEx *r)
11122 {
11123 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11124 return WERR_NOT_SUPPORTED;
11125 }
11126
11127 /****************************************************************
11128 _spoolss_44
11129 ****************************************************************/
11130
_spoolss_44(struct pipes_struct * p,struct spoolss_44 * r)11131 WERROR _spoolss_44(struct pipes_struct *p,
11132 struct spoolss_44 *r)
11133 {
11134 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11135 return WERR_NOT_SUPPORTED;
11136 }
11137
11138 /****************************************************************
11139 _spoolss_SetPort
11140 ****************************************************************/
11141
_spoolss_SetPort(struct pipes_struct * p,struct spoolss_SetPort * r)11142 WERROR _spoolss_SetPort(struct pipes_struct *p,
11143 struct spoolss_SetPort *r)
11144 {
11145 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11146 return WERR_NOT_SUPPORTED;
11147 }
11148
11149 /****************************************************************
11150 _spoolss_4a
11151 ****************************************************************/
11152
_spoolss_4a(struct pipes_struct * p,struct spoolss_4a * r)11153 WERROR _spoolss_4a(struct pipes_struct *p,
11154 struct spoolss_4a *r)
11155 {
11156 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11157 return WERR_NOT_SUPPORTED;
11158 }
11159
11160 /****************************************************************
11161 _spoolss_4b
11162 ****************************************************************/
11163
_spoolss_4b(struct pipes_struct * p,struct spoolss_4b * r)11164 WERROR _spoolss_4b(struct pipes_struct *p,
11165 struct spoolss_4b *r)
11166 {
11167 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11168 return WERR_NOT_SUPPORTED;
11169 }
11170
11171 /****************************************************************
11172 _spoolss_4c
11173 ****************************************************************/
11174
_spoolss_4c(struct pipes_struct * p,struct spoolss_4c * r)11175 WERROR _spoolss_4c(struct pipes_struct *p,
11176 struct spoolss_4c *r)
11177 {
11178 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11179 return WERR_NOT_SUPPORTED;
11180 }
11181
11182 /****************************************************************
11183 _spoolss_53
11184 ****************************************************************/
11185
_spoolss_53(struct pipes_struct * p,struct spoolss_53 * r)11186 WERROR _spoolss_53(struct pipes_struct *p,
11187 struct spoolss_53 *r)
11188 {
11189 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11190 return WERR_NOT_SUPPORTED;
11191 }
11192
11193 /****************************************************************
11194 _spoolss_AddPerMachineConnection
11195 ****************************************************************/
11196
_spoolss_AddPerMachineConnection(struct pipes_struct * p,struct spoolss_AddPerMachineConnection * r)11197 WERROR _spoolss_AddPerMachineConnection(struct pipes_struct *p,
11198 struct spoolss_AddPerMachineConnection *r)
11199 {
11200 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11201 return WERR_NOT_SUPPORTED;
11202 }
11203
11204 /****************************************************************
11205 _spoolss_DeletePerMachineConnection
11206 ****************************************************************/
11207
_spoolss_DeletePerMachineConnection(struct pipes_struct * p,struct spoolss_DeletePerMachineConnection * r)11208 WERROR _spoolss_DeletePerMachineConnection(struct pipes_struct *p,
11209 struct spoolss_DeletePerMachineConnection *r)
11210 {
11211 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11212 return WERR_NOT_SUPPORTED;
11213 }
11214
11215 /****************************************************************
11216 _spoolss_EnumPerMachineConnections
11217 ****************************************************************/
11218
_spoolss_EnumPerMachineConnections(struct pipes_struct * p,struct spoolss_EnumPerMachineConnections * r)11219 WERROR _spoolss_EnumPerMachineConnections(struct pipes_struct *p,
11220 struct spoolss_EnumPerMachineConnections *r)
11221 {
11222 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11223 return WERR_NOT_SUPPORTED;
11224 }
11225
11226 /****************************************************************
11227 _spoolss_5a
11228 ****************************************************************/
11229
_spoolss_5a(struct pipes_struct * p,struct spoolss_5a * r)11230 WERROR _spoolss_5a(struct pipes_struct *p,
11231 struct spoolss_5a *r)
11232 {
11233 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11234 return WERR_NOT_SUPPORTED;
11235 }
11236
11237 /****************************************************************
11238 _spoolss_5b
11239 ****************************************************************/
11240
_spoolss_5b(struct pipes_struct * p,struct spoolss_5b * r)11241 WERROR _spoolss_5b(struct pipes_struct *p,
11242 struct spoolss_5b *r)
11243 {
11244 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11245 return WERR_NOT_SUPPORTED;
11246 }
11247
11248 /****************************************************************
11249 _spoolss_5c
11250 ****************************************************************/
11251
_spoolss_5c(struct pipes_struct * p,struct spoolss_5c * r)11252 WERROR _spoolss_5c(struct pipes_struct *p,
11253 struct spoolss_5c *r)
11254 {
11255 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11256 return WERR_NOT_SUPPORTED;
11257 }
11258
11259 /****************************************************************
11260 _spoolss_5d
11261 ****************************************************************/
11262
_spoolss_5d(struct pipes_struct * p,struct spoolss_5d * r)11263 WERROR _spoolss_5d(struct pipes_struct *p,
11264 struct spoolss_5d *r)
11265 {
11266 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11267 return WERR_NOT_SUPPORTED;
11268 }
11269
11270 /****************************************************************
11271 _spoolss_5e
11272 ****************************************************************/
11273
_spoolss_5e(struct pipes_struct * p,struct spoolss_5e * r)11274 WERROR _spoolss_5e(struct pipes_struct *p,
11275 struct spoolss_5e *r)
11276 {
11277 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11278 return WERR_NOT_SUPPORTED;
11279 }
11280
11281 /****************************************************************
11282 _spoolss_5f
11283 ****************************************************************/
11284
_spoolss_5f(struct pipes_struct * p,struct spoolss_5f * r)11285 WERROR _spoolss_5f(struct pipes_struct *p,
11286 struct spoolss_5f *r)
11287 {
11288 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11289 return WERR_NOT_SUPPORTED;
11290 }
11291
11292 /****************************************************************
11293 _spoolss_60
11294 ****************************************************************/
11295
_spoolss_60(struct pipes_struct * p,struct spoolss_60 * r)11296 WERROR _spoolss_60(struct pipes_struct *p,
11297 struct spoolss_60 *r)
11298 {
11299 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11300 return WERR_NOT_SUPPORTED;
11301 }
11302
11303 /****************************************************************
11304 _spoolss_SendRecvBidiData
11305 ****************************************************************/
11306
_spoolss_SendRecvBidiData(struct pipes_struct * p,struct spoolss_SendRecvBidiData * r)11307 WERROR _spoolss_SendRecvBidiData(struct pipes_struct *p,
11308 struct spoolss_SendRecvBidiData *r)
11309 {
11310 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11311 return WERR_NOT_SUPPORTED;
11312 }
11313
11314 /****************************************************************
11315 _spoolss_62
11316 ****************************************************************/
11317
_spoolss_62(struct pipes_struct * p,struct spoolss_62 * r)11318 WERROR _spoolss_62(struct pipes_struct *p,
11319 struct spoolss_62 *r)
11320 {
11321 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11322 return WERR_NOT_SUPPORTED;
11323 }
11324
11325 /****************************************************************
11326 _spoolss_63
11327 ****************************************************************/
11328
_spoolss_63(struct pipes_struct * p,struct spoolss_63 * r)11329 WERROR _spoolss_63(struct pipes_struct *p,
11330 struct spoolss_63 *r)
11331 {
11332 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11333 return WERR_NOT_SUPPORTED;
11334 }
11335
11336 /****************************************************************
11337 _spoolss_64
11338 ****************************************************************/
11339
_spoolss_64(struct pipes_struct * p,struct spoolss_64 * r)11340 WERROR _spoolss_64(struct pipes_struct *p,
11341 struct spoolss_64 *r)
11342 {
11343 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11344 return WERR_NOT_SUPPORTED;
11345 }
11346
11347 /****************************************************************
11348 _spoolss_65
11349 ****************************************************************/
11350
_spoolss_65(struct pipes_struct * p,struct spoolss_65 * r)11351 WERROR _spoolss_65(struct pipes_struct *p,
11352 struct spoolss_65 *r)
11353 {
11354 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11355 return WERR_NOT_SUPPORTED;
11356 }
11357
11358 /****************************************************************
11359 _spoolss_GetCorePrinterDrivers
11360 ****************************************************************/
11361
_spoolss_GetCorePrinterDrivers(struct pipes_struct * p,struct spoolss_GetCorePrinterDrivers * r)11362 HRESULT _spoolss_GetCorePrinterDrivers(struct pipes_struct *p,
11363 struct spoolss_GetCorePrinterDrivers *r)
11364 {
11365 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11366 return HRES_ERROR_NOT_SUPPORTED;
11367 }
11368
11369 /****************************************************************
11370 _spoolss_67
11371 ****************************************************************/
11372
_spoolss_67(struct pipes_struct * p,struct spoolss_67 * r)11373 WERROR _spoolss_67(struct pipes_struct *p,
11374 struct spoolss_67 *r)
11375 {
11376 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11377 return WERR_NOT_SUPPORTED;
11378 }
11379
11380 /****************************************************************
11381 _spoolss_GetPrinterDriverPackagePath
11382 ****************************************************************/
11383
_spoolss_GetPrinterDriverPackagePath(struct pipes_struct * p,struct spoolss_GetPrinterDriverPackagePath * r)11384 HRESULT _spoolss_GetPrinterDriverPackagePath(struct pipes_struct *p,
11385 struct spoolss_GetPrinterDriverPackagePath *r)
11386 {
11387 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11388 return HRES_ERROR_NOT_SUPPORTED;
11389 }
11390
11391 /****************************************************************
11392 _spoolss_69
11393 ****************************************************************/
11394
_spoolss_69(struct pipes_struct * p,struct spoolss_69 * r)11395 WERROR _spoolss_69(struct pipes_struct *p,
11396 struct spoolss_69 *r)
11397 {
11398 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11399 return WERR_NOT_SUPPORTED;
11400 }
11401
11402 /****************************************************************
11403 _spoolss_6a
11404 ****************************************************************/
11405
_spoolss_6a(struct pipes_struct * p,struct spoolss_6a * r)11406 WERROR _spoolss_6a(struct pipes_struct *p,
11407 struct spoolss_6a *r)
11408 {
11409 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11410 return WERR_NOT_SUPPORTED;
11411 }
11412
11413 /****************************************************************
11414 _spoolss_6b
11415 ****************************************************************/
11416
_spoolss_6b(struct pipes_struct * p,struct spoolss_6b * r)11417 WERROR _spoolss_6b(struct pipes_struct *p,
11418 struct spoolss_6b *r)
11419 {
11420 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11421 return WERR_NOT_SUPPORTED;
11422 }
11423
11424 /****************************************************************
11425 _spoolss_6c
11426 ****************************************************************/
11427
_spoolss_6c(struct pipes_struct * p,struct spoolss_6c * r)11428 WERROR _spoolss_6c(struct pipes_struct *p,
11429 struct spoolss_6c *r)
11430 {
11431 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11432 return WERR_NOT_SUPPORTED;
11433 }
11434
11435 /****************************************************************
11436 _spoolss_6d
11437 ****************************************************************/
11438
_spoolss_6d(struct pipes_struct * p,struct spoolss_6d * r)11439 WERROR _spoolss_6d(struct pipes_struct *p,
11440 struct spoolss_6d *r)
11441 {
11442 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11443 return WERR_NOT_SUPPORTED;
11444 }
11445
11446 /****************************************************************
11447 _spoolss_GetJobNamedPropertyValue
11448 ****************************************************************/
11449
_spoolss_GetJobNamedPropertyValue(struct pipes_struct * p,struct spoolss_GetJobNamedPropertyValue * r)11450 WERROR _spoolss_GetJobNamedPropertyValue(struct pipes_struct *p,
11451 struct spoolss_GetJobNamedPropertyValue *r)
11452 {
11453 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11454 return WERR_NOT_SUPPORTED;
11455 }
11456
11457 /****************************************************************
11458 _spoolss_SetJobNamedProperty
11459 ****************************************************************/
11460
_spoolss_SetJobNamedProperty(struct pipes_struct * p,struct spoolss_SetJobNamedProperty * r)11461 WERROR _spoolss_SetJobNamedProperty(struct pipes_struct *p,
11462 struct spoolss_SetJobNamedProperty *r)
11463 {
11464 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11465 return WERR_NOT_SUPPORTED;
11466 }
11467
11468 /****************************************************************
11469 _spoolss_DeleteJobNamedProperty
11470 ****************************************************************/
11471
_spoolss_DeleteJobNamedProperty(struct pipes_struct * p,struct spoolss_DeleteJobNamedProperty * r)11472 WERROR _spoolss_DeleteJobNamedProperty(struct pipes_struct *p,
11473 struct spoolss_DeleteJobNamedProperty *r)
11474 {
11475 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11476 return WERR_NOT_SUPPORTED;
11477 }
11478
11479 /****************************************************************
11480 _spoolss_EnumJobNamedProperties
11481 ****************************************************************/
11482
_spoolss_EnumJobNamedProperties(struct pipes_struct * p,struct spoolss_EnumJobNamedProperties * r)11483 WERROR _spoolss_EnumJobNamedProperties(struct pipes_struct *p,
11484 struct spoolss_EnumJobNamedProperties *r)
11485 {
11486 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11487 return WERR_NOT_SUPPORTED;
11488 }
11489
11490 /****************************************************************
11491 _spoolss_72
11492 ****************************************************************/
11493
_spoolss_72(struct pipes_struct * p,struct spoolss_72 * r)11494 WERROR _spoolss_72(struct pipes_struct *p,
11495 struct spoolss_72 *r)
11496 {
11497 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11498 return WERR_NOT_SUPPORTED;
11499 }
11500
11501 /****************************************************************
11502 _spoolss_73
11503 ****************************************************************/
11504
_spoolss_73(struct pipes_struct * p,struct spoolss_73 * r)11505 WERROR _spoolss_73(struct pipes_struct *p,
11506 struct spoolss_73 *r)
11507 {
11508 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11509 return WERR_NOT_SUPPORTED;
11510 }
11511
11512 /****************************************************************
11513 _spoolss_RpcLogJobInfoForBranchOffice
11514 ****************************************************************/
11515
_spoolss_LogJobInfoForBranchOffice(struct pipes_struct * p,struct spoolss_LogJobInfoForBranchOffice * r)11516 WERROR _spoolss_LogJobInfoForBranchOffice(struct pipes_struct *p,
11517 struct spoolss_LogJobInfoForBranchOffice *r)
11518 {
11519 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
11520 return WERR_NOT_SUPPORTED;
11521 }
11522