1 /*
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    printing backend routines
5    Copyright (C) Andrew Tridgell 1992-2000
6    Copyright (C) Jeremy Allison 2002
7 
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21 
22 #include "includes.h"
23 #include "system/syslog.h"
24 #include "system/filesys.h"
25 #include "printing.h"
26 #include "../librpc/gen_ndr/ndr_spoolss.h"
27 #include "nt_printing.h"
28 #include "../librpc/gen_ndr/netlogon.h"
29 #include "printing/notify.h"
30 #include "printing/pcap.h"
31 #include "printing/printer_list.h"
32 #include "printing/queue_process.h"
33 #include "serverid.h"
34 #include "smbd/smbd.h"
35 #include "auth.h"
36 #include "messages.h"
37 #include "util_tdb.h"
38 #include "lib/param/loadparm.h"
39 #include "lib/util/sys_rw_data.h"
40 
41 extern userdom_struct current_user_info;
42 
43 /* Current printer interface */
44 static bool remove_from_jobs_added(const char* sharename, uint32_t jobid);
45 
46 /*
47    the printing backend revolves around a tdb database that stores the
48    SMB view of the print queue
49 
50    The key for this database is a jobid - a internally generated number that
51    uniquely identifies a print job
52 
53    reading the print queue involves two steps:
54      - possibly running lpq and updating the internal database from that
55      - reading entries from the database
56 
57    jobids are assigned when a job starts spooling.
58 */
59 
60 static TDB_CONTEXT *rap_tdb;
61 static uint16_t next_rap_jobid;
62 struct rap_jobid_key {
63 	fstring sharename;
64 	uint32_t  jobid;
65 };
66 
67 /***************************************************************************
68  Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
69  bit RPC jobids.... JRA.
70 ***************************************************************************/
71 
pjobid_to_rap(const char * sharename,uint32_t jobid)72 uint16_t pjobid_to_rap(const char* sharename, uint32_t jobid)
73 {
74 	uint16_t rap_jobid;
75 	TDB_DATA data, key;
76 	struct rap_jobid_key jinfo;
77 	uint8_t buf[2];
78 
79 	DEBUG(10,("pjobid_to_rap: called.\n"));
80 
81 	if (!rap_tdb) {
82 		/* Create the in-memory tdb. */
83 		rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
84 		if (!rap_tdb)
85 			return 0;
86 	}
87 
88 	ZERO_STRUCT( jinfo );
89 	fstrcpy( jinfo.sharename, sharename );
90 	jinfo.jobid = jobid;
91 	key.dptr = (uint8_t *)&jinfo;
92 	key.dsize = sizeof(jinfo);
93 
94 	data = tdb_fetch(rap_tdb, key);
95 	if (data.dptr && data.dsize == sizeof(uint16_t)) {
96 		rap_jobid = SVAL(data.dptr, 0);
97 		SAFE_FREE(data.dptr);
98 		DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
99 			(unsigned int)jobid, (unsigned int)rap_jobid));
100 		return rap_jobid;
101 	}
102 	SAFE_FREE(data.dptr);
103 	/* Not found - create and store mapping. */
104 	rap_jobid = ++next_rap_jobid;
105 	if (rap_jobid == 0)
106 		rap_jobid = ++next_rap_jobid;
107 	SSVAL(buf,0,rap_jobid);
108 	data.dptr = buf;
109 	data.dsize = sizeof(rap_jobid);
110 	tdb_store(rap_tdb, key, data, TDB_REPLACE);
111 	tdb_store(rap_tdb, data, key, TDB_REPLACE);
112 
113 	DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
114 		(unsigned int)jobid, (unsigned int)rap_jobid));
115 	return rap_jobid;
116 }
117 
rap_to_pjobid(uint16_t rap_jobid,fstring sharename,uint32_t * pjobid)118 bool rap_to_pjobid(uint16_t rap_jobid, fstring sharename, uint32_t *pjobid)
119 {
120 	TDB_DATA data, key;
121 	uint8_t buf[2];
122 
123 	DEBUG(10,("rap_to_pjobid called.\n"));
124 
125 	if (!rap_tdb)
126 		return False;
127 
128 	SSVAL(buf,0,rap_jobid);
129 	key.dptr = buf;
130 	key.dsize = sizeof(rap_jobid);
131 	data = tdb_fetch(rap_tdb, key);
132 	if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) )
133 	{
134 		struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
135 		if (sharename != NULL) {
136 			fstrcpy( sharename, jinfo->sharename );
137 		}
138 		*pjobid = jinfo->jobid;
139 		DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
140 			(unsigned int)*pjobid, (unsigned int)rap_jobid));
141 		SAFE_FREE(data.dptr);
142 		return True;
143 	}
144 
145 	DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
146 		(unsigned int)rap_jobid));
147 	SAFE_FREE(data.dptr);
148 	return False;
149 }
150 
rap_jobid_delete(const char * sharename,uint32_t jobid)151 void rap_jobid_delete(const char* sharename, uint32_t jobid)
152 {
153 	TDB_DATA key, data;
154 	uint16_t rap_jobid;
155 	struct rap_jobid_key jinfo;
156 	uint8_t buf[2];
157 
158 	DEBUG(10,("rap_jobid_delete: called.\n"));
159 
160 	if (!rap_tdb)
161 		return;
162 
163 	ZERO_STRUCT( jinfo );
164 	fstrcpy( jinfo.sharename, sharename );
165 	jinfo.jobid = jobid;
166 	key.dptr = (uint8_t *)&jinfo;
167 	key.dsize = sizeof(jinfo);
168 
169 	data = tdb_fetch(rap_tdb, key);
170 	if (!data.dptr || (data.dsize != sizeof(uint16_t))) {
171 		DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
172 			(unsigned int)jobid ));
173 		SAFE_FREE(data.dptr);
174 		return;
175 	}
176 
177 	DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
178 		(unsigned int)jobid ));
179 
180 	rap_jobid = SVAL(data.dptr, 0);
181 	SAFE_FREE(data.dptr);
182 	SSVAL(buf,0,rap_jobid);
183 	data.dptr = buf;
184 	data.dsize = sizeof(rap_jobid);
185 	tdb_delete(rap_tdb, key);
186 	tdb_delete(rap_tdb, data);
187 }
188 
189 static int get_queue_status(const char* sharename, print_status_struct *);
190 
191 /****************************************************************************
192  Initialise the printing backend. Called once at startup before the fork().
193 ****************************************************************************/
194 
print_backend_init(struct messaging_context * msg_ctx)195 bool print_backend_init(struct messaging_context *msg_ctx)
196 {
197 	const char *sversion = "INFO/version";
198 	int services = lp_numservices();
199 	int snum;
200 	bool ok;
201 	char *print_cache_path;
202 
203 	if (!printer_list_parent_init()) {
204 		return false;
205 	}
206 
207 	print_cache_path = cache_path(talloc_tos(), "printing");
208 	if (print_cache_path == NULL) {
209 		return false;
210 	}
211 	ok = directory_create_or_exist(print_cache_path, 0755);
212 	TALLOC_FREE(print_cache_path);
213 	if (!ok) {
214 		return false;
215 	}
216 
217 	print_cache_path = cache_path(talloc_tos(), "printing.tdb");
218 	if (print_cache_path == NULL) {
219 		return false;
220 	}
221 	unlink(print_cache_path);
222 	TALLOC_FREE(print_cache_path);
223 
224 	/* handle a Samba upgrade */
225 
226 	for (snum = 0; snum < services; snum++) {
227 		struct tdb_print_db *pdb;
228 		if (!lp_printable(snum))
229 			continue;
230 
231 		pdb = get_print_db_byname(lp_const_servicename(snum));
232 		if (!pdb)
233 			continue;
234 		if (tdb_lock_bystring(pdb->tdb, sversion) != 0) {
235 			DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
236 			release_print_db(pdb);
237 			return False;
238 		}
239 		if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
240 			tdb_wipe_all(pdb->tdb);
241 			tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
242 		}
243 		tdb_unlock_bystring(pdb->tdb, sversion);
244 		release_print_db(pdb);
245 	}
246 
247 	close_all_print_db(); /* Don't leave any open. */
248 
249 	/* do NT print initialization... */
250 	return nt_printing_init(msg_ctx);
251 }
252 
253 /****************************************************************************
254  Shut down printing backend. Called once at shutdown to close the tdb.
255 ****************************************************************************/
256 
printing_end(void)257 void printing_end(void)
258 {
259 	close_all_print_db(); /* Don't leave any open. */
260 }
261 
262 /****************************************************************************
263  Retrieve the set of printing functions for a given service.  This allows
264  us to set the printer function table based on the value of the 'printing'
265  service parameter.
266 
267  Use the generic interface as the default and only use cups interface only
268  when asked for (and only when supported)
269 ****************************************************************************/
270 
get_printer_fns_from_type(enum printing_types type)271 static struct printif *get_printer_fns_from_type( enum printing_types type )
272 {
273 	struct printif *printer_fns = &generic_printif;
274 
275 #ifdef HAVE_CUPS
276 	if ( type == PRINT_CUPS ) {
277 		printer_fns = &cups_printif;
278 	}
279 #endif /* HAVE_CUPS */
280 
281 #ifdef HAVE_IPRINT
282 	if ( type == PRINT_IPRINT ) {
283 		printer_fns = &iprint_printif;
284 	}
285 #endif /* HAVE_IPRINT */
286 
287 	printer_fns->type = type;
288 
289 	return printer_fns;
290 }
291 
get_printer_fns(int snum)292 static struct printif *get_printer_fns( int snum )
293 {
294 	return get_printer_fns_from_type( (enum printing_types)lp_printing(snum) );
295 }
296 
297 
298 /****************************************************************************
299  Useful function to generate a tdb key.
300 ****************************************************************************/
301 
print_key(uint32_t jobid,uint32_t * tmp)302 static TDB_DATA print_key(uint32_t jobid, uint32_t *tmp)
303 {
304 	TDB_DATA ret;
305 
306 	SIVAL(tmp, 0, jobid);
307 	ret.dptr = (uint8_t *)tmp;
308 	ret.dsize = sizeof(*tmp);
309 	return ret;
310 }
311 
312 /****************************************************************************
313  Pack the devicemode to store it in a tdb.
314 ****************************************************************************/
pack_devicemode(struct spoolss_DeviceMode * devmode,uint8_t * buf,int buflen)315 static int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8_t *buf, int buflen)
316 {
317 	enum ndr_err_code ndr_err;
318 	DATA_BLOB blob;
319 	int len = 0;
320 
321 	if (devmode) {
322 		ndr_err = ndr_push_struct_blob(&blob, talloc_tos(),
323 					       devmode,
324 					       (ndr_push_flags_fn_t)
325 					       ndr_push_spoolss_DeviceMode);
326 		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
327 			DEBUG(10, ("pack_devicemode: "
328 				   "error encoding spoolss_DeviceMode\n"));
329 			goto done;
330 		}
331 	} else {
332 		ZERO_STRUCT(blob);
333 	}
334 
335 	len = tdb_pack(buf, buflen, "B", blob.length, blob.data);
336 
337 	if (devmode) {
338 		DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname));
339 	}
340 
341 done:
342 	return len;
343 }
344 
345 /****************************************************************************
346  Unpack the devicemode to store it in a tdb.
347 ****************************************************************************/
unpack_devicemode(TALLOC_CTX * mem_ctx,const uint8_t * buf,int buflen,struct spoolss_DeviceMode ** devmode)348 static int unpack_devicemode(TALLOC_CTX *mem_ctx,
349 		      const uint8_t *buf, int buflen,
350 		      struct spoolss_DeviceMode **devmode)
351 {
352 	struct spoolss_DeviceMode *dm;
353 	enum ndr_err_code ndr_err;
354 	char *data = NULL;
355 	uint32_t data_len = 0;
356 	DATA_BLOB blob;
357 	int len = 0;
358 
359 	*devmode = NULL;
360 
361 	len = tdb_unpack(buf, buflen, "B", &data_len, &data);
362 	if (!data) {
363 		return len;
364 	}
365 
366 	dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
367 	if (!dm) {
368 		goto done;
369 	}
370 
371 	blob = data_blob_const(data, data_len);
372 
373 	ndr_err = ndr_pull_struct_blob(&blob, dm, dm,
374 			(ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);
375 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
376 		DEBUG(10, ("unpack_devicemode: "
377 			   "error parsing spoolss_DeviceMode\n"));
378 		goto done;
379 	}
380 
381 	DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
382 		  dm->devicename, dm->formname));
383 	if (dm->driverextra_data.data) {
384 		DEBUG(8, ("with a private section of %d bytes\n",
385 			  dm->__driverextra_length));
386 	}
387 
388 	*devmode = dm;
389 
390 done:
391 	SAFE_FREE(data);
392 	return len;
393 }
394 
395 /***********************************************************************
396  unpack a pjob from a tdb buffer
397 ***********************************************************************/
398 
unpack_pjob(TALLOC_CTX * mem_ctx,uint8_t * buf,int buflen,struct printjob * pjob)399 static int unpack_pjob(TALLOC_CTX *mem_ctx, uint8_t *buf, int buflen,
400 		       struct printjob *pjob)
401 {
402 	int	len = 0;
403 	int	used;
404 	uint32_t pjpid, pjjobid, pjsysjob, pjfd, pjstarttime, pjstatus;
405 	uint32_t pjsize, pjpage_count, pjspooled, pjsmbjob;
406 
407 	if (!buf || !pjob) {
408 		return -1;
409 	}
410 
411 	len += tdb_unpack(buf+len, buflen-len, "ddddddddddfffff",
412 				&pjpid,
413 				&pjjobid,
414 				&pjsysjob,
415 				&pjfd,
416 				&pjstarttime,
417 				&pjstatus,
418 				&pjsize,
419 				&pjpage_count,
420 				&pjspooled,
421 				&pjsmbjob,
422 				pjob->filename,
423 				pjob->jobname,
424 				pjob->user,
425 				pjob->clientmachine,
426 				pjob->queuename);
427 
428 	if (len == -1) {
429 		return -1;
430 	}
431 
432         used = unpack_devicemode(mem_ctx, buf+len, buflen-len, &pjob->devmode);
433         if (used == -1) {
434 		return -1;
435         }
436 
437 	len += used;
438 
439 	pjob->pid = pjpid;
440 	pjob->jobid = pjjobid;
441 	pjob->sysjob = pjsysjob;
442 	pjob->fd = pjfd;
443 	pjob->starttime = pjstarttime;
444 	pjob->status = pjstatus;
445 	pjob->size = pjsize;
446 	pjob->page_count = pjpage_count;
447 	pjob->spooled = pjspooled;
448 	pjob->smbjob = pjsmbjob;
449 
450 	return len;
451 
452 }
453 
454 /****************************************************************************
455  Useful function to find a print job in the database.
456 ****************************************************************************/
457 
print_job_find(TALLOC_CTX * mem_ctx,const char * sharename,uint32_t jobid)458 static struct printjob *print_job_find(TALLOC_CTX *mem_ctx,
459 				       const char *sharename,
460 				       uint32_t jobid)
461 {
462 	struct printjob		*pjob;
463 	uint32_t tmp;
464 	TDB_DATA 		ret;
465 	struct tdb_print_db 	*pdb = get_print_db_byname(sharename);
466 
467 	DEBUG(10,("print_job_find: looking up job %u for share %s\n",
468 			(unsigned int)jobid, sharename ));
469 
470 	if (!pdb) {
471 		return NULL;
472 	}
473 
474 	ret = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
475 	release_print_db(pdb);
476 
477 	if (!ret.dptr) {
478 		DEBUG(10, ("print_job_find: failed to find jobid %u.\n",
479 			   jobid));
480 		return NULL;
481 	}
482 
483 	pjob = talloc_zero(mem_ctx, struct printjob);
484 	if (pjob == NULL) {
485 		goto err_out;
486 	}
487 
488 	if (unpack_pjob(mem_ctx, ret.dptr, ret.dsize, pjob) == -1) {
489 		DEBUG(10, ("failed to unpack jobid %u.\n", jobid));
490 		talloc_free(pjob);
491 		pjob = NULL;
492 		goto err_out;
493 	}
494 
495 	DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
496 		  pjob->sysjob, jobid));
497 	SMB_ASSERT(pjob->jobid == jobid);
498 
499 err_out:
500 	SAFE_FREE(ret.dptr);
501 	return pjob;
502 }
503 
504 struct job_traverse_state {
505 	int sysjob;
506 	uint32_t jobid;
507 };
508 
509 /* find spoolss jobid based on sysjob */
sysjob_to_jobid_traverse_fn(TDB_CONTEXT * the_tdb,TDB_DATA key,TDB_DATA data,void * private_data)510 static int sysjob_to_jobid_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
511 				       TDB_DATA data, void *private_data)
512 {
513 	struct printjob *pjob;
514 	struct job_traverse_state *state =
515 		(struct job_traverse_state *)private_data;
516 
517 	if (!data.dptr || data.dsize == 0)
518 		return 0;
519 
520 	pjob = (struct printjob *)data.dptr;
521 	if (key.dsize != sizeof(uint32_t))
522 		return 0;
523 
524 	if (state->sysjob == pjob->sysjob) {
525 		state->jobid = pjob->jobid;
526 		return 1;
527 	}
528 
529 	return 0;
530 }
531 
sysjob_to_jobid_pdb(struct tdb_print_db * pdb,int sysjob)532 uint32_t sysjob_to_jobid_pdb(struct tdb_print_db *pdb, int sysjob)
533 {
534 	struct job_traverse_state state;
535 
536 	state.sysjob = sysjob;
537 	state.jobid = (uint32_t)-1;
538 
539 	tdb_traverse(pdb->tdb, sysjob_to_jobid_traverse_fn, &state);
540 
541 	return state.jobid;
542 }
543 
544 /****************************************************************************
545  This is a *horribly expensive call as we have to iterate through all the
546  current printer tdb's. Don't do this often ! JRA.
547 ****************************************************************************/
548 
sysjob_to_jobid(int unix_jobid)549 uint32_t sysjob_to_jobid(int unix_jobid)
550 {
551 	int services = lp_numservices();
552 	int snum;
553 	struct job_traverse_state state;
554 
555 	state.sysjob = unix_jobid;
556 	state.jobid = (uint32_t)-1;
557 
558 	for (snum = 0; snum < services; snum++) {
559 		struct tdb_print_db *pdb;
560 		if (!lp_printable(snum))
561 			continue;
562 		pdb = get_print_db_byname(lp_const_servicename(snum));
563 		if (!pdb) {
564 			continue;
565 		}
566 		tdb_traverse(pdb->tdb, sysjob_to_jobid_traverse_fn, &state);
567 		release_print_db(pdb);
568 		if (state.jobid != (uint32_t)-1)
569 			return state.jobid;
570 	}
571 	return (uint32_t)-1;
572 }
573 
574 /* find sysjob based on spoolss jobid */
jobid_to_sysjob_traverse_fn(TDB_CONTEXT * the_tdb,TDB_DATA key,TDB_DATA data,void * private_data)575 static int jobid_to_sysjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
576 				       TDB_DATA data, void *private_data)
577 {
578 	struct printjob *pjob;
579 	struct job_traverse_state *state =
580 		(struct job_traverse_state *)private_data;
581 
582 	if (!data.dptr || data.dsize == 0)
583 		return 0;
584 
585 	pjob = (struct printjob *)data.dptr;
586 	if (key.dsize != sizeof(uint32_t))
587 		return 0;
588 
589 	if (state->jobid == pjob->jobid) {
590 		state->sysjob = pjob->sysjob;
591 		return 1;
592 	}
593 
594 	return 0;
595 }
596 
jobid_to_sysjob_pdb(struct tdb_print_db * pdb,uint32_t jobid)597 int jobid_to_sysjob_pdb(struct tdb_print_db *pdb, uint32_t jobid)
598 {
599 	struct job_traverse_state state;
600 
601 	state.sysjob = -1;
602 	state.jobid = jobid;
603 
604 	tdb_traverse(pdb->tdb, jobid_to_sysjob_traverse_fn, &state);
605 
606 	return state.sysjob;
607 }
608 
609 /****************************************************************************
610  Send notifications based on what has changed after a pjob_store.
611 ****************************************************************************/
612 
613 static const struct {
614 	uint32_t lpq_status;
615 	uint32_t spoolss_status;
616 } lpq_to_spoolss_status_map[] = {
617 	{ LPQ_QUEUED, JOB_STATUS_QUEUED },
618 	{ LPQ_PAUSED, JOB_STATUS_PAUSED },
619 	{ LPQ_SPOOLING, JOB_STATUS_SPOOLING },
620 	{ LPQ_PRINTING, JOB_STATUS_PRINTING },
621 	{ LPQ_DELETING, JOB_STATUS_DELETING },
622 	{ LPQ_OFFLINE, JOB_STATUS_OFFLINE },
623 	{ LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
624 	{ LPQ_PRINTED, JOB_STATUS_PRINTED },
625 	{ LPQ_DELETED, JOB_STATUS_DELETED },
626 	{ LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ },
627 	{ LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
628 	{ (uint32_t)-1, 0 }
629 };
630 
631 /* Convert a lpq status value stored in printing.tdb into the
632    appropriate win32 API constant. */
633 
map_to_spoolss_status(uint32_t lpq_status)634 static uint32_t map_to_spoolss_status(uint32_t lpq_status)
635 {
636 	int i = 0;
637 
638 	while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
639 		if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
640 			return lpq_to_spoolss_status_map[i].spoolss_status;
641 		i++;
642 	}
643 
644 	return 0;
645 }
646 
647 /***************************************************************************
648  Append a jobid to the 'jobs changed' list.
649 ***************************************************************************/
650 
add_to_jobs_changed(struct tdb_print_db * pdb,uint32_t jobid)651 static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32_t jobid)
652 {
653 	TDB_DATA data;
654 	uint32_t store_jobid;
655 
656 	SIVAL(&store_jobid, 0, jobid);
657 	data.dptr = (uint8_t *) &store_jobid;
658 	data.dsize = 4;
659 
660 	DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid ));
661 
662 	return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
663 			   data) == 0);
664 }
665 
666 /***************************************************************************
667  Remove a jobid from the 'jobs changed' list.
668 ***************************************************************************/
669 
remove_from_jobs_changed(const char * sharename,uint32_t jobid)670 static bool remove_from_jobs_changed(const char* sharename, uint32_t jobid)
671 {
672 	struct tdb_print_db *pdb = get_print_db_byname(sharename);
673 	TDB_DATA data, key;
674 	size_t job_count, i;
675 	bool ret = False;
676 	bool gotlock = False;
677 
678 	if (!pdb) {
679 		return False;
680 	}
681 
682 	ZERO_STRUCT(data);
683 
684 	key = string_tdb_data("INFO/jobs_changed");
685 
686 	if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) != 0)
687 		goto out;
688 
689 	gotlock = True;
690 
691 	data = tdb_fetch(pdb->tdb, key);
692 
693 	if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
694 		goto out;
695 
696 	job_count = data.dsize / 4;
697 	for (i = 0; i < job_count; i++) {
698 		uint32_t ch_jobid;
699 
700 		ch_jobid = IVAL(data.dptr, i*4);
701 		if (ch_jobid == jobid) {
702 			if (i < job_count -1 )
703 				memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
704 			data.dsize -= 4;
705 			if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) != 0)
706 				goto out;
707 			break;
708 		}
709 	}
710 
711 	ret = True;
712   out:
713 
714 	if (gotlock)
715 		tdb_chainunlock(pdb->tdb, key);
716 	SAFE_FREE(data.dptr);
717 	release_print_db(pdb);
718 	if (ret)
719 		DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
720 	else
721 		DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
722 	return ret;
723 }
724 
pjob_store_notify(struct tevent_context * ev,struct messaging_context * msg_ctx,const char * sharename,uint32_t jobid,struct printjob * old_data,struct printjob * new_data,bool * pchanged)725 static void pjob_store_notify(struct tevent_context *ev,
726 			      struct messaging_context *msg_ctx,
727 			      const char* sharename, uint32_t jobid,
728 			      struct printjob *old_data,
729 			      struct printjob *new_data,
730 			      bool *pchanged)
731 {
732 	bool new_job = false;
733 	bool changed = false;
734 
735 	if (old_data == NULL) {
736 		new_job = true;
737 	}
738 
739 	/* ACHTUNG!  Due to a bug in Samba's spoolss parsing of the
740 	   NOTIFY_INFO_DATA buffer, we *have* to send the job submission
741 	   time first or else we'll end up with potential alignment
742 	   errors.  I don't think the systemtime should be spooled as
743 	   a string, but this gets us around that error.
744 	   --jerry (i'll feel dirty for this) */
745 
746 	if (new_job) {
747 		notify_job_submitted(ev, msg_ctx,
748 				     sharename, jobid, new_data->starttime);
749 		notify_job_username(ev, msg_ctx,
750 				    sharename, jobid, new_data->user);
751 		notify_job_name(ev, msg_ctx,
752 				sharename, jobid, new_data->jobname);
753 		notify_job_status(ev, msg_ctx,
754 				  sharename, jobid, map_to_spoolss_status(new_data->status));
755 		notify_job_total_bytes(ev, msg_ctx,
756 				       sharename, jobid, new_data->size);
757 		notify_job_total_pages(ev, msg_ctx,
758 				       sharename, jobid, new_data->page_count);
759 	} else {
760 		if (!strequal(old_data->jobname, new_data->jobname)) {
761 			notify_job_name(ev, msg_ctx, sharename,
762 					jobid, new_data->jobname);
763 			changed = true;
764 		}
765 
766 		if (old_data->status != new_data->status) {
767 			notify_job_status(ev, msg_ctx,
768 					  sharename, jobid,
769 					  map_to_spoolss_status(new_data->status));
770 		}
771 
772 		if (old_data->size != new_data->size) {
773 			notify_job_total_bytes(ev, msg_ctx,
774 					       sharename, jobid, new_data->size);
775 		}
776 
777 		if (old_data->page_count != new_data->page_count) {
778 			notify_job_total_pages(ev, msg_ctx,
779 					       sharename, jobid,
780 					       new_data->page_count);
781 		}
782 	}
783 
784 	*pchanged = changed;
785 }
786 
787 /****************************************************************************
788  Store a job structure back to the database.
789 ****************************************************************************/
790 
pjob_store(struct tevent_context * ev,struct messaging_context * msg_ctx,const char * sharename,uint32_t jobid,struct printjob * pjob)791 static bool pjob_store(struct tevent_context *ev,
792 		       struct messaging_context *msg_ctx,
793 		       const char* sharename, uint32_t jobid,
794 		       struct printjob *pjob)
795 {
796 	uint32_t tmp;
797 	TDB_DATA 		old_data, new_data;
798 	bool 			ret = False;
799 	struct tdb_print_db 	*pdb = get_print_db_byname(sharename);
800 	uint8_t			*buf = NULL;
801 	int			len, newlen, buflen;
802 
803 
804 	if (!pdb)
805 		return False;
806 
807 	/* Get old data */
808 
809 	old_data = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
810 
811 	/* Doh!  Now we have to pack/unpack data since the NT_DEVICEMODE was added */
812 
813 	newlen = 0;
814 
815 	do {
816 		len = 0;
817 		buflen = newlen;
818 		len += tdb_pack(buf+len, buflen-len, "ddddddddddfffff",
819 				(uint32_t)pjob->pid,
820 				(uint32_t)pjob->jobid,
821 				(uint32_t)pjob->sysjob,
822 				(uint32_t)pjob->fd,
823 				(uint32_t)pjob->starttime,
824 				(uint32_t)pjob->status,
825 				(uint32_t)pjob->size,
826 				(uint32_t)pjob->page_count,
827 				(uint32_t)pjob->spooled,
828 				(uint32_t)pjob->smbjob,
829 				pjob->filename,
830 				pjob->jobname,
831 				pjob->user,
832 				pjob->clientmachine,
833 				pjob->queuename);
834 
835 		len += pack_devicemode(pjob->devmode, buf+len, buflen-len);
836 
837 		if (buflen != len) {
838 			buf = (uint8_t *)SMB_REALLOC(buf, len);
839 			if (!buf) {
840 				DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
841 				goto done;
842 			}
843 			newlen = len;
844 		}
845 	} while ( buflen != len );
846 
847 
848 	/* Store new data */
849 
850 	new_data.dptr = buf;
851 	new_data.dsize = len;
852 	ret = (tdb_store(pdb->tdb, print_key(jobid, &tmp), new_data,
853 			 TDB_REPLACE) == 0);
854 
855 	/* Send notify updates for what has changed */
856 
857 	if (ret) {
858 		bool changed = false;
859 		struct printjob old_pjob;
860 
861 		if (old_data.dsize) {
862 			TALLOC_CTX *tmp_ctx = talloc_new(ev);
863 			if (tmp_ctx == NULL)
864 				goto done;
865 
866 			len = unpack_pjob(tmp_ctx, old_data.dptr,
867 					  old_data.dsize, &old_pjob);
868 			if (len != -1 ) {
869 				pjob_store_notify(ev,
870 						  msg_ctx,
871 						  sharename, jobid, &old_pjob,
872 						  pjob,
873 						  &changed);
874 				if (changed) {
875 					add_to_jobs_changed(pdb, jobid);
876 				}
877 			}
878 			talloc_free(tmp_ctx);
879 
880 		} else {
881 			/* new job */
882 			pjob_store_notify(ev, msg_ctx,
883 					  sharename, jobid, NULL, pjob,
884 					  &changed);
885 		}
886 	}
887 
888 done:
889 	release_print_db(pdb);
890 	SAFE_FREE( old_data.dptr );
891 	SAFE_FREE( buf );
892 
893 	return ret;
894 }
895 
896 /****************************************************************************
897  Remove a job structure from the database.
898 ****************************************************************************/
899 
pjob_delete(struct tevent_context * ev,struct messaging_context * msg_ctx,const char * sharename,uint32_t jobid)900 static void pjob_delete(struct tevent_context *ev,
901 			struct messaging_context *msg_ctx,
902 			const char* sharename, uint32_t jobid)
903 {
904 	uint32_t tmp;
905 	struct printjob *pjob;
906 	uint32_t job_status = 0;
907 	struct tdb_print_db *pdb;
908 	TALLOC_CTX *tmp_ctx = talloc_new(ev);
909 	if (tmp_ctx == NULL) {
910 		return;
911 	}
912 
913 	pdb = get_print_db_byname(sharename);
914 	if (!pdb) {
915 		goto err_out;
916 	}
917 
918 	pjob = print_job_find(tmp_ctx, sharename, jobid);
919 	if (!pjob) {
920 		DEBUG(5, ("we were asked to delete nonexistent job %u\n",
921 			  jobid));
922 		goto err_release;
923 	}
924 
925 	/* We must cycle through JOB_STATUS_DELETING and
926            JOB_STATUS_DELETED for the port monitor to delete the job
927            properly. */
928 
929 	job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
930 	notify_job_status(ev, msg_ctx, sharename, jobid, job_status);
931 
932 	/* Remove from printing.tdb */
933 
934 	tdb_delete(pdb->tdb, print_key(jobid, &tmp));
935 	remove_from_jobs_added(sharename, jobid);
936 	rap_jobid_delete(sharename, jobid);
937 err_release:
938 	release_print_db(pdb);
939 err_out:
940 	talloc_free(tmp_ctx);
941 }
942 
943 /****************************************************************************
944  List a unix job in the print database.
945 ****************************************************************************/
946 
print_unix_job(struct tevent_context * ev,struct messaging_context * msg_ctx,const char * sharename,print_queue_struct * q,uint32_t jobid)947 static void print_unix_job(struct tevent_context *ev,
948 			   struct messaging_context *msg_ctx,
949 			   const char *sharename, print_queue_struct *q,
950 			   uint32_t jobid)
951 {
952 	struct printjob pj, *old_pj;
953 	TALLOC_CTX *tmp_ctx = talloc_new(ev);
954 	if (tmp_ctx == NULL) {
955 		return;
956 	}
957 
958 	if (jobid == (uint32_t)-1) {
959 		jobid = q->sysjob + UNIX_JOB_START;
960 	}
961 
962 	/* Preserve the timestamp on an existing unix print job */
963 
964 	old_pj = print_job_find(tmp_ctx, sharename, jobid);
965 
966 	ZERO_STRUCT(pj);
967 
968 	pj.pid = (pid_t)-1;
969 	pj.jobid = jobid;
970 	pj.sysjob = q->sysjob;
971 	pj.fd = -1;
972 	pj.starttime = old_pj ? old_pj->starttime : q->time;
973 	pj.status = q->status;
974 	pj.size = q->size;
975 	pj.spooled = True;
976 	fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
977 	if (jobid < UNIX_JOB_START) {
978 		pj.smbjob = True;
979 		fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
980 	} else {
981 		pj.smbjob = False;
982 		fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
983 	}
984 	fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
985 	fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
986 
987 	pjob_store(ev, msg_ctx, sharename, jobid, &pj);
988 	talloc_free(tmp_ctx);
989 }
990 
991 
992 struct traverse_struct {
993 	print_queue_struct *queue;
994 	size_t qcount, snum, maxcount, total_jobs;
995 	const char *sharename;
996 	time_t lpq_time;
997 	const char *lprm_command;
998 	struct printif *print_if;
999 	struct tevent_context *ev;
1000 	struct messaging_context *msg_ctx;
1001 	TALLOC_CTX *mem_ctx;
1002 };
1003 
1004 /****************************************************************************
1005  Utility fn to delete any jobs that are no longer active.
1006 ****************************************************************************/
1007 
traverse_fn_delete(TDB_CONTEXT * t,TDB_DATA key,TDB_DATA data,void * state)1008 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
1009 {
1010 	struct traverse_struct *ts = (struct traverse_struct *)state;
1011 	struct printjob pjob;
1012 	uint32_t jobid;
1013 	size_t i = 0;
1014 
1015 	if (  key.dsize != sizeof(jobid) )
1016 		return 0;
1017 
1018 	if (unpack_pjob(ts->mem_ctx, data.dptr, data.dsize, &pjob) == -1)
1019 		return 0;
1020 	talloc_free(pjob.devmode);
1021 	jobid = pjob.jobid;
1022 
1023 	if (!pjob.smbjob) {
1024 		/* remove a unix job if it isn't in the system queue any more */
1025 		for (i=0;i<ts->qcount;i++) {
1026 			if (ts->queue[i].sysjob == pjob.sysjob) {
1027 				break;
1028 			}
1029 		}
1030 		if (i == ts->qcount) {
1031 			DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
1032 						(unsigned int)jobid ));
1033 			pjob_delete(ts->ev, ts->msg_ctx,
1034 				    ts->sharename, jobid);
1035 			return 0;
1036 		}
1037 
1038 		/* need to continue the the bottom of the function to
1039 		   save the correct attributes */
1040 	}
1041 
1042 	/* maybe it hasn't been spooled yet */
1043 	if (!pjob.spooled) {
1044 		/* if a job is not spooled and the process doesn't
1045                    exist then kill it. This cleans up after smbd
1046                    deaths */
1047 		if (!process_exists_by_pid(pjob.pid)) {
1048 			DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
1049 						(unsigned int)jobid, (unsigned int)pjob.pid ));
1050 			pjob_delete(ts->ev, ts->msg_ctx,
1051 				    ts->sharename, jobid);
1052 		} else
1053 			ts->total_jobs++;
1054 		return 0;
1055 	}
1056 
1057 	/* this check only makes sense for jobs submitted from Windows clients */
1058 
1059 	if (pjob.smbjob) {
1060 		for (i=0;i<ts->qcount;i++) {
1061 			if ( pjob.status == LPQ_DELETED )
1062 				continue;
1063 
1064 			if (ts->queue[i].sysjob == pjob.sysjob) {
1065 
1066 				/* try to clean up any jobs that need to be deleted */
1067 
1068 				if ( pjob.status == LPQ_DELETING ) {
1069 					int result;
1070 
1071 					result = (*(ts->print_if->job_delete))(
1072 						ts->sharename, ts->lprm_command, &pjob );
1073 
1074 					if ( result != 0 ) {
1075 						/* if we can't delete, then reset the job status */
1076 						pjob.status = LPQ_QUEUED;
1077 						pjob_store(ts->ev, ts->msg_ctx,
1078 							   ts->sharename, jobid, &pjob);
1079 					}
1080 					else {
1081 						/* if we deleted the job, the remove the tdb record */
1082 						pjob_delete(ts->ev,
1083 							    ts->msg_ctx,
1084 							    ts->sharename, jobid);
1085 						pjob.status = LPQ_DELETED;
1086 					}
1087 
1088 				}
1089 
1090 				break;
1091 			}
1092 		}
1093 	}
1094 
1095 	/* The job isn't in the system queue - we have to assume it has
1096 	   completed, so delete the database entry. */
1097 
1098 	if (i == ts->qcount) {
1099 
1100 		/* A race can occur between the time a job is spooled and
1101 		   when it appears in the lpq output.  This happens when
1102 		   the job is added to printing.tdb when another smbd
1103 		   running print_queue_update() has completed a lpq and
1104 		   is currently traversing the printing tdb and deleting jobs.
1105 		   Don't delete the job if it was submitted after the lpq_time. */
1106 
1107 		if (pjob.starttime < ts->lpq_time) {
1108 			DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
1109 						(unsigned int)jobid,
1110 						(unsigned int)pjob.starttime,
1111 						(unsigned int)ts->lpq_time ));
1112 			pjob_delete(ts->ev, ts->msg_ctx,
1113 				    ts->sharename, jobid);
1114 		} else
1115 			ts->total_jobs++;
1116 		return 0;
1117 	}
1118 
1119 	/* Save the pjob attributes we will store. */
1120 	ts->queue[i].sysjob = pjob.sysjob;
1121 	ts->queue[i].size = pjob.size;
1122 	ts->queue[i].page_count = pjob.page_count;
1123 	ts->queue[i].status = pjob.status;
1124 	ts->queue[i].priority = 1;
1125 	ts->queue[i].time = pjob.starttime;
1126 	fstrcpy(ts->queue[i].fs_user, pjob.user);
1127 	fstrcpy(ts->queue[i].fs_file, pjob.jobname);
1128 
1129 	ts->total_jobs++;
1130 
1131 	return 0;
1132 }
1133 
1134 /****************************************************************************
1135  Check if the print queue has been updated recently enough.
1136 ****************************************************************************/
1137 
print_cache_flush(const char * sharename)1138 static void print_cache_flush(const char *sharename)
1139 {
1140 	fstring key;
1141 	struct tdb_print_db *pdb = get_print_db_byname(sharename);
1142 
1143 	if (!pdb)
1144 		return;
1145 	slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
1146 	tdb_store_int32(pdb->tdb, key, -1);
1147 	release_print_db(pdb);
1148 }
1149 
1150 /****************************************************************************
1151  Check if someone already thinks they are doing the update.
1152 ****************************************************************************/
1153 
get_updating_pid(const char * sharename)1154 static pid_t get_updating_pid(const char *sharename)
1155 {
1156 	fstring keystr;
1157 	TDB_DATA data, key;
1158 	pid_t updating_pid;
1159 	struct tdb_print_db *pdb = get_print_db_byname(sharename);
1160 
1161 	if (!pdb)
1162 		return (pid_t)-1;
1163 	slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
1164     	key = string_tdb_data(keystr);
1165 
1166 	data = tdb_fetch(pdb->tdb, key);
1167 	release_print_db(pdb);
1168 	if (!data.dptr || data.dsize != sizeof(pid_t)) {
1169 		SAFE_FREE(data.dptr);
1170 		return (pid_t)-1;
1171 	}
1172 
1173 	updating_pid = IVAL(data.dptr, 0);
1174 	SAFE_FREE(data.dptr);
1175 
1176 	if (process_exists_by_pid(updating_pid))
1177 		return updating_pid;
1178 
1179 	return (pid_t)-1;
1180 }
1181 
1182 /****************************************************************************
1183  Set the fact that we're doing the update, or have finished doing the update
1184  in the tdb.
1185 ****************************************************************************/
1186 
set_updating_pid(const fstring sharename,bool updating)1187 static void set_updating_pid(const fstring sharename, bool updating)
1188 {
1189 	fstring keystr;
1190 	TDB_DATA key;
1191 	TDB_DATA data;
1192 	pid_t updating_pid = getpid();
1193 	uint8_t buffer[4];
1194 
1195 	struct tdb_print_db *pdb = get_print_db_byname(sharename);
1196 
1197 	if (!pdb)
1198 		return;
1199 
1200 	slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
1201     	key = string_tdb_data(keystr);
1202 
1203 	DEBUG(5, ("set_updating_pid: %supdating lpq cache for print share %s\n",
1204 		updating ? "" : "not ",
1205 		sharename ));
1206 
1207 	if ( !updating ) {
1208 		tdb_delete(pdb->tdb, key);
1209 		release_print_db(pdb);
1210 		return;
1211 	}
1212 
1213 	SIVAL( buffer, 0, updating_pid);
1214 	data.dptr = buffer;
1215 	data.dsize = 4;		/* we always assume this is a 4 byte value */
1216 
1217 	tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1218 	release_print_db(pdb);
1219 }
1220 
1221 /****************************************************************************
1222  Sort print jobs by submittal time.
1223 ****************************************************************************/
1224 
printjob_comp(print_queue_struct * j1,print_queue_struct * j2)1225 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
1226 {
1227 	/* Silly cases */
1228 
1229 	if (!j1 && !j2)
1230 		return 0;
1231 	if (!j1)
1232 		return -1;
1233 	if (!j2)
1234 		return 1;
1235 
1236 	/* Sort on job start time */
1237 
1238 	if (j1->time == j2->time)
1239 		return 0;
1240 	return (j1->time > j2->time) ? 1 : -1;
1241 }
1242 
1243 /****************************************************************************
1244  Store the sorted queue representation for later portmon retrieval.
1245  Skip deleted jobs
1246 ****************************************************************************/
1247 
store_queue_struct(struct tdb_print_db * pdb,struct traverse_struct * pts)1248 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
1249 {
1250 	TDB_DATA data;
1251 	int max_reported_jobs = lp_max_reported_print_jobs(pts->snum);
1252 	print_queue_struct *queue = pts->queue;
1253 	size_t len;
1254 	size_t i;
1255 	unsigned int qcount;
1256 
1257 	if (max_reported_jobs && (max_reported_jobs < pts->qcount))
1258 		pts->qcount = max_reported_jobs;
1259 	qcount = 0;
1260 
1261 	/* Work out the size. */
1262 	data.dsize = 0;
1263 	data.dsize += tdb_pack(NULL, 0, "d", qcount);
1264 
1265 	for (i = 0; i < pts->qcount; i++) {
1266 		if ( queue[i].status == LPQ_DELETED )
1267 			continue;
1268 
1269 		qcount++;
1270 		data.dsize += tdb_pack(NULL, 0, "ddddddff",
1271 				(uint32_t)queue[i].sysjob,
1272 				(uint32_t)queue[i].size,
1273 				(uint32_t)queue[i].page_count,
1274 				(uint32_t)queue[i].status,
1275 				(uint32_t)queue[i].priority,
1276 				(uint32_t)queue[i].time,
1277 				queue[i].fs_user,
1278 				queue[i].fs_file);
1279 	}
1280 
1281 	if ((data.dptr = (uint8_t *)SMB_MALLOC(data.dsize)) == NULL)
1282 		return;
1283 
1284         len = 0;
1285 	len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
1286 	for (i = 0; i < pts->qcount; i++) {
1287 		if ( queue[i].status == LPQ_DELETED )
1288 			continue;
1289 
1290 		len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
1291 				(uint32_t)queue[i].sysjob,
1292 				(uint32_t)queue[i].size,
1293 				(uint32_t)queue[i].page_count,
1294 				(uint32_t)queue[i].status,
1295 				(uint32_t)queue[i].priority,
1296 				(uint32_t)queue[i].time,
1297 				queue[i].fs_user,
1298 				queue[i].fs_file);
1299 	}
1300 
1301 	tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
1302 		  TDB_REPLACE);
1303 	SAFE_FREE(data.dptr);
1304 	return;
1305 }
1306 
get_jobs_added_data(struct tdb_print_db * pdb)1307 static TDB_DATA get_jobs_added_data(struct tdb_print_db *pdb)
1308 {
1309 	TDB_DATA data;
1310 
1311 	ZERO_STRUCT(data);
1312 
1313 	data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added"));
1314 	if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
1315 		SAFE_FREE(data.dptr);
1316 		ZERO_STRUCT(data);
1317 	}
1318 
1319 	return data;
1320 }
1321 
check_job_added(const char * sharename,TDB_DATA data,uint32_t jobid)1322 static void check_job_added(const char *sharename, TDB_DATA data, uint32_t jobid)
1323 {
1324 	unsigned int i;
1325 	unsigned int job_count = data.dsize / 4;
1326 
1327 	for (i = 0; i < job_count; i++) {
1328 		uint32_t ch_jobid;
1329 
1330 		ch_jobid = IVAL(data.dptr, i*4);
1331 		if (ch_jobid == jobid)
1332 			remove_from_jobs_added(sharename, jobid);
1333 	}
1334 }
1335 
1336 /****************************************************************************
1337  Check if the print queue has been updated recently enough.
1338 ****************************************************************************/
1339 
print_cache_expired(const char * sharename,bool check_pending)1340 static bool print_cache_expired(const char *sharename, bool check_pending)
1341 {
1342 	fstring key;
1343 	time_t last_qscan_time, time_now = time(NULL);
1344 	struct tdb_print_db *pdb = get_print_db_byname(sharename);
1345 	bool result = False;
1346 
1347 	if (!pdb)
1348 		return False;
1349 
1350 	snprintf(key, sizeof(key), "CACHE/%s", sharename);
1351 	last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1352 
1353 	/*
1354 	 * Invalidate the queue for 3 reasons.
1355 	 * (1). last queue scan time == -1.
1356 	 * (2). Current time - last queue scan time > allowed cache time.
1357 	 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1358 	 * This last test picks up machines for which the clock has been moved
1359 	 * forward, an lpq scan done and then the clock moved back. Otherwise
1360 	 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1361 	 */
1362 
1363 	if (last_qscan_time == ((time_t)-1)
1364 		|| (time_now - last_qscan_time) >= lp_lpq_cache_time()
1365 		|| last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
1366 	{
1367 		uint32_t u;
1368 		time_t msg_pending_time;
1369 
1370 		DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1371 			"(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1372 			sharename, (int)last_qscan_time, (int)time_now,
1373 			(int)lp_lpq_cache_time() ));
1374 
1375 		/* check if another smbd has already sent a message to update the
1376 		   queue.  Give the pending message one minute to clear and
1377 		   then send another message anyways.  Make sure to check for
1378 		   clocks that have been run forward and then back again. */
1379 
1380 		snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1381 
1382 		if ( check_pending
1383 			&& tdb_fetch_uint32( pdb->tdb, key, &u )
1384 			&& (msg_pending_time=u) > 0
1385 			&& msg_pending_time <= time_now
1386 			&& (time_now - msg_pending_time) < 60 )
1387 		{
1388 			DEBUG(4,("print_cache_expired: message already pending for %s.  Accepting cache\n",
1389 				sharename));
1390 			goto done;
1391 		}
1392 
1393 		result = True;
1394 	}
1395 
1396 done:
1397 	release_print_db(pdb);
1398 	return result;
1399 }
1400 
1401 /****************************************************************************
1402  main work for updating the lpq cache for a printer queue
1403 ****************************************************************************/
1404 
print_queue_update_internal(struct tevent_context * ev,struct messaging_context * msg_ctx,const char * sharename,struct printif * current_printif,char * lpq_command,char * lprm_command)1405 static void print_queue_update_internal(struct tevent_context *ev,
1406 					struct messaging_context *msg_ctx,
1407 					const char *sharename,
1408                                         struct printif *current_printif,
1409                                         char *lpq_command, char *lprm_command)
1410 {
1411 	size_t i, qcount;
1412 	print_queue_struct *queue = NULL;
1413 	print_status_struct status;
1414 	print_status_struct old_status;
1415 	struct printjob *pjob;
1416 	struct traverse_struct tstruct;
1417 	TDB_DATA data, key;
1418 	TDB_DATA jcdata;
1419 	fstring keystr, cachestr;
1420 	struct tdb_print_db *pdb = get_print_db_byname(sharename);
1421 	TALLOC_CTX *tmp_ctx = talloc_new(ev);
1422 
1423 	if ((pdb == NULL) || (tmp_ctx == NULL)) {
1424 		return;
1425 	}
1426 
1427 	DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1428 		sharename, current_printif->type, lpq_command));
1429 
1430 	/*
1431 	 * Update the cache time FIRST ! Stops others even
1432 	 * attempting to get the lock and doing this
1433 	 * if the lpq takes a long time.
1434 	 */
1435 
1436 	slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1437 	tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1438 
1439         /* get the current queue using the appropriate interface */
1440 	ZERO_STRUCT(status);
1441 
1442 	qcount = (*(current_printif->queue_get))(sharename,
1443 		current_printif->type,
1444 		lpq_command, &queue, &status);
1445 
1446 	DBG_NOTICE("%zu job%s in queue for %s\n",
1447 		   qcount,
1448 		   (qcount != 1) ? "s" : "",
1449 		   sharename);
1450 
1451 	/* Sort the queue by submission time otherwise they are displayed
1452 	   in hash order. */
1453 
1454 	TYPESAFE_QSORT(queue, qcount, printjob_comp);
1455 
1456 	/*
1457 	  any job in the internal database that is marked as spooled
1458 	  and doesn't exist in the system queue is considered finished
1459 	  and removed from the database
1460 
1461 	  any job in the system database but not in the internal database
1462 	  is added as a unix job
1463 
1464 	  fill in any system job numbers as we go
1465 	*/
1466 	jcdata = get_jobs_added_data(pdb);
1467 
1468 	for (i=0; i<qcount; i++) {
1469 		uint32_t jobid = sysjob_to_jobid_pdb(pdb, queue[i].sysjob);
1470 		if (jobid == (uint32_t)-1) {
1471 			/* assume its a unix print job */
1472 			print_unix_job(ev, msg_ctx,
1473 				       sharename, &queue[i], jobid);
1474 			continue;
1475 		}
1476 
1477 		/* we have an active SMB print job - update its status */
1478 		pjob = print_job_find(tmp_ctx, sharename, jobid);
1479 		if (!pjob) {
1480 			/* err, somethings wrong. Probably smbd was restarted
1481 			   with jobs in the queue. All we can do is treat them
1482 			   like unix jobs. Pity. */
1483 			DEBUG(1, ("queued print job %d not found in jobs list, "
1484 				  "assuming unix job\n", jobid));
1485 			print_unix_job(ev, msg_ctx,
1486 				       sharename, &queue[i], jobid);
1487 			continue;
1488 		}
1489 
1490 		/* don't reset the status on jobs to be deleted */
1491 
1492 		if ( pjob->status != LPQ_DELETING )
1493 			pjob->status = queue[i].status;
1494 
1495 		pjob_store(ev, msg_ctx, sharename, jobid, pjob);
1496 
1497 		check_job_added(sharename, jcdata, jobid);
1498 	}
1499 
1500 	SAFE_FREE(jcdata.dptr);
1501 
1502 	/* now delete any queued entries that don't appear in the
1503            system queue */
1504 	tstruct.queue = queue;
1505 	tstruct.qcount = qcount;
1506 	tstruct.snum = -1;
1507 	tstruct.total_jobs = 0;
1508 	tstruct.lpq_time = time(NULL);
1509 	tstruct.sharename = sharename;
1510 	tstruct.lprm_command = lprm_command;
1511 	tstruct.print_if = current_printif;
1512 	tstruct.ev = ev;
1513 	tstruct.msg_ctx = msg_ctx;
1514 	tstruct.mem_ctx = tmp_ctx;
1515 
1516 	tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1517 
1518 	/* Store the linearised queue, max jobs only. */
1519 	store_queue_struct(pdb, &tstruct);
1520 
1521 	SAFE_FREE(tstruct.queue);
1522 	talloc_free(tmp_ctx);
1523 
1524 	DBG_DEBUG("printer %s INFO, total_jobs = %zu\n",
1525 		  sharename,
1526 		  tstruct.total_jobs);
1527 
1528 	tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1529 
1530 	get_queue_status(sharename, &old_status);
1531 	if (old_status.qcount != qcount) {
1532 		DBG_DEBUG("Queue status change %zu jobs -> %zu jobs "
1533 			  "for printer %s\n",
1534 			  old_status.qcount,
1535 			  qcount,
1536 			  sharename);
1537 	}
1538 
1539 	/* store the new queue status structure */
1540 	slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1541 	key = string_tdb_data(keystr);
1542 
1543 	status.qcount = qcount;
1544 	data.dptr = (uint8_t *)&status;
1545 	data.dsize = sizeof(status);
1546 	tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1547 
1548 	/*
1549 	 * Update the cache time again. We want to do this call
1550 	 * as little as possible...
1551 	 */
1552 
1553 	slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1554 	tdb_store_int32(pdb->tdb, keystr, (int32_t)time(NULL));
1555 
1556 	/* clear the msg pending record for this queue */
1557 
1558 	snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1559 
1560 	if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1561 		/* log a message but continue on */
1562 
1563 		DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1564 			sharename));
1565 	}
1566 
1567 	release_print_db( pdb );
1568 
1569 	return;
1570 }
1571 
1572 /****************************************************************************
1573  Update the internal database from the system print queue for a queue.
1574  obtain a lock on the print queue before proceeding (needed when mutiple
1575  smbd processes maytry to update the lpq cache concurrently).
1576 ****************************************************************************/
1577 
print_queue_update_with_lock(struct tevent_context * ev,struct messaging_context * msg_ctx,const char * sharename,struct printif * current_printif,char * lpq_command,char * lprm_command)1578 static void print_queue_update_with_lock( struct tevent_context *ev,
1579 					  struct messaging_context *msg_ctx,
1580 					  const char *sharename,
1581                                           struct printif *current_printif,
1582                                           char *lpq_command, char *lprm_command )
1583 {
1584 	fstring keystr;
1585 	struct tdb_print_db *pdb;
1586 
1587 	DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1588 	pdb = get_print_db_byname(sharename);
1589 	if (!pdb)
1590 		return;
1591 
1592 	if ( !print_cache_expired(sharename, False) ) {
1593 		DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1594 		release_print_db(pdb);
1595 		return;
1596 	}
1597 
1598 	/*
1599 	 * Check to see if someone else is doing this update.
1600 	 * This is essentially a mutex on the update.
1601 	 */
1602 
1603 	if (get_updating_pid(sharename) != -1) {
1604 		release_print_db(pdb);
1605 		return;
1606 	}
1607 
1608 	/* Lock the queue for the database update */
1609 
1610 	slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1611 	/* Only wait 10 seconds for this. */
1612 	if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) != 0) {
1613 		DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1614 		release_print_db(pdb);
1615 		return;
1616 	}
1617 
1618 	/*
1619 	 * Ensure that no one else got in here.
1620 	 * If the updating pid is still -1 then we are
1621 	 * the winner.
1622 	 */
1623 
1624 	if (get_updating_pid(sharename) != -1) {
1625 		/*
1626 		 * Someone else is doing the update, exit.
1627 		 */
1628 		tdb_unlock_bystring(pdb->tdb, keystr);
1629 		release_print_db(pdb);
1630 		return;
1631 	}
1632 
1633 	/*
1634 	 * We're going to do the update ourselves.
1635 	 */
1636 
1637 	/* Tell others we're doing the update. */
1638 	set_updating_pid(sharename, True);
1639 
1640 	/*
1641 	 * Allow others to enter and notice we're doing
1642 	 * the update.
1643 	 */
1644 
1645 	tdb_unlock_bystring(pdb->tdb, keystr);
1646 
1647 	/* do the main work now */
1648 
1649 	print_queue_update_internal(ev, msg_ctx,
1650 				    sharename, current_printif,
1651 				    lpq_command, lprm_command);
1652 
1653 	/* Delete our pid from the db. */
1654 	set_updating_pid(sharename, False);
1655 	release_print_db(pdb);
1656 }
1657 
1658 /****************************************************************************
1659 this is the receive function of the background lpq updater
1660 ****************************************************************************/
print_queue_receive(struct messaging_context * msg,void * private_data,uint32_t msg_type,struct server_id server_id,DATA_BLOB * data)1661 void print_queue_receive(struct messaging_context *msg,
1662 				void *private_data,
1663 				uint32_t msg_type,
1664 				struct server_id server_id,
1665 				DATA_BLOB *data)
1666 {
1667 	fstring sharename;
1668 	char *lpqcommand = NULL, *lprmcommand = NULL;
1669 	int printing_type;
1670 	size_t len;
1671 
1672 	len = tdb_unpack( (uint8_t *)data->data, data->length, "fdPP",
1673 		sharename,
1674 		&printing_type,
1675 		&lpqcommand,
1676 		&lprmcommand );
1677 
1678 	if ( len == -1 ) {
1679 		SAFE_FREE(lpqcommand);
1680 		SAFE_FREE(lprmcommand);
1681 		DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1682 		return;
1683 	}
1684 
1685 	print_queue_update_with_lock(global_event_context(), msg, sharename,
1686 		get_printer_fns_from_type((enum printing_types)printing_type),
1687 		lpqcommand, lprmcommand );
1688 
1689 	SAFE_FREE(lpqcommand);
1690 	SAFE_FREE(lprmcommand);
1691 	return;
1692 }
1693 
1694 /****************************************************************************
1695 update the internal database from the system print queue for a queue
1696 ****************************************************************************/
1697 
1698 extern pid_t background_lpq_updater_pid;
1699 
print_queue_update(struct messaging_context * msg_ctx,int snum,bool force)1700 static void print_queue_update(struct messaging_context *msg_ctx,
1701 			       int snum, bool force)
1702 {
1703 	char key[268];
1704 	fstring sharename;
1705 	char *lpqcommand = NULL;
1706 	char *lprmcommand = NULL;
1707 	uint8_t *buffer = NULL;
1708 	size_t len = 0;
1709 	size_t newlen;
1710 	struct tdb_print_db *pdb;
1711 	int type;
1712 	struct printif *current_printif;
1713 	TALLOC_CTX *ctx = talloc_tos();
1714 	const struct loadparm_substitution *lp_sub =
1715 		loadparm_s3_global_substitution();
1716 
1717 	fstrcpy( sharename, lp_const_servicename(snum));
1718 
1719 	/* don't strip out characters like '$' from the printername */
1720 
1721 	lpqcommand = talloc_string_sub2(ctx,
1722 			lp_lpq_command(snum),
1723 			"%p",
1724 			lp_printername(talloc_tos(), lp_sub, snum),
1725 			false, false, false);
1726 	if (!lpqcommand) {
1727 		return;
1728 	}
1729 	lpqcommand = talloc_sub_full(ctx,
1730 			lp_servicename(talloc_tos(), lp_sub, snum),
1731 			current_user_info.unix_name,
1732 			"",
1733 			get_current_gid(NULL),
1734 			get_current_username(),
1735 			current_user_info.domain,
1736 			lpqcommand);
1737 	if (!lpqcommand) {
1738 		return;
1739 	}
1740 
1741 	lprmcommand = talloc_string_sub2(ctx,
1742 			lp_lprm_command(snum),
1743 			"%p",
1744 			lp_printername(talloc_tos(), lp_sub, snum),
1745 			false, false, false);
1746 	if (!lprmcommand) {
1747 		return;
1748 	}
1749 	lprmcommand = talloc_sub_full(ctx,
1750 			lp_servicename(talloc_tos(), lp_sub, snum),
1751 			current_user_info.unix_name,
1752 			"",
1753 			get_current_gid(NULL),
1754 			get_current_username(),
1755 			current_user_info.domain,
1756 			lprmcommand);
1757 	if (!lprmcommand) {
1758 		return;
1759 	}
1760 
1761 	/*
1762 	 * Make sure that the background queue process exists.
1763 	 * Otherwise just do the update ourselves
1764 	 */
1765 
1766 	if ( force || background_lpq_updater_pid == -1 ) {
1767 		DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1768 		current_printif = get_printer_fns( snum );
1769 		print_queue_update_with_lock(global_event_context(), msg_ctx,
1770 					     sharename, current_printif,
1771 					     lpqcommand, lprmcommand);
1772 
1773 		return;
1774 	}
1775 
1776 	type = lp_printing(snum);
1777 
1778 	/* get the length */
1779 
1780 	len = tdb_pack( NULL, 0, "fdPP",
1781 		sharename,
1782 		type,
1783 		lpqcommand,
1784 		lprmcommand );
1785 
1786 	buffer = SMB_XMALLOC_ARRAY( uint8_t, len );
1787 
1788 	/* now pack the buffer */
1789 	newlen = tdb_pack( buffer, len, "fdPP",
1790 		sharename,
1791 		type,
1792 		lpqcommand,
1793 		lprmcommand );
1794 
1795 	SMB_ASSERT( newlen == len );
1796 
1797 	DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1798 		"type = %d, lpq command = [%s] lprm command = [%s]\n",
1799 		sharename, type, lpqcommand, lprmcommand ));
1800 
1801 	/* here we set a msg pending record for other smbd processes
1802 	   to throttle the number of duplicate print_queue_update msgs
1803 	   sent.  */
1804 
1805 	pdb = get_print_db_byname(sharename);
1806 	if (!pdb) {
1807 		SAFE_FREE(buffer);
1808 		return;
1809 	}
1810 
1811 	snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1812 
1813 	if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1814 		/* log a message but continue on */
1815 
1816 		DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1817 			sharename));
1818 	}
1819 
1820 	release_print_db( pdb );
1821 
1822 	/* finally send the message */
1823 
1824 	messaging_send_buf(msg_ctx, pid_to_procid(background_lpq_updater_pid),
1825 			   MSG_PRINTER_UPDATE, (uint8_t *)buffer, len);
1826 
1827 	SAFE_FREE( buffer );
1828 
1829 	return;
1830 }
1831 
1832 /****************************************************************************
1833  Create/Update an entry in the print tdb that will allow us to send notify
1834  updates only to interested smbd's.
1835 ****************************************************************************/
1836 
print_notify_register_pid(int snum)1837 bool print_notify_register_pid(int snum)
1838 {
1839 	TDB_DATA data;
1840 	struct tdb_print_db *pdb = NULL;
1841 	TDB_CONTEXT *tdb = NULL;
1842 	const char *printername;
1843 	uint32_t mypid = (uint32_t)getpid();
1844 	bool ret = False;
1845 	size_t i;
1846 
1847 	/* if (snum == -1), then the change notify request was
1848 	   on a print server handle and we need to register on
1849 	   all print queus */
1850 
1851 	if (snum == -1)
1852 	{
1853 		int num_services = lp_numservices();
1854 		int idx;
1855 
1856 		for ( idx=0; idx<num_services; idx++ ) {
1857 			if (lp_snum_ok(idx) && lp_printable(idx) )
1858 				print_notify_register_pid(idx);
1859 		}
1860 
1861 		return True;
1862 	}
1863 	else /* register for a specific printer */
1864 	{
1865 		printername = lp_const_servicename(snum);
1866 		pdb = get_print_db_byname(printername);
1867 		if (!pdb)
1868 			return False;
1869 		tdb = pdb->tdb;
1870 	}
1871 
1872 	if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) != 0) {
1873 		DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1874 					printername));
1875 		if (pdb)
1876 			release_print_db(pdb);
1877 		return False;
1878 	}
1879 
1880 	data = get_printer_notify_pid_list( tdb, printername, True );
1881 
1882 	/* Add ourselves and increase the refcount. */
1883 
1884 	for (i = 0; i < data.dsize; i += 8) {
1885 		if (IVAL(data.dptr,i) == mypid) {
1886 			uint32_t new_refcount = IVAL(data.dptr, i+4) + 1;
1887 			SIVAL(data.dptr, i+4, new_refcount);
1888 			break;
1889 		}
1890 	}
1891 
1892 	if (i == data.dsize) {
1893 		/* We weren't in the list. Realloc. */
1894 		data.dptr = (uint8_t *)SMB_REALLOC(data.dptr, data.dsize + 8);
1895 		if (!data.dptr) {
1896 			DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1897 						printername));
1898 			goto done;
1899 		}
1900 		data.dsize += 8;
1901 		SIVAL(data.dptr,data.dsize - 8,mypid);
1902 		SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1903 	}
1904 
1905 	/* Store back the record. */
1906 	if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) != 0) {
1907 		DEBUG(0,("print_notify_register_pid: Failed to update pid \
1908 list for printer %s\n", printername));
1909 		goto done;
1910 	}
1911 
1912 	ret = True;
1913 
1914  done:
1915 
1916 	tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1917 	if (pdb)
1918 		release_print_db(pdb);
1919 	SAFE_FREE(data.dptr);
1920 	return ret;
1921 }
1922 
1923 /****************************************************************************
1924  Update an entry in the print tdb that will allow us to send notify
1925  updates only to interested smbd's.
1926 ****************************************************************************/
1927 
print_notify_deregister_pid(int snum)1928 bool print_notify_deregister_pid(int snum)
1929 {
1930 	TDB_DATA data;
1931 	struct tdb_print_db *pdb = NULL;
1932 	TDB_CONTEXT *tdb = NULL;
1933 	const char *printername;
1934 	uint32_t mypid = (uint32_t)getpid();
1935 	size_t i;
1936 	bool ret = False;
1937 
1938 	/* if ( snum == -1 ), we are deregister a print server handle
1939 	   which means to deregister on all print queues */
1940 
1941 	if (snum == -1)
1942 	{
1943 		int num_services = lp_numservices();
1944 		int idx;
1945 
1946 		for ( idx=0; idx<num_services; idx++ ) {
1947 			if ( lp_snum_ok(idx) && lp_printable(idx) )
1948 				print_notify_deregister_pid(idx);
1949 		}
1950 
1951 		return True;
1952 	}
1953 	else /* deregister a specific printer */
1954 	{
1955 		printername = lp_const_servicename(snum);
1956 		pdb = get_print_db_byname(printername);
1957 		if (!pdb)
1958 			return False;
1959 		tdb = pdb->tdb;
1960 	}
1961 
1962 	if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) != 0) {
1963 		DEBUG(0,("print_notify_register_pid: Failed to lock \
1964 printer %s database\n", printername));
1965 		if (pdb)
1966 			release_print_db(pdb);
1967 		return False;
1968 	}
1969 
1970 	data = get_printer_notify_pid_list( tdb, printername, True );
1971 
1972 	/* Reduce refcount. Remove ourselves if zero. */
1973 
1974 	for (i = 0; i < data.dsize; ) {
1975 		if (IVAL(data.dptr,i) == mypid) {
1976 			uint32_t refcount = IVAL(data.dptr, i+4);
1977 
1978 			refcount--;
1979 
1980 			if (refcount == 0) {
1981 				if (data.dsize - i > 8)
1982 					memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1983 				data.dsize -= 8;
1984 				continue;
1985 			}
1986 			SIVAL(data.dptr, i+4, refcount);
1987 		}
1988 
1989 		i += 8;
1990 	}
1991 
1992 	if (data.dsize == 0)
1993 		SAFE_FREE(data.dptr);
1994 
1995 	/* Store back the record. */
1996 	if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) != 0) {
1997 		DEBUG(0,("print_notify_register_pid: Failed to update pid \
1998 list for printer %s\n", printername));
1999 		goto done;
2000 	}
2001 
2002 	ret = True;
2003 
2004   done:
2005 
2006 	tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
2007 	if (pdb)
2008 		release_print_db(pdb);
2009 	SAFE_FREE(data.dptr);
2010 	return ret;
2011 }
2012 
2013 /****************************************************************************
2014  Check if a jobid is valid. It is valid if it exists in the database.
2015 ****************************************************************************/
2016 
print_job_exists(const char * sharename,uint32_t jobid)2017 bool print_job_exists(const char* sharename, uint32_t jobid)
2018 {
2019 	struct tdb_print_db *pdb = get_print_db_byname(sharename);
2020 	bool ret;
2021 	uint32_t tmp;
2022 
2023 	if (!pdb)
2024 		return False;
2025 	ret = tdb_exists(pdb->tdb, print_key(jobid, &tmp));
2026 	release_print_db(pdb);
2027 	return ret;
2028 }
2029 
2030 /****************************************************************************
2031  Return the device mode asigned to a specific print job.
2032  Only valid for the process doing the spooling and when the job
2033  has not been spooled.
2034 ****************************************************************************/
2035 
print_job_devmode(TALLOC_CTX * mem_ctx,const char * sharename,uint32_t jobid)2036 struct spoolss_DeviceMode *print_job_devmode(TALLOC_CTX *mem_ctx,
2037 					     const char *sharename,
2038 					     uint32_t jobid)
2039 {
2040 	struct printjob *pjob = print_job_find(mem_ctx, sharename, jobid);
2041 	if (pjob == NULL) {
2042 		return NULL;
2043 	}
2044 
2045 	return pjob->devmode;
2046 }
2047 
2048 /****************************************************************************
2049  Set the name of a job. Only possible for owner.
2050 ****************************************************************************/
2051 
print_job_set_name(struct tevent_context * ev,struct messaging_context * msg_ctx,const char * sharename,uint32_t jobid,const char * name)2052 bool print_job_set_name(struct tevent_context *ev,
2053 			struct messaging_context *msg_ctx,
2054 			const char *sharename, uint32_t jobid, const char *name)
2055 {
2056 	struct printjob *pjob;
2057 	bool ret;
2058 	TALLOC_CTX *tmp_ctx = talloc_new(ev);
2059 	if (tmp_ctx == NULL) {
2060 		return false;
2061 	}
2062 
2063 	pjob = print_job_find(tmp_ctx, sharename, jobid);
2064 	if (!pjob || pjob->pid != getpid()) {
2065 		ret = false;
2066 		goto err_out;
2067 	}
2068 
2069 	fstrcpy(pjob->jobname, name);
2070 	ret = pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2071 err_out:
2072 	talloc_free(tmp_ctx);
2073 	return ret;
2074 }
2075 
2076 /****************************************************************************
2077  Get the name of a job. Only possible for owner.
2078 ****************************************************************************/
2079 
print_job_get_name(TALLOC_CTX * mem_ctx,const char * sharename,uint32_t jobid,char ** name)2080 bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t jobid, char **name)
2081 {
2082 	struct printjob *pjob;
2083 
2084 	pjob = print_job_find(mem_ctx, sharename, jobid);
2085 	if (!pjob || pjob->pid != getpid()) {
2086 		return false;
2087 	}
2088 
2089 	*name = pjob->jobname;
2090 	return true;
2091 }
2092 
2093 
2094 /***************************************************************************
2095  Remove a jobid from the 'jobs added' list.
2096 ***************************************************************************/
2097 
remove_from_jobs_added(const char * sharename,uint32_t jobid)2098 static bool remove_from_jobs_added(const char* sharename, uint32_t jobid)
2099 {
2100 	struct tdb_print_db *pdb = get_print_db_byname(sharename);
2101 	TDB_DATA data, key;
2102 	size_t job_count, i;
2103 	bool ret = False;
2104 	bool gotlock = False;
2105 
2106 	if (!pdb) {
2107 		return False;
2108 	}
2109 
2110 	ZERO_STRUCT(data);
2111 
2112 	key = string_tdb_data("INFO/jobs_added");
2113 
2114 	if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) != 0)
2115 		goto out;
2116 
2117 	gotlock = True;
2118 
2119 	data = tdb_fetch(pdb->tdb, key);
2120 
2121 	if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
2122 		goto out;
2123 
2124 	job_count = data.dsize / 4;
2125 	for (i = 0; i < job_count; i++) {
2126 		uint32_t ch_jobid;
2127 
2128 		ch_jobid = IVAL(data.dptr, i*4);
2129 		if (ch_jobid == jobid) {
2130 			if (i < job_count -1 )
2131 				memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
2132 			data.dsize -= 4;
2133 			if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) != 0)
2134 				goto out;
2135 			break;
2136 		}
2137 	}
2138 
2139 	ret = True;
2140   out:
2141 
2142 	if (gotlock)
2143 		tdb_chainunlock(pdb->tdb, key);
2144 	SAFE_FREE(data.dptr);
2145 	release_print_db(pdb);
2146 	if (ret)
2147 		DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid ));
2148 	else
2149 		DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid ));
2150 	return ret;
2151 }
2152 
2153 /****************************************************************************
2154  Delete a print job - don't update queue.
2155 ****************************************************************************/
2156 
print_job_delete1(struct tevent_context * ev,struct messaging_context * msg_ctx,int snum,uint32_t jobid)2157 static bool print_job_delete1(struct tevent_context *ev,
2158 			      struct messaging_context *msg_ctx,
2159 			      int snum, uint32_t jobid)
2160 {
2161 	const char* sharename = lp_const_servicename(snum);
2162 	const struct loadparm_substitution *lp_sub =
2163 		loadparm_s3_global_substitution();
2164 	struct printjob *pjob;
2165 	int result = 0;
2166 	struct printif *current_printif = get_printer_fns( snum );
2167 	bool ret;
2168 	TALLOC_CTX *tmp_ctx = talloc_new(ev);
2169 	if (tmp_ctx == NULL) {
2170 		return false;
2171 	}
2172 
2173 	pjob = print_job_find(tmp_ctx, sharename, jobid);
2174 	if (!pjob) {
2175 		ret = false;
2176 		goto err_out;
2177 	}
2178 
2179 	/*
2180 	 * If already deleting just return.
2181 	 */
2182 
2183 	if (pjob->status == LPQ_DELETING) {
2184 		ret = true;
2185 		goto err_out;
2186 	}
2187 
2188 	/* Hrm - we need to be able to cope with deleting a job before it
2189 	   has reached the spooler.  Just mark it as LPQ_DELETING and
2190 	   let the print_queue_update() code rmeove the record */
2191 
2192 
2193 	if (pjob->sysjob == -1) {
2194 		DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
2195 	}
2196 
2197 	/* Set the tdb entry to be deleting. */
2198 
2199 	pjob->status = LPQ_DELETING;
2200 	pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2201 
2202 	if (pjob->spooled && pjob->sysjob != -1)
2203 	{
2204 		result = (*(current_printif->job_delete))(
2205 			lp_printername(talloc_tos(), lp_sub, snum),
2206 			lp_lprm_command(snum),
2207 			pjob);
2208 
2209 		/* Delete the tdb entry if the delete succeeded or the job hasn't
2210 		   been spooled. */
2211 
2212 		if (result == 0) {
2213 			struct tdb_print_db *pdb = get_print_db_byname(sharename);
2214 			int njobs = 1;
2215 
2216 			if (!pdb) {
2217 				ret = false;
2218 				goto err_out;
2219 			}
2220 			pjob_delete(ev, msg_ctx, sharename, jobid);
2221 			/* Ensure we keep a rough count of the number of total jobs... */
2222 			tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
2223 			release_print_db(pdb);
2224 		}
2225 	}
2226 
2227 	remove_from_jobs_added( sharename, jobid );
2228 
2229 	ret = (result == 0);
2230 err_out:
2231 	talloc_free(tmp_ctx);
2232 	return ret;
2233 }
2234 
2235 /****************************************************************************
2236  Return true if the current user owns the print job.
2237 ****************************************************************************/
2238 
is_owner(const struct auth_session_info * server_info,const char * servicename,uint32_t jobid)2239 static bool is_owner(const struct auth_session_info *server_info,
2240 		     const char *servicename,
2241 		     uint32_t jobid)
2242 {
2243 	struct printjob *pjob;
2244 	bool ret;
2245 	TALLOC_CTX *tmp_ctx = talloc_new(server_info);
2246 	if (tmp_ctx == NULL) {
2247 		return false;
2248 	}
2249 
2250 	pjob = print_job_find(tmp_ctx, servicename, jobid);
2251 	if (!pjob || !server_info) {
2252 		ret = false;
2253 		goto err_out;
2254 	}
2255 
2256 	ret = strequal(pjob->user, server_info->unix_info->sanitized_username);
2257 err_out:
2258 	talloc_free(tmp_ctx);
2259 	return ret;
2260 }
2261 
2262 /****************************************************************************
2263  Delete a print job.
2264 ****************************************************************************/
2265 
print_job_delete(const struct auth_session_info * server_info,struct messaging_context * msg_ctx,int snum,uint32_t jobid)2266 WERROR print_job_delete(const struct auth_session_info *server_info,
2267 			struct messaging_context *msg_ctx,
2268 			int snum, uint32_t jobid)
2269 {
2270 	const char* sharename = lp_const_servicename(snum);
2271 	const struct loadparm_substitution *lp_sub =
2272 		loadparm_s3_global_substitution();
2273 	struct printjob *pjob;
2274 	bool 	owner;
2275 	WERROR werr;
2276 	TALLOC_CTX *tmp_ctx = talloc_new(msg_ctx);
2277 	if (tmp_ctx == NULL) {
2278 		return WERR_NOT_ENOUGH_MEMORY;
2279 	}
2280 
2281 	owner = is_owner(server_info, lp_const_servicename(snum), jobid);
2282 
2283 	/* Check access against security descriptor or whether the user
2284 	   owns their job. */
2285 
2286 	if (!owner &&
2287 	    !W_ERROR_IS_OK(print_access_check(server_info, msg_ctx, snum,
2288 					      JOB_ACCESS_ADMINISTER))) {
2289 		DEBUG(0, ("print job delete denied."
2290 			  "User name: %s, Printer name: %s.",
2291 			  uidtoname(server_info->unix_token->uid),
2292 			  lp_printername(tmp_ctx, lp_sub, snum)));
2293 
2294 		werr = WERR_ACCESS_DENIED;
2295 		goto err_out;
2296 	}
2297 
2298 	/*
2299 	 * get the spooled filename of the print job
2300 	 * if this works, then the file has not been spooled
2301 	 * to the underlying print system.  Just delete the
2302 	 * spool file & return.
2303 	 */
2304 
2305 	pjob = print_job_find(tmp_ctx, sharename, jobid);
2306 	if (!pjob || pjob->spooled || pjob->pid != getpid()) {
2307 		DEBUG(10, ("Skipping spool file removal for job %u\n", jobid));
2308 	} else {
2309 		DEBUG(10, ("Removing spool file [%s]\n", pjob->filename));
2310 		if (unlink(pjob->filename) == -1) {
2311 			werr = map_werror_from_unix(errno);
2312 			goto err_out;
2313 		}
2314 	}
2315 
2316 	if (!print_job_delete1(global_event_context(), msg_ctx, snum, jobid)) {
2317 		werr = WERR_ACCESS_DENIED;
2318 		goto err_out;
2319 	}
2320 
2321 	/* force update the database and say the delete failed if the
2322            job still exists */
2323 
2324 	print_queue_update(msg_ctx, snum, True);
2325 
2326 	pjob = print_job_find(tmp_ctx, sharename, jobid);
2327 	if (pjob && (pjob->status != LPQ_DELETING)) {
2328 		werr = WERR_ACCESS_DENIED;
2329 		goto err_out;
2330 	}
2331 	werr = WERR_PRINTER_HAS_JOBS_QUEUED;
2332 
2333 err_out:
2334 	talloc_free(tmp_ctx);
2335 	return werr;
2336 }
2337 
2338 /****************************************************************************
2339  Pause a job.
2340 ****************************************************************************/
2341 
print_job_pause(const struct auth_session_info * server_info,struct messaging_context * msg_ctx,int snum,uint32_t jobid)2342 WERROR print_job_pause(const struct auth_session_info *server_info,
2343 		     struct messaging_context *msg_ctx,
2344 		     int snum, uint32_t jobid)
2345 {
2346 	const char* sharename = lp_const_servicename(snum);
2347 	const struct loadparm_substitution *lp_sub =
2348 		loadparm_s3_global_substitution();
2349 	struct printjob *pjob;
2350 	int ret = -1;
2351 	struct printif *current_printif = get_printer_fns( snum );
2352 	WERROR werr;
2353 	TALLOC_CTX *tmp_ctx = talloc_new(msg_ctx);
2354 	if (tmp_ctx == NULL) {
2355 		return WERR_NOT_ENOUGH_MEMORY;
2356 	}
2357 
2358 	pjob = print_job_find(tmp_ctx, sharename, jobid);
2359 	if (!pjob || !server_info) {
2360 		DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2361 			(unsigned int)jobid ));
2362 		werr = WERR_INVALID_PARAMETER;
2363 		goto err_out;
2364 	}
2365 
2366 	if (!pjob->spooled || pjob->sysjob == -1) {
2367 		DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2368 			(int)pjob->sysjob, (unsigned int)jobid ));
2369 		werr = WERR_INVALID_PARAMETER;
2370 		goto err_out;
2371 	}
2372 
2373 	if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2374 	    !W_ERROR_IS_OK(print_access_check(server_info, msg_ctx, snum,
2375 					      JOB_ACCESS_ADMINISTER))) {
2376 		DEBUG(0, ("print job pause denied."
2377 			  "User name: %s, Printer name: %s.",
2378 			  uidtoname(server_info->unix_token->uid),
2379 			  lp_printername(tmp_ctx, lp_sub, snum)));
2380 
2381 		werr = WERR_ACCESS_DENIED;
2382 		goto err_out;
2383 	}
2384 
2385 	/* need to pause the spooled entry */
2386 	ret = (*(current_printif->job_pause))(snum, pjob);
2387 
2388 	if (ret != 0) {
2389 		werr = WERR_INVALID_PARAMETER;
2390 		goto err_out;
2391 	}
2392 
2393 	/* force update the database */
2394 	print_cache_flush(lp_const_servicename(snum));
2395 
2396 	/* Send a printer notify message */
2397 
2398 	notify_job_status(global_event_context(), msg_ctx, sharename, jobid,
2399 			  JOB_STATUS_PAUSED);
2400 
2401 	/* how do we tell if this succeeded? */
2402 	werr = WERR_OK;
2403 err_out:
2404 	talloc_free(tmp_ctx);
2405 	return werr;
2406 }
2407 
2408 /****************************************************************************
2409  Resume a job.
2410 ****************************************************************************/
2411 
print_job_resume(const struct auth_session_info * server_info,struct messaging_context * msg_ctx,int snum,uint32_t jobid)2412 WERROR print_job_resume(const struct auth_session_info *server_info,
2413 		      struct messaging_context *msg_ctx,
2414 		      int snum, uint32_t jobid)
2415 {
2416 	const char *sharename = lp_const_servicename(snum);
2417 	const struct loadparm_substitution *lp_sub =
2418 		loadparm_s3_global_substitution();
2419 	struct printjob *pjob;
2420 	int ret;
2421 	struct printif *current_printif = get_printer_fns( snum );
2422 	WERROR werr;
2423 	TALLOC_CTX *tmp_ctx = talloc_new(msg_ctx);
2424 	if (tmp_ctx == NULL)
2425 		return WERR_NOT_ENOUGH_MEMORY;
2426 
2427 	pjob = print_job_find(tmp_ctx, sharename, jobid);
2428 	if (!pjob || !server_info) {
2429 		DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2430 			(unsigned int)jobid ));
2431 		werr = WERR_INVALID_PARAMETER;
2432 		goto err_out;
2433 	}
2434 
2435 	if (!pjob->spooled || pjob->sysjob == -1) {
2436 		DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2437 			(int)pjob->sysjob, (unsigned int)jobid ));
2438 		werr = WERR_INVALID_PARAMETER;
2439 		goto err_out;
2440 	}
2441 
2442 	if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2443 	    !W_ERROR_IS_OK(print_access_check(server_info, msg_ctx, snum,
2444 					      JOB_ACCESS_ADMINISTER))) {
2445 		DEBUG(0, ("print job resume denied."
2446 			  "User name: %s, Printer name: %s.",
2447 			  uidtoname(server_info->unix_token->uid),
2448 			  lp_printername(tmp_ctx, lp_sub, snum)));
2449 
2450 		werr = WERR_ACCESS_DENIED;
2451 		goto err_out;
2452 	}
2453 
2454 	ret = (*(current_printif->job_resume))(snum, pjob);
2455 
2456 	if (ret != 0) {
2457 		werr = WERR_INVALID_PARAMETER;
2458 		goto err_out;
2459 	}
2460 
2461 	/* force update the database */
2462 	print_cache_flush(lp_const_servicename(snum));
2463 
2464 	/* Send a printer notify message */
2465 
2466 	notify_job_status(global_event_context(), msg_ctx, sharename, jobid,
2467 			  JOB_STATUS_QUEUED);
2468 
2469 	werr = WERR_OK;
2470 err_out:
2471 	talloc_free(tmp_ctx);
2472 	return werr;
2473 }
2474 
2475 /****************************************************************************
2476  Write to a print file.
2477 ****************************************************************************/
2478 
print_job_write(struct tevent_context * ev,struct messaging_context * msg_ctx,int snum,uint32_t jobid,const char * buf,size_t size)2479 ssize_t print_job_write(struct tevent_context *ev,
2480 			struct messaging_context *msg_ctx,
2481 			int snum, uint32_t jobid, const char *buf, size_t size)
2482 {
2483 	const char* sharename = lp_const_servicename(snum);
2484 	ssize_t return_code;
2485 	struct printjob *pjob;
2486 	TALLOC_CTX *tmp_ctx = talloc_new(ev);
2487 	if (tmp_ctx == NULL) {
2488 		return -1;
2489 	}
2490 
2491 	pjob = print_job_find(tmp_ctx, sharename, jobid);
2492 	if (!pjob) {
2493 		return_code = -1;
2494 		goto err_out;
2495 	}
2496 
2497 	/* don't allow another process to get this info - it is meaningless */
2498 	if (pjob->pid != getpid()) {
2499 		return_code = -1;
2500 		goto err_out;
2501 	}
2502 
2503 	/* if SMBD is spooling this can't be allowed */
2504 	if (pjob->status == PJOB_SMBD_SPOOLING) {
2505 		return_code = -1;
2506 		goto err_out;
2507 	}
2508 
2509 	return_code = write_data(pjob->fd, buf, size);
2510 	if (return_code > 0) {
2511 		pjob->size += size;
2512 		pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2513 	}
2514 err_out:
2515 	talloc_free(tmp_ctx);
2516 	return return_code;
2517 }
2518 
2519 /****************************************************************************
2520  Get the queue status - do not update if db is out of date.
2521 ****************************************************************************/
2522 
get_queue_status(const char * sharename,print_status_struct * status)2523 static int get_queue_status(const char* sharename, print_status_struct *status)
2524 {
2525 	fstring keystr;
2526 	TDB_DATA data;
2527 	struct tdb_print_db *pdb = get_print_db_byname(sharename);
2528 	int len;
2529 
2530 	if (status) {
2531 		ZERO_STRUCTP(status);
2532 	}
2533 
2534 	if (!pdb)
2535 		return 0;
2536 
2537 	if (status) {
2538 		fstr_sprintf(keystr, "STATUS/%s", sharename);
2539 		data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2540 		if (data.dptr) {
2541 			if (data.dsize == sizeof(print_status_struct))
2542 				/* this memcpy is ok since the status struct was
2543 				   not packed before storing it in the tdb */
2544 				memcpy(status, data.dptr, sizeof(print_status_struct));
2545 			SAFE_FREE(data.dptr);
2546 		}
2547 	}
2548 	len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2549 	release_print_db(pdb);
2550 	return (len == -1 ? 0 : len);
2551 }
2552 
2553 /****************************************************************************
2554  Determine the number of jobs in a queue.
2555 ****************************************************************************/
2556 
print_queue_length(struct messaging_context * msg_ctx,int snum,print_status_struct * pstatus)2557 int print_queue_length(struct messaging_context *msg_ctx, int snum,
2558 		       print_status_struct *pstatus)
2559 {
2560 	const char* sharename = lp_const_servicename( snum );
2561 	print_status_struct status;
2562 	int len;
2563 
2564 	ZERO_STRUCT( status );
2565 
2566 	/* make sure the database is up to date */
2567 	if (print_cache_expired(lp_const_servicename(snum), True))
2568 		print_queue_update(msg_ctx, snum, False);
2569 
2570 	/* also fetch the queue status */
2571 	memset(&status, 0, sizeof(status));
2572 	len = get_queue_status(sharename, &status);
2573 
2574 	if (pstatus)
2575 		*pstatus = status;
2576 
2577 	return len;
2578 }
2579 
2580 /***************************************************************************
2581  Allocate a jobid. Hold the lock for as short a time as possible.
2582 ***************************************************************************/
2583 
allocate_print_jobid(struct tdb_print_db * pdb,int snum,const char * sharename,uint32_t * pjobid)2584 static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum,
2585 				   const char *sharename, uint32_t *pjobid)
2586 {
2587 	int i;
2588 	uint32_t jobid;
2589 	enum TDB_ERROR terr;
2590 	int ret;
2591 
2592 	*pjobid = (uint32_t)-1;
2593 
2594 	for (i = 0; i < 3; i++) {
2595 		/* Lock the database - only wait 20 seconds. */
2596 		ret = tdb_lock_bystring_with_timeout(pdb->tdb,
2597 						     "INFO/nextjob", 20);
2598 		if (ret != 0) {
2599 			DEBUG(0, ("allocate_print_jobid: "
2600 				  "Failed to lock printing database %s\n",
2601 				  sharename));
2602 			terr = tdb_error(pdb->tdb);
2603 			return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2604 		}
2605 
2606 		if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2607 			terr = tdb_error(pdb->tdb);
2608 			if (terr != TDB_ERR_NOEXIST) {
2609 				DEBUG(0, ("allocate_print_jobid: "
2610 					  "Failed to fetch INFO/nextjob "
2611 					  "for print queue %s\n", sharename));
2612 				tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2613 				return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2614 			}
2615 			DEBUG(10, ("allocate_print_jobid: "
2616 				   "No existing jobid in %s\n", sharename));
2617 			jobid = 0;
2618 		}
2619 
2620 		DEBUG(10, ("allocate_print_jobid: "
2621 			   "Read jobid %u from %s\n", jobid, sharename));
2622 
2623 		jobid = NEXT_JOBID(jobid);
2624 
2625 		ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid);
2626 		if (ret != 0) {
2627 			terr = tdb_error(pdb->tdb);
2628 			DEBUG(3, ("allocate_print_jobid: "
2629 				  "Failed to store INFO/nextjob.\n"));
2630 			tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2631 			return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2632 		}
2633 
2634 		/* We've finished with the INFO/nextjob lock. */
2635 		tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2636 
2637 		if (!print_job_exists(sharename, jobid)) {
2638 			break;
2639 		}
2640 		DEBUG(10, ("allocate_print_jobid: "
2641 			   "Found jobid %u in %s\n", jobid, sharename));
2642 	}
2643 
2644 	if (i > 2) {
2645 		DEBUG(0, ("allocate_print_jobid: "
2646 			  "Failed to allocate a print job for queue %s\n",
2647 			  sharename));
2648 		/* Probably full... */
2649 		return WERR_NO_SPOOL_SPACE;
2650 	}
2651 
2652 	/* Store a dummy placeholder. */
2653 	{
2654 		uint32_t tmp;
2655 		TDB_DATA dum;
2656 		dum.dptr = NULL;
2657 		dum.dsize = 0;
2658 		if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
2659 			      TDB_INSERT) != 0) {
2660 			DEBUG(3, ("allocate_print_jobid: "
2661 				  "jobid (%d) failed to store placeholder.\n",
2662 				  jobid ));
2663 			terr = tdb_error(pdb->tdb);
2664 			return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2665 		}
2666 	}
2667 
2668 	*pjobid = jobid;
2669 	return WERR_OK;
2670 }
2671 
2672 /***************************************************************************
2673  Append a jobid to the 'jobs added' list.
2674 ***************************************************************************/
2675 
add_to_jobs_added(struct tdb_print_db * pdb,uint32_t jobid)2676 static bool add_to_jobs_added(struct tdb_print_db *pdb, uint32_t jobid)
2677 {
2678 	TDB_DATA data;
2679 	uint32_t store_jobid;
2680 
2681 	SIVAL(&store_jobid, 0, jobid);
2682 	data.dptr = (uint8_t *)&store_jobid;
2683 	data.dsize = 4;
2684 
2685 	DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid ));
2686 
2687 	return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_added"),
2688 			   data) == 0);
2689 }
2690 
2691 
2692 /***************************************************************************
2693  Do all checks needed to determine if we can start a job.
2694 ***************************************************************************/
2695 
print_job_checks(const struct auth_session_info * server_info,struct messaging_context * msg_ctx,int snum,int * njobs)2696 static WERROR print_job_checks(const struct auth_session_info *server_info,
2697 			       struct messaging_context *msg_ctx,
2698 			       int snum, int *njobs)
2699 {
2700 	const char *sharename = lp_const_servicename(snum);
2701 	const struct loadparm_substitution *lp_sub =
2702 		loadparm_s3_global_substitution();
2703 	uint64_t dspace, dsize;
2704 	uint64_t minspace;
2705 	int ret;
2706 
2707 	if (!W_ERROR_IS_OK(print_access_check(server_info, msg_ctx, snum,
2708 					      PRINTER_ACCESS_USE))) {
2709 		DEBUG(3, ("print_job_checks: "
2710 			  "job start denied by security descriptor\n"));
2711 		return WERR_ACCESS_DENIED;
2712 	}
2713 
2714 	if (!print_time_access_check(server_info, msg_ctx, sharename)) {
2715 		DEBUG(3, ("print_job_checks: "
2716 			  "job start denied by time check\n"));
2717 		return WERR_ACCESS_DENIED;
2718 	}
2719 
2720 	/* see if we have sufficient disk space */
2721 	if (lp_min_print_space(snum)) {
2722 		minspace = lp_min_print_space(snum);
2723 		ret = sys_fsusage(lp_path(talloc_tos(), lp_sub, snum), &dspace, &dsize);
2724 		if (ret == 0 && dspace < 2*minspace) {
2725 			DEBUG(3, ("print_job_checks: "
2726 				  "disk space check failed.\n"));
2727 			return WERR_NO_SPOOL_SPACE;
2728 		}
2729 	}
2730 
2731 	/* for autoloaded printers, check that the printcap entry still exists */
2732 	if (lp_autoloaded(snum) && !pcap_printername_ok(sharename)) {
2733 		DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2734 			  sharename));
2735 		return WERR_ACCESS_DENIED;
2736 	}
2737 
2738 	/* Insure the maximum queue size is not violated */
2739 	*njobs = print_queue_length(msg_ctx, snum, NULL);
2740 	if (*njobs > lp_maxprintjobs(snum)) {
2741 		DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2742 			  "larger than max printjobs per queue (%d).\n",
2743 			  sharename, *njobs, lp_maxprintjobs(snum)));
2744 		return WERR_NO_SPOOL_SPACE;
2745 	}
2746 
2747 	return WERR_OK;
2748 }
2749 
2750 /***************************************************************************
2751  Create a job file.
2752 ***************************************************************************/
2753 
print_job_spool_file(int snum,uint32_t jobid,const char * output_file,struct printjob * pjob)2754 static WERROR print_job_spool_file(int snum, uint32_t jobid,
2755 				   const char *output_file,
2756 				   struct printjob *pjob)
2757 {
2758 	const struct loadparm_substitution *lp_sub =
2759 		loadparm_s3_global_substitution();
2760 	WERROR werr;
2761 	SMB_STRUCT_STAT st;
2762 	const char *path;
2763 	int len;
2764 	mode_t mask;
2765 
2766 	/* if this file is within the printer path, it means that smbd
2767 	 * is spooling it and will pass us control when it is finished.
2768 	 * Verify that the file name is ok, within path, and it is
2769 	 * already already there */
2770 	if (output_file) {
2771 		path = lp_path(talloc_tos(), lp_sub, snum);
2772 		len = strlen(path);
2773 		if (strncmp(output_file, path, len) == 0 &&
2774 		    (output_file[len - 1] == '/' || output_file[len] == '/')) {
2775 
2776 			/* verify path is not too long */
2777 			if (strlen(output_file) >= sizeof(pjob->filename)) {
2778 				return WERR_INVALID_NAME;
2779 			}
2780 
2781 			/* verify that the file exists */
2782 			if (sys_stat(output_file, &st, false) != 0) {
2783 				return WERR_INVALID_NAME;
2784 			}
2785 
2786 			fstrcpy(pjob->filename, output_file);
2787 
2788 			DEBUG(3, ("print_job_spool_file:"
2789 				  "External spooling activated\n"));
2790 
2791 			/* we do not open the file until spooling is done */
2792 			pjob->fd = -1;
2793 			pjob->status = PJOB_SMBD_SPOOLING;
2794 
2795 			return WERR_OK;
2796 		}
2797 	}
2798 
2799 	slprintf(pjob->filename, sizeof(pjob->filename)-1,
2800 		 "%s/%sXXXXXX", lp_path(talloc_tos(), lp_sub, snum),
2801 		 PRINT_SPOOL_PREFIX);
2802 	mask = umask(S_IRWXO | S_IRWXG);
2803 	pjob->fd = mkstemp(pjob->filename);
2804 	umask(mask);
2805 
2806 	if (pjob->fd == -1) {
2807 		werr = map_werror_from_unix(errno);
2808 		if (W_ERROR_EQUAL(werr, WERR_ACCESS_DENIED)) {
2809 			/* Common setup error, force a report. */
2810 			DEBUG(0, ("print_job_spool_file: "
2811 				  "insufficient permissions to open spool "
2812 				  "file %s.\n", pjob->filename));
2813 		} else {
2814 			/* Normal case, report at level 3 and above. */
2815 			DEBUG(3, ("print_job_spool_file: "
2816 				  "can't open spool file %s\n",
2817 				  pjob->filename));
2818 		}
2819 		return werr;
2820 	}
2821 
2822 	return WERR_OK;
2823 }
2824 
2825 /***************************************************************************
2826  Start spooling a job - return the jobid.
2827 ***************************************************************************/
2828 
print_job_start(const struct auth_session_info * server_info,struct messaging_context * msg_ctx,const char * clientmachine,int snum,const char * docname,const char * filename,struct spoolss_DeviceMode * devmode,uint32_t * _jobid)2829 WERROR print_job_start(const struct auth_session_info *server_info,
2830 		       struct messaging_context *msg_ctx,
2831 		       const char *clientmachine,
2832 		       int snum, const char *docname, const char *filename,
2833 		       struct spoolss_DeviceMode *devmode, uint32_t *_jobid)
2834 {
2835 	uint32_t jobid;
2836 	char *path = NULL, *userstr = NULL;
2837 	struct printjob pjob;
2838 	const char *sharename = lp_const_servicename(snum);
2839 	struct tdb_print_db *pdb = get_print_db_byname(sharename);
2840 	const struct loadparm_substitution *lp_sub =
2841 		loadparm_s3_global_substitution();
2842 	int njobs;
2843 	WERROR werr;
2844 
2845 	if (!pdb) {
2846 		return WERR_INTERNAL_DB_CORRUPTION;
2847 	}
2848 
2849 	path = lp_path(talloc_tos(), lp_sub, snum);
2850 
2851 	werr = print_job_checks(server_info, msg_ctx, snum, &njobs);
2852 	if (!W_ERROR_IS_OK(werr)) {
2853 		release_print_db(pdb);
2854 		return werr;
2855 	}
2856 
2857 	DEBUG(10, ("print_job_start: "
2858 		   "Queue %s number of jobs (%d), max printjobs = %d\n",
2859 		   sharename, njobs, lp_maxprintjobs(snum)));
2860 
2861 	werr = allocate_print_jobid(pdb, snum, sharename, &jobid);
2862 	if (!W_ERROR_IS_OK(werr)) {
2863 		goto fail;
2864 	}
2865 
2866 	/* create the database entry */
2867 
2868 	ZERO_STRUCT(pjob);
2869 
2870 	pjob.pid = getpid();
2871 	pjob.jobid = jobid;
2872 	pjob.sysjob = -1;
2873 	pjob.fd = -1;
2874 	pjob.starttime = time(NULL);
2875 	pjob.status = LPQ_SPOOLING;
2876 	pjob.size = 0;
2877 	pjob.spooled = False;
2878 	pjob.smbjob = True;
2879 	pjob.devmode = devmode;
2880 
2881 	fstrcpy(pjob.jobname, docname);
2882 
2883 	fstrcpy(pjob.clientmachine, clientmachine);
2884 
2885 	userstr = talloc_sub_full(talloc_tos(),
2886 			      sharename,
2887 			      server_info->unix_info->sanitized_username,
2888 			      path, server_info->unix_token->gid,
2889 			      server_info->unix_info->sanitized_username,
2890 			      server_info->info->domain_name,
2891 			      lp_printjob_username(snum));
2892 	if (userstr == NULL) {
2893 		werr = WERR_NOT_ENOUGH_MEMORY;
2894 		goto fail;
2895 	}
2896 	strlcpy(pjob.user, userstr, sizeof(pjob.user));
2897 	TALLOC_FREE(userstr);
2898 
2899 	fstrcpy(pjob.queuename, lp_const_servicename(snum));
2900 
2901 	/* we have a job entry - now create the spool file */
2902 	werr = print_job_spool_file(snum, jobid, filename, &pjob);
2903 	if (!W_ERROR_IS_OK(werr)) {
2904 		goto fail;
2905 	}
2906 
2907 	pjob_store(global_event_context(), msg_ctx, sharename, jobid, &pjob);
2908 
2909 	/* Update the 'jobs added' entry used by print_queue_status. */
2910 	add_to_jobs_added(pdb, jobid);
2911 
2912 	/* Ensure we keep a rough count of the number of total jobs... */
2913 	tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2914 
2915 	release_print_db(pdb);
2916 
2917 	*_jobid = jobid;
2918 	return WERR_OK;
2919 
2920 fail:
2921 	if (jobid != -1) {
2922 		pjob_delete(global_event_context(), msg_ctx, sharename, jobid);
2923 	}
2924 
2925 	release_print_db(pdb);
2926 
2927 	DEBUG(3, ("print_job_start: returning fail. "
2928 		  "Error = %s\n", win_errstr(werr)));
2929 	return werr;
2930 }
2931 
2932 /****************************************************************************
2933  Update the number of pages spooled to jobid
2934 ****************************************************************************/
2935 
print_job_endpage(struct messaging_context * msg_ctx,int snum,uint32_t jobid)2936 void print_job_endpage(struct messaging_context *msg_ctx,
2937 		       int snum, uint32_t jobid)
2938 {
2939 	const char* sharename = lp_const_servicename(snum);
2940 	struct printjob *pjob;
2941 	TALLOC_CTX *tmp_ctx = talloc_new(msg_ctx);
2942 	if (tmp_ctx == NULL) {
2943 		return;
2944 	}
2945 
2946 	pjob = print_job_find(tmp_ctx, sharename, jobid);
2947 	if (!pjob) {
2948 		goto err_out;
2949 	}
2950 	/* don't allow another process to get this info - it is meaningless */
2951 	if (pjob->pid != getpid()) {
2952 		goto err_out;
2953 	}
2954 
2955 	pjob->page_count++;
2956 	pjob_store(global_event_context(), msg_ctx, sharename, jobid, pjob);
2957 err_out:
2958 	talloc_free(tmp_ctx);
2959 }
2960 
2961 /****************************************************************************
2962  Print a file - called on closing the file. This spools the job.
2963  If normal close is false then we're tearing down the jobs - treat as an
2964  error.
2965 ****************************************************************************/
2966 
print_job_end(struct messaging_context * msg_ctx,int snum,uint32_t jobid,enum file_close_type close_type)2967 NTSTATUS print_job_end(struct messaging_context *msg_ctx, int snum,
2968 		       uint32_t jobid, enum file_close_type close_type)
2969 {
2970 	const char* sharename = lp_const_servicename(snum);
2971 	const struct loadparm_substitution *lp_sub =
2972 		loadparm_s3_global_substitution();
2973 	struct printjob *pjob;
2974 	int ret;
2975 	SMB_STRUCT_STAT sbuf;
2976 	struct printif *current_printif = get_printer_fns(snum);
2977 	NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2978 	char *lpq_cmd;
2979 	TALLOC_CTX *tmp_ctx = talloc_new(msg_ctx);
2980 	if (tmp_ctx == NULL) {
2981 		return NT_STATUS_NO_MEMORY;
2982 	}
2983 
2984 	pjob = print_job_find(tmp_ctx, sharename, jobid);
2985 	if (!pjob) {
2986 		status = NT_STATUS_PRINT_CANCELLED;
2987 		goto err_out;
2988 	}
2989 
2990 	if (pjob->spooled || pjob->pid != getpid()) {
2991 		status = NT_STATUS_ACCESS_DENIED;
2992 		goto err_out;
2993 	}
2994 
2995 	if (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) {
2996 		if (pjob->status == PJOB_SMBD_SPOOLING) {
2997 			/* take over the file now, smbd is done */
2998 			if (sys_stat(pjob->filename, &sbuf, false) != 0) {
2999 				status = map_nt_error_from_unix(errno);
3000 				DEBUG(3, ("print_job_end: "
3001 					  "stat file failed for jobid %d\n",
3002 					  jobid));
3003 				goto fail;
3004 			}
3005 
3006 			pjob->status = LPQ_SPOOLING;
3007 
3008 		} else {
3009 
3010 			if ((sys_fstat(pjob->fd, &sbuf, false) != 0)) {
3011 				status = map_nt_error_from_unix(errno);
3012 				close(pjob->fd);
3013 				DEBUG(3, ("print_job_end: "
3014 					  "stat file failed for jobid %d\n",
3015 					  jobid));
3016 				goto fail;
3017 			}
3018 
3019 			close(pjob->fd);
3020 		}
3021 
3022 		pjob->size = sbuf.st_ex_size;
3023 	} else {
3024 
3025 		/*
3026 		 * Not a normal close, something has gone wrong. Cleanup.
3027 		 */
3028 		if (pjob->fd != -1) {
3029 			close(pjob->fd);
3030 		}
3031 		goto fail;
3032 	}
3033 
3034 	/* Technically, this is not quite right. If the printer has a separator
3035 	 * page turned on, the NT spooler prints the separator page even if the
3036 	 * print job is 0 bytes. 010215 JRR */
3037 	if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
3038 		/* don't bother spooling empty files or something being deleted. */
3039 		DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
3040 			pjob->filename, pjob->size ? "deleted" : "zero length" ));
3041 		unlink(pjob->filename);
3042 		pjob_delete(global_event_context(), msg_ctx, sharename, jobid);
3043 		return NT_STATUS_OK;
3044 	}
3045 
3046 	/* don't strip out characters like '$' from the printername */
3047 	lpq_cmd = talloc_string_sub2(tmp_ctx,
3048 				     lp_lpq_command(snum),
3049 				     "%p",
3050 				     lp_printername(talloc_tos(), lp_sub, snum),
3051 				     false, false, false);
3052 	if (lpq_cmd == NULL) {
3053 		status = NT_STATUS_PRINT_CANCELLED;
3054 		goto fail;
3055 	}
3056 	lpq_cmd = talloc_sub_full(tmp_ctx,
3057 				      lp_servicename(talloc_tos(), lp_sub, snum),
3058 				      current_user_info.unix_name,
3059 				      "",
3060 				      get_current_gid(NULL),
3061 				      get_current_username(),
3062 				      current_user_info.domain,
3063 				      lpq_cmd);
3064 	if (lpq_cmd == NULL) {
3065 		status = NT_STATUS_PRINT_CANCELLED;
3066 		goto fail;
3067 	}
3068 
3069 	ret = (*(current_printif->job_submit))(snum, pjob,
3070 					       current_printif->type, lpq_cmd);
3071 	if (ret) {
3072 		status = NT_STATUS_PRINT_CANCELLED;
3073 		goto fail;
3074 	}
3075 
3076 	/* The print job has been successfully handed over to the back-end */
3077 
3078 	pjob->spooled = True;
3079 	pjob->status = LPQ_QUEUED;
3080 	pjob_store(global_event_context(), msg_ctx, sharename, jobid, pjob);
3081 
3082 	/* make sure the database is up to date */
3083 	if (print_cache_expired(lp_const_servicename(snum), True))
3084 		print_queue_update(msg_ctx, snum, False);
3085 
3086 	return NT_STATUS_OK;
3087 
3088 fail:
3089 
3090 	/* The print job was not successfully started. Cleanup */
3091 	/* Still need to add proper error return propagation! 010122:JRR */
3092 	pjob->fd = -1;
3093 	unlink(pjob->filename);
3094 	pjob_delete(global_event_context(), msg_ctx, sharename, jobid);
3095 err_out:
3096 	talloc_free(tmp_ctx);
3097 	return status;
3098 }
3099 
3100 /****************************************************************************
3101  Get a snapshot of jobs in the system without traversing.
3102 ****************************************************************************/
3103 
get_stored_queue_info(struct messaging_context * msg_ctx,struct tdb_print_db * pdb,int snum,int * pcount,print_queue_struct ** ppqueue)3104 static bool get_stored_queue_info(struct messaging_context *msg_ctx,
3105 				  struct tdb_print_db *pdb, int snum,
3106 				  int *pcount, print_queue_struct **ppqueue)
3107 {
3108 	const struct loadparm_substitution *lp_sub =
3109 		loadparm_s3_global_substitution();
3110 	TDB_DATA data, cgdata, jcdata;
3111 	print_queue_struct *queue = NULL;
3112 	uint32_t qcount = 0;
3113 	uint32_t extra_count = 0;
3114 	uint32_t changed_count = 0;
3115 	int total_count = 0;
3116 	size_t len = 0;
3117 	uint32_t i;
3118 	int max_reported_jobs = lp_max_reported_print_jobs(snum);
3119 	bool ret = false;
3120 	const char* sharename = lp_servicename(talloc_tos(), lp_sub, snum);
3121 	TALLOC_CTX *tmp_ctx = talloc_new(msg_ctx);
3122 	if (tmp_ctx == NULL) {
3123 		return false;
3124 	}
3125 
3126 	/* make sure the database is up to date */
3127 	if (print_cache_expired(lp_const_servicename(snum), True))
3128 		print_queue_update(msg_ctx, snum, False);
3129 
3130 	*pcount = 0;
3131 	*ppqueue = NULL;
3132 
3133 	ZERO_STRUCT(data);
3134 	ZERO_STRUCT(cgdata);
3135 
3136 	/* Get the stored queue data. */
3137 	data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
3138 
3139 	if (data.dptr && data.dsize >= sizeof(qcount))
3140 		len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
3141 
3142 	/* Get the added jobs list. */
3143 	cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added"));
3144 	if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
3145 		extra_count = cgdata.dsize/4;
3146 
3147 	/* Get the changed jobs list. */
3148 	jcdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
3149 	if (jcdata.dptr != NULL && (jcdata.dsize % 4 == 0))
3150 		changed_count = jcdata.dsize / 4;
3151 
3152 	DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
3153 
3154 	/* Allocate the queue size. */
3155 	if (qcount == 0 && extra_count == 0)
3156 		goto out;
3157 
3158 	if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
3159 		goto out;
3160 
3161 	/* Retrieve the linearised queue data. */
3162 
3163 	for(i = 0; i < qcount; i++) {
3164 		uint32_t qjob, qsize, qpage_count, qstatus, qpriority, qtime;
3165 		len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
3166 				&qjob,
3167 				&qsize,
3168 				&qpage_count,
3169 				&qstatus,
3170 				&qpriority,
3171 				&qtime,
3172 				queue[i].fs_user,
3173 				queue[i].fs_file);
3174 		queue[i].sysjob = qjob;
3175 		queue[i].size = qsize;
3176 		queue[i].page_count = qpage_count;
3177 		queue[i].status = qstatus;
3178 		queue[i].priority = qpriority;
3179 		queue[i].time = qtime;
3180 	}
3181 
3182 	total_count = qcount;
3183 
3184 	/* Add new jobids to the queue. */
3185 	for (i = 0; i < extra_count; i++) {
3186 		uint32_t jobid;
3187 		struct printjob *pjob;
3188 
3189 		jobid = IVAL(cgdata.dptr, i*4);
3190 		DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid));
3191 		pjob = print_job_find(tmp_ctx, lp_const_servicename(snum), jobid);
3192 		if (!pjob) {
3193 			DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid));
3194 			remove_from_jobs_added(sharename, jobid);
3195 			continue;
3196 		}
3197 
3198 		queue[total_count].sysjob = pjob->sysjob;
3199 		queue[total_count].size = pjob->size;
3200 		queue[total_count].page_count = pjob->page_count;
3201 		queue[total_count].status = pjob->status;
3202 		queue[total_count].priority = 1;
3203 		queue[total_count].time = pjob->starttime;
3204 		fstrcpy(queue[total_count].fs_user, pjob->user);
3205 		fstrcpy(queue[total_count].fs_file, pjob->jobname);
3206 		total_count++;
3207 		talloc_free(pjob);
3208 	}
3209 
3210 	/* Update the changed jobids. */
3211 	for (i = 0; i < changed_count; i++) {
3212 		uint32_t jobid = IVAL(jcdata.dptr, i * 4);
3213 		struct printjob *pjob;
3214 		uint32_t j;
3215 		bool found = false;
3216 
3217 		pjob = print_job_find(tmp_ctx, sharename, jobid);
3218 		if (pjob == NULL) {
3219 			DEBUG(5,("get_stored_queue_info: failed to find "
3220 				 "changed job = %u\n",
3221 				 (unsigned int)jobid));
3222 			remove_from_jobs_changed(sharename, jobid);
3223 			continue;
3224 		}
3225 
3226 		for (j = 0; j < total_count; j++) {
3227 			if (queue[j].sysjob == pjob->sysjob) {
3228 				found = true;
3229 				break;
3230 			}
3231 		}
3232 
3233 		if (found) {
3234 			DEBUG(5,("get_stored_queue_info: changed job: %u\n",
3235 				 (unsigned int)jobid));
3236 
3237 			queue[j].sysjob = pjob->sysjob;
3238 			queue[j].size = pjob->size;
3239 			queue[j].page_count = pjob->page_count;
3240 			queue[j].status = pjob->status;
3241 			queue[j].priority = 1;
3242 			queue[j].time = pjob->starttime;
3243 			fstrcpy(queue[j].fs_user, pjob->user);
3244 			fstrcpy(queue[j].fs_file, pjob->jobname);
3245 			talloc_free(pjob);
3246 
3247 			DEBUG(5,("updated queue[%u], jobid: %u, sysjob: %u, "
3248 				 "jobname: %s\n",
3249 				 (unsigned int)j, (unsigned int)jobid,
3250 				 (unsigned int)queue[j].sysjob, pjob->jobname));
3251 		}
3252 
3253 		remove_from_jobs_changed(sharename, jobid);
3254 	}
3255 
3256 	/* Sort the queue by submission time otherwise they are displayed
3257 	   in hash order. */
3258 
3259 	TYPESAFE_QSORT(queue, total_count, printjob_comp);
3260 
3261 	DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
3262 
3263 	if (max_reported_jobs && total_count > max_reported_jobs)
3264 		total_count = max_reported_jobs;
3265 
3266 	*ppqueue = queue;
3267 	*pcount = total_count;
3268 
3269 	ret = true;
3270 
3271   out:
3272 
3273 	SAFE_FREE(data.dptr);
3274 	SAFE_FREE(cgdata.dptr);
3275 	talloc_free(tmp_ctx);
3276 	return ret;
3277 }
3278 
3279 /****************************************************************************
3280  Get a printer queue listing.
3281  set queue = NULL and status = NULL if you just want to update the cache
3282 ****************************************************************************/
3283 
print_queue_status(struct messaging_context * msg_ctx,int snum,print_queue_struct ** ppqueue,print_status_struct * status)3284 int print_queue_status(struct messaging_context *msg_ctx, int snum,
3285 		       print_queue_struct **ppqueue,
3286 		       print_status_struct *status)
3287 {
3288 	fstring keystr;
3289 	TDB_DATA data, key;
3290 	const char *sharename;
3291 	struct tdb_print_db *pdb;
3292 	int count = 0;
3293 
3294 	/* make sure the database is up to date */
3295 
3296 	if (print_cache_expired(lp_const_servicename(snum), True))
3297 		print_queue_update(msg_ctx, snum, False);
3298 
3299 	/* return if we are done */
3300 	if ( !ppqueue || !status )
3301 		return 0;
3302 
3303 	*ppqueue = NULL;
3304 	sharename = lp_const_servicename(snum);
3305 	pdb = get_print_db_byname(sharename);
3306 
3307 	if (!pdb)
3308 		return 0;
3309 
3310 	/*
3311 	 * Fetch the queue status.  We must do this first, as there may
3312 	 * be no jobs in the queue.
3313 	 */
3314 
3315 	ZERO_STRUCTP(status);
3316 	slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
3317 	key = string_tdb_data(keystr);
3318 
3319 	data = tdb_fetch(pdb->tdb, key);
3320 	if (data.dptr) {
3321 		if (data.dsize == sizeof(*status)) {
3322 			/* this memcpy is ok since the status struct was
3323 			   not packed before storing it in the tdb */
3324 			memcpy(status, data.dptr, sizeof(*status));
3325 		}
3326 		SAFE_FREE(data.dptr);
3327 	}
3328 
3329 	/*
3330 	 * Now, fetch the print queue information.  We first count the number
3331 	 * of entries, and then only retrieve the queue if necessary.
3332 	 */
3333 
3334 	if (!get_stored_queue_info(msg_ctx, pdb, snum, &count, ppqueue)) {
3335 		release_print_db(pdb);
3336 		return 0;
3337 	}
3338 
3339 	release_print_db(pdb);
3340 	return count;
3341 }
3342 
3343 /****************************************************************************
3344  Pause a queue.
3345 ****************************************************************************/
3346 
print_queue_pause(const struct auth_session_info * server_info,struct messaging_context * msg_ctx,int snum)3347 WERROR print_queue_pause(const struct auth_session_info *server_info,
3348 			 struct messaging_context *msg_ctx, int snum)
3349 {
3350 	int ret;
3351 	struct printif *current_printif = get_printer_fns( snum );
3352 
3353 	if (!W_ERROR_IS_OK(print_access_check(server_info, msg_ctx, snum,
3354 					      PRINTER_ACCESS_ADMINISTER))) {
3355 		return WERR_ACCESS_DENIED;
3356 	}
3357 
3358 
3359 	become_root();
3360 
3361 	ret = (*(current_printif->queue_pause))(snum);
3362 
3363 	unbecome_root();
3364 
3365 	if (ret != 0) {
3366 		return WERR_INVALID_PARAMETER;
3367 	}
3368 
3369 	/* force update the database */
3370 	print_cache_flush(lp_const_servicename(snum));
3371 
3372 	/* Send a printer notify message */
3373 
3374 	notify_printer_status(global_event_context(), msg_ctx, snum,
3375 			      PRINTER_STATUS_PAUSED);
3376 
3377 	return WERR_OK;
3378 }
3379 
3380 /****************************************************************************
3381  Resume a queue.
3382 ****************************************************************************/
3383 
print_queue_resume(const struct auth_session_info * server_info,struct messaging_context * msg_ctx,int snum)3384 WERROR print_queue_resume(const struct auth_session_info *server_info,
3385 			  struct messaging_context *msg_ctx, int snum)
3386 {
3387 	int ret;
3388 	struct printif *current_printif = get_printer_fns( snum );
3389 
3390 	if (!W_ERROR_IS_OK(print_access_check(server_info, msg_ctx, snum,
3391 					      PRINTER_ACCESS_ADMINISTER))) {
3392 		return WERR_ACCESS_DENIED;
3393 	}
3394 
3395 	become_root();
3396 
3397 	ret = (*(current_printif->queue_resume))(snum);
3398 
3399 	unbecome_root();
3400 
3401 	if (ret != 0) {
3402 		return WERR_INVALID_PARAMETER;
3403 	}
3404 
3405 	/* make sure the database is up to date */
3406 	if (print_cache_expired(lp_const_servicename(snum), True))
3407 		print_queue_update(msg_ctx, snum, True);
3408 
3409 	/* Send a printer notify message */
3410 
3411 	notify_printer_status(global_event_context(), msg_ctx, snum,
3412 			      PRINTER_STATUS_OK);
3413 
3414 	return WERR_OK;
3415 }
3416 
3417 /****************************************************************************
3418  Purge a queue - implemented by deleting all jobs that we can delete.
3419 ****************************************************************************/
3420 
print_queue_purge(const struct auth_session_info * server_info,struct messaging_context * msg_ctx,int snum)3421 WERROR print_queue_purge(const struct auth_session_info *server_info,
3422 			 struct messaging_context *msg_ctx, int snum)
3423 {
3424 	print_queue_struct *queue;
3425 	print_status_struct status;
3426 	int njobs, i;
3427 	bool can_job_admin;
3428 
3429 	/* Force and update so the count is accurate (i.e. not a cached count) */
3430 	print_queue_update(msg_ctx, snum, True);
3431 
3432 	can_job_admin = W_ERROR_IS_OK(print_access_check(server_info,
3433 							 msg_ctx,
3434 							 snum,
3435 							JOB_ACCESS_ADMINISTER));
3436 	njobs = print_queue_status(msg_ctx, snum, &queue, &status);
3437 
3438 	if ( can_job_admin )
3439 		become_root();
3440 
3441 	for (i = 0; i < njobs; i++) {
3442 		struct tdb_print_db *pdb;
3443 		int jobid;
3444 		bool owner;
3445 		pdb = get_print_db_byname(lp_const_servicename(snum));
3446 		if (pdb == NULL) {
3447 			DEBUG(1, ("failed to find printdb for %s\n",
3448 				  lp_const_servicename(snum)));
3449 			continue;
3450 		}
3451 		jobid = sysjob_to_jobid_pdb(pdb, queue[i].sysjob);
3452 		if (jobid == (uint32_t)-1) {
3453 			DEBUG(2, ("jobid for system job %d not found\n",
3454 				  queue[i].sysjob));
3455 			continue;	/* unix job */
3456 		}
3457 		owner = is_owner(server_info, lp_const_servicename(snum),
3458 				 jobid);
3459 
3460 		if (owner || can_job_admin) {
3461 			print_job_delete1(global_event_context(), msg_ctx,
3462 					  snum, jobid);
3463 		}
3464 	}
3465 
3466 	if ( can_job_admin )
3467 		unbecome_root();
3468 
3469 	/* update the cache */
3470 	print_queue_update(msg_ctx, snum, True);
3471 
3472 	SAFE_FREE(queue);
3473 
3474 	return WERR_OK;
3475 }
3476