2 Unix SMB/Netbios implementation.
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/>.
24 #include "librpc/gen_ndr/messaging.h"
25 #include "../librpc/gen_ndr/ndr_spoolss.h"
26 #include "nt_printing.h"
27 #include "../librpc/gen_ndr/netlogon.h"
29 extern struct current_user current_user;
30 extern userdom_struct current_user_info;
32 /* Current printer interface */
33 static bool remove_from_jobs_changed(const char* sharename, uint32 jobid);
36 the printing backend revolves around a tdb database that stores the
37 SMB view of the print queue
39 The key for this database is a jobid - a internally generated number that
40 uniquely identifies a print job
42 reading the print queue involves two steps:
43 - possibly running lpq and updating the internal database from that
44 - reading entries from the database
46 jobids are assigned when a job starts spooling.
49 static TDB_CONTEXT *rap_tdb;
50 static uint16 next_rap_jobid;
51 struct rap_jobid_key {
56 /***************************************************************************
57 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
58 bit RPC jobids.... JRA.
59 ***************************************************************************/
61 uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
65 struct rap_jobid_key jinfo;
68 DEBUG(10,("pjobid_to_rap: called.\n"));
71 /* Create the in-memory tdb. */
72 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
78 fstrcpy( jinfo.sharename, sharename );
80 key.dptr = (uint8 *)&jinfo;
81 key.dsize = sizeof(jinfo);
83 data = tdb_fetch(rap_tdb, key);
84 if (data.dptr && data.dsize == sizeof(uint16)) {
85 rap_jobid = SVAL(data.dptr, 0);
87 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
88 (unsigned int)jobid, (unsigned int)rap_jobid));
92 /* Not found - create and store mapping. */
93 rap_jobid = ++next_rap_jobid;
95 rap_jobid = ++next_rap_jobid;
96 SSVAL(buf,0,rap_jobid);
98 data.dsize = sizeof(rap_jobid);
99 tdb_store(rap_tdb, key, data, TDB_REPLACE);
100 tdb_store(rap_tdb, data, key, TDB_REPLACE);
102 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
103 (unsigned int)jobid, (unsigned int)rap_jobid));
107 bool rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
112 DEBUG(10,("rap_to_pjobid called.\n"));
117 SSVAL(buf,0,rap_jobid);
119 key.dsize = sizeof(rap_jobid);
120 data = tdb_fetch(rap_tdb, key);
121 if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) )
123 struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
124 if (sharename != NULL) {
125 fstrcpy( sharename, jinfo->sharename );
127 *pjobid = jinfo->jobid;
128 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
129 (unsigned int)*pjobid, (unsigned int)rap_jobid));
130 SAFE_FREE(data.dptr);
134 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
135 (unsigned int)rap_jobid));
136 SAFE_FREE(data.dptr);
140 void rap_jobid_delete(const char* sharename, uint32 jobid)
144 struct rap_jobid_key jinfo;
147 DEBUG(10,("rap_jobid_delete: called.\n"));
152 ZERO_STRUCT( jinfo );
153 fstrcpy( jinfo.sharename, sharename );
155 key.dptr = (uint8 *)&jinfo;
156 key.dsize = sizeof(jinfo);
158 data = tdb_fetch(rap_tdb, key);
159 if (!data.dptr || (data.dsize != sizeof(uint16))) {
160 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
161 (unsigned int)jobid ));
162 SAFE_FREE(data.dptr);
166 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
167 (unsigned int)jobid ));
169 rap_jobid = SVAL(data.dptr, 0);
170 SAFE_FREE(data.dptr);
171 SSVAL(buf,0,rap_jobid);
173 data.dsize = sizeof(rap_jobid);
174 tdb_delete(rap_tdb, key);
175 tdb_delete(rap_tdb, data);
178 static int get_queue_status(const char* sharename, print_status_struct *);
180 /****************************************************************************
181 Initialise the printing backend. Called once at startup before the fork().
182 ****************************************************************************/
184 bool print_backend_init(struct messaging_context *msg_ctx)
186 const char *sversion = "INFO/version";
187 int services = lp_numservices();
190 unlink(cache_path("printing.tdb"));
191 mkdir(cache_path("printing"),0755);
193 /* handle a Samba upgrade */
195 for (snum = 0; snum < services; snum++) {
196 struct tdb_print_db *pdb;
197 if (!lp_print_ok(snum))
200 pdb = get_print_db_byname(lp_const_servicename(snum));
203 if (tdb_lock_bystring(pdb->tdb, sversion) == -1) {
204 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
205 release_print_db(pdb);
208 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
209 tdb_wipe_all(pdb->tdb);
210 tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
212 tdb_unlock_bystring(pdb->tdb, sversion);
213 release_print_db(pdb);
216 close_all_print_db(); /* Don't leave any open. */
218 /* do NT print initialization... */
219 return nt_printing_init(msg_ctx);
222 /****************************************************************************
223 Shut down printing backend. Called once at shutdown to close the tdb.
224 ****************************************************************************/
226 void printing_end(void)
228 close_all_print_db(); /* Don't leave any open. */
231 /****************************************************************************
232 Retrieve the set of printing functions for a given service. This allows
233 us to set the printer function table based on the value of the 'printing'
236 Use the generic interface as the default and only use cups interface only
237 when asked for (and only when supported)
238 ****************************************************************************/
240 static struct printif *get_printer_fns_from_type( enum printing_types type )
242 struct printif *printer_fns = &generic_printif;
245 if ( type == PRINT_CUPS ) {
246 printer_fns = &cups_printif;
248 #endif /* HAVE_CUPS */
251 if ( type == PRINT_IPRINT ) {
252 printer_fns = &iprint_printif;
254 #endif /* HAVE_IPRINT */
256 printer_fns->type = type;
261 static struct printif *get_printer_fns( int snum )
263 return get_printer_fns_from_type( (enum printing_types)lp_printing(snum) );
267 /****************************************************************************
268 Useful function to generate a tdb key.
269 ****************************************************************************/
271 static TDB_DATA print_key(uint32 jobid, uint32 *tmp)
275 SIVAL(tmp, 0, jobid);
276 ret.dptr = (uint8 *)tmp;
277 ret.dsize = sizeof(*tmp);
281 /****************************************************************************
282 Pack the devicemode to store it in a tdb.
283 ****************************************************************************/
284 static int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8 *buf, int buflen)
286 enum ndr_err_code ndr_err;
291 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(),
293 (ndr_push_flags_fn_t)
294 ndr_push_spoolss_DeviceMode);
295 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
296 DEBUG(10, ("pack_devicemode: "
297 "error encoding spoolss_DeviceMode\n"));
304 len = tdb_pack(buf, buflen, "B", blob.length, blob.data);
307 DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname));
314 /****************************************************************************
315 Unpack the devicemode to store it in a tdb.
316 ****************************************************************************/
317 static int unpack_devicemode(TALLOC_CTX *mem_ctx,
318 const uint8 *buf, int buflen,
319 struct spoolss_DeviceMode **devmode)
321 struct spoolss_DeviceMode *dm;
322 enum ndr_err_code ndr_err;
330 len = tdb_unpack(buf, buflen, "B", &data_len, &data);
335 dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
340 blob = data_blob_const(data, data_len);
342 ndr_err = ndr_pull_struct_blob(&blob, dm, dm,
343 (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);
344 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
345 DEBUG(10, ("unpack_devicemode: "
346 "error parsing spoolss_DeviceMode\n"));
350 DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
351 dm->devicename, dm->formname));
352 if (dm->driverextra_data.data) {
353 DEBUG(8, ("with a private section of %d bytes\n",
354 dm->__driverextra_length));
364 /***********************************************************************
365 unpack a pjob from a tdb buffer
366 ***********************************************************************/
368 int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )
372 uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
373 uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
378 len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
396 used = unpack_devicemode(NULL, buf+len, buflen-len, &pjob->devmode);
404 pjob->sysjob = pjsysjob;
406 pjob->starttime = pjstarttime;
407 pjob->status = pjstatus;
409 pjob->page_count = pjpage_count;
410 pjob->spooled = pjspooled;
411 pjob->smbjob = pjsmbjob;
417 /****************************************************************************
418 Useful function to find a print job in the database.
419 ****************************************************************************/
421 static struct printjob *print_job_find(const char *sharename, uint32 jobid)
423 static struct printjob pjob;
426 struct tdb_print_db *pdb = get_print_db_byname(sharename);
428 DEBUG(10,("print_job_find: looking up job %u for share %s\n",
429 (unsigned int)jobid, sharename ));
435 ret = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
436 release_print_db(pdb);
439 DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid ));
443 talloc_free(pjob.devmode);
447 if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
448 DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid ));
455 DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
456 (int)pjob.sysjob, (unsigned int)jobid ));
461 /* Convert a unix jobid to a smb jobid */
463 struct unixjob_traverse_state {
465 uint32 sysjob_to_jobid_value;
468 static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
469 TDB_DATA data, void *private_data)
471 struct printjob *pjob;
472 struct unixjob_traverse_state *state =
473 (struct unixjob_traverse_state *)private_data;
475 if (!data.dptr || data.dsize == 0)
478 pjob = (struct printjob *)data.dptr;
479 if (key.dsize != sizeof(uint32))
482 if (state->sysjob == pjob->sysjob) {
483 uint32 jobid = IVAL(key.dptr,0);
485 state->sysjob_to_jobid_value = jobid;
492 /****************************************************************************
493 This is a *horribly expensive call as we have to iterate through all the
494 current printer tdb's. Don't do this often ! JRA.
495 ****************************************************************************/
497 uint32 sysjob_to_jobid(int unix_jobid)
499 int services = lp_numservices();
501 struct unixjob_traverse_state state;
503 state.sysjob = unix_jobid;
504 state.sysjob_to_jobid_value = (uint32)-1;
506 for (snum = 0; snum < services; snum++) {
507 struct tdb_print_db *pdb;
508 if (!lp_print_ok(snum))
510 pdb = get_print_db_byname(lp_const_servicename(snum));
514 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &state);
515 release_print_db(pdb);
516 if (state.sysjob_to_jobid_value != (uint32)-1)
517 return state.sysjob_to_jobid_value;
522 /****************************************************************************
523 Send notifications based on what has changed after a pjob_store.
524 ****************************************************************************/
526 static const struct {
528 uint32 spoolss_status;
529 } lpq_to_spoolss_status_map[] = {
530 { LPQ_QUEUED, JOB_STATUS_QUEUED },
531 { LPQ_PAUSED, JOB_STATUS_PAUSED },
532 { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
533 { LPQ_PRINTING, JOB_STATUS_PRINTING },
534 { LPQ_DELETING, JOB_STATUS_DELETING },
535 { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
536 { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
537 { LPQ_PRINTED, JOB_STATUS_PRINTED },
538 { LPQ_DELETED, JOB_STATUS_DELETED },
539 { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ },
540 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
544 /* Convert a lpq status value stored in printing.tdb into the
545 appropriate win32 API constant. */
547 static uint32 map_to_spoolss_status(uint32 lpq_status)
551 while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
552 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
553 return lpq_to_spoolss_status_map[i].spoolss_status;
560 static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data,
561 struct printjob *new_data)
563 bool new_job = False;
568 /* Job attributes that can't be changed. We only send
569 notification for these on a new job. */
571 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
572 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
573 time first or else we'll end up with potential alignment
574 errors. I don't think the systemtime should be spooled as
575 a string, but this gets us around that error.
576 --jerry (i'll feel dirty for this) */
579 notify_job_submitted(sharename, jobid, new_data->starttime);
580 notify_job_username(sharename, jobid, new_data->user);
583 if (new_job || !strequal(old_data->jobname, new_data->jobname))
584 notify_job_name(sharename, jobid, new_data->jobname);
586 /* Job attributes of a new job or attributes that can be
589 if (new_job || !strequal(old_data->jobname, new_data->jobname))
590 notify_job_name(sharename, jobid, new_data->jobname);
592 if (new_job || old_data->status != new_data->status)
593 notify_job_status(server_event_context(),
594 server_messaging_context(),
596 map_to_spoolss_status(new_data->status));
598 if (new_job || old_data->size != new_data->size)
599 notify_job_total_bytes(sharename, jobid, new_data->size);
601 if (new_job || old_data->page_count != new_data->page_count)
602 notify_job_total_pages(sharename, jobid, new_data->page_count);
605 /****************************************************************************
606 Store a job structure back to the database.
607 ****************************************************************************/
609 static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob)
612 TDB_DATA old_data, new_data;
614 struct tdb_print_db *pdb = get_print_db_byname(sharename);
616 int len, newlen, buflen;
624 old_data = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
626 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
633 len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
635 (uint32)pjob->sysjob,
637 (uint32)pjob->starttime,
638 (uint32)pjob->status,
640 (uint32)pjob->page_count,
641 (uint32)pjob->spooled,
642 (uint32)pjob->smbjob,
648 len += pack_devicemode(pjob->devmode, buf+len, buflen-len);
651 buf = (uint8 *)SMB_REALLOC(buf, len);
653 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
658 } while ( buflen != len );
664 new_data.dsize = len;
665 ret = (tdb_store(pdb->tdb, print_key(jobid, &tmp), new_data,
668 release_print_db(pdb);
670 /* Send notify updates for what has changed */
673 struct printjob old_pjob;
675 if ( old_data.dsize )
677 if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
679 pjob_store_notify( sharename, jobid, &old_pjob , pjob );
680 talloc_free(old_pjob.devmode);
685 pjob_store_notify( sharename, jobid, NULL, pjob );
690 SAFE_FREE( old_data.dptr );
696 /****************************************************************************
697 Remove a job structure from the database.
698 ****************************************************************************/
700 void pjob_delete(const char* sharename, uint32 jobid)
703 struct printjob *pjob;
704 uint32 job_status = 0;
705 struct tdb_print_db *pdb;
707 pdb = get_print_db_byname( sharename );
712 pjob = print_job_find( sharename, jobid );
715 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
716 (unsigned int)jobid));
717 release_print_db(pdb);
721 /* We must cycle through JOB_STATUS_DELETING and
722 JOB_STATUS_DELETED for the port monitor to delete the job
725 job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
726 notify_job_status(server_event_context(),
727 server_messaging_context(),
728 sharename, jobid, job_status);
730 /* Remove from printing.tdb */
732 tdb_delete(pdb->tdb, print_key(jobid, &tmp));
733 remove_from_jobs_changed(sharename, jobid);
734 release_print_db( pdb );
735 rap_jobid_delete(sharename, jobid);
738 /****************************************************************************
739 List a unix job in the print database.
740 ****************************************************************************/
742 static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid)
744 struct printjob pj, *old_pj;
746 if (jobid == (uint32)-1)
747 jobid = q->job + UNIX_JOB_START;
749 /* Preserve the timestamp on an existing unix print job */
751 old_pj = print_job_find(sharename, jobid);
758 pj.starttime = old_pj ? old_pj->starttime : q->time;
759 pj.status = q->status;
762 fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
763 if (jobid < UNIX_JOB_START) {
765 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
768 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
770 fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
771 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
773 pjob_store(sharename, jobid, &pj);
777 struct traverse_struct {
778 print_queue_struct *queue;
779 int qcount, snum, maxcount, total_jobs;
780 const char *sharename;
782 const char *lprm_command;
783 struct printif *print_if;
786 /****************************************************************************
787 Utility fn to delete any jobs that are no longer active.
788 ****************************************************************************/
790 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
792 struct traverse_struct *ts = (struct traverse_struct *)state;
793 struct printjob pjob;
797 if ( key.dsize != sizeof(jobid) )
800 jobid = IVAL(key.dptr, 0);
801 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
803 talloc_free(pjob.devmode);
807 /* remove a unix job if it isn't in the system queue any more */
809 for (i=0;i<ts->qcount;i++) {
810 uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
811 if (jobid == u_jobid)
814 if (i == ts->qcount) {
815 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
816 (unsigned int)jobid ));
817 pjob_delete(ts->sharename, jobid);
821 /* need to continue the the bottom of the function to
822 save the correct attributes */
825 /* maybe it hasn't been spooled yet */
827 /* if a job is not spooled and the process doesn't
828 exist then kill it. This cleans up after smbd
830 if (!process_exists_by_pid(pjob.pid)) {
831 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
832 (unsigned int)jobid, (unsigned int)pjob.pid ));
833 pjob_delete(ts->sharename, jobid);
839 /* this check only makes sense for jobs submitted from Windows clients */
842 for (i=0;i<ts->qcount;i++) {
845 if ( pjob.status == LPQ_DELETED )
848 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
850 if (jobid == curr_jobid) {
852 /* try to clean up any jobs that need to be deleted */
854 if ( pjob.status == LPQ_DELETING ) {
857 result = (*(ts->print_if->job_delete))(
858 ts->sharename, ts->lprm_command, &pjob );
861 /* if we can't delete, then reset the job status */
862 pjob.status = LPQ_QUEUED;
863 pjob_store(ts->sharename, jobid, &pjob);
866 /* if we deleted the job, the remove the tdb record */
867 pjob_delete(ts->sharename, jobid);
868 pjob.status = LPQ_DELETED;
878 /* The job isn't in the system queue - we have to assume it has
879 completed, so delete the database entry. */
881 if (i == ts->qcount) {
883 /* A race can occur between the time a job is spooled and
884 when it appears in the lpq output. This happens when
885 the job is added to printing.tdb when another smbd
886 running print_queue_update() has completed a lpq and
887 is currently traversing the printing tdb and deleting jobs.
888 Don't delete the job if it was submitted after the lpq_time. */
890 if (pjob.starttime < ts->lpq_time) {
891 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
893 (unsigned int)pjob.starttime,
894 (unsigned int)ts->lpq_time ));
895 pjob_delete(ts->sharename, jobid);
901 /* Save the pjob attributes we will store.
902 FIXME!!! This is the only place where queue->job
903 represents the SMB jobid --jerry */
905 ts->queue[i].job = jobid;
906 ts->queue[i].size = pjob.size;
907 ts->queue[i].page_count = pjob.page_count;
908 ts->queue[i].status = pjob.status;
909 ts->queue[i].priority = 1;
910 ts->queue[i].time = pjob.starttime;
911 fstrcpy(ts->queue[i].fs_user, pjob.user);
912 fstrcpy(ts->queue[i].fs_file, pjob.jobname);
919 /****************************************************************************
920 Check if the print queue has been updated recently enough.
921 ****************************************************************************/
923 static void print_cache_flush(const char *sharename)
926 struct tdb_print_db *pdb = get_print_db_byname(sharename);
930 slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
931 tdb_store_int32(pdb->tdb, key, -1);
932 release_print_db(pdb);
935 /****************************************************************************
936 Check if someone already thinks they are doing the update.
937 ****************************************************************************/
939 static pid_t get_updating_pid(const char *sharename)
944 struct tdb_print_db *pdb = get_print_db_byname(sharename);
948 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
949 key = string_tdb_data(keystr);
951 data = tdb_fetch(pdb->tdb, key);
952 release_print_db(pdb);
953 if (!data.dptr || data.dsize != sizeof(pid_t)) {
954 SAFE_FREE(data.dptr);
958 updating_pid = IVAL(data.dptr, 0);
959 SAFE_FREE(data.dptr);
961 if (process_exists_by_pid(updating_pid))
967 /****************************************************************************
968 Set the fact that we're doing the update, or have finished doing the update
970 ****************************************************************************/
972 static void set_updating_pid(const fstring sharename, bool updating)
977 pid_t updating_pid = sys_getpid();
980 struct tdb_print_db *pdb = get_print_db_byname(sharename);
985 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
986 key = string_tdb_data(keystr);
988 DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
989 updating ? "" : "not ",
993 tdb_delete(pdb->tdb, key);
994 release_print_db(pdb);
998 SIVAL( buffer, 0, updating_pid);
1000 data.dsize = 4; /* we always assume this is a 4 byte value */
1002 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1003 release_print_db(pdb);
1006 /****************************************************************************
1007 Sort print jobs by submittal time.
1008 ****************************************************************************/
1010 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
1021 /* Sort on job start time */
1023 if (j1->time == j2->time)
1025 return (j1->time > j2->time) ? 1 : -1;
1028 /****************************************************************************
1029 Store the sorted queue representation for later portmon retrieval.
1031 ****************************************************************************/
1033 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
1036 int max_reported_jobs = lp_max_reported_jobs(pts->snum);
1037 print_queue_struct *queue = pts->queue;
1040 unsigned int qcount;
1042 if (max_reported_jobs && (max_reported_jobs < pts->qcount))
1043 pts->qcount = max_reported_jobs;
1046 /* Work out the size. */
1048 data.dsize += tdb_pack(NULL, 0, "d", qcount);
1050 for (i = 0; i < pts->qcount; i++) {
1051 if ( queue[i].status == LPQ_DELETED )
1055 data.dsize += tdb_pack(NULL, 0, "ddddddff",
1056 (uint32)queue[i].job,
1057 (uint32)queue[i].size,
1058 (uint32)queue[i].page_count,
1059 (uint32)queue[i].status,
1060 (uint32)queue[i].priority,
1061 (uint32)queue[i].time,
1066 if ((data.dptr = (uint8 *)SMB_MALLOC(data.dsize)) == NULL)
1070 len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
1071 for (i = 0; i < pts->qcount; i++) {
1072 if ( queue[i].status == LPQ_DELETED )
1075 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
1076 (uint32)queue[i].job,
1077 (uint32)queue[i].size,
1078 (uint32)queue[i].page_count,
1079 (uint32)queue[i].status,
1080 (uint32)queue[i].priority,
1081 (uint32)queue[i].time,
1086 tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
1088 SAFE_FREE(data.dptr);
1092 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
1098 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
1099 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
1100 SAFE_FREE(data.dptr);
1107 static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid)
1110 unsigned int job_count = data.dsize / 4;
1112 for (i = 0; i < job_count; i++) {
1115 ch_jobid = IVAL(data.dptr, i*4);
1116 if (ch_jobid == jobid)
1117 remove_from_jobs_changed(sharename, jobid);
1121 /****************************************************************************
1122 Check if the print queue has been updated recently enough.
1123 ****************************************************************************/
1125 static bool print_cache_expired(const char *sharename, bool check_pending)
1128 time_t last_qscan_time, time_now = time(NULL);
1129 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1130 bool result = False;
1135 snprintf(key, sizeof(key), "CACHE/%s", sharename);
1136 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1139 * Invalidate the queue for 3 reasons.
1140 * (1). last queue scan time == -1.
1141 * (2). Current time - last queue scan time > allowed cache time.
1142 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1143 * This last test picks up machines for which the clock has been moved
1144 * forward, an lpq scan done and then the clock moved back. Otherwise
1145 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1148 if (last_qscan_time == ((time_t)-1)
1149 || (time_now - last_qscan_time) >= lp_lpqcachetime()
1150 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
1153 time_t msg_pending_time;
1155 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1156 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1157 sharename, (int)last_qscan_time, (int)time_now,
1158 (int)lp_lpqcachetime() ));
1160 /* check if another smbd has already sent a message to update the
1161 queue. Give the pending message one minute to clear and
1162 then send another message anyways. Make sure to check for
1163 clocks that have been run forward and then back again. */
1165 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1168 && tdb_fetch_uint32( pdb->tdb, key, &u )
1169 && (msg_pending_time=u) > 0
1170 && msg_pending_time <= time_now
1171 && (time_now - msg_pending_time) < 60 )
1173 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1182 release_print_db(pdb);
1186 /****************************************************************************
1187 main work for updating the lpq cahe for a printer queue
1188 ****************************************************************************/
1190 static void print_queue_update_internal( const char *sharename,
1191 struct printif *current_printif,
1192 char *lpq_command, char *lprm_command )
1195 print_queue_struct *queue = NULL;
1196 print_status_struct status;
1197 print_status_struct old_status;
1198 struct printjob *pjob;
1199 struct traverse_struct tstruct;
1202 fstring keystr, cachestr;
1203 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1209 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1210 sharename, current_printif->type, lpq_command));
1213 * Update the cache time FIRST ! Stops others even
1214 * attempting to get the lock and doing this
1215 * if the lpq takes a long time.
1218 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1219 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1221 /* get the current queue using the appropriate interface */
1222 ZERO_STRUCT(status);
1224 qcount = (*(current_printif->queue_get))(sharename,
1225 current_printif->type,
1226 lpq_command, &queue, &status);
1228 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1229 qcount, (qcount != 1) ? "s" : "", sharename));
1231 /* Sort the queue by submission time otherwise they are displayed
1234 TYPESAFE_QSORT(queue, qcount, printjob_comp);
1237 any job in the internal database that is marked as spooled
1238 and doesn't exist in the system queue is considered finished
1239 and removed from the database
1241 any job in the system database but not in the internal database
1242 is added as a unix job
1244 fill in any system job numbers as we go
1247 jcdata = get_jobs_changed_data(pdb);
1249 for (i=0; i<qcount; i++) {
1250 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1252 if (jobid == (uint32)-1) {
1253 /* assume its a unix print job */
1254 print_unix_job(sharename, &queue[i], jobid);
1258 /* we have an active SMB print job - update its status */
1259 pjob = print_job_find(sharename, jobid);
1261 /* err, somethings wrong. Probably smbd was restarted
1262 with jobs in the queue. All we can do is treat them
1263 like unix jobs. Pity. */
1264 print_unix_job(sharename, &queue[i], jobid);
1268 pjob->sysjob = queue[i].job;
1270 /* don't reset the status on jobs to be deleted */
1272 if ( pjob->status != LPQ_DELETING )
1273 pjob->status = queue[i].status;
1275 pjob_store(sharename, jobid, pjob);
1277 check_job_changed(sharename, jcdata, jobid);
1280 SAFE_FREE(jcdata.dptr);
1282 /* now delete any queued entries that don't appear in the
1284 tstruct.queue = queue;
1285 tstruct.qcount = qcount;
1287 tstruct.total_jobs = 0;
1288 tstruct.lpq_time = time(NULL);
1289 tstruct.sharename = sharename;
1290 tstruct.lprm_command = lprm_command;
1291 tstruct.print_if = current_printif;
1293 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1295 /* Store the linearised queue, max jobs only. */
1296 store_queue_struct(pdb, &tstruct);
1298 SAFE_FREE(tstruct.queue);
1300 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1301 sharename, tstruct.total_jobs ));
1303 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1305 get_queue_status(sharename, &old_status);
1306 if (old_status.qcount != qcount)
1307 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1308 old_status.qcount, qcount, sharename));
1310 /* store the new queue status structure */
1311 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1312 key = string_tdb_data(keystr);
1314 status.qcount = qcount;
1315 data.dptr = (uint8 *)&status;
1316 data.dsize = sizeof(status);
1317 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1320 * Update the cache time again. We want to do this call
1321 * as little as possible...
1324 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1325 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1327 /* clear the msg pending record for this queue */
1329 snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1331 if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1332 /* log a message but continue on */
1334 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1338 release_print_db( pdb );
1343 /****************************************************************************
1344 Update the internal database from the system print queue for a queue.
1345 obtain a lock on the print queue before proceeding (needed when mutiple
1346 smbd processes maytry to update the lpq cache concurrently).
1347 ****************************************************************************/
1349 static void print_queue_update_with_lock( const char *sharename,
1350 struct printif *current_printif,
1351 char *lpq_command, char *lprm_command )
1354 struct tdb_print_db *pdb;
1356 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1357 pdb = get_print_db_byname(sharename);
1361 if ( !print_cache_expired(sharename, False) ) {
1362 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1363 release_print_db(pdb);
1368 * Check to see if someone else is doing this update.
1369 * This is essentially a mutex on the update.
1372 if (get_updating_pid(sharename) != -1) {
1373 release_print_db(pdb);
1377 /* Lock the queue for the database update */
1379 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1380 /* Only wait 10 seconds for this. */
1381 if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
1382 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1383 release_print_db(pdb);
1388 * Ensure that no one else got in here.
1389 * If the updating pid is still -1 then we are
1393 if (get_updating_pid(sharename) != -1) {
1395 * Someone else is doing the update, exit.
1397 tdb_unlock_bystring(pdb->tdb, keystr);
1398 release_print_db(pdb);
1403 * We're going to do the update ourselves.
1406 /* Tell others we're doing the update. */
1407 set_updating_pid(sharename, True);
1410 * Allow others to enter and notice we're doing
1414 tdb_unlock_bystring(pdb->tdb, keystr);
1416 /* do the main work now */
1418 print_queue_update_internal( sharename, current_printif,
1419 lpq_command, lprm_command );
1421 /* Delete our pid from the db. */
1422 set_updating_pid(sharename, False);
1423 release_print_db(pdb);
1426 /****************************************************************************
1427 this is the receive function of the background lpq updater
1428 ****************************************************************************/
1429 static void print_queue_receive(struct messaging_context *msg,
1432 struct server_id server_id,
1436 char *lpqcommand = NULL, *lprmcommand = NULL;
1440 len = tdb_unpack( (uint8 *)data->data, data->length, "fdPP",
1447 SAFE_FREE(lpqcommand);
1448 SAFE_FREE(lprmcommand);
1449 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1453 print_queue_update_with_lock(sharename,
1454 get_printer_fns_from_type((enum printing_types)printing_type),
1455 lpqcommand, lprmcommand );
1457 SAFE_FREE(lpqcommand);
1458 SAFE_FREE(lprmcommand);
1462 static void printing_pause_fd_handler(struct tevent_context *ev,
1463 struct tevent_fd *fde,
1468 * If pause_pipe[1] is closed it means the parent smbd
1469 * and children exited or aborted.
1471 exit_server_cleanly(NULL);
1474 extern struct child_pid *children;
1475 extern int num_children;
1477 static void add_child_pid(pid_t pid)
1479 struct child_pid *child;
1481 child = SMB_MALLOC_P(struct child_pid);
1482 if (child == NULL) {
1483 DEBUG(0, ("Could not add child struct -- malloc failed\n"));
1487 DLIST_ADD(children, child);
1491 static pid_t background_lpq_updater_pid = -1;
1493 /****************************************************************************
1494 main thread of the background lpq updater
1495 ****************************************************************************/
1496 void start_background_queue(struct tevent_context *ev,
1497 struct messaging_context *msg_ctx)
1499 /* Use local variables for this as we don't
1500 * need to save the parent side of this, just
1501 * ensure it closes when the process exits.
1505 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1507 if (pipe(pause_pipe) == -1) {
1508 DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno) ));
1512 background_lpq_updater_pid = sys_fork();
1514 if (background_lpq_updater_pid == -1) {
1515 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1519 /* Track the printing pid along with other smbd children */
1520 add_child_pid(background_lpq_updater_pid);
1522 if(background_lpq_updater_pid == 0) {
1523 struct tevent_fd *fde;
1528 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1530 close(pause_pipe[0]);
1533 status = reinit_after_fork(msg_ctx, ev, procid_self(), true);
1535 if (!NT_STATUS_IS_OK(status)) {
1536 DEBUG(0,("reinit_after_fork() failed\n"));
1537 smb_panic("reinit_after_fork() failed");
1540 smbd_setup_sig_term_handler();
1541 smbd_setup_sig_hup_handler(ev, msg_ctx);
1543 if (!serverid_register(procid_self(),
1544 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
1545 |FLAG_MSG_PRINT_GENERAL)) {
1549 if (!locking_init()) {
1553 messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE,
1554 print_queue_receive);
1556 fde = tevent_add_fd(ev, ev, pause_pipe[1], TEVENT_FD_READ,
1557 printing_pause_fd_handler,
1560 DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
1561 smb_panic("tevent_add_fd() failed for pause_pipe");
1564 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1565 ret = tevent_loop_wait(ev);
1566 /* should not be reached */
1567 DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
1568 ret, (ret == 0) ? "out of events" : strerror(errno)));
1572 close(pause_pipe[1]);
1575 /****************************************************************************
1576 update the internal database from the system print queue for a queue
1577 ****************************************************************************/
1579 static void print_queue_update(struct messaging_context *msg_ctx,
1580 int snum, bool force)
1584 char *lpqcommand = NULL;
1585 char *lprmcommand = NULL;
1586 uint8 *buffer = NULL;
1589 struct tdb_print_db *pdb;
1591 struct printif *current_printif;
1592 TALLOC_CTX *ctx = talloc_tos();
1594 fstrcpy( sharename, lp_const_servicename(snum));
1596 /* don't strip out characters like '$' from the printername */
1598 lpqcommand = talloc_string_sub2(ctx,
1599 lp_lpqcommand(snum),
1601 lp_printername(snum),
1602 false, false, false);
1606 lpqcommand = talloc_sub_advanced(ctx,
1607 lp_servicename(snum),
1608 current_user_info.unix_name,
1610 current_user.ut.gid,
1611 get_current_username(),
1612 current_user_info.domain,
1618 lprmcommand = talloc_string_sub2(ctx,
1619 lp_lprmcommand(snum),
1621 lp_printername(snum),
1622 false, false, false);
1626 lprmcommand = talloc_sub_advanced(ctx,
1627 lp_servicename(snum),
1628 current_user_info.unix_name,
1630 current_user.ut.gid,
1631 get_current_username(),
1632 current_user_info.domain,
1639 * Make sure that the background queue process exists.
1640 * Otherwise just do the update ourselves
1643 if ( force || background_lpq_updater_pid == -1 ) {
1644 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1645 current_printif = get_printer_fns( snum );
1646 print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand );
1651 type = lp_printing(snum);
1653 /* get the length */
1655 len = tdb_pack( NULL, 0, "fdPP",
1661 buffer = SMB_XMALLOC_ARRAY( uint8, len );
1663 /* now pack the buffer */
1664 newlen = tdb_pack( buffer, len, "fdPP",
1670 SMB_ASSERT( newlen == len );
1672 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1673 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1674 sharename, type, lpqcommand, lprmcommand ));
1676 /* here we set a msg pending record for other smbd processes
1677 to throttle the number of duplicate print_queue_update msgs
1680 pdb = get_print_db_byname(sharename);
1686 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1688 if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1689 /* log a message but continue on */
1691 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1695 release_print_db( pdb );
1697 /* finally send the message */
1699 messaging_send_buf(msg_ctx, pid_to_procid(background_lpq_updater_pid),
1700 MSG_PRINTER_UPDATE, (uint8 *)buffer, len);
1702 SAFE_FREE( buffer );
1707 /****************************************************************************
1708 Create/Update an entry in the print tdb that will allow us to send notify
1709 updates only to interested smbd's.
1710 ****************************************************************************/
1712 bool print_notify_register_pid(int snum)
1715 struct tdb_print_db *pdb = NULL;
1716 TDB_CONTEXT *tdb = NULL;
1717 const char *printername;
1718 uint32 mypid = (uint32)sys_getpid();
1722 /* if (snum == -1), then the change notify request was
1723 on a print server handle and we need to register on
1728 int num_services = lp_numservices();
1731 for ( idx=0; idx<num_services; idx++ ) {
1732 if (lp_snum_ok(idx) && lp_print_ok(idx) )
1733 print_notify_register_pid(idx);
1738 else /* register for a specific printer */
1740 printername = lp_const_servicename(snum);
1741 pdb = get_print_db_byname(printername);
1747 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1748 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1751 release_print_db(pdb);
1755 data = get_printer_notify_pid_list( tdb, printername, True );
1757 /* Add ourselves and increase the refcount. */
1759 for (i = 0; i < data.dsize; i += 8) {
1760 if (IVAL(data.dptr,i) == mypid) {
1761 uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1762 SIVAL(data.dptr, i+4, new_refcount);
1767 if (i == data.dsize) {
1768 /* We weren't in the list. Realloc. */
1769 data.dptr = (uint8 *)SMB_REALLOC(data.dptr, data.dsize + 8);
1771 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1776 SIVAL(data.dptr,data.dsize - 8,mypid);
1777 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1780 /* Store back the record. */
1781 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1782 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1783 list for printer %s\n", printername));
1791 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1793 release_print_db(pdb);
1794 SAFE_FREE(data.dptr);
1798 /****************************************************************************
1799 Update an entry in the print tdb that will allow us to send notify
1800 updates only to interested smbd's.
1801 ****************************************************************************/
1803 bool print_notify_deregister_pid(int snum)
1806 struct tdb_print_db *pdb = NULL;
1807 TDB_CONTEXT *tdb = NULL;
1808 const char *printername;
1809 uint32 mypid = (uint32)sys_getpid();
1813 /* if ( snum == -1 ), we are deregister a print server handle
1814 which means to deregister on all print queues */
1818 int num_services = lp_numservices();
1821 for ( idx=0; idx<num_services; idx++ ) {
1822 if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1823 print_notify_deregister_pid(idx);
1828 else /* deregister a specific printer */
1830 printername = lp_const_servicename(snum);
1831 pdb = get_print_db_byname(printername);
1837 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1838 DEBUG(0,("print_notify_register_pid: Failed to lock \
1839 printer %s database\n", printername));
1841 release_print_db(pdb);
1845 data = get_printer_notify_pid_list( tdb, printername, True );
1847 /* Reduce refcount. Remove ourselves if zero. */
1849 for (i = 0; i < data.dsize; ) {
1850 if (IVAL(data.dptr,i) == mypid) {
1851 uint32 refcount = IVAL(data.dptr, i+4);
1855 if (refcount == 0) {
1856 if (data.dsize - i > 8)
1857 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1861 SIVAL(data.dptr, i+4, refcount);
1867 if (data.dsize == 0)
1868 SAFE_FREE(data.dptr);
1870 /* Store back the record. */
1871 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1872 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1873 list for printer %s\n", printername));
1881 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1883 release_print_db(pdb);
1884 SAFE_FREE(data.dptr);
1888 /****************************************************************************
1889 Check if a jobid is valid. It is valid if it exists in the database.
1890 ****************************************************************************/
1892 bool print_job_exists(const char* sharename, uint32 jobid)
1894 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1900 ret = tdb_exists(pdb->tdb, print_key(jobid, &tmp));
1901 release_print_db(pdb);
1905 /****************************************************************************
1906 Give the filename used for a jobid.
1907 Only valid for the process doing the spooling and when the job
1908 has not been spooled.
1909 ****************************************************************************/
1911 char *print_job_fname(const char* sharename, uint32 jobid)
1913 struct printjob *pjob = print_job_find(sharename, jobid);
1914 if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
1916 return pjob->filename;
1920 /****************************************************************************
1921 Give the filename used for a jobid.
1922 Only valid for the process doing the spooling and when the job
1923 has not been spooled.
1924 ****************************************************************************/
1926 struct spoolss_DeviceMode *print_job_devmode(const char* sharename, uint32 jobid)
1928 struct printjob *pjob = print_job_find(sharename, jobid);
1933 return pjob->devmode;
1936 /****************************************************************************
1937 Set the name of a job. Only possible for owner.
1938 ****************************************************************************/
1940 bool print_job_set_name(const char *sharename, uint32 jobid, const char *name)
1942 struct printjob *pjob;
1944 pjob = print_job_find(sharename, jobid);
1945 if (!pjob || pjob->pid != sys_getpid())
1948 fstrcpy(pjob->jobname, name);
1949 return pjob_store(sharename, jobid, pjob);
1952 /****************************************************************************
1953 Get the name of a job. Only possible for owner.
1954 ****************************************************************************/
1956 bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t jobid, char **name)
1958 struct printjob *pjob;
1960 pjob = print_job_find(sharename, jobid);
1961 if (!pjob || pjob->pid != sys_getpid()) {
1965 *name = talloc_strdup(mem_ctx, pjob->jobname);
1974 /***************************************************************************
1975 Remove a jobid from the 'jobs changed' list.
1976 ***************************************************************************/
1978 static bool remove_from_jobs_changed(const char* sharename, uint32 jobid)
1980 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1982 size_t job_count, i;
1984 bool gotlock = False;
1992 key = string_tdb_data("INFO/jobs_changed");
1994 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
1999 data = tdb_fetch(pdb->tdb, key);
2001 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
2004 job_count = data.dsize / 4;
2005 for (i = 0; i < job_count; i++) {
2008 ch_jobid = IVAL(data.dptr, i*4);
2009 if (ch_jobid == jobid) {
2010 if (i < job_count -1 )
2011 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
2013 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
2023 tdb_chainunlock(pdb->tdb, key);
2024 SAFE_FREE(data.dptr);
2025 release_print_db(pdb);
2027 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
2029 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
2033 /****************************************************************************
2034 Delete a print job - don't update queue.
2035 ****************************************************************************/
2037 static bool print_job_delete1(int snum, uint32 jobid)
2039 const char* sharename = lp_const_servicename(snum);
2040 struct printjob *pjob = print_job_find(sharename, jobid);
2042 struct printif *current_printif = get_printer_fns( snum );
2048 * If already deleting just return.
2051 if (pjob->status == LPQ_DELETING)
2054 /* Hrm - we need to be able to cope with deleting a job before it
2055 has reached the spooler. Just mark it as LPQ_DELETING and
2056 let the print_queue_update() code rmeove the record */
2059 if (pjob->sysjob == -1) {
2060 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
2063 /* Set the tdb entry to be deleting. */
2065 pjob->status = LPQ_DELETING;
2066 pjob_store(sharename, jobid, pjob);
2068 if (pjob->spooled && pjob->sysjob != -1)
2070 result = (*(current_printif->job_delete))(
2071 lp_printername(snum),
2072 lp_lprmcommand(snum),
2075 /* Delete the tdb entry if the delete succeeded or the job hasn't
2079 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2084 pjob_delete(sharename, jobid);
2085 /* Ensure we keep a rough count of the number of total jobs... */
2086 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
2087 release_print_db(pdb);
2091 remove_from_jobs_changed( sharename, jobid );
2093 return (result == 0);
2096 /****************************************************************************
2097 Return true if the current user owns the print job.
2098 ****************************************************************************/
2100 static bool is_owner(struct auth_serversupplied_info *server_info,
2101 const char *servicename,
2104 struct printjob *pjob = print_job_find(servicename, jobid);
2106 if (!pjob || !server_info)
2109 return strequal(pjob->user, server_info->sanitized_username);
2112 /****************************************************************************
2114 ****************************************************************************/
2116 WERROR print_job_delete(struct auth_serversupplied_info *server_info,
2117 struct messaging_context *msg_ctx,
2118 int snum, uint32_t jobid)
2120 const char* sharename = lp_const_servicename(snum);
2121 struct printjob *pjob;
2125 owner = is_owner(server_info, lp_const_servicename(snum), jobid);
2127 /* Check access against security descriptor or whether the user
2131 !print_access_check(server_info, msg_ctx, snum,
2132 JOB_ACCESS_ADMINISTER)) {
2133 DEBUG(3, ("delete denied by security descriptor\n"));
2135 /* BEGIN_ADMIN_LOG */
2136 sys_adminlog( LOG_ERR,
2137 "Permission denied-- user not allowed to delete, \
2138 pause, or resume print job. User name: %s. Printer name: %s.",
2139 uidtoname(server_info->utok.uid),
2140 lp_printername(snum) );
2143 return WERR_ACCESS_DENIED;
2147 * get the spooled filename of the print job
2148 * if this works, then the file has not been spooled
2149 * to the underlying print system. Just delete the
2150 * spool file & return.
2153 fname = print_job_fname(sharename, jobid);
2154 if (fname != NULL) {
2155 /* remove the spool file */
2156 DEBUG(10, ("print_job_delete: "
2157 "Removing spool file [%s]\n", fname));
2158 if (unlink(fname) == -1) {
2159 return map_werror_from_unix(errno);
2163 if (!print_job_delete1(snum, jobid)) {
2164 return WERR_ACCESS_DENIED;
2167 /* force update the database and say the delete failed if the
2170 print_queue_update(msg_ctx, snum, True);
2172 pjob = print_job_find(sharename, jobid);
2173 if (pjob && (pjob->status != LPQ_DELETING)) {
2174 return WERR_ACCESS_DENIED;
2177 return WERR_PRINTER_HAS_JOBS_QUEUED;
2180 /****************************************************************************
2182 ****************************************************************************/
2184 bool print_job_pause(struct auth_serversupplied_info *server_info,
2185 struct messaging_context *msg_ctx,
2186 int snum, uint32 jobid, WERROR *errcode)
2188 const char* sharename = lp_const_servicename(snum);
2189 struct printjob *pjob;
2191 struct printif *current_printif = get_printer_fns( snum );
2193 pjob = print_job_find(sharename, jobid);
2195 if (!pjob || !server_info) {
2196 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2197 (unsigned int)jobid ));
2201 if (!pjob->spooled || pjob->sysjob == -1) {
2202 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2203 (int)pjob->sysjob, (unsigned int)jobid ));
2207 if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2208 !print_access_check(server_info, msg_ctx, snum,
2209 JOB_ACCESS_ADMINISTER)) {
2210 DEBUG(3, ("pause denied by security descriptor\n"));
2212 /* BEGIN_ADMIN_LOG */
2213 sys_adminlog( LOG_ERR,
2214 "Permission denied-- user not allowed to delete, \
2215 pause, or resume print job. User name: %s. Printer name: %s.",
2216 uidtoname(server_info->utok.uid),
2217 lp_printername(snum) );
2220 *errcode = WERR_ACCESS_DENIED;
2224 /* need to pause the spooled entry */
2225 ret = (*(current_printif->job_pause))(snum, pjob);
2228 *errcode = WERR_INVALID_PARAM;
2232 /* force update the database */
2233 print_cache_flush(lp_const_servicename(snum));
2235 /* Send a printer notify message */
2237 notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2240 /* how do we tell if this succeeded? */
2245 /****************************************************************************
2247 ****************************************************************************/
2249 bool print_job_resume(struct auth_serversupplied_info *server_info,
2250 struct messaging_context *msg_ctx,
2251 int snum, uint32 jobid, WERROR *errcode)
2253 const char *sharename = lp_const_servicename(snum);
2254 struct printjob *pjob;
2256 struct printif *current_printif = get_printer_fns( snum );
2258 pjob = print_job_find(sharename, jobid);
2260 if (!pjob || !server_info) {
2261 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2262 (unsigned int)jobid ));
2266 if (!pjob->spooled || pjob->sysjob == -1) {
2267 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2268 (int)pjob->sysjob, (unsigned int)jobid ));
2272 if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2273 !print_access_check(server_info, msg_ctx, snum,
2274 JOB_ACCESS_ADMINISTER)) {
2275 DEBUG(3, ("resume denied by security descriptor\n"));
2276 *errcode = WERR_ACCESS_DENIED;
2278 /* BEGIN_ADMIN_LOG */
2279 sys_adminlog( LOG_ERR,
2280 "Permission denied-- user not allowed to delete, \
2281 pause, or resume print job. User name: %s. Printer name: %s.",
2282 uidtoname(server_info->utok.uid),
2283 lp_printername(snum) );
2288 ret = (*(current_printif->job_resume))(snum, pjob);
2291 *errcode = WERR_INVALID_PARAM;
2295 /* force update the database */
2296 print_cache_flush(lp_const_servicename(snum));
2298 /* Send a printer notify message */
2300 notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2306 /****************************************************************************
2307 Write to a print file.
2308 ****************************************************************************/
2310 ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size)
2312 const char* sharename = lp_const_servicename(snum);
2313 ssize_t return_code;
2314 struct printjob *pjob;
2316 pjob = print_job_find(sharename, jobid);
2320 /* don't allow another process to get this info - it is meaningless */
2321 if (pjob->pid != sys_getpid())
2324 /* if SMBD is spooling this can't be allowed */
2325 if (pjob->status == PJOB_SMBD_SPOOLING) {
2329 return_code = write_data_at_offset(pjob->fd, buf, size, pos);
2331 if (return_code>0) {
2333 pjob_store(sharename, jobid, pjob);
2338 /****************************************************************************
2339 Get the queue status - do not update if db is out of date.
2340 ****************************************************************************/
2342 static int get_queue_status(const char* sharename, print_status_struct *status)
2346 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2350 ZERO_STRUCTP(status);
2357 fstr_sprintf(keystr, "STATUS/%s", sharename);
2358 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2360 if (data.dsize == sizeof(print_status_struct))
2361 /* this memcpy is ok since the status struct was
2362 not packed before storing it in the tdb */
2363 memcpy(status, data.dptr, sizeof(print_status_struct));
2364 SAFE_FREE(data.dptr);
2367 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2368 release_print_db(pdb);
2369 return (len == -1 ? 0 : len);
2372 /****************************************************************************
2373 Determine the number of jobs in a queue.
2374 ****************************************************************************/
2376 int print_queue_length(struct messaging_context *msg_ctx, int snum,
2377 print_status_struct *pstatus)
2379 const char* sharename = lp_const_servicename( snum );
2380 print_status_struct status;
2383 ZERO_STRUCT( status );
2385 /* make sure the database is up to date */
2386 if (print_cache_expired(lp_const_servicename(snum), True))
2387 print_queue_update(msg_ctx, snum, False);
2389 /* also fetch the queue status */
2390 memset(&status, 0, sizeof(status));
2391 len = get_queue_status(sharename, &status);
2399 /***************************************************************************
2400 Allocate a jobid. Hold the lock for as short a time as possible.
2401 ***************************************************************************/
2403 static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum,
2404 const char *sharename, uint32 *pjobid)
2408 enum TDB_ERROR terr;
2411 *pjobid = (uint32)-1;
2413 for (i = 0; i < 3; i++) {
2414 /* Lock the database - only wait 20 seconds. */
2415 ret = tdb_lock_bystring_with_timeout(pdb->tdb,
2416 "INFO/nextjob", 20);
2418 DEBUG(0, ("allocate_print_jobid: "
2419 "Failed to lock printing database %s\n",
2421 terr = tdb_error(pdb->tdb);
2422 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2425 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2426 terr = tdb_error(pdb->tdb);
2427 if (terr != TDB_ERR_NOEXIST) {
2428 DEBUG(0, ("allocate_print_jobid: "
2429 "Failed to fetch INFO/nextjob "
2430 "for print queue %s\n", sharename));
2431 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2432 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2434 DEBUG(10, ("allocate_print_jobid: "
2435 "No existing jobid in %s\n", sharename));
2439 DEBUG(10, ("allocate_print_jobid: "
2440 "Read jobid %u from %s\n", jobid, sharename));
2442 jobid = NEXT_JOBID(jobid);
2444 ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid);
2446 terr = tdb_error(pdb->tdb);
2447 DEBUG(3, ("allocate_print_jobid: "
2448 "Failed to store INFO/nextjob.\n"));
2449 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2450 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2453 /* We've finished with the INFO/nextjob lock. */
2454 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2456 if (!print_job_exists(sharename, jobid)) {
2459 DEBUG(10, ("allocate_print_jobid: "
2460 "Found jobid %u in %s\n", jobid, sharename));
2464 DEBUG(0, ("allocate_print_jobid: "
2465 "Failed to allocate a print job for queue %s\n",
2467 /* Probably full... */
2468 return WERR_NO_SPOOL_SPACE;
2471 /* Store a dummy placeholder. */
2477 if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
2478 TDB_INSERT) == -1) {
2479 DEBUG(3, ("allocate_print_jobid: "
2480 "jobid (%d) failed to store placeholder.\n",
2482 terr = tdb_error(pdb->tdb);
2483 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2491 /***************************************************************************
2492 Append a jobid to the 'jobs changed' list.
2493 ***************************************************************************/
2495 static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
2500 SIVAL(&store_jobid, 0, jobid);
2501 data.dptr = (uint8 *)&store_jobid;
2504 DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
2506 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
2511 /***************************************************************************
2512 Do all checks needed to determine if we can start a job.
2513 ***************************************************************************/
2515 static WERROR print_job_checks(struct auth_serversupplied_info *server_info,
2516 struct messaging_context *msg_ctx,
2517 int snum, int *njobs)
2519 const char *sharename = lp_const_servicename(snum);
2520 uint64_t dspace, dsize;
2524 if (!print_access_check(server_info, msg_ctx, snum,
2525 PRINTER_ACCESS_USE)) {
2526 DEBUG(3, ("print_job_checks: "
2527 "job start denied by security descriptor\n"));
2528 return WERR_ACCESS_DENIED;
2531 if (!print_time_access_check(server_info, msg_ctx, sharename)) {
2532 DEBUG(3, ("print_job_checks: "
2533 "job start denied by time check\n"));
2534 return WERR_ACCESS_DENIED;
2537 /* see if we have sufficient disk space */
2538 if (lp_minprintspace(snum)) {
2539 minspace = lp_minprintspace(snum);
2540 ret = sys_fsusage(lp_pathname(snum), &dspace, &dsize);
2541 if (ret == 0 && dspace < 2*minspace) {
2542 DEBUG(3, ("print_job_checks: "
2543 "disk space check failed.\n"));
2544 return WERR_NO_SPOOL_SPACE;
2548 /* for autoloaded printers, check that the printcap entry still exists */
2549 if (lp_autoloaded(snum) && !pcap_printername_ok(sharename)) {
2550 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2552 return WERR_ACCESS_DENIED;
2555 /* Insure the maximum queue size is not violated */
2556 *njobs = print_queue_length(msg_ctx, snum, NULL);
2557 if (*njobs > lp_maxprintjobs(snum)) {
2558 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2559 "larger than max printjobs per queue (%d).\n",
2560 sharename, *njobs, lp_maxprintjobs(snum)));
2561 return WERR_NO_SPOOL_SPACE;
2567 /***************************************************************************
2569 ***************************************************************************/
2571 static WERROR print_job_spool_file(int snum, uint32_t jobid,
2572 const char *output_file,
2573 struct printjob *pjob)
2580 /* if this file is within the printer path, it means that smbd
2581 * is spooling it and will pass us control when it is finished.
2582 * Verify that the file name is ok, within path, and it is
2583 * already already there */
2585 path = lp_pathname(snum);
2587 if (strncmp(output_file, path, len) == 0 &&
2588 (output_file[len - 1] == '/' || output_file[len] == '/')) {
2590 /* verify path is not too long */
2591 if (strlen(output_file) >= sizeof(pjob->filename)) {
2592 return WERR_INVALID_NAME;
2595 /* verify that the file exists */
2596 if (sys_stat(output_file, &st, false) != 0) {
2597 return WERR_INVALID_NAME;
2600 fstrcpy(pjob->filename, output_file);
2602 DEBUG(3, ("print_job_spool_file:"
2603 "External spooling activated"));
2605 /* we do not open the file until spooling is done */
2607 pjob->status = PJOB_SMBD_SPOOLING;
2613 slprintf(pjob->filename, sizeof(pjob->filename)-1,
2614 "%s/%s%.8u.XXXXXX", lp_pathname(snum),
2615 PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2616 pjob->fd = mkstemp(pjob->filename);
2618 if (pjob->fd == -1) {
2619 werr = map_werror_from_unix(errno);
2620 if (W_ERROR_EQUAL(werr, WERR_ACCESS_DENIED)) {
2621 /* Common setup error, force a report. */
2622 DEBUG(0, ("print_job_spool_file: "
2623 "insufficient permissions to open spool "
2624 "file %s.\n", pjob->filename));
2626 /* Normal case, report at level 3 and above. */
2627 DEBUG(3, ("print_job_spool_file: "
2628 "can't open spool file %s\n",
2637 /***************************************************************************
2638 Start spooling a job - return the jobid.
2639 ***************************************************************************/
2641 WERROR print_job_start(struct auth_serversupplied_info *server_info,
2642 struct messaging_context *msg_ctx,
2643 int snum, const char *docname, const char *filename,
2644 struct spoolss_DeviceMode *devmode, uint32_t *_jobid)
2648 struct printjob pjob;
2649 const char *sharename = lp_const_servicename(snum);
2650 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2655 return WERR_INTERNAL_DB_CORRUPTION;
2658 path = lp_pathname(snum);
2660 werr = print_job_checks(server_info, msg_ctx, snum, &njobs);
2661 if (!W_ERROR_IS_OK(werr)) {
2662 release_print_db(pdb);
2666 DEBUG(10, ("print_job_start: "
2667 "Queue %s number of jobs (%d), max printjobs = %d\n",
2668 sharename, njobs, lp_maxprintjobs(snum)));
2670 werr = allocate_print_jobid(pdb, snum, sharename, &jobid);
2671 if (!W_ERROR_IS_OK(werr)) {
2675 /* create the database entry */
2679 pjob.pid = sys_getpid();
2682 pjob.starttime = time(NULL);
2683 pjob.status = LPQ_SPOOLING;
2685 pjob.spooled = False;
2687 pjob.devmode = devmode;
2689 fstrcpy(pjob.jobname, docname);
2691 fstrcpy(pjob.user, lp_printjob_username(snum));
2692 standard_sub_advanced(sharename, server_info->sanitized_username,
2693 path, server_info->utok.gid,
2694 server_info->sanitized_username,
2695 server_info->info3->base.domain.string,
2696 pjob.user, sizeof(pjob.user)-1);
2697 /* ensure NULL termination */
2698 pjob.user[sizeof(pjob.user)-1] = '\0';
2700 fstrcpy(pjob.queuename, lp_const_servicename(snum));
2702 /* we have a job entry - now create the spool file */
2703 werr = print_job_spool_file(snum, jobid, filename, &pjob);
2704 if (!W_ERROR_IS_OK(werr)) {
2708 pjob_store(sharename, jobid, &pjob);
2710 /* Update the 'jobs changed' entry used by print_queue_status. */
2711 add_to_jobs_changed(pdb, jobid);
2713 /* Ensure we keep a rough count of the number of total jobs... */
2714 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2716 release_print_db(pdb);
2723 pjob_delete(sharename, jobid);
2726 release_print_db(pdb);
2728 DEBUG(3, ("print_job_start: returning fail. "
2729 "Error = %s\n", win_errstr(werr)));
2733 /****************************************************************************
2734 Update the number of pages spooled to jobid
2735 ****************************************************************************/
2737 void print_job_endpage(int snum, uint32 jobid)
2739 const char* sharename = lp_const_servicename(snum);
2740 struct printjob *pjob;
2742 pjob = print_job_find(sharename, jobid);
2745 /* don't allow another process to get this info - it is meaningless */
2746 if (pjob->pid != sys_getpid())
2750 pjob_store(sharename, jobid, pjob);
2753 /****************************************************************************
2754 Print a file - called on closing the file. This spools the job.
2755 If normal close is false then we're tearing down the jobs - treat as an
2757 ****************************************************************************/
2759 NTSTATUS print_job_end(struct messaging_context *msg_ctx, int snum,
2760 uint32 jobid, enum file_close_type close_type)
2762 const char* sharename = lp_const_servicename(snum);
2763 struct printjob *pjob;
2765 SMB_STRUCT_STAT sbuf;
2766 struct printif *current_printif = get_printer_fns( snum );
2767 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2769 pjob = print_job_find(sharename, jobid);
2772 return NT_STATUS_PRINT_CANCELLED;
2775 if (pjob->spooled || pjob->pid != sys_getpid()) {
2776 return NT_STATUS_ACCESS_DENIED;
2779 if (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) {
2780 if (pjob->status == PJOB_SMBD_SPOOLING) {
2781 /* take over the file now, smbd is done */
2782 if (sys_stat(pjob->filename, &sbuf, false) != 0) {
2783 status = map_nt_error_from_unix(errno);
2784 DEBUG(3, ("print_job_end: "
2785 "stat file failed for jobid %d\n",
2790 pjob->status = LPQ_SPOOLING;
2794 if ((sys_fstat(pjob->fd, &sbuf, false) != 0)) {
2795 status = map_nt_error_from_unix(errno);
2797 DEBUG(3, ("print_job_end: "
2798 "stat file failed for jobid %d\n",
2806 pjob->size = sbuf.st_ex_size;
2810 * Not a normal close, something has gone wrong. Cleanup.
2812 if (pjob->fd != -1) {
2818 /* Technically, this is not quite right. If the printer has a separator
2819 * page turned on, the NT spooler prints the separator page even if the
2820 * print job is 0 bytes. 010215 JRR */
2821 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2822 /* don't bother spooling empty files or something being deleted. */
2823 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2824 pjob->filename, pjob->size ? "deleted" : "zero length" ));
2825 unlink(pjob->filename);
2826 pjob_delete(sharename, jobid);
2827 return NT_STATUS_OK;
2830 ret = (*(current_printif->job_submit))(snum, pjob);
2833 status = NT_STATUS_PRINT_CANCELLED;
2837 /* The print job has been successfully handed over to the back-end */
2839 pjob->spooled = True;
2840 pjob->status = LPQ_QUEUED;
2841 pjob_store(sharename, jobid, pjob);
2843 /* make sure the database is up to date */
2844 if (print_cache_expired(lp_const_servicename(snum), True))
2845 print_queue_update(msg_ctx, snum, False);
2847 return NT_STATUS_OK;
2851 /* The print job was not successfully started. Cleanup */
2852 /* Still need to add proper error return propagation! 010122:JRR */
2854 unlink(pjob->filename);
2855 pjob_delete(sharename, jobid);
2859 /****************************************************************************
2860 Get a snapshot of jobs in the system without traversing.
2861 ****************************************************************************/
2863 static bool get_stored_queue_info(struct messaging_context *msg_ctx,
2864 struct tdb_print_db *pdb, int snum,
2865 int *pcount, print_queue_struct **ppqueue)
2867 TDB_DATA data, cgdata;
2868 print_queue_struct *queue = NULL;
2870 uint32 extra_count = 0;
2871 int total_count = 0;
2874 int max_reported_jobs = lp_max_reported_jobs(snum);
2876 const char* sharename = lp_servicename(snum);
2878 /* make sure the database is up to date */
2879 if (print_cache_expired(lp_const_servicename(snum), True))
2880 print_queue_update(msg_ctx, snum, False);
2886 ZERO_STRUCT(cgdata);
2888 /* Get the stored queue data. */
2889 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
2891 if (data.dptr && data.dsize >= sizeof(qcount))
2892 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2894 /* Get the changed jobs list. */
2895 cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
2896 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2897 extra_count = cgdata.dsize/4;
2899 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2901 /* Allocate the queue size. */
2902 if (qcount == 0 && extra_count == 0)
2905 if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
2908 /* Retrieve the linearised queue data. */
2910 for( i = 0; i < qcount; i++) {
2911 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2912 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2921 queue[i].job = qjob;
2922 queue[i].size = qsize;
2923 queue[i].page_count = qpage_count;
2924 queue[i].status = qstatus;
2925 queue[i].priority = qpriority;
2926 queue[i].time = qtime;
2929 total_count = qcount;
2931 /* Add in the changed jobids. */
2932 for( i = 0; i < extra_count; i++) {
2934 struct printjob *pjob;
2936 jobid = IVAL(cgdata.dptr, i*4);
2937 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2938 pjob = print_job_find(lp_const_servicename(snum), jobid);
2940 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2941 remove_from_jobs_changed(sharename, jobid);
2945 queue[total_count].job = jobid;
2946 queue[total_count].size = pjob->size;
2947 queue[total_count].page_count = pjob->page_count;
2948 queue[total_count].status = pjob->status;
2949 queue[total_count].priority = 1;
2950 queue[total_count].time = pjob->starttime;
2951 fstrcpy(queue[total_count].fs_user, pjob->user);
2952 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2956 /* Sort the queue by submission time otherwise they are displayed
2959 TYPESAFE_QSORT(queue, total_count, printjob_comp);
2961 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2963 if (max_reported_jobs && total_count > max_reported_jobs)
2964 total_count = max_reported_jobs;
2967 *pcount = total_count;
2973 SAFE_FREE(data.dptr);
2974 SAFE_FREE(cgdata.dptr);
2978 /****************************************************************************
2979 Get a printer queue listing.
2980 set queue = NULL and status = NULL if you just want to update the cache
2981 ****************************************************************************/
2983 int print_queue_status(struct messaging_context *msg_ctx, int snum,
2984 print_queue_struct **ppqueue,
2985 print_status_struct *status)
2989 const char *sharename;
2990 struct tdb_print_db *pdb;
2993 /* make sure the database is up to date */
2995 if (print_cache_expired(lp_const_servicename(snum), True))
2996 print_queue_update(msg_ctx, snum, False);
2998 /* return if we are done */
2999 if ( !ppqueue || !status )
3003 sharename = lp_const_servicename(snum);
3004 pdb = get_print_db_byname(sharename);
3010 * Fetch the queue status. We must do this first, as there may
3011 * be no jobs in the queue.
3014 ZERO_STRUCTP(status);
3015 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
3016 key = string_tdb_data(keystr);
3018 data = tdb_fetch(pdb->tdb, key);
3020 if (data.dsize == sizeof(*status)) {
3021 /* this memcpy is ok since the status struct was
3022 not packed before storing it in the tdb */
3023 memcpy(status, data.dptr, sizeof(*status));
3025 SAFE_FREE(data.dptr);
3029 * Now, fetch the print queue information. We first count the number
3030 * of entries, and then only retrieve the queue if necessary.
3033 if (!get_stored_queue_info(msg_ctx, pdb, snum, &count, ppqueue)) {
3034 release_print_db(pdb);
3038 release_print_db(pdb);
3042 /****************************************************************************
3044 ****************************************************************************/
3046 WERROR print_queue_pause(struct auth_serversupplied_info *server_info,
3047 struct messaging_context *msg_ctx, int snum)
3050 struct printif *current_printif = get_printer_fns( snum );
3052 if (!print_access_check(server_info, msg_ctx, snum,
3053 PRINTER_ACCESS_ADMINISTER)) {
3054 return WERR_ACCESS_DENIED;
3060 ret = (*(current_printif->queue_pause))(snum);
3065 return WERR_INVALID_PARAM;
3068 /* force update the database */
3069 print_cache_flush(lp_const_servicename(snum));
3071 /* Send a printer notify message */
3073 notify_printer_status(server_event_context(), msg_ctx, snum,
3074 PRINTER_STATUS_PAUSED);
3079 /****************************************************************************
3081 ****************************************************************************/
3083 WERROR print_queue_resume(struct auth_serversupplied_info *server_info,
3084 struct messaging_context *msg_ctx, int snum)
3087 struct printif *current_printif = get_printer_fns( snum );
3089 if (!print_access_check(server_info, msg_ctx, snum,
3090 PRINTER_ACCESS_ADMINISTER)) {
3091 return WERR_ACCESS_DENIED;
3096 ret = (*(current_printif->queue_resume))(snum);
3101 return WERR_INVALID_PARAM;
3104 /* make sure the database is up to date */
3105 if (print_cache_expired(lp_const_servicename(snum), True))
3106 print_queue_update(msg_ctx, snum, True);
3108 /* Send a printer notify message */
3110 notify_printer_status(server_event_context(), msg_ctx, snum,
3116 /****************************************************************************
3117 Purge a queue - implemented by deleting all jobs that we can delete.
3118 ****************************************************************************/
3120 WERROR print_queue_purge(struct auth_serversupplied_info *server_info,
3121 struct messaging_context *msg_ctx, int snum)
3123 print_queue_struct *queue;
3124 print_status_struct status;
3128 /* Force and update so the count is accurate (i.e. not a cached count) */
3129 print_queue_update(msg_ctx, snum, True);
3131 can_job_admin = print_access_check(server_info,
3134 JOB_ACCESS_ADMINISTER);
3135 njobs = print_queue_status(msg_ctx, snum, &queue, &status);
3137 if ( can_job_admin )
3140 for (i=0;i<njobs;i++) {
3141 bool owner = is_owner(server_info, lp_const_servicename(snum),
3144 if (owner || can_job_admin) {
3145 print_job_delete1(snum, queue[i].job);
3149 if ( can_job_admin )
3152 /* update the cache */
3153 print_queue_update(msg_ctx, snum, True);