source: branches/samba-3.3.x/source/printing/printing.c@ 699

Last change on this file since 699 was 699, checked in by Silvan Scherrer, 13 years ago

Samba Server 3.3: made it high-mem aware

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