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(&notifies[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 						&notifies[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 						&notifies[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 				     &notifies, &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( &notify, &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, &notify );
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