2 Unix SMB/Netbios implementation.
4 printing backend routines
5 Copyright (C) Andrew Tridgell 1992-2000
6 Copyright (C) Jeremy Allison 2002
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "system/syslog.h"
24 #include "system/filesys.h"
26 #include "../librpc/gen_ndr/ndr_spoolss.h"
27 #include "nt_printing.h"
28 #include "../librpc/gen_ndr/netlogon.h"
29 #include "printing/notify.h"
30 #include "printing/pcap.h"
31 #include "printing/printer_list.h"
32 #include "printing/queue_process.h"
34 #include "smbd/smbd.h"
38 #include "lib/param/loadparm.h"
40 extern struct current_user current_user
;
41 extern userdom_struct current_user_info
;
43 /* Current printer interface */
44 static bool remove_from_jobs_added(const char* sharename
, uint32 jobid
);
47 the printing backend revolves around a tdb database that stores the
48 SMB view of the print queue
50 The key for this database is a jobid - a internally generated number that
51 uniquely identifies a print job
53 reading the print queue involves two steps:
54 - possibly running lpq and updating the internal database from that
55 - reading entries from the database
57 jobids are assigned when a job starts spooling.
60 static TDB_CONTEXT
*rap_tdb
;
61 static uint16 next_rap_jobid
;
62 struct rap_jobid_key
{
67 /***************************************************************************
68 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
69 bit RPC jobids.... JRA.
70 ***************************************************************************/
72 uint16
pjobid_to_rap(const char* sharename
, uint32 jobid
)
76 struct rap_jobid_key jinfo
;
79 DEBUG(10,("pjobid_to_rap: called.\n"));
82 /* Create the in-memory tdb. */
83 rap_tdb
= tdb_open_log(NULL
, 0, TDB_INTERNAL
, (O_RDWR
|O_CREAT
), 0644);
89 fstrcpy( jinfo
.sharename
, sharename
);
91 key
.dptr
= (uint8
*)&jinfo
;
92 key
.dsize
= sizeof(jinfo
);
94 data
= tdb_fetch_compat(rap_tdb
, key
);
95 if (data
.dptr
&& data
.dsize
== sizeof(uint16
)) {
96 rap_jobid
= SVAL(data
.dptr
, 0);
98 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
99 (unsigned int)jobid
, (unsigned int)rap_jobid
));
102 SAFE_FREE(data
.dptr
);
103 /* Not found - create and store mapping. */
104 rap_jobid
= ++next_rap_jobid
;
106 rap_jobid
= ++next_rap_jobid
;
107 SSVAL(buf
,0,rap_jobid
);
109 data
.dsize
= sizeof(rap_jobid
);
110 tdb_store(rap_tdb
, key
, data
, TDB_REPLACE
);
111 tdb_store(rap_tdb
, data
, key
, TDB_REPLACE
);
113 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
114 (unsigned int)jobid
, (unsigned int)rap_jobid
));
118 bool rap_to_pjobid(uint16 rap_jobid
, fstring sharename
, uint32
*pjobid
)
123 DEBUG(10,("rap_to_pjobid called.\n"));
128 SSVAL(buf
,0,rap_jobid
);
130 key
.dsize
= sizeof(rap_jobid
);
131 data
= tdb_fetch_compat(rap_tdb
, key
);
132 if ( data
.dptr
&& data
.dsize
== sizeof(struct rap_jobid_key
) )
134 struct rap_jobid_key
*jinfo
= (struct rap_jobid_key
*)data
.dptr
;
135 if (sharename
!= NULL
) {
136 fstrcpy( sharename
, jinfo
->sharename
);
138 *pjobid
= jinfo
->jobid
;
139 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
140 (unsigned int)*pjobid
, (unsigned int)rap_jobid
));
141 SAFE_FREE(data
.dptr
);
145 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
146 (unsigned int)rap_jobid
));
147 SAFE_FREE(data
.dptr
);
151 void rap_jobid_delete(const char* sharename
, uint32 jobid
)
155 struct rap_jobid_key jinfo
;
158 DEBUG(10,("rap_jobid_delete: called.\n"));
163 ZERO_STRUCT( jinfo
);
164 fstrcpy( jinfo
.sharename
, sharename
);
166 key
.dptr
= (uint8
*)&jinfo
;
167 key
.dsize
= sizeof(jinfo
);
169 data
= tdb_fetch_compat(rap_tdb
, key
);
170 if (!data
.dptr
|| (data
.dsize
!= sizeof(uint16
))) {
171 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
172 (unsigned int)jobid
));
173 SAFE_FREE(data
.dptr
);
177 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
178 (unsigned int)jobid
));
180 rap_jobid
= SVAL(data
.dptr
, 0);
181 SAFE_FREE(data
.dptr
);
182 SSVAL(buf
,0,rap_jobid
);
184 data
.dsize
= sizeof(rap_jobid
);
185 tdb_delete(rap_tdb
, key
);
186 tdb_delete(rap_tdb
, data
);
189 static int get_queue_status(const char* sharename
, print_status_struct
*);
191 /****************************************************************************
192 Initialise the printing backend. Called once at startup before the fork().
193 ****************************************************************************/
195 bool print_backend_init(struct messaging_context
*msg_ctx
)
197 const char *sversion
= "INFO/version";
198 int services
= lp_numservices();
201 if (!printer_list_parent_init()) {
205 unlink(cache_path("printing.tdb"));
206 mkdir(cache_path("printing"),0755);
208 /* handle a Samba upgrade */
210 for (snum
= 0; snum
< services
; snum
++) {
211 struct tdb_print_db
*pdb
;
212 if (!lp_print_ok(snum
))
215 pdb
= get_print_db_byname(lp_const_servicename(snum
));
218 if (tdb_lock_bystring(pdb
->tdb
, sversion
) != 0) {
219 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum
) ));
220 release_print_db(pdb
);
223 if (tdb_fetch_int32(pdb
->tdb
, sversion
) != PRINT_DATABASE_VERSION
) {
224 tdb_wipe_all(pdb
->tdb
);
225 tdb_store_int32(pdb
->tdb
, sversion
, PRINT_DATABASE_VERSION
);
227 tdb_unlock_bystring(pdb
->tdb
, sversion
);
228 release_print_db(pdb
);
231 close_all_print_db(); /* Don't leave any open. */
233 /* do NT print initialization... */
234 return nt_printing_init(msg_ctx
);
237 /****************************************************************************
238 Shut down printing backend. Called once at shutdown to close the tdb.
239 ****************************************************************************/
241 void printing_end(void)
243 close_all_print_db(); /* Don't leave any open. */
246 /****************************************************************************
247 Retrieve the set of printing functions for a given service. This allows
248 us to set the printer function table based on the value of the 'printing'
251 Use the generic interface as the default and only use cups interface only
252 when asked for (and only when supported)
253 ****************************************************************************/
255 static struct printif
*get_printer_fns_from_type( enum printing_types type
)
257 struct printif
*printer_fns
= &generic_printif
;
260 if ( type
== PRINT_CUPS
) {
261 printer_fns
= &cups_printif
;
263 #endif /* HAVE_CUPS */
266 if ( type
== PRINT_IPRINT
) {
267 printer_fns
= &iprint_printif
;
269 #endif /* HAVE_IPRINT */
271 printer_fns
->type
= type
;
276 static struct printif
*get_printer_fns( int snum
)
278 return get_printer_fns_from_type( (enum printing_types
)lp_printing(snum
) );
282 /****************************************************************************
283 Useful function to generate a tdb key.
284 ****************************************************************************/
286 static TDB_DATA
print_key(uint32 jobid
, uint32
*tmp
)
290 SIVAL(tmp
, 0, jobid
);
291 ret
.dptr
= (uint8
*)tmp
;
292 ret
.dsize
= sizeof(*tmp
);
296 /****************************************************************************
297 Pack the devicemode to store it in a tdb.
298 ****************************************************************************/
299 static int pack_devicemode(struct spoolss_DeviceMode
*devmode
, uint8
*buf
, int buflen
)
301 enum ndr_err_code ndr_err
;
306 ndr_err
= ndr_push_struct_blob(&blob
, talloc_tos(),
308 (ndr_push_flags_fn_t
)
309 ndr_push_spoolss_DeviceMode
);
310 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
311 DEBUG(10, ("pack_devicemode: "
312 "error encoding spoolss_DeviceMode\n"));
319 len
= tdb_pack(buf
, buflen
, "B", blob
.length
, blob
.data
);
322 DEBUG(8, ("Packed devicemode [%s]\n", devmode
->formname
));
329 /****************************************************************************
330 Unpack the devicemode to store it in a tdb.
331 ****************************************************************************/
332 static int unpack_devicemode(TALLOC_CTX
*mem_ctx
,
333 const uint8
*buf
, int buflen
,
334 struct spoolss_DeviceMode
**devmode
)
336 struct spoolss_DeviceMode
*dm
;
337 enum ndr_err_code ndr_err
;
345 len
= tdb_unpack(buf
, buflen
, "B", &data_len
, &data
);
350 dm
= talloc_zero(mem_ctx
, struct spoolss_DeviceMode
);
355 blob
= data_blob_const(data
, data_len
);
357 ndr_err
= ndr_pull_struct_blob(&blob
, dm
, dm
,
358 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_DeviceMode
);
359 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
360 DEBUG(10, ("unpack_devicemode: "
361 "error parsing spoolss_DeviceMode\n"));
365 DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
366 dm
->devicename
, dm
->formname
));
367 if (dm
->driverextra_data
.data
) {
368 DEBUG(8, ("with a private section of %d bytes\n",
369 dm
->__driverextra_length
));
379 /***********************************************************************
380 unpack a pjob from a tdb buffer
381 ***********************************************************************/
383 static int unpack_pjob(TALLOC_CTX
*mem_ctx
, uint8
*buf
, int buflen
,
384 struct printjob
*pjob
)
388 uint32 pjpid
, pjjobid
, pjsysjob
, pjfd
, pjstarttime
, pjstatus
;
389 uint32 pjsize
, pjpage_count
, pjspooled
, pjsmbjob
;
395 len
+= tdb_unpack(buf
+len
, buflen
-len
, "ddddddddddfffff",
416 used
= unpack_devicemode(mem_ctx
, buf
+len
, buflen
-len
, &pjob
->devmode
);
424 pjob
->jobid
= pjjobid
;
425 pjob
->sysjob
= pjsysjob
;
427 pjob
->starttime
= pjstarttime
;
428 pjob
->status
= pjstatus
;
430 pjob
->page_count
= pjpage_count
;
431 pjob
->spooled
= pjspooled
;
432 pjob
->smbjob
= pjsmbjob
;
438 /****************************************************************************
439 Useful function to find a print job in the database.
440 ****************************************************************************/
442 static struct printjob
*print_job_find(TALLOC_CTX
*mem_ctx
,
443 const char *sharename
,
446 struct printjob
*pjob
;
449 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
451 DEBUG(10,("print_job_find: looking up job %u for share %s\n",
452 (unsigned int)jobid
, sharename
));
458 ret
= tdb_fetch_compat(pdb
->tdb
, print_key(jobid
, &tmp
));
459 release_print_db(pdb
);
462 DEBUG(10, ("print_job_find: failed to find jobid %u.\n",
467 pjob
= talloc_zero(mem_ctx
, struct printjob
);
472 if (unpack_pjob(mem_ctx
, ret
.dptr
, ret
.dsize
, pjob
) == -1) {
473 DEBUG(10, ("failed to unpack jobid %u.\n", jobid
));
479 DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
480 pjob
->sysjob
, jobid
));
481 SMB_ASSERT(pjob
->jobid
== jobid
);
488 struct job_traverse_state
{
493 /* find spoolss jobid based on sysjob */
494 static int sysjob_to_jobid_traverse_fn(TDB_CONTEXT
*the_tdb
, TDB_DATA key
,
495 TDB_DATA data
, void *private_data
)
497 struct printjob
*pjob
;
498 struct job_traverse_state
*state
=
499 (struct job_traverse_state
*)private_data
;
501 if (!data
.dptr
|| data
.dsize
== 0)
504 pjob
= (struct printjob
*)data
.dptr
;
505 if (key
.dsize
!= sizeof(uint32
))
508 if (state
->sysjob
== pjob
->sysjob
) {
509 state
->jobid
= pjob
->jobid
;
516 uint32
sysjob_to_jobid_pdb(struct tdb_print_db
*pdb
, int sysjob
)
518 struct job_traverse_state state
;
520 state
.sysjob
= sysjob
;
521 state
.jobid
= (uint32_t)-1;
523 tdb_traverse(pdb
->tdb
, sysjob_to_jobid_traverse_fn
, &state
);
528 /****************************************************************************
529 This is a *horribly expensive call as we have to iterate through all the
530 current printer tdb's. Don't do this often ! JRA.
531 ****************************************************************************/
533 uint32
sysjob_to_jobid(int unix_jobid
)
535 int services
= lp_numservices();
537 struct job_traverse_state state
;
539 state
.sysjob
= unix_jobid
;
540 state
.jobid
= (uint32_t)-1;
542 for (snum
= 0; snum
< services
; snum
++) {
543 struct tdb_print_db
*pdb
;
544 if (!lp_print_ok(snum
))
546 pdb
= get_print_db_byname(lp_const_servicename(snum
));
550 tdb_traverse(pdb
->tdb
, sysjob_to_jobid_traverse_fn
, &state
);
551 release_print_db(pdb
);
552 if (state
.jobid
!= (uint32_t)-1)
558 /* find sysjob based on spoolss jobid */
559 static int jobid_to_sysjob_traverse_fn(TDB_CONTEXT
*the_tdb
, TDB_DATA key
,
560 TDB_DATA data
, void *private_data
)
562 struct printjob
*pjob
;
563 struct job_traverse_state
*state
=
564 (struct job_traverse_state
*)private_data
;
566 if (!data
.dptr
|| data
.dsize
== 0)
569 pjob
= (struct printjob
*)data
.dptr
;
570 if (key
.dsize
!= sizeof(uint32_t))
573 if (state
->jobid
== pjob
->jobid
) {
574 state
->sysjob
= pjob
->sysjob
;
581 int jobid_to_sysjob_pdb(struct tdb_print_db
*pdb
, uint32_t jobid
)
583 struct job_traverse_state state
;
588 tdb_traverse(pdb
->tdb
, jobid_to_sysjob_traverse_fn
, &state
);
593 /****************************************************************************
594 Send notifications based on what has changed after a pjob_store.
595 ****************************************************************************/
597 static const struct {
599 uint32_t spoolss_status
;
600 } lpq_to_spoolss_status_map
[] = {
601 { LPQ_QUEUED
, JOB_STATUS_QUEUED
},
602 { LPQ_PAUSED
, JOB_STATUS_PAUSED
},
603 { LPQ_SPOOLING
, JOB_STATUS_SPOOLING
},
604 { LPQ_PRINTING
, JOB_STATUS_PRINTING
},
605 { LPQ_DELETING
, JOB_STATUS_DELETING
},
606 { LPQ_OFFLINE
, JOB_STATUS_OFFLINE
},
607 { LPQ_PAPEROUT
, JOB_STATUS_PAPEROUT
},
608 { LPQ_PRINTED
, JOB_STATUS_PRINTED
},
609 { LPQ_DELETED
, JOB_STATUS_DELETED
},
610 { LPQ_BLOCKED
, JOB_STATUS_BLOCKED_DEVQ
},
611 { LPQ_USER_INTERVENTION
, JOB_STATUS_USER_INTERVENTION
},
615 /* Convert a lpq status value stored in printing.tdb into the
616 appropriate win32 API constant. */
618 static uint32
map_to_spoolss_status(uint32 lpq_status
)
622 while (lpq_to_spoolss_status_map
[i
].lpq_status
!= -1) {
623 if (lpq_to_spoolss_status_map
[i
].lpq_status
== lpq_status
)
624 return lpq_to_spoolss_status_map
[i
].spoolss_status
;
631 /***************************************************************************
632 Append a jobid to the 'jobs changed' list.
633 ***************************************************************************/
635 static bool add_to_jobs_changed(struct tdb_print_db
*pdb
, uint32_t jobid
)
638 uint32_t store_jobid
;
640 SIVAL(&store_jobid
, 0, jobid
);
641 data
.dptr
= (uint8
*) &store_jobid
;
644 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid
));
646 return (tdb_append(pdb
->tdb
, string_tdb_data("INFO/jobs_changed"),
650 /***************************************************************************
651 Remove a jobid from the 'jobs changed' list.
652 ***************************************************************************/
654 static bool remove_from_jobs_changed(const char* sharename
, uint32_t jobid
)
656 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
660 bool gotlock
= False
;
668 key
= string_tdb_data("INFO/jobs_changed");
670 if (tdb_chainlock_with_timeout(pdb
->tdb
, key
, 5) != 0)
675 data
= tdb_fetch_compat(pdb
->tdb
, key
);
677 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0))
680 job_count
= data
.dsize
/ 4;
681 for (i
= 0; i
< job_count
; i
++) {
684 ch_jobid
= IVAL(data
.dptr
, i
*4);
685 if (ch_jobid
== jobid
) {
686 if (i
< job_count
-1 )
687 memmove(data
.dptr
+ (i
*4), data
.dptr
+ (i
*4) + 4, (job_count
- i
- 1)*4 );
689 if (tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
) != 0)
699 tdb_chainunlock(pdb
->tdb
, key
);
700 SAFE_FREE(data
.dptr
);
701 release_print_db(pdb
);
703 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid
));
705 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid
));
709 static void pjob_store_notify(struct tevent_context
*ev
,
710 struct messaging_context
*msg_ctx
,
711 const char* sharename
, uint32 jobid
,
712 struct printjob
*old_data
,
713 struct printjob
*new_data
,
716 bool new_job
= false;
717 bool changed
= false;
719 if (old_data
== NULL
) {
723 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
724 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
725 time first or else we'll end up with potential alignment
726 errors. I don't think the systemtime should be spooled as
727 a string, but this gets us around that error.
728 --jerry (i'll feel dirty for this) */
731 notify_job_submitted(ev
, msg_ctx
,
732 sharename
, jobid
, new_data
->starttime
);
733 notify_job_username(ev
, msg_ctx
,
734 sharename
, jobid
, new_data
->user
);
735 notify_job_name(ev
, msg_ctx
,
736 sharename
, jobid
, new_data
->jobname
);
737 notify_job_status(ev
, msg_ctx
,
738 sharename
, jobid
, map_to_spoolss_status(new_data
->status
));
739 notify_job_total_bytes(ev
, msg_ctx
,
740 sharename
, jobid
, new_data
->size
);
741 notify_job_total_pages(ev
, msg_ctx
,
742 sharename
, jobid
, new_data
->page_count
);
744 if (!strequal(old_data
->jobname
, new_data
->jobname
)) {
745 notify_job_name(ev
, msg_ctx
, sharename
,
746 jobid
, new_data
->jobname
);
750 if (old_data
->status
!= new_data
->status
) {
751 notify_job_status(ev
, msg_ctx
,
753 map_to_spoolss_status(new_data
->status
));
756 if (old_data
->size
!= new_data
->size
) {
757 notify_job_total_bytes(ev
, msg_ctx
,
758 sharename
, jobid
, new_data
->size
);
761 if (old_data
->page_count
!= new_data
->page_count
) {
762 notify_job_total_pages(ev
, msg_ctx
,
764 new_data
->page_count
);
771 /****************************************************************************
772 Store a job structure back to the database.
773 ****************************************************************************/
775 static bool pjob_store(struct tevent_context
*ev
,
776 struct messaging_context
*msg_ctx
,
777 const char* sharename
, uint32 jobid
,
778 struct printjob
*pjob
)
781 TDB_DATA old_data
, new_data
;
783 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
785 int len
, newlen
, buflen
;
793 old_data
= tdb_fetch_compat(pdb
->tdb
, print_key(jobid
, &tmp
));
795 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
802 len
+= tdb_pack(buf
+len
, buflen
-len
, "ddddddddddfffff",
805 (uint32
)pjob
->sysjob
,
807 (uint32
)pjob
->starttime
,
808 (uint32
)pjob
->status
,
810 (uint32
)pjob
->page_count
,
811 (uint32
)pjob
->spooled
,
812 (uint32
)pjob
->smbjob
,
819 len
+= pack_devicemode(pjob
->devmode
, buf
+len
, buflen
-len
);
822 buf
= (uint8
*)SMB_REALLOC(buf
, len
);
824 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
829 } while ( buflen
!= len
);
835 new_data
.dsize
= len
;
836 ret
= (tdb_store(pdb
->tdb
, print_key(jobid
, &tmp
), new_data
,
839 /* Send notify updates for what has changed */
842 bool changed
= false;
843 struct printjob old_pjob
;
845 if (old_data
.dsize
) {
846 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
850 len
= unpack_pjob(tmp_ctx
, old_data
.dptr
,
851 old_data
.dsize
, &old_pjob
);
853 pjob_store_notify(ev
,
855 sharename
, jobid
, &old_pjob
,
859 add_to_jobs_changed(pdb
, jobid
);
862 talloc_free(tmp_ctx
);
866 pjob_store_notify(ev
, msg_ctx
,
867 sharename
, jobid
, NULL
, pjob
,
873 release_print_db(pdb
);
874 SAFE_FREE( old_data
.dptr
);
880 /****************************************************************************
881 Remove a job structure from the database.
882 ****************************************************************************/
884 static void pjob_delete(struct tevent_context
*ev
,
885 struct messaging_context
*msg_ctx
,
886 const char* sharename
, uint32 jobid
)
889 struct printjob
*pjob
;
890 uint32 job_status
= 0;
891 struct tdb_print_db
*pdb
;
892 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
893 if (tmp_ctx
== NULL
) {
897 pdb
= get_print_db_byname(sharename
);
902 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
904 DEBUG(5, ("we were asked to delete nonexistent job %u\n",
909 /* We must cycle through JOB_STATUS_DELETING and
910 JOB_STATUS_DELETED for the port monitor to delete the job
913 job_status
= JOB_STATUS_DELETING
|JOB_STATUS_DELETED
;
914 notify_job_status(ev
, msg_ctx
, sharename
, jobid
, job_status
);
916 /* Remove from printing.tdb */
918 tdb_delete(pdb
->tdb
, print_key(jobid
, &tmp
));
919 remove_from_jobs_added(sharename
, jobid
);
920 rap_jobid_delete(sharename
, jobid
);
922 release_print_db(pdb
);
924 talloc_free(tmp_ctx
);
927 /****************************************************************************
928 List a unix job in the print database.
929 ****************************************************************************/
931 static void print_unix_job(struct tevent_context
*ev
,
932 struct messaging_context
*msg_ctx
,
933 const char *sharename
, print_queue_struct
*q
,
936 struct printjob pj
, *old_pj
;
937 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
938 if (tmp_ctx
== NULL
) {
942 if (jobid
== (uint32
)-1) {
943 jobid
= q
->sysjob
+ UNIX_JOB_START
;
946 /* Preserve the timestamp on an existing unix print job */
948 old_pj
= print_job_find(tmp_ctx
, sharename
, jobid
);
954 pj
.sysjob
= q
->sysjob
;
956 pj
.starttime
= old_pj
? old_pj
->starttime
: q
->time
;
957 pj
.status
= q
->status
;
960 fstrcpy(pj
.filename
, old_pj
? old_pj
->filename
: "");
961 if (jobid
< UNIX_JOB_START
) {
963 fstrcpy(pj
.jobname
, old_pj
? old_pj
->jobname
: "Remote Downlevel Document");
966 fstrcpy(pj
.jobname
, old_pj
? old_pj
->jobname
: q
->fs_file
);
968 fstrcpy(pj
.user
, old_pj
? old_pj
->user
: q
->fs_user
);
969 fstrcpy(pj
.queuename
, old_pj
? old_pj
->queuename
: sharename
);
971 pjob_store(ev
, msg_ctx
, sharename
, jobid
, &pj
);
972 talloc_free(tmp_ctx
);
976 struct traverse_struct
{
977 print_queue_struct
*queue
;
978 int qcount
, snum
, maxcount
, total_jobs
;
979 const char *sharename
;
981 const char *lprm_command
;
982 struct printif
*print_if
;
983 struct tevent_context
*ev
;
984 struct messaging_context
*msg_ctx
;
988 /****************************************************************************
989 Utility fn to delete any jobs that are no longer active.
990 ****************************************************************************/
992 static int traverse_fn_delete(TDB_CONTEXT
*t
, TDB_DATA key
, TDB_DATA data
, void *state
)
994 struct traverse_struct
*ts
= (struct traverse_struct
*)state
;
995 struct printjob pjob
;
999 if ( key
.dsize
!= sizeof(jobid
) )
1002 if (unpack_pjob(ts
->mem_ctx
, data
.dptr
, data
.dsize
, &pjob
) == -1)
1004 talloc_free(pjob
.devmode
);
1008 /* remove a unix job if it isn't in the system queue any more */
1009 for (i
=0;i
<ts
->qcount
;i
++) {
1010 if (ts
->queue
[i
].sysjob
== pjob
.sysjob
) {
1014 if (i
== ts
->qcount
) {
1015 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
1016 (unsigned int)jobid
));
1017 pjob_delete(ts
->ev
, ts
->msg_ctx
,
1018 ts
->sharename
, jobid
);
1022 /* need to continue the the bottom of the function to
1023 save the correct attributes */
1026 /* maybe it hasn't been spooled yet */
1027 if (!pjob
.spooled
) {
1028 /* if a job is not spooled and the process doesn't
1029 exist then kill it. This cleans up after smbd
1031 if (!process_exists_by_pid(pjob
.pid
)) {
1032 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
1033 (unsigned int)jobid
, (unsigned int)pjob
.pid
));
1034 pjob_delete(ts
->ev
, ts
->msg_ctx
,
1035 ts
->sharename
, jobid
);
1041 /* this check only makes sense for jobs submitted from Windows clients */
1044 for (i
=0;i
<ts
->qcount
;i
++) {
1045 if ( pjob
.status
== LPQ_DELETED
)
1048 if (ts
->queue
[i
].sysjob
== pjob
.sysjob
) {
1050 /* try to clean up any jobs that need to be deleted */
1052 if ( pjob
.status
== LPQ_DELETING
) {
1055 result
= (*(ts
->print_if
->job_delete
))(
1056 ts
->sharename
, ts
->lprm_command
, &pjob
);
1058 if ( result
!= 0 ) {
1059 /* if we can't delete, then reset the job status */
1060 pjob
.status
= LPQ_QUEUED
;
1061 pjob_store(ts
->ev
, ts
->msg_ctx
,
1062 ts
->sharename
, jobid
, &pjob
);
1065 /* if we deleted the job, the remove the tdb record */
1068 ts
->sharename
, jobid
);
1069 pjob
.status
= LPQ_DELETED
;
1079 /* The job isn't in the system queue - we have to assume it has
1080 completed, so delete the database entry. */
1082 if (i
== ts
->qcount
) {
1084 /* A race can occur between the time a job is spooled and
1085 when it appears in the lpq output. This happens when
1086 the job is added to printing.tdb when another smbd
1087 running print_queue_update() has completed a lpq and
1088 is currently traversing the printing tdb and deleting jobs.
1089 Don't delete the job if it was submitted after the lpq_time. */
1091 if (pjob
.starttime
< ts
->lpq_time
) {
1092 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
1093 (unsigned int)jobid
,
1094 (unsigned int)pjob
.starttime
,
1095 (unsigned int)ts
->lpq_time
));
1096 pjob_delete(ts
->ev
, ts
->msg_ctx
,
1097 ts
->sharename
, jobid
);
1103 /* Save the pjob attributes we will store. */
1104 ts
->queue
[i
].sysjob
= pjob
.sysjob
;
1105 ts
->queue
[i
].size
= pjob
.size
;
1106 ts
->queue
[i
].page_count
= pjob
.page_count
;
1107 ts
->queue
[i
].status
= pjob
.status
;
1108 ts
->queue
[i
].priority
= 1;
1109 ts
->queue
[i
].time
= pjob
.starttime
;
1110 fstrcpy(ts
->queue
[i
].fs_user
, pjob
.user
);
1111 fstrcpy(ts
->queue
[i
].fs_file
, pjob
.jobname
);
1118 /****************************************************************************
1119 Check if the print queue has been updated recently enough.
1120 ****************************************************************************/
1122 static void print_cache_flush(const char *sharename
)
1125 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1129 slprintf(key
, sizeof(key
)-1, "CACHE/%s", sharename
);
1130 tdb_store_int32(pdb
->tdb
, key
, -1);
1131 release_print_db(pdb
);
1134 /****************************************************************************
1135 Check if someone already thinks they are doing the update.
1136 ****************************************************************************/
1138 static pid_t
get_updating_pid(const char *sharename
)
1143 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1147 slprintf(keystr
, sizeof(keystr
)-1, "UPDATING/%s", sharename
);
1148 key
= string_tdb_data(keystr
);
1150 data
= tdb_fetch_compat(pdb
->tdb
, key
);
1151 release_print_db(pdb
);
1152 if (!data
.dptr
|| data
.dsize
!= sizeof(pid_t
)) {
1153 SAFE_FREE(data
.dptr
);
1157 updating_pid
= IVAL(data
.dptr
, 0);
1158 SAFE_FREE(data
.dptr
);
1160 if (process_exists_by_pid(updating_pid
))
1161 return updating_pid
;
1166 /****************************************************************************
1167 Set the fact that we're doing the update, or have finished doing the update
1169 ****************************************************************************/
1171 static void set_updating_pid(const fstring sharename
, bool updating
)
1176 pid_t updating_pid
= getpid();
1179 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1184 slprintf(keystr
, sizeof(keystr
)-1, "UPDATING/%s", sharename
);
1185 key
= string_tdb_data(keystr
);
1187 DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
1188 updating
? "" : "not ",
1192 tdb_delete(pdb
->tdb
, key
);
1193 release_print_db(pdb
);
1197 SIVAL( buffer
, 0, updating_pid
);
1199 data
.dsize
= 4; /* we always assume this is a 4 byte value */
1201 tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
);
1202 release_print_db(pdb
);
1205 /****************************************************************************
1206 Sort print jobs by submittal time.
1207 ****************************************************************************/
1209 static int printjob_comp(print_queue_struct
*j1
, print_queue_struct
*j2
)
1220 /* Sort on job start time */
1222 if (j1
->time
== j2
->time
)
1224 return (j1
->time
> j2
->time
) ? 1 : -1;
1227 /****************************************************************************
1228 Store the sorted queue representation for later portmon retrieval.
1230 ****************************************************************************/
1232 static void store_queue_struct(struct tdb_print_db
*pdb
, struct traverse_struct
*pts
)
1235 int max_reported_jobs
= lp_max_reported_jobs(pts
->snum
);
1236 print_queue_struct
*queue
= pts
->queue
;
1239 unsigned int qcount
;
1241 if (max_reported_jobs
&& (max_reported_jobs
< pts
->qcount
))
1242 pts
->qcount
= max_reported_jobs
;
1245 /* Work out the size. */
1247 data
.dsize
+= tdb_pack(NULL
, 0, "d", qcount
);
1249 for (i
= 0; i
< pts
->qcount
; i
++) {
1250 if ( queue
[i
].status
== LPQ_DELETED
)
1254 data
.dsize
+= tdb_pack(NULL
, 0, "ddddddff",
1255 (uint32
)queue
[i
].sysjob
,
1256 (uint32
)queue
[i
].size
,
1257 (uint32
)queue
[i
].page_count
,
1258 (uint32
)queue
[i
].status
,
1259 (uint32
)queue
[i
].priority
,
1260 (uint32
)queue
[i
].time
,
1265 if ((data
.dptr
= (uint8
*)SMB_MALLOC(data
.dsize
)) == NULL
)
1269 len
+= tdb_pack(data
.dptr
+ len
, data
.dsize
- len
, "d", qcount
);
1270 for (i
= 0; i
< pts
->qcount
; i
++) {
1271 if ( queue
[i
].status
== LPQ_DELETED
)
1274 len
+= tdb_pack(data
.dptr
+ len
, data
.dsize
- len
, "ddddddff",
1275 (uint32
)queue
[i
].sysjob
,
1276 (uint32
)queue
[i
].size
,
1277 (uint32
)queue
[i
].page_count
,
1278 (uint32
)queue
[i
].status
,
1279 (uint32
)queue
[i
].priority
,
1280 (uint32
)queue
[i
].time
,
1285 tdb_store(pdb
->tdb
, string_tdb_data("INFO/linear_queue_array"), data
,
1287 SAFE_FREE(data
.dptr
);
1291 static TDB_DATA
get_jobs_added_data(struct tdb_print_db
*pdb
)
1297 data
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data("INFO/jobs_added"));
1298 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0)) {
1299 SAFE_FREE(data
.dptr
);
1306 static void check_job_added(const char *sharename
, TDB_DATA data
, uint32 jobid
)
1309 unsigned int job_count
= data
.dsize
/ 4;
1311 for (i
= 0; i
< job_count
; i
++) {
1314 ch_jobid
= IVAL(data
.dptr
, i
*4);
1315 if (ch_jobid
== jobid
)
1316 remove_from_jobs_added(sharename
, jobid
);
1320 /****************************************************************************
1321 Check if the print queue has been updated recently enough.
1322 ****************************************************************************/
1324 static bool print_cache_expired(const char *sharename
, bool check_pending
)
1327 time_t last_qscan_time
, time_now
= time(NULL
);
1328 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1329 bool result
= False
;
1334 snprintf(key
, sizeof(key
), "CACHE/%s", sharename
);
1335 last_qscan_time
= (time_t)tdb_fetch_int32(pdb
->tdb
, key
);
1338 * Invalidate the queue for 3 reasons.
1339 * (1). last queue scan time == -1.
1340 * (2). Current time - last queue scan time > allowed cache time.
1341 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1342 * This last test picks up machines for which the clock has been moved
1343 * forward, an lpq scan done and then the clock moved back. Otherwise
1344 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1347 if (last_qscan_time
== ((time_t)-1)
1348 || (time_now
- last_qscan_time
) >= lp_lpqcachetime()
1349 || last_qscan_time
> (time_now
+ MAX_CACHE_VALID_TIME
))
1352 time_t msg_pending_time
;
1354 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1355 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1356 sharename
, (int)last_qscan_time
, (int)time_now
,
1357 (int)lp_lpqcachetime() ));
1359 /* check if another smbd has already sent a message to update the
1360 queue. Give the pending message one minute to clear and
1361 then send another message anyways. Make sure to check for
1362 clocks that have been run forward and then back again. */
1364 snprintf(key
, sizeof(key
), "MSG_PENDING/%s", sharename
);
1367 && tdb_fetch_uint32( pdb
->tdb
, key
, &u
)
1368 && (msg_pending_time
=u
) > 0
1369 && msg_pending_time
<= time_now
1370 && (time_now
- msg_pending_time
) < 60 )
1372 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1381 release_print_db(pdb
);
1385 /****************************************************************************
1386 main work for updating the lpq cache for a printer queue
1387 ****************************************************************************/
1389 static void print_queue_update_internal(struct tevent_context
*ev
,
1390 struct messaging_context
*msg_ctx
,
1391 const char *sharename
,
1392 struct printif
*current_printif
,
1393 char *lpq_command
, char *lprm_command
)
1396 print_queue_struct
*queue
= NULL
;
1397 print_status_struct status
;
1398 print_status_struct old_status
;
1399 struct printjob
*pjob
;
1400 struct traverse_struct tstruct
;
1403 fstring keystr
, cachestr
;
1404 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1405 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
1407 if ((pdb
== NULL
) || (tmp_ctx
== NULL
)) {
1411 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1412 sharename
, current_printif
->type
, lpq_command
));
1415 * Update the cache time FIRST ! Stops others even
1416 * attempting to get the lock and doing this
1417 * if the lpq takes a long time.
1420 slprintf(cachestr
, sizeof(cachestr
)-1, "CACHE/%s", sharename
);
1421 tdb_store_int32(pdb
->tdb
, cachestr
, (int)time(NULL
));
1423 /* get the current queue using the appropriate interface */
1424 ZERO_STRUCT(status
);
1426 qcount
= (*(current_printif
->queue_get
))(sharename
,
1427 current_printif
->type
,
1428 lpq_command
, &queue
, &status
);
1430 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1431 qcount
, (qcount
!= 1) ? "s" : "", sharename
));
1433 /* Sort the queue by submission time otherwise they are displayed
1436 TYPESAFE_QSORT(queue
, qcount
, printjob_comp
);
1439 any job in the internal database that is marked as spooled
1440 and doesn't exist in the system queue is considered finished
1441 and removed from the database
1443 any job in the system database but not in the internal database
1444 is added as a unix job
1446 fill in any system job numbers as we go
1448 jcdata
= get_jobs_added_data(pdb
);
1450 for (i
=0; i
<qcount
; i
++) {
1451 uint32 jobid
= sysjob_to_jobid_pdb(pdb
, queue
[i
].sysjob
);
1452 if (jobid
== (uint32
)-1) {
1453 /* assume its a unix print job */
1454 print_unix_job(ev
, msg_ctx
,
1455 sharename
, &queue
[i
], jobid
);
1459 /* we have an active SMB print job - update its status */
1460 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
1462 /* err, somethings wrong. Probably smbd was restarted
1463 with jobs in the queue. All we can do is treat them
1464 like unix jobs. Pity. */
1465 DEBUG(1, ("queued print job %d not found in jobs list, "
1466 "assuming unix job\n", jobid
));
1467 print_unix_job(ev
, msg_ctx
,
1468 sharename
, &queue
[i
], jobid
);
1472 /* don't reset the status on jobs to be deleted */
1474 if ( pjob
->status
!= LPQ_DELETING
)
1475 pjob
->status
= queue
[i
].status
;
1477 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
1479 check_job_added(sharename
, jcdata
, jobid
);
1482 SAFE_FREE(jcdata
.dptr
);
1484 /* now delete any queued entries that don't appear in the
1486 tstruct
.queue
= queue
;
1487 tstruct
.qcount
= qcount
;
1489 tstruct
.total_jobs
= 0;
1490 tstruct
.lpq_time
= time(NULL
);
1491 tstruct
.sharename
= sharename
;
1492 tstruct
.lprm_command
= lprm_command
;
1493 tstruct
.print_if
= current_printif
;
1495 tstruct
.msg_ctx
= msg_ctx
;
1496 tstruct
.mem_ctx
= tmp_ctx
;
1498 tdb_traverse(pdb
->tdb
, traverse_fn_delete
, (void *)&tstruct
);
1500 /* Store the linearised queue, max jobs only. */
1501 store_queue_struct(pdb
, &tstruct
);
1503 SAFE_FREE(tstruct
.queue
);
1504 talloc_free(tmp_ctx
);
1506 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1507 sharename
, tstruct
.total_jobs
));
1509 tdb_store_int32(pdb
->tdb
, "INFO/total_jobs", tstruct
.total_jobs
);
1511 get_queue_status(sharename
, &old_status
);
1512 if (old_status
.qcount
!= qcount
)
1513 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1514 old_status
.qcount
, qcount
, sharename
));
1516 /* store the new queue status structure */
1517 slprintf(keystr
, sizeof(keystr
)-1, "STATUS/%s", sharename
);
1518 key
= string_tdb_data(keystr
);
1520 status
.qcount
= qcount
;
1521 data
.dptr
= (uint8
*)&status
;
1522 data
.dsize
= sizeof(status
);
1523 tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
);
1526 * Update the cache time again. We want to do this call
1527 * as little as possible...
1530 slprintf(keystr
, sizeof(keystr
)-1, "CACHE/%s", sharename
);
1531 tdb_store_int32(pdb
->tdb
, keystr
, (int32
)time(NULL
));
1533 /* clear the msg pending record for this queue */
1535 snprintf(keystr
, sizeof(keystr
), "MSG_PENDING/%s", sharename
);
1537 if ( !tdb_store_uint32( pdb
->tdb
, keystr
, 0 ) ) {
1538 /* log a message but continue on */
1540 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1544 release_print_db( pdb
);
1549 /****************************************************************************
1550 Update the internal database from the system print queue for a queue.
1551 obtain a lock on the print queue before proceeding (needed when mutiple
1552 smbd processes maytry to update the lpq cache concurrently).
1553 ****************************************************************************/
1555 static void print_queue_update_with_lock( struct tevent_context
*ev
,
1556 struct messaging_context
*msg_ctx
,
1557 const char *sharename
,
1558 struct printif
*current_printif
,
1559 char *lpq_command
, char *lprm_command
)
1562 struct tdb_print_db
*pdb
;
1564 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename
));
1565 pdb
= get_print_db_byname(sharename
);
1569 if ( !print_cache_expired(sharename
, False
) ) {
1570 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename
));
1571 release_print_db(pdb
);
1576 * Check to see if someone else is doing this update.
1577 * This is essentially a mutex on the update.
1580 if (get_updating_pid(sharename
) != -1) {
1581 release_print_db(pdb
);
1585 /* Lock the queue for the database update */
1587 slprintf(keystr
, sizeof(keystr
) - 1, "LOCK/%s", sharename
);
1588 /* Only wait 10 seconds for this. */
1589 if (tdb_lock_bystring_with_timeout(pdb
->tdb
, keystr
, 10) != 0) {
1590 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename
));
1591 release_print_db(pdb
);
1596 * Ensure that no one else got in here.
1597 * If the updating pid is still -1 then we are
1601 if (get_updating_pid(sharename
) != -1) {
1603 * Someone else is doing the update, exit.
1605 tdb_unlock_bystring(pdb
->tdb
, keystr
);
1606 release_print_db(pdb
);
1611 * We're going to do the update ourselves.
1614 /* Tell others we're doing the update. */
1615 set_updating_pid(sharename
, True
);
1618 * Allow others to enter and notice we're doing
1622 tdb_unlock_bystring(pdb
->tdb
, keystr
);
1624 /* do the main work now */
1626 print_queue_update_internal(ev
, msg_ctx
,
1627 sharename
, current_printif
,
1628 lpq_command
, lprm_command
);
1630 /* Delete our pid from the db. */
1631 set_updating_pid(sharename
, False
);
1632 release_print_db(pdb
);
1635 /****************************************************************************
1636 this is the receive function of the background lpq updater
1637 ****************************************************************************/
1638 void print_queue_receive(struct messaging_context
*msg
,
1641 struct server_id server_id
,
1645 char *lpqcommand
= NULL
, *lprmcommand
= NULL
;
1649 len
= tdb_unpack( (uint8
*)data
->data
, data
->length
, "fdPP",
1656 SAFE_FREE(lpqcommand
);
1657 SAFE_FREE(lprmcommand
);
1658 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1662 print_queue_update_with_lock(server_event_context(), msg
, sharename
,
1663 get_printer_fns_from_type((enum printing_types
)printing_type
),
1664 lpqcommand
, lprmcommand
);
1666 SAFE_FREE(lpqcommand
);
1667 SAFE_FREE(lprmcommand
);
1671 /****************************************************************************
1672 update the internal database from the system print queue for a queue
1673 ****************************************************************************/
1675 extern pid_t background_lpq_updater_pid
;
1677 static void print_queue_update(struct messaging_context
*msg_ctx
,
1678 int snum
, bool force
)
1682 char *lpqcommand
= NULL
;
1683 char *lprmcommand
= NULL
;
1684 uint8
*buffer
= NULL
;
1687 struct tdb_print_db
*pdb
;
1689 struct printif
*current_printif
;
1690 TALLOC_CTX
*ctx
= talloc_tos();
1692 fstrcpy( sharename
, lp_const_servicename(snum
));
1694 /* don't strip out characters like '$' from the printername */
1696 lpqcommand
= talloc_string_sub2(ctx
,
1697 lp_lpqcommand(talloc_tos(), snum
),
1699 lp_printername(talloc_tos(), snum
),
1700 false, false, false);
1704 lpqcommand
= talloc_sub_advanced(ctx
,
1705 lp_servicename(talloc_tos(), snum
),
1706 current_user_info
.unix_name
,
1708 current_user
.ut
.gid
,
1709 get_current_username(),
1710 current_user_info
.domain
,
1716 lprmcommand
= talloc_string_sub2(ctx
,
1717 lp_lprmcommand(talloc_tos(), snum
),
1719 lp_printername(talloc_tos(), snum
),
1720 false, false, false);
1724 lprmcommand
= talloc_sub_advanced(ctx
,
1725 lp_servicename(talloc_tos(), snum
),
1726 current_user_info
.unix_name
,
1728 current_user
.ut
.gid
,
1729 get_current_username(),
1730 current_user_info
.domain
,
1737 * Make sure that the background queue process exists.
1738 * Otherwise just do the update ourselves
1741 if ( force
|| background_lpq_updater_pid
== -1 ) {
1742 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename
));
1743 current_printif
= get_printer_fns( snum
);
1744 print_queue_update_with_lock(server_event_context(), msg_ctx
,
1745 sharename
, current_printif
,
1746 lpqcommand
, lprmcommand
);
1751 type
= lp_printing(snum
);
1753 /* get the length */
1755 len
= tdb_pack( NULL
, 0, "fdPP",
1761 buffer
= SMB_XMALLOC_ARRAY( uint8
, len
);
1763 /* now pack the buffer */
1764 newlen
= tdb_pack( buffer
, len
, "fdPP",
1770 SMB_ASSERT( newlen
== len
);
1772 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1773 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1774 sharename
, type
, lpqcommand
, lprmcommand
));
1776 /* here we set a msg pending record for other smbd processes
1777 to throttle the number of duplicate print_queue_update msgs
1780 pdb
= get_print_db_byname(sharename
);
1786 snprintf(key
, sizeof(key
), "MSG_PENDING/%s", sharename
);
1788 if ( !tdb_store_uint32( pdb
->tdb
, key
, time(NULL
) ) ) {
1789 /* log a message but continue on */
1791 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1795 release_print_db( pdb
);
1797 /* finally send the message */
1799 messaging_send_buf(msg_ctx
, pid_to_procid(background_lpq_updater_pid
),
1800 MSG_PRINTER_UPDATE
, (uint8
*)buffer
, len
);
1802 SAFE_FREE( buffer
);
1807 /****************************************************************************
1808 Create/Update an entry in the print tdb that will allow us to send notify
1809 updates only to interested smbd's.
1810 ****************************************************************************/
1812 bool print_notify_register_pid(int snum
)
1815 struct tdb_print_db
*pdb
= NULL
;
1816 TDB_CONTEXT
*tdb
= NULL
;
1817 const char *printername
;
1818 uint32_t mypid
= (uint32_t)getpid();
1822 /* if (snum == -1), then the change notify request was
1823 on a print server handle and we need to register on
1828 int num_services
= lp_numservices();
1831 for ( idx
=0; idx
<num_services
; idx
++ ) {
1832 if (lp_snum_ok(idx
) && lp_print_ok(idx
) )
1833 print_notify_register_pid(idx
);
1838 else /* register for a specific printer */
1840 printername
= lp_const_servicename(snum
);
1841 pdb
= get_print_db_byname(printername
);
1847 if (tdb_lock_bystring_with_timeout(tdb
, NOTIFY_PID_LIST_KEY
, 10) != 0) {
1848 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1851 release_print_db(pdb
);
1855 data
= get_printer_notify_pid_list( tdb
, printername
, True
);
1857 /* Add ourselves and increase the refcount. */
1859 for (i
= 0; i
< data
.dsize
; i
+= 8) {
1860 if (IVAL(data
.dptr
,i
) == mypid
) {
1861 uint32 new_refcount
= IVAL(data
.dptr
, i
+4) + 1;
1862 SIVAL(data
.dptr
, i
+4, new_refcount
);
1867 if (i
== data
.dsize
) {
1868 /* We weren't in the list. Realloc. */
1869 data
.dptr
= (uint8
*)SMB_REALLOC(data
.dptr
, data
.dsize
+ 8);
1871 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1876 SIVAL(data
.dptr
,data
.dsize
- 8,mypid
);
1877 SIVAL(data
.dptr
,data
.dsize
- 4,1); /* Refcount. */
1880 /* Store back the record. */
1881 if (tdb_store_bystring(tdb
, NOTIFY_PID_LIST_KEY
, data
, TDB_REPLACE
) != 0) {
1882 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1883 list for printer %s\n", printername
));
1891 tdb_unlock_bystring(tdb
, NOTIFY_PID_LIST_KEY
);
1893 release_print_db(pdb
);
1894 SAFE_FREE(data
.dptr
);
1898 /****************************************************************************
1899 Update an entry in the print tdb that will allow us to send notify
1900 updates only to interested smbd's.
1901 ****************************************************************************/
1903 bool print_notify_deregister_pid(int snum
)
1906 struct tdb_print_db
*pdb
= NULL
;
1907 TDB_CONTEXT
*tdb
= NULL
;
1908 const char *printername
;
1909 uint32_t mypid
= (uint32_t)getpid();
1913 /* if ( snum == -1 ), we are deregister a print server handle
1914 which means to deregister on all print queues */
1918 int num_services
= lp_numservices();
1921 for ( idx
=0; idx
<num_services
; idx
++ ) {
1922 if ( lp_snum_ok(idx
) && lp_print_ok(idx
) )
1923 print_notify_deregister_pid(idx
);
1928 else /* deregister a specific printer */
1930 printername
= lp_const_servicename(snum
);
1931 pdb
= get_print_db_byname(printername
);
1937 if (tdb_lock_bystring_with_timeout(tdb
, NOTIFY_PID_LIST_KEY
, 10) != 0) {
1938 DEBUG(0,("print_notify_register_pid: Failed to lock \
1939 printer %s database\n", printername
));
1941 release_print_db(pdb
);
1945 data
= get_printer_notify_pid_list( tdb
, printername
, True
);
1947 /* Reduce refcount. Remove ourselves if zero. */
1949 for (i
= 0; i
< data
.dsize
; ) {
1950 if (IVAL(data
.dptr
,i
) == mypid
) {
1951 uint32 refcount
= IVAL(data
.dptr
, i
+4);
1955 if (refcount
== 0) {
1956 if (data
.dsize
- i
> 8)
1957 memmove( &data
.dptr
[i
], &data
.dptr
[i
+8], data
.dsize
- i
- 8);
1961 SIVAL(data
.dptr
, i
+4, refcount
);
1967 if (data
.dsize
== 0)
1968 SAFE_FREE(data
.dptr
);
1970 /* Store back the record. */
1971 if (tdb_store_bystring(tdb
, NOTIFY_PID_LIST_KEY
, data
, TDB_REPLACE
) != 0) {
1972 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1973 list for printer %s\n", printername
));
1981 tdb_unlock_bystring(tdb
, NOTIFY_PID_LIST_KEY
);
1983 release_print_db(pdb
);
1984 SAFE_FREE(data
.dptr
);
1988 /****************************************************************************
1989 Check if a jobid is valid. It is valid if it exists in the database.
1990 ****************************************************************************/
1992 bool print_job_exists(const char* sharename
, uint32 jobid
)
1994 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2000 ret
= tdb_exists(pdb
->tdb
, print_key(jobid
, &tmp
));
2001 release_print_db(pdb
);
2005 /****************************************************************************
2006 Return the device mode asigned to a specific print job.
2007 Only valid for the process doing the spooling and when the job
2008 has not been spooled.
2009 ****************************************************************************/
2011 struct spoolss_DeviceMode
*print_job_devmode(TALLOC_CTX
*mem_ctx
,
2012 const char *sharename
,
2015 struct printjob
*pjob
= print_job_find(mem_ctx
, sharename
, jobid
);
2020 return pjob
->devmode
;
2023 /****************************************************************************
2024 Set the name of a job. Only possible for owner.
2025 ****************************************************************************/
2027 bool print_job_set_name(struct tevent_context
*ev
,
2028 struct messaging_context
*msg_ctx
,
2029 const char *sharename
, uint32 jobid
, const char *name
)
2031 struct printjob
*pjob
;
2033 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
2034 if (tmp_ctx
== NULL
) {
2038 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2039 if (!pjob
|| pjob
->pid
!= getpid()) {
2044 fstrcpy(pjob
->jobname
, name
);
2045 ret
= pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2047 talloc_free(tmp_ctx
);
2051 /****************************************************************************
2052 Get the name of a job. Only possible for owner.
2053 ****************************************************************************/
2055 bool print_job_get_name(TALLOC_CTX
*mem_ctx
, const char *sharename
, uint32_t jobid
, char **name
)
2057 struct printjob
*pjob
;
2059 pjob
= print_job_find(mem_ctx
, sharename
, jobid
);
2060 if (!pjob
|| pjob
->pid
!= getpid()) {
2064 *name
= pjob
->jobname
;
2069 /***************************************************************************
2070 Remove a jobid from the 'jobs added' list.
2071 ***************************************************************************/
2073 static bool remove_from_jobs_added(const char* sharename
, uint32 jobid
)
2075 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2077 size_t job_count
, i
;
2079 bool gotlock
= False
;
2087 key
= string_tdb_data("INFO/jobs_added");
2089 if (tdb_chainlock_with_timeout(pdb
->tdb
, key
, 5) != 0)
2094 data
= tdb_fetch_compat(pdb
->tdb
, key
);
2096 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0))
2099 job_count
= data
.dsize
/ 4;
2100 for (i
= 0; i
< job_count
; i
++) {
2103 ch_jobid
= IVAL(data
.dptr
, i
*4);
2104 if (ch_jobid
== jobid
) {
2105 if (i
< job_count
-1 )
2106 memmove(data
.dptr
+ (i
*4), data
.dptr
+ (i
*4) + 4, (job_count
- i
- 1)*4 );
2108 if (tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
) != 0)
2118 tdb_chainunlock(pdb
->tdb
, key
);
2119 SAFE_FREE(data
.dptr
);
2120 release_print_db(pdb
);
2122 DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid
));
2124 DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid
));
2128 /****************************************************************************
2129 Delete a print job - don't update queue.
2130 ****************************************************************************/
2132 static bool print_job_delete1(struct tevent_context
*ev
,
2133 struct messaging_context
*msg_ctx
,
2134 int snum
, uint32 jobid
)
2136 const char* sharename
= lp_const_servicename(snum
);
2137 struct printjob
*pjob
;
2139 struct printif
*current_printif
= get_printer_fns( snum
);
2141 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
2142 if (tmp_ctx
== NULL
) {
2146 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2153 * If already deleting just return.
2156 if (pjob
->status
== LPQ_DELETING
) {
2161 /* Hrm - we need to be able to cope with deleting a job before it
2162 has reached the spooler. Just mark it as LPQ_DELETING and
2163 let the print_queue_update() code rmeove the record */
2166 if (pjob
->sysjob
== -1) {
2167 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid
));
2170 /* Set the tdb entry to be deleting. */
2172 pjob
->status
= LPQ_DELETING
;
2173 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2175 if (pjob
->spooled
&& pjob
->sysjob
!= -1)
2177 result
= (*(current_printif
->job_delete
))(
2178 lp_printername(talloc_tos(), snum
),
2179 lp_lprmcommand(talloc_tos(), snum
),
2182 /* Delete the tdb entry if the delete succeeded or the job hasn't
2186 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2193 pjob_delete(ev
, msg_ctx
, sharename
, jobid
);
2194 /* Ensure we keep a rough count of the number of total jobs... */
2195 tdb_change_int32_atomic(pdb
->tdb
, "INFO/total_jobs", &njobs
, -1);
2196 release_print_db(pdb
);
2200 remove_from_jobs_added( sharename
, jobid
);
2202 ret
= (result
== 0);
2204 talloc_free(tmp_ctx
);
2208 /****************************************************************************
2209 Return true if the current user owns the print job.
2210 ****************************************************************************/
2212 static bool is_owner(const struct auth_session_info
*server_info
,
2213 const char *servicename
,
2216 struct printjob
*pjob
;
2218 TALLOC_CTX
*tmp_ctx
= talloc_new(server_info
);
2219 if (tmp_ctx
== NULL
) {
2223 pjob
= print_job_find(tmp_ctx
, servicename
, jobid
);
2224 if (!pjob
|| !server_info
) {
2229 ret
= strequal(pjob
->user
, server_info
->unix_info
->sanitized_username
);
2231 talloc_free(tmp_ctx
);
2235 /****************************************************************************
2237 ****************************************************************************/
2239 WERROR
print_job_delete(const struct auth_session_info
*server_info
,
2240 struct messaging_context
*msg_ctx
,
2241 int snum
, uint32_t jobid
)
2243 const char* sharename
= lp_const_servicename(snum
);
2244 struct printjob
*pjob
;
2247 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2248 if (tmp_ctx
== NULL
) {
2249 return WERR_NOT_ENOUGH_MEMORY
;
2252 owner
= is_owner(server_info
, lp_const_servicename(snum
), jobid
);
2254 /* Check access against security descriptor or whether the user
2258 !print_access_check(server_info
, msg_ctx
, snum
,
2259 JOB_ACCESS_ADMINISTER
)) {
2260 DEBUG(3, ("delete denied by security descriptor\n"));
2262 /* BEGIN_ADMIN_LOG */
2263 sys_adminlog( LOG_ERR
,
2264 "Permission denied-- user not allowed to delete, \
2265 pause, or resume print job. User name: %s. Printer name: %s.",
2266 uidtoname(server_info
->unix_token
->uid
),
2267 lp_printername(talloc_tos(), snum
) );
2270 werr
= WERR_ACCESS_DENIED
;
2275 * get the spooled filename of the print job
2276 * if this works, then the file has not been spooled
2277 * to the underlying print system. Just delete the
2278 * spool file & return.
2281 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2282 if (!pjob
|| pjob
->spooled
|| pjob
->pid
!= getpid()) {
2283 DEBUG(10, ("Skipping spool file removal for job %u\n", jobid
));
2285 DEBUG(10, ("Removing spool file [%s]\n", pjob
->filename
));
2286 if (unlink(pjob
->filename
) == -1) {
2287 werr
= map_werror_from_unix(errno
);
2292 if (!print_job_delete1(server_event_context(), msg_ctx
, snum
, jobid
)) {
2293 werr
= WERR_ACCESS_DENIED
;
2297 /* force update the database and say the delete failed if the
2300 print_queue_update(msg_ctx
, snum
, True
);
2302 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2303 if (pjob
&& (pjob
->status
!= LPQ_DELETING
)) {
2304 werr
= WERR_ACCESS_DENIED
;
2307 werr
= WERR_PRINTER_HAS_JOBS_QUEUED
;
2310 talloc_free(tmp_ctx
);
2314 /****************************************************************************
2316 ****************************************************************************/
2318 WERROR
print_job_pause(const struct auth_session_info
*server_info
,
2319 struct messaging_context
*msg_ctx
,
2320 int snum
, uint32 jobid
)
2322 const char* sharename
= lp_const_servicename(snum
);
2323 struct printjob
*pjob
;
2325 struct printif
*current_printif
= get_printer_fns( snum
);
2327 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2328 if (tmp_ctx
== NULL
) {
2329 return WERR_NOT_ENOUGH_MEMORY
;
2332 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2333 if (!pjob
|| !server_info
) {
2334 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2335 (unsigned int)jobid
));
2336 werr
= WERR_INVALID_PARAM
;
2340 if (!pjob
->spooled
|| pjob
->sysjob
== -1) {
2341 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2342 (int)pjob
->sysjob
, (unsigned int)jobid
));
2343 werr
= WERR_INVALID_PARAM
;
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
->unix_token
->uid
),
2357 lp_printername(talloc_tos(), snum
) );
2360 werr
= WERR_ACCESS_DENIED
;
2364 /* need to pause the spooled entry */
2365 ret
= (*(current_printif
->job_pause
))(snum
, pjob
);
2368 werr
= 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? */
2383 talloc_free(tmp_ctx
);
2387 /****************************************************************************
2389 ****************************************************************************/
2391 WERROR
print_job_resume(const struct auth_session_info
*server_info
,
2392 struct messaging_context
*msg_ctx
,
2393 int snum
, uint32 jobid
)
2395 const char *sharename
= lp_const_servicename(snum
);
2396 struct printjob
*pjob
;
2398 struct printif
*current_printif
= get_printer_fns( snum
);
2400 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2401 if (tmp_ctx
== NULL
)
2402 return WERR_NOT_ENOUGH_MEMORY
;
2404 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2405 if (!pjob
|| !server_info
) {
2406 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2407 (unsigned int)jobid
));
2408 werr
= WERR_INVALID_PARAM
;
2412 if (!pjob
->spooled
|| pjob
->sysjob
== -1) {
2413 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2414 (int)pjob
->sysjob
, (unsigned int)jobid
));
2415 werr
= WERR_INVALID_PARAM
;
2419 if (!is_owner(server_info
, lp_const_servicename(snum
), jobid
) &&
2420 !print_access_check(server_info
, msg_ctx
, snum
,
2421 JOB_ACCESS_ADMINISTER
)) {
2422 DEBUG(3, ("resume denied by security descriptor\n"));
2424 /* BEGIN_ADMIN_LOG */
2425 sys_adminlog( LOG_ERR
,
2426 "Permission denied-- user not allowed to delete, \
2427 pause, or resume print job. User name: %s. Printer name: %s.",
2428 uidtoname(server_info
->unix_token
->uid
),
2429 lp_printername(talloc_tos(), snum
) );
2431 werr
= WERR_ACCESS_DENIED
;
2435 ret
= (*(current_printif
->job_resume
))(snum
, pjob
);
2438 werr
= WERR_INVALID_PARAM
;
2442 /* force update the database */
2443 print_cache_flush(lp_const_servicename(snum
));
2445 /* Send a printer notify message */
2447 notify_job_status(server_event_context(), msg_ctx
, sharename
, jobid
,
2452 talloc_free(tmp_ctx
);
2456 /****************************************************************************
2457 Write to a print file.
2458 ****************************************************************************/
2460 ssize_t
print_job_write(struct tevent_context
*ev
,
2461 struct messaging_context
*msg_ctx
,
2462 int snum
, uint32 jobid
, const char *buf
, size_t size
)
2464 const char* sharename
= lp_const_servicename(snum
);
2465 ssize_t return_code
;
2466 struct printjob
*pjob
;
2467 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
2468 if (tmp_ctx
== NULL
) {
2472 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2478 /* don't allow another process to get this info - it is meaningless */
2479 if (pjob
->pid
!= getpid()) {
2484 /* if SMBD is spooling this can't be allowed */
2485 if (pjob
->status
== PJOB_SMBD_SPOOLING
) {
2490 return_code
= write_data(pjob
->fd
, buf
, size
);
2491 if (return_code
> 0) {
2493 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2496 talloc_free(tmp_ctx
);
2500 /****************************************************************************
2501 Get the queue status - do not update if db is out of date.
2502 ****************************************************************************/
2504 static int get_queue_status(const char* sharename
, print_status_struct
*status
)
2508 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2512 ZERO_STRUCTP(status
);
2519 fstr_sprintf(keystr
, "STATUS/%s", sharename
);
2520 data
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data(keystr
));
2522 if (data
.dsize
== sizeof(print_status_struct
))
2523 /* this memcpy is ok since the status struct was
2524 not packed before storing it in the tdb */
2525 memcpy(status
, data
.dptr
, sizeof(print_status_struct
));
2526 SAFE_FREE(data
.dptr
);
2529 len
= tdb_fetch_int32(pdb
->tdb
, "INFO/total_jobs");
2530 release_print_db(pdb
);
2531 return (len
== -1 ? 0 : len
);
2534 /****************************************************************************
2535 Determine the number of jobs in a queue.
2536 ****************************************************************************/
2538 int print_queue_length(struct messaging_context
*msg_ctx
, int snum
,
2539 print_status_struct
*pstatus
)
2541 const char* sharename
= lp_const_servicename( snum
);
2542 print_status_struct status
;
2545 ZERO_STRUCT( status
);
2547 /* make sure the database is up to date */
2548 if (print_cache_expired(lp_const_servicename(snum
), True
))
2549 print_queue_update(msg_ctx
, snum
, False
);
2551 /* also fetch the queue status */
2552 memset(&status
, 0, sizeof(status
));
2553 len
= get_queue_status(sharename
, &status
);
2561 /***************************************************************************
2562 Allocate a jobid. Hold the lock for as short a time as possible.
2563 ***************************************************************************/
2565 static WERROR
allocate_print_jobid(struct tdb_print_db
*pdb
, int snum
,
2566 const char *sharename
, uint32
*pjobid
)
2570 enum TDB_ERROR terr
;
2573 *pjobid
= (uint32
)-1;
2575 for (i
= 0; i
< 3; i
++) {
2576 /* Lock the database - only wait 20 seconds. */
2577 ret
= tdb_lock_bystring_with_timeout(pdb
->tdb
,
2578 "INFO/nextjob", 20);
2580 DEBUG(0, ("allocate_print_jobid: "
2581 "Failed to lock printing database %s\n",
2583 terr
= tdb_error(pdb
->tdb
);
2584 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2587 if (!tdb_fetch_uint32(pdb
->tdb
, "INFO/nextjob", &jobid
)) {
2588 terr
= tdb_error(pdb
->tdb
);
2589 if (terr
!= TDB_ERR_NOEXIST
) {
2590 DEBUG(0, ("allocate_print_jobid: "
2591 "Failed to fetch INFO/nextjob "
2592 "for print queue %s\n", sharename
));
2593 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2594 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2596 DEBUG(10, ("allocate_print_jobid: "
2597 "No existing jobid in %s\n", sharename
));
2601 DEBUG(10, ("allocate_print_jobid: "
2602 "Read jobid %u from %s\n", jobid
, sharename
));
2604 jobid
= NEXT_JOBID(jobid
);
2606 ret
= tdb_store_int32(pdb
->tdb
, "INFO/nextjob", jobid
);
2608 terr
= tdb_error(pdb
->tdb
);
2609 DEBUG(3, ("allocate_print_jobid: "
2610 "Failed to store INFO/nextjob.\n"));
2611 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2612 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2615 /* We've finished with the INFO/nextjob lock. */
2616 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2618 if (!print_job_exists(sharename
, jobid
)) {
2621 DEBUG(10, ("allocate_print_jobid: "
2622 "Found jobid %u in %s\n", jobid
, sharename
));
2626 DEBUG(0, ("allocate_print_jobid: "
2627 "Failed to allocate a print job for queue %s\n",
2629 /* Probably full... */
2630 return WERR_NO_SPOOL_SPACE
;
2633 /* Store a dummy placeholder. */
2639 if (tdb_store(pdb
->tdb
, print_key(jobid
, &tmp
), dum
,
2641 DEBUG(3, ("allocate_print_jobid: "
2642 "jobid (%d) failed to store placeholder.\n",
2644 terr
= tdb_error(pdb
->tdb
);
2645 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2653 /***************************************************************************
2654 Append a jobid to the 'jobs added' list.
2655 ***************************************************************************/
2657 static bool add_to_jobs_added(struct tdb_print_db
*pdb
, uint32 jobid
)
2662 SIVAL(&store_jobid
, 0, jobid
);
2663 data
.dptr
= (uint8
*)&store_jobid
;
2666 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid
));
2668 return (tdb_append(pdb
->tdb
, string_tdb_data("INFO/jobs_added"),
2673 /***************************************************************************
2674 Do all checks needed to determine if we can start a job.
2675 ***************************************************************************/
2677 static WERROR
print_job_checks(const struct auth_session_info
*server_info
,
2678 struct messaging_context
*msg_ctx
,
2679 int snum
, int *njobs
)
2681 const char *sharename
= lp_const_servicename(snum
);
2682 uint64_t dspace
, dsize
;
2686 if (!print_access_check(server_info
, msg_ctx
, snum
,
2687 PRINTER_ACCESS_USE
)) {
2688 DEBUG(3, ("print_job_checks: "
2689 "job start denied by security descriptor\n"));
2690 return WERR_ACCESS_DENIED
;
2693 if (!print_time_access_check(server_info
, msg_ctx
, sharename
)) {
2694 DEBUG(3, ("print_job_checks: "
2695 "job start denied by time check\n"));
2696 return WERR_ACCESS_DENIED
;
2699 /* see if we have sufficient disk space */
2700 if (lp_minprintspace(snum
)) {
2701 minspace
= lp_minprintspace(snum
);
2702 ret
= sys_fsusage(lp_pathname(talloc_tos(), snum
), &dspace
, &dsize
);
2703 if (ret
== 0 && dspace
< 2*minspace
) {
2704 DEBUG(3, ("print_job_checks: "
2705 "disk space check failed.\n"));
2706 return WERR_NO_SPOOL_SPACE
;
2710 /* for autoloaded printers, check that the printcap entry still exists */
2711 if (lp_autoloaded(snum
) && !pcap_printername_ok(sharename
)) {
2712 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2714 return WERR_ACCESS_DENIED
;
2717 /* Insure the maximum queue size is not violated */
2718 *njobs
= print_queue_length(msg_ctx
, snum
, NULL
);
2719 if (*njobs
> lp_maxprintjobs(snum
)) {
2720 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2721 "larger than max printjobs per queue (%d).\n",
2722 sharename
, *njobs
, lp_maxprintjobs(snum
)));
2723 return WERR_NO_SPOOL_SPACE
;
2729 /***************************************************************************
2731 ***************************************************************************/
2733 static WERROR
print_job_spool_file(int snum
, uint32_t jobid
,
2734 const char *output_file
,
2735 struct printjob
*pjob
)
2742 /* if this file is within the printer path, it means that smbd
2743 * is spooling it and will pass us control when it is finished.
2744 * Verify that the file name is ok, within path, and it is
2745 * already already there */
2747 path
= lp_pathname(talloc_tos(), snum
);
2749 if (strncmp(output_file
, path
, len
) == 0 &&
2750 (output_file
[len
- 1] == '/' || output_file
[len
] == '/')) {
2752 /* verify path is not too long */
2753 if (strlen(output_file
) >= sizeof(pjob
->filename
)) {
2754 return WERR_INVALID_NAME
;
2757 /* verify that the file exists */
2758 if (sys_stat(output_file
, &st
, false) != 0) {
2759 return WERR_INVALID_NAME
;
2762 fstrcpy(pjob
->filename
, output_file
);
2764 DEBUG(3, ("print_job_spool_file:"
2765 "External spooling activated"));
2767 /* we do not open the file until spooling is done */
2769 pjob
->status
= PJOB_SMBD_SPOOLING
;
2775 slprintf(pjob
->filename
, sizeof(pjob
->filename
)-1,
2776 "%s/%sXXXXXX", lp_pathname(talloc_tos(), snum
),
2777 PRINT_SPOOL_PREFIX
);
2778 pjob
->fd
= mkstemp(pjob
->filename
);
2780 if (pjob
->fd
== -1) {
2781 werr
= map_werror_from_unix(errno
);
2782 if (W_ERROR_EQUAL(werr
, WERR_ACCESS_DENIED
)) {
2783 /* Common setup error, force a report. */
2784 DEBUG(0, ("print_job_spool_file: "
2785 "insufficient permissions to open spool "
2786 "file %s.\n", pjob
->filename
));
2788 /* Normal case, report at level 3 and above. */
2789 DEBUG(3, ("print_job_spool_file: "
2790 "can't open spool file %s\n",
2799 /***************************************************************************
2800 Start spooling a job - return the jobid.
2801 ***************************************************************************/
2803 WERROR
print_job_start(const struct auth_session_info
*server_info
,
2804 struct messaging_context
*msg_ctx
,
2805 const char *clientmachine
,
2806 int snum
, const char *docname
, const char *filename
,
2807 struct spoolss_DeviceMode
*devmode
, uint32_t *_jobid
)
2811 struct printjob pjob
;
2812 const char *sharename
= lp_const_servicename(snum
);
2813 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2818 return WERR_INTERNAL_DB_CORRUPTION
;
2821 path
= lp_pathname(talloc_tos(), snum
);
2823 werr
= print_job_checks(server_info
, msg_ctx
, snum
, &njobs
);
2824 if (!W_ERROR_IS_OK(werr
)) {
2825 release_print_db(pdb
);
2829 DEBUG(10, ("print_job_start: "
2830 "Queue %s number of jobs (%d), max printjobs = %d\n",
2831 sharename
, njobs
, lp_maxprintjobs(snum
)));
2833 werr
= allocate_print_jobid(pdb
, snum
, sharename
, &jobid
);
2834 if (!W_ERROR_IS_OK(werr
)) {
2838 /* create the database entry */
2842 pjob
.pid
= getpid();
2846 pjob
.starttime
= time(NULL
);
2847 pjob
.status
= LPQ_SPOOLING
;
2849 pjob
.spooled
= False
;
2851 pjob
.devmode
= devmode
;
2853 fstrcpy(pjob
.jobname
, docname
);
2855 fstrcpy(pjob
.clientmachine
, clientmachine
);
2857 fstrcpy(pjob
.user
, lp_printjob_username(snum
));
2858 standard_sub_advanced(sharename
, server_info
->unix_info
->sanitized_username
,
2859 path
, server_info
->unix_token
->gid
,
2860 server_info
->unix_info
->sanitized_username
,
2861 server_info
->info
->domain_name
,
2862 pjob
.user
, sizeof(pjob
.user
));
2864 fstrcpy(pjob
.queuename
, lp_const_servicename(snum
));
2866 /* we have a job entry - now create the spool file */
2867 werr
= print_job_spool_file(snum
, jobid
, filename
, &pjob
);
2868 if (!W_ERROR_IS_OK(werr
)) {
2872 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, &pjob
);
2874 /* Update the 'jobs added' entry used by print_queue_status. */
2875 add_to_jobs_added(pdb
, jobid
);
2877 /* Ensure we keep a rough count of the number of total jobs... */
2878 tdb_change_int32_atomic(pdb
->tdb
, "INFO/total_jobs", &njobs
, 1);
2880 release_print_db(pdb
);
2887 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
2890 release_print_db(pdb
);
2892 DEBUG(3, ("print_job_start: returning fail. "
2893 "Error = %s\n", win_errstr(werr
)));
2897 /****************************************************************************
2898 Update the number of pages spooled to jobid
2899 ****************************************************************************/
2901 void print_job_endpage(struct messaging_context
*msg_ctx
,
2902 int snum
, uint32 jobid
)
2904 const char* sharename
= lp_const_servicename(snum
);
2905 struct printjob
*pjob
;
2906 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2907 if (tmp_ctx
== NULL
) {
2911 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2915 /* don't allow another process to get this info - it is meaningless */
2916 if (pjob
->pid
!= getpid()) {
2921 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, pjob
);
2923 talloc_free(tmp_ctx
);
2926 /****************************************************************************
2927 Print a file - called on closing the file. This spools the job.
2928 If normal close is false then we're tearing down the jobs - treat as an
2930 ****************************************************************************/
2932 NTSTATUS
print_job_end(struct messaging_context
*msg_ctx
, int snum
,
2933 uint32 jobid
, enum file_close_type close_type
)
2935 const char* sharename
= lp_const_servicename(snum
);
2936 struct printjob
*pjob
;
2938 SMB_STRUCT_STAT sbuf
;
2939 struct printif
*current_printif
= get_printer_fns(snum
);
2940 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
2942 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2943 if (tmp_ctx
== NULL
) {
2944 return NT_STATUS_NO_MEMORY
;
2947 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2949 status
= NT_STATUS_PRINT_CANCELLED
;
2953 if (pjob
->spooled
|| pjob
->pid
!= getpid()) {
2954 status
= NT_STATUS_ACCESS_DENIED
;
2958 if (close_type
== NORMAL_CLOSE
|| close_type
== SHUTDOWN_CLOSE
) {
2959 if (pjob
->status
== PJOB_SMBD_SPOOLING
) {
2960 /* take over the file now, smbd is done */
2961 if (sys_stat(pjob
->filename
, &sbuf
, false) != 0) {
2962 status
= map_nt_error_from_unix(errno
);
2963 DEBUG(3, ("print_job_end: "
2964 "stat file failed for jobid %d\n",
2969 pjob
->status
= LPQ_SPOOLING
;
2973 if ((sys_fstat(pjob
->fd
, &sbuf
, false) != 0)) {
2974 status
= map_nt_error_from_unix(errno
);
2976 DEBUG(3, ("print_job_end: "
2977 "stat file failed for jobid %d\n",
2985 pjob
->size
= sbuf
.st_ex_size
;
2989 * Not a normal close, something has gone wrong. Cleanup.
2991 if (pjob
->fd
!= -1) {
2997 /* Technically, this is not quite right. If the printer has a separator
2998 * page turned on, the NT spooler prints the separator page even if the
2999 * print job is 0 bytes. 010215 JRR */
3000 if (pjob
->size
== 0 || pjob
->status
== LPQ_DELETING
) {
3001 /* don't bother spooling empty files or something being deleted. */
3002 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
3003 pjob
->filename
, pjob
->size
? "deleted" : "zero length" ));
3004 unlink(pjob
->filename
);
3005 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
3006 return NT_STATUS_OK
;
3009 /* don't strip out characters like '$' from the printername */
3010 lpq_cmd
= talloc_string_sub2(tmp_ctx
,
3011 lp_lpqcommand(talloc_tos(), snum
),
3013 lp_printername(talloc_tos(), snum
),
3014 false, false, false);
3015 if (lpq_cmd
== NULL
) {
3016 status
= NT_STATUS_PRINT_CANCELLED
;
3019 lpq_cmd
= talloc_sub_advanced(tmp_ctx
,
3020 lp_servicename(talloc_tos(), snum
),
3021 current_user_info
.unix_name
,
3023 current_user
.ut
.gid
,
3024 get_current_username(),
3025 current_user_info
.domain
,
3027 if (lpq_cmd
== NULL
) {
3028 status
= NT_STATUS_PRINT_CANCELLED
;
3032 ret
= (*(current_printif
->job_submit
))(snum
, pjob
,
3033 current_printif
->type
, lpq_cmd
);
3035 status
= NT_STATUS_PRINT_CANCELLED
;
3039 /* The print job has been successfully handed over to the back-end */
3041 pjob
->spooled
= True
;
3042 pjob
->status
= LPQ_QUEUED
;
3043 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, pjob
);
3045 /* make sure the database is up to date */
3046 if (print_cache_expired(lp_const_servicename(snum
), True
))
3047 print_queue_update(msg_ctx
, snum
, False
);
3049 return NT_STATUS_OK
;
3053 /* The print job was not successfully started. Cleanup */
3054 /* Still need to add proper error return propagation! 010122:JRR */
3056 unlink(pjob
->filename
);
3057 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
3059 talloc_free(tmp_ctx
);
3063 /****************************************************************************
3064 Get a snapshot of jobs in the system without traversing.
3065 ****************************************************************************/
3067 static bool get_stored_queue_info(struct messaging_context
*msg_ctx
,
3068 struct tdb_print_db
*pdb
, int snum
,
3069 int *pcount
, print_queue_struct
**ppqueue
)
3071 TDB_DATA data
, cgdata
, jcdata
;
3072 print_queue_struct
*queue
= NULL
;
3074 uint32 extra_count
= 0;
3075 uint32_t changed_count
= 0;
3076 int total_count
= 0;
3079 int max_reported_jobs
= lp_max_reported_jobs(snum
);
3081 const char* sharename
= lp_servicename(talloc_tos(), snum
);
3082 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
3083 if (tmp_ctx
== NULL
) {
3087 /* make sure the database is up to date */
3088 if (print_cache_expired(lp_const_servicename(snum
), True
))
3089 print_queue_update(msg_ctx
, snum
, False
);
3095 ZERO_STRUCT(cgdata
);
3097 /* Get the stored queue data. */
3098 data
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data("INFO/linear_queue_array"));
3100 if (data
.dptr
&& data
.dsize
>= sizeof(qcount
))
3101 len
+= tdb_unpack(data
.dptr
+ len
, data
.dsize
- len
, "d", &qcount
);
3103 /* Get the added jobs list. */
3104 cgdata
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data("INFO/jobs_added"));
3105 if (cgdata
.dptr
!= NULL
&& (cgdata
.dsize
% 4 == 0))
3106 extra_count
= cgdata
.dsize
/4;
3108 /* Get the changed jobs list. */
3109 jcdata
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data("INFO/jobs_changed"));
3110 if (jcdata
.dptr
!= NULL
&& (jcdata
.dsize
% 4 == 0))
3111 changed_count
= jcdata
.dsize
/ 4;
3113 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount
, (unsigned int)extra_count
));
3115 /* Allocate the queue size. */
3116 if (qcount
== 0 && extra_count
== 0)
3119 if ((queue
= SMB_MALLOC_ARRAY(print_queue_struct
, qcount
+ extra_count
)) == NULL
)
3122 /* Retrieve the linearised queue data. */
3124 for(i
= 0; i
< qcount
; i
++) {
3125 uint32 qjob
, qsize
, qpage_count
, qstatus
, qpriority
, qtime
;
3126 len
+= tdb_unpack(data
.dptr
+ len
, data
.dsize
- len
, "ddddddff",
3135 queue
[i
].sysjob
= qjob
;
3136 queue
[i
].size
= qsize
;
3137 queue
[i
].page_count
= qpage_count
;
3138 queue
[i
].status
= qstatus
;
3139 queue
[i
].priority
= qpriority
;
3140 queue
[i
].time
= qtime
;
3143 total_count
= qcount
;
3145 /* Add new jobids to the queue. */
3146 for (i
= 0; i
< extra_count
; i
++) {
3148 struct printjob
*pjob
;
3150 jobid
= IVAL(cgdata
.dptr
, i
*4);
3151 DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid
));
3152 pjob
= print_job_find(tmp_ctx
, lp_const_servicename(snum
), jobid
);
3154 DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid
));
3155 remove_from_jobs_added(sharename
, jobid
);
3159 queue
[total_count
].sysjob
= pjob
->sysjob
;
3160 queue
[total_count
].size
= pjob
->size
;
3161 queue
[total_count
].page_count
= pjob
->page_count
;
3162 queue
[total_count
].status
= pjob
->status
;
3163 queue
[total_count
].priority
= 1;
3164 queue
[total_count
].time
= pjob
->starttime
;
3165 fstrcpy(queue
[total_count
].fs_user
, pjob
->user
);
3166 fstrcpy(queue
[total_count
].fs_file
, pjob
->jobname
);
3171 /* Update the changed jobids. */
3172 for (i
= 0; i
< changed_count
; i
++) {
3173 uint32_t jobid
= IVAL(jcdata
.dptr
, i
* 4);
3174 struct printjob
*pjob
;
3178 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
3180 DEBUG(5,("get_stored_queue_info: failed to find "
3181 "changed job = %u\n",
3182 (unsigned int)jobid
));
3183 remove_from_jobs_changed(sharename
, jobid
);
3187 for (j
= 0; j
< total_count
; j
++) {
3188 if (queue
[j
].sysjob
== pjob
->sysjob
) {
3195 DEBUG(5,("get_stored_queue_info: changed job: %u\n",
3196 (unsigned int)jobid
));
3198 queue
[j
].sysjob
= pjob
->sysjob
;
3199 queue
[j
].size
= pjob
->size
;
3200 queue
[j
].page_count
= pjob
->page_count
;
3201 queue
[j
].status
= pjob
->status
;
3202 queue
[j
].priority
= 1;
3203 queue
[j
].time
= pjob
->starttime
;
3204 fstrcpy(queue
[j
].fs_user
, pjob
->user
);
3205 fstrcpy(queue
[j
].fs_file
, pjob
->jobname
);
3208 DEBUG(5,("updated queue[%u], jobid: %u, sysjob: %u, "
3210 (unsigned int)j
, (unsigned int)jobid
,
3211 (unsigned int)queue
[j
].sysjob
, pjob
->jobname
));
3214 remove_from_jobs_changed(sharename
, jobid
);
3217 /* Sort the queue by submission time otherwise they are displayed
3220 TYPESAFE_QSORT(queue
, total_count
, printjob_comp
);
3222 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count
));
3224 if (max_reported_jobs
&& total_count
> max_reported_jobs
)
3225 total_count
= max_reported_jobs
;
3228 *pcount
= total_count
;
3234 SAFE_FREE(data
.dptr
);
3235 SAFE_FREE(cgdata
.dptr
);
3236 talloc_free(tmp_ctx
);
3240 /****************************************************************************
3241 Get a printer queue listing.
3242 set queue = NULL and status = NULL if you just want to update the cache
3243 ****************************************************************************/
3245 int print_queue_status(struct messaging_context
*msg_ctx
, int snum
,
3246 print_queue_struct
**ppqueue
,
3247 print_status_struct
*status
)
3251 const char *sharename
;
3252 struct tdb_print_db
*pdb
;
3255 /* make sure the database is up to date */
3257 if (print_cache_expired(lp_const_servicename(snum
), True
))
3258 print_queue_update(msg_ctx
, snum
, False
);
3260 /* return if we are done */
3261 if ( !ppqueue
|| !status
)
3265 sharename
= lp_const_servicename(snum
);
3266 pdb
= get_print_db_byname(sharename
);
3272 * Fetch the queue status. We must do this first, as there may
3273 * be no jobs in the queue.
3276 ZERO_STRUCTP(status
);
3277 slprintf(keystr
, sizeof(keystr
)-1, "STATUS/%s", sharename
);
3278 key
= string_tdb_data(keystr
);
3280 data
= tdb_fetch_compat(pdb
->tdb
, key
);
3282 if (data
.dsize
== sizeof(*status
)) {
3283 /* this memcpy is ok since the status struct was
3284 not packed before storing it in the tdb */
3285 memcpy(status
, data
.dptr
, sizeof(*status
));
3287 SAFE_FREE(data
.dptr
);
3291 * Now, fetch the print queue information. We first count the number
3292 * of entries, and then only retrieve the queue if necessary.
3295 if (!get_stored_queue_info(msg_ctx
, pdb
, snum
, &count
, ppqueue
)) {
3296 release_print_db(pdb
);
3300 release_print_db(pdb
);
3304 /****************************************************************************
3306 ****************************************************************************/
3308 WERROR
print_queue_pause(const struct auth_session_info
*server_info
,
3309 struct messaging_context
*msg_ctx
, int snum
)
3312 struct printif
*current_printif
= get_printer_fns( snum
);
3314 if (!print_access_check(server_info
, msg_ctx
, snum
,
3315 PRINTER_ACCESS_ADMINISTER
)) {
3316 return WERR_ACCESS_DENIED
;
3322 ret
= (*(current_printif
->queue_pause
))(snum
);
3327 return WERR_INVALID_PARAM
;
3330 /* force update the database */
3331 print_cache_flush(lp_const_servicename(snum
));
3333 /* Send a printer notify message */
3335 notify_printer_status(server_event_context(), msg_ctx
, snum
,
3336 PRINTER_STATUS_PAUSED
);
3341 /****************************************************************************
3343 ****************************************************************************/
3345 WERROR
print_queue_resume(const struct auth_session_info
*server_info
,
3346 struct messaging_context
*msg_ctx
, int snum
)
3349 struct printif
*current_printif
= get_printer_fns( snum
);
3351 if (!print_access_check(server_info
, msg_ctx
, snum
,
3352 PRINTER_ACCESS_ADMINISTER
)) {
3353 return WERR_ACCESS_DENIED
;
3358 ret
= (*(current_printif
->queue_resume
))(snum
);
3363 return WERR_INVALID_PARAM
;
3366 /* make sure the database is up to date */
3367 if (print_cache_expired(lp_const_servicename(snum
), True
))
3368 print_queue_update(msg_ctx
, snum
, True
);
3370 /* Send a printer notify message */
3372 notify_printer_status(server_event_context(), msg_ctx
, snum
,
3378 /****************************************************************************
3379 Purge a queue - implemented by deleting all jobs that we can delete.
3380 ****************************************************************************/
3382 WERROR
print_queue_purge(const struct auth_session_info
*server_info
,
3383 struct messaging_context
*msg_ctx
, int snum
)
3385 print_queue_struct
*queue
;
3386 print_status_struct status
;
3390 /* Force and update so the count is accurate (i.e. not a cached count) */
3391 print_queue_update(msg_ctx
, snum
, True
);
3393 can_job_admin
= print_access_check(server_info
,
3396 JOB_ACCESS_ADMINISTER
);
3397 njobs
= print_queue_status(msg_ctx
, snum
, &queue
, &status
);
3399 if ( can_job_admin
)
3402 for (i
= 0; i
< njobs
; i
++) {
3403 struct tdb_print_db
*pdb
;
3406 pdb
= get_print_db_byname(lp_const_servicename(snum
));
3408 DEBUG(1, ("failed to find printdb for %s\n",
3409 lp_const_servicename(snum
)));
3412 jobid
= sysjob_to_jobid_pdb(pdb
, queue
[i
].sysjob
);
3413 if (jobid
== (uint32_t)-1) {
3414 DEBUG(2, ("jobid for system job %d not found\n",
3416 continue; /* unix job */
3418 owner
= is_owner(server_info
, lp_const_servicename(snum
),
3421 if (owner
|| can_job_admin
) {
3422 print_job_delete1(server_event_context(), msg_ctx
,
3427 if ( can_job_admin
)
3430 /* update the cache */
3431 print_queue_update(msg_ctx
, snum
, True
);