printing: update registry and publish in background
[Samba.git] / source3 / printing / printing.c
blob16821ae8a44075a3c180f9f57e685becf3674afc
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 "system/syslog.h"
24 #include "system/filesys.h"
25 #include "printing.h"
26 #include "../librpc/gen_ndr/ndr_spoolss.h"
27 #include "nt_printing.h"
28 #include "../librpc/gen_ndr/netlogon.h"
29 #include "printing/notify.h"
30 #include "printing/pcap.h"
31 #include "serverid.h"
32 #include "smbd/smbd.h"
33 #include "auth.h"
34 #include "messages.h"
35 #include "util_tdb.h"
37 extern struct current_user current_user;
38 extern userdom_struct current_user_info;
40 /* Current printer interface */
41 static bool remove_from_jobs_added(const char* sharename, uint32 jobid);
44 the printing backend revolves around a tdb database that stores the
45 SMB view of the print queue
47 The key for this database is a jobid - a internally generated number that
48 uniquely identifies a print job
50 reading the print queue involves two steps:
51 - possibly running lpq and updating the internal database from that
52 - reading entries from the database
54 jobids are assigned when a job starts spooling.
57 static TDB_CONTEXT *rap_tdb;
58 static uint16 next_rap_jobid;
59 struct rap_jobid_key {
60 fstring sharename;
61 uint32 jobid;
64 /***************************************************************************
65 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
66 bit RPC jobids.... JRA.
67 ***************************************************************************/
69 uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
71 uint16 rap_jobid;
72 TDB_DATA data, key;
73 struct rap_jobid_key jinfo;
74 uint8 buf[2];
76 DEBUG(10,("pjobid_to_rap: called.\n"));
78 if (!rap_tdb) {
79 /* Create the in-memory tdb. */
80 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
81 if (!rap_tdb)
82 return 0;
85 ZERO_STRUCT( jinfo );
86 fstrcpy( jinfo.sharename, sharename );
87 jinfo.jobid = jobid;
88 key.dptr = (uint8 *)&jinfo;
89 key.dsize = sizeof(jinfo);
91 data = tdb_fetch(rap_tdb, key);
92 if (data.dptr && data.dsize == sizeof(uint16)) {
93 rap_jobid = SVAL(data.dptr, 0);
94 SAFE_FREE(data.dptr);
95 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
96 (unsigned int)jobid, (unsigned int)rap_jobid));
97 return rap_jobid;
99 SAFE_FREE(data.dptr);
100 /* Not found - create and store mapping. */
101 rap_jobid = ++next_rap_jobid;
102 if (rap_jobid == 0)
103 rap_jobid = ++next_rap_jobid;
104 SSVAL(buf,0,rap_jobid);
105 data.dptr = buf;
106 data.dsize = sizeof(rap_jobid);
107 tdb_store(rap_tdb, key, data, TDB_REPLACE);
108 tdb_store(rap_tdb, data, key, TDB_REPLACE);
110 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
111 (unsigned int)jobid, (unsigned int)rap_jobid));
112 return rap_jobid;
115 bool rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
117 TDB_DATA data, key;
118 uint8 buf[2];
120 DEBUG(10,("rap_to_pjobid called.\n"));
122 if (!rap_tdb)
123 return False;
125 SSVAL(buf,0,rap_jobid);
126 key.dptr = buf;
127 key.dsize = sizeof(rap_jobid);
128 data = tdb_fetch(rap_tdb, key);
129 if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) )
131 struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
132 if (sharename != NULL) {
133 fstrcpy( sharename, jinfo->sharename );
135 *pjobid = jinfo->jobid;
136 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
137 (unsigned int)*pjobid, (unsigned int)rap_jobid));
138 SAFE_FREE(data.dptr);
139 return True;
142 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
143 (unsigned int)rap_jobid));
144 SAFE_FREE(data.dptr);
145 return False;
148 void rap_jobid_delete(const char* sharename, uint32 jobid)
150 TDB_DATA key, data;
151 uint16 rap_jobid;
152 struct rap_jobid_key jinfo;
153 uint8 buf[2];
155 DEBUG(10,("rap_jobid_delete: called.\n"));
157 if (!rap_tdb)
158 return;
160 ZERO_STRUCT( jinfo );
161 fstrcpy( jinfo.sharename, sharename );
162 jinfo.jobid = jobid;
163 key.dptr = (uint8 *)&jinfo;
164 key.dsize = sizeof(jinfo);
166 data = tdb_fetch(rap_tdb, key);
167 if (!data.dptr || (data.dsize != sizeof(uint16))) {
168 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
169 (unsigned int)jobid ));
170 SAFE_FREE(data.dptr);
171 return;
174 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
175 (unsigned int)jobid ));
177 rap_jobid = SVAL(data.dptr, 0);
178 SAFE_FREE(data.dptr);
179 SSVAL(buf,0,rap_jobid);
180 data.dptr = buf;
181 data.dsize = sizeof(rap_jobid);
182 tdb_delete(rap_tdb, key);
183 tdb_delete(rap_tdb, data);
186 static int get_queue_status(const char* sharename, print_status_struct *);
188 /****************************************************************************
189 Initialise the printing backend. Called once at startup before the fork().
190 ****************************************************************************/
192 bool print_backend_init(struct messaging_context *msg_ctx)
194 const char *sversion = "INFO/version";
195 int services = lp_numservices();
196 int snum;
198 unlink(cache_path("printing.tdb"));
199 mkdir(cache_path("printing"),0755);
201 /* handle a Samba upgrade */
203 for (snum = 0; snum < services; snum++) {
204 struct tdb_print_db *pdb;
205 if (!lp_print_ok(snum))
206 continue;
208 pdb = get_print_db_byname(lp_const_servicename(snum));
209 if (!pdb)
210 continue;
211 if (tdb_lock_bystring(pdb->tdb, sversion) == -1) {
212 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
213 release_print_db(pdb);
214 return False;
216 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
217 tdb_wipe_all(pdb->tdb);
218 tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
220 tdb_unlock_bystring(pdb->tdb, sversion);
221 release_print_db(pdb);
224 close_all_print_db(); /* Don't leave any open. */
226 /* do NT print initialization... */
227 return nt_printing_init(msg_ctx);
230 /****************************************************************************
231 Shut down printing backend. Called once at shutdown to close the tdb.
232 ****************************************************************************/
234 void printing_end(void)
236 close_all_print_db(); /* Don't leave any open. */
239 /****************************************************************************
240 Retrieve the set of printing functions for a given service. This allows
241 us to set the printer function table based on the value of the 'printing'
242 service parameter.
244 Use the generic interface as the default and only use cups interface only
245 when asked for (and only when supported)
246 ****************************************************************************/
248 static struct printif *get_printer_fns_from_type( enum printing_types type )
250 struct printif *printer_fns = &generic_printif;
252 #ifdef HAVE_CUPS
253 if ( type == PRINT_CUPS ) {
254 printer_fns = &cups_printif;
256 #endif /* HAVE_CUPS */
258 #ifdef HAVE_IPRINT
259 if ( type == PRINT_IPRINT ) {
260 printer_fns = &iprint_printif;
262 #endif /* HAVE_IPRINT */
264 printer_fns->type = type;
266 return printer_fns;
269 static struct printif *get_printer_fns( int snum )
271 return get_printer_fns_from_type( (enum printing_types)lp_printing(snum) );
275 /****************************************************************************
276 Useful function to generate a tdb key.
277 ****************************************************************************/
279 static TDB_DATA print_key(uint32 jobid, uint32 *tmp)
281 TDB_DATA ret;
283 SIVAL(tmp, 0, jobid);
284 ret.dptr = (uint8 *)tmp;
285 ret.dsize = sizeof(*tmp);
286 return ret;
289 /****************************************************************************
290 Pack the devicemode to store it in a tdb.
291 ****************************************************************************/
292 static int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8 *buf, int buflen)
294 enum ndr_err_code ndr_err;
295 DATA_BLOB blob;
296 int len = 0;
298 if (devmode) {
299 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(),
300 devmode,
301 (ndr_push_flags_fn_t)
302 ndr_push_spoolss_DeviceMode);
303 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
304 DEBUG(10, ("pack_devicemode: "
305 "error encoding spoolss_DeviceMode\n"));
306 goto done;
308 } else {
309 ZERO_STRUCT(blob);
312 len = tdb_pack(buf, buflen, "B", blob.length, blob.data);
314 if (devmode) {
315 DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname));
318 done:
319 return len;
322 /****************************************************************************
323 Unpack the devicemode to store it in a tdb.
324 ****************************************************************************/
325 static int unpack_devicemode(TALLOC_CTX *mem_ctx,
326 const uint8 *buf, int buflen,
327 struct spoolss_DeviceMode **devmode)
329 struct spoolss_DeviceMode *dm;
330 enum ndr_err_code ndr_err;
331 char *data = NULL;
332 int data_len = 0;
333 DATA_BLOB blob;
334 int len = 0;
336 *devmode = NULL;
338 len = tdb_unpack(buf, buflen, "B", &data_len, &data);
339 if (!data) {
340 return len;
343 dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
344 if (!dm) {
345 goto done;
348 blob = data_blob_const(data, data_len);
350 ndr_err = ndr_pull_struct_blob(&blob, dm, dm,
351 (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);
352 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
353 DEBUG(10, ("unpack_devicemode: "
354 "error parsing spoolss_DeviceMode\n"));
355 goto done;
358 DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
359 dm->devicename, dm->formname));
360 if (dm->driverextra_data.data) {
361 DEBUG(8, ("with a private section of %d bytes\n",
362 dm->__driverextra_length));
365 *devmode = dm;
367 done:
368 SAFE_FREE(data);
369 return len;
372 /***********************************************************************
373 unpack a pjob from a tdb buffer
374 ***********************************************************************/
376 static int unpack_pjob(TALLOC_CTX *mem_ctx, uint8 *buf, int buflen,
377 struct printjob *pjob)
379 int len = 0;
380 int used;
381 uint32 pjpid, pjjobid, pjsysjob, pjfd, pjstarttime, pjstatus;
382 uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
384 if (!buf || !pjob) {
385 return -1;
388 len += tdb_unpack(buf+len, buflen-len, "ddddddddddfffff",
389 &pjpid,
390 &pjjobid,
391 &pjsysjob,
392 &pjfd,
393 &pjstarttime,
394 &pjstatus,
395 &pjsize,
396 &pjpage_count,
397 &pjspooled,
398 &pjsmbjob,
399 pjob->filename,
400 pjob->jobname,
401 pjob->user,
402 pjob->clientmachine,
403 pjob->queuename);
405 if (len == -1) {
406 return -1;
409 used = unpack_devicemode(mem_ctx, buf+len, buflen-len, &pjob->devmode);
410 if (used == -1) {
411 return -1;
414 len += used;
416 pjob->pid = pjpid;
417 pjob->jobid = pjjobid;
418 pjob->sysjob = pjsysjob;
419 pjob->fd = pjfd;
420 pjob->starttime = pjstarttime;
421 pjob->status = pjstatus;
422 pjob->size = pjsize;
423 pjob->page_count = pjpage_count;
424 pjob->spooled = pjspooled;
425 pjob->smbjob = pjsmbjob;
427 return len;
431 /****************************************************************************
432 Useful function to find a print job in the database.
433 ****************************************************************************/
435 static struct printjob *print_job_find(TALLOC_CTX *mem_ctx,
436 const char *sharename,
437 uint32 jobid)
439 struct printjob *pjob;
440 uint32_t tmp;
441 TDB_DATA ret;
442 struct tdb_print_db *pdb = get_print_db_byname(sharename);
444 DEBUG(10,("print_job_find: looking up job %u for share %s\n",
445 (unsigned int)jobid, sharename ));
447 if (!pdb) {
448 return NULL;
451 ret = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
452 release_print_db(pdb);
454 if (!ret.dptr) {
455 DEBUG(10, ("print_job_find: failed to find jobid %u.\n",
456 jobid));
457 return NULL;
460 pjob = talloc_zero(mem_ctx, struct printjob);
461 if (pjob == NULL) {
462 goto err_out;
465 if (unpack_pjob(mem_ctx, ret.dptr, ret.dsize, pjob) == -1) {
466 DEBUG(10, ("failed to unpack jobid %u.\n", jobid));
467 talloc_free(pjob);
468 pjob = NULL;
469 goto err_out;
472 DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
473 pjob->sysjob, jobid));
474 SMB_ASSERT(pjob->jobid == jobid);
476 err_out:
477 SAFE_FREE(ret.dptr);
478 return pjob;
481 /* Convert a unix jobid to a smb jobid */
483 struct unixjob_traverse_state {
484 int sysjob;
485 uint32 sysjob_to_jobid_value;
488 static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
489 TDB_DATA data, void *private_data)
491 struct printjob *pjob;
492 struct unixjob_traverse_state *state =
493 (struct unixjob_traverse_state *)private_data;
495 if (!data.dptr || data.dsize == 0)
496 return 0;
498 pjob = (struct printjob *)data.dptr;
499 if (key.dsize != sizeof(uint32))
500 return 0;
502 if (state->sysjob == pjob->sysjob) {
503 state->sysjob_to_jobid_value = pjob->jobid;
504 return 1;
507 return 0;
510 static uint32 sysjob_to_jobid_pdb(struct tdb_print_db *pdb, int sysjob)
512 struct unixjob_traverse_state state;
514 state.sysjob = sysjob;
515 state.sysjob_to_jobid_value = (uint32)-1;
517 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &state);
519 return state.sysjob_to_jobid_value;
522 /****************************************************************************
523 This is a *horribly expensive call as we have to iterate through all the
524 current printer tdb's. Don't do this often ! JRA.
525 ****************************************************************************/
527 uint32 sysjob_to_jobid(int unix_jobid)
529 int services = lp_numservices();
530 int snum;
531 struct unixjob_traverse_state state;
533 state.sysjob = unix_jobid;
534 state.sysjob_to_jobid_value = (uint32)-1;
536 for (snum = 0; snum < services; snum++) {
537 struct tdb_print_db *pdb;
538 if (!lp_print_ok(snum))
539 continue;
540 pdb = get_print_db_byname(lp_const_servicename(snum));
541 if (!pdb) {
542 continue;
544 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &state);
545 release_print_db(pdb);
546 if (state.sysjob_to_jobid_value != (uint32)-1)
547 return state.sysjob_to_jobid_value;
549 return (uint32)-1;
552 /****************************************************************************
553 Send notifications based on what has changed after a pjob_store.
554 ****************************************************************************/
556 static const struct {
557 uint32_t lpq_status;
558 uint32_t spoolss_status;
559 } lpq_to_spoolss_status_map[] = {
560 { LPQ_QUEUED, JOB_STATUS_QUEUED },
561 { LPQ_PAUSED, JOB_STATUS_PAUSED },
562 { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
563 { LPQ_PRINTING, JOB_STATUS_PRINTING },
564 { LPQ_DELETING, JOB_STATUS_DELETING },
565 { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
566 { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
567 { LPQ_PRINTED, JOB_STATUS_PRINTED },
568 { LPQ_DELETED, JOB_STATUS_DELETED },
569 { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ },
570 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
571 { (uint32_t)-1, 0 }
574 /* Convert a lpq status value stored in printing.tdb into the
575 appropriate win32 API constant. */
577 static uint32 map_to_spoolss_status(uint32 lpq_status)
579 int i = 0;
581 while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
582 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
583 return lpq_to_spoolss_status_map[i].spoolss_status;
584 i++;
587 return 0;
590 /***************************************************************************
591 Append a jobid to the 'jobs changed' list.
592 ***************************************************************************/
594 static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32_t jobid)
596 TDB_DATA data;
597 uint32_t store_jobid;
599 SIVAL(&store_jobid, 0, jobid);
600 data.dptr = (uint8 *) &store_jobid;
601 data.dsize = 4;
603 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid ));
605 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
606 data) == 0);
609 /***************************************************************************
610 Remove a jobid from the 'jobs changed' list.
611 ***************************************************************************/
613 static bool remove_from_jobs_changed(const char* sharename, uint32_t jobid)
615 struct tdb_print_db *pdb = get_print_db_byname(sharename);
616 TDB_DATA data, key;
617 size_t job_count, i;
618 bool ret = False;
619 bool gotlock = False;
621 if (!pdb) {
622 return False;
625 ZERO_STRUCT(data);
627 key = string_tdb_data("INFO/jobs_changed");
629 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
630 goto out;
632 gotlock = True;
634 data = tdb_fetch(pdb->tdb, key);
636 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
637 goto out;
639 job_count = data.dsize / 4;
640 for (i = 0; i < job_count; i++) {
641 uint32 ch_jobid;
643 ch_jobid = IVAL(data.dptr, i*4);
644 if (ch_jobid == jobid) {
645 if (i < job_count -1 )
646 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
647 data.dsize -= 4;
648 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
649 goto out;
650 break;
654 ret = True;
655 out:
657 if (gotlock)
658 tdb_chainunlock(pdb->tdb, key);
659 SAFE_FREE(data.dptr);
660 release_print_db(pdb);
661 if (ret)
662 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
663 else
664 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
665 return ret;
668 static void pjob_store_notify(struct tevent_context *ev,
669 struct messaging_context *msg_ctx,
670 const char* sharename, uint32 jobid,
671 struct printjob *old_data,
672 struct printjob *new_data,
673 bool *pchanged)
675 bool new_job = false;
676 bool changed = false;
678 if (old_data == NULL) {
679 new_job = true;
682 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
683 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
684 time first or else we'll end up with potential alignment
685 errors. I don't think the systemtime should be spooled as
686 a string, but this gets us around that error.
687 --jerry (i'll feel dirty for this) */
689 if (new_job) {
690 notify_job_submitted(ev, msg_ctx,
691 sharename, jobid, new_data->starttime);
692 notify_job_username(ev, msg_ctx,
693 sharename, jobid, new_data->user);
694 notify_job_name(ev, msg_ctx,
695 sharename, jobid, new_data->jobname);
696 notify_job_status(ev, msg_ctx,
697 sharename, jobid, map_to_spoolss_status(new_data->status));
698 notify_job_total_bytes(ev, msg_ctx,
699 sharename, jobid, new_data->size);
700 notify_job_total_pages(ev, msg_ctx,
701 sharename, jobid, new_data->page_count);
702 } else {
703 if (!strequal(old_data->jobname, new_data->jobname)) {
704 notify_job_name(ev, msg_ctx, sharename,
705 jobid, new_data->jobname);
706 changed = true;
709 if (old_data->status != new_data->status) {
710 notify_job_status(ev, msg_ctx,
711 sharename, jobid,
712 map_to_spoolss_status(new_data->status));
715 if (old_data->size != new_data->size) {
716 notify_job_total_bytes(ev, msg_ctx,
717 sharename, jobid, new_data->size);
720 if (old_data->page_count != new_data->page_count) {
721 notify_job_total_pages(ev, msg_ctx,
722 sharename, jobid,
723 new_data->page_count);
727 *pchanged = changed;
730 /****************************************************************************
731 Store a job structure back to the database.
732 ****************************************************************************/
734 static bool pjob_store(struct tevent_context *ev,
735 struct messaging_context *msg_ctx,
736 const char* sharename, uint32 jobid,
737 struct printjob *pjob)
739 uint32_t tmp;
740 TDB_DATA old_data, new_data;
741 bool ret = False;
742 struct tdb_print_db *pdb = get_print_db_byname(sharename);
743 uint8 *buf = NULL;
744 int len, newlen, buflen;
747 if (!pdb)
748 return False;
750 /* Get old data */
752 old_data = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
754 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
756 newlen = 0;
758 do {
759 len = 0;
760 buflen = newlen;
761 len += tdb_pack(buf+len, buflen-len, "ddddddddddfffff",
762 (uint32)pjob->pid,
763 (uint32)pjob->jobid,
764 (uint32)pjob->sysjob,
765 (uint32)pjob->fd,
766 (uint32)pjob->starttime,
767 (uint32)pjob->status,
768 (uint32)pjob->size,
769 (uint32)pjob->page_count,
770 (uint32)pjob->spooled,
771 (uint32)pjob->smbjob,
772 pjob->filename,
773 pjob->jobname,
774 pjob->user,
775 pjob->clientmachine,
776 pjob->queuename);
778 len += pack_devicemode(pjob->devmode, buf+len, buflen-len);
780 if (buflen != len) {
781 buf = (uint8 *)SMB_REALLOC(buf, len);
782 if (!buf) {
783 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
784 goto done;
786 newlen = len;
788 } while ( buflen != len );
791 /* Store new data */
793 new_data.dptr = buf;
794 new_data.dsize = len;
795 ret = (tdb_store(pdb->tdb, print_key(jobid, &tmp), new_data,
796 TDB_REPLACE) == 0);
798 /* Send notify updates for what has changed */
800 if (ret) {
801 bool changed = false;
802 struct printjob old_pjob;
804 if (old_data.dsize) {
805 TALLOC_CTX *tmp_ctx = talloc_new(ev);
806 if (tmp_ctx == NULL)
807 goto done;
809 len = unpack_pjob(tmp_ctx, old_data.dptr,
810 old_data.dsize, &old_pjob);
811 if (len != -1 ) {
812 pjob_store_notify(ev,
813 msg_ctx,
814 sharename, jobid, &old_pjob,
815 pjob,
816 &changed);
817 if (changed) {
818 add_to_jobs_changed(pdb, jobid);
821 talloc_free(tmp_ctx);
823 } else {
824 /* new job */
825 pjob_store_notify(ev, msg_ctx,
826 sharename, jobid, NULL, pjob,
827 &changed);
831 done:
832 release_print_db(pdb);
833 SAFE_FREE( old_data.dptr );
834 SAFE_FREE( buf );
836 return ret;
839 /****************************************************************************
840 Remove a job structure from the database.
841 ****************************************************************************/
843 static void pjob_delete(struct tevent_context *ev,
844 struct messaging_context *msg_ctx,
845 const char* sharename, uint32 jobid)
847 uint32_t tmp;
848 struct printjob *pjob;
849 uint32 job_status = 0;
850 struct tdb_print_db *pdb;
851 TALLOC_CTX *tmp_ctx = talloc_new(ev);
852 if (tmp_ctx == NULL) {
853 return;
856 pdb = get_print_db_byname(sharename);
857 if (!pdb) {
858 goto err_out;
861 pjob = print_job_find(tmp_ctx, sharename, jobid);
862 if (!pjob) {
863 DEBUG(5, ("we were asked to delete nonexistent job %u\n",
864 jobid));
865 goto err_release;
868 /* We must cycle through JOB_STATUS_DELETING and
869 JOB_STATUS_DELETED for the port monitor to delete the job
870 properly. */
872 job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
873 notify_job_status(ev, msg_ctx, sharename, jobid, job_status);
875 /* Remove from printing.tdb */
877 tdb_delete(pdb->tdb, print_key(jobid, &tmp));
878 remove_from_jobs_added(sharename, jobid);
879 rap_jobid_delete(sharename, jobid);
880 err_release:
881 release_print_db(pdb);
882 err_out:
883 talloc_free(tmp_ctx);
886 /****************************************************************************
887 List a unix job in the print database.
888 ****************************************************************************/
890 static void print_unix_job(struct tevent_context *ev,
891 struct messaging_context *msg_ctx,
892 const char *sharename, print_queue_struct *q,
893 uint32 jobid)
895 struct printjob pj, *old_pj;
896 TALLOC_CTX *tmp_ctx = talloc_new(ev);
897 if (tmp_ctx == NULL) {
898 return;
901 if (jobid == (uint32)-1) {
902 jobid = q->sysjob + UNIX_JOB_START;
905 /* Preserve the timestamp on an existing unix print job */
907 old_pj = print_job_find(tmp_ctx, sharename, jobid);
909 ZERO_STRUCT(pj);
911 pj.pid = (pid_t)-1;
912 pj.jobid = jobid;
913 pj.sysjob = q->sysjob;
914 pj.fd = -1;
915 pj.starttime = old_pj ? old_pj->starttime : q->time;
916 pj.status = q->status;
917 pj.size = q->size;
918 pj.spooled = True;
919 fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
920 if (jobid < UNIX_JOB_START) {
921 pj.smbjob = True;
922 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
923 } else {
924 pj.smbjob = False;
925 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
927 fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
928 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
930 pjob_store(ev, msg_ctx, sharename, jobid, &pj);
931 talloc_free(tmp_ctx);
935 struct traverse_struct {
936 print_queue_struct *queue;
937 int qcount, snum, maxcount, total_jobs;
938 const char *sharename;
939 time_t lpq_time;
940 const char *lprm_command;
941 struct printif *print_if;
942 struct tevent_context *ev;
943 struct messaging_context *msg_ctx;
944 TALLOC_CTX *mem_ctx;
947 /****************************************************************************
948 Utility fn to delete any jobs that are no longer active.
949 ****************************************************************************/
951 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
953 struct traverse_struct *ts = (struct traverse_struct *)state;
954 struct printjob pjob;
955 uint32 jobid;
956 int i = 0;
958 if ( key.dsize != sizeof(jobid) )
959 return 0;
961 if (unpack_pjob(ts->mem_ctx, data.dptr, data.dsize, &pjob) == -1)
962 return 0;
963 talloc_free(pjob.devmode);
964 jobid = pjob.jobid;
966 if (!pjob.smbjob) {
967 /* remove a unix job if it isn't in the system queue any more */
968 for (i=0;i<ts->qcount;i++) {
969 if (ts->queue[i].sysjob == pjob.sysjob) {
970 break;
973 if (i == ts->qcount) {
974 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
975 (unsigned int)jobid ));
976 pjob_delete(ts->ev, ts->msg_ctx,
977 ts->sharename, jobid);
978 return 0;
981 /* need to continue the the bottom of the function to
982 save the correct attributes */
985 /* maybe it hasn't been spooled yet */
986 if (!pjob.spooled) {
987 /* if a job is not spooled and the process doesn't
988 exist then kill it. This cleans up after smbd
989 deaths */
990 if (!process_exists_by_pid(pjob.pid)) {
991 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
992 (unsigned int)jobid, (unsigned int)pjob.pid ));
993 pjob_delete(ts->ev, ts->msg_ctx,
994 ts->sharename, jobid);
995 } else
996 ts->total_jobs++;
997 return 0;
1000 /* this check only makes sense for jobs submitted from Windows clients */
1002 if (pjob.smbjob) {
1003 for (i=0;i<ts->qcount;i++) {
1004 if ( pjob.status == LPQ_DELETED )
1005 continue;
1007 if (ts->queue[i].sysjob == pjob.sysjob) {
1009 /* try to clean up any jobs that need to be deleted */
1011 if ( pjob.status == LPQ_DELETING ) {
1012 int result;
1014 result = (*(ts->print_if->job_delete))(
1015 ts->sharename, ts->lprm_command, &pjob );
1017 if ( result != 0 ) {
1018 /* if we can't delete, then reset the job status */
1019 pjob.status = LPQ_QUEUED;
1020 pjob_store(ts->ev, ts->msg_ctx,
1021 ts->sharename, jobid, &pjob);
1023 else {
1024 /* if we deleted the job, the remove the tdb record */
1025 pjob_delete(ts->ev,
1026 ts->msg_ctx,
1027 ts->sharename, jobid);
1028 pjob.status = LPQ_DELETED;
1033 break;
1038 /* The job isn't in the system queue - we have to assume it has
1039 completed, so delete the database entry. */
1041 if (i == ts->qcount) {
1043 /* A race can occur between the time a job is spooled and
1044 when it appears in the lpq output. This happens when
1045 the job is added to printing.tdb when another smbd
1046 running print_queue_update() has completed a lpq and
1047 is currently traversing the printing tdb and deleting jobs.
1048 Don't delete the job if it was submitted after the lpq_time. */
1050 if (pjob.starttime < ts->lpq_time) {
1051 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
1052 (unsigned int)jobid,
1053 (unsigned int)pjob.starttime,
1054 (unsigned int)ts->lpq_time ));
1055 pjob_delete(ts->ev, ts->msg_ctx,
1056 ts->sharename, jobid);
1057 } else
1058 ts->total_jobs++;
1059 return 0;
1062 /* Save the pjob attributes we will store. */
1063 ts->queue[i].sysjob = pjob.sysjob;
1064 ts->queue[i].size = pjob.size;
1065 ts->queue[i].page_count = pjob.page_count;
1066 ts->queue[i].status = pjob.status;
1067 ts->queue[i].priority = 1;
1068 ts->queue[i].time = pjob.starttime;
1069 fstrcpy(ts->queue[i].fs_user, pjob.user);
1070 fstrcpy(ts->queue[i].fs_file, pjob.jobname);
1072 ts->total_jobs++;
1074 return 0;
1077 /****************************************************************************
1078 Check if the print queue has been updated recently enough.
1079 ****************************************************************************/
1081 static void print_cache_flush(const char *sharename)
1083 fstring key;
1084 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1086 if (!pdb)
1087 return;
1088 slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
1089 tdb_store_int32(pdb->tdb, key, -1);
1090 release_print_db(pdb);
1093 /****************************************************************************
1094 Check if someone already thinks they are doing the update.
1095 ****************************************************************************/
1097 static pid_t get_updating_pid(const char *sharename)
1099 fstring keystr;
1100 TDB_DATA data, key;
1101 pid_t updating_pid;
1102 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1104 if (!pdb)
1105 return (pid_t)-1;
1106 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
1107 key = string_tdb_data(keystr);
1109 data = tdb_fetch(pdb->tdb, key);
1110 release_print_db(pdb);
1111 if (!data.dptr || data.dsize != sizeof(pid_t)) {
1112 SAFE_FREE(data.dptr);
1113 return (pid_t)-1;
1116 updating_pid = IVAL(data.dptr, 0);
1117 SAFE_FREE(data.dptr);
1119 if (process_exists_by_pid(updating_pid))
1120 return updating_pid;
1122 return (pid_t)-1;
1125 /****************************************************************************
1126 Set the fact that we're doing the update, or have finished doing the update
1127 in the tdb.
1128 ****************************************************************************/
1130 static void set_updating_pid(const fstring sharename, bool updating)
1132 fstring keystr;
1133 TDB_DATA key;
1134 TDB_DATA data;
1135 pid_t updating_pid = sys_getpid();
1136 uint8 buffer[4];
1138 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1140 if (!pdb)
1141 return;
1143 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
1144 key = string_tdb_data(keystr);
1146 DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
1147 updating ? "" : "not ",
1148 sharename ));
1150 if ( !updating ) {
1151 tdb_delete(pdb->tdb, key);
1152 release_print_db(pdb);
1153 return;
1156 SIVAL( buffer, 0, updating_pid);
1157 data.dptr = buffer;
1158 data.dsize = 4; /* we always assume this is a 4 byte value */
1160 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1161 release_print_db(pdb);
1164 /****************************************************************************
1165 Sort print jobs by submittal time.
1166 ****************************************************************************/
1168 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
1170 /* Silly cases */
1172 if (!j1 && !j2)
1173 return 0;
1174 if (!j1)
1175 return -1;
1176 if (!j2)
1177 return 1;
1179 /* Sort on job start time */
1181 if (j1->time == j2->time)
1182 return 0;
1183 return (j1->time > j2->time) ? 1 : -1;
1186 /****************************************************************************
1187 Store the sorted queue representation for later portmon retrieval.
1188 Skip deleted jobs
1189 ****************************************************************************/
1191 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
1193 TDB_DATA data;
1194 int max_reported_jobs = lp_max_reported_jobs(pts->snum);
1195 print_queue_struct *queue = pts->queue;
1196 size_t len;
1197 size_t i;
1198 unsigned int qcount;
1200 if (max_reported_jobs && (max_reported_jobs < pts->qcount))
1201 pts->qcount = max_reported_jobs;
1202 qcount = 0;
1204 /* Work out the size. */
1205 data.dsize = 0;
1206 data.dsize += tdb_pack(NULL, 0, "d", qcount);
1208 for (i = 0; i < pts->qcount; i++) {
1209 if ( queue[i].status == LPQ_DELETED )
1210 continue;
1212 qcount++;
1213 data.dsize += tdb_pack(NULL, 0, "ddddddff",
1214 (uint32)queue[i].sysjob,
1215 (uint32)queue[i].size,
1216 (uint32)queue[i].page_count,
1217 (uint32)queue[i].status,
1218 (uint32)queue[i].priority,
1219 (uint32)queue[i].time,
1220 queue[i].fs_user,
1221 queue[i].fs_file);
1224 if ((data.dptr = (uint8 *)SMB_MALLOC(data.dsize)) == NULL)
1225 return;
1227 len = 0;
1228 len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
1229 for (i = 0; i < pts->qcount; i++) {
1230 if ( queue[i].status == LPQ_DELETED )
1231 continue;
1233 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
1234 (uint32)queue[i].sysjob,
1235 (uint32)queue[i].size,
1236 (uint32)queue[i].page_count,
1237 (uint32)queue[i].status,
1238 (uint32)queue[i].priority,
1239 (uint32)queue[i].time,
1240 queue[i].fs_user,
1241 queue[i].fs_file);
1244 tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
1245 TDB_REPLACE);
1246 SAFE_FREE(data.dptr);
1247 return;
1250 static TDB_DATA get_jobs_added_data(struct tdb_print_db *pdb)
1252 TDB_DATA data;
1254 ZERO_STRUCT(data);
1256 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added"));
1257 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
1258 SAFE_FREE(data.dptr);
1259 ZERO_STRUCT(data);
1262 return data;
1265 static void check_job_added(const char *sharename, TDB_DATA data, uint32 jobid)
1267 unsigned int i;
1268 unsigned int job_count = data.dsize / 4;
1270 for (i = 0; i < job_count; i++) {
1271 uint32 ch_jobid;
1273 ch_jobid = IVAL(data.dptr, i*4);
1274 if (ch_jobid == jobid)
1275 remove_from_jobs_added(sharename, jobid);
1279 /****************************************************************************
1280 Check if the print queue has been updated recently enough.
1281 ****************************************************************************/
1283 static bool print_cache_expired(const char *sharename, bool check_pending)
1285 fstring key;
1286 time_t last_qscan_time, time_now = time(NULL);
1287 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1288 bool result = False;
1290 if (!pdb)
1291 return False;
1293 snprintf(key, sizeof(key), "CACHE/%s", sharename);
1294 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1297 * Invalidate the queue for 3 reasons.
1298 * (1). last queue scan time == -1.
1299 * (2). Current time - last queue scan time > allowed cache time.
1300 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1301 * This last test picks up machines for which the clock has been moved
1302 * forward, an lpq scan done and then the clock moved back. Otherwise
1303 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1306 if (last_qscan_time == ((time_t)-1)
1307 || (time_now - last_qscan_time) >= lp_lpqcachetime()
1308 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
1310 uint32 u;
1311 time_t msg_pending_time;
1313 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1314 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1315 sharename, (int)last_qscan_time, (int)time_now,
1316 (int)lp_lpqcachetime() ));
1318 /* check if another smbd has already sent a message to update the
1319 queue. Give the pending message one minute to clear and
1320 then send another message anyways. Make sure to check for
1321 clocks that have been run forward and then back again. */
1323 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1325 if ( check_pending
1326 && tdb_fetch_uint32( pdb->tdb, key, &u )
1327 && (msg_pending_time=u) > 0
1328 && msg_pending_time <= time_now
1329 && (time_now - msg_pending_time) < 60 )
1331 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1332 sharename));
1333 goto done;
1336 result = True;
1339 done:
1340 release_print_db(pdb);
1341 return result;
1344 /****************************************************************************
1345 main work for updating the lpq cache for a printer queue
1346 ****************************************************************************/
1348 static void print_queue_update_internal(struct tevent_context *ev,
1349 struct messaging_context *msg_ctx,
1350 const char *sharename,
1351 struct printif *current_printif,
1352 char *lpq_command, char *lprm_command)
1354 int i, qcount;
1355 print_queue_struct *queue = NULL;
1356 print_status_struct status;
1357 print_status_struct old_status;
1358 struct printjob *pjob;
1359 struct traverse_struct tstruct;
1360 TDB_DATA data, key;
1361 TDB_DATA jcdata;
1362 fstring keystr, cachestr;
1363 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1364 TALLOC_CTX *tmp_ctx = talloc_new(ev);
1366 if ((pdb == NULL) || (tmp_ctx == NULL)) {
1367 return;
1370 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1371 sharename, current_printif->type, lpq_command));
1374 * Update the cache time FIRST ! Stops others even
1375 * attempting to get the lock and doing this
1376 * if the lpq takes a long time.
1379 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1380 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1382 /* get the current queue using the appropriate interface */
1383 ZERO_STRUCT(status);
1385 qcount = (*(current_printif->queue_get))(sharename,
1386 current_printif->type,
1387 lpq_command, &queue, &status);
1389 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1390 qcount, (qcount != 1) ? "s" : "", sharename));
1392 /* Sort the queue by submission time otherwise they are displayed
1393 in hash order. */
1395 TYPESAFE_QSORT(queue, qcount, printjob_comp);
1398 any job in the internal database that is marked as spooled
1399 and doesn't exist in the system queue is considered finished
1400 and removed from the database
1402 any job in the system database but not in the internal database
1403 is added as a unix job
1405 fill in any system job numbers as we go
1407 jcdata = get_jobs_added_data(pdb);
1409 for (i=0; i<qcount; i++) {
1410 uint32 jobid = sysjob_to_jobid_pdb(pdb, queue[i].sysjob);
1411 if (jobid == (uint32)-1) {
1412 /* assume its a unix print job */
1413 print_unix_job(ev, msg_ctx,
1414 sharename, &queue[i], jobid);
1415 continue;
1418 /* we have an active SMB print job - update its status */
1419 pjob = print_job_find(tmp_ctx, sharename, jobid);
1420 if (!pjob) {
1421 /* err, somethings wrong. Probably smbd was restarted
1422 with jobs in the queue. All we can do is treat them
1423 like unix jobs. Pity. */
1424 DEBUG(1, ("queued print job %d not found in jobs list, "
1425 "assuming unix job\n", jobid));
1426 print_unix_job(ev, msg_ctx,
1427 sharename, &queue[i], jobid);
1428 continue;
1431 /* don't reset the status on jobs to be deleted */
1433 if ( pjob->status != LPQ_DELETING )
1434 pjob->status = queue[i].status;
1436 pjob_store(ev, msg_ctx, sharename, jobid, pjob);
1438 check_job_added(sharename, jcdata, jobid);
1441 SAFE_FREE(jcdata.dptr);
1443 /* now delete any queued entries that don't appear in the
1444 system queue */
1445 tstruct.queue = queue;
1446 tstruct.qcount = qcount;
1447 tstruct.snum = -1;
1448 tstruct.total_jobs = 0;
1449 tstruct.lpq_time = time(NULL);
1450 tstruct.sharename = sharename;
1451 tstruct.lprm_command = lprm_command;
1452 tstruct.print_if = current_printif;
1453 tstruct.ev = ev;
1454 tstruct.msg_ctx = msg_ctx;
1455 tstruct.mem_ctx = tmp_ctx;
1457 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1459 /* Store the linearised queue, max jobs only. */
1460 store_queue_struct(pdb, &tstruct);
1462 SAFE_FREE(tstruct.queue);
1463 talloc_free(tmp_ctx);
1465 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1466 sharename, tstruct.total_jobs ));
1468 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1470 get_queue_status(sharename, &old_status);
1471 if (old_status.qcount != qcount)
1472 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1473 old_status.qcount, qcount, sharename));
1475 /* store the new queue status structure */
1476 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1477 key = string_tdb_data(keystr);
1479 status.qcount = qcount;
1480 data.dptr = (uint8 *)&status;
1481 data.dsize = sizeof(status);
1482 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1485 * Update the cache time again. We want to do this call
1486 * as little as possible...
1489 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1490 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1492 /* clear the msg pending record for this queue */
1494 snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1496 if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1497 /* log a message but continue on */
1499 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1500 sharename));
1503 release_print_db( pdb );
1505 return;
1508 /****************************************************************************
1509 Update the internal database from the system print queue for a queue.
1510 obtain a lock on the print queue before proceeding (needed when mutiple
1511 smbd processes maytry to update the lpq cache concurrently).
1512 ****************************************************************************/
1514 static void print_queue_update_with_lock( struct tevent_context *ev,
1515 struct messaging_context *msg_ctx,
1516 const char *sharename,
1517 struct printif *current_printif,
1518 char *lpq_command, char *lprm_command )
1520 fstring keystr;
1521 struct tdb_print_db *pdb;
1523 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1524 pdb = get_print_db_byname(sharename);
1525 if (!pdb)
1526 return;
1528 if ( !print_cache_expired(sharename, False) ) {
1529 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1530 release_print_db(pdb);
1531 return;
1535 * Check to see if someone else is doing this update.
1536 * This is essentially a mutex on the update.
1539 if (get_updating_pid(sharename) != -1) {
1540 release_print_db(pdb);
1541 return;
1544 /* Lock the queue for the database update */
1546 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1547 /* Only wait 10 seconds for this. */
1548 if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
1549 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1550 release_print_db(pdb);
1551 return;
1555 * Ensure that no one else got in here.
1556 * If the updating pid is still -1 then we are
1557 * the winner.
1560 if (get_updating_pid(sharename) != -1) {
1562 * Someone else is doing the update, exit.
1564 tdb_unlock_bystring(pdb->tdb, keystr);
1565 release_print_db(pdb);
1566 return;
1570 * We're going to do the update ourselves.
1573 /* Tell others we're doing the update. */
1574 set_updating_pid(sharename, True);
1577 * Allow others to enter and notice we're doing
1578 * the update.
1581 tdb_unlock_bystring(pdb->tdb, keystr);
1583 /* do the main work now */
1585 print_queue_update_internal(ev, msg_ctx,
1586 sharename, current_printif,
1587 lpq_command, lprm_command);
1589 /* Delete our pid from the db. */
1590 set_updating_pid(sharename, False);
1591 release_print_db(pdb);
1594 /****************************************************************************
1595 this is the receive function of the background lpq updater
1596 ****************************************************************************/
1597 void print_queue_receive(struct messaging_context *msg,
1598 void *private_data,
1599 uint32_t msg_type,
1600 struct server_id server_id,
1601 DATA_BLOB *data)
1603 fstring sharename;
1604 char *lpqcommand = NULL, *lprmcommand = NULL;
1605 int printing_type;
1606 size_t len;
1608 len = tdb_unpack( (uint8 *)data->data, data->length, "fdPP",
1609 sharename,
1610 &printing_type,
1611 &lpqcommand,
1612 &lprmcommand );
1614 if ( len == -1 ) {
1615 SAFE_FREE(lpqcommand);
1616 SAFE_FREE(lprmcommand);
1617 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1618 return;
1621 print_queue_update_with_lock(server_event_context(), msg, sharename,
1622 get_printer_fns_from_type((enum printing_types)printing_type),
1623 lpqcommand, lprmcommand );
1625 SAFE_FREE(lpqcommand);
1626 SAFE_FREE(lprmcommand);
1627 return;
1630 static void printing_pause_fd_handler(struct tevent_context *ev,
1631 struct tevent_fd *fde,
1632 uint16_t flags,
1633 void *private_data)
1636 * If pause_pipe[1] is closed it means the parent smbd
1637 * and children exited or aborted.
1639 exit_server_cleanly(NULL);
1642 extern struct child_pid *children;
1643 extern int num_children;
1645 static void add_child_pid(pid_t pid)
1647 struct child_pid *child;
1649 child = SMB_MALLOC_P(struct child_pid);
1650 if (child == NULL) {
1651 DEBUG(0, ("Could not add child struct -- malloc failed\n"));
1652 return;
1654 child->pid = pid;
1655 DLIST_ADD(children, child);
1656 num_children += 1;
1659 /****************************************************************************
1660 Notify smbds of new printcap data
1661 **************************************************************************/
1662 static void reload_pcap_change_notify(struct tevent_context *ev,
1663 struct messaging_context *msg_ctx)
1666 * Reload the printers first in the background process so that
1667 * newly added printers get default values created in the registry.
1669 * This will block the process for some time (~1 sec per printer), but
1670 * it doesn't block smbd's servering clients.
1672 reload_printers_full(ev, msg_ctx);
1674 message_send_all(msg_ctx, MSG_PRINTER_PCAP, NULL, 0, NULL);
1677 static bool printer_housekeeping_fn(const struct timeval *now,
1678 void *private_data)
1680 static time_t last_pcap_reload_time = 0;
1681 time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
1682 time_t t = time_mono(NULL);
1684 DEBUG(5, ("printer housekeeping\n"));
1686 /* if periodic printcap rescan is enabled, see if it's time to reload */
1687 if ((printcap_cache_time != 0)
1688 && (t >= (last_pcap_reload_time + printcap_cache_time))) {
1689 DEBUG( 3,( "Printcap cache time expired.\n"));
1690 pcap_cache_reload(server_event_context(),
1691 smbd_messaging_context(),
1692 &reload_pcap_change_notify);
1693 last_pcap_reload_time = t;
1696 return true;
1699 static void printing_sig_term_handler(struct tevent_context *ev,
1700 struct tevent_signal *se,
1701 int signum,
1702 int count,
1703 void *siginfo,
1704 void *private_data)
1706 exit_server_cleanly("termination signal");
1709 static void printing_sig_hup_handler(struct tevent_context *ev,
1710 struct tevent_signal *se,
1711 int signum,
1712 int count,
1713 void *siginfo,
1714 void *private_data)
1716 struct messaging_context *msg_ctx = talloc_get_type_abort(
1717 private_data, struct messaging_context);
1719 DEBUG(1,("Reloading printers after SIGHUP\n"));
1720 pcap_cache_reload(ev, msg_ctx,
1721 &reload_pcap_change_notify);
1724 static void printing_conf_updated(struct messaging_context *msg,
1725 void *private_data,
1726 uint32_t msg_type,
1727 struct server_id server_id,
1728 DATA_BLOB *data)
1730 DEBUG(5,("Reloading printers after conf change\n"));
1731 pcap_cache_reload(messaging_event_context(msg), msg,
1732 &reload_pcap_change_notify);
1736 static pid_t background_lpq_updater_pid = -1;
1738 /****************************************************************************
1739 main thread of the background lpq updater
1740 ****************************************************************************/
1741 void start_background_queue(struct tevent_context *ev,
1742 struct messaging_context *msg_ctx)
1744 /* Use local variables for this as we don't
1745 * need to save the parent side of this, just
1746 * ensure it closes when the process exits.
1748 int pause_pipe[2];
1750 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1752 if (pipe(pause_pipe) == -1) {
1753 DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno) ));
1754 exit(1);
1757 background_lpq_updater_pid = sys_fork();
1759 if (background_lpq_updater_pid == -1) {
1760 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1761 exit(1);
1764 /* Track the printing pid along with other smbd children */
1765 add_child_pid(background_lpq_updater_pid);
1767 if(background_lpq_updater_pid == 0) {
1768 struct tevent_fd *fde;
1769 int ret;
1770 NTSTATUS status;
1771 struct tevent_signal *se;
1773 /* Child. */
1774 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1776 close(pause_pipe[0]);
1777 pause_pipe[0] = -1;
1779 status = reinit_after_fork(msg_ctx, ev, procid_self(), true);
1781 if (!NT_STATUS_IS_OK(status)) {
1782 DEBUG(0,("reinit_after_fork() failed\n"));
1783 smb_panic("reinit_after_fork() failed");
1786 se = tevent_add_signal(ev, ev, SIGTERM, 0,
1787 printing_sig_term_handler,
1788 NULL);
1789 if (se == NULL) {
1790 smb_panic("failed to setup SIGTERM handler");
1792 se = tevent_add_signal(ev, ev, SIGHUP, 0,
1793 printing_sig_hup_handler,
1794 msg_ctx);
1795 if (se == NULL) {
1796 smb_panic("failed to setup SIGHUP handler");
1799 if (!serverid_register(procid_self(),
1800 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
1801 |FLAG_MSG_PRINT_GENERAL)) {
1802 exit(1);
1805 if (!locking_init()) {
1806 exit(1);
1809 messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE,
1810 print_queue_receive);
1811 messaging_register(msg_ctx, NULL, MSG_SMB_CONF_UPDATED,
1812 printing_conf_updated);
1814 fde = tevent_add_fd(ev, ev, pause_pipe[1], TEVENT_FD_READ,
1815 printing_pause_fd_handler,
1816 NULL);
1817 if (!fde) {
1818 DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
1819 smb_panic("tevent_add_fd() failed for pause_pipe");
1822 /* reload on startup to ensure parent smbd is refreshed */
1823 pcap_cache_reload(server_event_context(),
1824 smbd_messaging_context(),
1825 &reload_pcap_change_notify);
1827 if (!(event_add_idle(ev, NULL,
1828 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
1829 "printer_housekeeping",
1830 printer_housekeeping_fn,
1831 NULL))) {
1832 DEBUG(0, ("Could not add printing housekeeping event\n"));
1833 exit(1);
1836 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1837 ret = tevent_loop_wait(ev);
1838 /* should not be reached */
1839 DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
1840 ret, (ret == 0) ? "out of events" : strerror(errno)));
1841 exit(1);
1844 close(pause_pipe[1]);
1847 /****************************************************************************
1848 update the internal database from the system print queue for a queue
1849 ****************************************************************************/
1851 static void print_queue_update(struct messaging_context *msg_ctx,
1852 int snum, bool force)
1854 fstring key;
1855 fstring sharename;
1856 char *lpqcommand = NULL;
1857 char *lprmcommand = NULL;
1858 uint8 *buffer = NULL;
1859 size_t len = 0;
1860 size_t newlen;
1861 struct tdb_print_db *pdb;
1862 int type;
1863 struct printif *current_printif;
1864 TALLOC_CTX *ctx = talloc_tos();
1866 fstrcpy( sharename, lp_const_servicename(snum));
1868 /* don't strip out characters like '$' from the printername */
1870 lpqcommand = talloc_string_sub2(ctx,
1871 lp_lpqcommand(snum),
1872 "%p",
1873 lp_printername(snum),
1874 false, false, false);
1875 if (!lpqcommand) {
1876 return;
1878 lpqcommand = talloc_sub_advanced(ctx,
1879 lp_servicename(snum),
1880 current_user_info.unix_name,
1882 current_user.ut.gid,
1883 get_current_username(),
1884 current_user_info.domain,
1885 lpqcommand);
1886 if (!lpqcommand) {
1887 return;
1890 lprmcommand = talloc_string_sub2(ctx,
1891 lp_lprmcommand(snum),
1892 "%p",
1893 lp_printername(snum),
1894 false, false, false);
1895 if (!lprmcommand) {
1896 return;
1898 lprmcommand = talloc_sub_advanced(ctx,
1899 lp_servicename(snum),
1900 current_user_info.unix_name,
1902 current_user.ut.gid,
1903 get_current_username(),
1904 current_user_info.domain,
1905 lprmcommand);
1906 if (!lprmcommand) {
1907 return;
1911 * Make sure that the background queue process exists.
1912 * Otherwise just do the update ourselves
1915 if ( force || background_lpq_updater_pid == -1 ) {
1916 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1917 current_printif = get_printer_fns( snum );
1918 print_queue_update_with_lock(server_event_context(), msg_ctx,
1919 sharename, current_printif,
1920 lpqcommand, lprmcommand);
1922 return;
1925 type = lp_printing(snum);
1927 /* get the length */
1929 len = tdb_pack( NULL, 0, "fdPP",
1930 sharename,
1931 type,
1932 lpqcommand,
1933 lprmcommand );
1935 buffer = SMB_XMALLOC_ARRAY( uint8, len );
1937 /* now pack the buffer */
1938 newlen = tdb_pack( buffer, len, "fdPP",
1939 sharename,
1940 type,
1941 lpqcommand,
1942 lprmcommand );
1944 SMB_ASSERT( newlen == len );
1946 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1947 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1948 sharename, type, lpqcommand, lprmcommand ));
1950 /* here we set a msg pending record for other smbd processes
1951 to throttle the number of duplicate print_queue_update msgs
1952 sent. */
1954 pdb = get_print_db_byname(sharename);
1955 if (!pdb) {
1956 SAFE_FREE(buffer);
1957 return;
1960 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1962 if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1963 /* log a message but continue on */
1965 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1966 sharename));
1969 release_print_db( pdb );
1971 /* finally send the message */
1973 messaging_send_buf(msg_ctx, pid_to_procid(background_lpq_updater_pid),
1974 MSG_PRINTER_UPDATE, (uint8 *)buffer, len);
1976 SAFE_FREE( buffer );
1978 return;
1981 /****************************************************************************
1982 Create/Update an entry in the print tdb that will allow us to send notify
1983 updates only to interested smbd's.
1984 ****************************************************************************/
1986 bool print_notify_register_pid(int snum)
1988 TDB_DATA data;
1989 struct tdb_print_db *pdb = NULL;
1990 TDB_CONTEXT *tdb = NULL;
1991 const char *printername;
1992 uint32 mypid = (uint32)sys_getpid();
1993 bool ret = False;
1994 size_t i;
1996 /* if (snum == -1), then the change notify request was
1997 on a print server handle and we need to register on
1998 all print queus */
2000 if (snum == -1)
2002 int num_services = lp_numservices();
2003 int idx;
2005 for ( idx=0; idx<num_services; idx++ ) {
2006 if (lp_snum_ok(idx) && lp_print_ok(idx) )
2007 print_notify_register_pid(idx);
2010 return True;
2012 else /* register for a specific printer */
2014 printername = lp_const_servicename(snum);
2015 pdb = get_print_db_byname(printername);
2016 if (!pdb)
2017 return False;
2018 tdb = pdb->tdb;
2021 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
2022 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
2023 printername));
2024 if (pdb)
2025 release_print_db(pdb);
2026 return False;
2029 data = get_printer_notify_pid_list( tdb, printername, True );
2031 /* Add ourselves and increase the refcount. */
2033 for (i = 0; i < data.dsize; i += 8) {
2034 if (IVAL(data.dptr,i) == mypid) {
2035 uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
2036 SIVAL(data.dptr, i+4, new_refcount);
2037 break;
2041 if (i == data.dsize) {
2042 /* We weren't in the list. Realloc. */
2043 data.dptr = (uint8 *)SMB_REALLOC(data.dptr, data.dsize + 8);
2044 if (!data.dptr) {
2045 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
2046 printername));
2047 goto done;
2049 data.dsize += 8;
2050 SIVAL(data.dptr,data.dsize - 8,mypid);
2051 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
2054 /* Store back the record. */
2055 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
2056 DEBUG(0,("print_notify_register_pid: Failed to update pid \
2057 list for printer %s\n", printername));
2058 goto done;
2061 ret = True;
2063 done:
2065 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
2066 if (pdb)
2067 release_print_db(pdb);
2068 SAFE_FREE(data.dptr);
2069 return ret;
2072 /****************************************************************************
2073 Update an entry in the print tdb that will allow us to send notify
2074 updates only to interested smbd's.
2075 ****************************************************************************/
2077 bool print_notify_deregister_pid(int snum)
2079 TDB_DATA data;
2080 struct tdb_print_db *pdb = NULL;
2081 TDB_CONTEXT *tdb = NULL;
2082 const char *printername;
2083 uint32 mypid = (uint32)sys_getpid();
2084 size_t i;
2085 bool ret = False;
2087 /* if ( snum == -1 ), we are deregister a print server handle
2088 which means to deregister on all print queues */
2090 if (snum == -1)
2092 int num_services = lp_numservices();
2093 int idx;
2095 for ( idx=0; idx<num_services; idx++ ) {
2096 if ( lp_snum_ok(idx) && lp_print_ok(idx) )
2097 print_notify_deregister_pid(idx);
2100 return True;
2102 else /* deregister a specific printer */
2104 printername = lp_const_servicename(snum);
2105 pdb = get_print_db_byname(printername);
2106 if (!pdb)
2107 return False;
2108 tdb = pdb->tdb;
2111 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
2112 DEBUG(0,("print_notify_register_pid: Failed to lock \
2113 printer %s database\n", printername));
2114 if (pdb)
2115 release_print_db(pdb);
2116 return False;
2119 data = get_printer_notify_pid_list( tdb, printername, True );
2121 /* Reduce refcount. Remove ourselves if zero. */
2123 for (i = 0; i < data.dsize; ) {
2124 if (IVAL(data.dptr,i) == mypid) {
2125 uint32 refcount = IVAL(data.dptr, i+4);
2127 refcount--;
2129 if (refcount == 0) {
2130 if (data.dsize - i > 8)
2131 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
2132 data.dsize -= 8;
2133 continue;
2135 SIVAL(data.dptr, i+4, refcount);
2138 i += 8;
2141 if (data.dsize == 0)
2142 SAFE_FREE(data.dptr);
2144 /* Store back the record. */
2145 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
2146 DEBUG(0,("print_notify_register_pid: Failed to update pid \
2147 list for printer %s\n", printername));
2148 goto done;
2151 ret = True;
2153 done:
2155 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
2156 if (pdb)
2157 release_print_db(pdb);
2158 SAFE_FREE(data.dptr);
2159 return ret;
2162 /****************************************************************************
2163 Check if a jobid is valid. It is valid if it exists in the database.
2164 ****************************************************************************/
2166 bool print_job_exists(const char* sharename, uint32 jobid)
2168 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2169 bool ret;
2170 uint32_t tmp;
2172 if (!pdb)
2173 return False;
2174 ret = tdb_exists(pdb->tdb, print_key(jobid, &tmp));
2175 release_print_db(pdb);
2176 return ret;
2179 /****************************************************************************
2180 Return the device mode asigned to a specific print job.
2181 Only valid for the process doing the spooling and when the job
2182 has not been spooled.
2183 ****************************************************************************/
2185 struct spoolss_DeviceMode *print_job_devmode(TALLOC_CTX *mem_ctx,
2186 const char *sharename,
2187 uint32 jobid)
2189 struct printjob *pjob = print_job_find(mem_ctx, sharename, jobid);
2190 if (pjob == NULL) {
2191 return NULL;
2194 return pjob->devmode;
2197 /****************************************************************************
2198 Set the name of a job. Only possible for owner.
2199 ****************************************************************************/
2201 bool print_job_set_name(struct tevent_context *ev,
2202 struct messaging_context *msg_ctx,
2203 const char *sharename, uint32 jobid, const char *name)
2205 struct printjob *pjob;
2206 bool ret;
2207 TALLOC_CTX *tmp_ctx = talloc_new(ev);
2208 if (tmp_ctx == NULL) {
2209 return false;
2212 pjob = print_job_find(tmp_ctx, sharename, jobid);
2213 if (!pjob || pjob->pid != sys_getpid()) {
2214 ret = false;
2215 goto err_out;
2218 fstrcpy(pjob->jobname, name);
2219 ret = pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2220 err_out:
2221 talloc_free(tmp_ctx);
2222 return ret;
2225 /****************************************************************************
2226 Get the name of a job. Only possible for owner.
2227 ****************************************************************************/
2229 bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t jobid, char **name)
2231 struct printjob *pjob;
2233 pjob = print_job_find(mem_ctx, sharename, jobid);
2234 if (!pjob || pjob->pid != sys_getpid()) {
2235 return false;
2238 *name = pjob->jobname;
2239 return true;
2243 /***************************************************************************
2244 Remove a jobid from the 'jobs added' list.
2245 ***************************************************************************/
2247 static bool remove_from_jobs_added(const char* sharename, uint32 jobid)
2249 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2250 TDB_DATA data, key;
2251 size_t job_count, i;
2252 bool ret = False;
2253 bool gotlock = False;
2255 if (!pdb) {
2256 return False;
2259 ZERO_STRUCT(data);
2261 key = string_tdb_data("INFO/jobs_added");
2263 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
2264 goto out;
2266 gotlock = True;
2268 data = tdb_fetch(pdb->tdb, key);
2270 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
2271 goto out;
2273 job_count = data.dsize / 4;
2274 for (i = 0; i < job_count; i++) {
2275 uint32 ch_jobid;
2277 ch_jobid = IVAL(data.dptr, i*4);
2278 if (ch_jobid == jobid) {
2279 if (i < job_count -1 )
2280 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
2281 data.dsize -= 4;
2282 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
2283 goto out;
2284 break;
2288 ret = True;
2289 out:
2291 if (gotlock)
2292 tdb_chainunlock(pdb->tdb, key);
2293 SAFE_FREE(data.dptr);
2294 release_print_db(pdb);
2295 if (ret)
2296 DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid ));
2297 else
2298 DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid ));
2299 return ret;
2302 /****************************************************************************
2303 Delete a print job - don't update queue.
2304 ****************************************************************************/
2306 static bool print_job_delete1(struct tevent_context *ev,
2307 struct messaging_context *msg_ctx,
2308 int snum, uint32 jobid)
2310 const char* sharename = lp_const_servicename(snum);
2311 struct printjob *pjob;
2312 int result = 0;
2313 struct printif *current_printif = get_printer_fns( snum );
2314 bool ret;
2315 TALLOC_CTX *tmp_ctx = talloc_new(ev);
2316 if (tmp_ctx == NULL) {
2317 return false;
2320 pjob = print_job_find(tmp_ctx, sharename, jobid);
2321 if (!pjob) {
2322 ret = false;
2323 goto err_out;
2327 * If already deleting just return.
2330 if (pjob->status == LPQ_DELETING) {
2331 ret = true;
2332 goto err_out;
2335 /* Hrm - we need to be able to cope with deleting a job before it
2336 has reached the spooler. Just mark it as LPQ_DELETING and
2337 let the print_queue_update() code rmeove the record */
2340 if (pjob->sysjob == -1) {
2341 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
2344 /* Set the tdb entry to be deleting. */
2346 pjob->status = LPQ_DELETING;
2347 pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2349 if (pjob->spooled && pjob->sysjob != -1)
2351 result = (*(current_printif->job_delete))(
2352 lp_printername(snum),
2353 lp_lprmcommand(snum),
2354 pjob);
2356 /* Delete the tdb entry if the delete succeeded or the job hasn't
2357 been spooled. */
2359 if (result == 0) {
2360 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2361 int njobs = 1;
2363 if (!pdb) {
2364 ret = false;
2365 goto err_out;
2367 pjob_delete(ev, msg_ctx, sharename, jobid);
2368 /* Ensure we keep a rough count of the number of total jobs... */
2369 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
2370 release_print_db(pdb);
2374 remove_from_jobs_added( sharename, jobid );
2376 ret = (result == 0);
2377 err_out:
2378 talloc_free(tmp_ctx);
2379 return ret;
2382 /****************************************************************************
2383 Return true if the current user owns the print job.
2384 ****************************************************************************/
2386 static bool is_owner(const struct auth_serversupplied_info *server_info,
2387 const char *servicename,
2388 uint32 jobid)
2390 struct printjob *pjob;
2391 bool ret;
2392 TALLOC_CTX *tmp_ctx = talloc_new(server_info);
2393 if (tmp_ctx == NULL) {
2394 return false;
2397 pjob = print_job_find(tmp_ctx, servicename, jobid);
2398 if (!pjob || !server_info) {
2399 ret = false;
2400 goto err_out;
2403 ret = strequal(pjob->user, server_info->sanitized_username);
2404 err_out:
2405 talloc_free(tmp_ctx);
2406 return ret;
2409 /****************************************************************************
2410 Delete a print job.
2411 ****************************************************************************/
2413 WERROR print_job_delete(const struct auth_serversupplied_info *server_info,
2414 struct messaging_context *msg_ctx,
2415 int snum, uint32_t jobid)
2417 const char* sharename = lp_const_servicename(snum);
2418 struct printjob *pjob;
2419 bool owner;
2420 WERROR werr;
2421 TALLOC_CTX *tmp_ctx = talloc_new(msg_ctx);
2422 if (tmp_ctx == NULL) {
2423 return WERR_NOT_ENOUGH_MEMORY;
2426 owner = is_owner(server_info, lp_const_servicename(snum), jobid);
2428 /* Check access against security descriptor or whether the user
2429 owns their job. */
2431 if (!owner &&
2432 !print_access_check(server_info, msg_ctx, snum,
2433 JOB_ACCESS_ADMINISTER)) {
2434 DEBUG(3, ("delete denied by security descriptor\n"));
2436 /* BEGIN_ADMIN_LOG */
2437 sys_adminlog( LOG_ERR,
2438 "Permission denied-- user not allowed to delete, \
2439 pause, or resume print job. User name: %s. Printer name: %s.",
2440 uidtoname(server_info->utok.uid),
2441 lp_printername(snum) );
2442 /* END_ADMIN_LOG */
2444 werr = WERR_ACCESS_DENIED;
2445 goto err_out;
2449 * get the spooled filename of the print job
2450 * if this works, then the file has not been spooled
2451 * to the underlying print system. Just delete the
2452 * spool file & return.
2455 pjob = print_job_find(tmp_ctx, sharename, jobid);
2456 if (!pjob || pjob->spooled || pjob->pid != getpid()) {
2457 DEBUG(10, ("Skipping spool file removal for job %u\n", jobid));
2458 } else {
2459 DEBUG(10, ("Removing spool file [%s]\n", pjob->filename));
2460 if (unlink(pjob->filename) == -1) {
2461 werr = map_werror_from_unix(errno);
2462 goto err_out;
2466 if (!print_job_delete1(server_event_context(), msg_ctx, snum, jobid)) {
2467 werr = WERR_ACCESS_DENIED;
2468 goto err_out;
2471 /* force update the database and say the delete failed if the
2472 job still exists */
2474 print_queue_update(msg_ctx, snum, True);
2476 pjob = print_job_find(tmp_ctx, sharename, jobid);
2477 if (pjob && (pjob->status != LPQ_DELETING)) {
2478 werr = WERR_ACCESS_DENIED;
2479 goto err_out;
2481 werr = WERR_PRINTER_HAS_JOBS_QUEUED;
2483 err_out:
2484 talloc_free(tmp_ctx);
2485 return werr;
2488 /****************************************************************************
2489 Pause a job.
2490 ****************************************************************************/
2492 WERROR print_job_pause(const struct auth_serversupplied_info *server_info,
2493 struct messaging_context *msg_ctx,
2494 int snum, uint32 jobid)
2496 const char* sharename = lp_const_servicename(snum);
2497 struct printjob *pjob;
2498 int ret = -1;
2499 struct printif *current_printif = get_printer_fns( snum );
2500 WERROR werr;
2501 TALLOC_CTX *tmp_ctx = talloc_new(msg_ctx);
2502 if (tmp_ctx == NULL) {
2503 return WERR_NOT_ENOUGH_MEMORY;
2506 pjob = print_job_find(tmp_ctx, sharename, jobid);
2507 if (!pjob || !server_info) {
2508 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2509 (unsigned int)jobid ));
2510 werr = WERR_INVALID_PARAM;
2511 goto err_out;
2514 if (!pjob->spooled || pjob->sysjob == -1) {
2515 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2516 (int)pjob->sysjob, (unsigned int)jobid ));
2517 werr = WERR_INVALID_PARAM;
2518 goto err_out;
2521 if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2522 !print_access_check(server_info, msg_ctx, snum,
2523 JOB_ACCESS_ADMINISTER)) {
2524 DEBUG(3, ("pause denied by security descriptor\n"));
2526 /* BEGIN_ADMIN_LOG */
2527 sys_adminlog( LOG_ERR,
2528 "Permission denied-- user not allowed to delete, \
2529 pause, or resume print job. User name: %s. Printer name: %s.",
2530 uidtoname(server_info->utok.uid),
2531 lp_printername(snum) );
2532 /* END_ADMIN_LOG */
2534 werr = WERR_ACCESS_DENIED;
2535 goto err_out;
2538 /* need to pause the spooled entry */
2539 ret = (*(current_printif->job_pause))(snum, pjob);
2541 if (ret != 0) {
2542 werr = WERR_INVALID_PARAM;
2543 goto err_out;
2546 /* force update the database */
2547 print_cache_flush(lp_const_servicename(snum));
2549 /* Send a printer notify message */
2551 notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2552 JOB_STATUS_PAUSED);
2554 /* how do we tell if this succeeded? */
2555 werr = WERR_OK;
2556 err_out:
2557 talloc_free(tmp_ctx);
2558 return werr;
2561 /****************************************************************************
2562 Resume a job.
2563 ****************************************************************************/
2565 WERROR print_job_resume(const struct auth_serversupplied_info *server_info,
2566 struct messaging_context *msg_ctx,
2567 int snum, uint32 jobid)
2569 const char *sharename = lp_const_servicename(snum);
2570 struct printjob *pjob;
2571 int ret;
2572 struct printif *current_printif = get_printer_fns( snum );
2573 WERROR werr;
2574 TALLOC_CTX *tmp_ctx = talloc_new(msg_ctx);
2575 if (tmp_ctx == NULL)
2576 return WERR_NOT_ENOUGH_MEMORY;
2578 pjob = print_job_find(tmp_ctx, sharename, jobid);
2579 if (!pjob || !server_info) {
2580 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2581 (unsigned int)jobid ));
2582 werr = WERR_INVALID_PARAM;
2583 goto err_out;
2586 if (!pjob->spooled || pjob->sysjob == -1) {
2587 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2588 (int)pjob->sysjob, (unsigned int)jobid ));
2589 werr = WERR_INVALID_PARAM;
2590 goto err_out;
2593 if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2594 !print_access_check(server_info, msg_ctx, snum,
2595 JOB_ACCESS_ADMINISTER)) {
2596 DEBUG(3, ("resume denied by security descriptor\n"));
2598 /* BEGIN_ADMIN_LOG */
2599 sys_adminlog( LOG_ERR,
2600 "Permission denied-- user not allowed to delete, \
2601 pause, or resume print job. User name: %s. Printer name: %s.",
2602 uidtoname(server_info->utok.uid),
2603 lp_printername(snum) );
2604 /* END_ADMIN_LOG */
2605 werr = WERR_ACCESS_DENIED;
2606 goto err_out;
2609 ret = (*(current_printif->job_resume))(snum, pjob);
2611 if (ret != 0) {
2612 werr = WERR_INVALID_PARAM;
2613 goto err_out;
2616 /* force update the database */
2617 print_cache_flush(lp_const_servicename(snum));
2619 /* Send a printer notify message */
2621 notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2622 JOB_STATUS_QUEUED);
2624 werr = WERR_OK;
2625 err_out:
2626 talloc_free(tmp_ctx);
2627 return werr;
2630 /****************************************************************************
2631 Write to a print file.
2632 ****************************************************************************/
2634 ssize_t print_job_write(struct tevent_context *ev,
2635 struct messaging_context *msg_ctx,
2636 int snum, uint32 jobid, const char *buf, size_t size)
2638 const char* sharename = lp_const_servicename(snum);
2639 ssize_t return_code;
2640 struct printjob *pjob;
2641 TALLOC_CTX *tmp_ctx = talloc_new(ev);
2642 if (tmp_ctx == NULL) {
2643 return -1;
2646 pjob = print_job_find(tmp_ctx, sharename, jobid);
2647 if (!pjob) {
2648 return_code = -1;
2649 goto err_out;
2652 /* don't allow another process to get this info - it is meaningless */
2653 if (pjob->pid != sys_getpid()) {
2654 return_code = -1;
2655 goto err_out;
2658 /* if SMBD is spooling this can't be allowed */
2659 if (pjob->status == PJOB_SMBD_SPOOLING) {
2660 return_code = -1;
2661 goto err_out;
2664 return_code = write_data(pjob->fd, buf, size);
2665 if (return_code > 0) {
2666 pjob->size += size;
2667 pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2669 err_out:
2670 talloc_free(tmp_ctx);
2671 return return_code;
2674 /****************************************************************************
2675 Get the queue status - do not update if db is out of date.
2676 ****************************************************************************/
2678 static int get_queue_status(const char* sharename, print_status_struct *status)
2680 fstring keystr;
2681 TDB_DATA data;
2682 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2683 int len;
2685 if (status) {
2686 ZERO_STRUCTP(status);
2689 if (!pdb)
2690 return 0;
2692 if (status) {
2693 fstr_sprintf(keystr, "STATUS/%s", sharename);
2694 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2695 if (data.dptr) {
2696 if (data.dsize == sizeof(print_status_struct))
2697 /* this memcpy is ok since the status struct was
2698 not packed before storing it in the tdb */
2699 memcpy(status, data.dptr, sizeof(print_status_struct));
2700 SAFE_FREE(data.dptr);
2703 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2704 release_print_db(pdb);
2705 return (len == -1 ? 0 : len);
2708 /****************************************************************************
2709 Determine the number of jobs in a queue.
2710 ****************************************************************************/
2712 int print_queue_length(struct messaging_context *msg_ctx, int snum,
2713 print_status_struct *pstatus)
2715 const char* sharename = lp_const_servicename( snum );
2716 print_status_struct status;
2717 int len;
2719 ZERO_STRUCT( status );
2721 /* make sure the database is up to date */
2722 if (print_cache_expired(lp_const_servicename(snum), True))
2723 print_queue_update(msg_ctx, snum, False);
2725 /* also fetch the queue status */
2726 memset(&status, 0, sizeof(status));
2727 len = get_queue_status(sharename, &status);
2729 if (pstatus)
2730 *pstatus = status;
2732 return len;
2735 /***************************************************************************
2736 Allocate a jobid. Hold the lock for as short a time as possible.
2737 ***************************************************************************/
2739 static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum,
2740 const char *sharename, uint32 *pjobid)
2742 int i;
2743 uint32 jobid;
2744 enum TDB_ERROR terr;
2745 int ret;
2747 *pjobid = (uint32)-1;
2749 for (i = 0; i < 3; i++) {
2750 /* Lock the database - only wait 20 seconds. */
2751 ret = tdb_lock_bystring_with_timeout(pdb->tdb,
2752 "INFO/nextjob", 20);
2753 if (ret == -1) {
2754 DEBUG(0, ("allocate_print_jobid: "
2755 "Failed to lock printing database %s\n",
2756 sharename));
2757 terr = tdb_error(pdb->tdb);
2758 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2761 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2762 terr = tdb_error(pdb->tdb);
2763 if (terr != TDB_ERR_NOEXIST) {
2764 DEBUG(0, ("allocate_print_jobid: "
2765 "Failed to fetch INFO/nextjob "
2766 "for print queue %s\n", sharename));
2767 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2768 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2770 DEBUG(10, ("allocate_print_jobid: "
2771 "No existing jobid in %s\n", sharename));
2772 jobid = 0;
2775 DEBUG(10, ("allocate_print_jobid: "
2776 "Read jobid %u from %s\n", jobid, sharename));
2778 jobid = NEXT_JOBID(jobid);
2780 ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid);
2781 if (ret == -1) {
2782 terr = tdb_error(pdb->tdb);
2783 DEBUG(3, ("allocate_print_jobid: "
2784 "Failed to store INFO/nextjob.\n"));
2785 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2786 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2789 /* We've finished with the INFO/nextjob lock. */
2790 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2792 if (!print_job_exists(sharename, jobid)) {
2793 break;
2795 DEBUG(10, ("allocate_print_jobid: "
2796 "Found jobid %u in %s\n", jobid, sharename));
2799 if (i > 2) {
2800 DEBUG(0, ("allocate_print_jobid: "
2801 "Failed to allocate a print job for queue %s\n",
2802 sharename));
2803 /* Probably full... */
2804 return WERR_NO_SPOOL_SPACE;
2807 /* Store a dummy placeholder. */
2809 uint32_t tmp;
2810 TDB_DATA dum;
2811 dum.dptr = NULL;
2812 dum.dsize = 0;
2813 if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
2814 TDB_INSERT) == -1) {
2815 DEBUG(3, ("allocate_print_jobid: "
2816 "jobid (%d) failed to store placeholder.\n",
2817 jobid ));
2818 terr = tdb_error(pdb->tdb);
2819 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2823 *pjobid = jobid;
2824 return WERR_OK;
2827 /***************************************************************************
2828 Append a jobid to the 'jobs added' list.
2829 ***************************************************************************/
2831 static bool add_to_jobs_added(struct tdb_print_db *pdb, uint32 jobid)
2833 TDB_DATA data;
2834 uint32 store_jobid;
2836 SIVAL(&store_jobid, 0, jobid);
2837 data.dptr = (uint8 *)&store_jobid;
2838 data.dsize = 4;
2840 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid ));
2842 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_added"),
2843 data) == 0);
2847 /***************************************************************************
2848 Do all checks needed to determine if we can start a job.
2849 ***************************************************************************/
2851 static WERROR print_job_checks(const struct auth_serversupplied_info *server_info,
2852 struct messaging_context *msg_ctx,
2853 int snum, int *njobs)
2855 const char *sharename = lp_const_servicename(snum);
2856 uint64_t dspace, dsize;
2857 uint64_t minspace;
2858 int ret;
2860 if (!print_access_check(server_info, msg_ctx, snum,
2861 PRINTER_ACCESS_USE)) {
2862 DEBUG(3, ("print_job_checks: "
2863 "job start denied by security descriptor\n"));
2864 return WERR_ACCESS_DENIED;
2867 if (!print_time_access_check(server_info, msg_ctx, sharename)) {
2868 DEBUG(3, ("print_job_checks: "
2869 "job start denied by time check\n"));
2870 return WERR_ACCESS_DENIED;
2873 /* see if we have sufficient disk space */
2874 if (lp_minprintspace(snum)) {
2875 minspace = lp_minprintspace(snum);
2876 ret = sys_fsusage(lp_pathname(snum), &dspace, &dsize);
2877 if (ret == 0 && dspace < 2*minspace) {
2878 DEBUG(3, ("print_job_checks: "
2879 "disk space check failed.\n"));
2880 return WERR_NO_SPOOL_SPACE;
2884 /* for autoloaded printers, check that the printcap entry still exists */
2885 if (lp_autoloaded(snum) && !pcap_printername_ok(sharename)) {
2886 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2887 sharename));
2888 return WERR_ACCESS_DENIED;
2891 /* Insure the maximum queue size is not violated */
2892 *njobs = print_queue_length(msg_ctx, snum, NULL);
2893 if (*njobs > lp_maxprintjobs(snum)) {
2894 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2895 "larger than max printjobs per queue (%d).\n",
2896 sharename, *njobs, lp_maxprintjobs(snum)));
2897 return WERR_NO_SPOOL_SPACE;
2900 return WERR_OK;
2903 /***************************************************************************
2904 Create a job file.
2905 ***************************************************************************/
2907 static WERROR print_job_spool_file(int snum, uint32_t jobid,
2908 const char *output_file,
2909 struct printjob *pjob)
2911 WERROR werr;
2912 SMB_STRUCT_STAT st;
2913 const char *path;
2914 int len;
2916 /* if this file is within the printer path, it means that smbd
2917 * is spooling it and will pass us control when it is finished.
2918 * Verify that the file name is ok, within path, and it is
2919 * already already there */
2920 if (output_file) {
2921 path = lp_pathname(snum);
2922 len = strlen(path);
2923 if (strncmp(output_file, path, len) == 0 &&
2924 (output_file[len - 1] == '/' || output_file[len] == '/')) {
2926 /* verify path is not too long */
2927 if (strlen(output_file) >= sizeof(pjob->filename)) {
2928 return WERR_INVALID_NAME;
2931 /* verify that the file exists */
2932 if (sys_stat(output_file, &st, false) != 0) {
2933 return WERR_INVALID_NAME;
2936 fstrcpy(pjob->filename, output_file);
2938 DEBUG(3, ("print_job_spool_file:"
2939 "External spooling activated"));
2941 /* we do not open the file until spooling is done */
2942 pjob->fd = -1;
2943 pjob->status = PJOB_SMBD_SPOOLING;
2945 return WERR_OK;
2949 slprintf(pjob->filename, sizeof(pjob->filename)-1,
2950 "%s/%sXXXXXX", lp_pathname(snum), PRINT_SPOOL_PREFIX);
2951 pjob->fd = mkstemp(pjob->filename);
2953 if (pjob->fd == -1) {
2954 werr = map_werror_from_unix(errno);
2955 if (W_ERROR_EQUAL(werr, WERR_ACCESS_DENIED)) {
2956 /* Common setup error, force a report. */
2957 DEBUG(0, ("print_job_spool_file: "
2958 "insufficient permissions to open spool "
2959 "file %s.\n", pjob->filename));
2960 } else {
2961 /* Normal case, report at level 3 and above. */
2962 DEBUG(3, ("print_job_spool_file: "
2963 "can't open spool file %s\n",
2964 pjob->filename));
2966 return werr;
2969 return WERR_OK;
2972 /***************************************************************************
2973 Start spooling a job - return the jobid.
2974 ***************************************************************************/
2976 WERROR print_job_start(const struct auth_serversupplied_info *server_info,
2977 struct messaging_context *msg_ctx,
2978 const char *clientmachine,
2979 int snum, const char *docname, const char *filename,
2980 struct spoolss_DeviceMode *devmode, uint32_t *_jobid)
2982 uint32_t jobid;
2983 char *path;
2984 struct printjob pjob;
2985 const char *sharename = lp_const_servicename(snum);
2986 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2987 int njobs;
2988 WERROR werr;
2990 if (!pdb) {
2991 return WERR_INTERNAL_DB_CORRUPTION;
2994 path = lp_pathname(snum);
2996 werr = print_job_checks(server_info, msg_ctx, snum, &njobs);
2997 if (!W_ERROR_IS_OK(werr)) {
2998 release_print_db(pdb);
2999 return werr;
3002 DEBUG(10, ("print_job_start: "
3003 "Queue %s number of jobs (%d), max printjobs = %d\n",
3004 sharename, njobs, lp_maxprintjobs(snum)));
3006 werr = allocate_print_jobid(pdb, snum, sharename, &jobid);
3007 if (!W_ERROR_IS_OK(werr)) {
3008 goto fail;
3011 /* create the database entry */
3013 ZERO_STRUCT(pjob);
3015 pjob.pid = sys_getpid();
3016 pjob.jobid = jobid;
3017 pjob.sysjob = -1;
3018 pjob.fd = -1;
3019 pjob.starttime = time(NULL);
3020 pjob.status = LPQ_SPOOLING;
3021 pjob.size = 0;
3022 pjob.spooled = False;
3023 pjob.smbjob = True;
3024 pjob.devmode = devmode;
3026 fstrcpy(pjob.jobname, docname);
3028 fstrcpy(pjob.clientmachine, clientmachine);
3030 fstrcpy(pjob.user, lp_printjob_username(snum));
3031 standard_sub_advanced(sharename, server_info->sanitized_username,
3032 path, server_info->utok.gid,
3033 server_info->sanitized_username,
3034 server_info->info3->base.domain.string,
3035 pjob.user, sizeof(pjob.user)-1);
3036 /* ensure NULL termination */
3037 pjob.user[sizeof(pjob.user)-1] = '\0';
3039 fstrcpy(pjob.queuename, lp_const_servicename(snum));
3041 /* we have a job entry - now create the spool file */
3042 werr = print_job_spool_file(snum, jobid, filename, &pjob);
3043 if (!W_ERROR_IS_OK(werr)) {
3044 goto fail;
3047 pjob_store(server_event_context(), msg_ctx, sharename, jobid, &pjob);
3049 /* Update the 'jobs added' entry used by print_queue_status. */
3050 add_to_jobs_added(pdb, jobid);
3052 /* Ensure we keep a rough count of the number of total jobs... */
3053 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
3055 release_print_db(pdb);
3057 *_jobid = jobid;
3058 return WERR_OK;
3060 fail:
3061 if (jobid != -1) {
3062 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
3065 release_print_db(pdb);
3067 DEBUG(3, ("print_job_start: returning fail. "
3068 "Error = %s\n", win_errstr(werr)));
3069 return werr;
3072 /****************************************************************************
3073 Update the number of pages spooled to jobid
3074 ****************************************************************************/
3076 void print_job_endpage(struct messaging_context *msg_ctx,
3077 int snum, uint32 jobid)
3079 const char* sharename = lp_const_servicename(snum);
3080 struct printjob *pjob;
3081 TALLOC_CTX *tmp_ctx = talloc_new(msg_ctx);
3082 if (tmp_ctx == NULL) {
3083 return;
3086 pjob = print_job_find(tmp_ctx, sharename, jobid);
3087 if (!pjob) {
3088 goto err_out;
3090 /* don't allow another process to get this info - it is meaningless */
3091 if (pjob->pid != sys_getpid()) {
3092 goto err_out;
3095 pjob->page_count++;
3096 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
3097 err_out:
3098 talloc_free(tmp_ctx);
3101 /****************************************************************************
3102 Print a file - called on closing the file. This spools the job.
3103 If normal close is false then we're tearing down the jobs - treat as an
3104 error.
3105 ****************************************************************************/
3107 NTSTATUS print_job_end(struct messaging_context *msg_ctx, int snum,
3108 uint32 jobid, enum file_close_type close_type)
3110 const char* sharename = lp_const_servicename(snum);
3111 struct printjob *pjob;
3112 int ret;
3113 SMB_STRUCT_STAT sbuf;
3114 struct printif *current_printif = get_printer_fns(snum);
3115 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
3116 char *lpq_cmd;
3117 TALLOC_CTX *tmp_ctx = talloc_new(msg_ctx);
3118 if (tmp_ctx == NULL) {
3119 return NT_STATUS_NO_MEMORY;
3122 pjob = print_job_find(tmp_ctx, sharename, jobid);
3123 if (!pjob) {
3124 status = NT_STATUS_PRINT_CANCELLED;
3125 goto err_out;
3128 if (pjob->spooled || pjob->pid != sys_getpid()) {
3129 status = NT_STATUS_ACCESS_DENIED;
3130 goto err_out;
3133 if (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) {
3134 if (pjob->status == PJOB_SMBD_SPOOLING) {
3135 /* take over the file now, smbd is done */
3136 if (sys_stat(pjob->filename, &sbuf, false) != 0) {
3137 status = map_nt_error_from_unix(errno);
3138 DEBUG(3, ("print_job_end: "
3139 "stat file failed for jobid %d\n",
3140 jobid));
3141 goto fail;
3144 pjob->status = LPQ_SPOOLING;
3146 } else {
3148 if ((sys_fstat(pjob->fd, &sbuf, false) != 0)) {
3149 status = map_nt_error_from_unix(errno);
3150 close(pjob->fd);
3151 DEBUG(3, ("print_job_end: "
3152 "stat file failed for jobid %d\n",
3153 jobid));
3154 goto fail;
3157 close(pjob->fd);
3160 pjob->size = sbuf.st_ex_size;
3161 } else {
3164 * Not a normal close, something has gone wrong. Cleanup.
3166 if (pjob->fd != -1) {
3167 close(pjob->fd);
3169 goto fail;
3172 /* Technically, this is not quite right. If the printer has a separator
3173 * page turned on, the NT spooler prints the separator page even if the
3174 * print job is 0 bytes. 010215 JRR */
3175 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
3176 /* don't bother spooling empty files or something being deleted. */
3177 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
3178 pjob->filename, pjob->size ? "deleted" : "zero length" ));
3179 unlink(pjob->filename);
3180 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
3181 return NT_STATUS_OK;
3184 /* don't strip out characters like '$' from the printername */
3185 lpq_cmd = talloc_string_sub2(tmp_ctx,
3186 lp_lpqcommand(snum),
3187 "%p",
3188 lp_printername(snum),
3189 false, false, false);
3190 if (lpq_cmd == NULL) {
3191 status = NT_STATUS_PRINT_CANCELLED;
3192 goto fail;
3194 lpq_cmd = talloc_sub_advanced(tmp_ctx,
3195 lp_servicename(snum),
3196 current_user_info.unix_name,
3198 current_user.ut.gid,
3199 get_current_username(),
3200 current_user_info.domain,
3201 lpq_cmd);
3202 if (lpq_cmd == NULL) {
3203 status = NT_STATUS_PRINT_CANCELLED;
3204 goto fail;
3207 ret = (*(current_printif->job_submit))(snum, pjob,
3208 current_printif->type, lpq_cmd);
3209 if (ret) {
3210 status = NT_STATUS_PRINT_CANCELLED;
3211 goto fail;
3214 /* The print job has been successfully handed over to the back-end */
3216 pjob->spooled = True;
3217 pjob->status = LPQ_QUEUED;
3218 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
3220 /* make sure the database is up to date */
3221 if (print_cache_expired(lp_const_servicename(snum), True))
3222 print_queue_update(msg_ctx, snum, False);
3224 return NT_STATUS_OK;
3226 fail:
3228 /* The print job was not successfully started. Cleanup */
3229 /* Still need to add proper error return propagation! 010122:JRR */
3230 pjob->fd = -1;
3231 unlink(pjob->filename);
3232 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
3233 err_out:
3234 talloc_free(tmp_ctx);
3235 return status;
3238 /****************************************************************************
3239 Get a snapshot of jobs in the system without traversing.
3240 ****************************************************************************/
3242 static bool get_stored_queue_info(struct messaging_context *msg_ctx,
3243 struct tdb_print_db *pdb, int snum,
3244 int *pcount, print_queue_struct **ppqueue)
3246 TDB_DATA data, cgdata, jcdata;
3247 print_queue_struct *queue = NULL;
3248 uint32 qcount = 0;
3249 uint32 extra_count = 0;
3250 uint32_t changed_count = 0;
3251 int total_count = 0;
3252 size_t len = 0;
3253 uint32 i;
3254 int max_reported_jobs = lp_max_reported_jobs(snum);
3255 bool ret = False;
3256 const char* sharename = lp_servicename(snum);
3257 TALLOC_CTX *tmp_ctx = talloc_new(msg_ctx);
3258 if (tmp_ctx == NULL) {
3259 return false;
3262 /* make sure the database is up to date */
3263 if (print_cache_expired(lp_const_servicename(snum), True))
3264 print_queue_update(msg_ctx, snum, False);
3266 *pcount = 0;
3267 *ppqueue = NULL;
3269 ZERO_STRUCT(data);
3270 ZERO_STRUCT(cgdata);
3272 /* Get the stored queue data. */
3273 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
3275 if (data.dptr && data.dsize >= sizeof(qcount))
3276 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
3278 /* Get the added jobs list. */
3279 cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added"));
3280 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
3281 extra_count = cgdata.dsize/4;
3283 /* Get the changed jobs list. */
3284 jcdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
3285 if (jcdata.dptr != NULL && (jcdata.dsize % 4 == 0))
3286 changed_count = jcdata.dsize / 4;
3288 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
3290 /* Allocate the queue size. */
3291 if (qcount == 0 && extra_count == 0)
3292 goto out;
3294 if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
3295 goto out;
3297 /* Retrieve the linearised queue data. */
3299 for( i = 0; i < qcount; i++) {
3300 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
3301 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
3302 &qjob,
3303 &qsize,
3304 &qpage_count,
3305 &qstatus,
3306 &qpriority,
3307 &qtime,
3308 queue[i].fs_user,
3309 queue[i].fs_file);
3310 queue[i].sysjob = qjob;
3311 queue[i].size = qsize;
3312 queue[i].page_count = qpage_count;
3313 queue[i].status = qstatus;
3314 queue[i].priority = qpriority;
3315 queue[i].time = qtime;
3318 total_count = qcount;
3320 /* Add new jobids to the queue. */
3321 for( i = 0; i < extra_count; i++) {
3322 uint32 jobid;
3323 struct printjob *pjob;
3325 jobid = IVAL(cgdata.dptr, i*4);
3326 DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid));
3327 pjob = print_job_find(tmp_ctx, lp_const_servicename(snum), jobid);
3328 if (!pjob) {
3329 DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid));
3330 remove_from_jobs_added(sharename, jobid);
3331 continue;
3334 queue[total_count].sysjob = jobid;
3335 queue[total_count].size = pjob->size;
3336 queue[total_count].page_count = pjob->page_count;
3337 queue[total_count].status = pjob->status;
3338 queue[total_count].priority = 1;
3339 queue[total_count].time = pjob->starttime;
3340 fstrcpy(queue[total_count].fs_user, pjob->user);
3341 fstrcpy(queue[total_count].fs_file, pjob->jobname);
3342 total_count++;
3343 talloc_free(pjob);
3346 /* Update the changed jobids. */
3347 for (i = 0; i < changed_count; i++) {
3348 uint32_t jobid = IVAL(jcdata.dptr, i * 4);
3349 uint32_t j;
3350 bool found = false;
3352 for (j = 0; j < total_count; j++) {
3353 if (queue[j].sysjob == jobid) {
3354 found = true;
3355 break;
3359 if (found) {
3360 struct printjob *pjob;
3362 DEBUG(5,("get_stored_queue_info: changed job: %u\n",
3363 (unsigned int) jobid));
3365 pjob = print_job_find(tmp_ctx, sharename, jobid);
3366 if (pjob == NULL) {
3367 DEBUG(5,("get_stored_queue_info: failed to find "
3368 "changed job = %u\n",
3369 (unsigned int) jobid));
3370 remove_from_jobs_changed(sharename, jobid);
3371 continue;
3374 queue[j].sysjob = jobid;
3375 queue[j].size = pjob->size;
3376 queue[j].page_count = pjob->page_count;
3377 queue[j].status = pjob->status;
3378 queue[j].priority = 1;
3379 queue[j].time = pjob->starttime;
3380 fstrcpy(queue[j].fs_user, pjob->user);
3381 fstrcpy(queue[j].fs_file, pjob->jobname);
3382 talloc_free(pjob);
3384 DEBUG(5,("get_stored_queue_info: updated queue[%u], jobid: %u, jobname: %s\n",
3385 (unsigned int) j, (unsigned int) jobid, pjob->jobname));
3388 remove_from_jobs_changed(sharename, jobid);
3391 /* Sort the queue by submission time otherwise they are displayed
3392 in hash order. */
3394 TYPESAFE_QSORT(queue, total_count, printjob_comp);
3396 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
3398 if (max_reported_jobs && total_count > max_reported_jobs)
3399 total_count = max_reported_jobs;
3401 *ppqueue = queue;
3402 *pcount = total_count;
3404 ret = True;
3406 out:
3408 SAFE_FREE(data.dptr);
3409 SAFE_FREE(cgdata.dptr);
3410 talloc_free(tmp_ctx);
3411 return ret;
3414 /****************************************************************************
3415 Get a printer queue listing.
3416 set queue = NULL and status = NULL if you just want to update the cache
3417 ****************************************************************************/
3419 int print_queue_status(struct messaging_context *msg_ctx, int snum,
3420 print_queue_struct **ppqueue,
3421 print_status_struct *status)
3423 fstring keystr;
3424 TDB_DATA data, key;
3425 const char *sharename;
3426 struct tdb_print_db *pdb;
3427 int count = 0;
3429 /* make sure the database is up to date */
3431 if (print_cache_expired(lp_const_servicename(snum), True))
3432 print_queue_update(msg_ctx, snum, False);
3434 /* return if we are done */
3435 if ( !ppqueue || !status )
3436 return 0;
3438 *ppqueue = NULL;
3439 sharename = lp_const_servicename(snum);
3440 pdb = get_print_db_byname(sharename);
3442 if (!pdb)
3443 return 0;
3446 * Fetch the queue status. We must do this first, as there may
3447 * be no jobs in the queue.
3450 ZERO_STRUCTP(status);
3451 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
3452 key = string_tdb_data(keystr);
3454 data = tdb_fetch(pdb->tdb, key);
3455 if (data.dptr) {
3456 if (data.dsize == sizeof(*status)) {
3457 /* this memcpy is ok since the status struct was
3458 not packed before storing it in the tdb */
3459 memcpy(status, data.dptr, sizeof(*status));
3461 SAFE_FREE(data.dptr);
3465 * Now, fetch the print queue information. We first count the number
3466 * of entries, and then only retrieve the queue if necessary.
3469 if (!get_stored_queue_info(msg_ctx, pdb, snum, &count, ppqueue)) {
3470 release_print_db(pdb);
3471 return 0;
3474 release_print_db(pdb);
3475 return count;
3478 /****************************************************************************
3479 Pause a queue.
3480 ****************************************************************************/
3482 WERROR print_queue_pause(const struct auth_serversupplied_info *server_info,
3483 struct messaging_context *msg_ctx, int snum)
3485 int ret;
3486 struct printif *current_printif = get_printer_fns( snum );
3488 if (!print_access_check(server_info, msg_ctx, snum,
3489 PRINTER_ACCESS_ADMINISTER)) {
3490 return WERR_ACCESS_DENIED;
3494 become_root();
3496 ret = (*(current_printif->queue_pause))(snum);
3498 unbecome_root();
3500 if (ret != 0) {
3501 return WERR_INVALID_PARAM;
3504 /* force update the database */
3505 print_cache_flush(lp_const_servicename(snum));
3507 /* Send a printer notify message */
3509 notify_printer_status(server_event_context(), msg_ctx, snum,
3510 PRINTER_STATUS_PAUSED);
3512 return WERR_OK;
3515 /****************************************************************************
3516 Resume a queue.
3517 ****************************************************************************/
3519 WERROR print_queue_resume(const struct auth_serversupplied_info *server_info,
3520 struct messaging_context *msg_ctx, int snum)
3522 int ret;
3523 struct printif *current_printif = get_printer_fns( snum );
3525 if (!print_access_check(server_info, msg_ctx, snum,
3526 PRINTER_ACCESS_ADMINISTER)) {
3527 return WERR_ACCESS_DENIED;
3530 become_root();
3532 ret = (*(current_printif->queue_resume))(snum);
3534 unbecome_root();
3536 if (ret != 0) {
3537 return WERR_INVALID_PARAM;
3540 /* make sure the database is up to date */
3541 if (print_cache_expired(lp_const_servicename(snum), True))
3542 print_queue_update(msg_ctx, snum, True);
3544 /* Send a printer notify message */
3546 notify_printer_status(server_event_context(), msg_ctx, snum,
3547 PRINTER_STATUS_OK);
3549 return WERR_OK;
3552 /****************************************************************************
3553 Purge a queue - implemented by deleting all jobs that we can delete.
3554 ****************************************************************************/
3556 WERROR print_queue_purge(const struct auth_serversupplied_info *server_info,
3557 struct messaging_context *msg_ctx, int snum)
3559 print_queue_struct *queue;
3560 print_status_struct status;
3561 int njobs, i;
3562 bool can_job_admin;
3564 /* Force and update so the count is accurate (i.e. not a cached count) */
3565 print_queue_update(msg_ctx, snum, True);
3567 can_job_admin = print_access_check(server_info,
3568 msg_ctx,
3569 snum,
3570 JOB_ACCESS_ADMINISTER);
3571 njobs = print_queue_status(msg_ctx, snum, &queue, &status);
3573 if ( can_job_admin )
3574 become_root();
3576 for (i=0;i<njobs;i++) {
3577 bool owner = is_owner(server_info, lp_const_servicename(snum),
3578 queue[i].sysjob);
3580 if (owner || can_job_admin) {
3581 print_job_delete1(server_event_context(), msg_ctx,
3582 snum, queue[i].sysjob);
3586 if ( can_job_admin )
3587 unbecome_root();
3589 /* update the cache */
3590 print_queue_update(msg_ctx, snum, True);
3592 SAFE_FREE(queue);
3594 return WERR_OK;