s3: Lift the server_messaging_context from notify_job_username
[Samba/gbeck.git] / source3 / printing / printing.c
blobfe42f55d1e2081a88e53996260722619b462404f
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
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.
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.
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/>.
22 #include "includes.h"
23 #include "printing.h"
24 #include "librpc/gen_ndr/messaging.h"
25 #include "../librpc/gen_ndr/ndr_spoolss.h"
26 #include "nt_printing.h"
27 #include "../librpc/gen_ndr/netlogon.h"
29 extern struct current_user current_user;
30 extern userdom_struct current_user_info;
32 /* Current printer interface */
33 static bool remove_from_jobs_changed(const char* sharename, uint32 jobid);
36 the printing backend revolves around a tdb database that stores the
37 SMB view of the print queue
39 The key for this database is a jobid - a internally generated number that
40 uniquely identifies a print job
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
46 jobids are assigned when a job starts spooling.
49 static TDB_CONTEXT *rap_tdb;
50 static uint16 next_rap_jobid;
51 struct rap_jobid_key {
52 fstring sharename;
53 uint32 jobid;
56 /***************************************************************************
57 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
58 bit RPC jobids.... JRA.
59 ***************************************************************************/
61 uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
63 uint16 rap_jobid;
64 TDB_DATA data, key;
65 struct rap_jobid_key jinfo;
66 uint8 buf[2];
68 DEBUG(10,("pjobid_to_rap: called.\n"));
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;
77 ZERO_STRUCT( jinfo );
78 fstrcpy( jinfo.sharename, sharename );
79 jinfo.jobid = jobid;
80 key.dptr = (uint8 *)&jinfo;
81 key.dsize = sizeof(jinfo);
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;
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);
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;
107 bool rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
109 TDB_DATA data, key;
110 uint8 buf[2];
112 DEBUG(10,("rap_to_pjobid called.\n"));
114 if (!rap_tdb)
115 return False;
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) )
123 struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
124 if (sharename != NULL) {
125 fstrcpy( sharename, jinfo->sharename );
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;
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;
140 void rap_jobid_delete(const char* sharename, uint32 jobid)
142 TDB_DATA key, data;
143 uint16 rap_jobid;
144 struct rap_jobid_key jinfo;
145 uint8 buf[2];
147 DEBUG(10,("rap_jobid_delete: called.\n"));
149 if (!rap_tdb)
150 return;
152 ZERO_STRUCT( jinfo );
153 fstrcpy( jinfo.sharename, sharename );
154 jinfo.jobid = jobid;
155 key.dptr = (uint8 *)&jinfo;
156 key.dsize = sizeof(jinfo);
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;
166 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
167 (unsigned int)jobid ));
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);
178 static int get_queue_status(const char* sharename, print_status_struct *);
180 /****************************************************************************
181 Initialise the printing backend. Called once at startup before the fork().
182 ****************************************************************************/
184 bool print_backend_init(struct messaging_context *msg_ctx)
186 const char *sversion = "INFO/version";
187 int services = lp_numservices();
188 int snum;
190 unlink(cache_path("printing.tdb"));
191 mkdir(cache_path("printing"),0755);
193 /* handle a Samba upgrade */
195 for (snum = 0; snum < services; snum++) {
196 struct tdb_print_db *pdb;
197 if (!lp_print_ok(snum))
198 continue;
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;
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);
212 tdb_unlock_bystring(pdb->tdb, sversion);
213 release_print_db(pdb);
216 close_all_print_db(); /* Don't leave any open. */
218 /* do NT print initialization... */
219 return nt_printing_init(msg_ctx);
222 /****************************************************************************
223 Shut down printing backend. Called once at shutdown to close the tdb.
224 ****************************************************************************/
226 void printing_end(void)
228 close_all_print_db(); /* Don't leave any open. */
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.
236 Use the generic interface as the default and only use cups interface only
237 when asked for (and only when supported)
238 ****************************************************************************/
240 static struct printif *get_printer_fns_from_type( enum printing_types type )
242 struct printif *printer_fns = &generic_printif;
244 #ifdef HAVE_CUPS
245 if ( type == PRINT_CUPS ) {
246 printer_fns = &cups_printif;
248 #endif /* HAVE_CUPS */
250 #ifdef HAVE_IPRINT
251 if ( type == PRINT_IPRINT ) {
252 printer_fns = &iprint_printif;
254 #endif /* HAVE_IPRINT */
256 printer_fns->type = type;
258 return printer_fns;
261 static struct printif *get_printer_fns( int snum )
263 return get_printer_fns_from_type( (enum printing_types)lp_printing(snum) );
267 /****************************************************************************
268 Useful function to generate a tdb key.
269 ****************************************************************************/
271 static TDB_DATA print_key(uint32 jobid, uint32 *tmp)
273 TDB_DATA ret;
275 SIVAL(tmp, 0, jobid);
276 ret.dptr = (uint8 *)tmp;
277 ret.dsize = sizeof(*tmp);
278 return ret;
281 /****************************************************************************
282 Pack the devicemode to store it in a tdb.
283 ****************************************************************************/
284 static int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8 *buf, int buflen)
286 enum ndr_err_code ndr_err;
287 DATA_BLOB blob;
288 int len = 0;
290 if (devmode) {
291 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(),
292 devmode,
293 (ndr_push_flags_fn_t)
294 ndr_push_spoolss_DeviceMode);
295 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
296 DEBUG(10, ("pack_devicemode: "
297 "error encoding spoolss_DeviceMode\n"));
298 goto done;
300 } else {
301 ZERO_STRUCT(blob);
304 len = tdb_pack(buf, buflen, "B", blob.length, blob.data);
306 if (devmode) {
307 DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname));
310 done:
311 return len;
314 /****************************************************************************
315 Unpack the devicemode to store it in a tdb.
316 ****************************************************************************/
317 static int unpack_devicemode(TALLOC_CTX *mem_ctx,
318 const uint8 *buf, int buflen,
319 struct spoolss_DeviceMode **devmode)
321 struct spoolss_DeviceMode *dm;
322 enum ndr_err_code ndr_err;
323 char *data = NULL;
324 int data_len = 0;
325 DATA_BLOB blob;
326 int len = 0;
328 *devmode = NULL;
330 len = tdb_unpack(buf, buflen, "B", &data_len, &data);
331 if (!data) {
332 return len;
335 dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
336 if (!dm) {
337 goto done;
340 blob = data_blob_const(data, data_len);
342 ndr_err = ndr_pull_struct_blob(&blob, dm, dm,
343 (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);
344 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
345 DEBUG(10, ("unpack_devicemode: "
346 "error parsing spoolss_DeviceMode\n"));
347 goto done;
350 DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
351 dm->devicename, dm->formname));
352 if (dm->driverextra_data.data) {
353 DEBUG(8, ("with a private section of %d bytes\n",
354 dm->__driverextra_length));
357 *devmode = dm;
359 done:
360 SAFE_FREE(data);
361 return len;
364 /***********************************************************************
365 unpack a pjob from a tdb buffer
366 ***********************************************************************/
368 int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )
370 int len = 0;
371 int used;
372 uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
373 uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
375 if ( !buf || !pjob )
376 return -1;
378 len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
379 &pjpid,
380 &pjsysjob,
381 &pjfd,
382 &pjstarttime,
383 &pjstatus,
384 &pjsize,
385 &pjpage_count,
386 &pjspooled,
387 &pjsmbjob,
388 pjob->filename,
389 pjob->jobname,
390 pjob->user,
391 pjob->queuename);
393 if ( len == -1 )
394 return -1;
396 used = unpack_devicemode(NULL, buf+len, buflen-len, &pjob->devmode);
397 if (used == -1) {
398 return -1;
401 len += used;
403 pjob->pid = pjpid;
404 pjob->sysjob = pjsysjob;
405 pjob->fd = pjfd;
406 pjob->starttime = pjstarttime;
407 pjob->status = pjstatus;
408 pjob->size = pjsize;
409 pjob->page_count = pjpage_count;
410 pjob->spooled = pjspooled;
411 pjob->smbjob = pjsmbjob;
413 return len;
417 /****************************************************************************
418 Useful function to find a print job in the database.
419 ****************************************************************************/
421 static struct printjob *print_job_find(const char *sharename, uint32 jobid)
423 static struct printjob pjob;
424 uint32_t tmp;
425 TDB_DATA ret;
426 struct tdb_print_db *pdb = get_print_db_byname(sharename);
428 DEBUG(10,("print_job_find: looking up job %u for share %s\n",
429 (unsigned int)jobid, sharename ));
431 if (!pdb) {
432 return NULL;
435 ret = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
436 release_print_db(pdb);
438 if (!ret.dptr) {
439 DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid ));
440 return NULL;
443 talloc_free(pjob.devmode);
445 ZERO_STRUCT( pjob );
447 if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
448 DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid ));
449 SAFE_FREE(ret.dptr);
450 return NULL;
453 SAFE_FREE(ret.dptr);
455 DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
456 (int)pjob.sysjob, (unsigned int)jobid ));
458 return &pjob;
461 /* Convert a unix jobid to a smb jobid */
463 struct unixjob_traverse_state {
464 int sysjob;
465 uint32 sysjob_to_jobid_value;
468 static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
469 TDB_DATA data, void *private_data)
471 struct printjob *pjob;
472 struct unixjob_traverse_state *state =
473 (struct unixjob_traverse_state *)private_data;
475 if (!data.dptr || data.dsize == 0)
476 return 0;
478 pjob = (struct printjob *)data.dptr;
479 if (key.dsize != sizeof(uint32))
480 return 0;
482 if (state->sysjob == pjob->sysjob) {
483 uint32 jobid = IVAL(key.dptr,0);
485 state->sysjob_to_jobid_value = jobid;
486 return 1;
489 return 0;
492 /****************************************************************************
493 This is a *horribly expensive call as we have to iterate through all the
494 current printer tdb's. Don't do this often ! JRA.
495 ****************************************************************************/
497 uint32 sysjob_to_jobid(int unix_jobid)
499 int services = lp_numservices();
500 int snum;
501 struct unixjob_traverse_state state;
503 state.sysjob = unix_jobid;
504 state.sysjob_to_jobid_value = (uint32)-1;
506 for (snum = 0; snum < services; snum++) {
507 struct tdb_print_db *pdb;
508 if (!lp_print_ok(snum))
509 continue;
510 pdb = get_print_db_byname(lp_const_servicename(snum));
511 if (!pdb) {
512 continue;
514 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &state);
515 release_print_db(pdb);
516 if (state.sysjob_to_jobid_value != (uint32)-1)
517 return state.sysjob_to_jobid_value;
519 return (uint32)-1;
522 /****************************************************************************
523 Send notifications based on what has changed after a pjob_store.
524 ****************************************************************************/
526 static const struct {
527 uint32 lpq_status;
528 uint32 spoolss_status;
529 } lpq_to_spoolss_status_map[] = {
530 { LPQ_QUEUED, JOB_STATUS_QUEUED },
531 { LPQ_PAUSED, JOB_STATUS_PAUSED },
532 { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
533 { LPQ_PRINTING, JOB_STATUS_PRINTING },
534 { LPQ_DELETING, JOB_STATUS_DELETING },
535 { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
536 { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
537 { LPQ_PRINTED, JOB_STATUS_PRINTED },
538 { LPQ_DELETED, JOB_STATUS_DELETED },
539 { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ },
540 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
541 { -1, 0 }
544 /* Convert a lpq status value stored in printing.tdb into the
545 appropriate win32 API constant. */
547 static uint32 map_to_spoolss_status(uint32 lpq_status)
549 int i = 0;
551 while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
552 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
553 return lpq_to_spoolss_status_map[i].spoolss_status;
554 i++;
557 return 0;
560 static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data,
561 struct printjob *new_data)
563 bool new_job = False;
565 if (!old_data)
566 new_job = True;
568 /* Job attributes that can't be changed. We only send
569 notification for these on a new job. */
571 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
572 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
573 time first or else we'll end up with potential alignment
574 errors. I don't think the systemtime should be spooled as
575 a string, but this gets us around that error.
576 --jerry (i'll feel dirty for this) */
578 if (new_job) {
579 notify_job_submitted(sharename, jobid, new_data->starttime);
580 notify_job_username(server_event_context(),
581 server_messaging_context(),
582 sharename, jobid, new_data->user);
585 if (new_job || !strequal(old_data->jobname, new_data->jobname))
586 notify_job_name(sharename, jobid, new_data->jobname);
588 /* Job attributes of a new job or attributes that can be
589 modified. */
591 if (new_job || !strequal(old_data->jobname, new_data->jobname))
592 notify_job_name(sharename, jobid, new_data->jobname);
594 if (new_job || old_data->status != new_data->status)
595 notify_job_status(server_event_context(),
596 server_messaging_context(),
597 sharename, jobid,
598 map_to_spoolss_status(new_data->status));
600 if (new_job || old_data->size != new_data->size)
601 notify_job_total_bytes(server_event_context(),
602 server_messaging_context(),
603 sharename, jobid, new_data->size);
605 if (new_job || old_data->page_count != new_data->page_count)
606 notify_job_total_pages(server_event_context(),
607 server_messaging_context(),
608 sharename, jobid, new_data->page_count);
611 /****************************************************************************
612 Store a job structure back to the database.
613 ****************************************************************************/
615 static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob)
617 uint32_t tmp;
618 TDB_DATA old_data, new_data;
619 bool ret = False;
620 struct tdb_print_db *pdb = get_print_db_byname(sharename);
621 uint8 *buf = NULL;
622 int len, newlen, buflen;
625 if (!pdb)
626 return False;
628 /* Get old data */
630 old_data = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
632 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
634 newlen = 0;
636 do {
637 len = 0;
638 buflen = newlen;
639 len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
640 (uint32)pjob->pid,
641 (uint32)pjob->sysjob,
642 (uint32)pjob->fd,
643 (uint32)pjob->starttime,
644 (uint32)pjob->status,
645 (uint32)pjob->size,
646 (uint32)pjob->page_count,
647 (uint32)pjob->spooled,
648 (uint32)pjob->smbjob,
649 pjob->filename,
650 pjob->jobname,
651 pjob->user,
652 pjob->queuename);
654 len += pack_devicemode(pjob->devmode, buf+len, buflen-len);
656 if (buflen != len) {
657 buf = (uint8 *)SMB_REALLOC(buf, len);
658 if (!buf) {
659 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
660 goto done;
662 newlen = len;
664 } while ( buflen != len );
667 /* Store new data */
669 new_data.dptr = buf;
670 new_data.dsize = len;
671 ret = (tdb_store(pdb->tdb, print_key(jobid, &tmp), new_data,
672 TDB_REPLACE) == 0);
674 release_print_db(pdb);
676 /* Send notify updates for what has changed */
678 if ( ret ) {
679 struct printjob old_pjob;
681 if ( old_data.dsize )
683 if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
685 pjob_store_notify( sharename, jobid, &old_pjob , pjob );
686 talloc_free(old_pjob.devmode);
689 else {
690 /* new job */
691 pjob_store_notify( sharename, jobid, NULL, pjob );
695 done:
696 SAFE_FREE( old_data.dptr );
697 SAFE_FREE( buf );
699 return ret;
702 /****************************************************************************
703 Remove a job structure from the database.
704 ****************************************************************************/
706 void pjob_delete(const char* sharename, uint32 jobid)
708 uint32_t tmp;
709 struct printjob *pjob;
710 uint32 job_status = 0;
711 struct tdb_print_db *pdb;
713 pdb = get_print_db_byname( sharename );
715 if (!pdb)
716 return;
718 pjob = print_job_find( sharename, jobid );
720 if (!pjob) {
721 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
722 (unsigned int)jobid));
723 release_print_db(pdb);
724 return;
727 /* We must cycle through JOB_STATUS_DELETING and
728 JOB_STATUS_DELETED for the port monitor to delete the job
729 properly. */
731 job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
732 notify_job_status(server_event_context(),
733 server_messaging_context(),
734 sharename, jobid, job_status);
736 /* Remove from printing.tdb */
738 tdb_delete(pdb->tdb, print_key(jobid, &tmp));
739 remove_from_jobs_changed(sharename, jobid);
740 release_print_db( pdb );
741 rap_jobid_delete(sharename, jobid);
744 /****************************************************************************
745 List a unix job in the print database.
746 ****************************************************************************/
748 static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid)
750 struct printjob pj, *old_pj;
752 if (jobid == (uint32)-1)
753 jobid = q->job + UNIX_JOB_START;
755 /* Preserve the timestamp on an existing unix print job */
757 old_pj = print_job_find(sharename, jobid);
759 ZERO_STRUCT(pj);
761 pj.pid = (pid_t)-1;
762 pj.sysjob = q->job;
763 pj.fd = -1;
764 pj.starttime = old_pj ? old_pj->starttime : q->time;
765 pj.status = q->status;
766 pj.size = q->size;
767 pj.spooled = True;
768 fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
769 if (jobid < UNIX_JOB_START) {
770 pj.smbjob = True;
771 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
772 } else {
773 pj.smbjob = False;
774 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
776 fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
777 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
779 pjob_store(sharename, jobid, &pj);
783 struct traverse_struct {
784 print_queue_struct *queue;
785 int qcount, snum, maxcount, total_jobs;
786 const char *sharename;
787 time_t lpq_time;
788 const char *lprm_command;
789 struct printif *print_if;
792 /****************************************************************************
793 Utility fn to delete any jobs that are no longer active.
794 ****************************************************************************/
796 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
798 struct traverse_struct *ts = (struct traverse_struct *)state;
799 struct printjob pjob;
800 uint32 jobid;
801 int i = 0;
803 if ( key.dsize != sizeof(jobid) )
804 return 0;
806 jobid = IVAL(key.dptr, 0);
807 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
808 return 0;
809 talloc_free(pjob.devmode);
812 if (!pjob.smbjob) {
813 /* remove a unix job if it isn't in the system queue any more */
815 for (i=0;i<ts->qcount;i++) {
816 uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
817 if (jobid == u_jobid)
818 break;
820 if (i == ts->qcount) {
821 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
822 (unsigned int)jobid ));
823 pjob_delete(ts->sharename, jobid);
824 return 0;
827 /* need to continue the the bottom of the function to
828 save the correct attributes */
831 /* maybe it hasn't been spooled yet */
832 if (!pjob.spooled) {
833 /* if a job is not spooled and the process doesn't
834 exist then kill it. This cleans up after smbd
835 deaths */
836 if (!process_exists_by_pid(pjob.pid)) {
837 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
838 (unsigned int)jobid, (unsigned int)pjob.pid ));
839 pjob_delete(ts->sharename, jobid);
840 } else
841 ts->total_jobs++;
842 return 0;
845 /* this check only makes sense for jobs submitted from Windows clients */
847 if ( pjob.smbjob ) {
848 for (i=0;i<ts->qcount;i++) {
849 uint32 curr_jobid;
851 if ( pjob.status == LPQ_DELETED )
852 continue;
854 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
856 if (jobid == curr_jobid) {
858 /* try to clean up any jobs that need to be deleted */
860 if ( pjob.status == LPQ_DELETING ) {
861 int result;
863 result = (*(ts->print_if->job_delete))(
864 ts->sharename, ts->lprm_command, &pjob );
866 if ( result != 0 ) {
867 /* if we can't delete, then reset the job status */
868 pjob.status = LPQ_QUEUED;
869 pjob_store(ts->sharename, jobid, &pjob);
871 else {
872 /* if we deleted the job, the remove the tdb record */
873 pjob_delete(ts->sharename, jobid);
874 pjob.status = LPQ_DELETED;
879 break;
884 /* The job isn't in the system queue - we have to assume it has
885 completed, so delete the database entry. */
887 if (i == ts->qcount) {
889 /* A race can occur between the time a job is spooled and
890 when it appears in the lpq output. This happens when
891 the job is added to printing.tdb when another smbd
892 running print_queue_update() has completed a lpq and
893 is currently traversing the printing tdb and deleting jobs.
894 Don't delete the job if it was submitted after the lpq_time. */
896 if (pjob.starttime < ts->lpq_time) {
897 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
898 (unsigned int)jobid,
899 (unsigned int)pjob.starttime,
900 (unsigned int)ts->lpq_time ));
901 pjob_delete(ts->sharename, jobid);
902 } else
903 ts->total_jobs++;
904 return 0;
907 /* Save the pjob attributes we will store.
908 FIXME!!! This is the only place where queue->job
909 represents the SMB jobid --jerry */
911 ts->queue[i].job = jobid;
912 ts->queue[i].size = pjob.size;
913 ts->queue[i].page_count = pjob.page_count;
914 ts->queue[i].status = pjob.status;
915 ts->queue[i].priority = 1;
916 ts->queue[i].time = pjob.starttime;
917 fstrcpy(ts->queue[i].fs_user, pjob.user);
918 fstrcpy(ts->queue[i].fs_file, pjob.jobname);
920 ts->total_jobs++;
922 return 0;
925 /****************************************************************************
926 Check if the print queue has been updated recently enough.
927 ****************************************************************************/
929 static void print_cache_flush(const char *sharename)
931 fstring key;
932 struct tdb_print_db *pdb = get_print_db_byname(sharename);
934 if (!pdb)
935 return;
936 slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
937 tdb_store_int32(pdb->tdb, key, -1);
938 release_print_db(pdb);
941 /****************************************************************************
942 Check if someone already thinks they are doing the update.
943 ****************************************************************************/
945 static pid_t get_updating_pid(const char *sharename)
947 fstring keystr;
948 TDB_DATA data, key;
949 pid_t updating_pid;
950 struct tdb_print_db *pdb = get_print_db_byname(sharename);
952 if (!pdb)
953 return (pid_t)-1;
954 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
955 key = string_tdb_data(keystr);
957 data = tdb_fetch(pdb->tdb, key);
958 release_print_db(pdb);
959 if (!data.dptr || data.dsize != sizeof(pid_t)) {
960 SAFE_FREE(data.dptr);
961 return (pid_t)-1;
964 updating_pid = IVAL(data.dptr, 0);
965 SAFE_FREE(data.dptr);
967 if (process_exists_by_pid(updating_pid))
968 return updating_pid;
970 return (pid_t)-1;
973 /****************************************************************************
974 Set the fact that we're doing the update, or have finished doing the update
975 in the tdb.
976 ****************************************************************************/
978 static void set_updating_pid(const fstring sharename, bool updating)
980 fstring keystr;
981 TDB_DATA key;
982 TDB_DATA data;
983 pid_t updating_pid = sys_getpid();
984 uint8 buffer[4];
986 struct tdb_print_db *pdb = get_print_db_byname(sharename);
988 if (!pdb)
989 return;
991 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
992 key = string_tdb_data(keystr);
994 DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
995 updating ? "" : "not ",
996 sharename ));
998 if ( !updating ) {
999 tdb_delete(pdb->tdb, key);
1000 release_print_db(pdb);
1001 return;
1004 SIVAL( buffer, 0, updating_pid);
1005 data.dptr = buffer;
1006 data.dsize = 4; /* we always assume this is a 4 byte value */
1008 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1009 release_print_db(pdb);
1012 /****************************************************************************
1013 Sort print jobs by submittal time.
1014 ****************************************************************************/
1016 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
1018 /* Silly cases */
1020 if (!j1 && !j2)
1021 return 0;
1022 if (!j1)
1023 return -1;
1024 if (!j2)
1025 return 1;
1027 /* Sort on job start time */
1029 if (j1->time == j2->time)
1030 return 0;
1031 return (j1->time > j2->time) ? 1 : -1;
1034 /****************************************************************************
1035 Store the sorted queue representation for later portmon retrieval.
1036 Skip deleted jobs
1037 ****************************************************************************/
1039 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
1041 TDB_DATA data;
1042 int max_reported_jobs = lp_max_reported_jobs(pts->snum);
1043 print_queue_struct *queue = pts->queue;
1044 size_t len;
1045 size_t i;
1046 unsigned int qcount;
1048 if (max_reported_jobs && (max_reported_jobs < pts->qcount))
1049 pts->qcount = max_reported_jobs;
1050 qcount = 0;
1052 /* Work out the size. */
1053 data.dsize = 0;
1054 data.dsize += tdb_pack(NULL, 0, "d", qcount);
1056 for (i = 0; i < pts->qcount; i++) {
1057 if ( queue[i].status == LPQ_DELETED )
1058 continue;
1060 qcount++;
1061 data.dsize += tdb_pack(NULL, 0, "ddddddff",
1062 (uint32)queue[i].job,
1063 (uint32)queue[i].size,
1064 (uint32)queue[i].page_count,
1065 (uint32)queue[i].status,
1066 (uint32)queue[i].priority,
1067 (uint32)queue[i].time,
1068 queue[i].fs_user,
1069 queue[i].fs_file);
1072 if ((data.dptr = (uint8 *)SMB_MALLOC(data.dsize)) == NULL)
1073 return;
1075 len = 0;
1076 len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
1077 for (i = 0; i < pts->qcount; i++) {
1078 if ( queue[i].status == LPQ_DELETED )
1079 continue;
1081 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
1082 (uint32)queue[i].job,
1083 (uint32)queue[i].size,
1084 (uint32)queue[i].page_count,
1085 (uint32)queue[i].status,
1086 (uint32)queue[i].priority,
1087 (uint32)queue[i].time,
1088 queue[i].fs_user,
1089 queue[i].fs_file);
1092 tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
1093 TDB_REPLACE);
1094 SAFE_FREE(data.dptr);
1095 return;
1098 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
1100 TDB_DATA data;
1102 ZERO_STRUCT(data);
1104 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
1105 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
1106 SAFE_FREE(data.dptr);
1107 ZERO_STRUCT(data);
1110 return data;
1113 static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid)
1115 unsigned int i;
1116 unsigned int job_count = data.dsize / 4;
1118 for (i = 0; i < job_count; i++) {
1119 uint32 ch_jobid;
1121 ch_jobid = IVAL(data.dptr, i*4);
1122 if (ch_jobid == jobid)
1123 remove_from_jobs_changed(sharename, jobid);
1127 /****************************************************************************
1128 Check if the print queue has been updated recently enough.
1129 ****************************************************************************/
1131 static bool print_cache_expired(const char *sharename, bool check_pending)
1133 fstring key;
1134 time_t last_qscan_time, time_now = time(NULL);
1135 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1136 bool result = False;
1138 if (!pdb)
1139 return False;
1141 snprintf(key, sizeof(key), "CACHE/%s", sharename);
1142 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1145 * Invalidate the queue for 3 reasons.
1146 * (1). last queue scan time == -1.
1147 * (2). Current time - last queue scan time > allowed cache time.
1148 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1149 * This last test picks up machines for which the clock has been moved
1150 * forward, an lpq scan done and then the clock moved back. Otherwise
1151 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1154 if (last_qscan_time == ((time_t)-1)
1155 || (time_now - last_qscan_time) >= lp_lpqcachetime()
1156 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
1158 uint32 u;
1159 time_t msg_pending_time;
1161 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1162 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1163 sharename, (int)last_qscan_time, (int)time_now,
1164 (int)lp_lpqcachetime() ));
1166 /* check if another smbd has already sent a message to update the
1167 queue. Give the pending message one minute to clear and
1168 then send another message anyways. Make sure to check for
1169 clocks that have been run forward and then back again. */
1171 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1173 if ( check_pending
1174 && tdb_fetch_uint32( pdb->tdb, key, &u )
1175 && (msg_pending_time=u) > 0
1176 && msg_pending_time <= time_now
1177 && (time_now - msg_pending_time) < 60 )
1179 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1180 sharename));
1181 goto done;
1184 result = True;
1187 done:
1188 release_print_db(pdb);
1189 return result;
1192 /****************************************************************************
1193 main work for updating the lpq cahe for a printer queue
1194 ****************************************************************************/
1196 static void print_queue_update_internal( const char *sharename,
1197 struct printif *current_printif,
1198 char *lpq_command, char *lprm_command )
1200 int i, qcount;
1201 print_queue_struct *queue = NULL;
1202 print_status_struct status;
1203 print_status_struct old_status;
1204 struct printjob *pjob;
1205 struct traverse_struct tstruct;
1206 TDB_DATA data, key;
1207 TDB_DATA jcdata;
1208 fstring keystr, cachestr;
1209 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1211 if (!pdb) {
1212 return;
1215 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1216 sharename, current_printif->type, lpq_command));
1219 * Update the cache time FIRST ! Stops others even
1220 * attempting to get the lock and doing this
1221 * if the lpq takes a long time.
1224 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1225 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1227 /* get the current queue using the appropriate interface */
1228 ZERO_STRUCT(status);
1230 qcount = (*(current_printif->queue_get))(sharename,
1231 current_printif->type,
1232 lpq_command, &queue, &status);
1234 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1235 qcount, (qcount != 1) ? "s" : "", sharename));
1237 /* Sort the queue by submission time otherwise they are displayed
1238 in hash order. */
1240 TYPESAFE_QSORT(queue, qcount, printjob_comp);
1243 any job in the internal database that is marked as spooled
1244 and doesn't exist in the system queue is considered finished
1245 and removed from the database
1247 any job in the system database but not in the internal database
1248 is added as a unix job
1250 fill in any system job numbers as we go
1253 jcdata = get_jobs_changed_data(pdb);
1255 for (i=0; i<qcount; i++) {
1256 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1258 if (jobid == (uint32)-1) {
1259 /* assume its a unix print job */
1260 print_unix_job(sharename, &queue[i], jobid);
1261 continue;
1264 /* we have an active SMB print job - update its status */
1265 pjob = print_job_find(sharename, jobid);
1266 if (!pjob) {
1267 /* err, somethings wrong. Probably smbd was restarted
1268 with jobs in the queue. All we can do is treat them
1269 like unix jobs. Pity. */
1270 print_unix_job(sharename, &queue[i], jobid);
1271 continue;
1274 pjob->sysjob = queue[i].job;
1276 /* don't reset the status on jobs to be deleted */
1278 if ( pjob->status != LPQ_DELETING )
1279 pjob->status = queue[i].status;
1281 pjob_store(sharename, jobid, pjob);
1283 check_job_changed(sharename, jcdata, jobid);
1286 SAFE_FREE(jcdata.dptr);
1288 /* now delete any queued entries that don't appear in the
1289 system queue */
1290 tstruct.queue = queue;
1291 tstruct.qcount = qcount;
1292 tstruct.snum = -1;
1293 tstruct.total_jobs = 0;
1294 tstruct.lpq_time = time(NULL);
1295 tstruct.sharename = sharename;
1296 tstruct.lprm_command = lprm_command;
1297 tstruct.print_if = current_printif;
1299 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1301 /* Store the linearised queue, max jobs only. */
1302 store_queue_struct(pdb, &tstruct);
1304 SAFE_FREE(tstruct.queue);
1306 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1307 sharename, tstruct.total_jobs ));
1309 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1311 get_queue_status(sharename, &old_status);
1312 if (old_status.qcount != qcount)
1313 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1314 old_status.qcount, qcount, sharename));
1316 /* store the new queue status structure */
1317 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1318 key = string_tdb_data(keystr);
1320 status.qcount = qcount;
1321 data.dptr = (uint8 *)&status;
1322 data.dsize = sizeof(status);
1323 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1326 * Update the cache time again. We want to do this call
1327 * as little as possible...
1330 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1331 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1333 /* clear the msg pending record for this queue */
1335 snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1337 if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1338 /* log a message but continue on */
1340 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1341 sharename));
1344 release_print_db( pdb );
1346 return;
1349 /****************************************************************************
1350 Update the internal database from the system print queue for a queue.
1351 obtain a lock on the print queue before proceeding (needed when mutiple
1352 smbd processes maytry to update the lpq cache concurrently).
1353 ****************************************************************************/
1355 static void print_queue_update_with_lock( const char *sharename,
1356 struct printif *current_printif,
1357 char *lpq_command, char *lprm_command )
1359 fstring keystr;
1360 struct tdb_print_db *pdb;
1362 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1363 pdb = get_print_db_byname(sharename);
1364 if (!pdb)
1365 return;
1367 if ( !print_cache_expired(sharename, False) ) {
1368 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1369 release_print_db(pdb);
1370 return;
1374 * Check to see if someone else is doing this update.
1375 * This is essentially a mutex on the update.
1378 if (get_updating_pid(sharename) != -1) {
1379 release_print_db(pdb);
1380 return;
1383 /* Lock the queue for the database update */
1385 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1386 /* Only wait 10 seconds for this. */
1387 if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
1388 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1389 release_print_db(pdb);
1390 return;
1394 * Ensure that no one else got in here.
1395 * If the updating pid is still -1 then we are
1396 * the winner.
1399 if (get_updating_pid(sharename) != -1) {
1401 * Someone else is doing the update, exit.
1403 tdb_unlock_bystring(pdb->tdb, keystr);
1404 release_print_db(pdb);
1405 return;
1409 * We're going to do the update ourselves.
1412 /* Tell others we're doing the update. */
1413 set_updating_pid(sharename, True);
1416 * Allow others to enter and notice we're doing
1417 * the update.
1420 tdb_unlock_bystring(pdb->tdb, keystr);
1422 /* do the main work now */
1424 print_queue_update_internal( sharename, current_printif,
1425 lpq_command, lprm_command );
1427 /* Delete our pid from the db. */
1428 set_updating_pid(sharename, False);
1429 release_print_db(pdb);
1432 /****************************************************************************
1433 this is the receive function of the background lpq updater
1434 ****************************************************************************/
1435 static void print_queue_receive(struct messaging_context *msg,
1436 void *private_data,
1437 uint32_t msg_type,
1438 struct server_id server_id,
1439 DATA_BLOB *data)
1441 fstring sharename;
1442 char *lpqcommand = NULL, *lprmcommand = NULL;
1443 int printing_type;
1444 size_t len;
1446 len = tdb_unpack( (uint8 *)data->data, data->length, "fdPP",
1447 sharename,
1448 &printing_type,
1449 &lpqcommand,
1450 &lprmcommand );
1452 if ( len == -1 ) {
1453 SAFE_FREE(lpqcommand);
1454 SAFE_FREE(lprmcommand);
1455 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1456 return;
1459 print_queue_update_with_lock(sharename,
1460 get_printer_fns_from_type((enum printing_types)printing_type),
1461 lpqcommand, lprmcommand );
1463 SAFE_FREE(lpqcommand);
1464 SAFE_FREE(lprmcommand);
1465 return;
1468 static void printing_pause_fd_handler(struct tevent_context *ev,
1469 struct tevent_fd *fde,
1470 uint16_t flags,
1471 void *private_data)
1474 * If pause_pipe[1] is closed it means the parent smbd
1475 * and children exited or aborted.
1477 exit_server_cleanly(NULL);
1480 extern struct child_pid *children;
1481 extern int num_children;
1483 static void add_child_pid(pid_t pid)
1485 struct child_pid *child;
1487 child = SMB_MALLOC_P(struct child_pid);
1488 if (child == NULL) {
1489 DEBUG(0, ("Could not add child struct -- malloc failed\n"));
1490 return;
1492 child->pid = pid;
1493 DLIST_ADD(children, child);
1494 num_children += 1;
1497 static pid_t background_lpq_updater_pid = -1;
1499 /****************************************************************************
1500 main thread of the background lpq updater
1501 ****************************************************************************/
1502 void start_background_queue(struct tevent_context *ev,
1503 struct messaging_context *msg_ctx)
1505 /* Use local variables for this as we don't
1506 * need to save the parent side of this, just
1507 * ensure it closes when the process exits.
1509 int pause_pipe[2];
1511 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1513 if (pipe(pause_pipe) == -1) {
1514 DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno) ));
1515 exit(1);
1518 background_lpq_updater_pid = sys_fork();
1520 if (background_lpq_updater_pid == -1) {
1521 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1522 exit(1);
1525 /* Track the printing pid along with other smbd children */
1526 add_child_pid(background_lpq_updater_pid);
1528 if(background_lpq_updater_pid == 0) {
1529 struct tevent_fd *fde;
1530 int ret;
1531 NTSTATUS status;
1533 /* Child. */
1534 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1536 close(pause_pipe[0]);
1537 pause_pipe[0] = -1;
1539 status = reinit_after_fork(msg_ctx, ev, procid_self(), true);
1541 if (!NT_STATUS_IS_OK(status)) {
1542 DEBUG(0,("reinit_after_fork() failed\n"));
1543 smb_panic("reinit_after_fork() failed");
1546 smbd_setup_sig_term_handler();
1547 smbd_setup_sig_hup_handler(ev, msg_ctx);
1549 if (!serverid_register(procid_self(),
1550 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
1551 |FLAG_MSG_PRINT_GENERAL)) {
1552 exit(1);
1555 if (!locking_init()) {
1556 exit(1);
1559 messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE,
1560 print_queue_receive);
1562 fde = tevent_add_fd(ev, ev, pause_pipe[1], TEVENT_FD_READ,
1563 printing_pause_fd_handler,
1564 NULL);
1565 if (!fde) {
1566 DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
1567 smb_panic("tevent_add_fd() failed for pause_pipe");
1570 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1571 ret = tevent_loop_wait(ev);
1572 /* should not be reached */
1573 DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
1574 ret, (ret == 0) ? "out of events" : strerror(errno)));
1575 exit(1);
1578 close(pause_pipe[1]);
1581 /****************************************************************************
1582 update the internal database from the system print queue for a queue
1583 ****************************************************************************/
1585 static void print_queue_update(struct messaging_context *msg_ctx,
1586 int snum, bool force)
1588 fstring key;
1589 fstring sharename;
1590 char *lpqcommand = NULL;
1591 char *lprmcommand = NULL;
1592 uint8 *buffer = NULL;
1593 size_t len = 0;
1594 size_t newlen;
1595 struct tdb_print_db *pdb;
1596 int type;
1597 struct printif *current_printif;
1598 TALLOC_CTX *ctx = talloc_tos();
1600 fstrcpy( sharename, lp_const_servicename(snum));
1602 /* don't strip out characters like '$' from the printername */
1604 lpqcommand = talloc_string_sub2(ctx,
1605 lp_lpqcommand(snum),
1606 "%p",
1607 lp_printername(snum),
1608 false, false, false);
1609 if (!lpqcommand) {
1610 return;
1612 lpqcommand = talloc_sub_advanced(ctx,
1613 lp_servicename(snum),
1614 current_user_info.unix_name,
1616 current_user.ut.gid,
1617 get_current_username(),
1618 current_user_info.domain,
1619 lpqcommand);
1620 if (!lpqcommand) {
1621 return;
1624 lprmcommand = talloc_string_sub2(ctx,
1625 lp_lprmcommand(snum),
1626 "%p",
1627 lp_printername(snum),
1628 false, false, false);
1629 if (!lprmcommand) {
1630 return;
1632 lprmcommand = talloc_sub_advanced(ctx,
1633 lp_servicename(snum),
1634 current_user_info.unix_name,
1636 current_user.ut.gid,
1637 get_current_username(),
1638 current_user_info.domain,
1639 lprmcommand);
1640 if (!lprmcommand) {
1641 return;
1645 * Make sure that the background queue process exists.
1646 * Otherwise just do the update ourselves
1649 if ( force || background_lpq_updater_pid == -1 ) {
1650 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1651 current_printif = get_printer_fns( snum );
1652 print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand );
1654 return;
1657 type = lp_printing(snum);
1659 /* get the length */
1661 len = tdb_pack( NULL, 0, "fdPP",
1662 sharename,
1663 type,
1664 lpqcommand,
1665 lprmcommand );
1667 buffer = SMB_XMALLOC_ARRAY( uint8, len );
1669 /* now pack the buffer */
1670 newlen = tdb_pack( buffer, len, "fdPP",
1671 sharename,
1672 type,
1673 lpqcommand,
1674 lprmcommand );
1676 SMB_ASSERT( newlen == len );
1678 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1679 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1680 sharename, type, lpqcommand, lprmcommand ));
1682 /* here we set a msg pending record for other smbd processes
1683 to throttle the number of duplicate print_queue_update msgs
1684 sent. */
1686 pdb = get_print_db_byname(sharename);
1687 if (!pdb) {
1688 SAFE_FREE(buffer);
1689 return;
1692 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1694 if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1695 /* log a message but continue on */
1697 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1698 sharename));
1701 release_print_db( pdb );
1703 /* finally send the message */
1705 messaging_send_buf(msg_ctx, pid_to_procid(background_lpq_updater_pid),
1706 MSG_PRINTER_UPDATE, (uint8 *)buffer, len);
1708 SAFE_FREE( buffer );
1710 return;
1713 /****************************************************************************
1714 Create/Update an entry in the print tdb that will allow us to send notify
1715 updates only to interested smbd's.
1716 ****************************************************************************/
1718 bool print_notify_register_pid(int snum)
1720 TDB_DATA data;
1721 struct tdb_print_db *pdb = NULL;
1722 TDB_CONTEXT *tdb = NULL;
1723 const char *printername;
1724 uint32 mypid = (uint32)sys_getpid();
1725 bool ret = False;
1726 size_t i;
1728 /* if (snum == -1), then the change notify request was
1729 on a print server handle and we need to register on
1730 all print queus */
1732 if (snum == -1)
1734 int num_services = lp_numservices();
1735 int idx;
1737 for ( idx=0; idx<num_services; idx++ ) {
1738 if (lp_snum_ok(idx) && lp_print_ok(idx) )
1739 print_notify_register_pid(idx);
1742 return True;
1744 else /* register for a specific printer */
1746 printername = lp_const_servicename(snum);
1747 pdb = get_print_db_byname(printername);
1748 if (!pdb)
1749 return False;
1750 tdb = pdb->tdb;
1753 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1754 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1755 printername));
1756 if (pdb)
1757 release_print_db(pdb);
1758 return False;
1761 data = get_printer_notify_pid_list( tdb, printername, True );
1763 /* Add ourselves and increase the refcount. */
1765 for (i = 0; i < data.dsize; i += 8) {
1766 if (IVAL(data.dptr,i) == mypid) {
1767 uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1768 SIVAL(data.dptr, i+4, new_refcount);
1769 break;
1773 if (i == data.dsize) {
1774 /* We weren't in the list. Realloc. */
1775 data.dptr = (uint8 *)SMB_REALLOC(data.dptr, data.dsize + 8);
1776 if (!data.dptr) {
1777 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1778 printername));
1779 goto done;
1781 data.dsize += 8;
1782 SIVAL(data.dptr,data.dsize - 8,mypid);
1783 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1786 /* Store back the record. */
1787 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1788 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1789 list for printer %s\n", printername));
1790 goto done;
1793 ret = True;
1795 done:
1797 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1798 if (pdb)
1799 release_print_db(pdb);
1800 SAFE_FREE(data.dptr);
1801 return ret;
1804 /****************************************************************************
1805 Update an entry in the print tdb that will allow us to send notify
1806 updates only to interested smbd's.
1807 ****************************************************************************/
1809 bool print_notify_deregister_pid(int snum)
1811 TDB_DATA data;
1812 struct tdb_print_db *pdb = NULL;
1813 TDB_CONTEXT *tdb = NULL;
1814 const char *printername;
1815 uint32 mypid = (uint32)sys_getpid();
1816 size_t i;
1817 bool ret = False;
1819 /* if ( snum == -1 ), we are deregister a print server handle
1820 which means to deregister on all print queues */
1822 if (snum == -1)
1824 int num_services = lp_numservices();
1825 int idx;
1827 for ( idx=0; idx<num_services; idx++ ) {
1828 if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1829 print_notify_deregister_pid(idx);
1832 return True;
1834 else /* deregister a specific printer */
1836 printername = lp_const_servicename(snum);
1837 pdb = get_print_db_byname(printername);
1838 if (!pdb)
1839 return False;
1840 tdb = pdb->tdb;
1843 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1844 DEBUG(0,("print_notify_register_pid: Failed to lock \
1845 printer %s database\n", printername));
1846 if (pdb)
1847 release_print_db(pdb);
1848 return False;
1851 data = get_printer_notify_pid_list( tdb, printername, True );
1853 /* Reduce refcount. Remove ourselves if zero. */
1855 for (i = 0; i < data.dsize; ) {
1856 if (IVAL(data.dptr,i) == mypid) {
1857 uint32 refcount = IVAL(data.dptr, i+4);
1859 refcount--;
1861 if (refcount == 0) {
1862 if (data.dsize - i > 8)
1863 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1864 data.dsize -= 8;
1865 continue;
1867 SIVAL(data.dptr, i+4, refcount);
1870 i += 8;
1873 if (data.dsize == 0)
1874 SAFE_FREE(data.dptr);
1876 /* Store back the record. */
1877 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1878 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1879 list for printer %s\n", printername));
1880 goto done;
1883 ret = True;
1885 done:
1887 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1888 if (pdb)
1889 release_print_db(pdb);
1890 SAFE_FREE(data.dptr);
1891 return ret;
1894 /****************************************************************************
1895 Check if a jobid is valid. It is valid if it exists in the database.
1896 ****************************************************************************/
1898 bool print_job_exists(const char* sharename, uint32 jobid)
1900 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1901 bool ret;
1902 uint32_t tmp;
1904 if (!pdb)
1905 return False;
1906 ret = tdb_exists(pdb->tdb, print_key(jobid, &tmp));
1907 release_print_db(pdb);
1908 return ret;
1911 /****************************************************************************
1912 Give the filename used for a jobid.
1913 Only valid for the process doing the spooling and when the job
1914 has not been spooled.
1915 ****************************************************************************/
1917 char *print_job_fname(const char* sharename, uint32 jobid)
1919 struct printjob *pjob = print_job_find(sharename, jobid);
1920 if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
1921 return NULL;
1922 return pjob->filename;
1926 /****************************************************************************
1927 Give the filename used for a jobid.
1928 Only valid for the process doing the spooling and when the job
1929 has not been spooled.
1930 ****************************************************************************/
1932 struct spoolss_DeviceMode *print_job_devmode(const char* sharename, uint32 jobid)
1934 struct printjob *pjob = print_job_find(sharename, jobid);
1936 if ( !pjob )
1937 return NULL;
1939 return pjob->devmode;
1942 /****************************************************************************
1943 Set the name of a job. Only possible for owner.
1944 ****************************************************************************/
1946 bool print_job_set_name(const char *sharename, uint32 jobid, const char *name)
1948 struct printjob *pjob;
1950 pjob = print_job_find(sharename, jobid);
1951 if (!pjob || pjob->pid != sys_getpid())
1952 return False;
1954 fstrcpy(pjob->jobname, name);
1955 return pjob_store(sharename, jobid, pjob);
1958 /****************************************************************************
1959 Get the name of a job. Only possible for owner.
1960 ****************************************************************************/
1962 bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t jobid, char **name)
1964 struct printjob *pjob;
1966 pjob = print_job_find(sharename, jobid);
1967 if (!pjob || pjob->pid != sys_getpid()) {
1968 return false;
1971 *name = talloc_strdup(mem_ctx, pjob->jobname);
1972 if (!*name) {
1973 return false;
1976 return true;
1980 /***************************************************************************
1981 Remove a jobid from the 'jobs changed' list.
1982 ***************************************************************************/
1984 static bool remove_from_jobs_changed(const char* sharename, uint32 jobid)
1986 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1987 TDB_DATA data, key;
1988 size_t job_count, i;
1989 bool ret = False;
1990 bool gotlock = False;
1992 if (!pdb) {
1993 return False;
1996 ZERO_STRUCT(data);
1998 key = string_tdb_data("INFO/jobs_changed");
2000 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
2001 goto out;
2003 gotlock = True;
2005 data = tdb_fetch(pdb->tdb, key);
2007 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
2008 goto out;
2010 job_count = data.dsize / 4;
2011 for (i = 0; i < job_count; i++) {
2012 uint32 ch_jobid;
2014 ch_jobid = IVAL(data.dptr, i*4);
2015 if (ch_jobid == jobid) {
2016 if (i < job_count -1 )
2017 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
2018 data.dsize -= 4;
2019 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
2020 goto out;
2021 break;
2025 ret = True;
2026 out:
2028 if (gotlock)
2029 tdb_chainunlock(pdb->tdb, key);
2030 SAFE_FREE(data.dptr);
2031 release_print_db(pdb);
2032 if (ret)
2033 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
2034 else
2035 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
2036 return ret;
2039 /****************************************************************************
2040 Delete a print job - don't update queue.
2041 ****************************************************************************/
2043 static bool print_job_delete1(int snum, uint32 jobid)
2045 const char* sharename = lp_const_servicename(snum);
2046 struct printjob *pjob = print_job_find(sharename, jobid);
2047 int result = 0;
2048 struct printif *current_printif = get_printer_fns( snum );
2050 if (!pjob)
2051 return False;
2054 * If already deleting just return.
2057 if (pjob->status == LPQ_DELETING)
2058 return True;
2060 /* Hrm - we need to be able to cope with deleting a job before it
2061 has reached the spooler. Just mark it as LPQ_DELETING and
2062 let the print_queue_update() code rmeove the record */
2065 if (pjob->sysjob == -1) {
2066 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
2069 /* Set the tdb entry to be deleting. */
2071 pjob->status = LPQ_DELETING;
2072 pjob_store(sharename, jobid, pjob);
2074 if (pjob->spooled && pjob->sysjob != -1)
2076 result = (*(current_printif->job_delete))(
2077 lp_printername(snum),
2078 lp_lprmcommand(snum),
2079 pjob);
2081 /* Delete the tdb entry if the delete succeeded or the job hasn't
2082 been spooled. */
2084 if (result == 0) {
2085 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2086 int njobs = 1;
2088 if (!pdb)
2089 return False;
2090 pjob_delete(sharename, jobid);
2091 /* Ensure we keep a rough count of the number of total jobs... */
2092 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
2093 release_print_db(pdb);
2097 remove_from_jobs_changed( sharename, jobid );
2099 return (result == 0);
2102 /****************************************************************************
2103 Return true if the current user owns the print job.
2104 ****************************************************************************/
2106 static bool is_owner(struct auth_serversupplied_info *server_info,
2107 const char *servicename,
2108 uint32 jobid)
2110 struct printjob *pjob = print_job_find(servicename, jobid);
2112 if (!pjob || !server_info)
2113 return False;
2115 return strequal(pjob->user, server_info->sanitized_username);
2118 /****************************************************************************
2119 Delete a print job.
2120 ****************************************************************************/
2122 WERROR print_job_delete(struct auth_serversupplied_info *server_info,
2123 struct messaging_context *msg_ctx,
2124 int snum, uint32_t jobid)
2126 const char* sharename = lp_const_servicename(snum);
2127 struct printjob *pjob;
2128 bool owner;
2129 char *fname;
2131 owner = is_owner(server_info, lp_const_servicename(snum), jobid);
2133 /* Check access against security descriptor or whether the user
2134 owns their job. */
2136 if (!owner &&
2137 !print_access_check(server_info, msg_ctx, snum,
2138 JOB_ACCESS_ADMINISTER)) {
2139 DEBUG(3, ("delete denied by security descriptor\n"));
2141 /* BEGIN_ADMIN_LOG */
2142 sys_adminlog( LOG_ERR,
2143 "Permission denied-- user not allowed to delete, \
2144 pause, or resume print job. User name: %s. Printer name: %s.",
2145 uidtoname(server_info->utok.uid),
2146 lp_printername(snum) );
2147 /* END_ADMIN_LOG */
2149 return WERR_ACCESS_DENIED;
2153 * get the spooled filename of the print job
2154 * if this works, then the file has not been spooled
2155 * to the underlying print system. Just delete the
2156 * spool file & return.
2159 fname = print_job_fname(sharename, jobid);
2160 if (fname != NULL) {
2161 /* remove the spool file */
2162 DEBUG(10, ("print_job_delete: "
2163 "Removing spool file [%s]\n", fname));
2164 if (unlink(fname) == -1) {
2165 return map_werror_from_unix(errno);
2169 if (!print_job_delete1(snum, jobid)) {
2170 return WERR_ACCESS_DENIED;
2173 /* force update the database and say the delete failed if the
2174 job still exists */
2176 print_queue_update(msg_ctx, snum, True);
2178 pjob = print_job_find(sharename, jobid);
2179 if (pjob && (pjob->status != LPQ_DELETING)) {
2180 return WERR_ACCESS_DENIED;
2183 return WERR_PRINTER_HAS_JOBS_QUEUED;
2186 /****************************************************************************
2187 Pause a job.
2188 ****************************************************************************/
2190 bool print_job_pause(struct auth_serversupplied_info *server_info,
2191 struct messaging_context *msg_ctx,
2192 int snum, uint32 jobid, WERROR *errcode)
2194 const char* sharename = lp_const_servicename(snum);
2195 struct printjob *pjob;
2196 int ret = -1;
2197 struct printif *current_printif = get_printer_fns( snum );
2199 pjob = print_job_find(sharename, jobid);
2201 if (!pjob || !server_info) {
2202 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2203 (unsigned int)jobid ));
2204 return False;
2207 if (!pjob->spooled || pjob->sysjob == -1) {
2208 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2209 (int)pjob->sysjob, (unsigned int)jobid ));
2210 return False;
2213 if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2214 !print_access_check(server_info, msg_ctx, snum,
2215 JOB_ACCESS_ADMINISTER)) {
2216 DEBUG(3, ("pause denied by security descriptor\n"));
2218 /* BEGIN_ADMIN_LOG */
2219 sys_adminlog( LOG_ERR,
2220 "Permission denied-- user not allowed to delete, \
2221 pause, or resume print job. User name: %s. Printer name: %s.",
2222 uidtoname(server_info->utok.uid),
2223 lp_printername(snum) );
2224 /* END_ADMIN_LOG */
2226 *errcode = WERR_ACCESS_DENIED;
2227 return False;
2230 /* need to pause the spooled entry */
2231 ret = (*(current_printif->job_pause))(snum, pjob);
2233 if (ret != 0) {
2234 *errcode = WERR_INVALID_PARAM;
2235 return False;
2238 /* force update the database */
2239 print_cache_flush(lp_const_servicename(snum));
2241 /* Send a printer notify message */
2243 notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2244 JOB_STATUS_PAUSED);
2246 /* how do we tell if this succeeded? */
2248 return True;
2251 /****************************************************************************
2252 Resume a job.
2253 ****************************************************************************/
2255 bool print_job_resume(struct auth_serversupplied_info *server_info,
2256 struct messaging_context *msg_ctx,
2257 int snum, uint32 jobid, WERROR *errcode)
2259 const char *sharename = lp_const_servicename(snum);
2260 struct printjob *pjob;
2261 int ret;
2262 struct printif *current_printif = get_printer_fns( snum );
2264 pjob = print_job_find(sharename, jobid);
2266 if (!pjob || !server_info) {
2267 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2268 (unsigned int)jobid ));
2269 return False;
2272 if (!pjob->spooled || pjob->sysjob == -1) {
2273 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2274 (int)pjob->sysjob, (unsigned int)jobid ));
2275 return False;
2278 if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2279 !print_access_check(server_info, msg_ctx, snum,
2280 JOB_ACCESS_ADMINISTER)) {
2281 DEBUG(3, ("resume denied by security descriptor\n"));
2282 *errcode = WERR_ACCESS_DENIED;
2284 /* BEGIN_ADMIN_LOG */
2285 sys_adminlog( LOG_ERR,
2286 "Permission denied-- user not allowed to delete, \
2287 pause, or resume print job. User name: %s. Printer name: %s.",
2288 uidtoname(server_info->utok.uid),
2289 lp_printername(snum) );
2290 /* END_ADMIN_LOG */
2291 return False;
2294 ret = (*(current_printif->job_resume))(snum, pjob);
2296 if (ret != 0) {
2297 *errcode = WERR_INVALID_PARAM;
2298 return False;
2301 /* force update the database */
2302 print_cache_flush(lp_const_servicename(snum));
2304 /* Send a printer notify message */
2306 notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2307 JOB_STATUS_QUEUED);
2309 return True;
2312 /****************************************************************************
2313 Write to a print file.
2314 ****************************************************************************/
2316 ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size)
2318 const char* sharename = lp_const_servicename(snum);
2319 ssize_t return_code;
2320 struct printjob *pjob;
2322 pjob = print_job_find(sharename, jobid);
2324 if (!pjob)
2325 return -1;
2326 /* don't allow another process to get this info - it is meaningless */
2327 if (pjob->pid != sys_getpid())
2328 return -1;
2330 /* if SMBD is spooling this can't be allowed */
2331 if (pjob->status == PJOB_SMBD_SPOOLING) {
2332 return -1;
2335 return_code = write_data_at_offset(pjob->fd, buf, size, pos);
2337 if (return_code>0) {
2338 pjob->size += size;
2339 pjob_store(sharename, jobid, pjob);
2341 return return_code;
2344 /****************************************************************************
2345 Get the queue status - do not update if db is out of date.
2346 ****************************************************************************/
2348 static int get_queue_status(const char* sharename, print_status_struct *status)
2350 fstring keystr;
2351 TDB_DATA data;
2352 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2353 int len;
2355 if (status) {
2356 ZERO_STRUCTP(status);
2359 if (!pdb)
2360 return 0;
2362 if (status) {
2363 fstr_sprintf(keystr, "STATUS/%s", sharename);
2364 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2365 if (data.dptr) {
2366 if (data.dsize == sizeof(print_status_struct))
2367 /* this memcpy is ok since the status struct was
2368 not packed before storing it in the tdb */
2369 memcpy(status, data.dptr, sizeof(print_status_struct));
2370 SAFE_FREE(data.dptr);
2373 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2374 release_print_db(pdb);
2375 return (len == -1 ? 0 : len);
2378 /****************************************************************************
2379 Determine the number of jobs in a queue.
2380 ****************************************************************************/
2382 int print_queue_length(struct messaging_context *msg_ctx, int snum,
2383 print_status_struct *pstatus)
2385 const char* sharename = lp_const_servicename( snum );
2386 print_status_struct status;
2387 int len;
2389 ZERO_STRUCT( status );
2391 /* make sure the database is up to date */
2392 if (print_cache_expired(lp_const_servicename(snum), True))
2393 print_queue_update(msg_ctx, snum, False);
2395 /* also fetch the queue status */
2396 memset(&status, 0, sizeof(status));
2397 len = get_queue_status(sharename, &status);
2399 if (pstatus)
2400 *pstatus = status;
2402 return len;
2405 /***************************************************************************
2406 Allocate a jobid. Hold the lock for as short a time as possible.
2407 ***************************************************************************/
2409 static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum,
2410 const char *sharename, uint32 *pjobid)
2412 int i;
2413 uint32 jobid;
2414 enum TDB_ERROR terr;
2415 int ret;
2417 *pjobid = (uint32)-1;
2419 for (i = 0; i < 3; i++) {
2420 /* Lock the database - only wait 20 seconds. */
2421 ret = tdb_lock_bystring_with_timeout(pdb->tdb,
2422 "INFO/nextjob", 20);
2423 if (ret == -1) {
2424 DEBUG(0, ("allocate_print_jobid: "
2425 "Failed to lock printing database %s\n",
2426 sharename));
2427 terr = tdb_error(pdb->tdb);
2428 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2431 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2432 terr = tdb_error(pdb->tdb);
2433 if (terr != TDB_ERR_NOEXIST) {
2434 DEBUG(0, ("allocate_print_jobid: "
2435 "Failed to fetch INFO/nextjob "
2436 "for print queue %s\n", sharename));
2437 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2438 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2440 DEBUG(10, ("allocate_print_jobid: "
2441 "No existing jobid in %s\n", sharename));
2442 jobid = 0;
2445 DEBUG(10, ("allocate_print_jobid: "
2446 "Read jobid %u from %s\n", jobid, sharename));
2448 jobid = NEXT_JOBID(jobid);
2450 ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid);
2451 if (ret == -1) {
2452 terr = tdb_error(pdb->tdb);
2453 DEBUG(3, ("allocate_print_jobid: "
2454 "Failed to store INFO/nextjob.\n"));
2455 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2456 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2459 /* We've finished with the INFO/nextjob lock. */
2460 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2462 if (!print_job_exists(sharename, jobid)) {
2463 break;
2465 DEBUG(10, ("allocate_print_jobid: "
2466 "Found jobid %u in %s\n", jobid, sharename));
2469 if (i > 2) {
2470 DEBUG(0, ("allocate_print_jobid: "
2471 "Failed to allocate a print job for queue %s\n",
2472 sharename));
2473 /* Probably full... */
2474 return WERR_NO_SPOOL_SPACE;
2477 /* Store a dummy placeholder. */
2479 uint32_t tmp;
2480 TDB_DATA dum;
2481 dum.dptr = NULL;
2482 dum.dsize = 0;
2483 if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
2484 TDB_INSERT) == -1) {
2485 DEBUG(3, ("allocate_print_jobid: "
2486 "jobid (%d) failed to store placeholder.\n",
2487 jobid ));
2488 terr = tdb_error(pdb->tdb);
2489 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2493 *pjobid = jobid;
2494 return WERR_OK;
2497 /***************************************************************************
2498 Append a jobid to the 'jobs changed' list.
2499 ***************************************************************************/
2501 static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
2503 TDB_DATA data;
2504 uint32 store_jobid;
2506 SIVAL(&store_jobid, 0, jobid);
2507 data.dptr = (uint8 *)&store_jobid;
2508 data.dsize = 4;
2510 DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
2512 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
2513 data) == 0);
2517 /***************************************************************************
2518 Do all checks needed to determine if we can start a job.
2519 ***************************************************************************/
2521 static WERROR print_job_checks(struct auth_serversupplied_info *server_info,
2522 struct messaging_context *msg_ctx,
2523 int snum, int *njobs)
2525 const char *sharename = lp_const_servicename(snum);
2526 uint64_t dspace, dsize;
2527 uint64_t minspace;
2528 int ret;
2530 if (!print_access_check(server_info, msg_ctx, snum,
2531 PRINTER_ACCESS_USE)) {
2532 DEBUG(3, ("print_job_checks: "
2533 "job start denied by security descriptor\n"));
2534 return WERR_ACCESS_DENIED;
2537 if (!print_time_access_check(server_info, msg_ctx, sharename)) {
2538 DEBUG(3, ("print_job_checks: "
2539 "job start denied by time check\n"));
2540 return WERR_ACCESS_DENIED;
2543 /* see if we have sufficient disk space */
2544 if (lp_minprintspace(snum)) {
2545 minspace = lp_minprintspace(snum);
2546 ret = sys_fsusage(lp_pathname(snum), &dspace, &dsize);
2547 if (ret == 0 && dspace < 2*minspace) {
2548 DEBUG(3, ("print_job_checks: "
2549 "disk space check failed.\n"));
2550 return WERR_NO_SPOOL_SPACE;
2554 /* for autoloaded printers, check that the printcap entry still exists */
2555 if (lp_autoloaded(snum) && !pcap_printername_ok(sharename)) {
2556 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2557 sharename));
2558 return WERR_ACCESS_DENIED;
2561 /* Insure the maximum queue size is not violated */
2562 *njobs = print_queue_length(msg_ctx, snum, NULL);
2563 if (*njobs > lp_maxprintjobs(snum)) {
2564 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2565 "larger than max printjobs per queue (%d).\n",
2566 sharename, *njobs, lp_maxprintjobs(snum)));
2567 return WERR_NO_SPOOL_SPACE;
2570 return WERR_OK;
2573 /***************************************************************************
2574 Create a job file.
2575 ***************************************************************************/
2577 static WERROR print_job_spool_file(int snum, uint32_t jobid,
2578 const char *output_file,
2579 struct printjob *pjob)
2581 WERROR werr;
2582 SMB_STRUCT_STAT st;
2583 const char *path;
2584 int len;
2586 /* if this file is within the printer path, it means that smbd
2587 * is spooling it and will pass us control when it is finished.
2588 * Verify that the file name is ok, within path, and it is
2589 * already already there */
2590 if (output_file) {
2591 path = lp_pathname(snum);
2592 len = strlen(path);
2593 if (strncmp(output_file, path, len) == 0 &&
2594 (output_file[len - 1] == '/' || output_file[len] == '/')) {
2596 /* verify path is not too long */
2597 if (strlen(output_file) >= sizeof(pjob->filename)) {
2598 return WERR_INVALID_NAME;
2601 /* verify that the file exists */
2602 if (sys_stat(output_file, &st, false) != 0) {
2603 return WERR_INVALID_NAME;
2606 fstrcpy(pjob->filename, output_file);
2608 DEBUG(3, ("print_job_spool_file:"
2609 "External spooling activated"));
2611 /* we do not open the file until spooling is done */
2612 pjob->fd = -1;
2613 pjob->status = PJOB_SMBD_SPOOLING;
2615 return WERR_OK;
2619 slprintf(pjob->filename, sizeof(pjob->filename)-1,
2620 "%s/%s%.8u.XXXXXX", lp_pathname(snum),
2621 PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2622 pjob->fd = mkstemp(pjob->filename);
2624 if (pjob->fd == -1) {
2625 werr = map_werror_from_unix(errno);
2626 if (W_ERROR_EQUAL(werr, WERR_ACCESS_DENIED)) {
2627 /* Common setup error, force a report. */
2628 DEBUG(0, ("print_job_spool_file: "
2629 "insufficient permissions to open spool "
2630 "file %s.\n", pjob->filename));
2631 } else {
2632 /* Normal case, report at level 3 and above. */
2633 DEBUG(3, ("print_job_spool_file: "
2634 "can't open spool file %s\n",
2635 pjob->filename));
2637 return werr;
2640 return WERR_OK;
2643 /***************************************************************************
2644 Start spooling a job - return the jobid.
2645 ***************************************************************************/
2647 WERROR print_job_start(struct auth_serversupplied_info *server_info,
2648 struct messaging_context *msg_ctx,
2649 int snum, const char *docname, const char *filename,
2650 struct spoolss_DeviceMode *devmode, uint32_t *_jobid)
2652 uint32_t jobid;
2653 char *path;
2654 struct printjob pjob;
2655 const char *sharename = lp_const_servicename(snum);
2656 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2657 int njobs;
2658 WERROR werr;
2660 if (!pdb) {
2661 return WERR_INTERNAL_DB_CORRUPTION;
2664 path = lp_pathname(snum);
2666 werr = print_job_checks(server_info, msg_ctx, snum, &njobs);
2667 if (!W_ERROR_IS_OK(werr)) {
2668 release_print_db(pdb);
2669 return werr;
2672 DEBUG(10, ("print_job_start: "
2673 "Queue %s number of jobs (%d), max printjobs = %d\n",
2674 sharename, njobs, lp_maxprintjobs(snum)));
2676 werr = allocate_print_jobid(pdb, snum, sharename, &jobid);
2677 if (!W_ERROR_IS_OK(werr)) {
2678 goto fail;
2681 /* create the database entry */
2683 ZERO_STRUCT(pjob);
2685 pjob.pid = sys_getpid();
2686 pjob.sysjob = -1;
2687 pjob.fd = -1;
2688 pjob.starttime = time(NULL);
2689 pjob.status = LPQ_SPOOLING;
2690 pjob.size = 0;
2691 pjob.spooled = False;
2692 pjob.smbjob = True;
2693 pjob.devmode = devmode;
2695 fstrcpy(pjob.jobname, docname);
2697 fstrcpy(pjob.user, lp_printjob_username(snum));
2698 standard_sub_advanced(sharename, server_info->sanitized_username,
2699 path, server_info->utok.gid,
2700 server_info->sanitized_username,
2701 server_info->info3->base.domain.string,
2702 pjob.user, sizeof(pjob.user)-1);
2703 /* ensure NULL termination */
2704 pjob.user[sizeof(pjob.user)-1] = '\0';
2706 fstrcpy(pjob.queuename, lp_const_servicename(snum));
2708 /* we have a job entry - now create the spool file */
2709 werr = print_job_spool_file(snum, jobid, filename, &pjob);
2710 if (!W_ERROR_IS_OK(werr)) {
2711 goto fail;
2714 pjob_store(sharename, jobid, &pjob);
2716 /* Update the 'jobs changed' entry used by print_queue_status. */
2717 add_to_jobs_changed(pdb, jobid);
2719 /* Ensure we keep a rough count of the number of total jobs... */
2720 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2722 release_print_db(pdb);
2724 *_jobid = jobid;
2725 return WERR_OK;
2727 fail:
2728 if (jobid != -1) {
2729 pjob_delete(sharename, jobid);
2732 release_print_db(pdb);
2734 DEBUG(3, ("print_job_start: returning fail. "
2735 "Error = %s\n", win_errstr(werr)));
2736 return werr;
2739 /****************************************************************************
2740 Update the number of pages spooled to jobid
2741 ****************************************************************************/
2743 void print_job_endpage(int snum, uint32 jobid)
2745 const char* sharename = lp_const_servicename(snum);
2746 struct printjob *pjob;
2748 pjob = print_job_find(sharename, jobid);
2749 if (!pjob)
2750 return;
2751 /* don't allow another process to get this info - it is meaningless */
2752 if (pjob->pid != sys_getpid())
2753 return;
2755 pjob->page_count++;
2756 pjob_store(sharename, jobid, pjob);
2759 /****************************************************************************
2760 Print a file - called on closing the file. This spools the job.
2761 If normal close is false then we're tearing down the jobs - treat as an
2762 error.
2763 ****************************************************************************/
2765 NTSTATUS print_job_end(struct messaging_context *msg_ctx, int snum,
2766 uint32 jobid, enum file_close_type close_type)
2768 const char* sharename = lp_const_servicename(snum);
2769 struct printjob *pjob;
2770 int ret;
2771 SMB_STRUCT_STAT sbuf;
2772 struct printif *current_printif = get_printer_fns( snum );
2773 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2775 pjob = print_job_find(sharename, jobid);
2777 if (!pjob) {
2778 return NT_STATUS_PRINT_CANCELLED;
2781 if (pjob->spooled || pjob->pid != sys_getpid()) {
2782 return NT_STATUS_ACCESS_DENIED;
2785 if (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) {
2786 if (pjob->status == PJOB_SMBD_SPOOLING) {
2787 /* take over the file now, smbd is done */
2788 if (sys_stat(pjob->filename, &sbuf, false) != 0) {
2789 status = map_nt_error_from_unix(errno);
2790 DEBUG(3, ("print_job_end: "
2791 "stat file failed for jobid %d\n",
2792 jobid));
2793 goto fail;
2796 pjob->status = LPQ_SPOOLING;
2798 } else {
2800 if ((sys_fstat(pjob->fd, &sbuf, false) != 0)) {
2801 status = map_nt_error_from_unix(errno);
2802 close(pjob->fd);
2803 DEBUG(3, ("print_job_end: "
2804 "stat file failed for jobid %d\n",
2805 jobid));
2806 goto fail;
2809 close(pjob->fd);
2812 pjob->size = sbuf.st_ex_size;
2813 } else {
2816 * Not a normal close, something has gone wrong. Cleanup.
2818 if (pjob->fd != -1) {
2819 close(pjob->fd);
2821 goto fail;
2824 /* Technically, this is not quite right. If the printer has a separator
2825 * page turned on, the NT spooler prints the separator page even if the
2826 * print job is 0 bytes. 010215 JRR */
2827 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2828 /* don't bother spooling empty files or something being deleted. */
2829 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2830 pjob->filename, pjob->size ? "deleted" : "zero length" ));
2831 unlink(pjob->filename);
2832 pjob_delete(sharename, jobid);
2833 return NT_STATUS_OK;
2836 ret = (*(current_printif->job_submit))(snum, pjob);
2838 if (ret) {
2839 status = NT_STATUS_PRINT_CANCELLED;
2840 goto fail;
2843 /* The print job has been successfully handed over to the back-end */
2845 pjob->spooled = True;
2846 pjob->status = LPQ_QUEUED;
2847 pjob_store(sharename, jobid, pjob);
2849 /* make sure the database is up to date */
2850 if (print_cache_expired(lp_const_servicename(snum), True))
2851 print_queue_update(msg_ctx, snum, False);
2853 return NT_STATUS_OK;
2855 fail:
2857 /* The print job was not successfully started. Cleanup */
2858 /* Still need to add proper error return propagation! 010122:JRR */
2859 pjob->fd = -1;
2860 unlink(pjob->filename);
2861 pjob_delete(sharename, jobid);
2862 return status;
2865 /****************************************************************************
2866 Get a snapshot of jobs in the system without traversing.
2867 ****************************************************************************/
2869 static bool get_stored_queue_info(struct messaging_context *msg_ctx,
2870 struct tdb_print_db *pdb, int snum,
2871 int *pcount, print_queue_struct **ppqueue)
2873 TDB_DATA data, cgdata;
2874 print_queue_struct *queue = NULL;
2875 uint32 qcount = 0;
2876 uint32 extra_count = 0;
2877 int total_count = 0;
2878 size_t len = 0;
2879 uint32 i;
2880 int max_reported_jobs = lp_max_reported_jobs(snum);
2881 bool ret = False;
2882 const char* sharename = lp_servicename(snum);
2884 /* make sure the database is up to date */
2885 if (print_cache_expired(lp_const_servicename(snum), True))
2886 print_queue_update(msg_ctx, snum, False);
2888 *pcount = 0;
2889 *ppqueue = NULL;
2891 ZERO_STRUCT(data);
2892 ZERO_STRUCT(cgdata);
2894 /* Get the stored queue data. */
2895 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
2897 if (data.dptr && data.dsize >= sizeof(qcount))
2898 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2900 /* Get the changed jobs list. */
2901 cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
2902 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2903 extra_count = cgdata.dsize/4;
2905 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2907 /* Allocate the queue size. */
2908 if (qcount == 0 && extra_count == 0)
2909 goto out;
2911 if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
2912 goto out;
2914 /* Retrieve the linearised queue data. */
2916 for( i = 0; i < qcount; i++) {
2917 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2918 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2919 &qjob,
2920 &qsize,
2921 &qpage_count,
2922 &qstatus,
2923 &qpriority,
2924 &qtime,
2925 queue[i].fs_user,
2926 queue[i].fs_file);
2927 queue[i].job = qjob;
2928 queue[i].size = qsize;
2929 queue[i].page_count = qpage_count;
2930 queue[i].status = qstatus;
2931 queue[i].priority = qpriority;
2932 queue[i].time = qtime;
2935 total_count = qcount;
2937 /* Add in the changed jobids. */
2938 for( i = 0; i < extra_count; i++) {
2939 uint32 jobid;
2940 struct printjob *pjob;
2942 jobid = IVAL(cgdata.dptr, i*4);
2943 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2944 pjob = print_job_find(lp_const_servicename(snum), jobid);
2945 if (!pjob) {
2946 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2947 remove_from_jobs_changed(sharename, jobid);
2948 continue;
2951 queue[total_count].job = jobid;
2952 queue[total_count].size = pjob->size;
2953 queue[total_count].page_count = pjob->page_count;
2954 queue[total_count].status = pjob->status;
2955 queue[total_count].priority = 1;
2956 queue[total_count].time = pjob->starttime;
2957 fstrcpy(queue[total_count].fs_user, pjob->user);
2958 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2959 total_count++;
2962 /* Sort the queue by submission time otherwise they are displayed
2963 in hash order. */
2965 TYPESAFE_QSORT(queue, total_count, printjob_comp);
2967 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2969 if (max_reported_jobs && total_count > max_reported_jobs)
2970 total_count = max_reported_jobs;
2972 *ppqueue = queue;
2973 *pcount = total_count;
2975 ret = True;
2977 out:
2979 SAFE_FREE(data.dptr);
2980 SAFE_FREE(cgdata.dptr);
2981 return ret;
2984 /****************************************************************************
2985 Get a printer queue listing.
2986 set queue = NULL and status = NULL if you just want to update the cache
2987 ****************************************************************************/
2989 int print_queue_status(struct messaging_context *msg_ctx, int snum,
2990 print_queue_struct **ppqueue,
2991 print_status_struct *status)
2993 fstring keystr;
2994 TDB_DATA data, key;
2995 const char *sharename;
2996 struct tdb_print_db *pdb;
2997 int count = 0;
2999 /* make sure the database is up to date */
3001 if (print_cache_expired(lp_const_servicename(snum), True))
3002 print_queue_update(msg_ctx, snum, False);
3004 /* return if we are done */
3005 if ( !ppqueue || !status )
3006 return 0;
3008 *ppqueue = NULL;
3009 sharename = lp_const_servicename(snum);
3010 pdb = get_print_db_byname(sharename);
3012 if (!pdb)
3013 return 0;
3016 * Fetch the queue status. We must do this first, as there may
3017 * be no jobs in the queue.
3020 ZERO_STRUCTP(status);
3021 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
3022 key = string_tdb_data(keystr);
3024 data = tdb_fetch(pdb->tdb, key);
3025 if (data.dptr) {
3026 if (data.dsize == sizeof(*status)) {
3027 /* this memcpy is ok since the status struct was
3028 not packed before storing it in the tdb */
3029 memcpy(status, data.dptr, sizeof(*status));
3031 SAFE_FREE(data.dptr);
3035 * Now, fetch the print queue information. We first count the number
3036 * of entries, and then only retrieve the queue if necessary.
3039 if (!get_stored_queue_info(msg_ctx, pdb, snum, &count, ppqueue)) {
3040 release_print_db(pdb);
3041 return 0;
3044 release_print_db(pdb);
3045 return count;
3048 /****************************************************************************
3049 Pause a queue.
3050 ****************************************************************************/
3052 WERROR print_queue_pause(struct auth_serversupplied_info *server_info,
3053 struct messaging_context *msg_ctx, int snum)
3055 int ret;
3056 struct printif *current_printif = get_printer_fns( snum );
3058 if (!print_access_check(server_info, msg_ctx, snum,
3059 PRINTER_ACCESS_ADMINISTER)) {
3060 return WERR_ACCESS_DENIED;
3064 become_root();
3066 ret = (*(current_printif->queue_pause))(snum);
3068 unbecome_root();
3070 if (ret != 0) {
3071 return WERR_INVALID_PARAM;
3074 /* force update the database */
3075 print_cache_flush(lp_const_servicename(snum));
3077 /* Send a printer notify message */
3079 notify_printer_status(server_event_context(), msg_ctx, snum,
3080 PRINTER_STATUS_PAUSED);
3082 return WERR_OK;
3085 /****************************************************************************
3086 Resume a queue.
3087 ****************************************************************************/
3089 WERROR print_queue_resume(struct auth_serversupplied_info *server_info,
3090 struct messaging_context *msg_ctx, int snum)
3092 int ret;
3093 struct printif *current_printif = get_printer_fns( snum );
3095 if (!print_access_check(server_info, msg_ctx, snum,
3096 PRINTER_ACCESS_ADMINISTER)) {
3097 return WERR_ACCESS_DENIED;
3100 become_root();
3102 ret = (*(current_printif->queue_resume))(snum);
3104 unbecome_root();
3106 if (ret != 0) {
3107 return WERR_INVALID_PARAM;
3110 /* make sure the database is up to date */
3111 if (print_cache_expired(lp_const_servicename(snum), True))
3112 print_queue_update(msg_ctx, snum, True);
3114 /* Send a printer notify message */
3116 notify_printer_status(server_event_context(), msg_ctx, snum,
3117 PRINTER_STATUS_OK);
3119 return WERR_OK;
3122 /****************************************************************************
3123 Purge a queue - implemented by deleting all jobs that we can delete.
3124 ****************************************************************************/
3126 WERROR print_queue_purge(struct auth_serversupplied_info *server_info,
3127 struct messaging_context *msg_ctx, int snum)
3129 print_queue_struct *queue;
3130 print_status_struct status;
3131 int njobs, i;
3132 bool can_job_admin;
3134 /* Force and update so the count is accurate (i.e. not a cached count) */
3135 print_queue_update(msg_ctx, snum, True);
3137 can_job_admin = print_access_check(server_info,
3138 msg_ctx,
3139 snum,
3140 JOB_ACCESS_ADMINISTER);
3141 njobs = print_queue_status(msg_ctx, snum, &queue, &status);
3143 if ( can_job_admin )
3144 become_root();
3146 for (i=0;i<njobs;i++) {
3147 bool owner = is_owner(server_info, lp_const_servicename(snum),
3148 queue[i].job);
3150 if (owner || can_job_admin) {
3151 print_job_delete1(snum, queue[i].job);
3155 if ( can_job_admin )
3156 unbecome_root();
3158 /* update the cache */
3159 print_queue_update(msg_ctx, snum, True);
3161 SAFE_FREE(queue);
3163 return WERR_OK;