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"
34 extern struct current_user current_user;
35 extern userdom_struct current_user_info;
37 /* Current printer interface */
38 static bool remove_from_jobs_added(const char* sharename, uint32 jobid);
41 the printing backend revolves around a tdb database that stores the
42 SMB view of the print queue
44 The key for this database is a jobid - a internally generated number that
45 uniquely identifies a print job
47 reading the print queue involves two steps:
48 - possibly running lpq and updating the internal database from that
49 - reading entries from the database
51 jobids are assigned when a job starts spooling.
54 static TDB_CONTEXT *rap_tdb;
55 static uint16 next_rap_jobid;
56 struct rap_jobid_key {
61 /***************************************************************************
62 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
63 bit RPC jobids.... JRA.
64 ***************************************************************************/
66 uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
70 struct rap_jobid_key jinfo;
73 DEBUG(10,("pjobid_to_rap: called.\n"));
76 /* Create the in-memory tdb. */
77 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
83 fstrcpy( jinfo.sharename, sharename );
85 key.dptr = (uint8 *)&jinfo;
86 key.dsize = sizeof(jinfo);
88 data = tdb_fetch(rap_tdb, key);
89 if (data.dptr && data.dsize == sizeof(uint16)) {
90 rap_jobid = SVAL(data.dptr, 0);
92 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
93 (unsigned int)jobid, (unsigned int)rap_jobid));
97 /* Not found - create and store mapping. */
98 rap_jobid = ++next_rap_jobid;
100 rap_jobid = ++next_rap_jobid;
101 SSVAL(buf,0,rap_jobid);
103 data.dsize = sizeof(rap_jobid);
104 tdb_store(rap_tdb, key, data, TDB_REPLACE);
105 tdb_store(rap_tdb, data, key, TDB_REPLACE);
107 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
108 (unsigned int)jobid, (unsigned int)rap_jobid));
112 bool rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
117 DEBUG(10,("rap_to_pjobid called.\n"));
122 SSVAL(buf,0,rap_jobid);
124 key.dsize = sizeof(rap_jobid);
125 data = tdb_fetch(rap_tdb, key);
126 if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) )
128 struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
129 if (sharename != NULL) {
130 fstrcpy( sharename, jinfo->sharename );
132 *pjobid = jinfo->jobid;
133 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
134 (unsigned int)*pjobid, (unsigned int)rap_jobid));
135 SAFE_FREE(data.dptr);
139 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
140 (unsigned int)rap_jobid));
141 SAFE_FREE(data.dptr);
145 void rap_jobid_delete(const char* sharename, uint32 jobid)
149 struct rap_jobid_key jinfo;
152 DEBUG(10,("rap_jobid_delete: called.\n"));
157 ZERO_STRUCT( jinfo );
158 fstrcpy( jinfo.sharename, sharename );
160 key.dptr = (uint8 *)&jinfo;
161 key.dsize = sizeof(jinfo);
163 data = tdb_fetch(rap_tdb, key);
164 if (!data.dptr || (data.dsize != sizeof(uint16))) {
165 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
166 (unsigned int)jobid ));
167 SAFE_FREE(data.dptr);
171 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
172 (unsigned int)jobid ));
174 rap_jobid = SVAL(data.dptr, 0);
175 SAFE_FREE(data.dptr);
176 SSVAL(buf,0,rap_jobid);
178 data.dsize = sizeof(rap_jobid);
179 tdb_delete(rap_tdb, key);
180 tdb_delete(rap_tdb, data);
183 static int get_queue_status(const char* sharename, print_status_struct *);
185 /****************************************************************************
186 Initialise the printing backend. Called once at startup before the fork().
187 ****************************************************************************/
189 bool print_backend_init(struct messaging_context *msg_ctx)
191 const char *sversion = "INFO/version";
192 int services = lp_numservices();
195 unlink(cache_path("printing.tdb"));
196 mkdir(cache_path("printing"),0755);
198 /* handle a Samba upgrade */
200 for (snum = 0; snum < services; snum++) {
201 struct tdb_print_db *pdb;
202 if (!lp_print_ok(snum))
205 pdb = get_print_db_byname(lp_const_servicename(snum));
208 if (tdb_lock_bystring(pdb->tdb, sversion) == -1) {
209 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
210 release_print_db(pdb);
213 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
214 tdb_wipe_all(pdb->tdb);
215 tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
217 tdb_unlock_bystring(pdb->tdb, sversion);
218 release_print_db(pdb);
221 close_all_print_db(); /* Don't leave any open. */
223 /* do NT print initialization... */
224 return nt_printing_init(msg_ctx);
227 /****************************************************************************
228 Shut down printing backend. Called once at shutdown to close the tdb.
229 ****************************************************************************/
231 void printing_end(void)
233 close_all_print_db(); /* Don't leave any open. */
236 /****************************************************************************
237 Retrieve the set of printing functions for a given service. This allows
238 us to set the printer function table based on the value of the 'printing'
241 Use the generic interface as the default and only use cups interface only
242 when asked for (and only when supported)
243 ****************************************************************************/
245 static struct printif *get_printer_fns_from_type( enum printing_types type )
247 struct printif *printer_fns = &generic_printif;
250 if ( type == PRINT_CUPS ) {
251 printer_fns = &cups_printif;
253 #endif /* HAVE_CUPS */
256 if ( type == PRINT_IPRINT ) {
257 printer_fns = &iprint_printif;
259 #endif /* HAVE_IPRINT */
261 printer_fns->type = type;
266 static struct printif *get_printer_fns( int snum )
268 return get_printer_fns_from_type( (enum printing_types)lp_printing(snum) );
272 /****************************************************************************
273 Useful function to generate a tdb key.
274 ****************************************************************************/
276 static TDB_DATA print_key(uint32 jobid, uint32 *tmp)
280 SIVAL(tmp, 0, jobid);
281 ret.dptr = (uint8 *)tmp;
282 ret.dsize = sizeof(*tmp);
286 /****************************************************************************
287 Pack the devicemode to store it in a tdb.
288 ****************************************************************************/
289 static int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8 *buf, int buflen)
291 enum ndr_err_code ndr_err;
296 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(),
298 (ndr_push_flags_fn_t)
299 ndr_push_spoolss_DeviceMode);
300 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
301 DEBUG(10, ("pack_devicemode: "
302 "error encoding spoolss_DeviceMode\n"));
309 len = tdb_pack(buf, buflen, "B", blob.length, blob.data);
312 DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname));
319 /****************************************************************************
320 Unpack the devicemode to store it in a tdb.
321 ****************************************************************************/
322 static int unpack_devicemode(TALLOC_CTX *mem_ctx,
323 const uint8 *buf, int buflen,
324 struct spoolss_DeviceMode **devmode)
326 struct spoolss_DeviceMode *dm;
327 enum ndr_err_code ndr_err;
335 len = tdb_unpack(buf, buflen, "B", &data_len, &data);
340 dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
345 blob = data_blob_const(data, data_len);
347 ndr_err = ndr_pull_struct_blob(&blob, dm, dm,
348 (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);
349 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
350 DEBUG(10, ("unpack_devicemode: "
351 "error parsing spoolss_DeviceMode\n"));
355 DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
356 dm->devicename, dm->formname));
357 if (dm->driverextra_data.data) {
358 DEBUG(8, ("with a private section of %d bytes\n",
359 dm->__driverextra_length));
369 /***********************************************************************
370 unpack a pjob from a tdb buffer
371 ***********************************************************************/
373 static int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )
377 uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
378 uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
383 len += tdb_unpack(buf+len, buflen-len, "dddddddddfffff",
402 used = unpack_devicemode(NULL, buf+len, buflen-len, &pjob->devmode);
410 pjob->sysjob = pjsysjob;
412 pjob->starttime = pjstarttime;
413 pjob->status = pjstatus;
415 pjob->page_count = pjpage_count;
416 pjob->spooled = pjspooled;
417 pjob->smbjob = pjsmbjob;
423 /****************************************************************************
424 Useful function to find a print job in the database.
425 ****************************************************************************/
427 static struct printjob *print_job_find(const char *sharename, uint32 jobid)
429 static struct printjob pjob;
432 struct tdb_print_db *pdb = get_print_db_byname(sharename);
434 DEBUG(10,("print_job_find: looking up job %u for share %s\n",
435 (unsigned int)jobid, sharename ));
441 ret = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
442 release_print_db(pdb);
445 DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid ));
449 talloc_free(pjob.devmode);
453 if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
454 DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid ));
461 DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
462 (int)pjob.sysjob, (unsigned int)jobid ));
467 /* Convert a unix jobid to a smb jobid */
469 struct unixjob_traverse_state {
471 uint32 sysjob_to_jobid_value;
474 static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
475 TDB_DATA data, void *private_data)
477 struct printjob *pjob;
478 struct unixjob_traverse_state *state =
479 (struct unixjob_traverse_state *)private_data;
481 if (!data.dptr || data.dsize == 0)
484 pjob = (struct printjob *)data.dptr;
485 if (key.dsize != sizeof(uint32))
488 if (state->sysjob == pjob->sysjob) {
489 uint32 jobid = IVAL(key.dptr,0);
491 state->sysjob_to_jobid_value = jobid;
498 /****************************************************************************
499 This is a *horribly expensive call as we have to iterate through all the
500 current printer tdb's. Don't do this often ! JRA.
501 ****************************************************************************/
503 uint32 sysjob_to_jobid(int unix_jobid)
505 int services = lp_numservices();
507 struct unixjob_traverse_state state;
509 state.sysjob = unix_jobid;
510 state.sysjob_to_jobid_value = (uint32)-1;
512 for (snum = 0; snum < services; snum++) {
513 struct tdb_print_db *pdb;
514 if (!lp_print_ok(snum))
516 pdb = get_print_db_byname(lp_const_servicename(snum));
520 tdb_traverse(pdb->tdb, unixjob_traverse_fn, &state);
521 release_print_db(pdb);
522 if (state.sysjob_to_jobid_value != (uint32)-1)
523 return state.sysjob_to_jobid_value;
528 /****************************************************************************
529 Send notifications based on what has changed after a pjob_store.
530 ****************************************************************************/
532 static const struct {
534 uint32_t spoolss_status;
535 } lpq_to_spoolss_status_map[] = {
536 { LPQ_QUEUED, JOB_STATUS_QUEUED },
537 { LPQ_PAUSED, JOB_STATUS_PAUSED },
538 { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
539 { LPQ_PRINTING, JOB_STATUS_PRINTING },
540 { LPQ_DELETING, JOB_STATUS_DELETING },
541 { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
542 { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
543 { LPQ_PRINTED, JOB_STATUS_PRINTED },
544 { LPQ_DELETED, JOB_STATUS_DELETED },
545 { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ },
546 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
550 /* Convert a lpq status value stored in printing.tdb into the
551 appropriate win32 API constant. */
553 static uint32 map_to_spoolss_status(uint32 lpq_status)
557 while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
558 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
559 return lpq_to_spoolss_status_map[i].spoolss_status;
566 /***************************************************************************
567 Append a jobid to the 'jobs changed' list.
568 ***************************************************************************/
570 static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32_t jobid)
573 uint32_t store_jobid;
575 SIVAL(&store_jobid, 0, jobid);
576 data.dptr = (uint8 *) &store_jobid;
579 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid ));
581 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
585 /***************************************************************************
586 Remove a jobid from the 'jobs changed' list.
587 ***************************************************************************/
589 static bool remove_from_jobs_changed(const char* sharename, uint32_t jobid)
591 struct tdb_print_db *pdb = get_print_db_byname(sharename);
595 bool gotlock = False;
603 key = string_tdb_data("INFO/jobs_changed");
605 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
610 data = tdb_fetch(pdb->tdb, key);
612 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
615 job_count = data.dsize / 4;
616 for (i = 0; i < job_count; i++) {
619 ch_jobid = IVAL(data.dptr, i*4);
620 if (ch_jobid == jobid) {
621 if (i < job_count -1 )
622 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
624 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
634 tdb_chainunlock(pdb->tdb, key);
635 SAFE_FREE(data.dptr);
636 release_print_db(pdb);
638 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
640 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
644 static void pjob_store_notify(struct tevent_context *ev,
645 struct messaging_context *msg_ctx,
646 const char* sharename, uint32 jobid,
647 struct printjob *old_data,
648 struct printjob *new_data,
651 bool new_job = false;
652 bool changed = false;
654 if (old_data == NULL) {
658 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
659 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
660 time first or else we'll end up with potential alignment
661 errors. I don't think the systemtime should be spooled as
662 a string, but this gets us around that error.
663 --jerry (i'll feel dirty for this) */
666 notify_job_submitted(ev, msg_ctx,
667 sharename, jobid, new_data->starttime);
668 notify_job_username(ev, msg_ctx,
669 sharename, jobid, new_data->user);
670 notify_job_name(ev, msg_ctx,
671 sharename, jobid, new_data->jobname);
672 notify_job_status(ev, msg_ctx,
673 sharename, jobid, map_to_spoolss_status(new_data->status));
674 notify_job_total_bytes(ev, msg_ctx,
675 sharename, jobid, new_data->size);
676 notify_job_total_pages(ev, msg_ctx,
677 sharename, jobid, new_data->page_count);
679 if (!strequal(old_data->jobname, new_data->jobname)) {
680 notify_job_name(ev, msg_ctx, sharename,
681 jobid, new_data->jobname);
685 if (old_data->status != new_data->status) {
686 notify_job_status(ev, msg_ctx,
688 map_to_spoolss_status(new_data->status));
691 if (old_data->size != new_data->size) {
692 notify_job_total_bytes(ev, msg_ctx,
693 sharename, jobid, new_data->size);
696 if (old_data->page_count != new_data->page_count) {
697 notify_job_total_pages(ev, msg_ctx,
699 new_data->page_count);
706 /****************************************************************************
707 Store a job structure back to the database.
708 ****************************************************************************/
710 static bool pjob_store(struct tevent_context *ev,
711 struct messaging_context *msg_ctx,
712 const char* sharename, uint32 jobid,
713 struct printjob *pjob)
716 TDB_DATA old_data, new_data;
718 struct tdb_print_db *pdb = get_print_db_byname(sharename);
720 int len, newlen, buflen;
728 old_data = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
730 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
737 len += tdb_pack(buf+len, buflen-len, "dddddddddfffff",
739 (uint32)pjob->sysjob,
741 (uint32)pjob->starttime,
742 (uint32)pjob->status,
744 (uint32)pjob->page_count,
745 (uint32)pjob->spooled,
746 (uint32)pjob->smbjob,
753 len += pack_devicemode(pjob->devmode, buf+len, buflen-len);
756 buf = (uint8 *)SMB_REALLOC(buf, len);
758 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
763 } while ( buflen != len );
769 new_data.dsize = len;
770 ret = (tdb_store(pdb->tdb, print_key(jobid, &tmp), new_data,
773 /* Send notify updates for what has changed */
776 bool changed = false;
777 struct printjob old_pjob;
779 if ( old_data.dsize )
781 if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
783 pjob_store_notify(server_event_context(),
785 sharename, jobid, &old_pjob,
788 talloc_free(old_pjob.devmode);
791 add_to_jobs_changed(pdb, jobid);
798 pjob_store_notify(server_event_context(), msg_ctx,
799 sharename, jobid, NULL, pjob,
804 release_print_db(pdb);
806 SAFE_FREE( old_data.dptr );
812 /****************************************************************************
813 Remove a job structure from the database.
814 ****************************************************************************/
816 static void pjob_delete(struct tevent_context *ev,
817 struct messaging_context *msg_ctx,
818 const char* sharename, uint32 jobid)
821 struct printjob *pjob;
822 uint32 job_status = 0;
823 struct tdb_print_db *pdb;
825 pdb = get_print_db_byname( sharename );
830 pjob = print_job_find( sharename, jobid );
833 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
834 (unsigned int)jobid));
835 release_print_db(pdb);
839 /* We must cycle through JOB_STATUS_DELETING and
840 JOB_STATUS_DELETED for the port monitor to delete the job
843 job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
844 notify_job_status(ev, msg_ctx, sharename, jobid, job_status);
846 /* Remove from printing.tdb */
848 tdb_delete(pdb->tdb, print_key(jobid, &tmp));
849 remove_from_jobs_added(sharename, jobid);
850 release_print_db( pdb );
851 rap_jobid_delete(sharename, jobid);
854 /****************************************************************************
855 List a unix job in the print database.
856 ****************************************************************************/
858 static void print_unix_job(struct tevent_context *ev,
859 struct messaging_context *msg_ctx,
860 const char *sharename, print_queue_struct *q,
863 struct printjob pj, *old_pj;
865 if (jobid == (uint32)-1)
866 jobid = q->job + UNIX_JOB_START;
868 /* Preserve the timestamp on an existing unix print job */
870 old_pj = print_job_find(sharename, jobid);
877 pj.starttime = old_pj ? old_pj->starttime : q->time;
878 pj.status = q->status;
881 fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
882 if (jobid < UNIX_JOB_START) {
884 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
887 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
889 fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
890 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
892 pjob_store(ev, msg_ctx, sharename, jobid, &pj);
896 struct traverse_struct {
897 print_queue_struct *queue;
898 int qcount, snum, maxcount, total_jobs;
899 const char *sharename;
901 const char *lprm_command;
902 struct printif *print_if;
903 struct tevent_context *ev;
904 struct messaging_context *msg_ctx;
907 /****************************************************************************
908 Utility fn to delete any jobs that are no longer active.
909 ****************************************************************************/
911 static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
913 struct traverse_struct *ts = (struct traverse_struct *)state;
914 struct printjob pjob;
918 if ( key.dsize != sizeof(jobid) )
921 jobid = IVAL(key.dptr, 0);
922 if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
924 talloc_free(pjob.devmode);
928 /* remove a unix job if it isn't in the system queue any more */
930 for (i=0;i<ts->qcount;i++) {
931 uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
932 if (jobid == u_jobid)
935 if (i == ts->qcount) {
936 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
937 (unsigned int)jobid ));
938 pjob_delete(ts->ev, ts->msg_ctx,
939 ts->sharename, jobid);
943 /* need to continue the the bottom of the function to
944 save the correct attributes */
947 /* maybe it hasn't been spooled yet */
949 /* if a job is not spooled and the process doesn't
950 exist then kill it. This cleans up after smbd
952 if (!process_exists_by_pid(pjob.pid)) {
953 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
954 (unsigned int)jobid, (unsigned int)pjob.pid ));
955 pjob_delete(ts->ev, ts->msg_ctx,
956 ts->sharename, jobid);
962 /* this check only makes sense for jobs submitted from Windows clients */
965 for (i=0;i<ts->qcount;i++) {
968 if ( pjob.status == LPQ_DELETED )
971 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
973 if (jobid == curr_jobid) {
975 /* try to clean up any jobs that need to be deleted */
977 if ( pjob.status == LPQ_DELETING ) {
980 result = (*(ts->print_if->job_delete))(
981 ts->sharename, ts->lprm_command, &pjob );
984 /* if we can't delete, then reset the job status */
985 pjob.status = LPQ_QUEUED;
986 pjob_store(ts->ev, ts->msg_ctx,
987 ts->sharename, jobid, &pjob);
990 /* if we deleted the job, the remove the tdb record */
993 ts->sharename, jobid);
994 pjob.status = LPQ_DELETED;
1004 /* The job isn't in the system queue - we have to assume it has
1005 completed, so delete the database entry. */
1007 if (i == ts->qcount) {
1009 /* A race can occur between the time a job is spooled and
1010 when it appears in the lpq output. This happens when
1011 the job is added to printing.tdb when another smbd
1012 running print_queue_update() has completed a lpq and
1013 is currently traversing the printing tdb and deleting jobs.
1014 Don't delete the job if it was submitted after the lpq_time. */
1016 if (pjob.starttime < ts->lpq_time) {
1017 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
1018 (unsigned int)jobid,
1019 (unsigned int)pjob.starttime,
1020 (unsigned int)ts->lpq_time ));
1021 pjob_delete(ts->ev, ts->msg_ctx,
1022 ts->sharename, jobid);
1028 /* Save the pjob attributes we will store.
1029 FIXME!!! This is the only place where queue->job
1030 represents the SMB jobid --jerry */
1032 ts->queue[i].job = jobid;
1033 ts->queue[i].size = pjob.size;
1034 ts->queue[i].page_count = pjob.page_count;
1035 ts->queue[i].status = pjob.status;
1036 ts->queue[i].priority = 1;
1037 ts->queue[i].time = pjob.starttime;
1038 fstrcpy(ts->queue[i].fs_user, pjob.user);
1039 fstrcpy(ts->queue[i].fs_file, pjob.jobname);
1046 /****************************************************************************
1047 Check if the print queue has been updated recently enough.
1048 ****************************************************************************/
1050 static void print_cache_flush(const char *sharename)
1053 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1057 slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
1058 tdb_store_int32(pdb->tdb, key, -1);
1059 release_print_db(pdb);
1062 /****************************************************************************
1063 Check if someone already thinks they are doing the update.
1064 ****************************************************************************/
1066 static pid_t get_updating_pid(const char *sharename)
1071 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1075 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
1076 key = string_tdb_data(keystr);
1078 data = tdb_fetch(pdb->tdb, key);
1079 release_print_db(pdb);
1080 if (!data.dptr || data.dsize != sizeof(pid_t)) {
1081 SAFE_FREE(data.dptr);
1085 updating_pid = IVAL(data.dptr, 0);
1086 SAFE_FREE(data.dptr);
1088 if (process_exists_by_pid(updating_pid))
1089 return updating_pid;
1094 /****************************************************************************
1095 Set the fact that we're doing the update, or have finished doing the update
1097 ****************************************************************************/
1099 static void set_updating_pid(const fstring sharename, bool updating)
1104 pid_t updating_pid = sys_getpid();
1107 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1112 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
1113 key = string_tdb_data(keystr);
1115 DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
1116 updating ? "" : "not ",
1120 tdb_delete(pdb->tdb, key);
1121 release_print_db(pdb);
1125 SIVAL( buffer, 0, updating_pid);
1127 data.dsize = 4; /* we always assume this is a 4 byte value */
1129 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1130 release_print_db(pdb);
1133 /****************************************************************************
1134 Sort print jobs by submittal time.
1135 ****************************************************************************/
1137 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
1148 /* Sort on job start time */
1150 if (j1->time == j2->time)
1152 return (j1->time > j2->time) ? 1 : -1;
1155 /****************************************************************************
1156 Store the sorted queue representation for later portmon retrieval.
1158 ****************************************************************************/
1160 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
1163 int max_reported_jobs = lp_max_reported_jobs(pts->snum);
1164 print_queue_struct *queue = pts->queue;
1167 unsigned int qcount;
1169 if (max_reported_jobs && (max_reported_jobs < pts->qcount))
1170 pts->qcount = max_reported_jobs;
1173 /* Work out the size. */
1175 data.dsize += tdb_pack(NULL, 0, "d", qcount);
1177 for (i = 0; i < pts->qcount; i++) {
1178 if ( queue[i].status == LPQ_DELETED )
1182 data.dsize += tdb_pack(NULL, 0, "ddddddff",
1183 (uint32)queue[i].job,
1184 (uint32)queue[i].size,
1185 (uint32)queue[i].page_count,
1186 (uint32)queue[i].status,
1187 (uint32)queue[i].priority,
1188 (uint32)queue[i].time,
1193 if ((data.dptr = (uint8 *)SMB_MALLOC(data.dsize)) == NULL)
1197 len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
1198 for (i = 0; i < pts->qcount; i++) {
1199 if ( queue[i].status == LPQ_DELETED )
1202 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
1203 (uint32)queue[i].job,
1204 (uint32)queue[i].size,
1205 (uint32)queue[i].page_count,
1206 (uint32)queue[i].status,
1207 (uint32)queue[i].priority,
1208 (uint32)queue[i].time,
1213 tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
1215 SAFE_FREE(data.dptr);
1219 static TDB_DATA get_jobs_added_data(struct tdb_print_db *pdb)
1225 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added"));
1226 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
1227 SAFE_FREE(data.dptr);
1234 static void check_job_added(const char *sharename, TDB_DATA data, uint32 jobid)
1237 unsigned int job_count = data.dsize / 4;
1239 for (i = 0; i < job_count; i++) {
1242 ch_jobid = IVAL(data.dptr, i*4);
1243 if (ch_jobid == jobid)
1244 remove_from_jobs_added(sharename, jobid);
1248 /****************************************************************************
1249 Check if the print queue has been updated recently enough.
1250 ****************************************************************************/
1252 static bool print_cache_expired(const char *sharename, bool check_pending)
1255 time_t last_qscan_time, time_now = time(NULL);
1256 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1257 bool result = False;
1262 snprintf(key, sizeof(key), "CACHE/%s", sharename);
1263 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1266 * Invalidate the queue for 3 reasons.
1267 * (1). last queue scan time == -1.
1268 * (2). Current time - last queue scan time > allowed cache time.
1269 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1270 * This last test picks up machines for which the clock has been moved
1271 * forward, an lpq scan done and then the clock moved back. Otherwise
1272 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1275 if (last_qscan_time == ((time_t)-1)
1276 || (time_now - last_qscan_time) >= lp_lpqcachetime()
1277 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
1280 time_t msg_pending_time;
1282 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1283 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1284 sharename, (int)last_qscan_time, (int)time_now,
1285 (int)lp_lpqcachetime() ));
1287 /* check if another smbd has already sent a message to update the
1288 queue. Give the pending message one minute to clear and
1289 then send another message anyways. Make sure to check for
1290 clocks that have been run forward and then back again. */
1292 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1295 && tdb_fetch_uint32( pdb->tdb, key, &u )
1296 && (msg_pending_time=u) > 0
1297 && msg_pending_time <= time_now
1298 && (time_now - msg_pending_time) < 60 )
1300 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1309 release_print_db(pdb);
1313 /****************************************************************************
1314 main work for updating the lpq cache for a printer queue
1315 ****************************************************************************/
1317 static void print_queue_update_internal( struct tevent_context *ev,
1318 struct messaging_context *msg_ctx,
1319 const char *sharename,
1320 struct printif *current_printif,
1321 char *lpq_command, char *lprm_command )
1324 print_queue_struct *queue = NULL;
1325 print_status_struct status;
1326 print_status_struct old_status;
1327 struct printjob *pjob;
1328 struct traverse_struct tstruct;
1331 fstring keystr, cachestr;
1332 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1338 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1339 sharename, current_printif->type, lpq_command));
1342 * Update the cache time FIRST ! Stops others even
1343 * attempting to get the lock and doing this
1344 * if the lpq takes a long time.
1347 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1348 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1350 /* get the current queue using the appropriate interface */
1351 ZERO_STRUCT(status);
1353 qcount = (*(current_printif->queue_get))(sharename,
1354 current_printif->type,
1355 lpq_command, &queue, &status);
1357 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1358 qcount, (qcount != 1) ? "s" : "", sharename));
1360 /* Sort the queue by submission time otherwise they are displayed
1363 TYPESAFE_QSORT(queue, qcount, printjob_comp);
1366 any job in the internal database that is marked as spooled
1367 and doesn't exist in the system queue is considered finished
1368 and removed from the database
1370 any job in the system database but not in the internal database
1371 is added as a unix job
1373 fill in any system job numbers as we go
1376 jcdata = get_jobs_added_data(pdb);
1378 for (i=0; i<qcount; i++) {
1379 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1381 if (jobid == (uint32)-1) {
1382 /* assume its a unix print job */
1383 print_unix_job(ev, msg_ctx,
1384 sharename, &queue[i], jobid);
1388 /* we have an active SMB print job - update its status */
1389 pjob = print_job_find(sharename, jobid);
1391 /* err, somethings wrong. Probably smbd was restarted
1392 with jobs in the queue. All we can do is treat them
1393 like unix jobs. Pity. */
1394 print_unix_job(ev, msg_ctx,
1395 sharename, &queue[i], jobid);
1399 pjob->sysjob = queue[i].job;
1401 /* don't reset the status on jobs to be deleted */
1403 if ( pjob->status != LPQ_DELETING )
1404 pjob->status = queue[i].status;
1406 pjob_store(ev, msg_ctx, sharename, jobid, pjob);
1408 check_job_added(sharename, jcdata, jobid);
1411 SAFE_FREE(jcdata.dptr);
1413 /* now delete any queued entries that don't appear in the
1415 tstruct.queue = queue;
1416 tstruct.qcount = qcount;
1418 tstruct.total_jobs = 0;
1419 tstruct.lpq_time = time(NULL);
1420 tstruct.sharename = sharename;
1421 tstruct.lprm_command = lprm_command;
1422 tstruct.print_if = current_printif;
1424 tstruct.msg_ctx = msg_ctx;
1426 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1428 /* Store the linearised queue, max jobs only. */
1429 store_queue_struct(pdb, &tstruct);
1431 SAFE_FREE(tstruct.queue);
1433 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1434 sharename, tstruct.total_jobs ));
1436 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1438 get_queue_status(sharename, &old_status);
1439 if (old_status.qcount != qcount)
1440 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1441 old_status.qcount, qcount, sharename));
1443 /* store the new queue status structure */
1444 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1445 key = string_tdb_data(keystr);
1447 status.qcount = qcount;
1448 data.dptr = (uint8 *)&status;
1449 data.dsize = sizeof(status);
1450 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1453 * Update the cache time again. We want to do this call
1454 * as little as possible...
1457 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1458 tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1460 /* clear the msg pending record for this queue */
1462 snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1464 if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1465 /* log a message but continue on */
1467 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1471 release_print_db( pdb );
1476 /****************************************************************************
1477 Update the internal database from the system print queue for a queue.
1478 obtain a lock on the print queue before proceeding (needed when mutiple
1479 smbd processes maytry to update the lpq cache concurrently).
1480 ****************************************************************************/
1482 static void print_queue_update_with_lock( struct tevent_context *ev,
1483 struct messaging_context *msg_ctx,
1484 const char *sharename,
1485 struct printif *current_printif,
1486 char *lpq_command, char *lprm_command )
1489 struct tdb_print_db *pdb;
1491 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1492 pdb = get_print_db_byname(sharename);
1496 if ( !print_cache_expired(sharename, False) ) {
1497 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1498 release_print_db(pdb);
1503 * Check to see if someone else is doing this update.
1504 * This is essentially a mutex on the update.
1507 if (get_updating_pid(sharename) != -1) {
1508 release_print_db(pdb);
1512 /* Lock the queue for the database update */
1514 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1515 /* Only wait 10 seconds for this. */
1516 if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
1517 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1518 release_print_db(pdb);
1523 * Ensure that no one else got in here.
1524 * If the updating pid is still -1 then we are
1528 if (get_updating_pid(sharename) != -1) {
1530 * Someone else is doing the update, exit.
1532 tdb_unlock_bystring(pdb->tdb, keystr);
1533 release_print_db(pdb);
1538 * We're going to do the update ourselves.
1541 /* Tell others we're doing the update. */
1542 set_updating_pid(sharename, True);
1545 * Allow others to enter and notice we're doing
1549 tdb_unlock_bystring(pdb->tdb, keystr);
1551 /* do the main work now */
1553 print_queue_update_internal(ev, msg_ctx,
1554 sharename, current_printif,
1555 lpq_command, lprm_command);
1557 /* Delete our pid from the db. */
1558 set_updating_pid(sharename, False);
1559 release_print_db(pdb);
1562 /****************************************************************************
1563 this is the receive function of the background lpq updater
1564 ****************************************************************************/
1565 void print_queue_receive(struct messaging_context *msg,
1568 struct server_id server_id,
1572 char *lpqcommand = NULL, *lprmcommand = NULL;
1576 len = tdb_unpack( (uint8 *)data->data, data->length, "fdPP",
1583 SAFE_FREE(lpqcommand);
1584 SAFE_FREE(lprmcommand);
1585 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1589 print_queue_update_with_lock(server_event_context(), msg, sharename,
1590 get_printer_fns_from_type((enum printing_types)printing_type),
1591 lpqcommand, lprmcommand );
1593 SAFE_FREE(lpqcommand);
1594 SAFE_FREE(lprmcommand);
1598 static void printing_pause_fd_handler(struct tevent_context *ev,
1599 struct tevent_fd *fde,
1604 * If pause_pipe[1] is closed it means the parent smbd
1605 * and children exited or aborted.
1607 exit_server_cleanly(NULL);
1610 extern struct child_pid *children;
1611 extern int num_children;
1613 static void add_child_pid(pid_t pid)
1615 struct child_pid *child;
1617 child = SMB_MALLOC_P(struct child_pid);
1618 if (child == NULL) {
1619 DEBUG(0, ("Could not add child struct -- malloc failed\n"));
1623 DLIST_ADD(children, child);
1627 static pid_t background_lpq_updater_pid = -1;
1629 /****************************************************************************
1630 main thread of the background lpq updater
1631 ****************************************************************************/
1632 void start_background_queue(struct tevent_context *ev,
1633 struct messaging_context *msg_ctx)
1635 /* Use local variables for this as we don't
1636 * need to save the parent side of this, just
1637 * ensure it closes when the process exits.
1641 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1643 if (pipe(pause_pipe) == -1) {
1644 DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno) ));
1648 background_lpq_updater_pid = sys_fork();
1650 if (background_lpq_updater_pid == -1) {
1651 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1655 /* Track the printing pid along with other smbd children */
1656 add_child_pid(background_lpq_updater_pid);
1658 if(background_lpq_updater_pid == 0) {
1659 struct tevent_fd *fde;
1664 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1666 close(pause_pipe[0]);
1669 status = reinit_after_fork(msg_ctx, ev, procid_self(), true);
1671 if (!NT_STATUS_IS_OK(status)) {
1672 DEBUG(0,("reinit_after_fork() failed\n"));
1673 smb_panic("reinit_after_fork() failed");
1676 smbd_setup_sig_term_handler();
1677 smbd_setup_sig_hup_handler(ev, msg_ctx);
1679 if (!serverid_register(procid_self(),
1680 FLAG_MSG_GENERAL|FLAG_MSG_SMBD
1681 |FLAG_MSG_PRINT_GENERAL)) {
1685 if (!locking_init()) {
1689 messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE,
1690 print_queue_receive);
1692 fde = tevent_add_fd(ev, ev, pause_pipe[1], TEVENT_FD_READ,
1693 printing_pause_fd_handler,
1696 DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
1697 smb_panic("tevent_add_fd() failed for pause_pipe");
1700 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1701 ret = tevent_loop_wait(ev);
1702 /* should not be reached */
1703 DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
1704 ret, (ret == 0) ? "out of events" : strerror(errno)));
1708 close(pause_pipe[1]);
1711 /****************************************************************************
1712 update the internal database from the system print queue for a queue
1713 ****************************************************************************/
1715 static void print_queue_update(struct messaging_context *msg_ctx,
1716 int snum, bool force)
1720 char *lpqcommand = NULL;
1721 char *lprmcommand = NULL;
1722 uint8 *buffer = NULL;
1725 struct tdb_print_db *pdb;
1727 struct printif *current_printif;
1728 TALLOC_CTX *ctx = talloc_tos();
1730 fstrcpy( sharename, lp_const_servicename(snum));
1732 /* don't strip out characters like '$' from the printername */
1734 lpqcommand = talloc_string_sub2(ctx,
1735 lp_lpqcommand(snum),
1737 lp_printername(snum),
1738 false, false, false);
1742 lpqcommand = talloc_sub_advanced(ctx,
1743 lp_servicename(snum),
1744 current_user_info.unix_name,
1746 current_user.ut.gid,
1747 get_current_username(),
1748 current_user_info.domain,
1754 lprmcommand = talloc_string_sub2(ctx,
1755 lp_lprmcommand(snum),
1757 lp_printername(snum),
1758 false, false, false);
1762 lprmcommand = talloc_sub_advanced(ctx,
1763 lp_servicename(snum),
1764 current_user_info.unix_name,
1766 current_user.ut.gid,
1767 get_current_username(),
1768 current_user_info.domain,
1775 * Make sure that the background queue process exists.
1776 * Otherwise just do the update ourselves
1779 if ( force || background_lpq_updater_pid == -1 ) {
1780 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1781 current_printif = get_printer_fns( snum );
1782 print_queue_update_with_lock(server_event_context(), msg_ctx,
1783 sharename, current_printif,
1784 lpqcommand, lprmcommand);
1789 type = lp_printing(snum);
1791 /* get the length */
1793 len = tdb_pack( NULL, 0, "fdPP",
1799 buffer = SMB_XMALLOC_ARRAY( uint8, len );
1801 /* now pack the buffer */
1802 newlen = tdb_pack( buffer, len, "fdPP",
1808 SMB_ASSERT( newlen == len );
1810 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1811 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1812 sharename, type, lpqcommand, lprmcommand ));
1814 /* here we set a msg pending record for other smbd processes
1815 to throttle the number of duplicate print_queue_update msgs
1818 pdb = get_print_db_byname(sharename);
1824 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1826 if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1827 /* log a message but continue on */
1829 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1833 release_print_db( pdb );
1835 /* finally send the message */
1837 messaging_send_buf(msg_ctx, pid_to_procid(background_lpq_updater_pid),
1838 MSG_PRINTER_UPDATE, (uint8 *)buffer, len);
1840 SAFE_FREE( buffer );
1845 /****************************************************************************
1846 Create/Update an entry in the print tdb that will allow us to send notify
1847 updates only to interested smbd's.
1848 ****************************************************************************/
1850 bool print_notify_register_pid(int snum)
1853 struct tdb_print_db *pdb = NULL;
1854 TDB_CONTEXT *tdb = NULL;
1855 const char *printername;
1856 uint32 mypid = (uint32)sys_getpid();
1860 /* if (snum == -1), then the change notify request was
1861 on a print server handle and we need to register on
1866 int num_services = lp_numservices();
1869 for ( idx=0; idx<num_services; idx++ ) {
1870 if (lp_snum_ok(idx) && lp_print_ok(idx) )
1871 print_notify_register_pid(idx);
1876 else /* register for a specific printer */
1878 printername = lp_const_servicename(snum);
1879 pdb = get_print_db_byname(printername);
1885 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1886 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1889 release_print_db(pdb);
1893 data = get_printer_notify_pid_list( tdb, printername, True );
1895 /* Add ourselves and increase the refcount. */
1897 for (i = 0; i < data.dsize; i += 8) {
1898 if (IVAL(data.dptr,i) == mypid) {
1899 uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1900 SIVAL(data.dptr, i+4, new_refcount);
1905 if (i == data.dsize) {
1906 /* We weren't in the list. Realloc. */
1907 data.dptr = (uint8 *)SMB_REALLOC(data.dptr, data.dsize + 8);
1909 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1914 SIVAL(data.dptr,data.dsize - 8,mypid);
1915 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1918 /* Store back the record. */
1919 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1920 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1921 list for printer %s\n", printername));
1929 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1931 release_print_db(pdb);
1932 SAFE_FREE(data.dptr);
1936 /****************************************************************************
1937 Update an entry in the print tdb that will allow us to send notify
1938 updates only to interested smbd's.
1939 ****************************************************************************/
1941 bool print_notify_deregister_pid(int snum)
1944 struct tdb_print_db *pdb = NULL;
1945 TDB_CONTEXT *tdb = NULL;
1946 const char *printername;
1947 uint32 mypid = (uint32)sys_getpid();
1951 /* if ( snum == -1 ), we are deregister a print server handle
1952 which means to deregister on all print queues */
1956 int num_services = lp_numservices();
1959 for ( idx=0; idx<num_services; idx++ ) {
1960 if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1961 print_notify_deregister_pid(idx);
1966 else /* deregister a specific printer */
1968 printername = lp_const_servicename(snum);
1969 pdb = get_print_db_byname(printername);
1975 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1976 DEBUG(0,("print_notify_register_pid: Failed to lock \
1977 printer %s database\n", printername));
1979 release_print_db(pdb);
1983 data = get_printer_notify_pid_list( tdb, printername, True );
1985 /* Reduce refcount. Remove ourselves if zero. */
1987 for (i = 0; i < data.dsize; ) {
1988 if (IVAL(data.dptr,i) == mypid) {
1989 uint32 refcount = IVAL(data.dptr, i+4);
1993 if (refcount == 0) {
1994 if (data.dsize - i > 8)
1995 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1999 SIVAL(data.dptr, i+4, refcount);
2005 if (data.dsize == 0)
2006 SAFE_FREE(data.dptr);
2008 /* Store back the record. */
2009 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
2010 DEBUG(0,("print_notify_register_pid: Failed to update pid \
2011 list for printer %s\n", printername));
2019 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
2021 release_print_db(pdb);
2022 SAFE_FREE(data.dptr);
2026 /****************************************************************************
2027 Check if a jobid is valid. It is valid if it exists in the database.
2028 ****************************************************************************/
2030 bool print_job_exists(const char* sharename, uint32 jobid)
2032 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2038 ret = tdb_exists(pdb->tdb, print_key(jobid, &tmp));
2039 release_print_db(pdb);
2043 /****************************************************************************
2044 Give the filename used for a jobid.
2045 Only valid for the process doing the spooling and when the job
2046 has not been spooled.
2047 ****************************************************************************/
2049 char *print_job_fname(const char* sharename, uint32 jobid)
2051 struct printjob *pjob = print_job_find(sharename, jobid);
2052 if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
2054 return pjob->filename;
2058 /****************************************************************************
2059 Give the filename used for a jobid.
2060 Only valid for the process doing the spooling and when the job
2061 has not been spooled.
2062 ****************************************************************************/
2064 struct spoolss_DeviceMode *print_job_devmode(const char* sharename, uint32 jobid)
2066 struct printjob *pjob = print_job_find(sharename, jobid);
2071 return pjob->devmode;
2074 /****************************************************************************
2075 Set the name of a job. Only possible for owner.
2076 ****************************************************************************/
2078 bool print_job_set_name(struct tevent_context *ev,
2079 struct messaging_context *msg_ctx,
2080 const char *sharename, uint32 jobid, const char *name)
2082 struct printjob *pjob;
2084 pjob = print_job_find(sharename, jobid);
2085 if (!pjob || pjob->pid != sys_getpid())
2088 fstrcpy(pjob->jobname, name);
2089 return pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2092 /****************************************************************************
2093 Get the name of a job. Only possible for owner.
2094 ****************************************************************************/
2096 bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t jobid, char **name)
2098 struct printjob *pjob;
2100 pjob = print_job_find(sharename, jobid);
2101 if (!pjob || pjob->pid != sys_getpid()) {
2105 *name = talloc_strdup(mem_ctx, pjob->jobname);
2114 /***************************************************************************
2115 Remove a jobid from the 'jobs added' list.
2116 ***************************************************************************/
2118 static bool remove_from_jobs_added(const char* sharename, uint32 jobid)
2120 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2122 size_t job_count, i;
2124 bool gotlock = False;
2132 key = string_tdb_data("INFO/jobs_added");
2134 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
2139 data = tdb_fetch(pdb->tdb, key);
2141 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
2144 job_count = data.dsize / 4;
2145 for (i = 0; i < job_count; i++) {
2148 ch_jobid = IVAL(data.dptr, i*4);
2149 if (ch_jobid == jobid) {
2150 if (i < job_count -1 )
2151 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
2153 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
2163 tdb_chainunlock(pdb->tdb, key);
2164 SAFE_FREE(data.dptr);
2165 release_print_db(pdb);
2167 DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid ));
2169 DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid ));
2173 /****************************************************************************
2174 Delete a print job - don't update queue.
2175 ****************************************************************************/
2177 static bool print_job_delete1(struct tevent_context *ev,
2178 struct messaging_context *msg_ctx,
2179 int snum, uint32 jobid)
2181 const char* sharename = lp_const_servicename(snum);
2182 struct printjob *pjob = print_job_find(sharename, jobid);
2184 struct printif *current_printif = get_printer_fns( snum );
2190 * If already deleting just return.
2193 if (pjob->status == LPQ_DELETING)
2196 /* Hrm - we need to be able to cope with deleting a job before it
2197 has reached the spooler. Just mark it as LPQ_DELETING and
2198 let the print_queue_update() code rmeove the record */
2201 if (pjob->sysjob == -1) {
2202 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
2205 /* Set the tdb entry to be deleting. */
2207 pjob->status = LPQ_DELETING;
2208 pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2210 if (pjob->spooled && pjob->sysjob != -1)
2212 result = (*(current_printif->job_delete))(
2213 lp_printername(snum),
2214 lp_lprmcommand(snum),
2217 /* Delete the tdb entry if the delete succeeded or the job hasn't
2221 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2226 pjob_delete(ev, msg_ctx, sharename, jobid);
2227 /* Ensure we keep a rough count of the number of total jobs... */
2228 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
2229 release_print_db(pdb);
2233 remove_from_jobs_added( sharename, jobid );
2235 return (result == 0);
2238 /****************************************************************************
2239 Return true if the current user owns the print job.
2240 ****************************************************************************/
2242 static bool is_owner(const struct auth_serversupplied_info *server_info,
2243 const char *servicename,
2246 struct printjob *pjob = print_job_find(servicename, jobid);
2248 if (!pjob || !server_info)
2251 return strequal(pjob->user, server_info->sanitized_username);
2254 /****************************************************************************
2256 ****************************************************************************/
2258 WERROR print_job_delete(const struct auth_serversupplied_info *server_info,
2259 struct messaging_context *msg_ctx,
2260 int snum, uint32_t jobid)
2262 const char* sharename = lp_const_servicename(snum);
2263 struct printjob *pjob;
2267 owner = is_owner(server_info, lp_const_servicename(snum), jobid);
2269 /* Check access against security descriptor or whether the user
2273 !print_access_check(server_info, msg_ctx, snum,
2274 JOB_ACCESS_ADMINISTER)) {
2275 DEBUG(3, ("delete denied by security descriptor\n"));
2277 /* BEGIN_ADMIN_LOG */
2278 sys_adminlog( LOG_ERR,
2279 "Permission denied-- user not allowed to delete, \
2280 pause, or resume print job. User name: %s. Printer name: %s.",
2281 uidtoname(server_info->utok.uid),
2282 lp_printername(snum) );
2285 return WERR_ACCESS_DENIED;
2289 * get the spooled filename of the print job
2290 * if this works, then the file has not been spooled
2291 * to the underlying print system. Just delete the
2292 * spool file & return.
2295 fname = print_job_fname(sharename, jobid);
2296 if (fname != NULL) {
2297 /* remove the spool file */
2298 DEBUG(10, ("print_job_delete: "
2299 "Removing spool file [%s]\n", fname));
2300 if (unlink(fname) == -1) {
2301 return map_werror_from_unix(errno);
2305 if (!print_job_delete1(server_event_context(), msg_ctx, snum, jobid)) {
2306 return WERR_ACCESS_DENIED;
2309 /* force update the database and say the delete failed if the
2312 print_queue_update(msg_ctx, snum, True);
2314 pjob = print_job_find(sharename, jobid);
2315 if (pjob && (pjob->status != LPQ_DELETING)) {
2316 return WERR_ACCESS_DENIED;
2319 return WERR_PRINTER_HAS_JOBS_QUEUED;
2322 /****************************************************************************
2324 ****************************************************************************/
2326 bool print_job_pause(const struct auth_serversupplied_info *server_info,
2327 struct messaging_context *msg_ctx,
2328 int snum, uint32 jobid, WERROR *errcode)
2330 const char* sharename = lp_const_servicename(snum);
2331 struct printjob *pjob;
2333 struct printif *current_printif = get_printer_fns( snum );
2335 pjob = print_job_find(sharename, jobid);
2337 if (!pjob || !server_info) {
2338 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2339 (unsigned int)jobid ));
2343 if (!pjob->spooled || pjob->sysjob == -1) {
2344 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2345 (int)pjob->sysjob, (unsigned int)jobid ));
2349 if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2350 !print_access_check(server_info, msg_ctx, snum,
2351 JOB_ACCESS_ADMINISTER)) {
2352 DEBUG(3, ("pause denied by security descriptor\n"));
2354 /* BEGIN_ADMIN_LOG */
2355 sys_adminlog( LOG_ERR,
2356 "Permission denied-- user not allowed to delete, \
2357 pause, or resume print job. User name: %s. Printer name: %s.",
2358 uidtoname(server_info->utok.uid),
2359 lp_printername(snum) );
2362 *errcode = WERR_ACCESS_DENIED;
2366 /* need to pause the spooled entry */
2367 ret = (*(current_printif->job_pause))(snum, pjob);
2370 *errcode = WERR_INVALID_PARAM;
2374 /* force update the database */
2375 print_cache_flush(lp_const_servicename(snum));
2377 /* Send a printer notify message */
2379 notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2382 /* how do we tell if this succeeded? */
2387 /****************************************************************************
2389 ****************************************************************************/
2391 bool print_job_resume(const struct auth_serversupplied_info *server_info,
2392 struct messaging_context *msg_ctx,
2393 int snum, uint32 jobid, WERROR *errcode)
2395 const char *sharename = lp_const_servicename(snum);
2396 struct printjob *pjob;
2398 struct printif *current_printif = get_printer_fns( snum );
2400 pjob = print_job_find(sharename, jobid);
2402 if (!pjob || !server_info) {
2403 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2404 (unsigned int)jobid ));
2408 if (!pjob->spooled || pjob->sysjob == -1) {
2409 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2410 (int)pjob->sysjob, (unsigned int)jobid ));
2414 if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2415 !print_access_check(server_info, msg_ctx, snum,
2416 JOB_ACCESS_ADMINISTER)) {
2417 DEBUG(3, ("resume denied by security descriptor\n"));
2418 *errcode = WERR_ACCESS_DENIED;
2420 /* BEGIN_ADMIN_LOG */
2421 sys_adminlog( LOG_ERR,
2422 "Permission denied-- user not allowed to delete, \
2423 pause, or resume print job. User name: %s. Printer name: %s.",
2424 uidtoname(server_info->utok.uid),
2425 lp_printername(snum) );
2430 ret = (*(current_printif->job_resume))(snum, pjob);
2433 *errcode = WERR_INVALID_PARAM;
2437 /* force update the database */
2438 print_cache_flush(lp_const_servicename(snum));
2440 /* Send a printer notify message */
2442 notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2448 /****************************************************************************
2449 Write to a print file.
2450 ****************************************************************************/
2452 ssize_t print_job_write(struct tevent_context *ev,
2453 struct messaging_context *msg_ctx,
2454 int snum, uint32 jobid, const char *buf, size_t size)
2456 const char* sharename = lp_const_servicename(snum);
2457 ssize_t return_code;
2458 struct printjob *pjob;
2460 pjob = print_job_find(sharename, jobid);
2464 /* don't allow another process to get this info - it is meaningless */
2465 if (pjob->pid != sys_getpid())
2468 /* if SMBD is spooling this can't be allowed */
2469 if (pjob->status == PJOB_SMBD_SPOOLING) {
2473 return_code = write_data(pjob->fd, buf, size);
2475 if (return_code>0) {
2477 pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2482 /****************************************************************************
2483 Get the queue status - do not update if db is out of date.
2484 ****************************************************************************/
2486 static int get_queue_status(const char* sharename, print_status_struct *status)
2490 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2494 ZERO_STRUCTP(status);
2501 fstr_sprintf(keystr, "STATUS/%s", sharename);
2502 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2504 if (data.dsize == sizeof(print_status_struct))
2505 /* this memcpy is ok since the status struct was
2506 not packed before storing it in the tdb */
2507 memcpy(status, data.dptr, sizeof(print_status_struct));
2508 SAFE_FREE(data.dptr);
2511 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2512 release_print_db(pdb);
2513 return (len == -1 ? 0 : len);
2516 /****************************************************************************
2517 Determine the number of jobs in a queue.
2518 ****************************************************************************/
2520 int print_queue_length(struct messaging_context *msg_ctx, int snum,
2521 print_status_struct *pstatus)
2523 const char* sharename = lp_const_servicename( snum );
2524 print_status_struct status;
2527 ZERO_STRUCT( status );
2529 /* make sure the database is up to date */
2530 if (print_cache_expired(lp_const_servicename(snum), True))
2531 print_queue_update(msg_ctx, snum, False);
2533 /* also fetch the queue status */
2534 memset(&status, 0, sizeof(status));
2535 len = get_queue_status(sharename, &status);
2543 /***************************************************************************
2544 Allocate a jobid. Hold the lock for as short a time as possible.
2545 ***************************************************************************/
2547 static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum,
2548 const char *sharename, uint32 *pjobid)
2552 enum TDB_ERROR terr;
2555 *pjobid = (uint32)-1;
2557 for (i = 0; i < 3; i++) {
2558 /* Lock the database - only wait 20 seconds. */
2559 ret = tdb_lock_bystring_with_timeout(pdb->tdb,
2560 "INFO/nextjob", 20);
2562 DEBUG(0, ("allocate_print_jobid: "
2563 "Failed to lock printing database %s\n",
2565 terr = tdb_error(pdb->tdb);
2566 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2569 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2570 terr = tdb_error(pdb->tdb);
2571 if (terr != TDB_ERR_NOEXIST) {
2572 DEBUG(0, ("allocate_print_jobid: "
2573 "Failed to fetch INFO/nextjob "
2574 "for print queue %s\n", sharename));
2575 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2576 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2578 DEBUG(10, ("allocate_print_jobid: "
2579 "No existing jobid in %s\n", sharename));
2583 DEBUG(10, ("allocate_print_jobid: "
2584 "Read jobid %u from %s\n", jobid, sharename));
2586 jobid = NEXT_JOBID(jobid);
2588 ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid);
2590 terr = tdb_error(pdb->tdb);
2591 DEBUG(3, ("allocate_print_jobid: "
2592 "Failed to store INFO/nextjob.\n"));
2593 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2594 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2597 /* We've finished with the INFO/nextjob lock. */
2598 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2600 if (!print_job_exists(sharename, jobid)) {
2603 DEBUG(10, ("allocate_print_jobid: "
2604 "Found jobid %u in %s\n", jobid, sharename));
2608 DEBUG(0, ("allocate_print_jobid: "
2609 "Failed to allocate a print job for queue %s\n",
2611 /* Probably full... */
2612 return WERR_NO_SPOOL_SPACE;
2615 /* Store a dummy placeholder. */
2621 if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
2622 TDB_INSERT) == -1) {
2623 DEBUG(3, ("allocate_print_jobid: "
2624 "jobid (%d) failed to store placeholder.\n",
2626 terr = tdb_error(pdb->tdb);
2627 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2635 /***************************************************************************
2636 Append a jobid to the 'jobs added' list.
2637 ***************************************************************************/
2639 static bool add_to_jobs_added(struct tdb_print_db *pdb, uint32 jobid)
2644 SIVAL(&store_jobid, 0, jobid);
2645 data.dptr = (uint8 *)&store_jobid;
2648 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid ));
2650 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_added"),
2655 /***************************************************************************
2656 Do all checks needed to determine if we can start a job.
2657 ***************************************************************************/
2659 static WERROR print_job_checks(const struct auth_serversupplied_info *server_info,
2660 struct messaging_context *msg_ctx,
2661 int snum, int *njobs)
2663 const char *sharename = lp_const_servicename(snum);
2664 uint64_t dspace, dsize;
2668 if (!print_access_check(server_info, msg_ctx, snum,
2669 PRINTER_ACCESS_USE)) {
2670 DEBUG(3, ("print_job_checks: "
2671 "job start denied by security descriptor\n"));
2672 return WERR_ACCESS_DENIED;
2675 if (!print_time_access_check(server_info, msg_ctx, sharename)) {
2676 DEBUG(3, ("print_job_checks: "
2677 "job start denied by time check\n"));
2678 return WERR_ACCESS_DENIED;
2681 /* see if we have sufficient disk space */
2682 if (lp_minprintspace(snum)) {
2683 minspace = lp_minprintspace(snum);
2684 ret = sys_fsusage(lp_pathname(snum), &dspace, &dsize);
2685 if (ret == 0 && dspace < 2*minspace) {
2686 DEBUG(3, ("print_job_checks: "
2687 "disk space check failed.\n"));
2688 return WERR_NO_SPOOL_SPACE;
2692 /* for autoloaded printers, check that the printcap entry still exists */
2693 if (lp_autoloaded(snum) && !pcap_printername_ok(sharename)) {
2694 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2696 return WERR_ACCESS_DENIED;
2699 /* Insure the maximum queue size is not violated */
2700 *njobs = print_queue_length(msg_ctx, snum, NULL);
2701 if (*njobs > lp_maxprintjobs(snum)) {
2702 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2703 "larger than max printjobs per queue (%d).\n",
2704 sharename, *njobs, lp_maxprintjobs(snum)));
2705 return WERR_NO_SPOOL_SPACE;
2711 /***************************************************************************
2713 ***************************************************************************/
2715 static WERROR print_job_spool_file(int snum, uint32_t jobid,
2716 const char *output_file,
2717 struct printjob *pjob)
2724 /* if this file is within the printer path, it means that smbd
2725 * is spooling it and will pass us control when it is finished.
2726 * Verify that the file name is ok, within path, and it is
2727 * already already there */
2729 path = lp_pathname(snum);
2731 if (strncmp(output_file, path, len) == 0 &&
2732 (output_file[len - 1] == '/' || output_file[len] == '/')) {
2734 /* verify path is not too long */
2735 if (strlen(output_file) >= sizeof(pjob->filename)) {
2736 return WERR_INVALID_NAME;
2739 /* verify that the file exists */
2740 if (sys_stat(output_file, &st, false) != 0) {
2741 return WERR_INVALID_NAME;
2744 fstrcpy(pjob->filename, output_file);
2746 DEBUG(3, ("print_job_spool_file:"
2747 "External spooling activated"));
2749 /* we do not open the file until spooling is done */
2751 pjob->status = PJOB_SMBD_SPOOLING;
2757 slprintf(pjob->filename, sizeof(pjob->filename)-1,
2758 "%s/%s%.8u.XXXXXX", lp_pathname(snum),
2759 PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2760 pjob->fd = mkstemp(pjob->filename);
2762 if (pjob->fd == -1) {
2763 werr = map_werror_from_unix(errno);
2764 if (W_ERROR_EQUAL(werr, WERR_ACCESS_DENIED)) {
2765 /* Common setup error, force a report. */
2766 DEBUG(0, ("print_job_spool_file: "
2767 "insufficient permissions to open spool "
2768 "file %s.\n", pjob->filename));
2770 /* Normal case, report at level 3 and above. */
2771 DEBUG(3, ("print_job_spool_file: "
2772 "can't open spool file %s\n",
2781 /***************************************************************************
2782 Start spooling a job - return the jobid.
2783 ***************************************************************************/
2785 WERROR print_job_start(const struct auth_serversupplied_info *server_info,
2786 struct messaging_context *msg_ctx,
2787 const char *clientmachine,
2788 int snum, const char *docname, const char *filename,
2789 struct spoolss_DeviceMode *devmode, uint32_t *_jobid)
2793 struct printjob pjob;
2794 const char *sharename = lp_const_servicename(snum);
2795 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2800 return WERR_INTERNAL_DB_CORRUPTION;
2803 path = lp_pathname(snum);
2805 werr = print_job_checks(server_info, msg_ctx, snum, &njobs);
2806 if (!W_ERROR_IS_OK(werr)) {
2807 release_print_db(pdb);
2811 DEBUG(10, ("print_job_start: "
2812 "Queue %s number of jobs (%d), max printjobs = %d\n",
2813 sharename, njobs, lp_maxprintjobs(snum)));
2815 werr = allocate_print_jobid(pdb, snum, sharename, &jobid);
2816 if (!W_ERROR_IS_OK(werr)) {
2820 /* create the database entry */
2824 pjob.pid = sys_getpid();
2827 pjob.starttime = time(NULL);
2828 pjob.status = LPQ_SPOOLING;
2830 pjob.spooled = False;
2832 pjob.devmode = devmode;
2834 fstrcpy(pjob.jobname, docname);
2836 fstrcpy(pjob.clientmachine, clientmachine);
2838 fstrcpy(pjob.user, lp_printjob_username(snum));
2839 standard_sub_advanced(sharename, server_info->sanitized_username,
2840 path, server_info->utok.gid,
2841 server_info->sanitized_username,
2842 server_info->info3->base.domain.string,
2843 pjob.user, sizeof(pjob.user)-1);
2844 /* ensure NULL termination */
2845 pjob.user[sizeof(pjob.user)-1] = '\0';
2847 fstrcpy(pjob.queuename, lp_const_servicename(snum));
2849 /* we have a job entry - now create the spool file */
2850 werr = print_job_spool_file(snum, jobid, filename, &pjob);
2851 if (!W_ERROR_IS_OK(werr)) {
2855 pjob_store(server_event_context(), msg_ctx, sharename, jobid, &pjob);
2857 /* Update the 'jobs added' entry used by print_queue_status. */
2858 add_to_jobs_added(pdb, jobid);
2860 /* Ensure we keep a rough count of the number of total jobs... */
2861 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2863 release_print_db(pdb);
2870 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
2873 release_print_db(pdb);
2875 DEBUG(3, ("print_job_start: returning fail. "
2876 "Error = %s\n", win_errstr(werr)));
2880 /****************************************************************************
2881 Update the number of pages spooled to jobid
2882 ****************************************************************************/
2884 void print_job_endpage(struct messaging_context *msg_ctx,
2885 int snum, uint32 jobid)
2887 const char* sharename = lp_const_servicename(snum);
2888 struct printjob *pjob;
2890 pjob = print_job_find(sharename, jobid);
2893 /* don't allow another process to get this info - it is meaningless */
2894 if (pjob->pid != sys_getpid())
2898 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
2901 /****************************************************************************
2902 Print a file - called on closing the file. This spools the job.
2903 If normal close is false then we're tearing down the jobs - treat as an
2905 ****************************************************************************/
2907 NTSTATUS print_job_end(struct messaging_context *msg_ctx, int snum,
2908 uint32 jobid, enum file_close_type close_type)
2910 const char* sharename = lp_const_servicename(snum);
2911 struct printjob *pjob;
2913 SMB_STRUCT_STAT sbuf;
2914 struct printif *current_printif = get_printer_fns( snum );
2915 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2917 pjob = print_job_find(sharename, jobid);
2920 return NT_STATUS_PRINT_CANCELLED;
2923 if (pjob->spooled || pjob->pid != sys_getpid()) {
2924 return NT_STATUS_ACCESS_DENIED;
2927 if (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) {
2928 if (pjob->status == PJOB_SMBD_SPOOLING) {
2929 /* take over the file now, smbd is done */
2930 if (sys_stat(pjob->filename, &sbuf, false) != 0) {
2931 status = map_nt_error_from_unix(errno);
2932 DEBUG(3, ("print_job_end: "
2933 "stat file failed for jobid %d\n",
2938 pjob->status = LPQ_SPOOLING;
2942 if ((sys_fstat(pjob->fd, &sbuf, false) != 0)) {
2943 status = map_nt_error_from_unix(errno);
2945 DEBUG(3, ("print_job_end: "
2946 "stat file failed for jobid %d\n",
2954 pjob->size = sbuf.st_ex_size;
2958 * Not a normal close, something has gone wrong. Cleanup.
2960 if (pjob->fd != -1) {
2966 /* Technically, this is not quite right. If the printer has a separator
2967 * page turned on, the NT spooler prints the separator page even if the
2968 * print job is 0 bytes. 010215 JRR */
2969 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2970 /* don't bother spooling empty files or something being deleted. */
2971 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2972 pjob->filename, pjob->size ? "deleted" : "zero length" ));
2973 unlink(pjob->filename);
2974 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
2975 return NT_STATUS_OK;
2978 ret = (*(current_printif->job_submit))(snum, pjob);
2981 status = NT_STATUS_PRINT_CANCELLED;
2985 /* The print job has been successfully handed over to the back-end */
2987 pjob->spooled = True;
2988 pjob->status = LPQ_QUEUED;
2989 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
2991 /* make sure the database is up to date */
2992 if (print_cache_expired(lp_const_servicename(snum), True))
2993 print_queue_update(msg_ctx, snum, False);
2995 return NT_STATUS_OK;
2999 /* The print job was not successfully started. Cleanup */
3000 /* Still need to add proper error return propagation! 010122:JRR */
3002 unlink(pjob->filename);
3003 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
3007 /****************************************************************************
3008 Get a snapshot of jobs in the system without traversing.
3009 ****************************************************************************/
3011 static bool get_stored_queue_info(struct messaging_context *msg_ctx,
3012 struct tdb_print_db *pdb, int snum,
3013 int *pcount, print_queue_struct **ppqueue)
3015 TDB_DATA data, cgdata, jcdata;
3016 print_queue_struct *queue = NULL;
3018 uint32 extra_count = 0;
3019 uint32_t changed_count = 0;
3020 int total_count = 0;
3023 int max_reported_jobs = lp_max_reported_jobs(snum);
3025 const char* sharename = lp_servicename(snum);
3027 /* make sure the database is up to date */
3028 if (print_cache_expired(lp_const_servicename(snum), True))
3029 print_queue_update(msg_ctx, snum, False);
3035 ZERO_STRUCT(cgdata);
3037 /* Get the stored queue data. */
3038 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
3040 if (data.dptr && data.dsize >= sizeof(qcount))
3041 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
3043 /* Get the added jobs list. */
3044 cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added"));
3045 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
3046 extra_count = cgdata.dsize/4;
3048 /* Get the changed jobs list. */
3049 jcdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
3050 if (jcdata.dptr != NULL && (jcdata.dsize % 4 == 0))
3051 changed_count = jcdata.dsize / 4;
3053 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
3055 /* Allocate the queue size. */
3056 if (qcount == 0 && extra_count == 0)
3059 if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
3062 /* Retrieve the linearised queue data. */
3064 for( i = 0; i < qcount; i++) {
3065 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
3066 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
3075 queue[i].job = qjob;
3076 queue[i].size = qsize;
3077 queue[i].page_count = qpage_count;
3078 queue[i].status = qstatus;
3079 queue[i].priority = qpriority;
3080 queue[i].time = qtime;
3083 total_count = qcount;
3085 /* Add new jobids to the queue. */
3086 for( i = 0; i < extra_count; i++) {
3088 struct printjob *pjob;
3090 jobid = IVAL(cgdata.dptr, i*4);
3091 DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid));
3092 pjob = print_job_find(lp_const_servicename(snum), jobid);
3094 DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid));
3095 remove_from_jobs_added(sharename, jobid);
3099 queue[total_count].job = jobid;
3100 queue[total_count].size = pjob->size;
3101 queue[total_count].page_count = pjob->page_count;
3102 queue[total_count].status = pjob->status;
3103 queue[total_count].priority = 1;
3104 queue[total_count].time = pjob->starttime;
3105 fstrcpy(queue[total_count].fs_user, pjob->user);
3106 fstrcpy(queue[total_count].fs_file, pjob->jobname);
3110 /* Update the changed jobids. */
3111 for (i = 0; i < changed_count; i++) {
3112 uint32_t jobid = IVAL(jcdata.dptr, i * 4);
3116 for (j = 0; j < total_count; j++) {
3117 if (queue[j].job == jobid) {
3124 struct printjob *pjob;
3126 DEBUG(5,("get_stored_queue_info: changed job: %u\n",
3127 (unsigned int) jobid));
3129 pjob = print_job_find(sharename, jobid);
3131 DEBUG(5,("get_stored_queue_info: failed to find "
3132 "changed job = %u\n",
3133 (unsigned int) jobid));
3134 remove_from_jobs_changed(sharename, jobid);
3138 queue[j].job = jobid;
3139 queue[j].size = pjob->size;
3140 queue[j].page_count = pjob->page_count;
3141 queue[j].status = pjob->status;
3142 queue[j].priority = 1;
3143 queue[j].time = pjob->starttime;
3144 fstrcpy(queue[j].fs_user, pjob->user);
3145 fstrcpy(queue[j].fs_file, pjob->jobname);
3147 DEBUG(5,("get_stored_queue_info: updated queue[%u], jobid: %u, jobname: %s\n",
3148 (unsigned int) j, (unsigned int) jobid, pjob->jobname));
3151 remove_from_jobs_changed(sharename, jobid);
3154 /* Sort the queue by submission time otherwise they are displayed
3157 TYPESAFE_QSORT(queue, total_count, printjob_comp);
3159 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
3161 if (max_reported_jobs && total_count > max_reported_jobs)
3162 total_count = max_reported_jobs;
3165 *pcount = total_count;
3171 SAFE_FREE(data.dptr);
3172 SAFE_FREE(cgdata.dptr);
3176 /****************************************************************************
3177 Get a printer queue listing.
3178 set queue = NULL and status = NULL if you just want to update the cache
3179 ****************************************************************************/
3181 int print_queue_status(struct messaging_context *msg_ctx, int snum,
3182 print_queue_struct **ppqueue,
3183 print_status_struct *status)
3187 const char *sharename;
3188 struct tdb_print_db *pdb;
3191 /* make sure the database is up to date */
3193 if (print_cache_expired(lp_const_servicename(snum), True))
3194 print_queue_update(msg_ctx, snum, False);
3196 /* return if we are done */
3197 if ( !ppqueue || !status )
3201 sharename = lp_const_servicename(snum);
3202 pdb = get_print_db_byname(sharename);
3208 * Fetch the queue status. We must do this first, as there may
3209 * be no jobs in the queue.
3212 ZERO_STRUCTP(status);
3213 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
3214 key = string_tdb_data(keystr);
3216 data = tdb_fetch(pdb->tdb, key);
3218 if (data.dsize == sizeof(*status)) {
3219 /* this memcpy is ok since the status struct was
3220 not packed before storing it in the tdb */
3221 memcpy(status, data.dptr, sizeof(*status));
3223 SAFE_FREE(data.dptr);
3227 * Now, fetch the print queue information. We first count the number
3228 * of entries, and then only retrieve the queue if necessary.
3231 if (!get_stored_queue_info(msg_ctx, pdb, snum, &count, ppqueue)) {
3232 release_print_db(pdb);
3236 release_print_db(pdb);
3240 /****************************************************************************
3242 ****************************************************************************/
3244 WERROR print_queue_pause(const struct auth_serversupplied_info *server_info,
3245 struct messaging_context *msg_ctx, int snum)
3248 struct printif *current_printif = get_printer_fns( snum );
3250 if (!print_access_check(server_info, msg_ctx, snum,
3251 PRINTER_ACCESS_ADMINISTER)) {
3252 return WERR_ACCESS_DENIED;
3258 ret = (*(current_printif->queue_pause))(snum);
3263 return WERR_INVALID_PARAM;
3266 /* force update the database */
3267 print_cache_flush(lp_const_servicename(snum));
3269 /* Send a printer notify message */
3271 notify_printer_status(server_event_context(), msg_ctx, snum,
3272 PRINTER_STATUS_PAUSED);
3277 /****************************************************************************
3279 ****************************************************************************/
3281 WERROR print_queue_resume(const struct auth_serversupplied_info *server_info,
3282 struct messaging_context *msg_ctx, int snum)
3285 struct printif *current_printif = get_printer_fns( snum );
3287 if (!print_access_check(server_info, msg_ctx, snum,
3288 PRINTER_ACCESS_ADMINISTER)) {
3289 return WERR_ACCESS_DENIED;
3294 ret = (*(current_printif->queue_resume))(snum);
3299 return WERR_INVALID_PARAM;
3302 /* make sure the database is up to date */
3303 if (print_cache_expired(lp_const_servicename(snum), True))
3304 print_queue_update(msg_ctx, snum, True);
3306 /* Send a printer notify message */
3308 notify_printer_status(server_event_context(), msg_ctx, snum,
3314 /****************************************************************************
3315 Purge a queue - implemented by deleting all jobs that we can delete.
3316 ****************************************************************************/
3318 WERROR print_queue_purge(const struct auth_serversupplied_info *server_info,
3319 struct messaging_context *msg_ctx, int snum)
3321 print_queue_struct *queue;
3322 print_status_struct status;
3326 /* Force and update so the count is accurate (i.e. not a cached count) */
3327 print_queue_update(msg_ctx, snum, True);
3329 can_job_admin = print_access_check(server_info,
3332 JOB_ACCESS_ADMINISTER);
3333 njobs = print_queue_status(msg_ctx, snum, &queue, &status);
3335 if ( can_job_admin )
3338 for (i=0;i<njobs;i++) {
3339 bool owner = is_owner(server_info, lp_const_servicename(snum),
3342 if (owner || can_job_admin) {
3343 print_job_delete1(server_event_context(), msg_ctx,
3344 snum, queue[i].job);
3348 if ( can_job_admin )
3351 /* update the cache */
3352 print_queue_update(msg_ctx, snum, True);