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/messaging.h"
27 #include "../librpc/gen_ndr/ndr_spoolss.h"
28 #include "nt_printing.h"
29 #include "../librpc/gen_ndr/netlogon.h"
30 #include "printing/notify.h"
31 #include "printing/pcap.h"
33 #include "smbd/smbd.h"
35 extern struct current_user current_user;
36 extern userdom_struct current_user_info;
38 /* Current printer interface */
39 static bool remove_from_jobs_added(const char* sharename, uint32 jobid);
42 the printing backend revolves around a tdb database that stores the
43 SMB view of the print queue
45 The key for this database is a jobid - a internally generated number that
46 uniquely identifies a print job
48 reading the print queue involves two steps:
49 - possibly running lpq and updating the internal database from that
50 - reading entries from the database
52 jobids are assigned when a job starts spooling.
55 static TDB_CONTEXT *rap_tdb;
56 static uint16 next_rap_jobid;
57 struct rap_jobid_key {
62 /***************************************************************************
63 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
64 bit RPC jobids.... JRA.
65 ***************************************************************************/
67 uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
71 struct rap_jobid_key jinfo;
74 DEBUG(10,("pjobid_to_rap: called.\n"));
77 /* Create the in-memory tdb. */
78 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
84 fstrcpy( jinfo.sharename, sharename );
86 key.dptr = (uint8 *)&jinfo;
87 key.dsize = sizeof(jinfo);
89 data = tdb_fetch(rap_tdb, key);
90 if (data.dptr && data.dsize == sizeof(uint16)) {
91 rap_jobid = SVAL(data.dptr, 0);
93 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
94 (unsigned int)jobid, (unsigned int)rap_jobid));
98 /* Not found - create and store mapping. */
99 rap_jobid = ++next_rap_jobid;
101 rap_jobid = ++next_rap_jobid;
102 SSVAL(buf,0,rap_jobid);
104 data.dsize = sizeof(rap_jobid);
105 tdb_store(rap_tdb, key, data, TDB_REPLACE);
106 tdb_store(rap_tdb, data, key, TDB_REPLACE);
108 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
109 (unsigned int)jobid, (unsigned int)rap_jobid));
113 bool rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
118 DEBUG(10,("rap_to_pjobid called.\n"));
123 SSVAL(buf,0,rap_jobid);
125 key.dsize = sizeof(rap_jobid);
126 data = tdb_fetch(rap_tdb, key);
127 if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) )
129 struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
130 if (sharename != NULL) {
131 fstrcpy( sharename, jinfo->sharename );
133 *pjobid = jinfo->jobid;
134 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
135 (unsigned int)*pjobid, (unsigned int)rap_jobid));
136 SAFE_FREE(data.dptr);
140 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
141 (unsigned int)rap_jobid));
142 SAFE_FREE(data.dptr);
146 void rap_jobid_delete(const char* sharename, uint32 jobid)
150 struct rap_jobid_key jinfo;
153 DEBUG(10,("rap_jobid_delete: called.\n"));
158 ZERO_STRUCT( jinfo );
159 fstrcpy( jinfo.sharename, sharename );
161 key.dptr = (uint8 *)&jinfo;
162 key.dsize = sizeof(jinfo);
164 data = tdb_fetch(rap_tdb, key);
165 if (!data.dptr || (data.dsize != sizeof(uint16))) {
166 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
167 (unsigned int)jobid ));
168 SAFE_FREE(data.dptr);
172 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
173 (unsigned int)jobid ));
175 rap_jobid = SVAL(data.dptr, 0);
176 SAFE_FREE(data.dptr);
177 SSVAL(buf,0,rap_jobid);
179 data.dsize = sizeof(rap_jobid);
180 tdb_delete(rap_tdb, key);
181 tdb_delete(rap_tdb, data);
184 static int get_queue_status(const char* sharename, print_status_struct *);
186 /****************************************************************************
187 Initialise the printing backend. Called once at startup before the fork().
188 ****************************************************************************/
190 bool print_backend_init(struct messaging_context *msg_ctx)
192 const char *sversion = "INFO/version";
193 int services = lp_numservices();
196 unlink(cache_path("printing.tdb"));
197 mkdir(cache_path("printing"),0755);
199 /* handle a Samba upgrade */
201 for (snum = 0; snum < services; snum++) {
202 struct tdb_print_db *pdb;
203 if (!lp_print_ok(snum))
206 pdb = get_print_db_byname(lp_const_servicename(snum));
209 if (tdb_lock_bystring(pdb->tdb, sversion) == -1) {
210 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
211 release_print_db(pdb);
214 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
215 tdb_wipe_all(pdb->tdb);
216 tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
218 tdb_unlock_bystring(pdb->tdb, sversion);
219 release_print_db(pdb);
222 close_all_print_db(); /* Don't leave any open. */
224 /* do NT print initialization... */
225 return nt_printing_init(msg_ctx);
228 /****************************************************************************
229 Shut down printing backend. Called once at shutdown to close the tdb.
230 ****************************************************************************/
232 void printing_end(void)
234 close_all_print_db(); /* Don't leave any open. */
237 /****************************************************************************
238 Retrieve the set of printing functions for a given service. This allows
239 us to set the printer function table based on the value of the 'printing'
242 Use the generic interface as the default and only use cups interface only
243 when asked for (and only when supported)
244 ****************************************************************************/
246 static struct printif *get_printer_fns_from_type( enum printing_types type )
248 struct printif *printer_fns = &generic_printif;
251 if ( type == PRINT_CUPS ) {
252 printer_fns = &cups_printif;
254 #endif /* HAVE_CUPS */
257 if ( type == PRINT_IPRINT ) {
258 printer_fns = &iprint_printif;
260 #endif /* HAVE_IPRINT */
262 printer_fns->type = type;
267 static struct printif *get_printer_fns( int snum )
269 return get_printer_fns_from_type( (enum printing_types)lp_printing(snum) );
273 /****************************************************************************
274 Useful function to generate a tdb key.
275 ****************************************************************************/
277 static TDB_DATA print_key(uint32 jobid, uint32 *tmp)
281 SIVAL(tmp, 0, jobid);
282 ret.dptr = (uint8 *)tmp;
283 ret.dsize = sizeof(*tmp);
287 /****************************************************************************
288 Pack the devicemode to store it in a tdb.
289 ****************************************************************************/
290 static int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8 *buf, int buflen)
292 enum ndr_err_code ndr_err;
297 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(),
299 (ndr_push_flags_fn_t)
300 ndr_push_spoolss_DeviceMode);
301 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
302 DEBUG(10, ("pack_devicemode: "
303 "error encoding spoolss_DeviceMode\n"));
310 len = tdb_pack(buf, buflen, "B", blob.length, blob.data);
313 DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname));
320 /****************************************************************************
321 Unpack the devicemode to store it in a tdb.
322 ****************************************************************************/
323 static int unpack_devicemode(TALLOC_CTX *mem_ctx,
324 const uint8 *buf, int buflen,
325 struct spoolss_DeviceMode **devmode)
327 struct spoolss_DeviceMode *dm;
328 enum ndr_err_code ndr_err;
336 len = tdb_unpack(buf, buflen, "B", &data_len, &data);
341 dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
346 blob = data_blob_const(data, data_len);
348 ndr_err = ndr_pull_struct_blob(&blob, dm, dm,
349 (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);
350 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
351 DEBUG(10, ("unpack_devicemode: "
352 "error parsing spoolss_DeviceMode\n"));
356 DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
357 dm->devicename, dm->formname));
358 if (dm->driverextra_data.data) {
359 DEBUG(8, ("with a private section of %d bytes\n",
360 dm->__driverextra_length));
370 /***********************************************************************
371 unpack a pjob from a tdb buffer
372 ***********************************************************************/
374 static int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )
378 uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
379 uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
384 len += tdb_unpack(buf+len, buflen-len, "dddddddddfffff",
403 used = unpack_devicemode(NULL, buf+len, buflen-len, &pjob->devmode);
411 pjob->sysjob = pjsysjob;
413 pjob->starttime = pjstarttime;
414 pjob->status = pjstatus;
416 pjob->page_count = pjpage_count;
417 pjob->spooled = pjspooled;
418 pjob->smbjob = pjsmbjob;
424 /****************************************************************************
425 Useful function to find a print job in the database.
426 ****************************************************************************/
428 static struct printjob *print_job_find(const char *sharename, uint32 jobid)
430 static struct printjob pjob;
433 struct tdb_print_db *pdb = get_print_db_byname(sharename);
435 DEBUG(10,("print_job_find: looking up job %u for share %s\n",
436 (unsigned int)jobid, sharename ));
442 ret = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
443 release_print_db(pdb);
446 DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid ));
450 talloc_free(pjob.devmode);
454 if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
455 DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid ));
462 DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
463 (int)pjob.sysjob, (unsigned int)jobid ));
468 /* Convert a unix jobid to a smb jobid */
470 struct unixjob_traverse_state {
472 uint32 sysjob_to_jobid_value;
475 static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
476 TDB_DATA data, void *private_data)
478 struct printjob *pjob;
479 struct unixjob_traverse_state *state =
480 (struct unixjob_traverse_state *)private_data;
482 if (!data.dptr || data.dsize == 0)
485 pjob = (struct printjob *)data.dptr;
486 if (key.dsize != sizeof(uint32))
489 if (state->sysjob == pjob->sysjob) {
490 uint32 jobid = IVAL(key.dptr,0);
492 state->sysjob_to_jobid_value = jobid;
499 /****************************************************************************
500 This is a *horribly expensive call as we have to iterate through all the
501 current printer tdb's. Don't do this often ! JRA.
502 ****************************************************************************/
504 uint32 sysjob_to_jobid(int unix_jobid)
506 int services = lp_numservices();
508 struct unixjob_traverse_state state;
510 state.sysjob = unix_jobid;
511 state.sysjob_to_jobid_value = (uint32)-1;
513 for (snum = 0; snum < services; snum++) {
514 struct tdb_print_db *pdb;
515 if (!lp_print_ok(snum))
517 pdb = get_print_db_byname(lp_const_servicename(snum));
521 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &state);
522 release_print_db(pdb);
523 if (state.sysjob_to_jobid_value != (uint32)-1)
524 return state.sysjob_to_jobid_value;
529 /****************************************************************************
530 Send notifications based on what has changed after a pjob_store.
531 ****************************************************************************/
533 static const struct {
535 uint32_t spoolss_status;
536 } lpq_to_spoolss_status_map[] = {
537 { LPQ_QUEUED, JOB_STATUS_QUEUED },
538 { LPQ_PAUSED, JOB_STATUS_PAUSED },
539 { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
540 { LPQ_PRINTING, JOB_STATUS_PRINTING },
541 { LPQ_DELETING, JOB_STATUS_DELETING },
542 { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
543 { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
544 { LPQ_PRINTED, JOB_STATUS_PRINTED },
545 { LPQ_DELETED, JOB_STATUS_DELETED },
546 { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ },
547 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
551 /* Convert a lpq status value stored in printing.tdb into the
552 appropriate win32 API constant. */
554 static uint32 map_to_spoolss_status(uint32 lpq_status)
558 while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
559 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
560 return lpq_to_spoolss_status_map[i].spoolss_status;
567 /***************************************************************************
568 Append a jobid to the 'jobs changed' list.
569 ***************************************************************************/
571 static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32_t jobid)
574 uint32_t store_jobid;
576 SIVAL(&store_jobid, 0, jobid);
577 data.dptr = (uint8 *) &store_jobid;
580 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid ));
582 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
586 /***************************************************************************
587 Remove a jobid from the 'jobs changed' list.
588 ***************************************************************************/
590 static bool remove_from_jobs_changed(const char* sharename, uint32_t jobid)
592 struct tdb_print_db *pdb = get_print_db_byname(sharename);
596 bool gotlock = False;
604 key = string_tdb_data("INFO/jobs_changed");
606 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
611 data = tdb_fetch(pdb->tdb, key);
613 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
616 job_count = data.dsize / 4;
617 for (i = 0; i < job_count; i++) {
620 ch_jobid = IVAL(data.dptr, i*4);
621 if (ch_jobid == jobid) {
622 if (i < job_count -1 )
623 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
625 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
635 tdb_chainunlock(pdb->tdb, key);
636 SAFE_FREE(data.dptr);
637 release_print_db(pdb);
639 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
641 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
645 static void pjob_store_notify(struct tevent_context *ev,
646 struct messaging_context *msg_ctx,
647 const char* sharename, uint32 jobid,
648 struct printjob *old_data,
649 struct printjob *new_data,
652 bool new_job = false;
653 bool changed = false;
655 if (old_data == NULL) {
659 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
660 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
661 time first or else we'll end up with potential alignment
662 errors. I don't think the systemtime should be spooled as
663 a string, but this gets us around that error.
664 --jerry (i'll feel dirty for this) */
667 notify_job_submitted(ev, msg_ctx,
668 sharename, jobid, new_data->starttime);
669 notify_job_username(ev, msg_ctx,
670 sharename, jobid, new_data->user);
671 notify_job_name(ev, msg_ctx,
672 sharename, jobid, new_data->jobname);
673 notify_job_status(ev, msg_ctx,
674 sharename, jobid, map_to_spoolss_status(new_data->status));
675 notify_job_total_bytes(ev, msg_ctx,
676 sharename, jobid, new_data->size);
677 notify_job_total_pages(ev, msg_ctx,
678 sharename, jobid, new_data->page_count);
680 if (!strequal(old_data->jobname, new_data->jobname)) {
681 notify_job_name(ev, msg_ctx, sharename,
682 jobid, new_data->jobname);
686 if (old_data->status != new_data->status) {
687 notify_job_status(ev, msg_ctx,
689 map_to_spoolss_status(new_data->status));
692 if (old_data->size != new_data->size) {
693 notify_job_total_bytes(ev, msg_ctx,
694 sharename, jobid, new_data->size);
697 if (old_data->page_count != new_data->page_count) {
698 notify_job_total_pages(ev, msg_ctx,
700 new_data->page_count);
707 /****************************************************************************
708 Store a job structure back to the database.
709 ****************************************************************************/
711 static bool pjob_store(struct tevent_context *ev,
712 struct messaging_context *msg_ctx,
713 const char* sharename, uint32 jobid,
714 struct printjob *pjob)
717 TDB_DATA old_data, new_data;
719 struct tdb_print_db *pdb = get_print_db_byname(sharename);
721 int len, newlen, buflen;
729 old_data = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
731 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
738 len += tdb_pack(buf+len, buflen-len, "dddddddddfffff",
740 (uint32)pjob->sysjob,
742 (uint32)pjob->starttime,
743 (uint32)pjob->status,
745 (uint32)pjob->page_count,
746 (uint32)pjob->spooled,
747 (uint32)pjob->smbjob,
754 len += pack_devicemode(pjob->devmode, buf+len, buflen-len);
757 buf = (uint8 *)SMB_REALLOC(buf, len);
759 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
764 } while ( buflen != len );
770 new_data.dsize = len;
771 ret = (tdb_store(pdb->tdb, print_key(jobid, &tmp), new_data,
774 /* Send notify updates for what has changed */
777 bool changed = false;
778 struct printjob old_pjob;
780 if ( old_data.dsize )
782 if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
784 pjob_store_notify(server_event_context(),
786 sharename, jobid, &old_pjob,
789 talloc_free(old_pjob.devmode);
792 add_to_jobs_changed(pdb, jobid);
799 pjob_store_notify(server_event_context(), msg_ctx,
800 sharename, jobid, NULL, pjob,
805 release_print_db(pdb);
807 SAFE_FREE( old_data.dptr );
813 /****************************************************************************
814 Remove a job structure from the database.
815 ****************************************************************************/
817 static void pjob_delete(struct tevent_context *ev,
818 struct messaging_context *msg_ctx,
819 const char* sharename, uint32 jobid)
822 struct printjob *pjob;
823 uint32 job_status = 0;
824 struct tdb_print_db *pdb;
826 pdb = get_print_db_byname( sharename );
831 pjob = print_job_find( sharename, jobid );
834 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
835 (unsigned int)jobid));
836 release_print_db(pdb);
840 /* We must cycle through JOB_STATUS_DELETING and
841 JOB_STATUS_DELETED for the port monitor to delete the job
844 job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
845 notify_job_status(ev, msg_ctx, sharename, jobid, job_status);
847 /* Remove from printing.tdb */
849 tdb_delete(pdb->tdb, print_key(jobid, &tmp));
850 remove_from_jobs_added(sharename, jobid);
851 release_print_db( pdb );
852 rap_jobid_delete(sharename, jobid);
855 /****************************************************************************
856 List a unix job in the print database.
857 ****************************************************************************/
859 static void print_unix_job(struct tevent_context *ev,
860 struct messaging_context *msg_ctx,
861 const char *sharename, print_queue_struct *q,
864 struct printjob pj, *old_pj;
866 if (jobid == (uint32)-1)
867 jobid = q->job + UNIX_JOB_START;
869 /* Preserve the timestamp on an existing unix print job */
871 old_pj = print_job_find(sharename, jobid);
878 pj.starttime = old_pj ? old_pj->starttime : q->time;
879 pj.status = q->status;
882 fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
883 if (jobid < UNIX_JOB_START) {
885 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
888 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
890 fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
891 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
893 pjob_store(ev, msg_ctx, sharename, jobid, &pj);
897 struct traverse_struct {
898 print_queue_struct *queue;
899 int qcount, snum, maxcount, total_jobs;
900 const char *sharename;
902 const char *lprm_command;
903 struct printif *print_if;
904 struct tevent_context *ev;
905 struct messaging_context *msg_ctx;
908 /****************************************************************************
909 Utility fn to delete any jobs that are no longer active.
910 ****************************************************************************/
912 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
914 struct traverse_struct *ts = (struct traverse_struct *)state;
915 struct printjob pjob;
919 if ( key.dsize != sizeof(jobid) )
922 jobid = IVAL(key.dptr, 0);
923 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
925 talloc_free(pjob.devmode);
929 /* remove a unix job if it isn't in the system queue any more */
931 for (i=0;i<ts->qcount;i++) {
932 uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
933 if (jobid == u_jobid)
936 if (i == ts->qcount) {
937 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
938 (unsigned int)jobid ));
939 pjob_delete(ts->ev, ts->msg_ctx,
940 ts->sharename, jobid);
944 /* need to continue the the bottom of the function to
945 save the correct attributes */
948 /* maybe it hasn't been spooled yet */
950 /* if a job is not spooled and the process doesn't
951 exist then kill it. This cleans up after smbd
953 if (!process_exists_by_pid(pjob.pid)) {
954 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
955 (unsigned int)jobid, (unsigned int)pjob.pid ));
956 pjob_delete(ts->ev, ts->msg_ctx,
957 ts->sharename, jobid);
963 /* this check only makes sense for jobs submitted from Windows clients */
966 for (i=0;i<ts->qcount;i++) {
969 if ( pjob.status == LPQ_DELETED )
972 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
974 if (jobid == curr_jobid) {
976 /* try to clean up any jobs that need to be deleted */
978 if ( pjob.status == LPQ_DELETING ) {
981 result = (*(ts->print_if->job_delete))(
982 ts->sharename, ts->lprm_command, &pjob );
985 /* if we can't delete, then reset the job status */
986 pjob.status = LPQ_QUEUED;
987 pjob_store(ts->ev, ts->msg_ctx,
988 ts->sharename, jobid, &pjob);
991 /* if we deleted the job, the remove the tdb record */
994 ts->sharename, jobid);
995 pjob.status = LPQ_DELETED;
1005 /* The job isn't in the system queue - we have to assume it has
1006 completed, so delete the database entry. */
1008 if (i == ts->qcount) {
1010 /* A race can occur between the time a job is spooled and
1011 when it appears in the lpq output. This happens when
1012 the job is added to printing.tdb when another smbd
1013 running print_queue_update() has completed a lpq and
1014 is currently traversing the printing tdb and deleting jobs.
1015 Don't delete the job if it was submitted after the lpq_time. */
1017 if (pjob.starttime < ts->lpq_time) {
1018 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
1019 (unsigned int)jobid,
1020 (unsigned int)pjob.starttime,
1021 (unsigned int)ts->lpq_time ));
1022 pjob_delete(ts->ev, ts->msg_ctx,
1023 ts->sharename, jobid);
1029 /* Save the pjob attributes we will store.
1030 FIXME!!! This is the only place where queue->job
1031 represents the SMB jobid --jerry */
1033 ts->queue[i].job = jobid;
1034 ts->queue[i].size = pjob.size;
1035 ts->queue[i].page_count = pjob.page_count;
1036 ts->queue[i].status = pjob.status;
1037 ts->queue[i].priority = 1;
1038 ts->queue[i].time = pjob.starttime;
1039 fstrcpy(ts->queue[i].fs_user, pjob.user);
1040 fstrcpy(ts->queue[i].fs_file, pjob.jobname);
1047 /****************************************************************************
1048 Check if the print queue has been updated recently enough.
1049 ****************************************************************************/
1051 static void print_cache_flush(const char *sharename)
1054 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1058 slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
1059 tdb_store_int32(pdb->tdb, key, -1);
1060 release_print_db(pdb);
1063 /****************************************************************************
1064 Check if someone already thinks they are doing the update.
1065 ****************************************************************************/
1067 static pid_t get_updating_pid(const char *sharename)
1072 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1076 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
1077 key = string_tdb_data(keystr);
1079 data = tdb_fetch(pdb->tdb, key);
1080 release_print_db(pdb);
1081 if (!data.dptr || data.dsize != sizeof(pid_t)) {
1082 SAFE_FREE(data.dptr);
1086 updating_pid = IVAL(data.dptr, 0);
1087 SAFE_FREE(data.dptr);
1089 if (process_exists_by_pid(updating_pid))
1090 return updating_pid;
1095 /****************************************************************************
1096 Set the fact that we're doing the update, or have finished doing the update
1098 ****************************************************************************/
1100 static void set_updating_pid(const fstring sharename, bool updating)
1105 pid_t updating_pid = sys_getpid();
1108 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1113 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
1114 key = string_tdb_data(keystr);
1116 DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
1117 updating ? "" : "not ",
1121 tdb_delete(pdb->tdb, key);
1122 release_print_db(pdb);
1126 SIVAL( buffer, 0, updating_pid);
1128 data.dsize = 4; /* we always assume this is a 4 byte value */
1130 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1131 release_print_db(pdb);
1134 /****************************************************************************
1135 Sort print jobs by submittal time.
1136 ****************************************************************************/
1138 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
1149 /* Sort on job start time */
1151 if (j1->time == j2->time)
1153 return (j1->time > j2->time) ? 1 : -1;
1156 /****************************************************************************
1157 Store the sorted queue representation for later portmon retrieval.
1159 ****************************************************************************/
1161 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
1164 int max_reported_jobs = lp_max_reported_jobs(pts->snum);
1165 print_queue_struct *queue = pts->queue;
1168 unsigned int qcount;
1170 if (max_reported_jobs && (max_reported_jobs < pts->qcount))
1171 pts->qcount = max_reported_jobs;
1174 /* Work out the size. */
1176 data.dsize += tdb_pack(NULL, 0, "d", qcount);
1178 for (i = 0; i < pts->qcount; i++) {
1179 if ( queue[i].status == LPQ_DELETED )
1183 data.dsize += tdb_pack(NULL, 0, "ddddddff",
1184 (uint32)queue[i].job,
1185 (uint32)queue[i].size,
1186 (uint32)queue[i].page_count,
1187 (uint32)queue[i].status,
1188 (uint32)queue[i].priority,
1189 (uint32)queue[i].time,
1194 if ((data.dptr = (uint8 *)SMB_MALLOC(data.dsize)) == NULL)
1198 len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
1199 for (i = 0; i < pts->qcount; i++) {
1200 if ( queue[i].status == LPQ_DELETED )
1203 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
1204 (uint32)queue[i].job,
1205 (uint32)queue[i].size,
1206 (uint32)queue[i].page_count,
1207 (uint32)queue[i].status,
1208 (uint32)queue[i].priority,
1209 (uint32)queue[i].time,
1214 tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
1216 SAFE_FREE(data.dptr);
1220 static TDB_DATA get_jobs_added_data(struct tdb_print_db *pdb)
1226 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added"));
1227 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
1228 SAFE_FREE(data.dptr);
1235 static void check_job_added(const char *sharename, TDB_DATA data, uint32 jobid)
1238 unsigned int job_count = data.dsize / 4;
1240 for (i = 0; i < job_count; i++) {
1243 ch_jobid = IVAL(data.dptr, i*4);
1244 if (ch_jobid == jobid)
1245 remove_from_jobs_added(sharename, jobid);
1249 /****************************************************************************
1250 Check if the print queue has been updated recently enough.
1251 ****************************************************************************/
1253 static bool print_cache_expired(const char *sharename, bool check_pending)
1256 time_t last_qscan_time, time_now = time(NULL);
1257 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1258 bool result = False;
1263 snprintf(key, sizeof(key), "CACHE/%s", sharename);
1264 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1267 * Invalidate the queue for 3 reasons.
1268 * (1). last queue scan time == -1.
1269 * (2). Current time - last queue scan time > allowed cache time.
1270 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1271 * This last test picks up machines for which the clock has been moved
1272 * forward, an lpq scan done and then the clock moved back. Otherwise
1273 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1276 if (last_qscan_time == ((time_t)-1)
1277 || (time_now - last_qscan_time) >= lp_lpqcachetime()
1278 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
1281 time_t msg_pending_time;
1283 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1284 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1285 sharename, (int)last_qscan_time, (int)time_now,
1286 (int)lp_lpqcachetime() ));
1288 /* check if another smbd has already sent a message to update the
1289 queue. Give the pending message one minute to clear and
1290 then send another message anyways. Make sure to check for
1291 clocks that have been run forward and then back again. */
1293 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1296 && tdb_fetch_uint32( pdb->tdb, key, &u )
1297 && (msg_pending_time=u) > 0
1298 && msg_pending_time <= time_now
1299 && (time_now - msg_pending_time) < 60 )
1301 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1310 release_print_db(pdb);
1314 /****************************************************************************
1315 main work for updating the lpq cache for a printer queue
1316 ****************************************************************************/
1318 static void print_queue_update_internal( struct tevent_context *ev,
1319 struct messaging_context *msg_ctx,
1320 const char *sharename,
1321 struct printif *current_printif,
1322 char *lpq_command, char *lprm_command )
1325 print_queue_struct *queue = NULL;
1326 print_status_struct status;
1327 print_status_struct old_status;
1328 struct printjob *pjob;
1329 struct traverse_struct tstruct;
1332 fstring keystr, cachestr;
1333 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1339 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1340 sharename, current_printif->type, lpq_command));
1343 * Update the cache time FIRST ! Stops others even
1344 * attempting to get the lock and doing this
1345 * if the lpq takes a long time.
1348 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1349 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1351 /* get the current queue using the appropriate interface */
1352 ZERO_STRUCT(status);
1354 qcount = (*(current_printif->queue_get))(sharename,
1355 current_printif->type,
1356 lpq_command, &queue, &status);
1358 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1359 qcount, (qcount != 1) ? "s" : "", sharename));
1361 /* Sort the queue by submission time otherwise they are displayed
1364 TYPESAFE_QSORT(queue, qcount, printjob_comp);
1367 any job in the internal database that is marked as spooled
1368 and doesn't exist in the system queue is considered finished
1369 and removed from the database
1371 any job in the system database but not in the internal database
1372 is added as a unix job
1374 fill in any system job numbers as we go
1377 jcdata = get_jobs_added_data(pdb);
1379 for (i=0; i<qcount; i++) {
1380 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1382 if (jobid == (uint32)-1) {
1383 /* assume its a unix print job */
1384 print_unix_job(ev, msg_ctx,
1385 sharename, &queue[i], jobid);
1389 /* we have an active SMB print job - update its status */
1390 pjob = print_job_find(sharename, jobid);
1392 /* err, somethings wrong. Probably smbd was restarted
1393 with jobs in the queue. All we can do is treat them
1394 like unix jobs. Pity. */
1395 print_unix_job(ev, msg_ctx,
1396 sharename, &queue[i], jobid);
1400 pjob->sysjob = queue[i].job;
1402 /* don't reset the status on jobs to be deleted */
1404 if ( pjob->status != LPQ_DELETING )
1405 pjob->status = queue[i].status;
1407 pjob_store(ev, msg_ctx, sharename, jobid, pjob);
1409 check_job_added(sharename, jcdata, jobid);
1412 SAFE_FREE(jcdata.dptr);
1414 /* now delete any queued entries that don't appear in the
1416 tstruct.queue = queue;
1417 tstruct.qcount = qcount;
1419 tstruct.total_jobs = 0;
1420 tstruct.lpq_time = time(NULL);
1421 tstruct.sharename = sharename;
1422 tstruct.lprm_command = lprm_command;
1423 tstruct.print_if = current_printif;
1425 tstruct.msg_ctx = msg_ctx;
1427 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1429 /* Store the linearised queue, max jobs only. */
1430 store_queue_struct(pdb, &tstruct);
1432 SAFE_FREE(tstruct.queue);
1434 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1435 sharename, tstruct.total_jobs ));
1437 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1439 get_queue_status(sharename, &old_status);
1440 if (old_status.qcount != qcount)
1441 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1442 old_status.qcount, qcount, sharename));
1444 /* store the new queue status structure */
1445 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1446 key = string_tdb_data(keystr);
1448 status.qcount = qcount;
1449 data.dptr = (uint8 *)&status;
1450 data.dsize = sizeof(status);
1451 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1454 * Update the cache time again. We want to do this call
1455 * as little as possible...
1458 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1459 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1461 /* clear the msg pending record for this queue */
1463 snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1465 if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1466 /* log a message but continue on */
1468 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1472 release_print_db( pdb );
1477 /****************************************************************************
1478 Update the internal database from the system print queue for a queue.
1479 obtain a lock on the print queue before proceeding (needed when mutiple
1480 smbd processes maytry to update the lpq cache concurrently).
1481 ****************************************************************************/
1483 static void print_queue_update_with_lock( struct tevent_context *ev,
1484 struct messaging_context *msg_ctx,
1485 const char *sharename,
1486 struct printif *current_printif,
1487 char *lpq_command, char *lprm_command )
1490 struct tdb_print_db *pdb;
1492 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1493 pdb = get_print_db_byname(sharename);
1497 if ( !print_cache_expired(sharename, False) ) {
1498 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1499 release_print_db(pdb);
1504 * Check to see if someone else is doing this update.
1505 * This is essentially a mutex on the update.
1508 if (get_updating_pid(sharename) != -1) {
1509 release_print_db(pdb);
1513 /* Lock the queue for the database update */
1515 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1516 /* Only wait 10 seconds for this. */
1517 if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
1518 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1519 release_print_db(pdb);
1524 * Ensure that no one else got in here.
1525 * If the updating pid is still -1 then we are
1529 if (get_updating_pid(sharename) != -1) {
1531 * Someone else is doing the update, exit.
1533 tdb_unlock_bystring(pdb->tdb, keystr);
1534 release_print_db(pdb);
1539 * We're going to do the update ourselves.
1542 /* Tell others we're doing the update. */
1543 set_updating_pid(sharename, True);
1546 * Allow others to enter and notice we're doing
1550 tdb_unlock_bystring(pdb->tdb, keystr);
1552 /* do the main work now */
1554 print_queue_update_internal(ev, msg_ctx,
1555 sharename, current_printif,
1556 lpq_command, lprm_command);
1558 /* Delete our pid from the db. */
1559 set_updating_pid(sharename, False);
1560 release_print_db(pdb);
1563 /****************************************************************************
1564 this is the receive function of the background lpq updater
1565 ****************************************************************************/
1566 void print_queue_receive(struct messaging_context *msg,
1569 struct server_id server_id,
1573 char *lpqcommand = NULL, *lprmcommand = NULL;
1577 len = tdb_unpack( (uint8 *)data->data, data->length, "fdPP",
1584 SAFE_FREE(lpqcommand);
1585 SAFE_FREE(lprmcommand);
1586 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1590 print_queue_update_with_lock(server_event_context(), msg, sharename,
1591 get_printer_fns_from_type((enum printing_types)printing_type),
1592 lpqcommand, lprmcommand );
1594 SAFE_FREE(lpqcommand);
1595 SAFE_FREE(lprmcommand);
1599 static void printing_pause_fd_handler(struct tevent_context *ev,
1600 struct tevent_fd *fde,
1605 * If pause_pipe[1] is closed it means the parent smbd
1606 * and children exited or aborted.
1608 exit_server_cleanly(NULL);
1611 extern struct child_pid *children;
1612 extern int num_children;
1614 static void add_child_pid(pid_t pid)
1616 struct child_pid *child;
1618 child = SMB_MALLOC_P(struct child_pid);
1619 if (child == NULL) {
1620 DEBUG(0, ("Could not add child struct -- malloc failed\n"));
1624 DLIST_ADD(children, child);
1628 static pid_t background_lpq_updater_pid = -1;
1630 /****************************************************************************
1631 main thread of the background lpq updater
1632 ****************************************************************************/
1633 void start_background_queue(struct tevent_context *ev,
1634 struct messaging_context *msg_ctx)
1636 /* Use local variables for this as we don't
1637 * need to save the parent side of this, just
1638 * ensure it closes when the process exits.
1642 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1644 if (pipe(pause_pipe) == -1) {
1645 DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno) ));
1649 background_lpq_updater_pid = sys_fork();
1651 if (background_lpq_updater_pid == -1) {
1652 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1656 /* Track the printing pid along with other smbd children */
1657 add_child_pid(background_lpq_updater_pid);
1659 if(background_lpq_updater_pid == 0) {
1660 struct tevent_fd *fde;
1665 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1667 close(pause_pipe[0]);
1670 status = reinit_after_fork(msg_ctx, ev, procid_self(), true);
1672 if (!NT_STATUS_IS_OK(status)) {
1673 DEBUG(0,("reinit_after_fork() failed\n"));
1674 smb_panic("reinit_after_fork() failed");
1677 smbd_setup_sig_term_handler();
1678 smbd_setup_sig_hup_handler(ev, msg_ctx);
1680 if (!serverid_register(procid_self(),
1681 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
1682 |FLAG_MSG_PRINT_GENERAL)) {
1686 if (!locking_init()) {
1690 messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE,
1691 print_queue_receive);
1693 fde = tevent_add_fd(ev, ev, pause_pipe[1], TEVENT_FD_READ,
1694 printing_pause_fd_handler,
1697 DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
1698 smb_panic("tevent_add_fd() failed for pause_pipe");
1701 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1702 ret = tevent_loop_wait(ev);
1703 /* should not be reached */
1704 DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
1705 ret, (ret == 0) ? "out of events" : strerror(errno)));
1709 close(pause_pipe[1]);
1712 /****************************************************************************
1713 update the internal database from the system print queue for a queue
1714 ****************************************************************************/
1716 static void print_queue_update(struct messaging_context *msg_ctx,
1717 int snum, bool force)
1721 char *lpqcommand = NULL;
1722 char *lprmcommand = NULL;
1723 uint8 *buffer = NULL;
1726 struct tdb_print_db *pdb;
1728 struct printif *current_printif;
1729 TALLOC_CTX *ctx = talloc_tos();
1731 fstrcpy( sharename, lp_const_servicename(snum));
1733 /* don't strip out characters like '$' from the printername */
1735 lpqcommand = talloc_string_sub2(ctx,
1736 lp_lpqcommand(snum),
1738 lp_printername(snum),
1739 false, false, false);
1743 lpqcommand = talloc_sub_advanced(ctx,
1744 lp_servicename(snum),
1745 current_user_info.unix_name,
1747 current_user.ut.gid,
1748 get_current_username(),
1749 current_user_info.domain,
1755 lprmcommand = talloc_string_sub2(ctx,
1756 lp_lprmcommand(snum),
1758 lp_printername(snum),
1759 false, false, false);
1763 lprmcommand = talloc_sub_advanced(ctx,
1764 lp_servicename(snum),
1765 current_user_info.unix_name,
1767 current_user.ut.gid,
1768 get_current_username(),
1769 current_user_info.domain,
1776 * Make sure that the background queue process exists.
1777 * Otherwise just do the update ourselves
1780 if ( force || background_lpq_updater_pid == -1 ) {
1781 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1782 current_printif = get_printer_fns( snum );
1783 print_queue_update_with_lock(server_event_context(), msg_ctx,
1784 sharename, current_printif,
1785 lpqcommand, lprmcommand);
1790 type = lp_printing(snum);
1792 /* get the length */
1794 len = tdb_pack( NULL, 0, "fdPP",
1800 buffer = SMB_XMALLOC_ARRAY( uint8, len );
1802 /* now pack the buffer */
1803 newlen = tdb_pack( buffer, len, "fdPP",
1809 SMB_ASSERT( newlen == len );
1811 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1812 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1813 sharename, type, lpqcommand, lprmcommand ));
1815 /* here we set a msg pending record for other smbd processes
1816 to throttle the number of duplicate print_queue_update msgs
1819 pdb = get_print_db_byname(sharename);
1825 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1827 if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1828 /* log a message but continue on */
1830 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1834 release_print_db( pdb );
1836 /* finally send the message */
1838 messaging_send_buf(msg_ctx, pid_to_procid(background_lpq_updater_pid),
1839 MSG_PRINTER_UPDATE, (uint8 *)buffer, len);
1841 SAFE_FREE( buffer );
1846 /****************************************************************************
1847 Create/Update an entry in the print tdb that will allow us to send notify
1848 updates only to interested smbd's.
1849 ****************************************************************************/
1851 bool print_notify_register_pid(int snum)
1854 struct tdb_print_db *pdb = NULL;
1855 TDB_CONTEXT *tdb = NULL;
1856 const char *printername;
1857 uint32 mypid = (uint32)sys_getpid();
1861 /* if (snum == -1), then the change notify request was
1862 on a print server handle and we need to register on
1867 int num_services = lp_numservices();
1870 for ( idx=0; idx<num_services; idx++ ) {
1871 if (lp_snum_ok(idx) && lp_print_ok(idx) )
1872 print_notify_register_pid(idx);
1877 else /* register for a specific printer */
1879 printername = lp_const_servicename(snum);
1880 pdb = get_print_db_byname(printername);
1886 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1887 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1890 release_print_db(pdb);
1894 data = get_printer_notify_pid_list( tdb, printername, True );
1896 /* Add ourselves and increase the refcount. */
1898 for (i = 0; i < data.dsize; i += 8) {
1899 if (IVAL(data.dptr,i) == mypid) {
1900 uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1901 SIVAL(data.dptr, i+4, new_refcount);
1906 if (i == data.dsize) {
1907 /* We weren't in the list. Realloc. */
1908 data.dptr = (uint8 *)SMB_REALLOC(data.dptr, data.dsize + 8);
1910 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1915 SIVAL(data.dptr,data.dsize - 8,mypid);
1916 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1919 /* Store back the record. */
1920 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1921 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1922 list for printer %s\n", printername));
1930 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1932 release_print_db(pdb);
1933 SAFE_FREE(data.dptr);
1937 /****************************************************************************
1938 Update an entry in the print tdb that will allow us to send notify
1939 updates only to interested smbd's.
1940 ****************************************************************************/
1942 bool print_notify_deregister_pid(int snum)
1945 struct tdb_print_db *pdb = NULL;
1946 TDB_CONTEXT *tdb = NULL;
1947 const char *printername;
1948 uint32 mypid = (uint32)sys_getpid();
1952 /* if ( snum == -1 ), we are deregister a print server handle
1953 which means to deregister on all print queues */
1957 int num_services = lp_numservices();
1960 for ( idx=0; idx<num_services; idx++ ) {
1961 if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1962 print_notify_deregister_pid(idx);
1967 else /* deregister a specific printer */
1969 printername = lp_const_servicename(snum);
1970 pdb = get_print_db_byname(printername);
1976 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1977 DEBUG(0,("print_notify_register_pid: Failed to lock \
1978 printer %s database\n", printername));
1980 release_print_db(pdb);
1984 data = get_printer_notify_pid_list( tdb, printername, True );
1986 /* Reduce refcount. Remove ourselves if zero. */
1988 for (i = 0; i < data.dsize; ) {
1989 if (IVAL(data.dptr,i) == mypid) {
1990 uint32 refcount = IVAL(data.dptr, i+4);
1994 if (refcount == 0) {
1995 if (data.dsize - i > 8)
1996 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
2000 SIVAL(data.dptr, i+4, refcount);
2006 if (data.dsize == 0)
2007 SAFE_FREE(data.dptr);
2009 /* Store back the record. */
2010 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
2011 DEBUG(0,("print_notify_register_pid: Failed to update pid \
2012 list for printer %s\n", printername));
2020 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
2022 release_print_db(pdb);
2023 SAFE_FREE(data.dptr);
2027 /****************************************************************************
2028 Check if a jobid is valid. It is valid if it exists in the database.
2029 ****************************************************************************/
2031 bool print_job_exists(const char* sharename, uint32 jobid)
2033 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2039 ret = tdb_exists(pdb->tdb, print_key(jobid, &tmp));
2040 release_print_db(pdb);
2044 /****************************************************************************
2045 Give the filename used for a jobid.
2046 Only valid for the process doing the spooling and when the job
2047 has not been spooled.
2048 ****************************************************************************/
2050 char *print_job_fname(const char* sharename, uint32 jobid)
2052 struct printjob *pjob = print_job_find(sharename, jobid);
2053 if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
2055 return pjob->filename;
2059 /****************************************************************************
2060 Give the filename used for a jobid.
2061 Only valid for the process doing the spooling and when the job
2062 has not been spooled.
2063 ****************************************************************************/
2065 struct spoolss_DeviceMode *print_job_devmode(const char* sharename, uint32 jobid)
2067 struct printjob *pjob = print_job_find(sharename, jobid);
2072 return pjob->devmode;
2075 /****************************************************************************
2076 Set the name of a job. Only possible for owner.
2077 ****************************************************************************/
2079 bool print_job_set_name(struct tevent_context *ev,
2080 struct messaging_context *msg_ctx,
2081 const char *sharename, uint32 jobid, const char *name)
2083 struct printjob *pjob;
2085 pjob = print_job_find(sharename, jobid);
2086 if (!pjob || pjob->pid != sys_getpid())
2089 fstrcpy(pjob->jobname, name);
2090 return pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2093 /****************************************************************************
2094 Get the name of a job. Only possible for owner.
2095 ****************************************************************************/
2097 bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t jobid, char **name)
2099 struct printjob *pjob;
2101 pjob = print_job_find(sharename, jobid);
2102 if (!pjob || pjob->pid != sys_getpid()) {
2106 *name = talloc_strdup(mem_ctx, pjob->jobname);
2115 /***************************************************************************
2116 Remove a jobid from the 'jobs added' list.
2117 ***************************************************************************/
2119 static bool remove_from_jobs_added(const char* sharename, uint32 jobid)
2121 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2123 size_t job_count, i;
2125 bool gotlock = False;
2133 key = string_tdb_data("INFO/jobs_added");
2135 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
2140 data = tdb_fetch(pdb->tdb, key);
2142 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
2145 job_count = data.dsize / 4;
2146 for (i = 0; i < job_count; i++) {
2149 ch_jobid = IVAL(data.dptr, i*4);
2150 if (ch_jobid == jobid) {
2151 if (i < job_count -1 )
2152 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
2154 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
2164 tdb_chainunlock(pdb->tdb, key);
2165 SAFE_FREE(data.dptr);
2166 release_print_db(pdb);
2168 DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid ));
2170 DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid ));
2174 /****************************************************************************
2175 Delete a print job - don't update queue.
2176 ****************************************************************************/
2178 static bool print_job_delete1(struct tevent_context *ev,
2179 struct messaging_context *msg_ctx,
2180 int snum, uint32 jobid)
2182 const char* sharename = lp_const_servicename(snum);
2183 struct printjob *pjob = print_job_find(sharename, jobid);
2185 struct printif *current_printif = get_printer_fns( snum );
2191 * If already deleting just return.
2194 if (pjob->status == LPQ_DELETING)
2197 /* Hrm - we need to be able to cope with deleting a job before it
2198 has reached the spooler. Just mark it as LPQ_DELETING and
2199 let the print_queue_update() code rmeove the record */
2202 if (pjob->sysjob == -1) {
2203 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
2206 /* Set the tdb entry to be deleting. */
2208 pjob->status = LPQ_DELETING;
2209 pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2211 if (pjob->spooled && pjob->sysjob != -1)
2213 result = (*(current_printif->job_delete))(
2214 lp_printername(snum),
2215 lp_lprmcommand(snum),
2218 /* Delete the tdb entry if the delete succeeded or the job hasn't
2222 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2227 pjob_delete(ev, msg_ctx, sharename, jobid);
2228 /* Ensure we keep a rough count of the number of total jobs... */
2229 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
2230 release_print_db(pdb);
2234 remove_from_jobs_added( sharename, jobid );
2236 return (result == 0);
2239 /****************************************************************************
2240 Return true if the current user owns the print job.
2241 ****************************************************************************/
2243 static bool is_owner(const struct auth_serversupplied_info *server_info,
2244 const char *servicename,
2247 struct printjob *pjob = print_job_find(servicename, jobid);
2249 if (!pjob || !server_info)
2252 return strequal(pjob->user, server_info->sanitized_username);
2255 /****************************************************************************
2257 ****************************************************************************/
2259 WERROR print_job_delete(const struct auth_serversupplied_info *server_info,
2260 struct messaging_context *msg_ctx,
2261 int snum, uint32_t jobid)
2263 const char* sharename = lp_const_servicename(snum);
2264 struct printjob *pjob;
2268 owner = is_owner(server_info, lp_const_servicename(snum), jobid);
2270 /* Check access against security descriptor or whether the user
2274 !print_access_check(server_info, msg_ctx, snum,
2275 JOB_ACCESS_ADMINISTER)) {
2276 DEBUG(3, ("delete denied by security descriptor\n"));
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) );
2286 return WERR_ACCESS_DENIED;
2290 * get the spooled filename of the print job
2291 * if this works, then the file has not been spooled
2292 * to the underlying print system. Just delete the
2293 * spool file & return.
2296 fname = print_job_fname(sharename, jobid);
2297 if (fname != NULL) {
2298 /* remove the spool file */
2299 DEBUG(10, ("print_job_delete: "
2300 "Removing spool file [%s]\n", fname));
2301 if (unlink(fname) == -1) {
2302 return map_werror_from_unix(errno);
2306 if (!print_job_delete1(server_event_context(), msg_ctx, snum, jobid)) {
2307 return WERR_ACCESS_DENIED;
2310 /* force update the database and say the delete failed if the
2313 print_queue_update(msg_ctx, snum, True);
2315 pjob = print_job_find(sharename, jobid);
2316 if (pjob && (pjob->status != LPQ_DELETING)) {
2317 return WERR_ACCESS_DENIED;
2320 return WERR_PRINTER_HAS_JOBS_QUEUED;
2323 /****************************************************************************
2325 ****************************************************************************/
2327 bool print_job_pause(const struct auth_serversupplied_info *server_info,
2328 struct messaging_context *msg_ctx,
2329 int snum, uint32 jobid, WERROR *errcode)
2331 const char* sharename = lp_const_servicename(snum);
2332 struct printjob *pjob;
2334 struct printif *current_printif = get_printer_fns( snum );
2336 pjob = print_job_find(sharename, jobid);
2338 if (!pjob || !server_info) {
2339 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2340 (unsigned int)jobid ));
2344 if (!pjob->spooled || pjob->sysjob == -1) {
2345 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2346 (int)pjob->sysjob, (unsigned int)jobid ));
2350 if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2351 !print_access_check(server_info, msg_ctx, snum,
2352 JOB_ACCESS_ADMINISTER)) {
2353 DEBUG(3, ("pause denied by security descriptor\n"));
2355 /* BEGIN_ADMIN_LOG */
2356 sys_adminlog( LOG_ERR,
2357 "Permission denied-- user not allowed to delete, \
2358 pause, or resume print job. User name: %s. Printer name: %s.",
2359 uidtoname(server_info->utok.uid),
2360 lp_printername(snum) );
2363 *errcode = WERR_ACCESS_DENIED;
2367 /* need to pause the spooled entry */
2368 ret = (*(current_printif->job_pause))(snum, pjob);
2371 *errcode = WERR_INVALID_PARAM;
2375 /* force update the database */
2376 print_cache_flush(lp_const_servicename(snum));
2378 /* Send a printer notify message */
2380 notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2383 /* how do we tell if this succeeded? */
2388 /****************************************************************************
2390 ****************************************************************************/
2392 bool print_job_resume(const struct auth_serversupplied_info *server_info,
2393 struct messaging_context *msg_ctx,
2394 int snum, uint32 jobid, WERROR *errcode)
2396 const char *sharename = lp_const_servicename(snum);
2397 struct printjob *pjob;
2399 struct printif *current_printif = get_printer_fns( snum );
2401 pjob = print_job_find(sharename, jobid);
2403 if (!pjob || !server_info) {
2404 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2405 (unsigned int)jobid ));
2409 if (!pjob->spooled || pjob->sysjob == -1) {
2410 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2411 (int)pjob->sysjob, (unsigned int)jobid ));
2415 if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2416 !print_access_check(server_info, msg_ctx, snum,
2417 JOB_ACCESS_ADMINISTER)) {
2418 DEBUG(3, ("resume denied by security descriptor\n"));
2419 *errcode = WERR_ACCESS_DENIED;
2421 /* BEGIN_ADMIN_LOG */
2422 sys_adminlog( LOG_ERR,
2423 "Permission denied-- user not allowed to delete, \
2424 pause, or resume print job. User name: %s. Printer name: %s.",
2425 uidtoname(server_info->utok.uid),
2426 lp_printername(snum) );
2431 ret = (*(current_printif->job_resume))(snum, pjob);
2434 *errcode = WERR_INVALID_PARAM;
2438 /* force update the database */
2439 print_cache_flush(lp_const_servicename(snum));
2441 /* Send a printer notify message */
2443 notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2449 /****************************************************************************
2450 Write to a print file.
2451 ****************************************************************************/
2453 ssize_t print_job_write(struct tevent_context *ev,
2454 struct messaging_context *msg_ctx,
2455 int snum, uint32 jobid, const char *buf, size_t size)
2457 const char* sharename = lp_const_servicename(snum);
2458 ssize_t return_code;
2459 struct printjob *pjob;
2461 pjob = print_job_find(sharename, jobid);
2465 /* don't allow another process to get this info - it is meaningless */
2466 if (pjob->pid != sys_getpid())
2469 /* if SMBD is spooling this can't be allowed */
2470 if (pjob->status == PJOB_SMBD_SPOOLING) {
2474 return_code = write_data(pjob->fd, buf, size);
2476 if (return_code>0) {
2478 pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2483 /****************************************************************************
2484 Get the queue status - do not update if db is out of date.
2485 ****************************************************************************/
2487 static int get_queue_status(const char* sharename, print_status_struct *status)
2491 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2495 ZERO_STRUCTP(status);
2502 fstr_sprintf(keystr, "STATUS/%s", sharename);
2503 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2505 if (data.dsize == sizeof(print_status_struct))
2506 /* this memcpy is ok since the status struct was
2507 not packed before storing it in the tdb */
2508 memcpy(status, data.dptr, sizeof(print_status_struct));
2509 SAFE_FREE(data.dptr);
2512 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2513 release_print_db(pdb);
2514 return (len == -1 ? 0 : len);
2517 /****************************************************************************
2518 Determine the number of jobs in a queue.
2519 ****************************************************************************/
2521 int print_queue_length(struct messaging_context *msg_ctx, int snum,
2522 print_status_struct *pstatus)
2524 const char* sharename = lp_const_servicename( snum );
2525 print_status_struct status;
2528 ZERO_STRUCT( status );
2530 /* make sure the database is up to date */
2531 if (print_cache_expired(lp_const_servicename(snum), True))
2532 print_queue_update(msg_ctx, snum, False);
2534 /* also fetch the queue status */
2535 memset(&status, 0, sizeof(status));
2536 len = get_queue_status(sharename, &status);
2544 /***************************************************************************
2545 Allocate a jobid. Hold the lock for as short a time as possible.
2546 ***************************************************************************/
2548 static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum,
2549 const char *sharename, uint32 *pjobid)
2553 enum TDB_ERROR terr;
2556 *pjobid = (uint32)-1;
2558 for (i = 0; i < 3; i++) {
2559 /* Lock the database - only wait 20 seconds. */
2560 ret = tdb_lock_bystring_with_timeout(pdb->tdb,
2561 "INFO/nextjob", 20);
2563 DEBUG(0, ("allocate_print_jobid: "
2564 "Failed to lock printing database %s\n",
2566 terr = tdb_error(pdb->tdb);
2567 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2570 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2571 terr = tdb_error(pdb->tdb);
2572 if (terr != TDB_ERR_NOEXIST) {
2573 DEBUG(0, ("allocate_print_jobid: "
2574 "Failed to fetch INFO/nextjob "
2575 "for print queue %s\n", sharename));
2576 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2577 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2579 DEBUG(10, ("allocate_print_jobid: "
2580 "No existing jobid in %s\n", sharename));
2584 DEBUG(10, ("allocate_print_jobid: "
2585 "Read jobid %u from %s\n", jobid, sharename));
2587 jobid = NEXT_JOBID(jobid);
2589 ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid);
2591 terr = tdb_error(pdb->tdb);
2592 DEBUG(3, ("allocate_print_jobid: "
2593 "Failed to store INFO/nextjob.\n"));
2594 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2595 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2598 /* We've finished with the INFO/nextjob lock. */
2599 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2601 if (!print_job_exists(sharename, jobid)) {
2604 DEBUG(10, ("allocate_print_jobid: "
2605 "Found jobid %u in %s\n", jobid, sharename));
2609 DEBUG(0, ("allocate_print_jobid: "
2610 "Failed to allocate a print job for queue %s\n",
2612 /* Probably full... */
2613 return WERR_NO_SPOOL_SPACE;
2616 /* Store a dummy placeholder. */
2622 if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
2623 TDB_INSERT) == -1) {
2624 DEBUG(3, ("allocate_print_jobid: "
2625 "jobid (%d) failed to store placeholder.\n",
2627 terr = tdb_error(pdb->tdb);
2628 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2636 /***************************************************************************
2637 Append a jobid to the 'jobs added' list.
2638 ***************************************************************************/
2640 static bool add_to_jobs_added(struct tdb_print_db *pdb, uint32 jobid)
2645 SIVAL(&store_jobid, 0, jobid);
2646 data.dptr = (uint8 *)&store_jobid;
2649 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid ));
2651 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_added"),
2656 /***************************************************************************
2657 Do all checks needed to determine if we can start a job.
2658 ***************************************************************************/
2660 static WERROR print_job_checks(const struct auth_serversupplied_info *server_info,
2661 struct messaging_context *msg_ctx,
2662 int snum, int *njobs)
2664 const char *sharename = lp_const_servicename(snum);
2665 uint64_t dspace, dsize;
2669 if (!print_access_check(server_info, msg_ctx, snum,
2670 PRINTER_ACCESS_USE)) {
2671 DEBUG(3, ("print_job_checks: "
2672 "job start denied by security descriptor\n"));
2673 return WERR_ACCESS_DENIED;
2676 if (!print_time_access_check(server_info, msg_ctx, sharename)) {
2677 DEBUG(3, ("print_job_checks: "
2678 "job start denied by time check\n"));
2679 return WERR_ACCESS_DENIED;
2682 /* see if we have sufficient disk space */
2683 if (lp_minprintspace(snum)) {
2684 minspace = lp_minprintspace(snum);
2685 ret = sys_fsusage(lp_pathname(snum), &dspace, &dsize);
2686 if (ret == 0 && dspace < 2*minspace) {
2687 DEBUG(3, ("print_job_checks: "
2688 "disk space check failed.\n"));
2689 return WERR_NO_SPOOL_SPACE;
2693 /* for autoloaded printers, check that the printcap entry still exists */
2694 if (lp_autoloaded(snum) && !pcap_printername_ok(sharename)) {
2695 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2697 return WERR_ACCESS_DENIED;
2700 /* Insure the maximum queue size is not violated */
2701 *njobs = print_queue_length(msg_ctx, snum, NULL);
2702 if (*njobs > lp_maxprintjobs(snum)) {
2703 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2704 "larger than max printjobs per queue (%d).\n",
2705 sharename, *njobs, lp_maxprintjobs(snum)));
2706 return WERR_NO_SPOOL_SPACE;
2712 /***************************************************************************
2714 ***************************************************************************/
2716 static WERROR print_job_spool_file(int snum, uint32_t jobid,
2717 const char *output_file,
2718 struct printjob *pjob)
2725 /* if this file is within the printer path, it means that smbd
2726 * is spooling it and will pass us control when it is finished.
2727 * Verify that the file name is ok, within path, and it is
2728 * already already there */
2730 path = lp_pathname(snum);
2732 if (strncmp(output_file, path, len) == 0 &&
2733 (output_file[len - 1] == '/' || output_file[len] == '/')) {
2735 /* verify path is not too long */
2736 if (strlen(output_file) >= sizeof(pjob->filename)) {
2737 return WERR_INVALID_NAME;
2740 /* verify that the file exists */
2741 if (sys_stat(output_file, &st, false) != 0) {
2742 return WERR_INVALID_NAME;
2745 fstrcpy(pjob->filename, output_file);
2747 DEBUG(3, ("print_job_spool_file:"
2748 "External spooling activated"));
2750 /* we do not open the file until spooling is done */
2752 pjob->status = PJOB_SMBD_SPOOLING;
2758 slprintf(pjob->filename, sizeof(pjob->filename)-1,
2759 "%s/%s%.8u.XXXXXX", lp_pathname(snum),
2760 PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2761 pjob->fd = mkstemp(pjob->filename);
2763 if (pjob->fd == -1) {
2764 werr = map_werror_from_unix(errno);
2765 if (W_ERROR_EQUAL(werr, WERR_ACCESS_DENIED)) {
2766 /* Common setup error, force a report. */
2767 DEBUG(0, ("print_job_spool_file: "
2768 "insufficient permissions to open spool "
2769 "file %s.\n", pjob->filename));
2771 /* Normal case, report at level 3 and above. */
2772 DEBUG(3, ("print_job_spool_file: "
2773 "can't open spool file %s\n",
2782 /***************************************************************************
2783 Start spooling a job - return the jobid.
2784 ***************************************************************************/
2786 WERROR print_job_start(const struct auth_serversupplied_info *server_info,
2787 struct messaging_context *msg_ctx,
2788 const char *clientmachine,
2789 int snum, const char *docname, const char *filename,
2790 struct spoolss_DeviceMode *devmode, uint32_t *_jobid)
2794 struct printjob pjob;
2795 const char *sharename = lp_const_servicename(snum);
2796 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2801 return WERR_INTERNAL_DB_CORRUPTION;
2804 path = lp_pathname(snum);
2806 werr = print_job_checks(server_info, msg_ctx, snum, &njobs);
2807 if (!W_ERROR_IS_OK(werr)) {
2808 release_print_db(pdb);
2812 DEBUG(10, ("print_job_start: "
2813 "Queue %s number of jobs (%d), max printjobs = %d\n",
2814 sharename, njobs, lp_maxprintjobs(snum)));
2816 werr = allocate_print_jobid(pdb, snum, sharename, &jobid);
2817 if (!W_ERROR_IS_OK(werr)) {
2821 /* create the database entry */
2825 pjob.pid = sys_getpid();
2828 pjob.starttime = time(NULL);
2829 pjob.status = LPQ_SPOOLING;
2831 pjob.spooled = False;
2833 pjob.devmode = devmode;
2835 fstrcpy(pjob.jobname, docname);
2837 fstrcpy(pjob.clientmachine, clientmachine);
2839 fstrcpy(pjob.user, lp_printjob_username(snum));
2840 standard_sub_advanced(sharename, server_info->sanitized_username,
2841 path, server_info->utok.gid,
2842 server_info->sanitized_username,
2843 server_info->info3->base.domain.string,
2844 pjob.user, sizeof(pjob.user)-1);
2845 /* ensure NULL termination */
2846 pjob.user[sizeof(pjob.user)-1] = '\0';
2848 fstrcpy(pjob.queuename, lp_const_servicename(snum));
2850 /* we have a job entry - now create the spool file */
2851 werr = print_job_spool_file(snum, jobid, filename, &pjob);
2852 if (!W_ERROR_IS_OK(werr)) {
2856 pjob_store(server_event_context(), msg_ctx, sharename, jobid, &pjob);
2858 /* Update the 'jobs added' entry used by print_queue_status. */
2859 add_to_jobs_added(pdb, jobid);
2861 /* Ensure we keep a rough count of the number of total jobs... */
2862 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2864 release_print_db(pdb);
2871 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
2874 release_print_db(pdb);
2876 DEBUG(3, ("print_job_start: returning fail. "
2877 "Error = %s\n", win_errstr(werr)));
2881 /****************************************************************************
2882 Update the number of pages spooled to jobid
2883 ****************************************************************************/
2885 void print_job_endpage(struct messaging_context *msg_ctx,
2886 int snum, uint32 jobid)
2888 const char* sharename = lp_const_servicename(snum);
2889 struct printjob *pjob;
2891 pjob = print_job_find(sharename, jobid);
2894 /* don't allow another process to get this info - it is meaningless */
2895 if (pjob->pid != sys_getpid())
2899 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
2902 /****************************************************************************
2903 Print a file - called on closing the file. This spools the job.
2904 If normal close is false then we're tearing down the jobs - treat as an
2906 ****************************************************************************/
2908 NTSTATUS print_job_end(struct messaging_context *msg_ctx, int snum,
2909 uint32 jobid, enum file_close_type close_type)
2911 const char* sharename = lp_const_servicename(snum);
2912 struct printjob *pjob;
2914 SMB_STRUCT_STAT sbuf;
2915 struct printif *current_printif = get_printer_fns( snum );
2916 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2918 pjob = print_job_find(sharename, jobid);
2921 return NT_STATUS_PRINT_CANCELLED;
2924 if (pjob->spooled || pjob->pid != sys_getpid()) {
2925 return NT_STATUS_ACCESS_DENIED;
2928 if (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) {
2929 if (pjob->status == PJOB_SMBD_SPOOLING) {
2930 /* take over the file now, smbd is done */
2931 if (sys_stat(pjob->filename, &sbuf, false) != 0) {
2932 status = map_nt_error_from_unix(errno);
2933 DEBUG(3, ("print_job_end: "
2934 "stat file failed for jobid %d\n",
2939 pjob->status = LPQ_SPOOLING;
2943 if ((sys_fstat(pjob->fd, &sbuf, false) != 0)) {
2944 status = map_nt_error_from_unix(errno);
2946 DEBUG(3, ("print_job_end: "
2947 "stat file failed for jobid %d\n",
2955 pjob->size = sbuf.st_ex_size;
2959 * Not a normal close, something has gone wrong. Cleanup.
2961 if (pjob->fd != -1) {
2967 /* Technically, this is not quite right. If the printer has a separator
2968 * page turned on, the NT spooler prints the separator page even if the
2969 * print job is 0 bytes. 010215 JRR */
2970 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2971 /* don't bother spooling empty files or something being deleted. */
2972 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2973 pjob->filename, pjob->size ? "deleted" : "zero length" ));
2974 unlink(pjob->filename);
2975 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
2976 return NT_STATUS_OK;
2979 ret = (*(current_printif->job_submit))(snum, pjob);
2982 status = NT_STATUS_PRINT_CANCELLED;
2986 /* The print job has been successfully handed over to the back-end */
2988 pjob->spooled = True;
2989 pjob->status = LPQ_QUEUED;
2990 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
2992 /* make sure the database is up to date */
2993 if (print_cache_expired(lp_const_servicename(snum), True))
2994 print_queue_update(msg_ctx, snum, False);
2996 return NT_STATUS_OK;
3000 /* The print job was not successfully started. Cleanup */
3001 /* Still need to add proper error return propagation! 010122:JRR */
3003 unlink(pjob->filename);
3004 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
3008 /****************************************************************************
3009 Get a snapshot of jobs in the system without traversing.
3010 ****************************************************************************/
3012 static bool get_stored_queue_info(struct messaging_context *msg_ctx,
3013 struct tdb_print_db *pdb, int snum,
3014 int *pcount, print_queue_struct **ppqueue)
3016 TDB_DATA data, cgdata, jcdata;
3017 print_queue_struct *queue = NULL;
3019 uint32 extra_count = 0;
3020 uint32_t changed_count = 0;
3021 int total_count = 0;
3024 int max_reported_jobs = lp_max_reported_jobs(snum);
3026 const char* sharename = lp_servicename(snum);
3028 /* make sure the database is up to date */
3029 if (print_cache_expired(lp_const_servicename(snum), True))
3030 print_queue_update(msg_ctx, snum, False);
3036 ZERO_STRUCT(cgdata);
3038 /* Get the stored queue data. */
3039 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
3041 if (data.dptr && data.dsize >= sizeof(qcount))
3042 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
3044 /* Get the added jobs list. */
3045 cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added"));
3046 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
3047 extra_count = cgdata.dsize/4;
3049 /* Get the changed jobs list. */
3050 jcdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
3051 if (jcdata.dptr != NULL && (jcdata.dsize % 4 == 0))
3052 changed_count = jcdata.dsize / 4;
3054 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
3056 /* Allocate the queue size. */
3057 if (qcount == 0 && extra_count == 0)
3060 if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
3063 /* Retrieve the linearised queue data. */
3065 for( i = 0; i < qcount; i++) {
3066 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
3067 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
3076 queue[i].job = qjob;
3077 queue[i].size = qsize;
3078 queue[i].page_count = qpage_count;
3079 queue[i].status = qstatus;
3080 queue[i].priority = qpriority;
3081 queue[i].time = qtime;
3084 total_count = qcount;
3086 /* Add new jobids to the queue. */
3087 for( i = 0; i < extra_count; i++) {
3089 struct printjob *pjob;
3091 jobid = IVAL(cgdata.dptr, i*4);
3092 DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid));
3093 pjob = print_job_find(lp_const_servicename(snum), jobid);
3095 DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid));
3096 remove_from_jobs_added(sharename, jobid);
3100 queue[total_count].job = jobid;
3101 queue[total_count].size = pjob->size;
3102 queue[total_count].page_count = pjob->page_count;
3103 queue[total_count].status = pjob->status;
3104 queue[total_count].priority = 1;
3105 queue[total_count].time = pjob->starttime;
3106 fstrcpy(queue[total_count].fs_user, pjob->user);
3107 fstrcpy(queue[total_count].fs_file, pjob->jobname);
3111 /* Update the changed jobids. */
3112 for (i = 0; i < changed_count; i++) {
3113 uint32_t jobid = IVAL(jcdata.dptr, i * 4);
3117 for (j = 0; j < total_count; j++) {
3118 if (queue[j].job == jobid) {
3125 struct printjob *pjob;
3127 DEBUG(5,("get_stored_queue_info: changed job: %u\n",
3128 (unsigned int) jobid));
3130 pjob = print_job_find(sharename, jobid);
3132 DEBUG(5,("get_stored_queue_info: failed to find "
3133 "changed job = %u\n",
3134 (unsigned int) jobid));
3135 remove_from_jobs_changed(sharename, jobid);
3139 queue[j].job = jobid;
3140 queue[j].size = pjob->size;
3141 queue[j].page_count = pjob->page_count;
3142 queue[j].status = pjob->status;
3143 queue[j].priority = 1;
3144 queue[j].time = pjob->starttime;
3145 fstrcpy(queue[j].fs_user, pjob->user);
3146 fstrcpy(queue[j].fs_file, pjob->jobname);
3148 DEBUG(5,("get_stored_queue_info: updated queue[%u], jobid: %u, jobname: %s\n",
3149 (unsigned int) j, (unsigned int) jobid, pjob->jobname));
3152 remove_from_jobs_changed(sharename, jobid);
3155 /* Sort the queue by submission time otherwise they are displayed
3158 TYPESAFE_QSORT(queue, total_count, printjob_comp);
3160 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
3162 if (max_reported_jobs && total_count > max_reported_jobs)
3163 total_count = max_reported_jobs;
3166 *pcount = total_count;
3172 SAFE_FREE(data.dptr);
3173 SAFE_FREE(cgdata.dptr);
3177 /****************************************************************************
3178 Get a printer queue listing.
3179 set queue = NULL and status = NULL if you just want to update the cache
3180 ****************************************************************************/
3182 int print_queue_status(struct messaging_context *msg_ctx, int snum,
3183 print_queue_struct **ppqueue,
3184 print_status_struct *status)
3188 const char *sharename;
3189 struct tdb_print_db *pdb;
3192 /* make sure the database is up to date */
3194 if (print_cache_expired(lp_const_servicename(snum), True))
3195 print_queue_update(msg_ctx, snum, False);
3197 /* return if we are done */
3198 if ( !ppqueue || !status )
3202 sharename = lp_const_servicename(snum);
3203 pdb = get_print_db_byname(sharename);
3209 * Fetch the queue status. We must do this first, as there may
3210 * be no jobs in the queue.
3213 ZERO_STRUCTP(status);
3214 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
3215 key = string_tdb_data(keystr);
3217 data = tdb_fetch(pdb->tdb, key);
3219 if (data.dsize == sizeof(*status)) {
3220 /* this memcpy is ok since the status struct was
3221 not packed before storing it in the tdb */
3222 memcpy(status, data.dptr, sizeof(*status));
3224 SAFE_FREE(data.dptr);
3228 * Now, fetch the print queue information. We first count the number
3229 * of entries, and then only retrieve the queue if necessary.
3232 if (!get_stored_queue_info(msg_ctx, pdb, snum, &count, ppqueue)) {
3233 release_print_db(pdb);
3237 release_print_db(pdb);
3241 /****************************************************************************
3243 ****************************************************************************/
3245 WERROR print_queue_pause(const struct auth_serversupplied_info *server_info,
3246 struct messaging_context *msg_ctx, int snum)
3249 struct printif *current_printif = get_printer_fns( snum );
3251 if (!print_access_check(server_info, msg_ctx, snum,
3252 PRINTER_ACCESS_ADMINISTER)) {
3253 return WERR_ACCESS_DENIED;
3259 ret = (*(current_printif->queue_pause))(snum);
3264 return WERR_INVALID_PARAM;
3267 /* force update the database */
3268 print_cache_flush(lp_const_servicename(snum));
3270 /* Send a printer notify message */
3272 notify_printer_status(server_event_context(), msg_ctx, snum,
3273 PRINTER_STATUS_PAUSED);
3278 /****************************************************************************
3280 ****************************************************************************/
3282 WERROR print_queue_resume(const struct auth_serversupplied_info *server_info,
3283 struct messaging_context *msg_ctx, int snum)
3286 struct printif *current_printif = get_printer_fns( snum );
3288 if (!print_access_check(server_info, msg_ctx, snum,
3289 PRINTER_ACCESS_ADMINISTER)) {
3290 return WERR_ACCESS_DENIED;
3295 ret = (*(current_printif->queue_resume))(snum);
3300 return WERR_INVALID_PARAM;
3303 /* make sure the database is up to date */
3304 if (print_cache_expired(lp_const_servicename(snum), True))
3305 print_queue_update(msg_ctx, snum, True);
3307 /* Send a printer notify message */
3309 notify_printer_status(server_event_context(), msg_ctx, snum,
3315 /****************************************************************************
3316 Purge a queue - implemented by deleting all jobs that we can delete.
3317 ****************************************************************************/
3319 WERROR print_queue_purge(const struct auth_serversupplied_info *server_info,
3320 struct messaging_context *msg_ctx, int snum)
3322 print_queue_struct *queue;
3323 print_status_struct status;
3327 /* Force and update so the count is accurate (i.e. not a cached count) */
3328 print_queue_update(msg_ctx, snum, True);
3330 can_job_admin = print_access_check(server_info,
3333 JOB_ACCESS_ADMINISTER);
3334 njobs = print_queue_status(msg_ctx, snum, &queue, &status);
3336 if ( can_job_admin )
3339 for (i=0;i<njobs;i++) {
3340 bool owner = is_owner(server_info, lp_const_servicename(snum),
3343 if (owner || can_job_admin) {
3344 print_job_delete1(server_event_context(), msg_ctx,
3345 snum, queue[i].job);
3349 if ( can_job_admin )
3352 /* update the cache */
3353 print_queue_update(msg_ctx, snum, True);