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/>.
23 #include "system/syslog.h"
24 #include "system/filesys.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"
32 #include "smbd/smbd.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 {
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)
73 struct rap_jobid_key jinfo;
76 DEBUG(10,("pjobid_to_rap: called.\n"));
79 /* Create the in-memory tdb. */
80 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
86 fstrcpy( jinfo.sharename, sharename );
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);
95 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
96 (unsigned int)jobid, (unsigned int)rap_jobid));
100 /* Not found - create and store mapping. */
101 rap_jobid = ++next_rap_jobid;
103 rap_jobid = ++next_rap_jobid;
104 SSVAL(buf,0,rap_jobid);
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));
115 bool rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
120 DEBUG(10,("rap_to_pjobid called.\n"));
125 SSVAL(buf,0,rap_jobid);
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);
142 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
143 (unsigned int)rap_jobid));
144 SAFE_FREE(data.dptr);
148 void rap_jobid_delete(const char* sharename, uint32 jobid)
152 struct rap_jobid_key jinfo;
155 DEBUG(10,("rap_jobid_delete: called.\n"));
160 ZERO_STRUCT( jinfo );
161 fstrcpy( jinfo.sharename, sharename );
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);
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);
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();
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))
208 pdb = get_print_db_byname(lp_const_servicename(snum));
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);
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'
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;
253 if ( type == PRINT_CUPS ) {
254 printer_fns = &cups_printif;
256 #endif /* HAVE_CUPS */
259 if ( type == PRINT_IPRINT ) {
260 printer_fns = &iprint_printif;
262 #endif /* HAVE_IPRINT */
264 printer_fns->type = type;
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)
283 SIVAL(tmp, 0, jobid);
284 ret.dptr = (uint8 *)tmp;
285 ret.dsize = sizeof(*tmp);
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;
299 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(),
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"));
312 len = tdb_pack(buf, buflen, "B", blob.length, blob.data);
315 DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname));
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;
338 len = tdb_unpack(buf, buflen, "B", &data_len, &data);
343 dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
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"));
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));
372 /***********************************************************************
373 unpack a pjob from a tdb buffer
374 ***********************************************************************/
376 static int unpack_pjob(uint8 *buf, int buflen, struct printjob *pjob)
380 uint32 pjpid, pjjobid, pjsysjob, pjfd, pjstarttime, pjstatus;
381 uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
387 len += tdb_unpack(buf+len, buflen-len, "ddddddddddfffff",
408 used = unpack_devicemode(NULL, buf+len, buflen-len, &pjob->devmode);
416 pjob->jobid = pjjobid;
417 pjob->sysjob = pjsysjob;
419 pjob->starttime = pjstarttime;
420 pjob->status = pjstatus;
422 pjob->page_count = pjpage_count;
423 pjob->spooled = pjspooled;
424 pjob->smbjob = pjsmbjob;
430 /****************************************************************************
431 Useful function to find a print job in the database.
432 ****************************************************************************/
434 static struct printjob *print_job_find(const char *sharename, uint32 jobid)
436 static struct printjob pjob;
439 struct tdb_print_db *pdb = get_print_db_byname(sharename);
441 DEBUG(10,("print_job_find: looking up job %u for share %s\n",
442 (unsigned int)jobid, sharename ));
448 ret = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
449 release_print_db(pdb);
452 DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid ));
456 talloc_free(pjob.devmode);
460 if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
461 DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid ));
468 DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
469 (int)pjob.sysjob, (unsigned int)jobid ));
470 SMB_ASSERT(pjob.jobid == jobid);
475 /* Convert a unix jobid to a smb jobid */
477 struct unixjob_traverse_state {
479 uint32 sysjob_to_jobid_value;
482 static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
483 TDB_DATA data, void *private_data)
485 struct printjob *pjob;
486 struct unixjob_traverse_state *state =
487 (struct unixjob_traverse_state *)private_data;
489 if (!data.dptr || data.dsize == 0)
492 pjob = (struct printjob *)data.dptr;
493 if (key.dsize != sizeof(uint32))
496 if (state->sysjob == pjob->sysjob) {
497 state->sysjob_to_jobid_value = pjob->jobid;
504 /****************************************************************************
505 This is a *horribly expensive call as we have to iterate through all the
506 current printer tdb's. Don't do this often ! JRA.
507 ****************************************************************************/
509 uint32 sysjob_to_jobid(int unix_jobid)
511 int services = lp_numservices();
513 struct unixjob_traverse_state state;
515 state.sysjob = unix_jobid;
516 state.sysjob_to_jobid_value = (uint32)-1;
518 for (snum = 0; snum < services; snum++) {
519 struct tdb_print_db *pdb;
520 if (!lp_print_ok(snum))
522 pdb = get_print_db_byname(lp_const_servicename(snum));
526 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &state);
527 release_print_db(pdb);
528 if (state.sysjob_to_jobid_value != (uint32)-1)
529 return state.sysjob_to_jobid_value;
534 /****************************************************************************
535 Send notifications based on what has changed after a pjob_store.
536 ****************************************************************************/
538 static const struct {
540 uint32_t spoolss_status;
541 } lpq_to_spoolss_status_map[] = {
542 { LPQ_QUEUED, JOB_STATUS_QUEUED },
543 { LPQ_PAUSED, JOB_STATUS_PAUSED },
544 { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
545 { LPQ_PRINTING, JOB_STATUS_PRINTING },
546 { LPQ_DELETING, JOB_STATUS_DELETING },
547 { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
548 { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
549 { LPQ_PRINTED, JOB_STATUS_PRINTED },
550 { LPQ_DELETED, JOB_STATUS_DELETED },
551 { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ },
552 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
556 /* Convert a lpq status value stored in printing.tdb into the
557 appropriate win32 API constant. */
559 static uint32 map_to_spoolss_status(uint32 lpq_status)
563 while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
564 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
565 return lpq_to_spoolss_status_map[i].spoolss_status;
572 /***************************************************************************
573 Append a jobid to the 'jobs changed' list.
574 ***************************************************************************/
576 static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32_t jobid)
579 uint32_t store_jobid;
581 SIVAL(&store_jobid, 0, jobid);
582 data.dptr = (uint8 *) &store_jobid;
585 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid ));
587 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
591 /***************************************************************************
592 Remove a jobid from the 'jobs changed' list.
593 ***************************************************************************/
595 static bool remove_from_jobs_changed(const char* sharename, uint32_t jobid)
597 struct tdb_print_db *pdb = get_print_db_byname(sharename);
601 bool gotlock = False;
609 key = string_tdb_data("INFO/jobs_changed");
611 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
616 data = tdb_fetch(pdb->tdb, key);
618 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
621 job_count = data.dsize / 4;
622 for (i = 0; i < job_count; i++) {
625 ch_jobid = IVAL(data.dptr, i*4);
626 if (ch_jobid == jobid) {
627 if (i < job_count -1 )
628 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
630 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
640 tdb_chainunlock(pdb->tdb, key);
641 SAFE_FREE(data.dptr);
642 release_print_db(pdb);
644 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
646 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
650 static void pjob_store_notify(struct tevent_context *ev,
651 struct messaging_context *msg_ctx,
652 const char* sharename, uint32 jobid,
653 struct printjob *old_data,
654 struct printjob *new_data,
657 bool new_job = false;
658 bool changed = false;
660 if (old_data == NULL) {
664 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
665 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
666 time first or else we'll end up with potential alignment
667 errors. I don't think the systemtime should be spooled as
668 a string, but this gets us around that error.
669 --jerry (i'll feel dirty for this) */
672 notify_job_submitted(ev, msg_ctx,
673 sharename, jobid, new_data->starttime);
674 notify_job_username(ev, msg_ctx,
675 sharename, jobid, new_data->user);
676 notify_job_name(ev, msg_ctx,
677 sharename, jobid, new_data->jobname);
678 notify_job_status(ev, msg_ctx,
679 sharename, jobid, map_to_spoolss_status(new_data->status));
680 notify_job_total_bytes(ev, msg_ctx,
681 sharename, jobid, new_data->size);
682 notify_job_total_pages(ev, msg_ctx,
683 sharename, jobid, new_data->page_count);
685 if (!strequal(old_data->jobname, new_data->jobname)) {
686 notify_job_name(ev, msg_ctx, sharename,
687 jobid, new_data->jobname);
691 if (old_data->status != new_data->status) {
692 notify_job_status(ev, msg_ctx,
694 map_to_spoolss_status(new_data->status));
697 if (old_data->size != new_data->size) {
698 notify_job_total_bytes(ev, msg_ctx,
699 sharename, jobid, new_data->size);
702 if (old_data->page_count != new_data->page_count) {
703 notify_job_total_pages(ev, msg_ctx,
705 new_data->page_count);
712 /****************************************************************************
713 Store a job structure back to the database.
714 ****************************************************************************/
716 static bool pjob_store(struct tevent_context *ev,
717 struct messaging_context *msg_ctx,
718 const char* sharename, uint32 jobid,
719 struct printjob *pjob)
722 TDB_DATA old_data, new_data;
724 struct tdb_print_db *pdb = get_print_db_byname(sharename);
726 int len, newlen, buflen;
734 old_data = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
736 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
743 len += tdb_pack(buf+len, buflen-len, "ddddddddddfffff",
746 (uint32)pjob->sysjob,
748 (uint32)pjob->starttime,
749 (uint32)pjob->status,
751 (uint32)pjob->page_count,
752 (uint32)pjob->spooled,
753 (uint32)pjob->smbjob,
760 len += pack_devicemode(pjob->devmode, buf+len, buflen-len);
763 buf = (uint8 *)SMB_REALLOC(buf, len);
765 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
770 } while ( buflen != len );
776 new_data.dsize = len;
777 ret = (tdb_store(pdb->tdb, print_key(jobid, &tmp), new_data,
780 /* Send notify updates for what has changed */
783 bool changed = false;
784 struct printjob old_pjob;
786 if ( old_data.dsize )
788 if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
790 pjob_store_notify(server_event_context(),
792 sharename, jobid, &old_pjob,
795 talloc_free(old_pjob.devmode);
798 add_to_jobs_changed(pdb, jobid);
805 pjob_store_notify(server_event_context(), msg_ctx,
806 sharename, jobid, NULL, pjob,
811 release_print_db(pdb);
813 SAFE_FREE( old_data.dptr );
819 /****************************************************************************
820 Remove a job structure from the database.
821 ****************************************************************************/
823 static void pjob_delete(struct tevent_context *ev,
824 struct messaging_context *msg_ctx,
825 const char* sharename, uint32 jobid)
828 struct printjob *pjob;
829 uint32 job_status = 0;
830 struct tdb_print_db *pdb;
832 pdb = get_print_db_byname( sharename );
837 pjob = print_job_find( sharename, jobid );
840 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
841 (unsigned int)jobid));
842 release_print_db(pdb);
846 /* We must cycle through JOB_STATUS_DELETING and
847 JOB_STATUS_DELETED for the port monitor to delete the job
850 job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
851 notify_job_status(ev, msg_ctx, sharename, jobid, job_status);
853 /* Remove from printing.tdb */
855 tdb_delete(pdb->tdb, print_key(jobid, &tmp));
856 remove_from_jobs_added(sharename, jobid);
857 release_print_db( pdb );
858 rap_jobid_delete(sharename, jobid);
861 /****************************************************************************
862 List a unix job in the print database.
863 ****************************************************************************/
865 static void print_unix_job(struct tevent_context *ev,
866 struct messaging_context *msg_ctx,
867 const char *sharename, print_queue_struct *q,
870 struct printjob pj, *old_pj;
872 if (jobid == (uint32)-1)
873 jobid = q->sysjob + UNIX_JOB_START;
875 /* Preserve the timestamp on an existing unix print job */
877 old_pj = print_job_find(sharename, jobid);
883 pj.sysjob = q->sysjob;
885 pj.starttime = old_pj ? old_pj->starttime : q->time;
886 pj.status = q->status;
889 fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
890 if (jobid < UNIX_JOB_START) {
892 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
895 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
897 fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
898 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
900 pjob_store(ev, msg_ctx, sharename, jobid, &pj);
904 struct traverse_struct {
905 print_queue_struct *queue;
906 int qcount, snum, maxcount, total_jobs;
907 const char *sharename;
909 const char *lprm_command;
910 struct printif *print_if;
911 struct tevent_context *ev;
912 struct messaging_context *msg_ctx;
915 /****************************************************************************
916 Utility fn to delete any jobs that are no longer active.
917 ****************************************************************************/
919 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
921 struct traverse_struct *ts = (struct traverse_struct *)state;
922 struct printjob pjob;
926 if ( key.dsize != sizeof(jobid) )
929 if (unpack_pjob(data.dptr, data.dsize, &pjob) == -1)
931 talloc_free(pjob.devmode);
935 /* remove a unix job if it isn't in the system queue any more */
937 for (i=0;i<ts->qcount;i++) {
938 uint32 u_jobid = (ts->queue[i].sysjob + UNIX_JOB_START);
939 if (jobid == u_jobid)
942 if (i == ts->qcount) {
943 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
944 (unsigned int)jobid ));
945 pjob_delete(ts->ev, ts->msg_ctx,
946 ts->sharename, jobid);
950 /* need to continue the the bottom of the function to
951 save the correct attributes */
954 /* maybe it hasn't been spooled yet */
956 /* if a job is not spooled and the process doesn't
957 exist then kill it. This cleans up after smbd
959 if (!process_exists_by_pid(pjob.pid)) {
960 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
961 (unsigned int)jobid, (unsigned int)pjob.pid ));
962 pjob_delete(ts->ev, ts->msg_ctx,
963 ts->sharename, jobid);
969 /* this check only makes sense for jobs submitted from Windows clients */
972 for (i=0;i<ts->qcount;i++) {
975 if ( pjob.status == LPQ_DELETED )
978 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
980 if (jobid == curr_jobid) {
982 /* try to clean up any jobs that need to be deleted */
984 if ( pjob.status == LPQ_DELETING ) {
987 result = (*(ts->print_if->job_delete))(
988 ts->sharename, ts->lprm_command, &pjob );
991 /* if we can't delete, then reset the job status */
992 pjob.status = LPQ_QUEUED;
993 pjob_store(ts->ev, ts->msg_ctx,
994 ts->sharename, jobid, &pjob);
997 /* if we deleted the job, the remove the tdb record */
1000 ts->sharename, jobid);
1001 pjob.status = LPQ_DELETED;
1011 /* The job isn't in the system queue - we have to assume it has
1012 completed, so delete the database entry. */
1014 if (i == ts->qcount) {
1016 /* A race can occur between the time a job is spooled and
1017 when it appears in the lpq output. This happens when
1018 the job is added to printing.tdb when another smbd
1019 running print_queue_update() has completed a lpq and
1020 is currently traversing the printing tdb and deleting jobs.
1021 Don't delete the job if it was submitted after the lpq_time. */
1023 if (pjob.starttime < ts->lpq_time) {
1024 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
1025 (unsigned int)jobid,
1026 (unsigned int)pjob.starttime,
1027 (unsigned int)ts->lpq_time ));
1028 pjob_delete(ts->ev, ts->msg_ctx,
1029 ts->sharename, jobid);
1035 /* Save the pjob attributes we will store.
1036 FIXME!!! This is the only place where queue->job
1037 represents the SMB jobid --jerry */
1039 ts->queue[i].sysjob = jobid;
1040 ts->queue[i].size = pjob.size;
1041 ts->queue[i].page_count = pjob.page_count;
1042 ts->queue[i].status = pjob.status;
1043 ts->queue[i].priority = 1;
1044 ts->queue[i].time = pjob.starttime;
1045 fstrcpy(ts->queue[i].fs_user, pjob.user);
1046 fstrcpy(ts->queue[i].fs_file, pjob.jobname);
1053 /****************************************************************************
1054 Check if the print queue has been updated recently enough.
1055 ****************************************************************************/
1057 static void print_cache_flush(const char *sharename)
1060 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1064 slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
1065 tdb_store_int32(pdb->tdb, key, -1);
1066 release_print_db(pdb);
1069 /****************************************************************************
1070 Check if someone already thinks they are doing the update.
1071 ****************************************************************************/
1073 static pid_t get_updating_pid(const char *sharename)
1078 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1082 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
1083 key = string_tdb_data(keystr);
1085 data = tdb_fetch(pdb->tdb, key);
1086 release_print_db(pdb);
1087 if (!data.dptr || data.dsize != sizeof(pid_t)) {
1088 SAFE_FREE(data.dptr);
1092 updating_pid = IVAL(data.dptr, 0);
1093 SAFE_FREE(data.dptr);
1095 if (process_exists_by_pid(updating_pid))
1096 return updating_pid;
1101 /****************************************************************************
1102 Set the fact that we're doing the update, or have finished doing the update
1104 ****************************************************************************/
1106 static void set_updating_pid(const fstring sharename, bool updating)
1111 pid_t updating_pid = sys_getpid();
1114 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1119 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
1120 key = string_tdb_data(keystr);
1122 DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
1123 updating ? "" : "not ",
1127 tdb_delete(pdb->tdb, key);
1128 release_print_db(pdb);
1132 SIVAL( buffer, 0, updating_pid);
1134 data.dsize = 4; /* we always assume this is a 4 byte value */
1136 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1137 release_print_db(pdb);
1140 /****************************************************************************
1141 Sort print jobs by submittal time.
1142 ****************************************************************************/
1144 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
1155 /* Sort on job start time */
1157 if (j1->time == j2->time)
1159 return (j1->time > j2->time) ? 1 : -1;
1162 /****************************************************************************
1163 Store the sorted queue representation for later portmon retrieval.
1165 ****************************************************************************/
1167 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
1170 int max_reported_jobs = lp_max_reported_jobs(pts->snum);
1171 print_queue_struct *queue = pts->queue;
1174 unsigned int qcount;
1176 if (max_reported_jobs && (max_reported_jobs < pts->qcount))
1177 pts->qcount = max_reported_jobs;
1180 /* Work out the size. */
1182 data.dsize += tdb_pack(NULL, 0, "d", qcount);
1184 for (i = 0; i < pts->qcount; i++) {
1185 if ( queue[i].status == LPQ_DELETED )
1189 data.dsize += tdb_pack(NULL, 0, "ddddddff",
1190 (uint32)queue[i].sysjob,
1191 (uint32)queue[i].size,
1192 (uint32)queue[i].page_count,
1193 (uint32)queue[i].status,
1194 (uint32)queue[i].priority,
1195 (uint32)queue[i].time,
1200 if ((data.dptr = (uint8 *)SMB_MALLOC(data.dsize)) == NULL)
1204 len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
1205 for (i = 0; i < pts->qcount; i++) {
1206 if ( queue[i].status == LPQ_DELETED )
1209 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
1210 (uint32)queue[i].sysjob,
1211 (uint32)queue[i].size,
1212 (uint32)queue[i].page_count,
1213 (uint32)queue[i].status,
1214 (uint32)queue[i].priority,
1215 (uint32)queue[i].time,
1220 tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
1222 SAFE_FREE(data.dptr);
1226 static TDB_DATA get_jobs_added_data(struct tdb_print_db *pdb)
1232 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added"));
1233 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
1234 SAFE_FREE(data.dptr);
1241 static void check_job_added(const char *sharename, TDB_DATA data, uint32 jobid)
1244 unsigned int job_count = data.dsize / 4;
1246 for (i = 0; i < job_count; i++) {
1249 ch_jobid = IVAL(data.dptr, i*4);
1250 if (ch_jobid == jobid)
1251 remove_from_jobs_added(sharename, jobid);
1255 /****************************************************************************
1256 Check if the print queue has been updated recently enough.
1257 ****************************************************************************/
1259 static bool print_cache_expired(const char *sharename, bool check_pending)
1262 time_t last_qscan_time, time_now = time(NULL);
1263 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1264 bool result = False;
1269 snprintf(key, sizeof(key), "CACHE/%s", sharename);
1270 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1273 * Invalidate the queue for 3 reasons.
1274 * (1). last queue scan time == -1.
1275 * (2). Current time - last queue scan time > allowed cache time.
1276 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1277 * This last test picks up machines for which the clock has been moved
1278 * forward, an lpq scan done and then the clock moved back. Otherwise
1279 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1282 if (last_qscan_time == ((time_t)-1)
1283 || (time_now - last_qscan_time) >= lp_lpqcachetime()
1284 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
1287 time_t msg_pending_time;
1289 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1290 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1291 sharename, (int)last_qscan_time, (int)time_now,
1292 (int)lp_lpqcachetime() ));
1294 /* check if another smbd has already sent a message to update the
1295 queue. Give the pending message one minute to clear and
1296 then send another message anyways. Make sure to check for
1297 clocks that have been run forward and then back again. */
1299 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1302 && tdb_fetch_uint32( pdb->tdb, key, &u )
1303 && (msg_pending_time=u) > 0
1304 && msg_pending_time <= time_now
1305 && (time_now - msg_pending_time) < 60 )
1307 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1316 release_print_db(pdb);
1320 /****************************************************************************
1321 main work for updating the lpq cache for a printer queue
1322 ****************************************************************************/
1324 static void print_queue_update_internal( struct tevent_context *ev,
1325 struct messaging_context *msg_ctx,
1326 const char *sharename,
1327 struct printif *current_printif,
1328 char *lpq_command, char *lprm_command )
1331 print_queue_struct *queue = NULL;
1332 print_status_struct status;
1333 print_status_struct old_status;
1334 struct printjob *pjob;
1335 struct traverse_struct tstruct;
1338 fstring keystr, cachestr;
1339 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1345 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1346 sharename, current_printif->type, lpq_command));
1349 * Update the cache time FIRST ! Stops others even
1350 * attempting to get the lock and doing this
1351 * if the lpq takes a long time.
1354 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1355 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1357 /* get the current queue using the appropriate interface */
1358 ZERO_STRUCT(status);
1360 qcount = (*(current_printif->queue_get))(sharename,
1361 current_printif->type,
1362 lpq_command, &queue, &status);
1364 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1365 qcount, (qcount != 1) ? "s" : "", sharename));
1367 /* Sort the queue by submission time otherwise they are displayed
1370 TYPESAFE_QSORT(queue, qcount, printjob_comp);
1373 any job in the internal database that is marked as spooled
1374 and doesn't exist in the system queue is considered finished
1375 and removed from the database
1377 any job in the system database but not in the internal database
1378 is added as a unix job
1380 fill in any system job numbers as we go
1383 jcdata = get_jobs_added_data(pdb);
1385 for (i=0; i<qcount; i++) {
1386 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1388 if (jobid == (uint32)-1) {
1389 /* assume its a unix print job */
1390 print_unix_job(ev, msg_ctx,
1391 sharename, &queue[i], jobid);
1395 /* we have an active SMB print job - update its status */
1396 pjob = print_job_find(sharename, jobid);
1398 /* err, somethings wrong. Probably smbd was restarted
1399 with jobs in the queue. All we can do is treat them
1400 like unix jobs. Pity. */
1401 print_unix_job(ev, msg_ctx,
1402 sharename, &queue[i], jobid);
1406 pjob->sysjob = queue[i].sysjob;
1408 /* don't reset the status on jobs to be deleted */
1410 if ( pjob->status != LPQ_DELETING )
1411 pjob->status = queue[i].status;
1413 pjob_store(ev, msg_ctx, sharename, jobid, pjob);
1415 check_job_added(sharename, jcdata, jobid);
1418 SAFE_FREE(jcdata.dptr);
1420 /* now delete any queued entries that don't appear in the
1422 tstruct.queue = queue;
1423 tstruct.qcount = qcount;
1425 tstruct.total_jobs = 0;
1426 tstruct.lpq_time = time(NULL);
1427 tstruct.sharename = sharename;
1428 tstruct.lprm_command = lprm_command;
1429 tstruct.print_if = current_printif;
1431 tstruct.msg_ctx = msg_ctx;
1433 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1435 /* Store the linearised queue, max jobs only. */
1436 store_queue_struct(pdb, &tstruct);
1438 SAFE_FREE(tstruct.queue);
1440 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1441 sharename, tstruct.total_jobs ));
1443 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1445 get_queue_status(sharename, &old_status);
1446 if (old_status.qcount != qcount)
1447 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1448 old_status.qcount, qcount, sharename));
1450 /* store the new queue status structure */
1451 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1452 key = string_tdb_data(keystr);
1454 status.qcount = qcount;
1455 data.dptr = (uint8 *)&status;
1456 data.dsize = sizeof(status);
1457 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1460 * Update the cache time again. We want to do this call
1461 * as little as possible...
1464 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1465 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1467 /* clear the msg pending record for this queue */
1469 snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1471 if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1472 /* log a message but continue on */
1474 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1478 release_print_db( pdb );
1483 /****************************************************************************
1484 Update the internal database from the system print queue for a queue.
1485 obtain a lock on the print queue before proceeding (needed when mutiple
1486 smbd processes maytry to update the lpq cache concurrently).
1487 ****************************************************************************/
1489 static void print_queue_update_with_lock( struct tevent_context *ev,
1490 struct messaging_context *msg_ctx,
1491 const char *sharename,
1492 struct printif *current_printif,
1493 char *lpq_command, char *lprm_command )
1496 struct tdb_print_db *pdb;
1498 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1499 pdb = get_print_db_byname(sharename);
1503 if ( !print_cache_expired(sharename, False) ) {
1504 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1505 release_print_db(pdb);
1510 * Check to see if someone else is doing this update.
1511 * This is essentially a mutex on the update.
1514 if (get_updating_pid(sharename) != -1) {
1515 release_print_db(pdb);
1519 /* Lock the queue for the database update */
1521 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1522 /* Only wait 10 seconds for this. */
1523 if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
1524 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1525 release_print_db(pdb);
1530 * Ensure that no one else got in here.
1531 * If the updating pid is still -1 then we are
1535 if (get_updating_pid(sharename) != -1) {
1537 * Someone else is doing the update, exit.
1539 tdb_unlock_bystring(pdb->tdb, keystr);
1540 release_print_db(pdb);
1545 * We're going to do the update ourselves.
1548 /* Tell others we're doing the update. */
1549 set_updating_pid(sharename, True);
1552 * Allow others to enter and notice we're doing
1556 tdb_unlock_bystring(pdb->tdb, keystr);
1558 /* do the main work now */
1560 print_queue_update_internal(ev, msg_ctx,
1561 sharename, current_printif,
1562 lpq_command, lprm_command);
1564 /* Delete our pid from the db. */
1565 set_updating_pid(sharename, False);
1566 release_print_db(pdb);
1569 /****************************************************************************
1570 this is the receive function of the background lpq updater
1571 ****************************************************************************/
1572 void print_queue_receive(struct messaging_context *msg,
1575 struct server_id server_id,
1579 char *lpqcommand = NULL, *lprmcommand = NULL;
1583 len = tdb_unpack( (uint8 *)data->data, data->length, "fdPP",
1590 SAFE_FREE(lpqcommand);
1591 SAFE_FREE(lprmcommand);
1592 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1596 print_queue_update_with_lock(server_event_context(), msg, sharename,
1597 get_printer_fns_from_type((enum printing_types)printing_type),
1598 lpqcommand, lprmcommand );
1600 SAFE_FREE(lpqcommand);
1601 SAFE_FREE(lprmcommand);
1605 static void printing_pause_fd_handler(struct tevent_context *ev,
1606 struct tevent_fd *fde,
1611 * If pause_pipe[1] is closed it means the parent smbd
1612 * and children exited or aborted.
1614 exit_server_cleanly(NULL);
1617 extern struct child_pid *children;
1618 extern int num_children;
1620 static void add_child_pid(pid_t pid)
1622 struct child_pid *child;
1624 child = SMB_MALLOC_P(struct child_pid);
1625 if (child == NULL) {
1626 DEBUG(0, ("Could not add child struct -- malloc failed\n"));
1630 DLIST_ADD(children, child);
1634 static pid_t background_lpq_updater_pid = -1;
1636 /****************************************************************************
1637 main thread of the background lpq updater
1638 ****************************************************************************/
1639 void start_background_queue(struct tevent_context *ev,
1640 struct messaging_context *msg_ctx)
1642 /* Use local variables for this as we don't
1643 * need to save the parent side of this, just
1644 * ensure it closes when the process exits.
1648 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1650 if (pipe(pause_pipe) == -1) {
1651 DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno) ));
1655 background_lpq_updater_pid = sys_fork();
1657 if (background_lpq_updater_pid == -1) {
1658 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1662 /* Track the printing pid along with other smbd children */
1663 add_child_pid(background_lpq_updater_pid);
1665 if(background_lpq_updater_pid == 0) {
1666 struct tevent_fd *fde;
1671 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1673 close(pause_pipe[0]);
1676 status = reinit_after_fork(msg_ctx, ev, procid_self(), true);
1678 if (!NT_STATUS_IS_OK(status)) {
1679 DEBUG(0,("reinit_after_fork() failed\n"));
1680 smb_panic("reinit_after_fork() failed");
1683 smbd_setup_sig_term_handler();
1684 smbd_setup_sig_hup_handler(ev, msg_ctx);
1686 if (!serverid_register(procid_self(),
1687 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
1688 |FLAG_MSG_PRINT_GENERAL)) {
1692 if (!locking_init()) {
1696 messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE,
1697 print_queue_receive);
1699 fde = tevent_add_fd(ev, ev, pause_pipe[1], TEVENT_FD_READ,
1700 printing_pause_fd_handler,
1703 DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
1704 smb_panic("tevent_add_fd() failed for pause_pipe");
1707 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1708 ret = tevent_loop_wait(ev);
1709 /* should not be reached */
1710 DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
1711 ret, (ret == 0) ? "out of events" : strerror(errno)));
1715 close(pause_pipe[1]);
1718 /****************************************************************************
1719 update the internal database from the system print queue for a queue
1720 ****************************************************************************/
1722 static void print_queue_update(struct messaging_context *msg_ctx,
1723 int snum, bool force)
1727 char *lpqcommand = NULL;
1728 char *lprmcommand = NULL;
1729 uint8 *buffer = NULL;
1732 struct tdb_print_db *pdb;
1734 struct printif *current_printif;
1735 TALLOC_CTX *ctx = talloc_tos();
1737 fstrcpy( sharename, lp_const_servicename(snum));
1739 /* don't strip out characters like '$' from the printername */
1741 lpqcommand = talloc_string_sub2(ctx,
1742 lp_lpqcommand(snum),
1744 lp_printername(snum),
1745 false, false, false);
1749 lpqcommand = talloc_sub_advanced(ctx,
1750 lp_servicename(snum),
1751 current_user_info.unix_name,
1753 current_user.ut.gid,
1754 get_current_username(),
1755 current_user_info.domain,
1761 lprmcommand = talloc_string_sub2(ctx,
1762 lp_lprmcommand(snum),
1764 lp_printername(snum),
1765 false, false, false);
1769 lprmcommand = talloc_sub_advanced(ctx,
1770 lp_servicename(snum),
1771 current_user_info.unix_name,
1773 current_user.ut.gid,
1774 get_current_username(),
1775 current_user_info.domain,
1782 * Make sure that the background queue process exists.
1783 * Otherwise just do the update ourselves
1786 if ( force || background_lpq_updater_pid == -1 ) {
1787 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1788 current_printif = get_printer_fns( snum );
1789 print_queue_update_with_lock(server_event_context(), msg_ctx,
1790 sharename, current_printif,
1791 lpqcommand, lprmcommand);
1796 type = lp_printing(snum);
1798 /* get the length */
1800 len = tdb_pack( NULL, 0, "fdPP",
1806 buffer = SMB_XMALLOC_ARRAY( uint8, len );
1808 /* now pack the buffer */
1809 newlen = tdb_pack( buffer, len, "fdPP",
1815 SMB_ASSERT( newlen == len );
1817 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1818 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1819 sharename, type, lpqcommand, lprmcommand ));
1821 /* here we set a msg pending record for other smbd processes
1822 to throttle the number of duplicate print_queue_update msgs
1825 pdb = get_print_db_byname(sharename);
1831 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1833 if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1834 /* log a message but continue on */
1836 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1840 release_print_db( pdb );
1842 /* finally send the message */
1844 messaging_send_buf(msg_ctx, pid_to_procid(background_lpq_updater_pid),
1845 MSG_PRINTER_UPDATE, (uint8 *)buffer, len);
1847 SAFE_FREE( buffer );
1852 /****************************************************************************
1853 Create/Update an entry in the print tdb that will allow us to send notify
1854 updates only to interested smbd's.
1855 ****************************************************************************/
1857 bool print_notify_register_pid(int snum)
1860 struct tdb_print_db *pdb = NULL;
1861 TDB_CONTEXT *tdb = NULL;
1862 const char *printername;
1863 uint32 mypid = (uint32)sys_getpid();
1867 /* if (snum == -1), then the change notify request was
1868 on a print server handle and we need to register on
1873 int num_services = lp_numservices();
1876 for ( idx=0; idx<num_services; idx++ ) {
1877 if (lp_snum_ok(idx) && lp_print_ok(idx) )
1878 print_notify_register_pid(idx);
1883 else /* register for a specific printer */
1885 printername = lp_const_servicename(snum);
1886 pdb = get_print_db_byname(printername);
1892 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1893 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1896 release_print_db(pdb);
1900 data = get_printer_notify_pid_list( tdb, printername, True );
1902 /* Add ourselves and increase the refcount. */
1904 for (i = 0; i < data.dsize; i += 8) {
1905 if (IVAL(data.dptr,i) == mypid) {
1906 uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1907 SIVAL(data.dptr, i+4, new_refcount);
1912 if (i == data.dsize) {
1913 /* We weren't in the list. Realloc. */
1914 data.dptr = (uint8 *)SMB_REALLOC(data.dptr, data.dsize + 8);
1916 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1921 SIVAL(data.dptr,data.dsize - 8,mypid);
1922 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1925 /* Store back the record. */
1926 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1927 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1928 list for printer %s\n", printername));
1936 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1938 release_print_db(pdb);
1939 SAFE_FREE(data.dptr);
1943 /****************************************************************************
1944 Update an entry in the print tdb that will allow us to send notify
1945 updates only to interested smbd's.
1946 ****************************************************************************/
1948 bool print_notify_deregister_pid(int snum)
1951 struct tdb_print_db *pdb = NULL;
1952 TDB_CONTEXT *tdb = NULL;
1953 const char *printername;
1954 uint32 mypid = (uint32)sys_getpid();
1958 /* if ( snum == -1 ), we are deregister a print server handle
1959 which means to deregister on all print queues */
1963 int num_services = lp_numservices();
1966 for ( idx=0; idx<num_services; idx++ ) {
1967 if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1968 print_notify_deregister_pid(idx);
1973 else /* deregister a specific printer */
1975 printername = lp_const_servicename(snum);
1976 pdb = get_print_db_byname(printername);
1982 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1983 DEBUG(0,("print_notify_register_pid: Failed to lock \
1984 printer %s database\n", printername));
1986 release_print_db(pdb);
1990 data = get_printer_notify_pid_list( tdb, printername, True );
1992 /* Reduce refcount. Remove ourselves if zero. */
1994 for (i = 0; i < data.dsize; ) {
1995 if (IVAL(data.dptr,i) == mypid) {
1996 uint32 refcount = IVAL(data.dptr, i+4);
2000 if (refcount == 0) {
2001 if (data.dsize - i > 8)
2002 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
2006 SIVAL(data.dptr, i+4, refcount);
2012 if (data.dsize == 0)
2013 SAFE_FREE(data.dptr);
2015 /* Store back the record. */
2016 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
2017 DEBUG(0,("print_notify_register_pid: Failed to update pid \
2018 list for printer %s\n", printername));
2026 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
2028 release_print_db(pdb);
2029 SAFE_FREE(data.dptr);
2033 /****************************************************************************
2034 Check if a jobid is valid. It is valid if it exists in the database.
2035 ****************************************************************************/
2037 bool print_job_exists(const char* sharename, uint32 jobid)
2039 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2045 ret = tdb_exists(pdb->tdb, print_key(jobid, &tmp));
2046 release_print_db(pdb);
2050 /****************************************************************************
2051 Give the filename used for a jobid.
2052 Only valid for the process doing the spooling and when the job
2053 has not been spooled.
2054 ****************************************************************************/
2056 char *print_job_fname(const char* sharename, uint32 jobid)
2058 struct printjob *pjob = print_job_find(sharename, jobid);
2059 if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
2061 return pjob->filename;
2065 /****************************************************************************
2066 Give the filename used for a jobid.
2067 Only valid for the process doing the spooling and when the job
2068 has not been spooled.
2069 ****************************************************************************/
2071 struct spoolss_DeviceMode *print_job_devmode(const char* sharename, uint32 jobid)
2073 struct printjob *pjob = print_job_find(sharename, jobid);
2078 return pjob->devmode;
2081 /****************************************************************************
2082 Set the name of a job. Only possible for owner.
2083 ****************************************************************************/
2085 bool print_job_set_name(struct tevent_context *ev,
2086 struct messaging_context *msg_ctx,
2087 const char *sharename, uint32 jobid, const char *name)
2089 struct printjob *pjob;
2091 pjob = print_job_find(sharename, jobid);
2092 if (!pjob || pjob->pid != sys_getpid())
2095 fstrcpy(pjob->jobname, name);
2096 return pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2099 /****************************************************************************
2100 Get the name of a job. Only possible for owner.
2101 ****************************************************************************/
2103 bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t jobid, char **name)
2105 struct printjob *pjob;
2107 pjob = print_job_find(sharename, jobid);
2108 if (!pjob || pjob->pid != sys_getpid()) {
2112 *name = talloc_strdup(mem_ctx, pjob->jobname);
2121 /***************************************************************************
2122 Remove a jobid from the 'jobs added' list.
2123 ***************************************************************************/
2125 static bool remove_from_jobs_added(const char* sharename, uint32 jobid)
2127 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2129 size_t job_count, i;
2131 bool gotlock = False;
2139 key = string_tdb_data("INFO/jobs_added");
2141 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
2146 data = tdb_fetch(pdb->tdb, key);
2148 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
2151 job_count = data.dsize / 4;
2152 for (i = 0; i < job_count; i++) {
2155 ch_jobid = IVAL(data.dptr, i*4);
2156 if (ch_jobid == jobid) {
2157 if (i < job_count -1 )
2158 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
2160 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
2170 tdb_chainunlock(pdb->tdb, key);
2171 SAFE_FREE(data.dptr);
2172 release_print_db(pdb);
2174 DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid ));
2176 DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid ));
2180 /****************************************************************************
2181 Delete a print job - don't update queue.
2182 ****************************************************************************/
2184 static bool print_job_delete1(struct tevent_context *ev,
2185 struct messaging_context *msg_ctx,
2186 int snum, uint32 jobid)
2188 const char* sharename = lp_const_servicename(snum);
2189 struct printjob *pjob = print_job_find(sharename, jobid);
2191 struct printif *current_printif = get_printer_fns( snum );
2197 * If already deleting just return.
2200 if (pjob->status == LPQ_DELETING)
2203 /* Hrm - we need to be able to cope with deleting a job before it
2204 has reached the spooler. Just mark it as LPQ_DELETING and
2205 let the print_queue_update() code rmeove the record */
2208 if (pjob->sysjob == -1) {
2209 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
2212 /* Set the tdb entry to be deleting. */
2214 pjob->status = LPQ_DELETING;
2215 pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2217 if (pjob->spooled && pjob->sysjob != -1)
2219 result = (*(current_printif->job_delete))(
2220 lp_printername(snum),
2221 lp_lprmcommand(snum),
2224 /* Delete the tdb entry if the delete succeeded or the job hasn't
2228 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2233 pjob_delete(ev, msg_ctx, sharename, jobid);
2234 /* Ensure we keep a rough count of the number of total jobs... */
2235 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
2236 release_print_db(pdb);
2240 remove_from_jobs_added( sharename, jobid );
2242 return (result == 0);
2245 /****************************************************************************
2246 Return true if the current user owns the print job.
2247 ****************************************************************************/
2249 static bool is_owner(const struct auth_serversupplied_info *server_info,
2250 const char *servicename,
2253 struct printjob *pjob = print_job_find(servicename, jobid);
2255 if (!pjob || !server_info)
2258 return strequal(pjob->user, server_info->sanitized_username);
2261 /****************************************************************************
2263 ****************************************************************************/
2265 WERROR print_job_delete(const struct auth_serversupplied_info *server_info,
2266 struct messaging_context *msg_ctx,
2267 int snum, uint32_t jobid)
2269 const char* sharename = lp_const_servicename(snum);
2270 struct printjob *pjob;
2274 owner = is_owner(server_info, lp_const_servicename(snum), jobid);
2276 /* Check access against security descriptor or whether the user
2280 !print_access_check(server_info, msg_ctx, snum,
2281 JOB_ACCESS_ADMINISTER)) {
2282 DEBUG(3, ("delete denied by security descriptor\n"));
2284 /* BEGIN_ADMIN_LOG */
2285 sys_adminlog( LOG_ERR,
2286 "Permission denied-- user not allowed to delete, \
2287 pause, or resume print job. User name: %s. Printer name: %s.",
2288 uidtoname(server_info->utok.uid),
2289 lp_printername(snum) );
2292 return WERR_ACCESS_DENIED;
2296 * get the spooled filename of the print job
2297 * if this works, then the file has not been spooled
2298 * to the underlying print system. Just delete the
2299 * spool file & return.
2302 fname = print_job_fname(sharename, jobid);
2303 if (fname != NULL) {
2304 /* remove the spool file */
2305 DEBUG(10, ("print_job_delete: "
2306 "Removing spool file [%s]\n", fname));
2307 if (unlink(fname) == -1) {
2308 return map_werror_from_unix(errno);
2312 if (!print_job_delete1(server_event_context(), msg_ctx, snum, jobid)) {
2313 return WERR_ACCESS_DENIED;
2316 /* force update the database and say the delete failed if the
2319 print_queue_update(msg_ctx, snum, True);
2321 pjob = print_job_find(sharename, jobid);
2322 if (pjob && (pjob->status != LPQ_DELETING)) {
2323 return WERR_ACCESS_DENIED;
2326 return WERR_PRINTER_HAS_JOBS_QUEUED;
2329 /****************************************************************************
2331 ****************************************************************************/
2333 bool print_job_pause(const struct auth_serversupplied_info *server_info,
2334 struct messaging_context *msg_ctx,
2335 int snum, uint32 jobid, WERROR *errcode)
2337 const char* sharename = lp_const_servicename(snum);
2338 struct printjob *pjob;
2340 struct printif *current_printif = get_printer_fns( snum );
2342 pjob = print_job_find(sharename, jobid);
2344 if (!pjob || !server_info) {
2345 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2346 (unsigned int)jobid ));
2350 if (!pjob->spooled || pjob->sysjob == -1) {
2351 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2352 (int)pjob->sysjob, (unsigned int)jobid ));
2356 if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2357 !print_access_check(server_info, msg_ctx, snum,
2358 JOB_ACCESS_ADMINISTER)) {
2359 DEBUG(3, ("pause denied by security descriptor\n"));
2361 /* BEGIN_ADMIN_LOG */
2362 sys_adminlog( LOG_ERR,
2363 "Permission denied-- user not allowed to delete, \
2364 pause, or resume print job. User name: %s. Printer name: %s.",
2365 uidtoname(server_info->utok.uid),
2366 lp_printername(snum) );
2369 *errcode = WERR_ACCESS_DENIED;
2373 /* need to pause the spooled entry */
2374 ret = (*(current_printif->job_pause))(snum, pjob);
2377 *errcode = WERR_INVALID_PARAM;
2381 /* force update the database */
2382 print_cache_flush(lp_const_servicename(snum));
2384 /* Send a printer notify message */
2386 notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2389 /* how do we tell if this succeeded? */
2394 /****************************************************************************
2396 ****************************************************************************/
2398 bool print_job_resume(const struct auth_serversupplied_info *server_info,
2399 struct messaging_context *msg_ctx,
2400 int snum, uint32 jobid, WERROR *errcode)
2402 const char *sharename = lp_const_servicename(snum);
2403 struct printjob *pjob;
2405 struct printif *current_printif = get_printer_fns( snum );
2407 pjob = print_job_find(sharename, jobid);
2409 if (!pjob || !server_info) {
2410 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2411 (unsigned int)jobid ));
2415 if (!pjob->spooled || pjob->sysjob == -1) {
2416 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2417 (int)pjob->sysjob, (unsigned int)jobid ));
2421 if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2422 !print_access_check(server_info, msg_ctx, snum,
2423 JOB_ACCESS_ADMINISTER)) {
2424 DEBUG(3, ("resume denied by security descriptor\n"));
2425 *errcode = WERR_ACCESS_DENIED;
2427 /* BEGIN_ADMIN_LOG */
2428 sys_adminlog( LOG_ERR,
2429 "Permission denied-- user not allowed to delete, \
2430 pause, or resume print job. User name: %s. Printer name: %s.",
2431 uidtoname(server_info->utok.uid),
2432 lp_printername(snum) );
2437 ret = (*(current_printif->job_resume))(snum, pjob);
2440 *errcode = WERR_INVALID_PARAM;
2444 /* force update the database */
2445 print_cache_flush(lp_const_servicename(snum));
2447 /* Send a printer notify message */
2449 notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2455 /****************************************************************************
2456 Write to a print file.
2457 ****************************************************************************/
2459 ssize_t print_job_write(struct tevent_context *ev,
2460 struct messaging_context *msg_ctx,
2461 int snum, uint32 jobid, const char *buf, size_t size)
2463 const char* sharename = lp_const_servicename(snum);
2464 ssize_t return_code;
2465 struct printjob *pjob;
2467 pjob = print_job_find(sharename, jobid);
2471 /* don't allow another process to get this info - it is meaningless */
2472 if (pjob->pid != sys_getpid())
2475 /* if SMBD is spooling this can't be allowed */
2476 if (pjob->status == PJOB_SMBD_SPOOLING) {
2480 return_code = write_data(pjob->fd, buf, size);
2482 if (return_code>0) {
2484 pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2489 /****************************************************************************
2490 Get the queue status - do not update if db is out of date.
2491 ****************************************************************************/
2493 static int get_queue_status(const char* sharename, print_status_struct *status)
2497 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2501 ZERO_STRUCTP(status);
2508 fstr_sprintf(keystr, "STATUS/%s", sharename);
2509 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2511 if (data.dsize == sizeof(print_status_struct))
2512 /* this memcpy is ok since the status struct was
2513 not packed before storing it in the tdb */
2514 memcpy(status, data.dptr, sizeof(print_status_struct));
2515 SAFE_FREE(data.dptr);
2518 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2519 release_print_db(pdb);
2520 return (len == -1 ? 0 : len);
2523 /****************************************************************************
2524 Determine the number of jobs in a queue.
2525 ****************************************************************************/
2527 int print_queue_length(struct messaging_context *msg_ctx, int snum,
2528 print_status_struct *pstatus)
2530 const char* sharename = lp_const_servicename( snum );
2531 print_status_struct status;
2534 ZERO_STRUCT( status );
2536 /* make sure the database is up to date */
2537 if (print_cache_expired(lp_const_servicename(snum), True))
2538 print_queue_update(msg_ctx, snum, False);
2540 /* also fetch the queue status */
2541 memset(&status, 0, sizeof(status));
2542 len = get_queue_status(sharename, &status);
2550 /***************************************************************************
2551 Allocate a jobid. Hold the lock for as short a time as possible.
2552 ***************************************************************************/
2554 static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum,
2555 const char *sharename, uint32 *pjobid)
2559 enum TDB_ERROR terr;
2562 *pjobid = (uint32)-1;
2564 for (i = 0; i < 3; i++) {
2565 /* Lock the database - only wait 20 seconds. */
2566 ret = tdb_lock_bystring_with_timeout(pdb->tdb,
2567 "INFO/nextjob", 20);
2569 DEBUG(0, ("allocate_print_jobid: "
2570 "Failed to lock printing database %s\n",
2572 terr = tdb_error(pdb->tdb);
2573 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2576 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2577 terr = tdb_error(pdb->tdb);
2578 if (terr != TDB_ERR_NOEXIST) {
2579 DEBUG(0, ("allocate_print_jobid: "
2580 "Failed to fetch INFO/nextjob "
2581 "for print queue %s\n", sharename));
2582 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2583 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2585 DEBUG(10, ("allocate_print_jobid: "
2586 "No existing jobid in %s\n", sharename));
2590 DEBUG(10, ("allocate_print_jobid: "
2591 "Read jobid %u from %s\n", jobid, sharename));
2593 jobid = NEXT_JOBID(jobid);
2595 ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid);
2597 terr = tdb_error(pdb->tdb);
2598 DEBUG(3, ("allocate_print_jobid: "
2599 "Failed to store INFO/nextjob.\n"));
2600 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2601 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2604 /* We've finished with the INFO/nextjob lock. */
2605 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2607 if (!print_job_exists(sharename, jobid)) {
2610 DEBUG(10, ("allocate_print_jobid: "
2611 "Found jobid %u in %s\n", jobid, sharename));
2615 DEBUG(0, ("allocate_print_jobid: "
2616 "Failed to allocate a print job for queue %s\n",
2618 /* Probably full... */
2619 return WERR_NO_SPOOL_SPACE;
2622 /* Store a dummy placeholder. */
2628 if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
2629 TDB_INSERT) == -1) {
2630 DEBUG(3, ("allocate_print_jobid: "
2631 "jobid (%d) failed to store placeholder.\n",
2633 terr = tdb_error(pdb->tdb);
2634 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2642 /***************************************************************************
2643 Append a jobid to the 'jobs added' list.
2644 ***************************************************************************/
2646 static bool add_to_jobs_added(struct tdb_print_db *pdb, uint32 jobid)
2651 SIVAL(&store_jobid, 0, jobid);
2652 data.dptr = (uint8 *)&store_jobid;
2655 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid ));
2657 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_added"),
2662 /***************************************************************************
2663 Do all checks needed to determine if we can start a job.
2664 ***************************************************************************/
2666 static WERROR print_job_checks(const struct auth_serversupplied_info *server_info,
2667 struct messaging_context *msg_ctx,
2668 int snum, int *njobs)
2670 const char *sharename = lp_const_servicename(snum);
2671 uint64_t dspace, dsize;
2675 if (!print_access_check(server_info, msg_ctx, snum,
2676 PRINTER_ACCESS_USE)) {
2677 DEBUG(3, ("print_job_checks: "
2678 "job start denied by security descriptor\n"));
2679 return WERR_ACCESS_DENIED;
2682 if (!print_time_access_check(server_info, msg_ctx, sharename)) {
2683 DEBUG(3, ("print_job_checks: "
2684 "job start denied by time check\n"));
2685 return WERR_ACCESS_DENIED;
2688 /* see if we have sufficient disk space */
2689 if (lp_minprintspace(snum)) {
2690 minspace = lp_minprintspace(snum);
2691 ret = sys_fsusage(lp_pathname(snum), &dspace, &dsize);
2692 if (ret == 0 && dspace < 2*minspace) {
2693 DEBUG(3, ("print_job_checks: "
2694 "disk space check failed.\n"));
2695 return WERR_NO_SPOOL_SPACE;
2699 /* for autoloaded printers, check that the printcap entry still exists */
2700 if (lp_autoloaded(snum) && !pcap_printername_ok(sharename)) {
2701 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2703 return WERR_ACCESS_DENIED;
2706 /* Insure the maximum queue size is not violated */
2707 *njobs = print_queue_length(msg_ctx, snum, NULL);
2708 if (*njobs > lp_maxprintjobs(snum)) {
2709 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2710 "larger than max printjobs per queue (%d).\n",
2711 sharename, *njobs, lp_maxprintjobs(snum)));
2712 return WERR_NO_SPOOL_SPACE;
2718 /***************************************************************************
2720 ***************************************************************************/
2722 static WERROR print_job_spool_file(int snum, uint32_t jobid,
2723 const char *output_file,
2724 struct printjob *pjob)
2731 /* if this file is within the printer path, it means that smbd
2732 * is spooling it and will pass us control when it is finished.
2733 * Verify that the file name is ok, within path, and it is
2734 * already already there */
2736 path = lp_pathname(snum);
2738 if (strncmp(output_file, path, len) == 0 &&
2739 (output_file[len - 1] == '/' || output_file[len] == '/')) {
2741 /* verify path is not too long */
2742 if (strlen(output_file) >= sizeof(pjob->filename)) {
2743 return WERR_INVALID_NAME;
2746 /* verify that the file exists */
2747 if (sys_stat(output_file, &st, false) != 0) {
2748 return WERR_INVALID_NAME;
2751 fstrcpy(pjob->filename, output_file);
2753 DEBUG(3, ("print_job_spool_file:"
2754 "External spooling activated"));
2756 /* we do not open the file until spooling is done */
2758 pjob->status = PJOB_SMBD_SPOOLING;
2764 slprintf(pjob->filename, sizeof(pjob->filename)-1,
2765 "%s/%s%.8u.XXXXXX", lp_pathname(snum),
2766 PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2767 pjob->fd = mkstemp(pjob->filename);
2769 if (pjob->fd == -1) {
2770 werr = map_werror_from_unix(errno);
2771 if (W_ERROR_EQUAL(werr, WERR_ACCESS_DENIED)) {
2772 /* Common setup error, force a report. */
2773 DEBUG(0, ("print_job_spool_file: "
2774 "insufficient permissions to open spool "
2775 "file %s.\n", pjob->filename));
2777 /* Normal case, report at level 3 and above. */
2778 DEBUG(3, ("print_job_spool_file: "
2779 "can't open spool file %s\n",
2788 /***************************************************************************
2789 Start spooling a job - return the jobid.
2790 ***************************************************************************/
2792 WERROR print_job_start(const struct auth_serversupplied_info *server_info,
2793 struct messaging_context *msg_ctx,
2794 const char *clientmachine,
2795 int snum, const char *docname, const char *filename,
2796 struct spoolss_DeviceMode *devmode, uint32_t *_jobid)
2800 struct printjob pjob;
2801 const char *sharename = lp_const_servicename(snum);
2802 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2807 return WERR_INTERNAL_DB_CORRUPTION;
2810 path = lp_pathname(snum);
2812 werr = print_job_checks(server_info, msg_ctx, snum, &njobs);
2813 if (!W_ERROR_IS_OK(werr)) {
2814 release_print_db(pdb);
2818 DEBUG(10, ("print_job_start: "
2819 "Queue %s number of jobs (%d), max printjobs = %d\n",
2820 sharename, njobs, lp_maxprintjobs(snum)));
2822 werr = allocate_print_jobid(pdb, snum, sharename, &jobid);
2823 if (!W_ERROR_IS_OK(werr)) {
2827 /* create the database entry */
2831 pjob.pid = sys_getpid();
2835 pjob.starttime = time(NULL);
2836 pjob.status = LPQ_SPOOLING;
2838 pjob.spooled = False;
2840 pjob.devmode = devmode;
2842 fstrcpy(pjob.jobname, docname);
2844 fstrcpy(pjob.clientmachine, clientmachine);
2846 fstrcpy(pjob.user, lp_printjob_username(snum));
2847 standard_sub_advanced(sharename, server_info->sanitized_username,
2848 path, server_info->utok.gid,
2849 server_info->sanitized_username,
2850 server_info->info3->base.domain.string,
2851 pjob.user, sizeof(pjob.user)-1);
2852 /* ensure NULL termination */
2853 pjob.user[sizeof(pjob.user)-1] = '\0';
2855 fstrcpy(pjob.queuename, lp_const_servicename(snum));
2857 /* we have a job entry - now create the spool file */
2858 werr = print_job_spool_file(snum, jobid, filename, &pjob);
2859 if (!W_ERROR_IS_OK(werr)) {
2863 pjob_store(server_event_context(), msg_ctx, sharename, jobid, &pjob);
2865 /* Update the 'jobs added' entry used by print_queue_status. */
2866 add_to_jobs_added(pdb, jobid);
2868 /* Ensure we keep a rough count of the number of total jobs... */
2869 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2871 release_print_db(pdb);
2878 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
2881 release_print_db(pdb);
2883 DEBUG(3, ("print_job_start: returning fail. "
2884 "Error = %s\n", win_errstr(werr)));
2888 /****************************************************************************
2889 Update the number of pages spooled to jobid
2890 ****************************************************************************/
2892 void print_job_endpage(struct messaging_context *msg_ctx,
2893 int snum, uint32 jobid)
2895 const char* sharename = lp_const_servicename(snum);
2896 struct printjob *pjob;
2898 pjob = print_job_find(sharename, jobid);
2901 /* don't allow another process to get this info - it is meaningless */
2902 if (pjob->pid != sys_getpid())
2906 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
2909 /****************************************************************************
2910 Print a file - called on closing the file. This spools the job.
2911 If normal close is false then we're tearing down the jobs - treat as an
2913 ****************************************************************************/
2915 NTSTATUS print_job_end(struct messaging_context *msg_ctx, int snum,
2916 uint32 jobid, enum file_close_type close_type)
2918 const char* sharename = lp_const_servicename(snum);
2919 struct printjob *pjob;
2921 SMB_STRUCT_STAT sbuf;
2922 struct printif *current_printif = get_printer_fns( snum );
2923 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2925 pjob = print_job_find(sharename, jobid);
2928 return NT_STATUS_PRINT_CANCELLED;
2931 if (pjob->spooled || pjob->pid != sys_getpid()) {
2932 return NT_STATUS_ACCESS_DENIED;
2935 if (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) {
2936 if (pjob->status == PJOB_SMBD_SPOOLING) {
2937 /* take over the file now, smbd is done */
2938 if (sys_stat(pjob->filename, &sbuf, false) != 0) {
2939 status = map_nt_error_from_unix(errno);
2940 DEBUG(3, ("print_job_end: "
2941 "stat file failed for jobid %d\n",
2946 pjob->status = LPQ_SPOOLING;
2950 if ((sys_fstat(pjob->fd, &sbuf, false) != 0)) {
2951 status = map_nt_error_from_unix(errno);
2953 DEBUG(3, ("print_job_end: "
2954 "stat file failed for jobid %d\n",
2962 pjob->size = sbuf.st_ex_size;
2966 * Not a normal close, something has gone wrong. Cleanup.
2968 if (pjob->fd != -1) {
2974 /* Technically, this is not quite right. If the printer has a separator
2975 * page turned on, the NT spooler prints the separator page even if the
2976 * print job is 0 bytes. 010215 JRR */
2977 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2978 /* don't bother spooling empty files or something being deleted. */
2979 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2980 pjob->filename, pjob->size ? "deleted" : "zero length" ));
2981 unlink(pjob->filename);
2982 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
2983 return NT_STATUS_OK;
2986 ret = (*(current_printif->job_submit))(snum, pjob);
2989 status = NT_STATUS_PRINT_CANCELLED;
2993 /* The print job has been successfully handed over to the back-end */
2995 pjob->spooled = True;
2996 pjob->status = LPQ_QUEUED;
2997 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
2999 /* make sure the database is up to date */
3000 if (print_cache_expired(lp_const_servicename(snum), True))
3001 print_queue_update(msg_ctx, snum, False);
3003 return NT_STATUS_OK;
3007 /* The print job was not successfully started. Cleanup */
3008 /* Still need to add proper error return propagation! 010122:JRR */
3010 unlink(pjob->filename);
3011 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
3015 /****************************************************************************
3016 Get a snapshot of jobs in the system without traversing.
3017 ****************************************************************************/
3019 static bool get_stored_queue_info(struct messaging_context *msg_ctx,
3020 struct tdb_print_db *pdb, int snum,
3021 int *pcount, print_queue_struct **ppqueue)
3023 TDB_DATA data, cgdata, jcdata;
3024 print_queue_struct *queue = NULL;
3026 uint32 extra_count = 0;
3027 uint32_t changed_count = 0;
3028 int total_count = 0;
3031 int max_reported_jobs = lp_max_reported_jobs(snum);
3033 const char* sharename = lp_servicename(snum);
3035 /* make sure the database is up to date */
3036 if (print_cache_expired(lp_const_servicename(snum), True))
3037 print_queue_update(msg_ctx, snum, False);
3043 ZERO_STRUCT(cgdata);
3045 /* Get the stored queue data. */
3046 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
3048 if (data.dptr && data.dsize >= sizeof(qcount))
3049 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
3051 /* Get the added jobs list. */
3052 cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added"));
3053 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
3054 extra_count = cgdata.dsize/4;
3056 /* Get the changed jobs list. */
3057 jcdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
3058 if (jcdata.dptr != NULL && (jcdata.dsize % 4 == 0))
3059 changed_count = jcdata.dsize / 4;
3061 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
3063 /* Allocate the queue size. */
3064 if (qcount == 0 && extra_count == 0)
3067 if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
3070 /* Retrieve the linearised queue data. */
3072 for( i = 0; i < qcount; i++) {
3073 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
3074 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
3083 queue[i].sysjob = qjob;
3084 queue[i].size = qsize;
3085 queue[i].page_count = qpage_count;
3086 queue[i].status = qstatus;
3087 queue[i].priority = qpriority;
3088 queue[i].time = qtime;
3091 total_count = qcount;
3093 /* Add new jobids to the queue. */
3094 for( i = 0; i < extra_count; i++) {
3096 struct printjob *pjob;
3098 jobid = IVAL(cgdata.dptr, i*4);
3099 DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid));
3100 pjob = print_job_find(lp_const_servicename(snum), jobid);
3102 DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid));
3103 remove_from_jobs_added(sharename, jobid);
3107 queue[total_count].sysjob = jobid;
3108 queue[total_count].size = pjob->size;
3109 queue[total_count].page_count = pjob->page_count;
3110 queue[total_count].status = pjob->status;
3111 queue[total_count].priority = 1;
3112 queue[total_count].time = pjob->starttime;
3113 fstrcpy(queue[total_count].fs_user, pjob->user);
3114 fstrcpy(queue[total_count].fs_file, pjob->jobname);
3118 /* Update the changed jobids. */
3119 for (i = 0; i < changed_count; i++) {
3120 uint32_t jobid = IVAL(jcdata.dptr, i * 4);
3124 for (j = 0; j < total_count; j++) {
3125 if (queue[j].sysjob == jobid) {
3132 struct printjob *pjob;
3134 DEBUG(5,("get_stored_queue_info: changed job: %u\n",
3135 (unsigned int) jobid));
3137 pjob = print_job_find(sharename, jobid);
3139 DEBUG(5,("get_stored_queue_info: failed to find "
3140 "changed job = %u\n",
3141 (unsigned int) jobid));
3142 remove_from_jobs_changed(sharename, jobid);
3146 queue[j].sysjob = jobid;
3147 queue[j].size = pjob->size;
3148 queue[j].page_count = pjob->page_count;
3149 queue[j].status = pjob->status;
3150 queue[j].priority = 1;
3151 queue[j].time = pjob->starttime;
3152 fstrcpy(queue[j].fs_user, pjob->user);
3153 fstrcpy(queue[j].fs_file, pjob->jobname);
3155 DEBUG(5,("get_stored_queue_info: updated queue[%u], jobid: %u, jobname: %s\n",
3156 (unsigned int) j, (unsigned int) jobid, pjob->jobname));
3159 remove_from_jobs_changed(sharename, jobid);
3162 /* Sort the queue by submission time otherwise they are displayed
3165 TYPESAFE_QSORT(queue, total_count, printjob_comp);
3167 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
3169 if (max_reported_jobs && total_count > max_reported_jobs)
3170 total_count = max_reported_jobs;
3173 *pcount = total_count;
3179 SAFE_FREE(data.dptr);
3180 SAFE_FREE(cgdata.dptr);
3184 /****************************************************************************
3185 Get a printer queue listing.
3186 set queue = NULL and status = NULL if you just want to update the cache
3187 ****************************************************************************/
3189 int print_queue_status(struct messaging_context *msg_ctx, int snum,
3190 print_queue_struct **ppqueue,
3191 print_status_struct *status)
3195 const char *sharename;
3196 struct tdb_print_db *pdb;
3199 /* make sure the database is up to date */
3201 if (print_cache_expired(lp_const_servicename(snum), True))
3202 print_queue_update(msg_ctx, snum, False);
3204 /* return if we are done */
3205 if ( !ppqueue || !status )
3209 sharename = lp_const_servicename(snum);
3210 pdb = get_print_db_byname(sharename);
3216 * Fetch the queue status. We must do this first, as there may
3217 * be no jobs in the queue.
3220 ZERO_STRUCTP(status);
3221 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
3222 key = string_tdb_data(keystr);
3224 data = tdb_fetch(pdb->tdb, key);
3226 if (data.dsize == sizeof(*status)) {
3227 /* this memcpy is ok since the status struct was
3228 not packed before storing it in the tdb */
3229 memcpy(status, data.dptr, sizeof(*status));
3231 SAFE_FREE(data.dptr);
3235 * Now, fetch the print queue information. We first count the number
3236 * of entries, and then only retrieve the queue if necessary.
3239 if (!get_stored_queue_info(msg_ctx, pdb, snum, &count, ppqueue)) {
3240 release_print_db(pdb);
3244 release_print_db(pdb);
3248 /****************************************************************************
3250 ****************************************************************************/
3252 WERROR print_queue_pause(const struct auth_serversupplied_info *server_info,
3253 struct messaging_context *msg_ctx, int snum)
3256 struct printif *current_printif = get_printer_fns( snum );
3258 if (!print_access_check(server_info, msg_ctx, snum,
3259 PRINTER_ACCESS_ADMINISTER)) {
3260 return WERR_ACCESS_DENIED;
3266 ret = (*(current_printif->queue_pause))(snum);
3271 return WERR_INVALID_PARAM;
3274 /* force update the database */
3275 print_cache_flush(lp_const_servicename(snum));
3277 /* Send a printer notify message */
3279 notify_printer_status(server_event_context(), msg_ctx, snum,
3280 PRINTER_STATUS_PAUSED);
3285 /****************************************************************************
3287 ****************************************************************************/
3289 WERROR print_queue_resume(const struct auth_serversupplied_info *server_info,
3290 struct messaging_context *msg_ctx, int snum)
3293 struct printif *current_printif = get_printer_fns( snum );
3295 if (!print_access_check(server_info, msg_ctx, snum,
3296 PRINTER_ACCESS_ADMINISTER)) {
3297 return WERR_ACCESS_DENIED;
3302 ret = (*(current_printif->queue_resume))(snum);
3307 return WERR_INVALID_PARAM;
3310 /* make sure the database is up to date */
3311 if (print_cache_expired(lp_const_servicename(snum), True))
3312 print_queue_update(msg_ctx, snum, True);
3314 /* Send a printer notify message */
3316 notify_printer_status(server_event_context(), msg_ctx, snum,
3322 /****************************************************************************
3323 Purge a queue - implemented by deleting all jobs that we can delete.
3324 ****************************************************************************/
3326 WERROR print_queue_purge(const struct auth_serversupplied_info *server_info,
3327 struct messaging_context *msg_ctx, int snum)
3329 print_queue_struct *queue;
3330 print_status_struct status;
3334 /* Force and update so the count is accurate (i.e. not a cached count) */
3335 print_queue_update(msg_ctx, snum, True);
3337 can_job_admin = print_access_check(server_info,
3340 JOB_ACCESS_ADMINISTER);
3341 njobs = print_queue_status(msg_ctx, snum, &queue, &status);
3343 if ( can_job_admin )
3346 for (i=0;i<njobs;i++) {
3347 bool owner = is_owner(server_info, lp_const_servicename(snum),
3350 if (owner || can_job_admin) {
3351 print_job_delete1(server_event_context(), msg_ctx,
3352 snum, queue[i].sysjob);
3356 if ( can_job_admin )
3359 /* update the cache */
3360 print_queue_update(msg_ctx, snum, True);