2 Unix SMB/Netbios implementation.
4 printing backend routines
5 Copyright (C) Andrew Tridgell 1992-2000
6 Copyright (C) Jeremy Allison 2002
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "librpc/gen_ndr/messaging.h"
25 #include "../librpc/gen_ndr/ndr_spoolss.h"
26 #include "nt_printing.h"
27 #include "../librpc/gen_ndr/netlogon.h"
28 #include "printing/notify.h"
29 #include "printing/pcap.h"
32 extern struct current_user current_user;
33 extern userdom_struct current_user_info;
35 /* Current printer interface */
36 static bool remove_from_jobs_added(const char* sharename, uint32 jobid);
39 the printing backend revolves around a tdb database that stores the
40 SMB view of the print queue
42 The key for this database is a jobid - a internally generated number that
43 uniquely identifies a print job
45 reading the print queue involves two steps:
46 - possibly running lpq and updating the internal database from that
47 - reading entries from the database
49 jobids are assigned when a job starts spooling.
52 static TDB_CONTEXT *rap_tdb;
53 static uint16 next_rap_jobid;
54 struct rap_jobid_key {
59 /***************************************************************************
60 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
61 bit RPC jobids.... JRA.
62 ***************************************************************************/
64 uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
68 struct rap_jobid_key jinfo;
71 DEBUG(10,("pjobid_to_rap: called.\n"));
74 /* Create the in-memory tdb. */
75 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
81 fstrcpy( jinfo.sharename, sharename );
83 key.dptr = (uint8 *)&jinfo;
84 key.dsize = sizeof(jinfo);
86 data = tdb_fetch(rap_tdb, key);
87 if (data.dptr && data.dsize == sizeof(uint16)) {
88 rap_jobid = SVAL(data.dptr, 0);
90 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
91 (unsigned int)jobid, (unsigned int)rap_jobid));
95 /* Not found - create and store mapping. */
96 rap_jobid = ++next_rap_jobid;
98 rap_jobid = ++next_rap_jobid;
99 SSVAL(buf,0,rap_jobid);
101 data.dsize = sizeof(rap_jobid);
102 tdb_store(rap_tdb, key, data, TDB_REPLACE);
103 tdb_store(rap_tdb, data, key, TDB_REPLACE);
105 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
106 (unsigned int)jobid, (unsigned int)rap_jobid));
110 bool rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
115 DEBUG(10,("rap_to_pjobid called.\n"));
120 SSVAL(buf,0,rap_jobid);
122 key.dsize = sizeof(rap_jobid);
123 data = tdb_fetch(rap_tdb, key);
124 if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) )
126 struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
127 if (sharename != NULL) {
128 fstrcpy( sharename, jinfo->sharename );
130 *pjobid = jinfo->jobid;
131 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
132 (unsigned int)*pjobid, (unsigned int)rap_jobid));
133 SAFE_FREE(data.dptr);
137 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
138 (unsigned int)rap_jobid));
139 SAFE_FREE(data.dptr);
143 void rap_jobid_delete(const char* sharename, uint32 jobid)
147 struct rap_jobid_key jinfo;
150 DEBUG(10,("rap_jobid_delete: called.\n"));
155 ZERO_STRUCT( jinfo );
156 fstrcpy( jinfo.sharename, sharename );
158 key.dptr = (uint8 *)&jinfo;
159 key.dsize = sizeof(jinfo);
161 data = tdb_fetch(rap_tdb, key);
162 if (!data.dptr || (data.dsize != sizeof(uint16))) {
163 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
164 (unsigned int)jobid ));
165 SAFE_FREE(data.dptr);
169 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
170 (unsigned int)jobid ));
172 rap_jobid = SVAL(data.dptr, 0);
173 SAFE_FREE(data.dptr);
174 SSVAL(buf,0,rap_jobid);
176 data.dsize = sizeof(rap_jobid);
177 tdb_delete(rap_tdb, key);
178 tdb_delete(rap_tdb, data);
181 static int get_queue_status(const char* sharename, print_status_struct *);
183 /****************************************************************************
184 Initialise the printing backend. Called once at startup before the fork().
185 ****************************************************************************/
187 bool print_backend_init(struct messaging_context *msg_ctx)
189 const char *sversion = "INFO/version";
190 int services = lp_numservices();
193 unlink(cache_path("printing.tdb"));
194 mkdir(cache_path("printing"),0755);
196 /* handle a Samba upgrade */
198 for (snum = 0; snum < services; snum++) {
199 struct tdb_print_db *pdb;
200 if (!lp_print_ok(snum))
203 pdb = get_print_db_byname(lp_const_servicename(snum));
206 if (tdb_lock_bystring(pdb->tdb, sversion) == -1) {
207 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
208 release_print_db(pdb);
211 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
212 tdb_wipe_all(pdb->tdb);
213 tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
215 tdb_unlock_bystring(pdb->tdb, sversion);
216 release_print_db(pdb);
219 close_all_print_db(); /* Don't leave any open. */
221 /* do NT print initialization... */
222 return nt_printing_init(msg_ctx);
225 /****************************************************************************
226 Shut down printing backend. Called once at shutdown to close the tdb.
227 ****************************************************************************/
229 void printing_end(void)
231 close_all_print_db(); /* Don't leave any open. */
234 /****************************************************************************
235 Retrieve the set of printing functions for a given service. This allows
236 us to set the printer function table based on the value of the 'printing'
239 Use the generic interface as the default and only use cups interface only
240 when asked for (and only when supported)
241 ****************************************************************************/
243 static struct printif *get_printer_fns_from_type( enum printing_types type )
245 struct printif *printer_fns = &generic_printif;
248 if ( type == PRINT_CUPS ) {
249 printer_fns = &cups_printif;
251 #endif /* HAVE_CUPS */
254 if ( type == PRINT_IPRINT ) {
255 printer_fns = &iprint_printif;
257 #endif /* HAVE_IPRINT */
259 printer_fns->type = type;
264 static struct printif *get_printer_fns( int snum )
266 return get_printer_fns_from_type( (enum printing_types)lp_printing(snum) );
270 /****************************************************************************
271 Useful function to generate a tdb key.
272 ****************************************************************************/
274 static TDB_DATA print_key(uint32 jobid, uint32 *tmp)
278 SIVAL(tmp, 0, jobid);
279 ret.dptr = (uint8 *)tmp;
280 ret.dsize = sizeof(*tmp);
284 /****************************************************************************
285 Pack the devicemode to store it in a tdb.
286 ****************************************************************************/
287 static int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8 *buf, int buflen)
289 enum ndr_err_code ndr_err;
294 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(),
296 (ndr_push_flags_fn_t)
297 ndr_push_spoolss_DeviceMode);
298 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
299 DEBUG(10, ("pack_devicemode: "
300 "error encoding spoolss_DeviceMode\n"));
307 len = tdb_pack(buf, buflen, "B", blob.length, blob.data);
310 DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname));
317 /****************************************************************************
318 Unpack the devicemode to store it in a tdb.
319 ****************************************************************************/
320 static int unpack_devicemode(TALLOC_CTX *mem_ctx,
321 const uint8 *buf, int buflen,
322 struct spoolss_DeviceMode **devmode)
324 struct spoolss_DeviceMode *dm;
325 enum ndr_err_code ndr_err;
333 len = tdb_unpack(buf, buflen, "B", &data_len, &data);
338 dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
343 blob = data_blob_const(data, data_len);
345 ndr_err = ndr_pull_struct_blob(&blob, dm, dm,
346 (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);
347 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
348 DEBUG(10, ("unpack_devicemode: "
349 "error parsing spoolss_DeviceMode\n"));
353 DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
354 dm->devicename, dm->formname));
355 if (dm->driverextra_data.data) {
356 DEBUG(8, ("with a private section of %d bytes\n",
357 dm->__driverextra_length));
367 /***********************************************************************
368 unpack a pjob from a tdb buffer
369 ***********************************************************************/
371 static int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )
375 uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
376 uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
381 len += tdb_unpack(buf+len, buflen-len, "dddddddddfffff",
400 used = unpack_devicemode(NULL, buf+len, buflen-len, &pjob->devmode);
408 pjob->sysjob = pjsysjob;
410 pjob->starttime = pjstarttime;
411 pjob->status = pjstatus;
413 pjob->page_count = pjpage_count;
414 pjob->spooled = pjspooled;
415 pjob->smbjob = pjsmbjob;
421 /****************************************************************************
422 Useful function to find a print job in the database.
423 ****************************************************************************/
425 static struct printjob *print_job_find(const char *sharename, uint32 jobid)
427 static struct printjob pjob;
430 struct tdb_print_db *pdb = get_print_db_byname(sharename);
432 DEBUG(10,("print_job_find: looking up job %u for share %s\n",
433 (unsigned int)jobid, sharename ));
439 ret = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
440 release_print_db(pdb);
443 DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid ));
447 talloc_free(pjob.devmode);
451 if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
452 DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid ));
459 DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
460 (int)pjob.sysjob, (unsigned int)jobid ));
465 /* Convert a unix jobid to a smb jobid */
467 struct unixjob_traverse_state {
469 uint32 sysjob_to_jobid_value;
472 static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
473 TDB_DATA data, void *private_data)
475 struct printjob *pjob;
476 struct unixjob_traverse_state *state =
477 (struct unixjob_traverse_state *)private_data;
479 if (!data.dptr || data.dsize == 0)
482 pjob = (struct printjob *)data.dptr;
483 if (key.dsize != sizeof(uint32))
486 if (state->sysjob == pjob->sysjob) {
487 uint32 jobid = IVAL(key.dptr,0);
489 state->sysjob_to_jobid_value = jobid;
496 /****************************************************************************
497 This is a *horribly expensive call as we have to iterate through all the
498 current printer tdb's. Don't do this often ! JRA.
499 ****************************************************************************/
501 uint32 sysjob_to_jobid(int unix_jobid)
503 int services = lp_numservices();
505 struct unixjob_traverse_state state;
507 state.sysjob = unix_jobid;
508 state.sysjob_to_jobid_value = (uint32)-1;
510 for (snum = 0; snum < services; snum++) {
511 struct tdb_print_db *pdb;
512 if (!lp_print_ok(snum))
514 pdb = get_print_db_byname(lp_const_servicename(snum));
518 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &state);
519 release_print_db(pdb);
520 if (state.sysjob_to_jobid_value != (uint32)-1)
521 return state.sysjob_to_jobid_value;
526 /****************************************************************************
527 Send notifications based on what has changed after a pjob_store.
528 ****************************************************************************/
530 static const struct {
532 uint32_t spoolss_status;
533 } lpq_to_spoolss_status_map[] = {
534 { LPQ_QUEUED, JOB_STATUS_QUEUED },
535 { LPQ_PAUSED, JOB_STATUS_PAUSED },
536 { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
537 { LPQ_PRINTING, JOB_STATUS_PRINTING },
538 { LPQ_DELETING, JOB_STATUS_DELETING },
539 { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
540 { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
541 { LPQ_PRINTED, JOB_STATUS_PRINTED },
542 { LPQ_DELETED, JOB_STATUS_DELETED },
543 { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ },
544 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
548 /* Convert a lpq status value stored in printing.tdb into the
549 appropriate win32 API constant. */
551 static uint32 map_to_spoolss_status(uint32 lpq_status)
555 while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
556 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
557 return lpq_to_spoolss_status_map[i].spoolss_status;
564 /***************************************************************************
565 Append a jobid to the 'jobs changed' list.
566 ***************************************************************************/
568 static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32_t jobid)
571 uint32_t store_jobid;
573 SIVAL(&store_jobid, 0, jobid);
574 data.dptr = (uint8 *) &store_jobid;
577 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid ));
579 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
583 /***************************************************************************
584 Remove a jobid from the 'jobs changed' list.
585 ***************************************************************************/
587 static bool remove_from_jobs_changed(const char* sharename, uint32_t jobid)
589 struct tdb_print_db *pdb = get_print_db_byname(sharename);
593 bool gotlock = False;
601 key = string_tdb_data("INFO/jobs_changed");
603 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
608 data = tdb_fetch(pdb->tdb, key);
610 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
613 job_count = data.dsize / 4;
614 for (i = 0; i < job_count; i++) {
617 ch_jobid = IVAL(data.dptr, i*4);
618 if (ch_jobid == jobid) {
619 if (i < job_count -1 )
620 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
622 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
632 tdb_chainunlock(pdb->tdb, key);
633 SAFE_FREE(data.dptr);
634 release_print_db(pdb);
636 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
638 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
642 static void pjob_store_notify(struct tevent_context *ev,
643 struct messaging_context *msg_ctx,
644 const char* sharename, uint32 jobid,
645 struct printjob *old_data,
646 struct printjob *new_data,
649 bool new_job = false;
650 bool changed = false;
652 if (old_data == NULL) {
656 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
657 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
658 time first or else we'll end up with potential alignment
659 errors. I don't think the systemtime should be spooled as
660 a string, but this gets us around that error.
661 --jerry (i'll feel dirty for this) */
664 notify_job_submitted(ev, msg_ctx,
665 sharename, jobid, new_data->starttime);
666 notify_job_username(ev, msg_ctx,
667 sharename, jobid, new_data->user);
668 notify_job_name(ev, msg_ctx,
669 sharename, jobid, new_data->jobname);
670 notify_job_status(ev, msg_ctx,
671 sharename, jobid, map_to_spoolss_status(new_data->status));
672 notify_job_total_bytes(ev, msg_ctx,
673 sharename, jobid, new_data->size);
674 notify_job_total_pages(ev, msg_ctx,
675 sharename, jobid, new_data->page_count);
677 if (!strequal(old_data->jobname, new_data->jobname)) {
678 notify_job_name(ev, msg_ctx, sharename,
679 jobid, new_data->jobname);
683 if (old_data->status != new_data->status) {
684 notify_job_status(ev, msg_ctx,
686 map_to_spoolss_status(new_data->status));
689 if (old_data->size != new_data->size) {
690 notify_job_total_bytes(ev, msg_ctx,
691 sharename, jobid, new_data->size);
694 if (old_data->page_count != new_data->page_count) {
695 notify_job_total_pages(ev, msg_ctx,
697 new_data->page_count);
704 /****************************************************************************
705 Store a job structure back to the database.
706 ****************************************************************************/
708 static bool pjob_store(struct tevent_context *ev,
709 struct messaging_context *msg_ctx,
710 const char* sharename, uint32 jobid,
711 struct printjob *pjob)
714 TDB_DATA old_data, new_data;
716 struct tdb_print_db *pdb = get_print_db_byname(sharename);
718 int len, newlen, buflen;
726 old_data = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
728 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
735 len += tdb_pack(buf+len, buflen-len, "dddddddddfffff",
737 (uint32)pjob->sysjob,
739 (uint32)pjob->starttime,
740 (uint32)pjob->status,
742 (uint32)pjob->page_count,
743 (uint32)pjob->spooled,
744 (uint32)pjob->smbjob,
751 len += pack_devicemode(pjob->devmode, buf+len, buflen-len);
754 buf = (uint8 *)SMB_REALLOC(buf, len);
756 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
761 } while ( buflen != len );
767 new_data.dsize = len;
768 ret = (tdb_store(pdb->tdb, print_key(jobid, &tmp), new_data,
771 /* Send notify updates for what has changed */
774 bool changed = false;
775 struct printjob old_pjob;
777 if ( old_data.dsize )
779 if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
781 pjob_store_notify(server_event_context(),
783 sharename, jobid, &old_pjob,
786 talloc_free(old_pjob.devmode);
789 add_to_jobs_changed(pdb, jobid);
796 pjob_store_notify(server_event_context(), msg_ctx,
797 sharename, jobid, NULL, pjob,
802 release_print_db(pdb);
804 SAFE_FREE( old_data.dptr );
810 /****************************************************************************
811 Remove a job structure from the database.
812 ****************************************************************************/
814 static void pjob_delete(struct tevent_context *ev,
815 struct messaging_context *msg_ctx,
816 const char* sharename, uint32 jobid)
819 struct printjob *pjob;
820 uint32 job_status = 0;
821 struct tdb_print_db *pdb;
823 pdb = get_print_db_byname( sharename );
828 pjob = print_job_find( sharename, jobid );
831 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
832 (unsigned int)jobid));
833 release_print_db(pdb);
837 /* We must cycle through JOB_STATUS_DELETING and
838 JOB_STATUS_DELETED for the port monitor to delete the job
841 job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
842 notify_job_status(ev, msg_ctx, sharename, jobid, job_status);
844 /* Remove from printing.tdb */
846 tdb_delete(pdb->tdb, print_key(jobid, &tmp));
847 remove_from_jobs_added(sharename, jobid);
848 release_print_db( pdb );
849 rap_jobid_delete(sharename, jobid);
852 /****************************************************************************
853 List a unix job in the print database.
854 ****************************************************************************/
856 static void print_unix_job(struct tevent_context *ev,
857 struct messaging_context *msg_ctx,
858 const char *sharename, print_queue_struct *q,
861 struct printjob pj, *old_pj;
863 if (jobid == (uint32)-1)
864 jobid = q->job + UNIX_JOB_START;
866 /* Preserve the timestamp on an existing unix print job */
868 old_pj = print_job_find(sharename, jobid);
875 pj.starttime = old_pj ? old_pj->starttime : q->time;
876 pj.status = q->status;
879 fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
880 if (jobid < UNIX_JOB_START) {
882 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
885 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
887 fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
888 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
890 pjob_store(ev, msg_ctx, sharename, jobid, &pj);
894 struct traverse_struct {
895 print_queue_struct *queue;
896 int qcount, snum, maxcount, total_jobs;
897 const char *sharename;
899 const char *lprm_command;
900 struct printif *print_if;
901 struct tevent_context *ev;
902 struct messaging_context *msg_ctx;
905 /****************************************************************************
906 Utility fn to delete any jobs that are no longer active.
907 ****************************************************************************/
909 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
911 struct traverse_struct *ts = (struct traverse_struct *)state;
912 struct printjob pjob;
916 if ( key.dsize != sizeof(jobid) )
919 jobid = IVAL(key.dptr, 0);
920 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
922 talloc_free(pjob.devmode);
926 /* remove a unix job if it isn't in the system queue any more */
928 for (i=0;i<ts->qcount;i++) {
929 uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
930 if (jobid == u_jobid)
933 if (i == ts->qcount) {
934 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
935 (unsigned int)jobid ));
936 pjob_delete(ts->ev, ts->msg_ctx,
937 ts->sharename, jobid);
941 /* need to continue the the bottom of the function to
942 save the correct attributes */
945 /* maybe it hasn't been spooled yet */
947 /* if a job is not spooled and the process doesn't
948 exist then kill it. This cleans up after smbd
950 if (!process_exists_by_pid(pjob.pid)) {
951 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
952 (unsigned int)jobid, (unsigned int)pjob.pid ));
953 pjob_delete(ts->ev, ts->msg_ctx,
954 ts->sharename, jobid);
960 /* this check only makes sense for jobs submitted from Windows clients */
963 for (i=0;i<ts->qcount;i++) {
966 if ( pjob.status == LPQ_DELETED )
969 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
971 if (jobid == curr_jobid) {
973 /* try to clean up any jobs that need to be deleted */
975 if ( pjob.status == LPQ_DELETING ) {
978 result = (*(ts->print_if->job_delete))(
979 ts->sharename, ts->lprm_command, &pjob );
982 /* if we can't delete, then reset the job status */
983 pjob.status = LPQ_QUEUED;
984 pjob_store(ts->ev, ts->msg_ctx,
985 ts->sharename, jobid, &pjob);
988 /* if we deleted the job, the remove the tdb record */
991 ts->sharename, jobid);
992 pjob.status = LPQ_DELETED;
1002 /* The job isn't in the system queue - we have to assume it has
1003 completed, so delete the database entry. */
1005 if (i == ts->qcount) {
1007 /* A race can occur between the time a job is spooled and
1008 when it appears in the lpq output. This happens when
1009 the job is added to printing.tdb when another smbd
1010 running print_queue_update() has completed a lpq and
1011 is currently traversing the printing tdb and deleting jobs.
1012 Don't delete the job if it was submitted after the lpq_time. */
1014 if (pjob.starttime < ts->lpq_time) {
1015 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
1016 (unsigned int)jobid,
1017 (unsigned int)pjob.starttime,
1018 (unsigned int)ts->lpq_time ));
1019 pjob_delete(ts->ev, ts->msg_ctx,
1020 ts->sharename, jobid);
1026 /* Save the pjob attributes we will store.
1027 FIXME!!! This is the only place where queue->job
1028 represents the SMB jobid --jerry */
1030 ts->queue[i].job = jobid;
1031 ts->queue[i].size = pjob.size;
1032 ts->queue[i].page_count = pjob.page_count;
1033 ts->queue[i].status = pjob.status;
1034 ts->queue[i].priority = 1;
1035 ts->queue[i].time = pjob.starttime;
1036 fstrcpy(ts->queue[i].fs_user, pjob.user);
1037 fstrcpy(ts->queue[i].fs_file, pjob.jobname);
1044 /****************************************************************************
1045 Check if the print queue has been updated recently enough.
1046 ****************************************************************************/
1048 static void print_cache_flush(const char *sharename)
1051 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1055 slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
1056 tdb_store_int32(pdb->tdb, key, -1);
1057 release_print_db(pdb);
1060 /****************************************************************************
1061 Check if someone already thinks they are doing the update.
1062 ****************************************************************************/
1064 static pid_t get_updating_pid(const char *sharename)
1069 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1073 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
1074 key = string_tdb_data(keystr);
1076 data = tdb_fetch(pdb->tdb, key);
1077 release_print_db(pdb);
1078 if (!data.dptr || data.dsize != sizeof(pid_t)) {
1079 SAFE_FREE(data.dptr);
1083 updating_pid = IVAL(data.dptr, 0);
1084 SAFE_FREE(data.dptr);
1086 if (process_exists_by_pid(updating_pid))
1087 return updating_pid;
1092 /****************************************************************************
1093 Set the fact that we're doing the update, or have finished doing the update
1095 ****************************************************************************/
1097 static void set_updating_pid(const fstring sharename, bool updating)
1102 pid_t updating_pid = sys_getpid();
1105 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1110 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
1111 key = string_tdb_data(keystr);
1113 DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
1114 updating ? "" : "not ",
1118 tdb_delete(pdb->tdb, key);
1119 release_print_db(pdb);
1123 SIVAL( buffer, 0, updating_pid);
1125 data.dsize = 4; /* we always assume this is a 4 byte value */
1127 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1128 release_print_db(pdb);
1131 /****************************************************************************
1132 Sort print jobs by submittal time.
1133 ****************************************************************************/
1135 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
1146 /* Sort on job start time */
1148 if (j1->time == j2->time)
1150 return (j1->time > j2->time) ? 1 : -1;
1153 /****************************************************************************
1154 Store the sorted queue representation for later portmon retrieval.
1156 ****************************************************************************/
1158 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
1161 int max_reported_jobs = lp_max_reported_jobs(pts->snum);
1162 print_queue_struct *queue = pts->queue;
1165 unsigned int qcount;
1167 if (max_reported_jobs && (max_reported_jobs < pts->qcount))
1168 pts->qcount = max_reported_jobs;
1171 /* Work out the size. */
1173 data.dsize += tdb_pack(NULL, 0, "d", qcount);
1175 for (i = 0; i < pts->qcount; i++) {
1176 if ( queue[i].status == LPQ_DELETED )
1180 data.dsize += tdb_pack(NULL, 0, "ddddddff",
1181 (uint32)queue[i].job,
1182 (uint32)queue[i].size,
1183 (uint32)queue[i].page_count,
1184 (uint32)queue[i].status,
1185 (uint32)queue[i].priority,
1186 (uint32)queue[i].time,
1191 if ((data.dptr = (uint8 *)SMB_MALLOC(data.dsize)) == NULL)
1195 len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
1196 for (i = 0; i < pts->qcount; i++) {
1197 if ( queue[i].status == LPQ_DELETED )
1200 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
1201 (uint32)queue[i].job,
1202 (uint32)queue[i].size,
1203 (uint32)queue[i].page_count,
1204 (uint32)queue[i].status,
1205 (uint32)queue[i].priority,
1206 (uint32)queue[i].time,
1211 tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
1213 SAFE_FREE(data.dptr);
1217 static TDB_DATA get_jobs_added_data(struct tdb_print_db *pdb)
1223 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added"));
1224 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
1225 SAFE_FREE(data.dptr);
1232 static void check_job_added(const char *sharename, TDB_DATA data, uint32 jobid)
1235 unsigned int job_count = data.dsize / 4;
1237 for (i = 0; i < job_count; i++) {
1240 ch_jobid = IVAL(data.dptr, i*4);
1241 if (ch_jobid == jobid)
1242 remove_from_jobs_added(sharename, jobid);
1246 /****************************************************************************
1247 Check if the print queue has been updated recently enough.
1248 ****************************************************************************/
1250 static bool print_cache_expired(const char *sharename, bool check_pending)
1253 time_t last_qscan_time, time_now = time(NULL);
1254 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1255 bool result = False;
1260 snprintf(key, sizeof(key), "CACHE/%s", sharename);
1261 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1264 * Invalidate the queue for 3 reasons.
1265 * (1). last queue scan time == -1.
1266 * (2). Current time - last queue scan time > allowed cache time.
1267 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1268 * This last test picks up machines for which the clock has been moved
1269 * forward, an lpq scan done and then the clock moved back. Otherwise
1270 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1273 if (last_qscan_time == ((time_t)-1)
1274 || (time_now - last_qscan_time) >= lp_lpqcachetime()
1275 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
1278 time_t msg_pending_time;
1280 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1281 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1282 sharename, (int)last_qscan_time, (int)time_now,
1283 (int)lp_lpqcachetime() ));
1285 /* check if another smbd has already sent a message to update the
1286 queue. Give the pending message one minute to clear and
1287 then send another message anyways. Make sure to check for
1288 clocks that have been run forward and then back again. */
1290 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1293 && tdb_fetch_uint32( pdb->tdb, key, &u )
1294 && (msg_pending_time=u) > 0
1295 && msg_pending_time <= time_now
1296 && (time_now - msg_pending_time) < 60 )
1298 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1307 release_print_db(pdb);
1311 /****************************************************************************
1312 main work for updating the lpq cache for a printer queue
1313 ****************************************************************************/
1315 static void print_queue_update_internal( struct tevent_context *ev,
1316 struct messaging_context *msg_ctx,
1317 const char *sharename,
1318 struct printif *current_printif,
1319 char *lpq_command, char *lprm_command )
1322 print_queue_struct *queue = NULL;
1323 print_status_struct status;
1324 print_status_struct old_status;
1325 struct printjob *pjob;
1326 struct traverse_struct tstruct;
1329 fstring keystr, cachestr;
1330 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1336 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1337 sharename, current_printif->type, lpq_command));
1340 * Update the cache time FIRST ! Stops others even
1341 * attempting to get the lock and doing this
1342 * if the lpq takes a long time.
1345 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1346 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1348 /* get the current queue using the appropriate interface */
1349 ZERO_STRUCT(status);
1351 qcount = (*(current_printif->queue_get))(sharename,
1352 current_printif->type,
1353 lpq_command, &queue, &status);
1355 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1356 qcount, (qcount != 1) ? "s" : "", sharename));
1358 /* Sort the queue by submission time otherwise they are displayed
1361 TYPESAFE_QSORT(queue, qcount, printjob_comp);
1364 any job in the internal database that is marked as spooled
1365 and doesn't exist in the system queue is considered finished
1366 and removed from the database
1368 any job in the system database but not in the internal database
1369 is added as a unix job
1371 fill in any system job numbers as we go
1374 jcdata = get_jobs_added_data(pdb);
1376 for (i=0; i<qcount; i++) {
1377 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1379 if (jobid == (uint32)-1) {
1380 /* assume its a unix print job */
1381 print_unix_job(ev, msg_ctx,
1382 sharename, &queue[i], jobid);
1386 /* we have an active SMB print job - update its status */
1387 pjob = print_job_find(sharename, jobid);
1389 /* err, somethings wrong. Probably smbd was restarted
1390 with jobs in the queue. All we can do is treat them
1391 like unix jobs. Pity. */
1392 print_unix_job(ev, msg_ctx,
1393 sharename, &queue[i], jobid);
1397 pjob->sysjob = queue[i].job;
1399 /* don't reset the status on jobs to be deleted */
1401 if ( pjob->status != LPQ_DELETING )
1402 pjob->status = queue[i].status;
1404 pjob_store(ev, msg_ctx, sharename, jobid, pjob);
1406 check_job_added(sharename, jcdata, jobid);
1409 SAFE_FREE(jcdata.dptr);
1411 /* now delete any queued entries that don't appear in the
1413 tstruct.queue = queue;
1414 tstruct.qcount = qcount;
1416 tstruct.total_jobs = 0;
1417 tstruct.lpq_time = time(NULL);
1418 tstruct.sharename = sharename;
1419 tstruct.lprm_command = lprm_command;
1420 tstruct.print_if = current_printif;
1422 tstruct.msg_ctx = msg_ctx;
1424 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1426 /* Store the linearised queue, max jobs only. */
1427 store_queue_struct(pdb, &tstruct);
1429 SAFE_FREE(tstruct.queue);
1431 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1432 sharename, tstruct.total_jobs ));
1434 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1436 get_queue_status(sharename, &old_status);
1437 if (old_status.qcount != qcount)
1438 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1439 old_status.qcount, qcount, sharename));
1441 /* store the new queue status structure */
1442 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1443 key = string_tdb_data(keystr);
1445 status.qcount = qcount;
1446 data.dptr = (uint8 *)&status;
1447 data.dsize = sizeof(status);
1448 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1451 * Update the cache time again. We want to do this call
1452 * as little as possible...
1455 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1456 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1458 /* clear the msg pending record for this queue */
1460 snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1462 if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1463 /* log a message but continue on */
1465 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1469 release_print_db( pdb );
1474 /****************************************************************************
1475 Update the internal database from the system print queue for a queue.
1476 obtain a lock on the print queue before proceeding (needed when mutiple
1477 smbd processes maytry to update the lpq cache concurrently).
1478 ****************************************************************************/
1480 static void print_queue_update_with_lock( struct tevent_context *ev,
1481 struct messaging_context *msg_ctx,
1482 const char *sharename,
1483 struct printif *current_printif,
1484 char *lpq_command, char *lprm_command )
1487 struct tdb_print_db *pdb;
1489 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1490 pdb = get_print_db_byname(sharename);
1494 if ( !print_cache_expired(sharename, False) ) {
1495 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1496 release_print_db(pdb);
1501 * Check to see if someone else is doing this update.
1502 * This is essentially a mutex on the update.
1505 if (get_updating_pid(sharename) != -1) {
1506 release_print_db(pdb);
1510 /* Lock the queue for the database update */
1512 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1513 /* Only wait 10 seconds for this. */
1514 if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
1515 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1516 release_print_db(pdb);
1521 * Ensure that no one else got in here.
1522 * If the updating pid is still -1 then we are
1526 if (get_updating_pid(sharename) != -1) {
1528 * Someone else is doing the update, exit.
1530 tdb_unlock_bystring(pdb->tdb, keystr);
1531 release_print_db(pdb);
1536 * We're going to do the update ourselves.
1539 /* Tell others we're doing the update. */
1540 set_updating_pid(sharename, True);
1543 * Allow others to enter and notice we're doing
1547 tdb_unlock_bystring(pdb->tdb, keystr);
1549 /* do the main work now */
1551 print_queue_update_internal(ev, msg_ctx,
1552 sharename, current_printif,
1553 lpq_command, lprm_command);
1555 /* Delete our pid from the db. */
1556 set_updating_pid(sharename, False);
1557 release_print_db(pdb);
1560 /****************************************************************************
1561 this is the receive function of the background lpq updater
1562 ****************************************************************************/
1563 static void print_queue_receive(struct messaging_context *msg,
1566 struct server_id server_id,
1570 char *lpqcommand = NULL, *lprmcommand = NULL;
1574 len = tdb_unpack( (uint8 *)data->data, data->length, "fdPP",
1581 SAFE_FREE(lpqcommand);
1582 SAFE_FREE(lprmcommand);
1583 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1587 print_queue_update_with_lock(server_event_context(), msg, sharename,
1588 get_printer_fns_from_type((enum printing_types)printing_type),
1589 lpqcommand, lprmcommand );
1591 SAFE_FREE(lpqcommand);
1592 SAFE_FREE(lprmcommand);
1596 static void printing_pause_fd_handler(struct tevent_context *ev,
1597 struct tevent_fd *fde,
1602 * If pause_pipe[1] is closed it means the parent smbd
1603 * and children exited or aborted.
1605 exit_server_cleanly(NULL);
1608 extern struct child_pid *children;
1609 extern int num_children;
1611 static void add_child_pid(pid_t pid)
1613 struct child_pid *child;
1615 child = SMB_MALLOC_P(struct child_pid);
1616 if (child == NULL) {
1617 DEBUG(0, ("Could not add child struct -- malloc failed\n"));
1621 DLIST_ADD(children, child);
1625 static pid_t background_lpq_updater_pid = -1;
1627 /****************************************************************************
1628 main thread of the background lpq updater
1629 ****************************************************************************/
1630 void start_background_queue(struct tevent_context *ev,
1631 struct messaging_context *msg_ctx)
1633 /* Use local variables for this as we don't
1634 * need to save the parent side of this, just
1635 * ensure it closes when the process exits.
1639 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1641 if (pipe(pause_pipe) == -1) {
1642 DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno) ));
1646 background_lpq_updater_pid = sys_fork();
1648 if (background_lpq_updater_pid == -1) {
1649 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1653 /* Track the printing pid along with other smbd children */
1654 add_child_pid(background_lpq_updater_pid);
1656 if(background_lpq_updater_pid == 0) {
1657 struct tevent_fd *fde;
1662 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1664 close(pause_pipe[0]);
1667 status = reinit_after_fork(msg_ctx, ev, procid_self(), true);
1669 if (!NT_STATUS_IS_OK(status)) {
1670 DEBUG(0,("reinit_after_fork() failed\n"));
1671 smb_panic("reinit_after_fork() failed");
1674 smbd_setup_sig_term_handler();
1675 smbd_setup_sig_hup_handler(ev, msg_ctx);
1677 if (!serverid_register(procid_self(),
1678 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
1679 |FLAG_MSG_PRINT_GENERAL)) {
1683 if (!locking_init()) {
1687 messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE,
1688 print_queue_receive);
1690 fde = tevent_add_fd(ev, ev, pause_pipe[1], TEVENT_FD_READ,
1691 printing_pause_fd_handler,
1694 DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
1695 smb_panic("tevent_add_fd() failed for pause_pipe");
1698 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1699 ret = tevent_loop_wait(ev);
1700 /* should not be reached */
1701 DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
1702 ret, (ret == 0) ? "out of events" : strerror(errno)));
1706 close(pause_pipe[1]);
1709 /****************************************************************************
1710 update the internal database from the system print queue for a queue
1711 ****************************************************************************/
1713 static void print_queue_update(struct messaging_context *msg_ctx,
1714 int snum, bool force)
1718 char *lpqcommand = NULL;
1719 char *lprmcommand = NULL;
1720 uint8 *buffer = NULL;
1723 struct tdb_print_db *pdb;
1725 struct printif *current_printif;
1726 TALLOC_CTX *ctx = talloc_tos();
1728 fstrcpy( sharename, lp_const_servicename(snum));
1730 /* don't strip out characters like '$' from the printername */
1732 lpqcommand = talloc_string_sub2(ctx,
1733 lp_lpqcommand(snum),
1735 lp_printername(snum),
1736 false, false, false);
1740 lpqcommand = talloc_sub_advanced(ctx,
1741 lp_servicename(snum),
1742 current_user_info.unix_name,
1744 current_user.ut.gid,
1745 get_current_username(),
1746 current_user_info.domain,
1752 lprmcommand = talloc_string_sub2(ctx,
1753 lp_lprmcommand(snum),
1755 lp_printername(snum),
1756 false, false, false);
1760 lprmcommand = talloc_sub_advanced(ctx,
1761 lp_servicename(snum),
1762 current_user_info.unix_name,
1764 current_user.ut.gid,
1765 get_current_username(),
1766 current_user_info.domain,
1773 * Make sure that the background queue process exists.
1774 * Otherwise just do the update ourselves
1777 if ( force || background_lpq_updater_pid == -1 ) {
1778 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1779 current_printif = get_printer_fns( snum );
1780 print_queue_update_with_lock(server_event_context(), msg_ctx,
1781 sharename, current_printif,
1782 lpqcommand, lprmcommand);
1787 type = lp_printing(snum);
1789 /* get the length */
1791 len = tdb_pack( NULL, 0, "fdPP",
1797 buffer = SMB_XMALLOC_ARRAY( uint8, len );
1799 /* now pack the buffer */
1800 newlen = tdb_pack( buffer, len, "fdPP",
1806 SMB_ASSERT( newlen == len );
1808 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1809 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1810 sharename, type, lpqcommand, lprmcommand ));
1812 /* here we set a msg pending record for other smbd processes
1813 to throttle the number of duplicate print_queue_update msgs
1816 pdb = get_print_db_byname(sharename);
1822 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1824 if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1825 /* log a message but continue on */
1827 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1831 release_print_db( pdb );
1833 /* finally send the message */
1835 messaging_send_buf(msg_ctx, pid_to_procid(background_lpq_updater_pid),
1836 MSG_PRINTER_UPDATE, (uint8 *)buffer, len);
1838 SAFE_FREE( buffer );
1843 /****************************************************************************
1844 Create/Update an entry in the print tdb that will allow us to send notify
1845 updates only to interested smbd's.
1846 ****************************************************************************/
1848 bool print_notify_register_pid(int snum)
1851 struct tdb_print_db *pdb = NULL;
1852 TDB_CONTEXT *tdb = NULL;
1853 const char *printername;
1854 uint32 mypid = (uint32)sys_getpid();
1858 /* if (snum == -1), then the change notify request was
1859 on a print server handle and we need to register on
1864 int num_services = lp_numservices();
1867 for ( idx=0; idx<num_services; idx++ ) {
1868 if (lp_snum_ok(idx) && lp_print_ok(idx) )
1869 print_notify_register_pid(idx);
1874 else /* register for a specific printer */
1876 printername = lp_const_servicename(snum);
1877 pdb = get_print_db_byname(printername);
1883 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1884 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1887 release_print_db(pdb);
1891 data = get_printer_notify_pid_list( tdb, printername, True );
1893 /* Add ourselves and increase the refcount. */
1895 for (i = 0; i < data.dsize; i += 8) {
1896 if (IVAL(data.dptr,i) == mypid) {
1897 uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1898 SIVAL(data.dptr, i+4, new_refcount);
1903 if (i == data.dsize) {
1904 /* We weren't in the list. Realloc. */
1905 data.dptr = (uint8 *)SMB_REALLOC(data.dptr, data.dsize + 8);
1907 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1912 SIVAL(data.dptr,data.dsize - 8,mypid);
1913 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1916 /* Store back the record. */
1917 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1918 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1919 list for printer %s\n", printername));
1927 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1929 release_print_db(pdb);
1930 SAFE_FREE(data.dptr);
1934 /****************************************************************************
1935 Update an entry in the print tdb that will allow us to send notify
1936 updates only to interested smbd's.
1937 ****************************************************************************/
1939 bool print_notify_deregister_pid(int snum)
1942 struct tdb_print_db *pdb = NULL;
1943 TDB_CONTEXT *tdb = NULL;
1944 const char *printername;
1945 uint32 mypid = (uint32)sys_getpid();
1949 /* if ( snum == -1 ), we are deregister a print server handle
1950 which means to deregister on all print queues */
1954 int num_services = lp_numservices();
1957 for ( idx=0; idx<num_services; idx++ ) {
1958 if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1959 print_notify_deregister_pid(idx);
1964 else /* deregister a specific printer */
1966 printername = lp_const_servicename(snum);
1967 pdb = get_print_db_byname(printername);
1973 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1974 DEBUG(0,("print_notify_register_pid: Failed to lock \
1975 printer %s database\n", printername));
1977 release_print_db(pdb);
1981 data = get_printer_notify_pid_list( tdb, printername, True );
1983 /* Reduce refcount. Remove ourselves if zero. */
1985 for (i = 0; i < data.dsize; ) {
1986 if (IVAL(data.dptr,i) == mypid) {
1987 uint32 refcount = IVAL(data.dptr, i+4);
1991 if (refcount == 0) {
1992 if (data.dsize - i > 8)
1993 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1997 SIVAL(data.dptr, i+4, refcount);
2003 if (data.dsize == 0)
2004 SAFE_FREE(data.dptr);
2006 /* Store back the record. */
2007 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
2008 DEBUG(0,("print_notify_register_pid: Failed to update pid \
2009 list for printer %s\n", printername));
2017 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
2019 release_print_db(pdb);
2020 SAFE_FREE(data.dptr);
2024 /****************************************************************************
2025 Check if a jobid is valid. It is valid if it exists in the database.
2026 ****************************************************************************/
2028 bool print_job_exists(const char* sharename, uint32 jobid)
2030 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2036 ret = tdb_exists(pdb->tdb, print_key(jobid, &tmp));
2037 release_print_db(pdb);
2041 /****************************************************************************
2042 Give the filename used for a jobid.
2043 Only valid for the process doing the spooling and when the job
2044 has not been spooled.
2045 ****************************************************************************/
2047 char *print_job_fname(const char* sharename, uint32 jobid)
2049 struct printjob *pjob = print_job_find(sharename, jobid);
2050 if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
2052 return pjob->filename;
2056 /****************************************************************************
2057 Give the filename used for a jobid.
2058 Only valid for the process doing the spooling and when the job
2059 has not been spooled.
2060 ****************************************************************************/
2062 struct spoolss_DeviceMode *print_job_devmode(const char* sharename, uint32 jobid)
2064 struct printjob *pjob = print_job_find(sharename, jobid);
2069 return pjob->devmode;
2072 /****************************************************************************
2073 Set the name of a job. Only possible for owner.
2074 ****************************************************************************/
2076 bool print_job_set_name(struct tevent_context *ev,
2077 struct messaging_context *msg_ctx,
2078 const char *sharename, uint32 jobid, const char *name)
2080 struct printjob *pjob;
2082 pjob = print_job_find(sharename, jobid);
2083 if (!pjob || pjob->pid != sys_getpid())
2086 fstrcpy(pjob->jobname, name);
2087 return pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2090 /****************************************************************************
2091 Get the name of a job. Only possible for owner.
2092 ****************************************************************************/
2094 bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t jobid, char **name)
2096 struct printjob *pjob;
2098 pjob = print_job_find(sharename, jobid);
2099 if (!pjob || pjob->pid != sys_getpid()) {
2103 *name = talloc_strdup(mem_ctx, pjob->jobname);
2112 /***************************************************************************
2113 Remove a jobid from the 'jobs added' list.
2114 ***************************************************************************/
2116 static bool remove_from_jobs_added(const char* sharename, uint32 jobid)
2118 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2120 size_t job_count, i;
2122 bool gotlock = False;
2130 key = string_tdb_data("INFO/jobs_added");
2132 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
2137 data = tdb_fetch(pdb->tdb, key);
2139 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
2142 job_count = data.dsize / 4;
2143 for (i = 0; i < job_count; i++) {
2146 ch_jobid = IVAL(data.dptr, i*4);
2147 if (ch_jobid == jobid) {
2148 if (i < job_count -1 )
2149 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
2151 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
2161 tdb_chainunlock(pdb->tdb, key);
2162 SAFE_FREE(data.dptr);
2163 release_print_db(pdb);
2165 DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid ));
2167 DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid ));
2171 /****************************************************************************
2172 Delete a print job - don't update queue.
2173 ****************************************************************************/
2175 static bool print_job_delete1(struct tevent_context *ev,
2176 struct messaging_context *msg_ctx,
2177 int snum, uint32 jobid)
2179 const char* sharename = lp_const_servicename(snum);
2180 struct printjob *pjob = print_job_find(sharename, jobid);
2182 struct printif *current_printif = get_printer_fns( snum );
2188 * If already deleting just return.
2191 if (pjob->status == LPQ_DELETING)
2194 /* Hrm - we need to be able to cope with deleting a job before it
2195 has reached the spooler. Just mark it as LPQ_DELETING and
2196 let the print_queue_update() code rmeove the record */
2199 if (pjob->sysjob == -1) {
2200 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
2203 /* Set the tdb entry to be deleting. */
2205 pjob->status = LPQ_DELETING;
2206 pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2208 if (pjob->spooled && pjob->sysjob != -1)
2210 result = (*(current_printif->job_delete))(
2211 lp_printername(snum),
2212 lp_lprmcommand(snum),
2215 /* Delete the tdb entry if the delete succeeded or the job hasn't
2219 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2224 pjob_delete(ev, msg_ctx, sharename, jobid);
2225 /* Ensure we keep a rough count of the number of total jobs... */
2226 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
2227 release_print_db(pdb);
2231 remove_from_jobs_added( sharename, jobid );
2233 return (result == 0);
2236 /****************************************************************************
2237 Return true if the current user owns the print job.
2238 ****************************************************************************/
2240 static bool is_owner(const struct auth_serversupplied_info *server_info,
2241 const char *servicename,
2244 struct printjob *pjob = print_job_find(servicename, jobid);
2246 if (!pjob || !server_info)
2249 return strequal(pjob->user, server_info->sanitized_username);
2252 /****************************************************************************
2254 ****************************************************************************/
2256 WERROR print_job_delete(const struct auth_serversupplied_info *server_info,
2257 struct messaging_context *msg_ctx,
2258 int snum, uint32_t jobid)
2260 const char* sharename = lp_const_servicename(snum);
2261 struct printjob *pjob;
2265 owner = is_owner(server_info, lp_const_servicename(snum), jobid);
2267 /* Check access against security descriptor or whether the user
2271 !print_access_check(server_info, msg_ctx, snum,
2272 JOB_ACCESS_ADMINISTER)) {
2273 DEBUG(3, ("delete denied by security descriptor\n"));
2275 /* BEGIN_ADMIN_LOG */
2276 sys_adminlog( LOG_ERR,
2277 "Permission denied-- user not allowed to delete, \
2278 pause, or resume print job. User name: %s. Printer name: %s.",
2279 uidtoname(server_info->utok.uid),
2280 lp_printername(snum) );
2283 return WERR_ACCESS_DENIED;
2287 * get the spooled filename of the print job
2288 * if this works, then the file has not been spooled
2289 * to the underlying print system. Just delete the
2290 * spool file & return.
2293 fname = print_job_fname(sharename, jobid);
2294 if (fname != NULL) {
2295 /* remove the spool file */
2296 DEBUG(10, ("print_job_delete: "
2297 "Removing spool file [%s]\n", fname));
2298 if (unlink(fname) == -1) {
2299 return map_werror_from_unix(errno);
2303 if (!print_job_delete1(server_event_context(), msg_ctx, snum, jobid)) {
2304 return WERR_ACCESS_DENIED;
2307 /* force update the database and say the delete failed if the
2310 print_queue_update(msg_ctx, snum, True);
2312 pjob = print_job_find(sharename, jobid);
2313 if (pjob && (pjob->status != LPQ_DELETING)) {
2314 return WERR_ACCESS_DENIED;
2317 return WERR_PRINTER_HAS_JOBS_QUEUED;
2320 /****************************************************************************
2322 ****************************************************************************/
2324 bool print_job_pause(const struct auth_serversupplied_info *server_info,
2325 struct messaging_context *msg_ctx,
2326 int snum, uint32 jobid, WERROR *errcode)
2328 const char* sharename = lp_const_servicename(snum);
2329 struct printjob *pjob;
2331 struct printif *current_printif = get_printer_fns( snum );
2333 pjob = print_job_find(sharename, jobid);
2335 if (!pjob || !server_info) {
2336 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2337 (unsigned int)jobid ));
2341 if (!pjob->spooled || pjob->sysjob == -1) {
2342 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2343 (int)pjob->sysjob, (unsigned int)jobid ));
2347 if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2348 !print_access_check(server_info, msg_ctx, snum,
2349 JOB_ACCESS_ADMINISTER)) {
2350 DEBUG(3, ("pause denied by security descriptor\n"));
2352 /* BEGIN_ADMIN_LOG */
2353 sys_adminlog( LOG_ERR,
2354 "Permission denied-- user not allowed to delete, \
2355 pause, or resume print job. User name: %s. Printer name: %s.",
2356 uidtoname(server_info->utok.uid),
2357 lp_printername(snum) );
2360 *errcode = WERR_ACCESS_DENIED;
2364 /* need to pause the spooled entry */
2365 ret = (*(current_printif->job_pause))(snum, pjob);
2368 *errcode = WERR_INVALID_PARAM;
2372 /* force update the database */
2373 print_cache_flush(lp_const_servicename(snum));
2375 /* Send a printer notify message */
2377 notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2380 /* how do we tell if this succeeded? */
2385 /****************************************************************************
2387 ****************************************************************************/
2389 bool print_job_resume(const struct auth_serversupplied_info *server_info,
2390 struct messaging_context *msg_ctx,
2391 int snum, uint32 jobid, WERROR *errcode)
2393 const char *sharename = lp_const_servicename(snum);
2394 struct printjob *pjob;
2396 struct printif *current_printif = get_printer_fns( snum );
2398 pjob = print_job_find(sharename, jobid);
2400 if (!pjob || !server_info) {
2401 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2402 (unsigned int)jobid ));
2406 if (!pjob->spooled || pjob->sysjob == -1) {
2407 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2408 (int)pjob->sysjob, (unsigned int)jobid ));
2412 if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2413 !print_access_check(server_info, msg_ctx, snum,
2414 JOB_ACCESS_ADMINISTER)) {
2415 DEBUG(3, ("resume denied by security descriptor\n"));
2416 *errcode = WERR_ACCESS_DENIED;
2418 /* BEGIN_ADMIN_LOG */
2419 sys_adminlog( LOG_ERR,
2420 "Permission denied-- user not allowed to delete, \
2421 pause, or resume print job. User name: %s. Printer name: %s.",
2422 uidtoname(server_info->utok.uid),
2423 lp_printername(snum) );
2428 ret = (*(current_printif->job_resume))(snum, pjob);
2431 *errcode = WERR_INVALID_PARAM;
2435 /* force update the database */
2436 print_cache_flush(lp_const_servicename(snum));
2438 /* Send a printer notify message */
2440 notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2446 /****************************************************************************
2447 Write to a print file.
2448 ****************************************************************************/
2450 ssize_t print_job_write(struct tevent_context *ev,
2451 struct messaging_context *msg_ctx,
2452 int snum, uint32 jobid, const char *buf, size_t size)
2454 const char* sharename = lp_const_servicename(snum);
2455 ssize_t return_code;
2456 struct printjob *pjob;
2458 pjob = print_job_find(sharename, jobid);
2462 /* don't allow another process to get this info - it is meaningless */
2463 if (pjob->pid != sys_getpid())
2466 /* if SMBD is spooling this can't be allowed */
2467 if (pjob->status == PJOB_SMBD_SPOOLING) {
2471 return_code = write_data(pjob->fd, buf, size);
2473 if (return_code>0) {
2475 pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2480 /****************************************************************************
2481 Get the queue status - do not update if db is out of date.
2482 ****************************************************************************/
2484 static int get_queue_status(const char* sharename, print_status_struct *status)
2488 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2492 ZERO_STRUCTP(status);
2499 fstr_sprintf(keystr, "STATUS/%s", sharename);
2500 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2502 if (data.dsize == sizeof(print_status_struct))
2503 /* this memcpy is ok since the status struct was
2504 not packed before storing it in the tdb */
2505 memcpy(status, data.dptr, sizeof(print_status_struct));
2506 SAFE_FREE(data.dptr);
2509 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2510 release_print_db(pdb);
2511 return (len == -1 ? 0 : len);
2514 /****************************************************************************
2515 Determine the number of jobs in a queue.
2516 ****************************************************************************/
2518 int print_queue_length(struct messaging_context *msg_ctx, int snum,
2519 print_status_struct *pstatus)
2521 const char* sharename = lp_const_servicename( snum );
2522 print_status_struct status;
2525 ZERO_STRUCT( status );
2527 /* make sure the database is up to date */
2528 if (print_cache_expired(lp_const_servicename(snum), True))
2529 print_queue_update(msg_ctx, snum, False);
2531 /* also fetch the queue status */
2532 memset(&status, 0, sizeof(status));
2533 len = get_queue_status(sharename, &status);
2541 /***************************************************************************
2542 Allocate a jobid. Hold the lock for as short a time as possible.
2543 ***************************************************************************/
2545 static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum,
2546 const char *sharename, uint32 *pjobid)
2550 enum TDB_ERROR terr;
2553 *pjobid = (uint32)-1;
2555 for (i = 0; i < 3; i++) {
2556 /* Lock the database - only wait 20 seconds. */
2557 ret = tdb_lock_bystring_with_timeout(pdb->tdb,
2558 "INFO/nextjob", 20);
2560 DEBUG(0, ("allocate_print_jobid: "
2561 "Failed to lock printing database %s\n",
2563 terr = tdb_error(pdb->tdb);
2564 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2567 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2568 terr = tdb_error(pdb->tdb);
2569 if (terr != TDB_ERR_NOEXIST) {
2570 DEBUG(0, ("allocate_print_jobid: "
2571 "Failed to fetch INFO/nextjob "
2572 "for print queue %s\n", sharename));
2573 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2574 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2576 DEBUG(10, ("allocate_print_jobid: "
2577 "No existing jobid in %s\n", sharename));
2581 DEBUG(10, ("allocate_print_jobid: "
2582 "Read jobid %u from %s\n", jobid, sharename));
2584 jobid = NEXT_JOBID(jobid);
2586 ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid);
2588 terr = tdb_error(pdb->tdb);
2589 DEBUG(3, ("allocate_print_jobid: "
2590 "Failed to store INFO/nextjob.\n"));
2591 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2592 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2595 /* We've finished with the INFO/nextjob lock. */
2596 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2598 if (!print_job_exists(sharename, jobid)) {
2601 DEBUG(10, ("allocate_print_jobid: "
2602 "Found jobid %u in %s\n", jobid, sharename));
2606 DEBUG(0, ("allocate_print_jobid: "
2607 "Failed to allocate a print job for queue %s\n",
2609 /* Probably full... */
2610 return WERR_NO_SPOOL_SPACE;
2613 /* Store a dummy placeholder. */
2619 if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
2620 TDB_INSERT) == -1) {
2621 DEBUG(3, ("allocate_print_jobid: "
2622 "jobid (%d) failed to store placeholder.\n",
2624 terr = tdb_error(pdb->tdb);
2625 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2633 /***************************************************************************
2634 Append a jobid to the 'jobs added' list.
2635 ***************************************************************************/
2637 static bool add_to_jobs_added(struct tdb_print_db *pdb, uint32 jobid)
2642 SIVAL(&store_jobid, 0, jobid);
2643 data.dptr = (uint8 *)&store_jobid;
2646 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid ));
2648 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_added"),
2653 /***************************************************************************
2654 Do all checks needed to determine if we can start a job.
2655 ***************************************************************************/
2657 static WERROR print_job_checks(const struct auth_serversupplied_info *server_info,
2658 struct messaging_context *msg_ctx,
2659 int snum, int *njobs)
2661 const char *sharename = lp_const_servicename(snum);
2662 uint64_t dspace, dsize;
2666 if (!print_access_check(server_info, msg_ctx, snum,
2667 PRINTER_ACCESS_USE)) {
2668 DEBUG(3, ("print_job_checks: "
2669 "job start denied by security descriptor\n"));
2670 return WERR_ACCESS_DENIED;
2673 if (!print_time_access_check(server_info, msg_ctx, sharename)) {
2674 DEBUG(3, ("print_job_checks: "
2675 "job start denied by time check\n"));
2676 return WERR_ACCESS_DENIED;
2679 /* see if we have sufficient disk space */
2680 if (lp_minprintspace(snum)) {
2681 minspace = lp_minprintspace(snum);
2682 ret = sys_fsusage(lp_pathname(snum), &dspace, &dsize);
2683 if (ret == 0 && dspace < 2*minspace) {
2684 DEBUG(3, ("print_job_checks: "
2685 "disk space check failed.\n"));
2686 return WERR_NO_SPOOL_SPACE;
2690 /* for autoloaded printers, check that the printcap entry still exists */
2691 if (lp_autoloaded(snum) && !pcap_printername_ok(sharename)) {
2692 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2694 return WERR_ACCESS_DENIED;
2697 /* Insure the maximum queue size is not violated */
2698 *njobs = print_queue_length(msg_ctx, snum, NULL);
2699 if (*njobs > lp_maxprintjobs(snum)) {
2700 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2701 "larger than max printjobs per queue (%d).\n",
2702 sharename, *njobs, lp_maxprintjobs(snum)));
2703 return WERR_NO_SPOOL_SPACE;
2709 /***************************************************************************
2711 ***************************************************************************/
2713 static WERROR print_job_spool_file(int snum, uint32_t jobid,
2714 const char *output_file,
2715 struct printjob *pjob)
2722 /* if this file is within the printer path, it means that smbd
2723 * is spooling it and will pass us control when it is finished.
2724 * Verify that the file name is ok, within path, and it is
2725 * already already there */
2727 path = lp_pathname(snum);
2729 if (strncmp(output_file, path, len) == 0 &&
2730 (output_file[len - 1] == '/' || output_file[len] == '/')) {
2732 /* verify path is not too long */
2733 if (strlen(output_file) >= sizeof(pjob->filename)) {
2734 return WERR_INVALID_NAME;
2737 /* verify that the file exists */
2738 if (sys_stat(output_file, &st, false) != 0) {
2739 return WERR_INVALID_NAME;
2742 fstrcpy(pjob->filename, output_file);
2744 DEBUG(3, ("print_job_spool_file:"
2745 "External spooling activated"));
2747 /* we do not open the file until spooling is done */
2749 pjob->status = PJOB_SMBD_SPOOLING;
2755 slprintf(pjob->filename, sizeof(pjob->filename)-1,
2756 "%s/%s%.8u.XXXXXX", lp_pathname(snum),
2757 PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2758 pjob->fd = mkstemp(pjob->filename);
2760 if (pjob->fd == -1) {
2761 werr = map_werror_from_unix(errno);
2762 if (W_ERROR_EQUAL(werr, WERR_ACCESS_DENIED)) {
2763 /* Common setup error, force a report. */
2764 DEBUG(0, ("print_job_spool_file: "
2765 "insufficient permissions to open spool "
2766 "file %s.\n", pjob->filename));
2768 /* Normal case, report at level 3 and above. */
2769 DEBUG(3, ("print_job_spool_file: "
2770 "can't open spool file %s\n",
2779 /***************************************************************************
2780 Start spooling a job - return the jobid.
2781 ***************************************************************************/
2783 WERROR print_job_start(const struct auth_serversupplied_info *server_info,
2784 struct messaging_context *msg_ctx,
2785 const char *clientmachine,
2786 int snum, const char *docname, const char *filename,
2787 struct spoolss_DeviceMode *devmode, uint32_t *_jobid)
2791 struct printjob pjob;
2792 const char *sharename = lp_const_servicename(snum);
2793 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2798 return WERR_INTERNAL_DB_CORRUPTION;
2801 path = lp_pathname(snum);
2803 werr = print_job_checks(server_info, msg_ctx, snum, &njobs);
2804 if (!W_ERROR_IS_OK(werr)) {
2805 release_print_db(pdb);
2809 DEBUG(10, ("print_job_start: "
2810 "Queue %s number of jobs (%d), max printjobs = %d\n",
2811 sharename, njobs, lp_maxprintjobs(snum)));
2813 werr = allocate_print_jobid(pdb, snum, sharename, &jobid);
2814 if (!W_ERROR_IS_OK(werr)) {
2818 /* create the database entry */
2822 pjob.pid = sys_getpid();
2825 pjob.starttime = time(NULL);
2826 pjob.status = LPQ_SPOOLING;
2828 pjob.spooled = False;
2830 pjob.devmode = devmode;
2832 fstrcpy(pjob.jobname, docname);
2834 fstrcpy(pjob.clientmachine, clientmachine);
2836 fstrcpy(pjob.user, lp_printjob_username(snum));
2837 standard_sub_advanced(sharename, server_info->sanitized_username,
2838 path, server_info->utok.gid,
2839 server_info->sanitized_username,
2840 server_info->info3->base.domain.string,
2841 pjob.user, sizeof(pjob.user)-1);
2842 /* ensure NULL termination */
2843 pjob.user[sizeof(pjob.user)-1] = '\0';
2845 fstrcpy(pjob.queuename, lp_const_servicename(snum));
2847 /* we have a job entry - now create the spool file */
2848 werr = print_job_spool_file(snum, jobid, filename, &pjob);
2849 if (!W_ERROR_IS_OK(werr)) {
2853 pjob_store(server_event_context(), msg_ctx, sharename, jobid, &pjob);
2855 /* Update the 'jobs added' entry used by print_queue_status. */
2856 add_to_jobs_added(pdb, jobid);
2858 /* Ensure we keep a rough count of the number of total jobs... */
2859 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2861 release_print_db(pdb);
2868 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
2871 release_print_db(pdb);
2873 DEBUG(3, ("print_job_start: returning fail. "
2874 "Error = %s\n", win_errstr(werr)));
2878 /****************************************************************************
2879 Update the number of pages spooled to jobid
2880 ****************************************************************************/
2882 void print_job_endpage(struct messaging_context *msg_ctx,
2883 int snum, uint32 jobid)
2885 const char* sharename = lp_const_servicename(snum);
2886 struct printjob *pjob;
2888 pjob = print_job_find(sharename, jobid);
2891 /* don't allow another process to get this info - it is meaningless */
2892 if (pjob->pid != sys_getpid())
2896 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
2899 /****************************************************************************
2900 Print a file - called on closing the file. This spools the job.
2901 If normal close is false then we're tearing down the jobs - treat as an
2903 ****************************************************************************/
2905 NTSTATUS print_job_end(struct messaging_context *msg_ctx, int snum,
2906 uint32 jobid, enum file_close_type close_type)
2908 const char* sharename = lp_const_servicename(snum);
2909 struct printjob *pjob;
2911 SMB_STRUCT_STAT sbuf;
2912 struct printif *current_printif = get_printer_fns( snum );
2913 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2915 pjob = print_job_find(sharename, jobid);
2918 return NT_STATUS_PRINT_CANCELLED;
2921 if (pjob->spooled || pjob->pid != sys_getpid()) {
2922 return NT_STATUS_ACCESS_DENIED;
2925 if (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) {
2926 if (pjob->status == PJOB_SMBD_SPOOLING) {
2927 /* take over the file now, smbd is done */
2928 if (sys_stat(pjob->filename, &sbuf, false) != 0) {
2929 status = map_nt_error_from_unix(errno);
2930 DEBUG(3, ("print_job_end: "
2931 "stat file failed for jobid %d\n",
2936 pjob->status = LPQ_SPOOLING;
2940 if ((sys_fstat(pjob->fd, &sbuf, false) != 0)) {
2941 status = map_nt_error_from_unix(errno);
2943 DEBUG(3, ("print_job_end: "
2944 "stat file failed for jobid %d\n",
2952 pjob->size = sbuf.st_ex_size;
2956 * Not a normal close, something has gone wrong. Cleanup.
2958 if (pjob->fd != -1) {
2964 /* Technically, this is not quite right. If the printer has a separator
2965 * page turned on, the NT spooler prints the separator page even if the
2966 * print job is 0 bytes. 010215 JRR */
2967 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2968 /* don't bother spooling empty files or something being deleted. */
2969 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2970 pjob->filename, pjob->size ? "deleted" : "zero length" ));
2971 unlink(pjob->filename);
2972 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
2973 return NT_STATUS_OK;
2976 ret = (*(current_printif->job_submit))(snum, pjob);
2979 status = NT_STATUS_PRINT_CANCELLED;
2983 /* The print job has been successfully handed over to the back-end */
2985 pjob->spooled = True;
2986 pjob->status = LPQ_QUEUED;
2987 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
2989 /* make sure the database is up to date */
2990 if (print_cache_expired(lp_const_servicename(snum), True))
2991 print_queue_update(msg_ctx, snum, False);
2993 return NT_STATUS_OK;
2997 /* The print job was not successfully started. Cleanup */
2998 /* Still need to add proper error return propagation! 010122:JRR */
3000 unlink(pjob->filename);
3001 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
3005 /****************************************************************************
3006 Get a snapshot of jobs in the system without traversing.
3007 ****************************************************************************/
3009 static bool get_stored_queue_info(struct messaging_context *msg_ctx,
3010 struct tdb_print_db *pdb, int snum,
3011 int *pcount, print_queue_struct **ppqueue)
3013 TDB_DATA data, cgdata, jcdata;
3014 print_queue_struct *queue = NULL;
3016 uint32 extra_count = 0;
3017 uint32_t changed_count = 0;
3018 int total_count = 0;
3021 int max_reported_jobs = lp_max_reported_jobs(snum);
3023 const char* sharename = lp_servicename(snum);
3025 /* make sure the database is up to date */
3026 if (print_cache_expired(lp_const_servicename(snum), True))
3027 print_queue_update(msg_ctx, snum, False);
3033 ZERO_STRUCT(cgdata);
3035 /* Get the stored queue data. */
3036 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
3038 if (data.dptr && data.dsize >= sizeof(qcount))
3039 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
3041 /* Get the added jobs list. */
3042 cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added"));
3043 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
3044 extra_count = cgdata.dsize/4;
3046 /* Get the changed jobs list. */
3047 jcdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
3048 if (jcdata.dptr != NULL && (jcdata.dsize % 4 == 0))
3049 changed_count = jcdata.dsize / 4;
3051 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
3053 /* Allocate the queue size. */
3054 if (qcount == 0 && extra_count == 0)
3057 if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
3060 /* Retrieve the linearised queue data. */
3062 for( i = 0; i < qcount; i++) {
3063 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
3064 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
3073 queue[i].job = qjob;
3074 queue[i].size = qsize;
3075 queue[i].page_count = qpage_count;
3076 queue[i].status = qstatus;
3077 queue[i].priority = qpriority;
3078 queue[i].time = qtime;
3081 total_count = qcount;
3083 /* Add new jobids to the queue. */
3084 for( i = 0; i < extra_count; i++) {
3086 struct printjob *pjob;
3088 jobid = IVAL(cgdata.dptr, i*4);
3089 DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid));
3090 pjob = print_job_find(lp_const_servicename(snum), jobid);
3092 DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid));
3093 remove_from_jobs_added(sharename, jobid);
3097 queue[total_count].job = jobid;
3098 queue[total_count].size = pjob->size;
3099 queue[total_count].page_count = pjob->page_count;
3100 queue[total_count].status = pjob->status;
3101 queue[total_count].priority = 1;
3102 queue[total_count].time = pjob->starttime;
3103 fstrcpy(queue[total_count].fs_user, pjob->user);
3104 fstrcpy(queue[total_count].fs_file, pjob->jobname);
3108 /* Update the changed jobids. */
3109 for (i = 0; i < changed_count; i++) {
3110 uint32_t jobid = IVAL(jcdata.dptr, i * 4);
3114 for (j = 0; j < total_count; j++) {
3115 if (queue[j].job == jobid) {
3122 struct printjob *pjob;
3124 DEBUG(5,("get_stored_queue_info: changed job: %u\n",
3125 (unsigned int) jobid));
3127 pjob = print_job_find(sharename, jobid);
3129 DEBUG(5,("get_stored_queue_info: failed to find "
3130 "changed job = %u\n",
3131 (unsigned int) jobid));
3132 remove_from_jobs_changed(sharename, jobid);
3136 queue[j].job = jobid;
3137 queue[j].size = pjob->size;
3138 queue[j].page_count = pjob->page_count;
3139 queue[j].status = pjob->status;
3140 queue[j].priority = 1;
3141 queue[j].time = pjob->starttime;
3142 fstrcpy(queue[j].fs_user, pjob->user);
3143 fstrcpy(queue[j].fs_file, pjob->jobname);
3145 DEBUG(5,("get_stored_queue_info: updated queue[%u], jobid: %u, jobname: %s\n",
3146 (unsigned int) j, (unsigned int) jobid, pjob->jobname));
3149 remove_from_jobs_changed(sharename, jobid);
3152 /* Sort the queue by submission time otherwise they are displayed
3155 TYPESAFE_QSORT(queue, total_count, printjob_comp);
3157 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
3159 if (max_reported_jobs && total_count > max_reported_jobs)
3160 total_count = max_reported_jobs;
3163 *pcount = total_count;
3169 SAFE_FREE(data.dptr);
3170 SAFE_FREE(cgdata.dptr);
3174 /****************************************************************************
3175 Get a printer queue listing.
3176 set queue = NULL and status = NULL if you just want to update the cache
3177 ****************************************************************************/
3179 int print_queue_status(struct messaging_context *msg_ctx, int snum,
3180 print_queue_struct **ppqueue,
3181 print_status_struct *status)
3185 const char *sharename;
3186 struct tdb_print_db *pdb;
3189 /* make sure the database is up to date */
3191 if (print_cache_expired(lp_const_servicename(snum), True))
3192 print_queue_update(msg_ctx, snum, False);
3194 /* return if we are done */
3195 if ( !ppqueue || !status )
3199 sharename = lp_const_servicename(snum);
3200 pdb = get_print_db_byname(sharename);
3206 * Fetch the queue status. We must do this first, as there may
3207 * be no jobs in the queue.
3210 ZERO_STRUCTP(status);
3211 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
3212 key = string_tdb_data(keystr);
3214 data = tdb_fetch(pdb->tdb, key);
3216 if (data.dsize == sizeof(*status)) {
3217 /* this memcpy is ok since the status struct was
3218 not packed before storing it in the tdb */
3219 memcpy(status, data.dptr, sizeof(*status));
3221 SAFE_FREE(data.dptr);
3225 * Now, fetch the print queue information. We first count the number
3226 * of entries, and then only retrieve the queue if necessary.
3229 if (!get_stored_queue_info(msg_ctx, pdb, snum, &count, ppqueue)) {
3230 release_print_db(pdb);
3234 release_print_db(pdb);
3238 /****************************************************************************
3240 ****************************************************************************/
3242 WERROR print_queue_pause(const struct auth_serversupplied_info *server_info,
3243 struct messaging_context *msg_ctx, int snum)
3246 struct printif *current_printif = get_printer_fns( snum );
3248 if (!print_access_check(server_info, msg_ctx, snum,
3249 PRINTER_ACCESS_ADMINISTER)) {
3250 return WERR_ACCESS_DENIED;
3256 ret = (*(current_printif->queue_pause))(snum);
3261 return WERR_INVALID_PARAM;
3264 /* force update the database */
3265 print_cache_flush(lp_const_servicename(snum));
3267 /* Send a printer notify message */
3269 notify_printer_status(server_event_context(), msg_ctx, snum,
3270 PRINTER_STATUS_PAUSED);
3275 /****************************************************************************
3277 ****************************************************************************/
3279 WERROR print_queue_resume(const struct auth_serversupplied_info *server_info,
3280 struct messaging_context *msg_ctx, int snum)
3283 struct printif *current_printif = get_printer_fns( snum );
3285 if (!print_access_check(server_info, msg_ctx, snum,
3286 PRINTER_ACCESS_ADMINISTER)) {
3287 return WERR_ACCESS_DENIED;
3292 ret = (*(current_printif->queue_resume))(snum);
3297 return WERR_INVALID_PARAM;
3300 /* make sure the database is up to date */
3301 if (print_cache_expired(lp_const_servicename(snum), True))
3302 print_queue_update(msg_ctx, snum, True);
3304 /* Send a printer notify message */
3306 notify_printer_status(server_event_context(), msg_ctx, snum,
3312 /****************************************************************************
3313 Purge a queue - implemented by deleting all jobs that we can delete.
3314 ****************************************************************************/
3316 WERROR print_queue_purge(const struct auth_serversupplied_info *server_info,
3317 struct messaging_context *msg_ctx, int snum)
3319 print_queue_struct *queue;
3320 print_status_struct status;
3324 /* Force and update so the count is accurate (i.e. not a cached count) */
3325 print_queue_update(msg_ctx, snum, True);
3327 can_job_admin = print_access_check(server_info,
3330 JOB_ACCESS_ADMINISTER);
3331 njobs = print_queue_status(msg_ctx, snum, &queue, &status);
3333 if ( can_job_admin )
3336 for (i=0;i<njobs;i++) {
3337 bool owner = is_owner(server_info, lp_const_servicename(snum),
3340 if (owner || can_job_admin) {
3341 print_job_delete1(server_event_context(), msg_ctx,
3342 snum, queue[i].job);
3346 if ( can_job_admin )
3349 /* update the cache */
3350 print_queue_update(msg_ctx, snum, True);