source: trunk/server/source3/printing/printing.c@ 617

Last change on this file since 617 was 480, checked in by Silvan Scherrer, 15 years ago

Samba Server 3.5: trunk update to 3.5.4

File size: 79.9 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
25extern struct current_user current_user;
26extern userdom_struct current_user_info;
27
28/* Current printer interface */
29static bool remove_from_jobs_changed(const char* sharename, uint32 jobid);
30
31/*
32 the printing backend revolves around a tdb database that stores the
33 SMB view of the print queue
34
35 The key for this database is a jobid - a internally generated number that
36 uniquely identifies a print job
37
38 reading the print queue involves two steps:
39 - possibly running lpq and updating the internal database from that
40 - reading entries from the database
41
42 jobids are assigned when a job starts spooling.
43*/
44
45static TDB_CONTEXT *rap_tdb;
46static uint16 next_rap_jobid;
47struct rap_jobid_key {
48 fstring sharename;
49 uint32 jobid;
50};
51
52/***************************************************************************
53 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
54 bit RPC jobids.... JRA.
55***************************************************************************/
56
57uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
58{
59 uint16 rap_jobid;
60 TDB_DATA data, key;
61 struct rap_jobid_key jinfo;
62 uint8 buf[2];
63
64 DEBUG(10,("pjobid_to_rap: called.\n"));
65
66 if (!rap_tdb) {
67 /* Create the in-memory tdb. */
68 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
69 if (!rap_tdb)
70 return 0;
71 }
72
73 ZERO_STRUCT( jinfo );
74 fstrcpy( jinfo.sharename, sharename );
75 jinfo.jobid = jobid;
76 key.dptr = (uint8 *)&jinfo;
77 key.dsize = sizeof(jinfo);
78
79 data = tdb_fetch(rap_tdb, key);
80 if (data.dptr && data.dsize == sizeof(uint16)) {
81 rap_jobid = SVAL(data.dptr, 0);
82 SAFE_FREE(data.dptr);
83 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
84 (unsigned int)jobid, (unsigned int)rap_jobid));
85 return rap_jobid;
86 }
87 SAFE_FREE(data.dptr);
88 /* Not found - create and store mapping. */
89 rap_jobid = ++next_rap_jobid;
90 if (rap_jobid == 0)
91 rap_jobid = ++next_rap_jobid;
92 SSVAL(buf,0,rap_jobid);
93 data.dptr = buf;
94 data.dsize = sizeof(rap_jobid);
95 tdb_store(rap_tdb, key, data, TDB_REPLACE);
96 tdb_store(rap_tdb, data, key, TDB_REPLACE);
97
98 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
99 (unsigned int)jobid, (unsigned int)rap_jobid));
100 return rap_jobid;
101}
102
103bool rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
104{
105 TDB_DATA data, key;
106 uint8 buf[2];
107
108 DEBUG(10,("rap_to_pjobid called.\n"));
109
110 if (!rap_tdb)
111 return False;
112
113 SSVAL(buf,0,rap_jobid);
114 key.dptr = buf;
115 key.dsize = sizeof(rap_jobid);
116 data = tdb_fetch(rap_tdb, key);
117 if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) )
118 {
119 struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
120 if (sharename != NULL) {
121 fstrcpy( sharename, jinfo->sharename );
122 }
123 *pjobid = jinfo->jobid;
124 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
125 (unsigned int)*pjobid, (unsigned int)rap_jobid));
126 SAFE_FREE(data.dptr);
127 return True;
128 }
129
130 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
131 (unsigned int)rap_jobid));
132 SAFE_FREE(data.dptr);
133 return False;
134}
135
136static void rap_jobid_delete(const char* sharename, uint32 jobid)
137{
138 TDB_DATA key, data;
139 uint16 rap_jobid;
140 struct rap_jobid_key jinfo;
141 uint8 buf[2];
142
143 DEBUG(10,("rap_jobid_delete: called.\n"));
144
145 if (!rap_tdb)
146 return;
147
148 ZERO_STRUCT( jinfo );
149 fstrcpy( jinfo.sharename, sharename );
150 jinfo.jobid = jobid;
151 key.dptr = (uint8 *)&jinfo;
152 key.dsize = sizeof(jinfo);
153
154 data = tdb_fetch(rap_tdb, key);
155 if (!data.dptr || (data.dsize != sizeof(uint16))) {
156 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
157 (unsigned int)jobid ));
158 SAFE_FREE(data.dptr);
159 return;
160 }
161
162 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
163 (unsigned int)jobid ));
164
165 rap_jobid = SVAL(data.dptr, 0);
166 SAFE_FREE(data.dptr);
167 SSVAL(buf,0,rap_jobid);
168 data.dptr = buf;
169 data.dsize = sizeof(rap_jobid);
170 tdb_delete(rap_tdb, key);
171 tdb_delete(rap_tdb, data);
172}
173
174static int get_queue_status(const char* sharename, print_status_struct *);
175
176/****************************************************************************
177 Initialise the printing backend. Called once at startup before the fork().
178****************************************************************************/
179
180bool print_backend_init(struct messaging_context *msg_ctx)
181{
182 const char *sversion = "INFO/version";
183 int services = lp_numservices();
184 int snum;
185
186 unlink(cache_path("printing.tdb"));
187 mkdir(cache_path("printing"),0755);
188
189 /* handle a Samba upgrade */
190
191 for (snum = 0; snum < services; snum++) {
192 struct tdb_print_db *pdb;
193 if (!lp_print_ok(snum))
194 continue;
195
196 pdb = get_print_db_byname(lp_const_servicename(snum));
197 if (!pdb)
198 continue;
199 if (tdb_lock_bystring(pdb->tdb, sversion) == -1) {
200 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
201 release_print_db(pdb);
202 return False;
203 }
204 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
205 tdb_wipe_all(pdb->tdb);
206 tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
207 }
208 tdb_unlock_bystring(pdb->tdb, sversion);
209 release_print_db(pdb);
210 }
211
212 close_all_print_db(); /* Don't leave any open. */
213
214 /* do NT print initialization... */
215 return nt_printing_init(msg_ctx);
216}
217
218/****************************************************************************
219 Shut down printing backend. Called once at shutdown to close the tdb.
220****************************************************************************/
221
222void printing_end(void)
223{
224 close_all_print_db(); /* Don't leave any open. */
225}
226
227/****************************************************************************
228 Retrieve the set of printing functions for a given service. This allows
229 us to set the printer function table based on the value of the 'printing'
230 service parameter.
231
232 Use the generic interface as the default and only use cups interface only
233 when asked for (and only when supported)
234****************************************************************************/
235
236static struct printif *get_printer_fns_from_type( enum printing_types type )
237{
238 struct printif *printer_fns = &generic_printif;
239
240#ifdef HAVE_CUPS
241 if ( type == PRINT_CUPS ) {
242 printer_fns = &cups_printif;
243 }
244#endif /* HAVE_CUPS */
245
246#ifdef HAVE_IPRINT
247 if ( type == PRINT_IPRINT ) {
248 printer_fns = &iprint_printif;
249 }
250#endif /* HAVE_IPRINT */
251
252 printer_fns->type = type;
253
254 return printer_fns;
255}
256
257static struct printif *get_printer_fns( int snum )
258{
259 return get_printer_fns_from_type( (enum printing_types)lp_printing(snum) );
260}
261
262
263/****************************************************************************
264 Useful function to generate a tdb key.
265****************************************************************************/
266
267static TDB_DATA print_key(uint32 jobid, uint32 *tmp)
268{
269 TDB_DATA ret;
270
271 SIVAL(tmp, 0, jobid);
272 ret.dptr = (uint8 *)tmp;
273 ret.dsize = sizeof(*tmp);
274 return ret;
275}
276
277/***********************************************************************
278 unpack a pjob from a tdb buffer
279***********************************************************************/
280
281int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )
282{
283 int len = 0;
284 int used;
285 uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
286 uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
287
288 if ( !buf || !pjob )
289 return -1;
290
291 len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
292 &pjpid,
293 &pjsysjob,
294 &pjfd,
295 &pjstarttime,
296 &pjstatus,
297 &pjsize,
298 &pjpage_count,
299 &pjspooled,
300 &pjsmbjob,
301 pjob->filename,
302 pjob->jobname,
303 pjob->user,
304 pjob->queuename);
305
306 if ( len == -1 )
307 return -1;
308
309 if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 )
310 return -1;
311
312 len += used;
313
314 pjob->pid = pjpid;
315 pjob->sysjob = pjsysjob;
316 pjob->fd = pjfd;
317 pjob->starttime = pjstarttime;
318 pjob->status = pjstatus;
319 pjob->size = pjsize;
320 pjob->page_count = pjpage_count;
321 pjob->spooled = pjspooled;
322 pjob->smbjob = pjsmbjob;
323
324 return len;
325
326}
327
328/****************************************************************************
329 Useful function to find a print job in the database.
330****************************************************************************/
331
332static struct printjob *print_job_find(const char *sharename, uint32 jobid)
333{
334 static struct printjob pjob;
335 uint32_t tmp;
336 TDB_DATA ret;
337 struct tdb_print_db *pdb = get_print_db_byname(sharename);
338
339 DEBUG(10,("print_job_find: looking up job %u for share %s\n",
340 (unsigned int)jobid, sharename ));
341
342 if (!pdb) {
343 return NULL;
344 }
345
346 ret = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
347 release_print_db(pdb);
348
349 if (!ret.dptr) {
350 DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid ));
351 return NULL;
352 }
353
354 if ( pjob.nt_devmode ) {
355 free_nt_devicemode( &pjob.nt_devmode );
356 }
357
358 ZERO_STRUCT( pjob );
359
360 if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
361 DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid ));
362 SAFE_FREE(ret.dptr);
363 return NULL;
364 }
365
366 SAFE_FREE(ret.dptr);
367
368 DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
369 (int)pjob.sysjob, (unsigned int)jobid ));
370
371 return &pjob;
372}
373
374/* Convert a unix jobid to a smb jobid */
375
376struct unixjob_traverse_state {
377 int sysjob;
378 uint32 sysjob_to_jobid_value;
379};
380
381static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
382 TDB_DATA data, void *private_data)
383{
384 struct printjob *pjob;
385 struct unixjob_traverse_state *state =
386 (struct unixjob_traverse_state *)private_data;
387
388 if (!data.dptr || data.dsize == 0)
389 return 0;
390
391 pjob = (struct printjob *)data.dptr;
392 if (key.dsize != sizeof(uint32))
393 return 0;
394
395 if (state->sysjob == pjob->sysjob) {
396 uint32 jobid = IVAL(key.dptr,0);
397
398 state->sysjob_to_jobid_value = jobid;
399 return 1;
400 }
401
402 return 0;
403}
404
405/****************************************************************************
406 This is a *horribly expensive call as we have to iterate through all the
407 current printer tdb's. Don't do this often ! JRA.
408****************************************************************************/
409
410uint32 sysjob_to_jobid(int unix_jobid)
411{
412 int services = lp_numservices();
413 int snum;
414 struct unixjob_traverse_state state;
415
416 state.sysjob = unix_jobid;
417 state.sysjob_to_jobid_value = (uint32)-1;
418
419 for (snum = 0; snum < services; snum++) {
420 struct tdb_print_db *pdb;
421 if (!lp_print_ok(snum))
422 continue;
423 pdb = get_print_db_byname(lp_const_servicename(snum));
424 if (!pdb) {
425 continue;
426 }
427 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &state);
428 release_print_db(pdb);
429 if (state.sysjob_to_jobid_value != (uint32)-1)
430 return state.sysjob_to_jobid_value;
431 }
432 return (uint32)-1;
433}
434
435/****************************************************************************
436 Send notifications based on what has changed after a pjob_store.
437****************************************************************************/
438
439static const struct {
440 uint32 lpq_status;
441 uint32 spoolss_status;
442} lpq_to_spoolss_status_map[] = {
443 { LPQ_QUEUED, JOB_STATUS_QUEUED },
444 { LPQ_PAUSED, JOB_STATUS_PAUSED },
445 { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
446 { LPQ_PRINTING, JOB_STATUS_PRINTING },
447 { LPQ_DELETING, JOB_STATUS_DELETING },
448 { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
449 { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
450 { LPQ_PRINTED, JOB_STATUS_PRINTED },
451 { LPQ_DELETED, JOB_STATUS_DELETED },
452 { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ },
453 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
454 { -1, 0 }
455};
456
457/* Convert a lpq status value stored in printing.tdb into the
458 appropriate win32 API constant. */
459
460static uint32 map_to_spoolss_status(uint32 lpq_status)
461{
462 int i = 0;
463
464 while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
465 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
466 return lpq_to_spoolss_status_map[i].spoolss_status;
467 i++;
468 }
469
470 return 0;
471}
472
473static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data,
474 struct printjob *new_data)
475{
476 bool new_job = False;
477
478 if (!old_data)
479 new_job = True;
480
481 /* Job attributes that can't be changed. We only send
482 notification for these on a new job. */
483
484 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
485 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
486 time first or else we'll end up with potential alignment
487 errors. I don't think the systemtime should be spooled as
488 a string, but this gets us around that error.
489 --jerry (i'll feel dirty for this) */
490
491 if (new_job) {
492 notify_job_submitted(sharename, jobid, new_data->starttime);
493 notify_job_username(sharename, jobid, new_data->user);
494 }
495
496 if (new_job || !strequal(old_data->jobname, new_data->jobname))
497 notify_job_name(sharename, jobid, new_data->jobname);
498
499 /* Job attributes of a new job or attributes that can be
500 modified. */
501
502 if (new_job || !strequal(old_data->jobname, new_data->jobname))
503 notify_job_name(sharename, jobid, new_data->jobname);
504
505 if (new_job || old_data->status != new_data->status)
506 notify_job_status(sharename, jobid, map_to_spoolss_status(new_data->status));
507
508 if (new_job || old_data->size != new_data->size)
509 notify_job_total_bytes(sharename, jobid, new_data->size);
510
511 if (new_job || old_data->page_count != new_data->page_count)
512 notify_job_total_pages(sharename, jobid, new_data->page_count);
513}
514
515/****************************************************************************
516 Store a job structure back to the database.
517****************************************************************************/
518
519static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob)
520{
521 uint32_t tmp;
522 TDB_DATA old_data, new_data;
523 bool ret = False;
524 struct tdb_print_db *pdb = get_print_db_byname(sharename);
525 uint8 *buf = NULL;
526 int len, newlen, buflen;
527
528
529 if (!pdb)
530 return False;
531
532 /* Get old data */
533
534 old_data = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
535
536 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
537
538 newlen = 0;
539
540 do {
541 len = 0;
542 buflen = newlen;
543 len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
544 (uint32)pjob->pid,
545 (uint32)pjob->sysjob,
546 (uint32)pjob->fd,
547 (uint32)pjob->starttime,
548 (uint32)pjob->status,
549 (uint32)pjob->size,
550 (uint32)pjob->page_count,
551 (uint32)pjob->spooled,
552 (uint32)pjob->smbjob,
553 pjob->filename,
554 pjob->jobname,
555 pjob->user,
556 pjob->queuename);
557
558 len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len);
559
560 if (buflen != len) {
561 buf = (uint8 *)SMB_REALLOC(buf, len);
562 if (!buf) {
563 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
564 goto done;
565 }
566 newlen = len;
567 }
568 } while ( buflen != len );
569
570
571 /* Store new data */
572
573 new_data.dptr = buf;
574 new_data.dsize = len;
575 ret = (tdb_store(pdb->tdb, print_key(jobid, &tmp), new_data,
576 TDB_REPLACE) == 0);
577
578 release_print_db(pdb);
579
580 /* Send notify updates for what has changed */
581
582 if ( ret ) {
583 struct printjob old_pjob;
584
585 if ( old_data.dsize )
586 {
587 if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
588 {
589 pjob_store_notify( sharename, jobid, &old_pjob , pjob );
590 free_nt_devicemode( &old_pjob.nt_devmode );
591 }
592 }
593 else {
594 /* new job */
595 pjob_store_notify( sharename, jobid, NULL, pjob );
596 }
597 }
598
599done:
600 SAFE_FREE( old_data.dptr );
601 SAFE_FREE( buf );
602
603 return ret;
604}
605
606/****************************************************************************
607 Remove a job structure from the database.
608****************************************************************************/
609
610void pjob_delete(const char* sharename, uint32 jobid)
611{
612 uint32_t tmp;
613 struct printjob *pjob;
614 uint32 job_status = 0;
615 struct tdb_print_db *pdb;
616
617 pdb = get_print_db_byname( sharename );
618
619 if (!pdb)
620 return;
621
622 pjob = print_job_find( sharename, jobid );
623
624 if (!pjob) {
625 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
626 (unsigned int)jobid));
627 release_print_db(pdb);
628 return;
629 }
630
631 /* We must cycle through JOB_STATUS_DELETING and
632 JOB_STATUS_DELETED for the port monitor to delete the job
633 properly. */
634
635 job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
636 notify_job_status(sharename, jobid, job_status);
637
638 /* Remove from printing.tdb */
639
640 tdb_delete(pdb->tdb, print_key(jobid, &tmp));
641 remove_from_jobs_changed(sharename, jobid);
642 release_print_db( pdb );
643 rap_jobid_delete(sharename, jobid);
644}
645
646/****************************************************************************
647 List a unix job in the print database.
648****************************************************************************/
649
650static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid)
651{
652 struct printjob pj, *old_pj;
653
654 if (jobid == (uint32)-1)
655 jobid = q->job + UNIX_JOB_START;
656
657 /* Preserve the timestamp on an existing unix print job */
658
659 old_pj = print_job_find(sharename, jobid);
660
661 ZERO_STRUCT(pj);
662
663 pj.pid = (pid_t)-1;
664 pj.sysjob = q->job;
665 pj.fd = -1;
666 pj.starttime = old_pj ? old_pj->starttime : q->time;
667 pj.status = q->status;
668 pj.size = q->size;
669 pj.spooled = True;
670 fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
671 if (jobid < UNIX_JOB_START) {
672 pj.smbjob = True;
673 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
674 } else {
675 pj.smbjob = False;
676 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
677 }
678 fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
679 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
680
681 pjob_store(sharename, jobid, &pj);
682}
683
684
685struct traverse_struct {
686 print_queue_struct *queue;
687 int qcount, snum, maxcount, total_jobs;
688 const char *sharename;
689 time_t lpq_time;
690 const char *lprm_command;
691 struct printif *print_if;
692};
693
694/****************************************************************************
695 Utility fn to delete any jobs that are no longer active.
696****************************************************************************/
697
698static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
699{
700 struct traverse_struct *ts = (struct traverse_struct *)state;
701 struct printjob pjob;
702 uint32 jobid;
703 int i = 0;
704
705 if ( key.dsize != sizeof(jobid) )
706 return 0;
707
708 jobid = IVAL(key.dptr, 0);
709 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
710 return 0;
711 free_nt_devicemode( &pjob.nt_devmode );
712
713
714 if (!pjob.smbjob) {
715 /* remove a unix job if it isn't in the system queue any more */
716
717 for (i=0;i<ts->qcount;i++) {
718 uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
719 if (jobid == u_jobid)
720 break;
721 }
722 if (i == ts->qcount) {
723 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
724 (unsigned int)jobid ));
725 pjob_delete(ts->sharename, jobid);
726 return 0;
727 }
728
729 /* need to continue the the bottom of the function to
730 save the correct attributes */
731 }
732
733 /* maybe it hasn't been spooled yet */
734 if (!pjob.spooled) {
735 /* if a job is not spooled and the process doesn't
736 exist then kill it. This cleans up after smbd
737 deaths */
738 if (!process_exists_by_pid(pjob.pid)) {
739 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
740 (unsigned int)jobid, (unsigned int)pjob.pid ));
741 pjob_delete(ts->sharename, jobid);
742 } else
743 ts->total_jobs++;
744 return 0;
745 }
746
747 /* this check only makes sense for jobs submitted from Windows clients */
748
749 if ( pjob.smbjob ) {
750 for (i=0;i<ts->qcount;i++) {
751 uint32 curr_jobid;
752
753 if ( pjob.status == LPQ_DELETED )
754 continue;
755
756 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
757
758 if (jobid == curr_jobid) {
759
760 /* try to clean up any jobs that need to be deleted */
761
762 if ( pjob.status == LPQ_DELETING ) {
763 int result;
764
765 result = (*(ts->print_if->job_delete))(
766 ts->sharename, ts->lprm_command, &pjob );
767
768 if ( result != 0 ) {
769 /* if we can't delete, then reset the job status */
770 pjob.status = LPQ_QUEUED;
771 pjob_store(ts->sharename, jobid, &pjob);
772 }
773 else {
774 /* if we deleted the job, the remove the tdb record */
775 pjob_delete(ts->sharename, jobid);
776 pjob.status = LPQ_DELETED;
777 }
778
779 }
780
781 break;
782 }
783 }
784 }
785
786 /* The job isn't in the system queue - we have to assume it has
787 completed, so delete the database entry. */
788
789 if (i == ts->qcount) {
790
791 /* A race can occur between the time a job is spooled and
792 when it appears in the lpq output. This happens when
793 the job is added to printing.tdb when another smbd
794 running print_queue_update() has completed a lpq and
795 is currently traversing the printing tdb and deleting jobs.
796 Don't delete the job if it was submitted after the lpq_time. */
797
798 if (pjob.starttime < ts->lpq_time) {
799 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
800 (unsigned int)jobid,
801 (unsigned int)pjob.starttime,
802 (unsigned int)ts->lpq_time ));
803 pjob_delete(ts->sharename, jobid);
804 } else
805 ts->total_jobs++;
806 return 0;
807 }
808
809 /* Save the pjob attributes we will store.
810 FIXME!!! This is the only place where queue->job
811 represents the SMB jobid --jerry */
812
813 ts->queue[i].job = jobid;
814 ts->queue[i].size = pjob.size;
815 ts->queue[i].page_count = pjob.page_count;
816 ts->queue[i].status = pjob.status;
817 ts->queue[i].priority = 1;
818 ts->queue[i].time = pjob.starttime;
819 fstrcpy(ts->queue[i].fs_user, pjob.user);
820 fstrcpy(ts->queue[i].fs_file, pjob.jobname);
821
822 ts->total_jobs++;
823
824 return 0;
825}
826
827/****************************************************************************
828 Check if the print queue has been updated recently enough.
829****************************************************************************/
830
831static void print_cache_flush(const char *sharename)
832{
833 fstring key;
834 struct tdb_print_db *pdb = get_print_db_byname(sharename);
835
836 if (!pdb)
837 return;
838 slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
839 tdb_store_int32(pdb->tdb, key, -1);
840 release_print_db(pdb);
841}
842
843/****************************************************************************
844 Check if someone already thinks they are doing the update.
845****************************************************************************/
846
847static pid_t get_updating_pid(const char *sharename)
848{
849 fstring keystr;
850 TDB_DATA data, key;
851 pid_t updating_pid;
852 struct tdb_print_db *pdb = get_print_db_byname(sharename);
853
854 if (!pdb)
855 return (pid_t)-1;
856 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
857 key = string_tdb_data(keystr);
858
859 data = tdb_fetch(pdb->tdb, key);
860 release_print_db(pdb);
861 if (!data.dptr || data.dsize != sizeof(pid_t)) {
862 SAFE_FREE(data.dptr);
863 return (pid_t)-1;
864 }
865
866 updating_pid = IVAL(data.dptr, 0);
867 SAFE_FREE(data.dptr);
868
869 if (process_exists_by_pid(updating_pid))
870 return updating_pid;
871
872 return (pid_t)-1;
873}
874
875/****************************************************************************
876 Set the fact that we're doing the update, or have finished doing the update
877 in the tdb.
878****************************************************************************/
879
880static void set_updating_pid(const fstring sharename, bool updating)
881{
882 fstring keystr;
883 TDB_DATA key;
884 TDB_DATA data;
885 pid_t updating_pid = sys_getpid();
886 uint8 buffer[4];
887
888 struct tdb_print_db *pdb = get_print_db_byname(sharename);
889
890 if (!pdb)
891 return;
892
893 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
894 key = string_tdb_data(keystr);
895
896 DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
897 updating ? "" : "not ",
898 sharename ));
899
900 if ( !updating ) {
901 tdb_delete(pdb->tdb, key);
902 release_print_db(pdb);
903 return;
904 }
905
906 SIVAL( buffer, 0, updating_pid);
907 data.dptr = buffer;
908 data.dsize = 4; /* we always assume this is a 4 byte value */
909
910 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
911 release_print_db(pdb);
912}
913
914/****************************************************************************
915 Sort print jobs by submittal time.
916****************************************************************************/
917
918static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
919{
920 /* Silly cases */
921
922 if (!j1 && !j2)
923 return 0;
924 if (!j1)
925 return -1;
926 if (!j2)
927 return 1;
928
929 /* Sort on job start time */
930
931 if (j1->time == j2->time)
932 return 0;
933 return (j1->time > j2->time) ? 1 : -1;
934}
935
936/****************************************************************************
937 Store the sorted queue representation for later portmon retrieval.
938 Skip deleted jobs
939****************************************************************************/
940
941static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
942{
943 TDB_DATA data;
944 int max_reported_jobs = lp_max_reported_jobs(pts->snum);
945 print_queue_struct *queue = pts->queue;
946 size_t len;
947 size_t i;
948 unsigned int qcount;
949
950 if (max_reported_jobs && (max_reported_jobs < pts->qcount))
951 pts->qcount = max_reported_jobs;
952 qcount = 0;
953
954 /* Work out the size. */
955 data.dsize = 0;
956 data.dsize += tdb_pack(NULL, 0, "d", qcount);
957
958 for (i = 0; i < pts->qcount; i++) {
959 if ( queue[i].status == LPQ_DELETED )
960 continue;
961
962 qcount++;
963 data.dsize += tdb_pack(NULL, 0, "ddddddff",
964 (uint32)queue[i].job,
965 (uint32)queue[i].size,
966 (uint32)queue[i].page_count,
967 (uint32)queue[i].status,
968 (uint32)queue[i].priority,
969 (uint32)queue[i].time,
970 queue[i].fs_user,
971 queue[i].fs_file);
972 }
973
974 if ((data.dptr = (uint8 *)SMB_MALLOC(data.dsize)) == NULL)
975 return;
976
977 len = 0;
978 len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
979 for (i = 0; i < pts->qcount; i++) {
980 if ( queue[i].status == LPQ_DELETED )
981 continue;
982
983 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
984 (uint32)queue[i].job,
985 (uint32)queue[i].size,
986 (uint32)queue[i].page_count,
987 (uint32)queue[i].status,
988 (uint32)queue[i].priority,
989 (uint32)queue[i].time,
990 queue[i].fs_user,
991 queue[i].fs_file);
992 }
993
994 tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
995 TDB_REPLACE);
996 SAFE_FREE(data.dptr);
997 return;
998}
999
1000static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
1001{
1002 TDB_DATA data;
1003
1004 ZERO_STRUCT(data);
1005
1006 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
1007 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
1008 SAFE_FREE(data.dptr);
1009 ZERO_STRUCT(data);
1010 }
1011
1012 return data;
1013}
1014
1015static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid)
1016{
1017 unsigned int i;
1018 unsigned int job_count = data.dsize / 4;
1019
1020 for (i = 0; i < job_count; i++) {
1021 uint32 ch_jobid;
1022
1023 ch_jobid = IVAL(data.dptr, i*4);
1024 if (ch_jobid == jobid)
1025 remove_from_jobs_changed(sharename, jobid);
1026 }
1027}
1028
1029/****************************************************************************
1030 Check if the print queue has been updated recently enough.
1031****************************************************************************/
1032
1033static bool print_cache_expired(const char *sharename, bool check_pending)
1034{
1035 fstring key;
1036 time_t last_qscan_time, time_now = time(NULL);
1037 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1038 bool result = False;
1039
1040 if (!pdb)
1041 return False;
1042
1043 snprintf(key, sizeof(key), "CACHE/%s", sharename);
1044 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1045
1046 /*
1047 * Invalidate the queue for 3 reasons.
1048 * (1). last queue scan time == -1.
1049 * (2). Current time - last queue scan time > allowed cache time.
1050 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1051 * This last test picks up machines for which the clock has been moved
1052 * forward, an lpq scan done and then the clock moved back. Otherwise
1053 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1054 */
1055
1056 if (last_qscan_time == ((time_t)-1)
1057 || (time_now - last_qscan_time) >= lp_lpqcachetime()
1058 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
1059 {
1060 uint32 u;
1061 time_t msg_pending_time;
1062
1063 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1064 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1065 sharename, (int)last_qscan_time, (int)time_now,
1066 (int)lp_lpqcachetime() ));
1067
1068 /* check if another smbd has already sent a message to update the
1069 queue. Give the pending message one minute to clear and
1070 then send another message anyways. Make sure to check for
1071 clocks that have been run forward and then back again. */
1072
1073 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1074
1075 if ( check_pending
1076 && tdb_fetch_uint32( pdb->tdb, key, &u )
1077 && (msg_pending_time=u) > 0
1078 && msg_pending_time <= time_now
1079 && (time_now - msg_pending_time) < 60 )
1080 {
1081 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1082 sharename));
1083 goto done;
1084 }
1085
1086 result = True;
1087 }
1088
1089done:
1090 release_print_db(pdb);
1091 return result;
1092}
1093
1094/****************************************************************************
1095 main work for updating the lpq cahe for a printer queue
1096****************************************************************************/
1097
1098static void print_queue_update_internal( const char *sharename,
1099 struct printif *current_printif,
1100 char *lpq_command, char *lprm_command )
1101{
1102 int i, qcount;
1103 print_queue_struct *queue = NULL;
1104 print_status_struct status;
1105 print_status_struct old_status;
1106 struct printjob *pjob;
1107 struct traverse_struct tstruct;
1108 TDB_DATA data, key;
1109 TDB_DATA jcdata;
1110 fstring keystr, cachestr;
1111 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1112
1113 if (!pdb) {
1114 return;
1115 }
1116
1117 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1118 sharename, current_printif->type, lpq_command));
1119
1120 /*
1121 * Update the cache time FIRST ! Stops others even
1122 * attempting to get the lock and doing this
1123 * if the lpq takes a long time.
1124 */
1125
1126 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1127 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1128
1129 /* get the current queue using the appropriate interface */
1130 ZERO_STRUCT(status);
1131
1132 qcount = (*(current_printif->queue_get))(sharename,
1133 current_printif->type,
1134 lpq_command, &queue, &status);
1135
1136 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1137 qcount, (qcount != 1) ? "s" : "", sharename));
1138
1139 /* Sort the queue by submission time otherwise they are displayed
1140 in hash order. */
1141
1142 qsort(queue, qcount, sizeof(print_queue_struct),
1143 QSORT_CAST(printjob_comp));
1144
1145 /*
1146 any job in the internal database that is marked as spooled
1147 and doesn't exist in the system queue is considered finished
1148 and removed from the database
1149
1150 any job in the system database but not in the internal database
1151 is added as a unix job
1152
1153 fill in any system job numbers as we go
1154 */
1155
1156 jcdata = get_jobs_changed_data(pdb);
1157
1158 for (i=0; i<qcount; i++) {
1159 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1160
1161 if (jobid == (uint32)-1) {
1162 /* assume its a unix print job */
1163 print_unix_job(sharename, &queue[i], jobid);
1164 continue;
1165 }
1166
1167 /* we have an active SMB print job - update its status */
1168 pjob = print_job_find(sharename, jobid);
1169 if (!pjob) {
1170 /* err, somethings wrong. Probably smbd was restarted
1171 with jobs in the queue. All we can do is treat them
1172 like unix jobs. Pity. */
1173 print_unix_job(sharename, &queue[i], jobid);
1174 continue;
1175 }
1176
1177 pjob->sysjob = queue[i].job;
1178
1179 /* don't reset the status on jobs to be deleted */
1180
1181 if ( pjob->status != LPQ_DELETING )
1182 pjob->status = queue[i].status;
1183
1184 pjob_store(sharename, jobid, pjob);
1185
1186 check_job_changed(sharename, jcdata, jobid);
1187 }
1188
1189 SAFE_FREE(jcdata.dptr);
1190
1191 /* now delete any queued entries that don't appear in the
1192 system queue */
1193 tstruct.queue = queue;
1194 tstruct.qcount = qcount;
1195 tstruct.snum = -1;
1196 tstruct.total_jobs = 0;
1197 tstruct.lpq_time = time(NULL);
1198 tstruct.sharename = sharename;
1199 tstruct.lprm_command = lprm_command;
1200 tstruct.print_if = current_printif;
1201
1202 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1203
1204 /* Store the linearised queue, max jobs only. */
1205 store_queue_struct(pdb, &tstruct);
1206
1207 SAFE_FREE(tstruct.queue);
1208
1209 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1210 sharename, tstruct.total_jobs ));
1211
1212 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1213
1214 get_queue_status(sharename, &old_status);
1215 if (old_status.qcount != qcount)
1216 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1217 old_status.qcount, qcount, sharename));
1218
1219 /* store the new queue status structure */
1220 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1221 key = string_tdb_data(keystr);
1222
1223 status.qcount = qcount;
1224 data.dptr = (uint8 *)&status;
1225 data.dsize = sizeof(status);
1226 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1227
1228 /*
1229 * Update the cache time again. We want to do this call
1230 * as little as possible...
1231 */
1232
1233 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1234 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1235
1236 /* clear the msg pending record for this queue */
1237
1238 snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1239
1240 if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1241 /* log a message but continue on */
1242
1243 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1244 sharename));
1245 }
1246
1247 release_print_db( pdb );
1248
1249 return;
1250}
1251
1252/****************************************************************************
1253 Update the internal database from the system print queue for a queue.
1254 obtain a lock on the print queue before proceeding (needed when mutiple
1255 smbd processes maytry to update the lpq cache concurrently).
1256****************************************************************************/
1257
1258static void print_queue_update_with_lock( const char *sharename,
1259 struct printif *current_printif,
1260 char *lpq_command, char *lprm_command )
1261{
1262 fstring keystr;
1263 struct tdb_print_db *pdb;
1264
1265 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1266 pdb = get_print_db_byname(sharename);
1267 if (!pdb)
1268 return;
1269
1270 if ( !print_cache_expired(sharename, False) ) {
1271 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1272 release_print_db(pdb);
1273 return;
1274 }
1275
1276 /*
1277 * Check to see if someone else is doing this update.
1278 * This is essentially a mutex on the update.
1279 */
1280
1281 if (get_updating_pid(sharename) != -1) {
1282 release_print_db(pdb);
1283 return;
1284 }
1285
1286 /* Lock the queue for the database update */
1287
1288 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1289 /* Only wait 10 seconds for this. */
1290 if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
1291 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1292 release_print_db(pdb);
1293 return;
1294 }
1295
1296 /*
1297 * Ensure that no one else got in here.
1298 * If the updating pid is still -1 then we are
1299 * the winner.
1300 */
1301
1302 if (get_updating_pid(sharename) != -1) {
1303 /*
1304 * Someone else is doing the update, exit.
1305 */
1306 tdb_unlock_bystring(pdb->tdb, keystr);
1307 release_print_db(pdb);
1308 return;
1309 }
1310
1311 /*
1312 * We're going to do the update ourselves.
1313 */
1314
1315 /* Tell others we're doing the update. */
1316 set_updating_pid(sharename, True);
1317
1318 /*
1319 * Allow others to enter and notice we're doing
1320 * the update.
1321 */
1322
1323 tdb_unlock_bystring(pdb->tdb, keystr);
1324
1325 /* do the main work now */
1326
1327 print_queue_update_internal( sharename, current_printif,
1328 lpq_command, lprm_command );
1329
1330 /* Delete our pid from the db. */
1331 set_updating_pid(sharename, False);
1332 release_print_db(pdb);
1333}
1334
1335/****************************************************************************
1336this is the receive function of the background lpq updater
1337****************************************************************************/
1338static void print_queue_receive(struct messaging_context *msg,
1339 void *private_data,
1340 uint32_t msg_type,
1341 struct server_id server_id,
1342 DATA_BLOB *data)
1343{
1344 fstring sharename;
1345 char *lpqcommand = NULL, *lprmcommand = NULL;
1346 int printing_type;
1347 size_t len;
1348
1349 len = tdb_unpack( (uint8 *)data->data, data->length, "fdPP",
1350 sharename,
1351 &printing_type,
1352 &lpqcommand,
1353 &lprmcommand );
1354
1355 if ( len == -1 ) {
1356 SAFE_FREE(lpqcommand);
1357 SAFE_FREE(lprmcommand);
1358 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1359 return;
1360 }
1361
1362 print_queue_update_with_lock(sharename,
1363 get_printer_fns_from_type((enum printing_types)printing_type),
1364 lpqcommand, lprmcommand );
1365
1366 SAFE_FREE(lpqcommand);
1367 SAFE_FREE(lprmcommand);
1368 return;
1369}
1370
1371static void printing_pause_fd_handler(struct tevent_context *ev,
1372 struct tevent_fd *fde,
1373 uint16_t flags,
1374 void *private_data)
1375{
1376 /*
1377 * If pause_pipe[1] is closed it means the parent smbd
1378 * and children exited or aborted.
1379 */
1380 exit_server_cleanly(NULL);
1381}
1382
1383static void add_child_pid(pid_t pid)
1384{
1385 extern struct child_pid *children;
1386 struct child_pid *child;
1387 extern int num_children;
1388
1389 child = SMB_MALLOC_P(struct child_pid);
1390 if (child == NULL) {
1391 DEBUG(0, ("Could not add child struct -- malloc failed\n"));
1392 return;
1393 }
1394 child->pid = pid;
1395 DLIST_ADD(children, child);
1396 num_children += 1;
1397}
1398
1399static pid_t background_lpq_updater_pid = -1;
1400
1401/****************************************************************************
1402main thread of the background lpq updater
1403****************************************************************************/
1404void start_background_queue(void)
1405{
1406 /* Use local variables for this as we don't
1407 * need to save the parent side of this, just
1408 * ensure it closes when the process exits.
1409 */
1410 int pause_pipe[2];
1411
1412 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1413
1414#ifndef __OS2__
1415 if (pipe(pause_pipe) == -1) {
1416#else // on OS2 we have no select() on pipes, so we use socketpair() instead
1417 if (socketpair(AF_UNIX, SOCK_STREAM,0, pause_pipe) < 0) {
1418#endif
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.