source: branches/samba-3.5.x/source3/printing/printing.c@ 1075

Last change on this file since 1075 was 664, checked in by Silvan Scherrer, 14 years ago

Samba Server 3.5: fixed a missing return, changed os2_socketpair to os2_pipe

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