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 2 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, write to the Free Software
20   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23#include "includes.h"
24#include "printing.h"
25
26extern SIG_ATOMIC_T got_sig_term;
27extern SIG_ATOMIC_T reload_after_sighup;
28
29/* Current printer interface */
30static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid);
31
32/*
33   the printing backend revolves around a tdb database that stores the
34   SMB view of the print queue
35
36   The key for this database is a jobid - a internally generated number that
37   uniquely identifies a print job
38
39   reading the print queue involves two steps:
40     - possibly running lpq and updating the internal database from that
41     - reading entries from the database
42
43   jobids are assigned when a job starts spooling.
44*/
45
46struct print_queue_update_context {
47	char* sharename;
48	enum printing_types printing_type;
49	char* lpqcommand;
50};
51
52
53static TDB_CONTEXT *rap_tdb;
54static uint16 next_rap_jobid;
55struct rap_jobid_key {
56	fstring sharename;
57	uint32  jobid;
58};
59
60/***************************************************************************
61 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
62 bit RPC jobids.... JRA.
63***************************************************************************/
64
65uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
66{
67	uint16 rap_jobid;
68	TDB_DATA data, key;
69	struct rap_jobid_key jinfo;
70
71	DEBUG(10,("pjobid_to_rap: called.\n"));
72
73	if (!rap_tdb) {
74		/* Create the in-memory tdb. */
75		rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
76		if (!rap_tdb)
77			return 0;
78	}
79
80	ZERO_STRUCT( jinfo );
81	fstrcpy( jinfo.sharename, sharename );
82	jinfo.jobid = jobid;
83	key.dptr = (char*)&jinfo;
84	key.dsize = sizeof(jinfo);
85
86	data = tdb_fetch(rap_tdb, key);
87	if (data.dptr && data.dsize == sizeof(uint16)) {
88		rap_jobid = SVAL(data.dptr, 0);
89		SAFE_FREE(data.dptr);
90		DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
91			(unsigned int)jobid, (unsigned int)rap_jobid));
92		return rap_jobid;
93	}
94	SAFE_FREE(data.dptr);
95	/* Not found - create and store mapping. */
96	rap_jobid = ++next_rap_jobid;
97	if (rap_jobid == 0)
98		rap_jobid = ++next_rap_jobid;
99	data.dptr = (char *)&rap_jobid;
100	data.dsize = sizeof(rap_jobid);
101	tdb_store(rap_tdb, key, data, TDB_REPLACE);
102	tdb_store(rap_tdb, data, key, TDB_REPLACE);
103
104	DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
105		(unsigned int)jobid, (unsigned int)rap_jobid));
106	return rap_jobid;
107}
108
109BOOL rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
110{
111	TDB_DATA data, key;
112
113	DEBUG(10,("rap_to_pjobid called.\n"));
114
115	if (!rap_tdb)
116		return False;
117
118	key.dptr = (char *)&rap_jobid;
119	key.dsize = sizeof(rap_jobid);
120	data = tdb_fetch(rap_tdb, key);
121	if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) )
122	{
123		struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
124		fstrcpy( sharename, jinfo->sharename );
125		*pjobid = jinfo->jobid;
126		DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
127			(unsigned int)*pjobid, (unsigned int)rap_jobid));
128		SAFE_FREE(data.dptr);
129		return True;
130	}
131
132	DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
133		(unsigned int)rap_jobid));
134	SAFE_FREE(data.dptr);
135	return False;
136}
137
138static void rap_jobid_delete(const char* sharename, uint32 jobid)
139{
140	TDB_DATA key, data;
141	uint16 rap_jobid;
142	struct rap_jobid_key jinfo;
143
144	DEBUG(10,("rap_jobid_delete: called.\n"));
145
146	if (!rap_tdb)
147		return;
148
149	ZERO_STRUCT( jinfo );
150	fstrcpy( jinfo.sharename, sharename );
151	jinfo.jobid = jobid;
152	key.dptr = (char*)&jinfo;
153	key.dsize = sizeof(jinfo);
154
155	data = tdb_fetch(rap_tdb, key);
156	if (!data.dptr || (data.dsize != sizeof(uint16))) {
157		DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
158			(unsigned int)jobid ));
159		SAFE_FREE(data.dptr);
160		return;
161	}
162
163	DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
164		(unsigned int)jobid ));
165
166	rap_jobid = SVAL(data.dptr, 0);
167	SAFE_FREE(data.dptr);
168	data.dptr = (char *)&rap_jobid;
169	data.dsize = sizeof(rap_jobid);
170	tdb_delete(rap_tdb, key);
171	tdb_delete(rap_tdb, data);
172}
173
174static int get_queue_status(const char* sharename, print_status_struct *);
175
176/****************************************************************************
177 Initialise the printing backend. Called once at startup before the fork().
178****************************************************************************/
179
180BOOL print_backend_init(void)
181{
182	const char *sversion = "INFO/version";
183	pstring printing_path;
184	int services = lp_numservices();
185	int snum;
186
187	unlink(lock_path("printing.tdb"));
188	pstrcpy(printing_path,lock_path("printing"));
189	mkdir(printing_path,0755);
190
191	/* handle a Samba upgrade */
192
193	for (snum = 0; snum < services; snum++) {
194		struct tdb_print_db *pdb;
195		if (!lp_print_ok(snum))
196			continue;
197
198		pdb = get_print_db_byname(lp_const_servicename(snum));
199		if (!pdb)
200			continue;
201		if (tdb_lock_bystring(pdb->tdb, sversion, 0) == -1) {
202			DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
203			release_print_db(pdb);
204			return False;
205		}
206		if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
207			tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL);
208			tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
209		}
210		tdb_unlock_bystring(pdb->tdb, sversion);
211		release_print_db(pdb);
212	}
213
214	close_all_print_db(); /* Don't leave any open. */
215
216	/* do NT print initialization... */
217	return nt_printing_init();
218}
219
220/****************************************************************************
221 Shut down printing backend. Called once at shutdown to close the tdb.
222****************************************************************************/
223
224void printing_end(void)
225{
226	close_all_print_db(); /* Don't leave any open. */
227}
228
229/****************************************************************************
230 Retrieve the set of printing functions for a given service.  This allows
231 us to set the printer function table based on the value of the 'printing'
232 service parameter.
233
234 Use the generic interface as the default and only use cups interface only
235 when asked for (and only when supported)
236****************************************************************************/
237
238static struct printif *get_printer_fns_from_type( enum printing_types type )
239{
240	struct printif *printer_fns = &generic_printif;
241
242#ifdef HAVE_CUPS
243	if ( type == PRINT_CUPS ) {
244		printer_fns = &cups_printif;
245	}
246#endif /* HAVE_CUPS */
247
248	printer_fns->type = type;
249
250	return printer_fns;
251}
252
253static struct printif *get_printer_fns( int snum )
254{
255	return get_printer_fns_from_type( lp_printing(snum) );
256}
257
258
259/****************************************************************************
260 Useful function to generate a tdb key.
261****************************************************************************/
262
263static TDB_DATA print_key(uint32 jobid)
264{
265	static uint32 j;
266	TDB_DATA ret;
267
268	SIVAL(&j, 0, jobid);
269	ret.dptr = (void *)&j;
270	ret.dsize = sizeof(j);
271	return ret;
272}
273
274/***********************************************************************
275 unpack a pjob from a tdb buffer
276***********************************************************************/
277
278int unpack_pjob( char* buf, int buflen, struct printjob *pjob )
279{
280	int	len = 0;
281	int	used;
282	uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
283	uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
284
285	if ( !buf || !pjob )
286		return -1;
287
288	len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
289				&pjpid,
290				&pjsysjob,
291				&pjfd,
292				&pjstarttime,
293				&pjstatus,
294				&pjsize,
295				&pjpage_count,
296				&pjspooled,
297				&pjsmbjob,
298				pjob->filename,
299				pjob->jobname,
300				pjob->user,
301				pjob->queuename);
302
303	if ( len == -1 )
304		return -1;
305
306	if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 )
307		return -1;
308
309	len += used;
310
311	pjob->pid = pjpid;
312	pjob->sysjob = pjsysjob;
313	pjob->fd = pjfd;
314	pjob->starttime = pjstarttime;
315	pjob->status = pjstatus;
316	pjob->size = pjsize;
317	pjob->page_count = pjpage_count;
318	pjob->spooled = pjspooled;
319	pjob->smbjob = pjsmbjob;
320
321	return len;
322
323}
324
325/****************************************************************************
326 Useful function to find a print job in the database.
327****************************************************************************/
328
329static struct printjob *print_job_find(const char *sharename, uint32 jobid)
330{
331	static struct printjob 	pjob;
332	TDB_DATA 		ret;
333	struct tdb_print_db 	*pdb = get_print_db_byname(sharename);
334
335
336	if (!pdb)
337		return NULL;
338
339	ret = tdb_fetch(pdb->tdb, print_key(jobid));
340	release_print_db(pdb);
341
342	if (!ret.dptr)
343		return NULL;
344
345	if ( pjob.nt_devmode )
346		free_nt_devicemode( &pjob.nt_devmode );
347
348	ZERO_STRUCT( pjob );
349
350	if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
351		SAFE_FREE(ret.dptr);
352		return NULL;
353	}
354
355	SAFE_FREE(ret.dptr);
356	return &pjob;
357}
358
359/* Convert a unix jobid to a smb jobid */
360
361static uint32 sysjob_to_jobid_value;
362
363static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
364			       TDB_DATA data, void *state)
365{
366	struct printjob *pjob;
367	int *sysjob = (int *)state;
368
369	if (!data.dptr || data.dsize == 0)
370		return 0;
371
372	pjob = (struct printjob *)data.dptr;
373	if (key.dsize != sizeof(uint32))
374		return 0;
375
376	if (*sysjob == pjob->sysjob) {
377		uint32 jobid = IVAL(key.dptr,0);
378
379		sysjob_to_jobid_value = jobid;
380		return 1;
381	}
382
383	return 0;
384}
385
386/****************************************************************************
387 This is a *horribly expensive call as we have to iterate through all the
388 current printer tdb's. Don't do this often ! JRA.
389****************************************************************************/
390
391uint32 sysjob_to_jobid(int unix_jobid)
392{
393	int services = lp_numservices();
394	int snum;
395
396	sysjob_to_jobid_value = (uint32)-1;
397
398	for (snum = 0; snum < services; snum++) {
399		struct tdb_print_db *pdb;
400		if (!lp_print_ok(snum))
401			continue;
402		pdb = get_print_db_byname(lp_const_servicename(snum));
403		if (pdb)
404			tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
405		release_print_db(pdb);
406		if (sysjob_to_jobid_value != (uint32)-1)
407			return sysjob_to_jobid_value;
408	}
409	return (uint32)-1;
410}
411
412/****************************************************************************
413 Send notifications based on what has changed after a pjob_store.
414****************************************************************************/
415
416static struct {
417	uint32 lpq_status;
418	uint32 spoolss_status;
419} lpq_to_spoolss_status_map[] = {
420	{ LPQ_QUEUED, JOB_STATUS_QUEUED },
421	{ LPQ_PAUSED, JOB_STATUS_PAUSED },
422	{ LPQ_SPOOLING, JOB_STATUS_SPOOLING },
423	{ LPQ_PRINTING, JOB_STATUS_PRINTING },
424	{ LPQ_DELETING, JOB_STATUS_DELETING },
425	{ LPQ_OFFLINE, JOB_STATUS_OFFLINE },
426	{ LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
427	{ LPQ_PRINTED, JOB_STATUS_PRINTED },
428	{ LPQ_DELETED, JOB_STATUS_DELETED },
429	{ LPQ_BLOCKED, JOB_STATUS_BLOCKED },
430	{ LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
431	{ -1, 0 }
432};
433
434/* Convert a lpq status value stored in printing.tdb into the
435   appropriate win32 API constant. */
436
437static uint32 map_to_spoolss_status(uint32 lpq_status)
438{
439	int i = 0;
440
441	while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
442		if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
443			return lpq_to_spoolss_status_map[i].spoolss_status;
444		i++;
445	}
446
447	return 0;
448}
449
450static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data,
451			      struct printjob *new_data)
452{
453	BOOL new_job = False;
454
455	if (!old_data)
456		new_job = True;
457
458	/* Job attributes that can't be changed.  We only send
459	   notification for these on a new job. */
460
461 	/* ACHTUNG!  Due to a bug in Samba's spoolss parsing of the
462 	   NOTIFY_INFO_DATA buffer, we *have* to send the job submission
463 	   time first or else we'll end up with potential alignment
464 	   errors.  I don't think the systemtime should be spooled as
465 	   a string, but this gets us around that error.
466 	   --jerry (i'll feel dirty for this) */
467
468	if (new_job) {
469		notify_job_submitted(sharename, jobid, new_data->starttime);
470		notify_job_username(sharename, jobid, new_data->user);
471	}
472
473	if (new_job || !strequal(old_data->jobname, new_data->jobname))
474		notify_job_name(sharename, jobid, new_data->jobname);
475
476	/* Job attributes of a new job or attributes that can be
477	   modified. */
478
479	if (new_job || !strequal(old_data->jobname, new_data->jobname))
480		notify_job_name(sharename, jobid, new_data->jobname);
481
482	if (new_job || old_data->status != new_data->status)
483		notify_job_status(sharename, jobid, map_to_spoolss_status(new_data->status));
484
485	if (new_job || old_data->size != new_data->size)
486		notify_job_total_bytes(sharename, jobid, new_data->size);
487
488	if (new_job || old_data->page_count != new_data->page_count)
489		notify_job_total_pages(sharename, jobid, new_data->page_count);
490}
491
492/****************************************************************************
493 Store a job structure back to the database.
494****************************************************************************/
495
496static BOOL pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob)
497{
498	TDB_DATA 		old_data, new_data;
499	BOOL 			ret = False;
500	struct tdb_print_db 	*pdb = get_print_db_byname(sharename);
501	char			*buf = NULL;
502	int			len, newlen, buflen;
503
504
505	if (!pdb)
506		return False;
507
508	/* Get old data */
509
510	old_data = tdb_fetch(pdb->tdb, print_key(jobid));
511
512	/* Doh!  Now we have to pack/unpack data since the NT_DEVICEMODE was added */
513
514	newlen = 0;
515
516	do {
517		len = 0;
518		buflen = newlen;
519		len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
520				(uint32)pjob->pid,
521				(uint32)pjob->sysjob,
522				(uint32)pjob->fd,
523				(uint32)pjob->starttime,
524				(uint32)pjob->status,
525				(uint32)pjob->size,
526				(uint32)pjob->page_count,
527				(uint32)pjob->spooled,
528				(uint32)pjob->smbjob,
529				pjob->filename,
530				pjob->jobname,
531				pjob->user,
532				pjob->queuename);
533
534		len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len);
535
536		if (buflen != len) {
537			char *tb;
538
539			tb = (char *)SMB_REALLOC(buf, len);
540			if (!tb) {
541				DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
542				goto done;
543			}
544			else
545				buf = tb;
546			newlen = len;
547		}
548	} while ( buflen != len );
549
550
551	/* Store new data */
552
553	new_data.dptr = buf;
554	new_data.dsize = len;
555	ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0);
556
557	release_print_db(pdb);
558
559	/* Send notify updates for what has changed */
560
561	if ( ret ) {
562		struct printjob old_pjob;
563
564		if ( old_data.dsize )
565		{
566			if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
567			{
568				pjob_store_notify( sharename, jobid, &old_pjob , pjob );
569				free_nt_devicemode( &old_pjob.nt_devmode );
570			}
571		}
572		else {
573			/* new job */
574			pjob_store_notify( sharename, jobid, NULL, pjob );
575		}
576	}
577
578done:
579	SAFE_FREE( old_data.dptr );
580	SAFE_FREE( buf );
581
582	return ret;
583}
584
585/****************************************************************************
586 Remove a job structure from the database.
587****************************************************************************/
588
589void pjob_delete(const char* sharename, uint32 jobid)
590{
591	struct printjob *pjob;
592	uint32 job_status = 0;
593	struct tdb_print_db *pdb;
594
595	pdb = get_print_db_byname( sharename );
596
597	if (!pdb)
598		return;
599
600	pjob = print_job_find( sharename, jobid );
601
602	if (!pjob) {
603		DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
604					(unsigned int)jobid));
605		release_print_db(pdb);
606		return;
607	}
608
609	/* We must cycle through JOB_STATUS_DELETING and
610           JOB_STATUS_DELETED for the port monitor to delete the job
611           properly. */
612
613	job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
614	notify_job_status(sharename, jobid, job_status);
615
616	/* Remove from printing.tdb */
617
618	tdb_delete(pdb->tdb, print_key(jobid));
619	remove_from_jobs_changed(sharename, jobid);
620	release_print_db( pdb );
621	rap_jobid_delete(sharename, jobid);
622}
623
624/****************************************************************************
625 Parse a file name from the system spooler to generate a jobid.
626****************************************************************************/
627
628static uint32 print_parse_jobid(char *fname)
629{
630	int jobid;
631
632	if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0)
633		return (uint32)-1;
634	fname += strlen(PRINT_SPOOL_PREFIX);
635
636	jobid = atoi(fname);
637	if (jobid <= 0)
638		return (uint32)-1;
639
640	return (uint32)jobid;
641}
642
643/****************************************************************************
644 List a unix job in the print database.
645****************************************************************************/
646
647static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid)
648{
649	struct printjob pj, *old_pj;
650
651	if (jobid == (uint32)-1)
652		jobid = q->job + UNIX_JOB_START;
653
654	/* Preserve the timestamp on an existing unix print job */
655
656	old_pj = print_job_find(sharename, jobid);
657
658	ZERO_STRUCT(pj);
659
660	pj.pid = (pid_t)-1;
661	pj.sysjob = q->job;
662	pj.fd = -1;
663	pj.starttime = old_pj ? old_pj->starttime : q->time;
664	pj.status = q->status;
665	pj.size = q->size;
666	pj.spooled = True;
667	fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
668	if (jobid < UNIX_JOB_START) {
669		pj.smbjob = True;
670		fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
671	} else {
672		pj.smbjob = False;
673		fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
674	}
675	fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
676	fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
677
678	pjob_store(sharename, jobid, &pj);
679}
680
681
682struct traverse_struct {
683	print_queue_struct *queue;
684	int qcount, snum, maxcount, total_jobs;
685	const char *sharename;
686	time_t lpq_time;
687};
688
689/****************************************************************************
690 Utility fn to delete any jobs that are no longer active.
691****************************************************************************/
692
693static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
694{
695	struct traverse_struct *ts = (struct traverse_struct *)state;
696	struct printjob pjob;
697	uint32 jobid;
698	int i = 0;
699
700	if (  key.dsize != sizeof(jobid) )
701		return 0;
702
703	jobid = IVAL(key.dptr, 0);
704	if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
705		return 0;
706	free_nt_devicemode( &pjob.nt_devmode );
707
708
709	if (!pjob.smbjob) {
710		/* remove a unix job if it isn't in the system queue any more */
711
712		for (i=0;i<ts->qcount;i++) {
713			uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
714			if (jobid == u_jobid)
715				break;
716		}
717		if (i == ts->qcount) {
718			DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
719						(unsigned int)jobid ));
720			pjob_delete(ts->sharename, jobid);
721			return 0;
722		}
723
724		/* need to continue the the bottom of the function to
725		   save the correct attributes */
726	}
727
728	/* maybe it hasn't been spooled yet */
729	if (!pjob.spooled) {
730		/* if a job is not spooled and the process doesn't
731                   exist then kill it. This cleans up after smbd
732                   deaths */
733		if (!process_exists(pjob.pid)) {
734			DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
735						(unsigned int)jobid, (unsigned int)pjob.pid ));
736			pjob_delete(ts->sharename, jobid);
737		} else
738			ts->total_jobs++;
739		return 0;
740	}
741
742	/* this check only makes sense for jobs submitted from Windows clients */
743
744	if ( pjob.smbjob ) {
745		for (i=0;i<ts->qcount;i++) {
746			uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
747			if (jobid == curr_jobid)
748				break;
749		}
750	}
751
752	/* The job isn't in the system queue - we have to assume it has
753	   completed, so delete the database entry. */
754
755	if (i == ts->qcount) {
756
757		/* A race can occur between the time a job is spooled and
758		   when it appears in the lpq output.  This happens when
759		   the job is added to printing.tdb when another smbd
760		   running print_queue_update() has completed a lpq and
761		   is currently traversing the printing tdb and deleting jobs.
762		   Don't delete the job if it was submitted after the lpq_time. */
763
764		if (pjob.starttime < ts->lpq_time) {
765			DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
766						(unsigned int)jobid,
767						(unsigned int)pjob.starttime,
768						(unsigned int)ts->lpq_time ));
769			pjob_delete(ts->sharename, jobid);
770		} else
771			ts->total_jobs++;
772		return 0;
773	}
774
775	/* Save the pjob attributes we will store. */
776	/* FIXME!!! This is the only place where queue->job
777	   represents the SMB jobid      --jerry */
778	ts->queue[i].job = jobid;
779	ts->queue[i].size = pjob.size;
780	ts->queue[i].page_count = pjob.page_count;
781	ts->queue[i].status = pjob.status;
782	ts->queue[i].priority = 1;
783	ts->queue[i].time = pjob.starttime;
784	fstrcpy(ts->queue[i].fs_user, pjob.user);
785	fstrcpy(ts->queue[i].fs_file, pjob.jobname);
786
787	ts->total_jobs++;
788
789	return 0;
790}
791
792/****************************************************************************
793 Check if the print queue has been updated recently enough.
794****************************************************************************/
795
796static void print_cache_flush(int snum)
797{
798	fstring key;
799	const char *sharename = lp_const_servicename(snum);
800	struct tdb_print_db *pdb = get_print_db_byname(sharename);
801
802	if (!pdb)
803		return;
804	slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
805	tdb_store_int32(pdb->tdb, key, -1);
806	release_print_db(pdb);
807}
808
809/****************************************************************************
810 Check if someone already thinks they are doing the update.
811****************************************************************************/
812
813static pid_t get_updating_pid(const char *sharename)
814{
815	fstring keystr;
816	TDB_DATA data, key;
817	pid_t updating_pid;
818	struct tdb_print_db *pdb = get_print_db_byname(sharename);
819
820	if (!pdb)
821		return (pid_t)-1;
822	slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
823    	key.dptr = keystr;
824	key.dsize = strlen(keystr);
825
826	data = tdb_fetch(pdb->tdb, key);
827	release_print_db(pdb);
828	if (!data.dptr || data.dsize != sizeof(pid_t)) {
829		SAFE_FREE(data.dptr);
830		return (pid_t)-1;
831	}
832
833	updating_pid = IVAL(data.dptr, 0);
834	SAFE_FREE(data.dptr);
835
836	if (process_exists(updating_pid))
837		return updating_pid;
838
839	return (pid_t)-1;
840}
841
842/****************************************************************************
843 Set the fact that we're doing the update, or have finished doing the update
844 in the tdb.
845****************************************************************************/
846
847static void set_updating_pid(const fstring sharename, BOOL updating)
848{
849	fstring keystr;
850	TDB_DATA key;
851	TDB_DATA data;
852	pid_t updating_pid = sys_getpid();
853	uint8 buffer[4];
854
855	struct tdb_print_db *pdb = get_print_db_byname(sharename);
856
857	if (!pdb)
858		return;
859
860	slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
861    	key.dptr = keystr;
862	key.dsize = strlen(keystr);
863
864	DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
865		updating ? "" : "not ",
866		sharename ));
867
868	if ( !updating ) {
869		tdb_delete(pdb->tdb, key);
870		release_print_db(pdb);
871		return;
872	}
873
874	SIVAL( buffer, 0, updating_pid);
875	data.dptr = (void *)buffer;
876	data.dsize = 4;		/* we always assume this is a 4 byte value */
877
878	tdb_store(pdb->tdb, key, data, TDB_REPLACE);
879	release_print_db(pdb);
880}
881
882/****************************************************************************
883 Sort print jobs by submittal time.
884****************************************************************************/
885
886static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
887{
888	/* Silly cases */
889
890	if (!j1 && !j2)
891		return 0;
892	if (!j1)
893		return -1;
894	if (!j2)
895		return 1;
896
897	/* Sort on job start time */
898
899	if (j1->time == j2->time)
900		return 0;
901	return (j1->time > j2->time) ? 1 : -1;
902}
903
904/****************************************************************************
905 Store the sorted queue representation for later portmon retrieval.
906****************************************************************************/
907
908static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
909{
910	TDB_DATA data, key;
911	int max_reported_jobs = lp_max_reported_jobs(pts->snum);
912	print_queue_struct *queue = pts->queue;
913	size_t len;
914	size_t i;
915	uint qcount;
916
917	if (max_reported_jobs && (max_reported_jobs < pts->qcount))
918		pts->qcount = max_reported_jobs;
919	qcount = pts->qcount;
920
921	/* Work out the size. */
922	data.dsize = 0;
923	data.dsize += tdb_pack(NULL, 0, "d", qcount);
924
925	for (i = 0; i < pts->qcount; i++) {
926		data.dsize += tdb_pack(NULL, 0, "ddddddff",
927				(uint32)queue[i].job,
928				(uint32)queue[i].size,
929				(uint32)queue[i].page_count,
930				(uint32)queue[i].status,
931				(uint32)queue[i].priority,
932				(uint32)queue[i].time,
933				queue[i].fs_user,
934				queue[i].fs_file);
935	}
936
937	if ((data.dptr = SMB_MALLOC(data.dsize)) == NULL)
938		return;
939
940        len = 0;
941	len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
942	for (i = 0; i < pts->qcount; i++) {
943		len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
944				(uint32)queue[i].job,
945				(uint32)queue[i].size,
946				(uint32)queue[i].page_count,
947				(uint32)queue[i].status,
948				(uint32)queue[i].priority,
949				(uint32)queue[i].time,
950				queue[i].fs_user,
951				queue[i].fs_file);
952	}
953
954	key.dptr = "INFO/linear_queue_array";
955	key.dsize = strlen(key.dptr);
956	tdb_store(pdb->tdb, key, data, TDB_REPLACE);
957	SAFE_FREE(data.dptr);
958	return;
959}
960
961static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
962{
963	TDB_DATA data, key;
964
965	key.dptr = "INFO/jobs_changed";
966	key.dsize = strlen(key.dptr);
967	ZERO_STRUCT(data);
968
969	data = tdb_fetch(pdb->tdb, key);
970	if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
971		SAFE_FREE(data.dptr);
972		ZERO_STRUCT(data);
973	}
974
975	return data;
976}
977
978static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid)
979{
980	unsigned int i;
981	unsigned int job_count = data.dsize / 4;
982
983	for (i = 0; i < job_count; i++) {
984		uint32 ch_jobid;
985
986		ch_jobid = IVAL(data.dptr, i*4);
987		if (ch_jobid == jobid)
988			remove_from_jobs_changed(sharename, jobid);
989	}
990}
991
992/****************************************************************************
993 Check if the print queue has been updated recently enough.
994****************************************************************************/
995
996static BOOL print_cache_expired(const char *sharename, BOOL check_pending)
997{
998	fstring key;
999	time_t last_qscan_time, time_now = time(NULL);
1000	struct tdb_print_db *pdb = get_print_db_byname(sharename);
1001	BOOL result = False;
1002
1003	if (!pdb)
1004		return False;
1005
1006	snprintf(key, sizeof(key), "CACHE/%s", sharename);
1007	last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1008
1009	/*
1010	 * Invalidate the queue for 3 reasons.
1011	 * (1). last queue scan time == -1.
1012	 * (2). Current time - last queue scan time > allowed cache time.
1013	 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1014	 * This last test picks up machines for which the clock has been moved
1015	 * forward, an lpq scan done and then the clock moved back. Otherwise
1016	 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1017	 */
1018
1019	if (last_qscan_time == ((time_t)-1)
1020		|| (time_now - last_qscan_time) >= lp_lpqcachetime()
1021		|| last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
1022	{
1023		time_t msg_pending_time;
1024
1025		DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1026			"(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1027			sharename, (int)last_qscan_time, (int)time_now,
1028			(int)lp_lpqcachetime() ));
1029
1030		/* check if another smbd has already sent a message to update the
1031		   queue.  Give the pending message one minute to clear and
1032		   then send another message anyways.  Make sure to check for
1033		   clocks that have been run forward and then back again. */
1034
1035		snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1036
1037		if ( check_pending
1038			&& tdb_fetch_uint32( pdb->tdb, key, &msg_pending_time )
1039			&& msg_pending_time > 0
1040			&& msg_pending_time <= time_now
1041			&& (time_now - msg_pending_time) < 60 )
1042		{
1043			DEBUG(4,("print_cache_expired: message already pending for %s.  Accepting cache\n",
1044				sharename));
1045			goto done;
1046		}
1047
1048		result = True;
1049	}
1050
1051done:
1052	release_print_db(pdb);
1053	return result;
1054}
1055
1056/****************************************************************************
1057 main work for updating the lpq cahe for a printer queue
1058****************************************************************************/
1059
1060static void print_queue_update_internal( const char *sharename,
1061                                         struct printif *current_printif,
1062                                         char *lpq_command )
1063{
1064	int i, qcount;
1065	print_queue_struct *queue = NULL;
1066	print_status_struct status;
1067	print_status_struct old_status;
1068	struct printjob *pjob;
1069	struct traverse_struct tstruct;
1070	TDB_DATA data, key;
1071	TDB_DATA jcdata;
1072	fstring keystr, cachestr;
1073	struct tdb_print_db *pdb = get_print_db_byname(sharename);
1074
1075	DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1076		sharename, current_printif->type, lpq_command));
1077
1078	/*
1079	 * Update the cache time FIRST ! Stops others even
1080	 * attempting to get the lock and doing this
1081	 * if the lpq takes a long time.
1082	 */
1083
1084	slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1085	tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1086
1087        /* get the current queue using the appropriate interface */
1088	ZERO_STRUCT(status);
1089
1090	qcount = (*(current_printif->queue_get))(sharename,
1091		current_printif->type,
1092		lpq_command, &queue, &status);
1093
1094	DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1095		qcount, (qcount != 1) ?	"s" : "", sharename));
1096
1097	/* Sort the queue by submission time otherwise they are displayed
1098	   in hash order. */
1099
1100	qsort(queue, qcount, sizeof(print_queue_struct),
1101		QSORT_CAST(printjob_comp));
1102
1103	/*
1104	  any job in the internal database that is marked as spooled
1105	  and doesn't exist in the system queue is considered finished
1106	  and removed from the database
1107
1108	  any job in the system database but not in the internal database
1109	  is added as a unix job
1110
1111	  fill in any system job numbers as we go
1112	*/
1113
1114	jcdata = get_jobs_changed_data(pdb);
1115
1116	for (i=0; i<qcount; i++) {
1117		uint32 jobid = print_parse_jobid(queue[i].fs_file);
1118
1119		if (jobid == (uint32)-1) {
1120			/* assume its a unix print job */
1121			print_unix_job(sharename, &queue[i], jobid);
1122			continue;
1123		}
1124
1125		/* we have an active SMB print job - update its status */
1126		pjob = print_job_find(sharename, jobid);
1127		if (!pjob) {
1128			/* err, somethings wrong. Probably smbd was restarted
1129			   with jobs in the queue. All we can do is treat them
1130			   like unix jobs. Pity. */
1131			print_unix_job(sharename, &queue[i], jobid);
1132			continue;
1133		}
1134
1135		pjob->sysjob = queue[i].job;
1136		pjob->status = queue[i].status;
1137		pjob_store(sharename, jobid, pjob);
1138		check_job_changed(sharename, jcdata, jobid);
1139	}
1140
1141	SAFE_FREE(jcdata.dptr);
1142
1143	/* now delete any queued entries that don't appear in the
1144           system queue */
1145	tstruct.queue = queue;
1146	tstruct.qcount = qcount;
1147	tstruct.snum = -1;
1148	tstruct.total_jobs = 0;
1149	tstruct.lpq_time = time(NULL);
1150	tstruct.sharename = sharename;
1151
1152	tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1153
1154	/* Store the linearised queue, max jobs only. */
1155	store_queue_struct(pdb, &tstruct);
1156
1157	SAFE_FREE(tstruct.queue);
1158
1159	DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1160				sharename, tstruct.total_jobs ));
1161
1162	tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1163
1164	get_queue_status(sharename, &old_status);
1165	if (old_status.qcount != qcount)
1166		DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1167					old_status.qcount, qcount, sharename));
1168
1169	/* store the new queue status structure */
1170	slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1171	key.dptr = keystr;
1172	key.dsize = strlen(keystr);
1173
1174	status.qcount = qcount;
1175	data.dptr = (void *)&status;
1176	data.dsize = sizeof(status);
1177	tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1178
1179	/*
1180	 * Update the cache time again. We want to do this call
1181	 * as little as possible...
1182	 */
1183
1184	slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1185	tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1186
1187	/* clear the msg pending record for this queue */
1188
1189	snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1190
1191	if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1192		/* log a message but continue on */
1193
1194		DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1195			sharename));
1196	}
1197
1198	release_print_db( pdb );
1199
1200	return;
1201}
1202
1203/****************************************************************************
1204 Update the internal database from the system print queue for a queue.
1205 obtain a lock on the print queue before proceeding (needed when mutiple
1206 smbd processes maytry to update the lpq cache concurrently).
1207****************************************************************************/
1208
1209static void print_queue_update_with_lock( const char *sharename,
1210                                          struct printif *current_printif,
1211                                          char *lpq_command )
1212{
1213	fstring keystr;
1214	struct tdb_print_db *pdb;
1215
1216	DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1217	pdb = get_print_db_byname(sharename);
1218	if (!pdb)
1219		return;
1220
1221	if ( !print_cache_expired(sharename, False) ) {
1222		DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1223		release_print_db(pdb);
1224		return;
1225	}
1226
1227	/*
1228	 * Check to see if someone else is doing this update.
1229	 * This is essentially a mutex on the update.
1230	 */
1231
1232	if (get_updating_pid(sharename) != -1) {
1233		release_print_db(pdb);
1234		return;
1235	}
1236
1237	/* Lock the queue for the database update */
1238
1239	slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1240	/* Only wait 10 seconds for this. */
1241	if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
1242		DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1243		release_print_db(pdb);
1244		return;
1245	}
1246
1247	/*
1248	 * Ensure that no one else got in here.
1249	 * If the updating pid is still -1 then we are
1250	 * the winner.
1251	 */
1252
1253	if (get_updating_pid(sharename) != -1) {
1254		/*
1255		 * Someone else is doing the update, exit.
1256		 */
1257		tdb_unlock_bystring(pdb->tdb, keystr);
1258		release_print_db(pdb);
1259		return;
1260	}
1261
1262	/*
1263	 * We're going to do the update ourselves.
1264	 */
1265
1266	/* Tell others we're doing the update. */
1267	set_updating_pid(sharename, True);
1268
1269	/*
1270	 * Allow others to enter and notice we're doing
1271	 * the update.
1272	 */
1273
1274	tdb_unlock_bystring(pdb->tdb, keystr);
1275
1276	/* do the main work now */
1277
1278	print_queue_update_internal( sharename, current_printif, lpq_command );
1279
1280	/* Delete our pid from the db. */
1281	set_updating_pid(sharename, False);
1282	release_print_db(pdb);
1283}
1284
1285/****************************************************************************
1286this is the receive function of the background lpq updater
1287****************************************************************************/
1288static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msglen)
1289{
1290	struct print_queue_update_context ctx;
1291	fstring sharename;
1292	pstring lpqcommand;
1293	size_t len;
1294
1295	len = tdb_unpack( buf, msglen, "fdP",
1296		sharename,
1297		&ctx.printing_type,
1298		lpqcommand );
1299
1300	if ( len == -1 ) {
1301		DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1302		return;
1303	}
1304
1305	ctx.sharename = sharename;
1306	ctx.lpqcommand = lpqcommand;
1307
1308	print_queue_update_with_lock(ctx.sharename,
1309		get_printer_fns_from_type(ctx.printing_type),
1310		ctx.lpqcommand );
1311
1312	return;
1313}
1314
1315static pid_t background_lpq_updater_pid = -1;
1316
1317/****************************************************************************
1318main thread of the background lpq updater
1319****************************************************************************/
1320void start_background_queue(void)
1321{
1322	DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1323	background_lpq_updater_pid = sys_fork();
1324
1325	if (background_lpq_updater_pid == -1) {
1326		DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1327		exit(1);
1328	}
1329
1330	if(background_lpq_updater_pid == 0) {
1331		/* Child. */
1332		DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1333
1334		claim_connection( NULL, "smbd lpq backend", 0, False,
1335			FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINT_GENERAL);
1336
1337		if (!locking_init(0)) {
1338			exit(1);
1339		}
1340
1341		message_register(MSG_PRINTER_UPDATE, print_queue_receive);
1342
1343		DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1344		while (1) {
1345			pause();
1346
1347			/* check for some essential signals first */
1348
1349                        if (got_sig_term) {
1350                                exit_server("Caught TERM signal");
1351                        }
1352
1353                        if (reload_after_sighup) {
1354                                change_to_root_user();
1355                                DEBUG(1,("Reloading services after SIGHUP\n"));
1356                                reload_services(False);
1357                                reload_after_sighup = 0;
1358                        }
1359
1360			/* now check for messages */
1361
1362			DEBUG(10,("start_background_queue: background LPQ thread got a message\n"));
1363			message_dispatch();
1364
1365			/* process any pending print change notify messages */
1366
1367			print_notify_send_messages(0);
1368		}
1369	}
1370}
1371
1372/****************************************************************************
1373update the internal database from the system print queue for a queue
1374****************************************************************************/
1375
1376static void print_queue_update(int snum, BOOL force)
1377{
1378	fstring key;
1379	fstring sharename;
1380	pstring lpqcommand;
1381	char *buffer = NULL;
1382	size_t len = 0;
1383	size_t newlen;
1384	struct tdb_print_db *pdb;
1385	enum printing_types type;
1386	struct printif *current_printif;
1387
1388	fstrcpy( sharename, lp_const_servicename(snum));
1389
1390	pstrcpy( lpqcommand, lp_lpqcommand(snum));
1391	pstring_sub( lpqcommand, "%p", PRINTERNAME(snum) );
1392	standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) );
1393
1394	/*
1395	 * Make sure that the background queue process exists.
1396	 * Otherwise just do the update ourselves
1397	 */
1398
1399	if ( force || background_lpq_updater_pid == -1 ) {
1400		DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1401		current_printif = get_printer_fns( snum );
1402		print_queue_update_with_lock( sharename, current_printif, lpqcommand );
1403
1404		return;
1405	}
1406
1407	type = lp_printing(snum);
1408
1409	/* get the length */
1410
1411	len = tdb_pack( buffer, len, "fdP",
1412		sharename,
1413		type,
1414		lpqcommand );
1415
1416	buffer = SMB_XMALLOC_ARRAY( char, len );
1417
1418	/* now pack the buffer */
1419	newlen = tdb_pack( buffer, len, "fdP",
1420		sharename,
1421		type,
1422		lpqcommand );
1423
1424	SMB_ASSERT( newlen == len );
1425
1426	DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1427		"type = %d, lpq command = [%s]\n", sharename, type, lpqcommand ));
1428
1429	/* here we set a msg pending record for other smbd processes
1430	   to throttle the number of duplicate print_queue_update msgs
1431	   sent.  */
1432
1433	pdb = get_print_db_byname(sharename);
1434	snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1435
1436	if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1437		/* log a message but continue on */
1438
1439		DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1440			sharename));
1441	}
1442
1443	release_print_db( pdb );
1444
1445	/* finally send the message */
1446
1447	become_root();
1448	message_send_pid(background_lpq_updater_pid,
1449		 MSG_PRINTER_UPDATE, buffer, len, False);
1450	unbecome_root();
1451
1452	SAFE_FREE( buffer );
1453
1454	return;
1455}
1456
1457/****************************************************************************
1458 Create/Update an entry in the print tdb that will allow us to send notify
1459 updates only to interested smbd's.
1460****************************************************************************/
1461
1462BOOL print_notify_register_pid(int snum)
1463{
1464	TDB_DATA data;
1465	struct tdb_print_db *pdb = NULL;
1466	TDB_CONTEXT *tdb = NULL;
1467	const char *printername;
1468	uint32 mypid = (uint32)sys_getpid();
1469	BOOL ret = False;
1470	size_t i;
1471
1472	/* if (snum == -1), then the change notify request was
1473	   on a print server handle and we need to register on
1474	   all print queus */
1475
1476	if (snum == -1)
1477	{
1478		int num_services = lp_numservices();
1479		int idx;
1480
1481		for ( idx=0; idx<num_services; idx++ ) {
1482			if (lp_snum_ok(idx) && lp_print_ok(idx) )
1483				print_notify_register_pid(idx);
1484		}
1485
1486		return True;
1487	}
1488	else /* register for a specific printer */
1489	{
1490		printername = lp_const_servicename(snum);
1491		pdb = get_print_db_byname(printername);
1492		if (!pdb)
1493			return False;
1494		tdb = pdb->tdb;
1495	}
1496
1497	if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1498		DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1499					printername));
1500		if (pdb)
1501			release_print_db(pdb);
1502		return False;
1503	}
1504
1505	data = get_printer_notify_pid_list( tdb, printername, True );
1506
1507	/* Add ourselves and increase the refcount. */
1508
1509	for (i = 0; i < data.dsize; i += 8) {
1510		if (IVAL(data.dptr,i) == mypid) {
1511			uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1512			SIVAL(data.dptr, i+4, new_refcount);
1513			break;
1514		}
1515	}
1516
1517	if (i == data.dsize) {
1518		/* We weren't in the list. Realloc. */
1519		data.dptr = SMB_REALLOC(data.dptr, data.dsize + 8);
1520		if (!data.dptr) {
1521			DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1522						printername));
1523			goto done;
1524		}
1525		data.dsize += 8;
1526		SIVAL(data.dptr,data.dsize - 8,mypid);
1527		SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1528	}
1529
1530	/* Store back the record. */
1531	if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1532		DEBUG(0,("print_notify_register_pid: Failed to update pid \
1533list for printer %s\n", printername));
1534		goto done;
1535	}
1536
1537	ret = True;
1538
1539 done:
1540
1541	tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1542	if (pdb)
1543		release_print_db(pdb);
1544	SAFE_FREE(data.dptr);
1545	return ret;
1546}
1547
1548/****************************************************************************
1549 Update an entry in the print tdb that will allow us to send notify
1550 updates only to interested smbd's.
1551****************************************************************************/
1552
1553BOOL print_notify_deregister_pid(int snum)
1554{
1555	TDB_DATA data;
1556	struct tdb_print_db *pdb = NULL;
1557	TDB_CONTEXT *tdb = NULL;
1558	const char *printername;
1559	uint32 mypid = (uint32)sys_getpid();
1560	size_t i;
1561	BOOL ret = False;
1562
1563	/* if ( snum == -1 ), we are deregister a print server handle
1564	   which means to deregister on all print queues */
1565
1566	if (snum == -1)
1567	{
1568		int num_services = lp_numservices();
1569		int idx;
1570
1571		for ( idx=0; idx<num_services; idx++ ) {
1572			if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1573				print_notify_deregister_pid(idx);
1574		}
1575
1576		return True;
1577	}
1578	else /* deregister a specific printer */
1579	{
1580		printername = lp_const_servicename(snum);
1581		pdb = get_print_db_byname(printername);
1582		if (!pdb)
1583			return False;
1584		tdb = pdb->tdb;
1585	}
1586
1587	if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1588		DEBUG(0,("print_notify_register_pid: Failed to lock \
1589printer %s database\n", printername));
1590		if (pdb)
1591			release_print_db(pdb);
1592		return False;
1593	}
1594
1595	data = get_printer_notify_pid_list( tdb, printername, True );
1596
1597	/* Reduce refcount. Remove ourselves if zero. */
1598
1599	for (i = 0; i < data.dsize; ) {
1600		if (IVAL(data.dptr,i) == mypid) {
1601			uint32 refcount = IVAL(data.dptr, i+4);
1602
1603			refcount--;
1604
1605			if (refcount == 0) {
1606				if (data.dsize - i > 8)
1607					memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1608				data.dsize -= 8;
1609				continue;
1610			}
1611			SIVAL(data.dptr, i+4, refcount);
1612		}
1613
1614		i += 8;
1615	}
1616
1617	if (data.dsize == 0)
1618		SAFE_FREE(data.dptr);
1619
1620	/* Store back the record. */
1621	if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1622		DEBUG(0,("print_notify_register_pid: Failed to update pid \
1623list for printer %s\n", printername));
1624		goto done;
1625	}
1626
1627	ret = True;
1628
1629  done:
1630
1631	tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1632	if (pdb)
1633		release_print_db(pdb);
1634	SAFE_FREE(data.dptr);
1635	return ret;
1636}
1637
1638/****************************************************************************
1639 Check if a jobid is valid. It is valid if it exists in the database.
1640****************************************************************************/
1641
1642BOOL print_job_exists(const char* sharename, uint32 jobid)
1643{
1644	struct tdb_print_db *pdb = get_print_db_byname(sharename);
1645	BOOL ret;
1646
1647	if (!pdb)
1648		return False;
1649	ret = tdb_exists(pdb->tdb, print_key(jobid));
1650	release_print_db(pdb);
1651	return ret;
1652}
1653
1654/****************************************************************************
1655 Give the fd used for a jobid.
1656****************************************************************************/
1657
1658int print_job_fd(const char* sharename, uint32 jobid)
1659{
1660	struct printjob *pjob = print_job_find(sharename, jobid);
1661	if (!pjob)
1662		return -1;
1663	/* don't allow another process to get this info - it is meaningless */
1664	if (pjob->pid != sys_getpid())
1665		return -1;
1666	return pjob->fd;
1667}
1668
1669/****************************************************************************
1670 Give the filename used for a jobid.
1671 Only valid for the process doing the spooling and when the job
1672 has not been spooled.
1673****************************************************************************/
1674
1675char *print_job_fname(const char* sharename, uint32 jobid)
1676{
1677	struct printjob *pjob = print_job_find(sharename, jobid);
1678	if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
1679		return NULL;
1680	return pjob->filename;
1681}
1682
1683
1684/****************************************************************************
1685 Give the filename used for a jobid.
1686 Only valid for the process doing the spooling and when the job
1687 has not been spooled.
1688****************************************************************************/
1689
1690NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid)
1691{
1692	struct printjob *pjob = print_job_find(sharename, jobid);
1693
1694	if ( !pjob )
1695		return NULL;
1696
1697	return pjob->nt_devmode;
1698}
1699
1700/****************************************************************************
1701 Set the place in the queue for a job.
1702****************************************************************************/
1703
1704BOOL print_job_set_place(int snum, uint32 jobid, int place)
1705{
1706	DEBUG(2,("print_job_set_place not implemented yet\n"));
1707	return False;
1708}
1709
1710/****************************************************************************
1711 Set the name of a job. Only possible for owner.
1712****************************************************************************/
1713
1714BOOL print_job_set_name(int snum, uint32 jobid, char *name)
1715{
1716	const char* sharename = lp_const_servicename(snum);
1717	struct printjob *pjob;
1718
1719	pjob = print_job_find(sharename, jobid);
1720	if (!pjob || pjob->pid != sys_getpid())
1721		return False;
1722
1723	fstrcpy(pjob->jobname, name);
1724	return pjob_store(sharename, jobid, pjob);
1725}
1726
1727/***************************************************************************
1728 Remove a jobid from the 'jobs changed' list.
1729***************************************************************************/
1730
1731static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid)
1732{
1733	struct tdb_print_db *pdb = get_print_db_byname(sharename);
1734	TDB_DATA data, key;
1735	size_t job_count, i;
1736	BOOL ret = False;
1737	BOOL gotlock = False;
1738
1739	key.dptr = "INFO/jobs_changed";
1740	key.dsize = strlen(key.dptr);
1741	ZERO_STRUCT(data);
1742
1743	if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1744		goto out;
1745
1746	gotlock = True;
1747
1748	data = tdb_fetch(pdb->tdb, key);
1749
1750	if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
1751		goto out;
1752
1753	job_count = data.dsize / 4;
1754	for (i = 0; i < job_count; i++) {
1755		uint32 ch_jobid;
1756
1757		ch_jobid = IVAL(data.dptr, i*4);
1758		if (ch_jobid == jobid) {
1759			if (i < job_count -1 )
1760				memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
1761			data.dsize -= 4;
1762			if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
1763				goto out;
1764			break;
1765		}
1766	}
1767
1768	ret = True;
1769  out:
1770
1771	if (gotlock)
1772		tdb_chainunlock(pdb->tdb, key);
1773	SAFE_FREE(data.dptr);
1774	release_print_db(pdb);
1775	if (ret)
1776		DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
1777	else
1778		DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
1779	return ret;
1780}
1781
1782/****************************************************************************
1783 Delete a print job - don't update queue.
1784****************************************************************************/
1785
1786static BOOL print_job_delete1(int snum, uint32 jobid)
1787{
1788	const char* sharename = lp_const_servicename(snum);
1789	struct printjob *pjob = print_job_find(sharename, jobid);
1790	int result = 0;
1791	struct printif *current_printif = get_printer_fns( snum );
1792
1793	pjob = print_job_find(sharename, jobid);
1794
1795	if (!pjob)
1796		return False;
1797
1798	/*
1799	 * If already deleting just return.
1800	 */
1801
1802	if (pjob->status == LPQ_DELETING)
1803		return True;
1804
1805	/* Hrm - we need to be able to cope with deleting a job before it
1806	   has reached the spooler. */
1807
1808	if (pjob->sysjob == -1) {
1809		DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
1810	}
1811
1812	/* Set the tdb entry to be deleting. */
1813
1814	pjob->status = LPQ_DELETING;
1815	pjob_store(sharename, jobid, pjob);
1816
1817	if (pjob->spooled && pjob->sysjob != -1)
1818		result = (*(current_printif->job_delete))(snum, pjob);
1819
1820	/* Delete the tdb entry if the delete succeeded or the job hasn't
1821	   been spooled. */
1822
1823	if (result == 0) {
1824		struct tdb_print_db *pdb = get_print_db_byname(sharename);
1825		int njobs = 1;
1826
1827		if (!pdb)
1828			return False;
1829		pjob_delete(sharename, jobid);
1830		/* Ensure we keep a rough count of the number of total jobs... */
1831		tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
1832		release_print_db(pdb);
1833	}
1834
1835	return (result == 0);
1836}
1837
1838/****************************************************************************
1839 Return true if the current user owns the print job.
1840****************************************************************************/
1841
1842static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
1843{
1844	struct printjob *pjob = print_job_find(lp_const_servicename(snum), jobid);
1845	user_struct *vuser;
1846
1847	if (!pjob || !user)
1848		return False;
1849
1850	if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
1851		return strequal(pjob->user, vuser->user.smb_name);
1852	} else {
1853		return strequal(pjob->user, uidtoname(user->uid));
1854	}
1855}
1856
1857/****************************************************************************
1858 Delete a print job.
1859****************************************************************************/
1860
1861BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1862{
1863	const char* sharename = lp_const_servicename( snum );
1864	BOOL 	owner, deleted;
1865	char 	*fname;
1866
1867	*errcode = WERR_OK;
1868
1869	owner = is_owner(user, snum, jobid);
1870
1871	/* Check access against security descriptor or whether the user
1872	   owns their job. */
1873
1874	if (!owner &&
1875	    !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1876		DEBUG(3, ("delete denied by security descriptor\n"));
1877		*errcode = WERR_ACCESS_DENIED;
1878
1879		/* BEGIN_ADMIN_LOG */
1880		sys_adminlog( LOG_ERR,
1881			      "Permission denied-- user not allowed to delete, \
1882pause, or resume print job. User name: %s. Printer name: %s.",
1883			      uidtoname(user->uid), PRINTERNAME(snum) );
1884		/* END_ADMIN_LOG */
1885
1886		return False;
1887	}
1888
1889	/*
1890	 * get the spooled filename of the print job
1891	 * if this works, then the file has not been spooled
1892	 * to the underlying print system.  Just delete the
1893	 * spool file & return.
1894	 */
1895
1896	if ( (fname = print_job_fname( sharename, jobid )) != NULL )
1897	{
1898		/* remove the spool file */
1899		DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
1900		if ( unlink( fname ) == -1 ) {
1901			*errcode = map_werror_from_unix(errno);
1902			return False;
1903		}
1904	}
1905
1906	if (!print_job_delete1(snum, jobid)) {
1907		*errcode = WERR_ACCESS_DENIED;
1908		return False;
1909	}
1910
1911	/* force update the database and say the delete failed if the
1912           job still exists */
1913
1914	print_queue_update(snum, True);
1915
1916	deleted = !print_job_exists(sharename, jobid);
1917	if ( !deleted )
1918		*errcode = WERR_ACCESS_DENIED;
1919
1920	return deleted;
1921}
1922
1923/****************************************************************************
1924 Pause a job.
1925****************************************************************************/
1926
1927BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1928{
1929	const char* sharename = lp_const_servicename(snum);
1930	struct printjob *pjob;
1931	int ret = -1;
1932	struct printif *current_printif = get_printer_fns( snum );
1933
1934	pjob = print_job_find(sharename, jobid);
1935
1936	if (!pjob || !user)
1937		return False;
1938
1939	if (!pjob->spooled || pjob->sysjob == -1)
1940		return False;
1941
1942	if (!is_owner(user, snum, jobid) &&
1943	    !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1944		DEBUG(3, ("pause denied by security descriptor\n"));
1945
1946		/* BEGIN_ADMIN_LOG */
1947		sys_adminlog( LOG_ERR,
1948			"Permission denied-- user not allowed to delete, \
1949pause, or resume print job. User name: %s. Printer name: %s.",
1950				uidtoname(user->uid), PRINTERNAME(snum) );
1951		/* END_ADMIN_LOG */
1952
1953		*errcode = WERR_ACCESS_DENIED;
1954		return False;
1955	}
1956
1957	/* need to pause the spooled entry */
1958	ret = (*(current_printif->job_pause))(snum, pjob);
1959
1960	if (ret != 0) {
1961		*errcode = WERR_INVALID_PARAM;
1962		return False;
1963	}
1964
1965	/* force update the database */
1966	print_cache_flush(snum);
1967
1968	/* Send a printer notify message */
1969
1970	notify_job_status(sharename, jobid, JOB_STATUS_PAUSED);
1971
1972	/* how do we tell if this succeeded? */
1973
1974	return True;
1975}
1976
1977/****************************************************************************
1978 Resume a job.
1979****************************************************************************/
1980
1981BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
1982{
1983	const char *sharename = lp_const_servicename(snum);
1984	struct printjob *pjob;
1985	int ret;
1986	struct printif *current_printif = get_printer_fns( snum );
1987
1988	pjob = print_job_find(sharename, jobid);
1989
1990	if (!pjob || !user)
1991		return False;
1992
1993	if (!pjob->spooled || pjob->sysjob == -1)
1994		return False;
1995
1996	if (!is_owner(user, snum, jobid) &&
1997	    !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
1998		DEBUG(3, ("resume denied by security descriptor\n"));
1999		*errcode = WERR_ACCESS_DENIED;
2000
2001		/* BEGIN_ADMIN_LOG */
2002		sys_adminlog( LOG_ERR,
2003			 "Permission denied-- user not allowed to delete, \
2004pause, or resume print job. User name: %s. Printer name: %s.",
2005			uidtoname(user->uid), PRINTERNAME(snum) );
2006		/* END_ADMIN_LOG */
2007		return False;
2008	}
2009
2010	ret = (*(current_printif->job_resume))(snum, pjob);
2011
2012	if (ret != 0) {
2013		*errcode = WERR_INVALID_PARAM;
2014		return False;
2015	}
2016
2017	/* force update the database */
2018	print_cache_flush(snum);
2019
2020	/* Send a printer notify message */
2021
2022	notify_job_status(sharename, jobid, JOB_STATUS_QUEUED);
2023
2024	return True;
2025}
2026
2027/****************************************************************************
2028 Write to a print file.
2029****************************************************************************/
2030
2031int print_job_write(int snum, uint32 jobid, const char *buf, int size)
2032{
2033	const char* sharename = lp_const_servicename(snum);
2034	int return_code;
2035	struct printjob *pjob;
2036
2037	pjob = print_job_find(sharename, jobid);
2038
2039	if (!pjob)
2040		return -1;
2041	/* don't allow another process to get this info - it is meaningless */
2042	if (pjob->pid != sys_getpid())
2043		return -1;
2044
2045	return_code = write(pjob->fd, buf, size);
2046	if (return_code>0) {
2047		pjob->size += size;
2048		pjob_store(sharename, jobid, pjob);
2049	}
2050	return return_code;
2051}
2052
2053/****************************************************************************
2054 Get the queue status - do not update if db is out of date.
2055****************************************************************************/
2056
2057static int get_queue_status(const char* sharename, print_status_struct *status)
2058{
2059	fstring keystr;
2060	TDB_DATA data, key;
2061	struct tdb_print_db *pdb = get_print_db_byname(sharename);
2062	int len;
2063
2064	if (!pdb)
2065		return 0;
2066
2067	if (status) {
2068		ZERO_STRUCTP(status);
2069		slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
2070		key.dptr = keystr;
2071		key.dsize = strlen(keystr);
2072		data = tdb_fetch(pdb->tdb, key);
2073		if (data.dptr) {
2074			if (data.dsize == sizeof(print_status_struct))
2075				/* this memcpy is ok since the status struct was
2076				   not packed before storing it in the tdb */
2077				memcpy(status, data.dptr, sizeof(print_status_struct));
2078			SAFE_FREE(data.dptr);
2079		}
2080	}
2081	len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2082	release_print_db(pdb);
2083	return (len == -1 ? 0 : len);
2084}
2085
2086/****************************************************************************
2087 Determine the number of jobs in a queue.
2088****************************************************************************/
2089
2090int print_queue_length(int snum, print_status_struct *pstatus)
2091{
2092	const char* sharename = lp_const_servicename( snum );
2093	print_status_struct status;
2094	int len;
2095
2096	/* make sure the database is up to date */
2097	if (print_cache_expired(lp_const_servicename(snum), True))
2098		print_queue_update(snum, False);
2099
2100	/* also fetch the queue status */
2101	memset(&status, 0, sizeof(status));
2102	len = get_queue_status(sharename, &status);
2103
2104	if (pstatus)
2105		*pstatus = status;
2106
2107	return len;
2108}
2109
2110/***************************************************************************
2111 Allocate a jobid. Hold the lock for as short a time as possible.
2112***************************************************************************/
2113
2114static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid)
2115{
2116	int i;
2117	uint32 jobid;
2118
2119	*pjobid = (uint32)-1;
2120
2121	for (i = 0; i < 3; i++) {
2122		/* Lock the database - only wait 20 seconds. */
2123		if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
2124			DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename));
2125			return False;
2126		}
2127
2128		if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2129			if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
2130				DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
2131					sharename));
2132				return False;
2133			}
2134			jobid = 0;
2135		}
2136
2137		jobid = NEXT_JOBID(jobid);
2138
2139		if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
2140			DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
2141			tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2142			return False;
2143		}
2144
2145		/* We've finished with the INFO/nextjob lock. */
2146		tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2147
2148		if (!print_job_exists(sharename, jobid))
2149			break;
2150	}
2151
2152	if (i > 2) {
2153		DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
2154			sharename));
2155		/* Probably full... */
2156		errno = ENOSPC;
2157		return False;
2158	}
2159
2160	/* Store a dummy placeholder. */
2161	{
2162		TDB_DATA dum;
2163		dum.dptr = NULL;
2164		dum.dsize = 0;
2165		if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
2166			DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
2167				jobid ));
2168			return False;
2169		}
2170	}
2171
2172	*pjobid = jobid;
2173	return True;
2174}
2175
2176/***************************************************************************
2177 Append a jobid to the 'jobs changed' list.
2178***************************************************************************/
2179
2180static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
2181{
2182	TDB_DATA data, key;
2183	uint32 store_jobid;
2184
2185	key.dptr = "INFO/jobs_changed";
2186	key.dsize = strlen(key.dptr);
2187	SIVAL(&store_jobid, 0, jobid);
2188	data.dptr = (char *)&store_jobid;
2189	data.dsize = 4;
2190
2191	DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
2192
2193	return (tdb_append(pdb->tdb, key, data) == 0);
2194}
2195
2196/***************************************************************************
2197 Start spooling a job - return the jobid.
2198***************************************************************************/
2199
2200uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
2201{
2202	uint32 jobid;
2203	char *path;
2204	struct printjob pjob;
2205	user_struct *vuser;
2206	const char *sharename = lp_const_servicename(snum);
2207	struct tdb_print_db *pdb = get_print_db_byname(sharename);
2208	int njobs;
2209
2210	errno = 0;
2211
2212	if (!pdb)
2213		return (uint32)-1;
2214
2215	if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
2216		DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
2217		release_print_db(pdb);
2218		return (uint32)-1;
2219	}
2220
2221	if (!print_time_access_check(snum)) {
2222		DEBUG(3, ("print_job_start: job start denied by time check\n"));
2223		release_print_db(pdb);
2224		return (uint32)-1;
2225	}
2226
2227	path = lp_pathname(snum);
2228
2229	/* see if we have sufficient disk space */
2230	if (lp_minprintspace(snum)) {
2231		SMB_BIG_UINT dspace, dsize;
2232		if (sys_fsusage(path, &dspace, &dsize) == 0 &&
2233		    dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
2234			DEBUG(3, ("print_job_start: disk space check failed.\n"));
2235			release_print_db(pdb);
2236			errno = ENOSPC;
2237			return (uint32)-1;
2238		}
2239	}
2240
2241	/* for autoloaded printers, check that the printcap entry still exists */
2242	if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) {
2243		DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
2244		release_print_db(pdb);
2245		errno = ENOENT;
2246		return (uint32)-1;
2247	}
2248
2249	/* Insure the maximum queue size is not violated */
2250	if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
2251		DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
2252			sharename, njobs, lp_maxprintjobs(snum) ));
2253		release_print_db(pdb);
2254		errno = ENOSPC;
2255		return (uint32)-1;
2256	}
2257
2258	DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
2259		sharename, njobs, lp_maxprintjobs(snum) ));
2260
2261	if (!allocate_print_jobid(pdb, snum, sharename, &jobid))
2262		goto fail;
2263
2264	/* create the database entry */
2265
2266	ZERO_STRUCT(pjob);
2267
2268	pjob.pid = sys_getpid();
2269	pjob.sysjob = -1;
2270	pjob.fd = -1;
2271	pjob.starttime = time(NULL);
2272	pjob.status = LPQ_SPOOLING;
2273	pjob.size = 0;
2274	pjob.spooled = False;
2275	pjob.smbjob = True;
2276	pjob.nt_devmode = nt_devmode;
2277
2278	fstrcpy(pjob.jobname, jobname);
2279
2280	if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
2281		fstrcpy(pjob.user, vuser->user.smb_name);
2282	} else {
2283		fstrcpy(pjob.user, uidtoname(user->uid));
2284	}
2285
2286	fstrcpy(pjob.queuename, lp_const_servicename(snum));
2287
2288	/* we have a job entry - now create the spool file */
2289	slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX",
2290		 path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2291	pjob.fd = smb_mkstemp(pjob.filename);
2292
2293	if (pjob.fd == -1) {
2294		if (errno == EACCES) {
2295			/* Common setup error, force a report. */
2296			DEBUG(0, ("print_job_start: insufficient permissions \
2297to open spool file %s.\n", pjob.filename));
2298		} else {
2299			/* Normal case, report at level 3 and above. */
2300			DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
2301			DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
2302		}
2303		goto fail;
2304	}
2305
2306	pjob_store(sharename, jobid, &pjob);
2307
2308	/* Update the 'jobs changed' entry used by print_queue_status. */
2309	add_to_jobs_changed(pdb, jobid);
2310
2311	/* Ensure we keep a rough count of the number of total jobs... */
2312	tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2313
2314	release_print_db(pdb);
2315
2316	return jobid;
2317
2318 fail:
2319	if (jobid != -1)
2320		pjob_delete(sharename, jobid);
2321
2322	release_print_db(pdb);
2323
2324	DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
2325	return (uint32)-1;
2326}
2327
2328/****************************************************************************
2329 Update the number of pages spooled to jobid
2330****************************************************************************/
2331
2332void print_job_endpage(int snum, uint32 jobid)
2333{
2334	const char* sharename = lp_const_servicename(snum);
2335	struct printjob *pjob;
2336
2337	pjob = print_job_find(sharename, jobid);
2338	if (!pjob)
2339		return;
2340	/* don't allow another process to get this info - it is meaningless */
2341	if (pjob->pid != sys_getpid())
2342		return;
2343
2344	pjob->page_count++;
2345	pjob_store(sharename, jobid, pjob);
2346}
2347
2348/****************************************************************************
2349 Print a file - called on closing the file. This spools the job.
2350 If normal close is false then we're tearing down the jobs - treat as an
2351 error.
2352****************************************************************************/
2353
2354BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
2355{
2356	const char* sharename = lp_const_servicename(snum);
2357	struct printjob *pjob;
2358	int ret;
2359	SMB_STRUCT_STAT sbuf;
2360	struct printif *current_printif = get_printer_fns( snum );
2361
2362	pjob = print_job_find(sharename, jobid);
2363
2364	if (!pjob)
2365		return False;
2366
2367	if (pjob->spooled || pjob->pid != sys_getpid())
2368		return False;
2369
2370	if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
2371		pjob->size = sbuf.st_size;
2372		close(pjob->fd);
2373		pjob->fd = -1;
2374	} else {
2375
2376		/*
2377		 * Not a normal close or we couldn't stat the job file,
2378		 * so something has gone wrong. Cleanup.
2379		 */
2380		close(pjob->fd);
2381		pjob->fd = -1;
2382		DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
2383		goto fail;
2384	}
2385
2386	/* Technically, this is not quite right. If the printer has a separator
2387	 * page turned on, the NT spooler prints the separator page even if the
2388	 * print job is 0 bytes. 010215 JRR */
2389	if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2390		/* don't bother spooling empty files or something being deleted. */
2391		DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2392			pjob->filename, pjob->size ? "deleted" : "zero length" ));
2393		unlink(pjob->filename);
2394		pjob_delete(sharename, jobid);
2395		return True;
2396	}
2397
2398	pjob->smbjob = jobid;
2399
2400	ret = (*(current_printif->job_submit))(snum, pjob);
2401
2402	if (ret)
2403		goto fail;
2404
2405	/* The print job has been sucessfully handed over to the back-end */
2406
2407	pjob->spooled = True;
2408	pjob->status = LPQ_QUEUED;
2409	pjob_store(sharename, jobid, pjob);
2410
2411	/* make sure the database is up to date */
2412	if (print_cache_expired(lp_const_servicename(snum), True))
2413		print_queue_update(snum, False);
2414
2415	return True;
2416
2417fail:
2418
2419	/* The print job was not succesfully started. Cleanup */
2420	/* Still need to add proper error return propagation! 010122:JRR */
2421	unlink(pjob->filename);
2422	pjob_delete(sharename, jobid);
2423	return False;
2424}
2425
2426/****************************************************************************
2427 Get a snapshot of jobs in the system without traversing.
2428****************************************************************************/
2429
2430static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
2431{
2432	TDB_DATA data, key, cgdata;
2433	print_queue_struct *queue = NULL;
2434	uint32 qcount = 0;
2435	uint32 extra_count = 0;
2436	int total_count = 0;
2437	size_t len = 0;
2438	uint32 i;
2439	int max_reported_jobs = lp_max_reported_jobs(snum);
2440	BOOL ret = False;
2441	const char* sharename = lp_servicename(snum);
2442
2443	/* make sure the database is up to date */
2444	if (print_cache_expired(lp_const_servicename(snum), True))
2445		print_queue_update(snum, False);
2446
2447	*pcount = 0;
2448	*ppqueue = NULL;
2449
2450	ZERO_STRUCT(data);
2451	ZERO_STRUCT(cgdata);
2452	key.dptr = "INFO/linear_queue_array";
2453	key.dsize = strlen(key.dptr);
2454
2455	/* Get the stored queue data. */
2456	data = tdb_fetch(pdb->tdb, key);
2457
2458	if (data.dptr && data.dsize >= sizeof(qcount))
2459		len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2460
2461	/* Get the changed jobs list. */
2462	key.dptr = "INFO/jobs_changed";
2463	key.dsize = strlen(key.dptr);
2464
2465	cgdata = tdb_fetch(pdb->tdb, key);
2466	if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2467		extra_count = cgdata.dsize/4;
2468
2469	DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2470
2471	/* Allocate the queue size. */
2472	if (qcount == 0 && extra_count == 0)
2473		goto out;
2474
2475	if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
2476		goto out;
2477
2478	/* Retrieve the linearised queue data. */
2479
2480	for( i  = 0; i < qcount; i++) {
2481		uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2482		len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2483				&qjob,
2484				&qsize,
2485				&qpage_count,
2486				&qstatus,
2487				&qpriority,
2488				&qtime,
2489				queue[i].fs_user,
2490				queue[i].fs_file);
2491		queue[i].job = qjob;
2492		queue[i].size = qsize;
2493		queue[i].page_count = qpage_count;
2494		queue[i].status = qstatus;
2495		queue[i].priority = qpriority;
2496		queue[i].time = qtime;
2497	}
2498
2499	total_count = qcount;
2500
2501	/* Add in the changed jobids. */
2502	for( i  = 0; i < extra_count; i++) {
2503		uint32 jobid;
2504		struct printjob *pjob;
2505
2506		jobid = IVAL(cgdata.dptr, i*4);
2507		DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2508		pjob = print_job_find(lp_const_servicename(snum), jobid);
2509		if (!pjob) {
2510			DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2511			remove_from_jobs_changed(sharename, jobid);
2512			continue;
2513		}
2514
2515		queue[total_count].job = jobid;
2516		queue[total_count].size = pjob->size;
2517		queue[total_count].page_count = pjob->page_count;
2518		queue[total_count].status = pjob->status;
2519		queue[total_count].priority = 1;
2520		queue[total_count].time = pjob->starttime;
2521		fstrcpy(queue[total_count].fs_user, pjob->user);
2522		fstrcpy(queue[total_count].fs_file, pjob->jobname);
2523		total_count++;
2524	}
2525
2526	/* Sort the queue by submission time otherwise they are displayed
2527	   in hash order. */
2528
2529	qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
2530
2531	DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2532
2533	if (max_reported_jobs && total_count > max_reported_jobs)
2534		total_count = max_reported_jobs;
2535
2536	*ppqueue = queue;
2537	*pcount = total_count;
2538
2539	ret = True;
2540
2541  out:
2542
2543	SAFE_FREE(data.dptr);
2544	SAFE_FREE(cgdata.dptr);
2545	return ret;
2546}
2547
2548/****************************************************************************
2549 Get a printer queue listing.
2550 set queue = NULL and status = NULL if you just want to update the cache
2551****************************************************************************/
2552
2553int print_queue_status(int snum,
2554		       print_queue_struct **ppqueue,
2555		       print_status_struct *status)
2556{
2557	fstring keystr;
2558	TDB_DATA data, key;
2559	const char *sharename;
2560	struct tdb_print_db *pdb;
2561	int count = 0;
2562
2563	/* make sure the database is up to date */
2564
2565	if (print_cache_expired(lp_const_servicename(snum), True))
2566		print_queue_update(snum, False);
2567
2568	/* return if we are done */
2569	if ( !ppqueue || !status )
2570		return 0;
2571
2572	*ppqueue = NULL;
2573	sharename = lp_const_servicename(snum);
2574	pdb = get_print_db_byname(sharename);
2575
2576	if (!pdb)
2577		return 0;
2578
2579	/*
2580	 * Fetch the queue status.  We must do this first, as there may
2581	 * be no jobs in the queue.
2582	 */
2583
2584	ZERO_STRUCTP(status);
2585	slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
2586	key.dptr = keystr;
2587	key.dsize = strlen(keystr);
2588	data = tdb_fetch(pdb->tdb, key);
2589	if (data.dptr) {
2590		if (data.dsize == sizeof(*status)) {
2591			/* this memcpy is ok since the status struct was
2592			   not packed before storing it in the tdb */
2593			memcpy(status, data.dptr, sizeof(*status));
2594		}
2595		SAFE_FREE(data.dptr);
2596	}
2597
2598	/*
2599	 * Now, fetch the print queue information.  We first count the number
2600	 * of entries, and then only retrieve the queue if necessary.
2601	 */
2602
2603	if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
2604		release_print_db(pdb);
2605		return 0;
2606	}
2607
2608	release_print_db(pdb);
2609	return count;
2610}
2611
2612/****************************************************************************
2613 Pause a queue.
2614****************************************************************************/
2615
2616BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
2617{
2618	int ret;
2619	struct printif *current_printif = get_printer_fns( snum );
2620
2621	if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2622		*errcode = WERR_ACCESS_DENIED;
2623		return False;
2624	}
2625
2626
2627	become_root();
2628
2629	ret = (*(current_printif->queue_pause))(snum);
2630
2631	unbecome_root();
2632
2633	if (ret != 0) {
2634		*errcode = WERR_INVALID_PARAM;
2635		return False;
2636	}
2637
2638	/* force update the database */
2639	print_cache_flush(snum);
2640
2641	/* Send a printer notify message */
2642
2643	notify_printer_status(snum, PRINTER_STATUS_PAUSED);
2644
2645	return True;
2646}
2647
2648/****************************************************************************
2649 Resume a queue.
2650****************************************************************************/
2651
2652BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
2653{
2654	int ret;
2655	struct printif *current_printif = get_printer_fns( snum );
2656
2657	if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
2658		*errcode = WERR_ACCESS_DENIED;
2659		return False;
2660	}
2661
2662	become_root();
2663
2664	ret = (*(current_printif->queue_resume))(snum);
2665
2666	unbecome_root();
2667
2668	if (ret != 0) {
2669		*errcode = WERR_INVALID_PARAM;
2670		return False;
2671	}
2672
2673	/* make sure the database is up to date */
2674	if (print_cache_expired(lp_const_servicename(snum), True))
2675		print_queue_update(snum, True);
2676
2677	/* Send a printer notify message */
2678
2679	notify_printer_status(snum, PRINTER_STATUS_OK);
2680
2681	return True;
2682}
2683
2684/****************************************************************************
2685 Purge a queue - implemented by deleting all jobs that we can delete.
2686****************************************************************************/
2687
2688BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
2689{
2690	print_queue_struct *queue;
2691	print_status_struct status;
2692	int njobs, i;
2693	BOOL can_job_admin;
2694
2695	/* Force and update so the count is accurate (i.e. not a cached count) */
2696	print_queue_update(snum, True);
2697
2698	can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
2699	njobs = print_queue_status(snum, &queue, &status);
2700
2701	if ( can_job_admin )
2702		become_root();
2703
2704	for (i=0;i<njobs;i++) {
2705		BOOL owner = is_owner(user, snum, queue[i].job);
2706
2707		if (owner || can_job_admin) {
2708			print_job_delete1(snum, queue[i].job);
2709		}
2710	}
2711
2712	if ( can_job_admin )
2713		unbecome_root();
2714
2715	/* update the cache */
2716	print_queue_update( snum, True );
2717
2718	SAFE_FREE(queue);
2719
2720	return True;
2721}
2722