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();
202 if (!printer_list_parent_init()) {
206 ok
= directory_create_or_exist(cache_path("printing"), geteuid(), 0755);
211 unlink(cache_path("printing.tdb"));
213 /* handle a Samba upgrade */
215 for (snum
= 0; snum
< services
; snum
++) {
216 struct tdb_print_db
*pdb
;
217 if (!lp_print_ok(snum
))
220 pdb
= get_print_db_byname(lp_const_servicename(snum
));
223 if (tdb_lock_bystring(pdb
->tdb
, sversion
) != 0) {
224 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum
) ));
225 release_print_db(pdb
);
228 if (tdb_fetch_int32(pdb
->tdb
, sversion
) != PRINT_DATABASE_VERSION
) {
229 tdb_wipe_all(pdb
->tdb
);
230 tdb_store_int32(pdb
->tdb
, sversion
, PRINT_DATABASE_VERSION
);
232 tdb_unlock_bystring(pdb
->tdb
, sversion
);
233 release_print_db(pdb
);
236 close_all_print_db(); /* Don't leave any open. */
238 /* do NT print initialization... */
239 return nt_printing_init(msg_ctx
);
242 /****************************************************************************
243 Shut down printing backend. Called once at shutdown to close the tdb.
244 ****************************************************************************/
246 void printing_end(void)
248 close_all_print_db(); /* Don't leave any open. */
251 /****************************************************************************
252 Retrieve the set of printing functions for a given service. This allows
253 us to set the printer function table based on the value of the 'printing'
256 Use the generic interface as the default and only use cups interface only
257 when asked for (and only when supported)
258 ****************************************************************************/
260 static struct printif
*get_printer_fns_from_type( enum printing_types type
)
262 struct printif
*printer_fns
= &generic_printif
;
265 if ( type
== PRINT_CUPS
) {
266 printer_fns
= &cups_printif
;
268 #endif /* HAVE_CUPS */
271 if ( type
== PRINT_IPRINT
) {
272 printer_fns
= &iprint_printif
;
274 #endif /* HAVE_IPRINT */
276 printer_fns
->type
= type
;
281 static struct printif
*get_printer_fns( int snum
)
283 return get_printer_fns_from_type( (enum printing_types
)lp_printing(snum
) );
287 /****************************************************************************
288 Useful function to generate a tdb key.
289 ****************************************************************************/
291 static TDB_DATA
print_key(uint32 jobid
, uint32
*tmp
)
295 SIVAL(tmp
, 0, jobid
);
296 ret
.dptr
= (uint8
*)tmp
;
297 ret
.dsize
= sizeof(*tmp
);
301 /****************************************************************************
302 Pack the devicemode to store it in a tdb.
303 ****************************************************************************/
304 static int pack_devicemode(struct spoolss_DeviceMode
*devmode
, uint8
*buf
, int buflen
)
306 enum ndr_err_code ndr_err
;
311 ndr_err
= ndr_push_struct_blob(&blob
, talloc_tos(),
313 (ndr_push_flags_fn_t
)
314 ndr_push_spoolss_DeviceMode
);
315 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
316 DEBUG(10, ("pack_devicemode: "
317 "error encoding spoolss_DeviceMode\n"));
324 len
= tdb_pack(buf
, buflen
, "B", blob
.length
, blob
.data
);
327 DEBUG(8, ("Packed devicemode [%s]\n", devmode
->formname
));
334 /****************************************************************************
335 Unpack the devicemode to store it in a tdb.
336 ****************************************************************************/
337 static int unpack_devicemode(TALLOC_CTX
*mem_ctx
,
338 const uint8
*buf
, int buflen
,
339 struct spoolss_DeviceMode
**devmode
)
341 struct spoolss_DeviceMode
*dm
;
342 enum ndr_err_code ndr_err
;
350 len
= tdb_unpack(buf
, buflen
, "B", &data_len
, &data
);
355 dm
= talloc_zero(mem_ctx
, struct spoolss_DeviceMode
);
360 blob
= data_blob_const(data
, data_len
);
362 ndr_err
= ndr_pull_struct_blob(&blob
, dm
, dm
,
363 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_DeviceMode
);
364 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
365 DEBUG(10, ("unpack_devicemode: "
366 "error parsing spoolss_DeviceMode\n"));
370 DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
371 dm
->devicename
, dm
->formname
));
372 if (dm
->driverextra_data
.data
) {
373 DEBUG(8, ("with a private section of %d bytes\n",
374 dm
->__driverextra_length
));
384 /***********************************************************************
385 unpack a pjob from a tdb buffer
386 ***********************************************************************/
388 static int unpack_pjob(TALLOC_CTX
*mem_ctx
, uint8
*buf
, int buflen
,
389 struct printjob
*pjob
)
393 uint32 pjpid
, pjjobid
, pjsysjob
, pjfd
, pjstarttime
, pjstatus
;
394 uint32 pjsize
, pjpage_count
, pjspooled
, pjsmbjob
;
400 len
+= tdb_unpack(buf
+len
, buflen
-len
, "ddddddddddfffff",
421 used
= unpack_devicemode(mem_ctx
, buf
+len
, buflen
-len
, &pjob
->devmode
);
429 pjob
->jobid
= pjjobid
;
430 pjob
->sysjob
= pjsysjob
;
432 pjob
->starttime
= pjstarttime
;
433 pjob
->status
= pjstatus
;
435 pjob
->page_count
= pjpage_count
;
436 pjob
->spooled
= pjspooled
;
437 pjob
->smbjob
= pjsmbjob
;
443 /****************************************************************************
444 Useful function to find a print job in the database.
445 ****************************************************************************/
447 static struct printjob
*print_job_find(TALLOC_CTX
*mem_ctx
,
448 const char *sharename
,
451 struct printjob
*pjob
;
454 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
456 DEBUG(10,("print_job_find: looking up job %u for share %s\n",
457 (unsigned int)jobid
, sharename
));
463 ret
= tdb_fetch_compat(pdb
->tdb
, print_key(jobid
, &tmp
));
464 release_print_db(pdb
);
467 DEBUG(10, ("print_job_find: failed to find jobid %u.\n",
472 pjob
= talloc_zero(mem_ctx
, struct printjob
);
477 if (unpack_pjob(mem_ctx
, ret
.dptr
, ret
.dsize
, pjob
) == -1) {
478 DEBUG(10, ("failed to unpack jobid %u.\n", jobid
));
484 DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
485 pjob
->sysjob
, jobid
));
486 SMB_ASSERT(pjob
->jobid
== jobid
);
493 struct job_traverse_state
{
498 /* find spoolss jobid based on sysjob */
499 static int sysjob_to_jobid_traverse_fn(TDB_CONTEXT
*the_tdb
, TDB_DATA key
,
500 TDB_DATA data
, void *private_data
)
502 struct printjob
*pjob
;
503 struct job_traverse_state
*state
=
504 (struct job_traverse_state
*)private_data
;
506 if (!data
.dptr
|| data
.dsize
== 0)
509 pjob
= (struct printjob
*)data
.dptr
;
510 if (key
.dsize
!= sizeof(uint32
))
513 if (state
->sysjob
== pjob
->sysjob
) {
514 state
->jobid
= pjob
->jobid
;
521 uint32
sysjob_to_jobid_pdb(struct tdb_print_db
*pdb
, int sysjob
)
523 struct job_traverse_state state
;
525 state
.sysjob
= sysjob
;
526 state
.jobid
= (uint32_t)-1;
528 tdb_traverse(pdb
->tdb
, sysjob_to_jobid_traverse_fn
, &state
);
533 /****************************************************************************
534 This is a *horribly expensive call as we have to iterate through all the
535 current printer tdb's. Don't do this often ! JRA.
536 ****************************************************************************/
538 uint32
sysjob_to_jobid(int unix_jobid
)
540 int services
= lp_numservices();
542 struct job_traverse_state state
;
544 state
.sysjob
= unix_jobid
;
545 state
.jobid
= (uint32_t)-1;
547 for (snum
= 0; snum
< services
; snum
++) {
548 struct tdb_print_db
*pdb
;
549 if (!lp_print_ok(snum
))
551 pdb
= get_print_db_byname(lp_const_servicename(snum
));
555 tdb_traverse(pdb
->tdb
, sysjob_to_jobid_traverse_fn
, &state
);
556 release_print_db(pdb
);
557 if (state
.jobid
!= (uint32_t)-1)
563 /* find sysjob based on spoolss jobid */
564 static int jobid_to_sysjob_traverse_fn(TDB_CONTEXT
*the_tdb
, TDB_DATA key
,
565 TDB_DATA data
, void *private_data
)
567 struct printjob
*pjob
;
568 struct job_traverse_state
*state
=
569 (struct job_traverse_state
*)private_data
;
571 if (!data
.dptr
|| data
.dsize
== 0)
574 pjob
= (struct printjob
*)data
.dptr
;
575 if (key
.dsize
!= sizeof(uint32_t))
578 if (state
->jobid
== pjob
->jobid
) {
579 state
->sysjob
= pjob
->sysjob
;
586 int jobid_to_sysjob_pdb(struct tdb_print_db
*pdb
, uint32_t jobid
)
588 struct job_traverse_state state
;
593 tdb_traverse(pdb
->tdb
, jobid_to_sysjob_traverse_fn
, &state
);
598 /****************************************************************************
599 Send notifications based on what has changed after a pjob_store.
600 ****************************************************************************/
602 static const struct {
604 uint32_t spoolss_status
;
605 } lpq_to_spoolss_status_map
[] = {
606 { LPQ_QUEUED
, JOB_STATUS_QUEUED
},
607 { LPQ_PAUSED
, JOB_STATUS_PAUSED
},
608 { LPQ_SPOOLING
, JOB_STATUS_SPOOLING
},
609 { LPQ_PRINTING
, JOB_STATUS_PRINTING
},
610 { LPQ_DELETING
, JOB_STATUS_DELETING
},
611 { LPQ_OFFLINE
, JOB_STATUS_OFFLINE
},
612 { LPQ_PAPEROUT
, JOB_STATUS_PAPEROUT
},
613 { LPQ_PRINTED
, JOB_STATUS_PRINTED
},
614 { LPQ_DELETED
, JOB_STATUS_DELETED
},
615 { LPQ_BLOCKED
, JOB_STATUS_BLOCKED_DEVQ
},
616 { LPQ_USER_INTERVENTION
, JOB_STATUS_USER_INTERVENTION
},
620 /* Convert a lpq status value stored in printing.tdb into the
621 appropriate win32 API constant. */
623 static uint32
map_to_spoolss_status(uint32 lpq_status
)
627 while (lpq_to_spoolss_status_map
[i
].lpq_status
!= -1) {
628 if (lpq_to_spoolss_status_map
[i
].lpq_status
== lpq_status
)
629 return lpq_to_spoolss_status_map
[i
].spoolss_status
;
636 /***************************************************************************
637 Append a jobid to the 'jobs changed' list.
638 ***************************************************************************/
640 static bool add_to_jobs_changed(struct tdb_print_db
*pdb
, uint32_t jobid
)
643 uint32_t store_jobid
;
645 SIVAL(&store_jobid
, 0, jobid
);
646 data
.dptr
= (uint8
*) &store_jobid
;
649 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid
));
651 return (tdb_append(pdb
->tdb
, string_tdb_data("INFO/jobs_changed"),
655 /***************************************************************************
656 Remove a jobid from the 'jobs changed' list.
657 ***************************************************************************/
659 static bool remove_from_jobs_changed(const char* sharename
, uint32_t jobid
)
661 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
665 bool gotlock
= False
;
673 key
= string_tdb_data("INFO/jobs_changed");
675 if (tdb_chainlock_with_timeout(pdb
->tdb
, key
, 5) != 0)
680 data
= tdb_fetch_compat(pdb
->tdb
, key
);
682 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0))
685 job_count
= data
.dsize
/ 4;
686 for (i
= 0; i
< job_count
; i
++) {
689 ch_jobid
= IVAL(data
.dptr
, i
*4);
690 if (ch_jobid
== jobid
) {
691 if (i
< job_count
-1 )
692 memmove(data
.dptr
+ (i
*4), data
.dptr
+ (i
*4) + 4, (job_count
- i
- 1)*4 );
694 if (tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
) != 0)
704 tdb_chainunlock(pdb
->tdb
, key
);
705 SAFE_FREE(data
.dptr
);
706 release_print_db(pdb
);
708 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid
));
710 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid
));
714 static void pjob_store_notify(struct tevent_context
*ev
,
715 struct messaging_context
*msg_ctx
,
716 const char* sharename
, uint32 jobid
,
717 struct printjob
*old_data
,
718 struct printjob
*new_data
,
721 bool new_job
= false;
722 bool changed
= false;
724 if (old_data
== NULL
) {
728 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
729 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
730 time first or else we'll end up with potential alignment
731 errors. I don't think the systemtime should be spooled as
732 a string, but this gets us around that error.
733 --jerry (i'll feel dirty for this) */
736 notify_job_submitted(ev
, msg_ctx
,
737 sharename
, jobid
, new_data
->starttime
);
738 notify_job_username(ev
, msg_ctx
,
739 sharename
, jobid
, new_data
->user
);
740 notify_job_name(ev
, msg_ctx
,
741 sharename
, jobid
, new_data
->jobname
);
742 notify_job_status(ev
, msg_ctx
,
743 sharename
, jobid
, map_to_spoolss_status(new_data
->status
));
744 notify_job_total_bytes(ev
, msg_ctx
,
745 sharename
, jobid
, new_data
->size
);
746 notify_job_total_pages(ev
, msg_ctx
,
747 sharename
, jobid
, new_data
->page_count
);
749 if (!strequal(old_data
->jobname
, new_data
->jobname
)) {
750 notify_job_name(ev
, msg_ctx
, sharename
,
751 jobid
, new_data
->jobname
);
755 if (old_data
->status
!= new_data
->status
) {
756 notify_job_status(ev
, msg_ctx
,
758 map_to_spoolss_status(new_data
->status
));
761 if (old_data
->size
!= new_data
->size
) {
762 notify_job_total_bytes(ev
, msg_ctx
,
763 sharename
, jobid
, new_data
->size
);
766 if (old_data
->page_count
!= new_data
->page_count
) {
767 notify_job_total_pages(ev
, msg_ctx
,
769 new_data
->page_count
);
776 /****************************************************************************
777 Store a job structure back to the database.
778 ****************************************************************************/
780 static bool pjob_store(struct tevent_context
*ev
,
781 struct messaging_context
*msg_ctx
,
782 const char* sharename
, uint32 jobid
,
783 struct printjob
*pjob
)
786 TDB_DATA old_data
, new_data
;
788 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
790 int len
, newlen
, buflen
;
798 old_data
= tdb_fetch_compat(pdb
->tdb
, print_key(jobid
, &tmp
));
800 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
807 len
+= tdb_pack(buf
+len
, buflen
-len
, "ddddddddddfffff",
810 (uint32
)pjob
->sysjob
,
812 (uint32
)pjob
->starttime
,
813 (uint32
)pjob
->status
,
815 (uint32
)pjob
->page_count
,
816 (uint32
)pjob
->spooled
,
817 (uint32
)pjob
->smbjob
,
824 len
+= pack_devicemode(pjob
->devmode
, buf
+len
, buflen
-len
);
827 buf
= (uint8
*)SMB_REALLOC(buf
, len
);
829 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
834 } while ( buflen
!= len
);
840 new_data
.dsize
= len
;
841 ret
= (tdb_store(pdb
->tdb
, print_key(jobid
, &tmp
), new_data
,
844 /* Send notify updates for what has changed */
847 bool changed
= false;
848 struct printjob old_pjob
;
850 if (old_data
.dsize
) {
851 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
855 len
= unpack_pjob(tmp_ctx
, old_data
.dptr
,
856 old_data
.dsize
, &old_pjob
);
858 pjob_store_notify(ev
,
860 sharename
, jobid
, &old_pjob
,
864 add_to_jobs_changed(pdb
, jobid
);
867 talloc_free(tmp_ctx
);
871 pjob_store_notify(ev
, msg_ctx
,
872 sharename
, jobid
, NULL
, pjob
,
878 release_print_db(pdb
);
879 SAFE_FREE( old_data
.dptr
);
885 /****************************************************************************
886 Remove a job structure from the database.
887 ****************************************************************************/
889 static void pjob_delete(struct tevent_context
*ev
,
890 struct messaging_context
*msg_ctx
,
891 const char* sharename
, uint32 jobid
)
894 struct printjob
*pjob
;
895 uint32 job_status
= 0;
896 struct tdb_print_db
*pdb
;
897 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
898 if (tmp_ctx
== NULL
) {
902 pdb
= get_print_db_byname(sharename
);
907 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
909 DEBUG(5, ("we were asked to delete nonexistent job %u\n",
914 /* We must cycle through JOB_STATUS_DELETING and
915 JOB_STATUS_DELETED for the port monitor to delete the job
918 job_status
= JOB_STATUS_DELETING
|JOB_STATUS_DELETED
;
919 notify_job_status(ev
, msg_ctx
, sharename
, jobid
, job_status
);
921 /* Remove from printing.tdb */
923 tdb_delete(pdb
->tdb
, print_key(jobid
, &tmp
));
924 remove_from_jobs_added(sharename
, jobid
);
925 rap_jobid_delete(sharename
, jobid
);
927 release_print_db(pdb
);
929 talloc_free(tmp_ctx
);
932 /****************************************************************************
933 List a unix job in the print database.
934 ****************************************************************************/
936 static void print_unix_job(struct tevent_context
*ev
,
937 struct messaging_context
*msg_ctx
,
938 const char *sharename
, print_queue_struct
*q
,
941 struct printjob pj
, *old_pj
;
942 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
943 if (tmp_ctx
== NULL
) {
947 if (jobid
== (uint32
)-1) {
948 jobid
= q
->sysjob
+ UNIX_JOB_START
;
951 /* Preserve the timestamp on an existing unix print job */
953 old_pj
= print_job_find(tmp_ctx
, sharename
, jobid
);
959 pj
.sysjob
= q
->sysjob
;
961 pj
.starttime
= old_pj
? old_pj
->starttime
: q
->time
;
962 pj
.status
= q
->status
;
965 fstrcpy(pj
.filename
, old_pj
? old_pj
->filename
: "");
966 if (jobid
< UNIX_JOB_START
) {
968 fstrcpy(pj
.jobname
, old_pj
? old_pj
->jobname
: "Remote Downlevel Document");
971 fstrcpy(pj
.jobname
, old_pj
? old_pj
->jobname
: q
->fs_file
);
973 fstrcpy(pj
.user
, old_pj
? old_pj
->user
: q
->fs_user
);
974 fstrcpy(pj
.queuename
, old_pj
? old_pj
->queuename
: sharename
);
976 pjob_store(ev
, msg_ctx
, sharename
, jobid
, &pj
);
977 talloc_free(tmp_ctx
);
981 struct traverse_struct
{
982 print_queue_struct
*queue
;
983 int qcount
, snum
, maxcount
, total_jobs
;
984 const char *sharename
;
986 const char *lprm_command
;
987 struct printif
*print_if
;
988 struct tevent_context
*ev
;
989 struct messaging_context
*msg_ctx
;
993 /****************************************************************************
994 Utility fn to delete any jobs that are no longer active.
995 ****************************************************************************/
997 static int traverse_fn_delete(TDB_CONTEXT
*t
, TDB_DATA key
, TDB_DATA data
, void *state
)
999 struct traverse_struct
*ts
= (struct traverse_struct
*)state
;
1000 struct printjob pjob
;
1004 if ( key
.dsize
!= sizeof(jobid
) )
1007 if (unpack_pjob(ts
->mem_ctx
, data
.dptr
, data
.dsize
, &pjob
) == -1)
1009 talloc_free(pjob
.devmode
);
1013 /* remove a unix job if it isn't in the system queue any more */
1014 for (i
=0;i
<ts
->qcount
;i
++) {
1015 if (ts
->queue
[i
].sysjob
== pjob
.sysjob
) {
1019 if (i
== ts
->qcount
) {
1020 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
1021 (unsigned int)jobid
));
1022 pjob_delete(ts
->ev
, ts
->msg_ctx
,
1023 ts
->sharename
, jobid
);
1027 /* need to continue the the bottom of the function to
1028 save the correct attributes */
1031 /* maybe it hasn't been spooled yet */
1032 if (!pjob
.spooled
) {
1033 /* if a job is not spooled and the process doesn't
1034 exist then kill it. This cleans up after smbd
1036 if (!process_exists_by_pid(pjob
.pid
)) {
1037 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
1038 (unsigned int)jobid
, (unsigned int)pjob
.pid
));
1039 pjob_delete(ts
->ev
, ts
->msg_ctx
,
1040 ts
->sharename
, jobid
);
1046 /* this check only makes sense for jobs submitted from Windows clients */
1049 for (i
=0;i
<ts
->qcount
;i
++) {
1050 if ( pjob
.status
== LPQ_DELETED
)
1053 if (ts
->queue
[i
].sysjob
== pjob
.sysjob
) {
1055 /* try to clean up any jobs that need to be deleted */
1057 if ( pjob
.status
== LPQ_DELETING
) {
1060 result
= (*(ts
->print_if
->job_delete
))(
1061 ts
->sharename
, ts
->lprm_command
, &pjob
);
1063 if ( result
!= 0 ) {
1064 /* if we can't delete, then reset the job status */
1065 pjob
.status
= LPQ_QUEUED
;
1066 pjob_store(ts
->ev
, ts
->msg_ctx
,
1067 ts
->sharename
, jobid
, &pjob
);
1070 /* if we deleted the job, the remove the tdb record */
1073 ts
->sharename
, jobid
);
1074 pjob
.status
= LPQ_DELETED
;
1084 /* The job isn't in the system queue - we have to assume it has
1085 completed, so delete the database entry. */
1087 if (i
== ts
->qcount
) {
1089 /* A race can occur between the time a job is spooled and
1090 when it appears in the lpq output. This happens when
1091 the job is added to printing.tdb when another smbd
1092 running print_queue_update() has completed a lpq and
1093 is currently traversing the printing tdb and deleting jobs.
1094 Don't delete the job if it was submitted after the lpq_time. */
1096 if (pjob
.starttime
< ts
->lpq_time
) {
1097 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
1098 (unsigned int)jobid
,
1099 (unsigned int)pjob
.starttime
,
1100 (unsigned int)ts
->lpq_time
));
1101 pjob_delete(ts
->ev
, ts
->msg_ctx
,
1102 ts
->sharename
, jobid
);
1108 /* Save the pjob attributes we will store. */
1109 ts
->queue
[i
].sysjob
= pjob
.sysjob
;
1110 ts
->queue
[i
].size
= pjob
.size
;
1111 ts
->queue
[i
].page_count
= pjob
.page_count
;
1112 ts
->queue
[i
].status
= pjob
.status
;
1113 ts
->queue
[i
].priority
= 1;
1114 ts
->queue
[i
].time
= pjob
.starttime
;
1115 fstrcpy(ts
->queue
[i
].fs_user
, pjob
.user
);
1116 fstrcpy(ts
->queue
[i
].fs_file
, pjob
.jobname
);
1123 /****************************************************************************
1124 Check if the print queue has been updated recently enough.
1125 ****************************************************************************/
1127 static void print_cache_flush(const char *sharename
)
1130 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1134 slprintf(key
, sizeof(key
)-1, "CACHE/%s", sharename
);
1135 tdb_store_int32(pdb
->tdb
, key
, -1);
1136 release_print_db(pdb
);
1139 /****************************************************************************
1140 Check if someone already thinks they are doing the update.
1141 ****************************************************************************/
1143 static pid_t
get_updating_pid(const char *sharename
)
1148 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1152 slprintf(keystr
, sizeof(keystr
)-1, "UPDATING/%s", sharename
);
1153 key
= string_tdb_data(keystr
);
1155 data
= tdb_fetch_compat(pdb
->tdb
, key
);
1156 release_print_db(pdb
);
1157 if (!data
.dptr
|| data
.dsize
!= sizeof(pid_t
)) {
1158 SAFE_FREE(data
.dptr
);
1162 updating_pid
= IVAL(data
.dptr
, 0);
1163 SAFE_FREE(data
.dptr
);
1165 if (process_exists_by_pid(updating_pid
))
1166 return updating_pid
;
1171 /****************************************************************************
1172 Set the fact that we're doing the update, or have finished doing the update
1174 ****************************************************************************/
1176 static void set_updating_pid(const fstring sharename
, bool updating
)
1181 pid_t updating_pid
= getpid();
1184 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1189 slprintf(keystr
, sizeof(keystr
)-1, "UPDATING/%s", sharename
);
1190 key
= string_tdb_data(keystr
);
1192 DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
1193 updating
? "" : "not ",
1197 tdb_delete(pdb
->tdb
, key
);
1198 release_print_db(pdb
);
1202 SIVAL( buffer
, 0, updating_pid
);
1204 data
.dsize
= 4; /* we always assume this is a 4 byte value */
1206 tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
);
1207 release_print_db(pdb
);
1210 /****************************************************************************
1211 Sort print jobs by submittal time.
1212 ****************************************************************************/
1214 static int printjob_comp(print_queue_struct
*j1
, print_queue_struct
*j2
)
1225 /* Sort on job start time */
1227 if (j1
->time
== j2
->time
)
1229 return (j1
->time
> j2
->time
) ? 1 : -1;
1232 /****************************************************************************
1233 Store the sorted queue representation for later portmon retrieval.
1235 ****************************************************************************/
1237 static void store_queue_struct(struct tdb_print_db
*pdb
, struct traverse_struct
*pts
)
1240 int max_reported_jobs
= lp_max_reported_jobs(pts
->snum
);
1241 print_queue_struct
*queue
= pts
->queue
;
1244 unsigned int qcount
;
1246 if (max_reported_jobs
&& (max_reported_jobs
< pts
->qcount
))
1247 pts
->qcount
= max_reported_jobs
;
1250 /* Work out the size. */
1252 data
.dsize
+= tdb_pack(NULL
, 0, "d", qcount
);
1254 for (i
= 0; i
< pts
->qcount
; i
++) {
1255 if ( queue
[i
].status
== LPQ_DELETED
)
1259 data
.dsize
+= tdb_pack(NULL
, 0, "ddddddff",
1260 (uint32
)queue
[i
].sysjob
,
1261 (uint32
)queue
[i
].size
,
1262 (uint32
)queue
[i
].page_count
,
1263 (uint32
)queue
[i
].status
,
1264 (uint32
)queue
[i
].priority
,
1265 (uint32
)queue
[i
].time
,
1270 if ((data
.dptr
= (uint8
*)SMB_MALLOC(data
.dsize
)) == NULL
)
1274 len
+= tdb_pack(data
.dptr
+ len
, data
.dsize
- len
, "d", qcount
);
1275 for (i
= 0; i
< pts
->qcount
; i
++) {
1276 if ( queue
[i
].status
== LPQ_DELETED
)
1279 len
+= tdb_pack(data
.dptr
+ len
, data
.dsize
- len
, "ddddddff",
1280 (uint32
)queue
[i
].sysjob
,
1281 (uint32
)queue
[i
].size
,
1282 (uint32
)queue
[i
].page_count
,
1283 (uint32
)queue
[i
].status
,
1284 (uint32
)queue
[i
].priority
,
1285 (uint32
)queue
[i
].time
,
1290 tdb_store(pdb
->tdb
, string_tdb_data("INFO/linear_queue_array"), data
,
1292 SAFE_FREE(data
.dptr
);
1296 static TDB_DATA
get_jobs_added_data(struct tdb_print_db
*pdb
)
1302 data
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data("INFO/jobs_added"));
1303 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0)) {
1304 SAFE_FREE(data
.dptr
);
1311 static void check_job_added(const char *sharename
, TDB_DATA data
, uint32 jobid
)
1314 unsigned int job_count
= data
.dsize
/ 4;
1316 for (i
= 0; i
< job_count
; i
++) {
1319 ch_jobid
= IVAL(data
.dptr
, i
*4);
1320 if (ch_jobid
== jobid
)
1321 remove_from_jobs_added(sharename
, jobid
);
1325 /****************************************************************************
1326 Check if the print queue has been updated recently enough.
1327 ****************************************************************************/
1329 static bool print_cache_expired(const char *sharename
, bool check_pending
)
1332 time_t last_qscan_time
, time_now
= time(NULL
);
1333 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1334 bool result
= False
;
1339 snprintf(key
, sizeof(key
), "CACHE/%s", sharename
);
1340 last_qscan_time
= (time_t)tdb_fetch_int32(pdb
->tdb
, key
);
1343 * Invalidate the queue for 3 reasons.
1344 * (1). last queue scan time == -1.
1345 * (2). Current time - last queue scan time > allowed cache time.
1346 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1347 * This last test picks up machines for which the clock has been moved
1348 * forward, an lpq scan done and then the clock moved back. Otherwise
1349 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1352 if (last_qscan_time
== ((time_t)-1)
1353 || (time_now
- last_qscan_time
) >= lp_lpqcachetime()
1354 || last_qscan_time
> (time_now
+ MAX_CACHE_VALID_TIME
))
1357 time_t msg_pending_time
;
1359 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1360 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1361 sharename
, (int)last_qscan_time
, (int)time_now
,
1362 (int)lp_lpqcachetime() ));
1364 /* check if another smbd has already sent a message to update the
1365 queue. Give the pending message one minute to clear and
1366 then send another message anyways. Make sure to check for
1367 clocks that have been run forward and then back again. */
1369 snprintf(key
, sizeof(key
), "MSG_PENDING/%s", sharename
);
1372 && tdb_fetch_uint32( pdb
->tdb
, key
, &u
)
1373 && (msg_pending_time
=u
) > 0
1374 && msg_pending_time
<= time_now
1375 && (time_now
- msg_pending_time
) < 60 )
1377 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1386 release_print_db(pdb
);
1390 /****************************************************************************
1391 main work for updating the lpq cache for a printer queue
1392 ****************************************************************************/
1394 static void print_queue_update_internal(struct tevent_context
*ev
,
1395 struct messaging_context
*msg_ctx
,
1396 const char *sharename
,
1397 struct printif
*current_printif
,
1398 char *lpq_command
, char *lprm_command
)
1401 print_queue_struct
*queue
= NULL
;
1402 print_status_struct status
;
1403 print_status_struct old_status
;
1404 struct printjob
*pjob
;
1405 struct traverse_struct tstruct
;
1408 fstring keystr
, cachestr
;
1409 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1410 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
1412 if ((pdb
== NULL
) || (tmp_ctx
== NULL
)) {
1416 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1417 sharename
, current_printif
->type
, lpq_command
));
1420 * Update the cache time FIRST ! Stops others even
1421 * attempting to get the lock and doing this
1422 * if the lpq takes a long time.
1425 slprintf(cachestr
, sizeof(cachestr
)-1, "CACHE/%s", sharename
);
1426 tdb_store_int32(pdb
->tdb
, cachestr
, (int)time(NULL
));
1428 /* get the current queue using the appropriate interface */
1429 ZERO_STRUCT(status
);
1431 qcount
= (*(current_printif
->queue_get
))(sharename
,
1432 current_printif
->type
,
1433 lpq_command
, &queue
, &status
);
1435 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1436 qcount
, (qcount
!= 1) ? "s" : "", sharename
));
1438 /* Sort the queue by submission time otherwise they are displayed
1441 TYPESAFE_QSORT(queue
, qcount
, printjob_comp
);
1444 any job in the internal database that is marked as spooled
1445 and doesn't exist in the system queue is considered finished
1446 and removed from the database
1448 any job in the system database but not in the internal database
1449 is added as a unix job
1451 fill in any system job numbers as we go
1453 jcdata
= get_jobs_added_data(pdb
);
1455 for (i
=0; i
<qcount
; i
++) {
1456 uint32 jobid
= sysjob_to_jobid_pdb(pdb
, queue
[i
].sysjob
);
1457 if (jobid
== (uint32
)-1) {
1458 /* assume its a unix print job */
1459 print_unix_job(ev
, msg_ctx
,
1460 sharename
, &queue
[i
], jobid
);
1464 /* we have an active SMB print job - update its status */
1465 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
1467 /* err, somethings wrong. Probably smbd was restarted
1468 with jobs in the queue. All we can do is treat them
1469 like unix jobs. Pity. */
1470 DEBUG(1, ("queued print job %d not found in jobs list, "
1471 "assuming unix job\n", jobid
));
1472 print_unix_job(ev
, msg_ctx
,
1473 sharename
, &queue
[i
], jobid
);
1477 /* don't reset the status on jobs to be deleted */
1479 if ( pjob
->status
!= LPQ_DELETING
)
1480 pjob
->status
= queue
[i
].status
;
1482 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
1484 check_job_added(sharename
, jcdata
, jobid
);
1487 SAFE_FREE(jcdata
.dptr
);
1489 /* now delete any queued entries that don't appear in the
1491 tstruct
.queue
= queue
;
1492 tstruct
.qcount
= qcount
;
1494 tstruct
.total_jobs
= 0;
1495 tstruct
.lpq_time
= time(NULL
);
1496 tstruct
.sharename
= sharename
;
1497 tstruct
.lprm_command
= lprm_command
;
1498 tstruct
.print_if
= current_printif
;
1500 tstruct
.msg_ctx
= msg_ctx
;
1501 tstruct
.mem_ctx
= tmp_ctx
;
1503 tdb_traverse(pdb
->tdb
, traverse_fn_delete
, (void *)&tstruct
);
1505 /* Store the linearised queue, max jobs only. */
1506 store_queue_struct(pdb
, &tstruct
);
1508 SAFE_FREE(tstruct
.queue
);
1509 talloc_free(tmp_ctx
);
1511 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1512 sharename
, tstruct
.total_jobs
));
1514 tdb_store_int32(pdb
->tdb
, "INFO/total_jobs", tstruct
.total_jobs
);
1516 get_queue_status(sharename
, &old_status
);
1517 if (old_status
.qcount
!= qcount
)
1518 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1519 old_status
.qcount
, qcount
, sharename
));
1521 /* store the new queue status structure */
1522 slprintf(keystr
, sizeof(keystr
)-1, "STATUS/%s", sharename
);
1523 key
= string_tdb_data(keystr
);
1525 status
.qcount
= qcount
;
1526 data
.dptr
= (uint8
*)&status
;
1527 data
.dsize
= sizeof(status
);
1528 tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
);
1531 * Update the cache time again. We want to do this call
1532 * as little as possible...
1535 slprintf(keystr
, sizeof(keystr
)-1, "CACHE/%s", sharename
);
1536 tdb_store_int32(pdb
->tdb
, keystr
, (int32
)time(NULL
));
1538 /* clear the msg pending record for this queue */
1540 snprintf(keystr
, sizeof(keystr
), "MSG_PENDING/%s", sharename
);
1542 if ( !tdb_store_uint32( pdb
->tdb
, keystr
, 0 ) ) {
1543 /* log a message but continue on */
1545 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1549 release_print_db( pdb
);
1554 /****************************************************************************
1555 Update the internal database from the system print queue for a queue.
1556 obtain a lock on the print queue before proceeding (needed when mutiple
1557 smbd processes maytry to update the lpq cache concurrently).
1558 ****************************************************************************/
1560 static void print_queue_update_with_lock( struct tevent_context
*ev
,
1561 struct messaging_context
*msg_ctx
,
1562 const char *sharename
,
1563 struct printif
*current_printif
,
1564 char *lpq_command
, char *lprm_command
)
1567 struct tdb_print_db
*pdb
;
1569 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename
));
1570 pdb
= get_print_db_byname(sharename
);
1574 if ( !print_cache_expired(sharename
, False
) ) {
1575 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename
));
1576 release_print_db(pdb
);
1581 * Check to see if someone else is doing this update.
1582 * This is essentially a mutex on the update.
1585 if (get_updating_pid(sharename
) != -1) {
1586 release_print_db(pdb
);
1590 /* Lock the queue for the database update */
1592 slprintf(keystr
, sizeof(keystr
) - 1, "LOCK/%s", sharename
);
1593 /* Only wait 10 seconds for this. */
1594 if (tdb_lock_bystring_with_timeout(pdb
->tdb
, keystr
, 10) != 0) {
1595 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename
));
1596 release_print_db(pdb
);
1601 * Ensure that no one else got in here.
1602 * If the updating pid is still -1 then we are
1606 if (get_updating_pid(sharename
) != -1) {
1608 * Someone else is doing the update, exit.
1610 tdb_unlock_bystring(pdb
->tdb
, keystr
);
1611 release_print_db(pdb
);
1616 * We're going to do the update ourselves.
1619 /* Tell others we're doing the update. */
1620 set_updating_pid(sharename
, True
);
1623 * Allow others to enter and notice we're doing
1627 tdb_unlock_bystring(pdb
->tdb
, keystr
);
1629 /* do the main work now */
1631 print_queue_update_internal(ev
, msg_ctx
,
1632 sharename
, current_printif
,
1633 lpq_command
, lprm_command
);
1635 /* Delete our pid from the db. */
1636 set_updating_pid(sharename
, False
);
1637 release_print_db(pdb
);
1640 /****************************************************************************
1641 this is the receive function of the background lpq updater
1642 ****************************************************************************/
1643 void print_queue_receive(struct messaging_context
*msg
,
1646 struct server_id server_id
,
1650 char *lpqcommand
= NULL
, *lprmcommand
= NULL
;
1654 len
= tdb_unpack( (uint8
*)data
->data
, data
->length
, "fdPP",
1661 SAFE_FREE(lpqcommand
);
1662 SAFE_FREE(lprmcommand
);
1663 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1667 print_queue_update_with_lock(server_event_context(), msg
, sharename
,
1668 get_printer_fns_from_type((enum printing_types
)printing_type
),
1669 lpqcommand
, lprmcommand
);
1671 SAFE_FREE(lpqcommand
);
1672 SAFE_FREE(lprmcommand
);
1676 /****************************************************************************
1677 update the internal database from the system print queue for a queue
1678 ****************************************************************************/
1680 extern pid_t background_lpq_updater_pid
;
1682 static void print_queue_update(struct messaging_context
*msg_ctx
,
1683 int snum
, bool force
)
1687 char *lpqcommand
= NULL
;
1688 char *lprmcommand
= NULL
;
1689 uint8
*buffer
= NULL
;
1692 struct tdb_print_db
*pdb
;
1694 struct printif
*current_printif
;
1695 TALLOC_CTX
*ctx
= talloc_tos();
1697 fstrcpy( sharename
, lp_const_servicename(snum
));
1699 /* don't strip out characters like '$' from the printername */
1701 lpqcommand
= talloc_string_sub2(ctx
,
1702 lp_lpqcommand(talloc_tos(), snum
),
1704 lp_printername(talloc_tos(), snum
),
1705 false, false, false);
1709 lpqcommand
= talloc_sub_advanced(ctx
,
1710 lp_servicename(talloc_tos(), snum
),
1711 current_user_info
.unix_name
,
1713 current_user
.ut
.gid
,
1714 get_current_username(),
1715 current_user_info
.domain
,
1721 lprmcommand
= talloc_string_sub2(ctx
,
1722 lp_lprmcommand(talloc_tos(), snum
),
1724 lp_printername(talloc_tos(), snum
),
1725 false, false, false);
1729 lprmcommand
= talloc_sub_advanced(ctx
,
1730 lp_servicename(talloc_tos(), snum
),
1731 current_user_info
.unix_name
,
1733 current_user
.ut
.gid
,
1734 get_current_username(),
1735 current_user_info
.domain
,
1742 * Make sure that the background queue process exists.
1743 * Otherwise just do the update ourselves
1746 if ( force
|| background_lpq_updater_pid
== -1 ) {
1747 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename
));
1748 current_printif
= get_printer_fns( snum
);
1749 print_queue_update_with_lock(server_event_context(), msg_ctx
,
1750 sharename
, current_printif
,
1751 lpqcommand
, lprmcommand
);
1756 type
= lp_printing(snum
);
1758 /* get the length */
1760 len
= tdb_pack( NULL
, 0, "fdPP",
1766 buffer
= SMB_XMALLOC_ARRAY( uint8
, len
);
1768 /* now pack the buffer */
1769 newlen
= tdb_pack( buffer
, len
, "fdPP",
1775 SMB_ASSERT( newlen
== len
);
1777 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1778 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1779 sharename
, type
, lpqcommand
, lprmcommand
));
1781 /* here we set a msg pending record for other smbd processes
1782 to throttle the number of duplicate print_queue_update msgs
1785 pdb
= get_print_db_byname(sharename
);
1791 snprintf(key
, sizeof(key
), "MSG_PENDING/%s", sharename
);
1793 if ( !tdb_store_uint32( pdb
->tdb
, key
, time(NULL
) ) ) {
1794 /* log a message but continue on */
1796 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1800 release_print_db( pdb
);
1802 /* finally send the message */
1804 messaging_send_buf(msg_ctx
, pid_to_procid(background_lpq_updater_pid
),
1805 MSG_PRINTER_UPDATE
, (uint8
*)buffer
, len
);
1807 SAFE_FREE( buffer
);
1812 /****************************************************************************
1813 Create/Update an entry in the print tdb that will allow us to send notify
1814 updates only to interested smbd's.
1815 ****************************************************************************/
1817 bool print_notify_register_pid(int snum
)
1820 struct tdb_print_db
*pdb
= NULL
;
1821 TDB_CONTEXT
*tdb
= NULL
;
1822 const char *printername
;
1823 uint32_t mypid
= (uint32_t)getpid();
1827 /* if (snum == -1), then the change notify request was
1828 on a print server handle and we need to register on
1833 int num_services
= lp_numservices();
1836 for ( idx
=0; idx
<num_services
; idx
++ ) {
1837 if (lp_snum_ok(idx
) && lp_print_ok(idx
) )
1838 print_notify_register_pid(idx
);
1843 else /* register for a specific printer */
1845 printername
= lp_const_servicename(snum
);
1846 pdb
= get_print_db_byname(printername
);
1852 if (tdb_lock_bystring_with_timeout(tdb
, NOTIFY_PID_LIST_KEY
, 10) != 0) {
1853 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1856 release_print_db(pdb
);
1860 data
= get_printer_notify_pid_list( tdb
, printername
, True
);
1862 /* Add ourselves and increase the refcount. */
1864 for (i
= 0; i
< data
.dsize
; i
+= 8) {
1865 if (IVAL(data
.dptr
,i
) == mypid
) {
1866 uint32 new_refcount
= IVAL(data
.dptr
, i
+4) + 1;
1867 SIVAL(data
.dptr
, i
+4, new_refcount
);
1872 if (i
== data
.dsize
) {
1873 /* We weren't in the list. Realloc. */
1874 data
.dptr
= (uint8
*)SMB_REALLOC(data
.dptr
, data
.dsize
+ 8);
1876 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1881 SIVAL(data
.dptr
,data
.dsize
- 8,mypid
);
1882 SIVAL(data
.dptr
,data
.dsize
- 4,1); /* Refcount. */
1885 /* Store back the record. */
1886 if (tdb_store_bystring(tdb
, NOTIFY_PID_LIST_KEY
, data
, TDB_REPLACE
) != 0) {
1887 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1888 list for printer %s\n", printername
));
1896 tdb_unlock_bystring(tdb
, NOTIFY_PID_LIST_KEY
);
1898 release_print_db(pdb
);
1899 SAFE_FREE(data
.dptr
);
1903 /****************************************************************************
1904 Update an entry in the print tdb that will allow us to send notify
1905 updates only to interested smbd's.
1906 ****************************************************************************/
1908 bool print_notify_deregister_pid(int snum
)
1911 struct tdb_print_db
*pdb
= NULL
;
1912 TDB_CONTEXT
*tdb
= NULL
;
1913 const char *printername
;
1914 uint32_t mypid
= (uint32_t)getpid();
1918 /* if ( snum == -1 ), we are deregister a print server handle
1919 which means to deregister on all print queues */
1923 int num_services
= lp_numservices();
1926 for ( idx
=0; idx
<num_services
; idx
++ ) {
1927 if ( lp_snum_ok(idx
) && lp_print_ok(idx
) )
1928 print_notify_deregister_pid(idx
);
1933 else /* deregister a specific printer */
1935 printername
= lp_const_servicename(snum
);
1936 pdb
= get_print_db_byname(printername
);
1942 if (tdb_lock_bystring_with_timeout(tdb
, NOTIFY_PID_LIST_KEY
, 10) != 0) {
1943 DEBUG(0,("print_notify_register_pid: Failed to lock \
1944 printer %s database\n", printername
));
1946 release_print_db(pdb
);
1950 data
= get_printer_notify_pid_list( tdb
, printername
, True
);
1952 /* Reduce refcount. Remove ourselves if zero. */
1954 for (i
= 0; i
< data
.dsize
; ) {
1955 if (IVAL(data
.dptr
,i
) == mypid
) {
1956 uint32 refcount
= IVAL(data
.dptr
, i
+4);
1960 if (refcount
== 0) {
1961 if (data
.dsize
- i
> 8)
1962 memmove( &data
.dptr
[i
], &data
.dptr
[i
+8], data
.dsize
- i
- 8);
1966 SIVAL(data
.dptr
, i
+4, refcount
);
1972 if (data
.dsize
== 0)
1973 SAFE_FREE(data
.dptr
);
1975 /* Store back the record. */
1976 if (tdb_store_bystring(tdb
, NOTIFY_PID_LIST_KEY
, data
, TDB_REPLACE
) != 0) {
1977 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1978 list for printer %s\n", printername
));
1986 tdb_unlock_bystring(tdb
, NOTIFY_PID_LIST_KEY
);
1988 release_print_db(pdb
);
1989 SAFE_FREE(data
.dptr
);
1993 /****************************************************************************
1994 Check if a jobid is valid. It is valid if it exists in the database.
1995 ****************************************************************************/
1997 bool print_job_exists(const char* sharename
, uint32 jobid
)
1999 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2005 ret
= tdb_exists(pdb
->tdb
, print_key(jobid
, &tmp
));
2006 release_print_db(pdb
);
2010 /****************************************************************************
2011 Return the device mode asigned to a specific print job.
2012 Only valid for the process doing the spooling and when the job
2013 has not been spooled.
2014 ****************************************************************************/
2016 struct spoolss_DeviceMode
*print_job_devmode(TALLOC_CTX
*mem_ctx
,
2017 const char *sharename
,
2020 struct printjob
*pjob
= print_job_find(mem_ctx
, sharename
, jobid
);
2025 return pjob
->devmode
;
2028 /****************************************************************************
2029 Set the name of a job. Only possible for owner.
2030 ****************************************************************************/
2032 bool print_job_set_name(struct tevent_context
*ev
,
2033 struct messaging_context
*msg_ctx
,
2034 const char *sharename
, uint32 jobid
, const char *name
)
2036 struct printjob
*pjob
;
2038 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
2039 if (tmp_ctx
== NULL
) {
2043 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2044 if (!pjob
|| pjob
->pid
!= getpid()) {
2049 fstrcpy(pjob
->jobname
, name
);
2050 ret
= pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2052 talloc_free(tmp_ctx
);
2056 /****************************************************************************
2057 Get the name of a job. Only possible for owner.
2058 ****************************************************************************/
2060 bool print_job_get_name(TALLOC_CTX
*mem_ctx
, const char *sharename
, uint32_t jobid
, char **name
)
2062 struct printjob
*pjob
;
2064 pjob
= print_job_find(mem_ctx
, sharename
, jobid
);
2065 if (!pjob
|| pjob
->pid
!= getpid()) {
2069 *name
= pjob
->jobname
;
2074 /***************************************************************************
2075 Remove a jobid from the 'jobs added' list.
2076 ***************************************************************************/
2078 static bool remove_from_jobs_added(const char* sharename
, uint32 jobid
)
2080 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2082 size_t job_count
, i
;
2084 bool gotlock
= False
;
2092 key
= string_tdb_data("INFO/jobs_added");
2094 if (tdb_chainlock_with_timeout(pdb
->tdb
, key
, 5) != 0)
2099 data
= tdb_fetch_compat(pdb
->tdb
, key
);
2101 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0))
2104 job_count
= data
.dsize
/ 4;
2105 for (i
= 0; i
< job_count
; i
++) {
2108 ch_jobid
= IVAL(data
.dptr
, i
*4);
2109 if (ch_jobid
== jobid
) {
2110 if (i
< job_count
-1 )
2111 memmove(data
.dptr
+ (i
*4), data
.dptr
+ (i
*4) + 4, (job_count
- i
- 1)*4 );
2113 if (tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
) != 0)
2123 tdb_chainunlock(pdb
->tdb
, key
);
2124 SAFE_FREE(data
.dptr
);
2125 release_print_db(pdb
);
2127 DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid
));
2129 DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid
));
2133 /****************************************************************************
2134 Delete a print job - don't update queue.
2135 ****************************************************************************/
2137 static bool print_job_delete1(struct tevent_context
*ev
,
2138 struct messaging_context
*msg_ctx
,
2139 int snum
, uint32 jobid
)
2141 const char* sharename
= lp_const_servicename(snum
);
2142 struct printjob
*pjob
;
2144 struct printif
*current_printif
= get_printer_fns( snum
);
2146 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
2147 if (tmp_ctx
== NULL
) {
2151 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2158 * If already deleting just return.
2161 if (pjob
->status
== LPQ_DELETING
) {
2166 /* Hrm - we need to be able to cope with deleting a job before it
2167 has reached the spooler. Just mark it as LPQ_DELETING and
2168 let the print_queue_update() code rmeove the record */
2171 if (pjob
->sysjob
== -1) {
2172 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid
));
2175 /* Set the tdb entry to be deleting. */
2177 pjob
->status
= LPQ_DELETING
;
2178 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2180 if (pjob
->spooled
&& pjob
->sysjob
!= -1)
2182 result
= (*(current_printif
->job_delete
))(
2183 lp_printername(talloc_tos(), snum
),
2184 lp_lprmcommand(talloc_tos(), snum
),
2187 /* Delete the tdb entry if the delete succeeded or the job hasn't
2191 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2198 pjob_delete(ev
, msg_ctx
, sharename
, jobid
);
2199 /* Ensure we keep a rough count of the number of total jobs... */
2200 tdb_change_int32_atomic(pdb
->tdb
, "INFO/total_jobs", &njobs
, -1);
2201 release_print_db(pdb
);
2205 remove_from_jobs_added( sharename
, jobid
);
2207 ret
= (result
== 0);
2209 talloc_free(tmp_ctx
);
2213 /****************************************************************************
2214 Return true if the current user owns the print job.
2215 ****************************************************************************/
2217 static bool is_owner(const struct auth_session_info
*server_info
,
2218 const char *servicename
,
2221 struct printjob
*pjob
;
2223 TALLOC_CTX
*tmp_ctx
= talloc_new(server_info
);
2224 if (tmp_ctx
== NULL
) {
2228 pjob
= print_job_find(tmp_ctx
, servicename
, jobid
);
2229 if (!pjob
|| !server_info
) {
2234 ret
= strequal(pjob
->user
, server_info
->unix_info
->sanitized_username
);
2236 talloc_free(tmp_ctx
);
2240 /****************************************************************************
2242 ****************************************************************************/
2244 WERROR
print_job_delete(const struct auth_session_info
*server_info
,
2245 struct messaging_context
*msg_ctx
,
2246 int snum
, uint32_t jobid
)
2248 const char* sharename
= lp_const_servicename(snum
);
2249 struct printjob
*pjob
;
2252 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2253 if (tmp_ctx
== NULL
) {
2254 return WERR_NOT_ENOUGH_MEMORY
;
2257 owner
= is_owner(server_info
, lp_const_servicename(snum
), jobid
);
2259 /* Check access against security descriptor or whether the user
2263 !print_access_check(server_info
, msg_ctx
, snum
,
2264 JOB_ACCESS_ADMINISTER
)) {
2265 DEBUG(3, ("delete denied by security descriptor\n"));
2267 /* BEGIN_ADMIN_LOG */
2268 sys_adminlog( LOG_ERR
,
2269 "Permission denied-- user not allowed to delete, \
2270 pause, or resume print job. User name: %s. Printer name: %s.",
2271 uidtoname(server_info
->unix_token
->uid
),
2272 lp_printername(talloc_tos(), snum
) );
2275 werr
= WERR_ACCESS_DENIED
;
2280 * get the spooled filename of the print job
2281 * if this works, then the file has not been spooled
2282 * to the underlying print system. Just delete the
2283 * spool file & return.
2286 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2287 if (!pjob
|| pjob
->spooled
|| pjob
->pid
!= getpid()) {
2288 DEBUG(10, ("Skipping spool file removal for job %u\n", jobid
));
2290 DEBUG(10, ("Removing spool file [%s]\n", pjob
->filename
));
2291 if (unlink(pjob
->filename
) == -1) {
2292 werr
= map_werror_from_unix(errno
);
2297 if (!print_job_delete1(server_event_context(), msg_ctx
, snum
, jobid
)) {
2298 werr
= WERR_ACCESS_DENIED
;
2302 /* force update the database and say the delete failed if the
2305 print_queue_update(msg_ctx
, snum
, True
);
2307 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2308 if (pjob
&& (pjob
->status
!= LPQ_DELETING
)) {
2309 werr
= WERR_ACCESS_DENIED
;
2312 werr
= WERR_PRINTER_HAS_JOBS_QUEUED
;
2315 talloc_free(tmp_ctx
);
2319 /****************************************************************************
2321 ****************************************************************************/
2323 WERROR
print_job_pause(const struct auth_session_info
*server_info
,
2324 struct messaging_context
*msg_ctx
,
2325 int snum
, uint32 jobid
)
2327 const char* sharename
= lp_const_servicename(snum
);
2328 struct printjob
*pjob
;
2330 struct printif
*current_printif
= get_printer_fns( snum
);
2332 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2333 if (tmp_ctx
== NULL
) {
2334 return WERR_NOT_ENOUGH_MEMORY
;
2337 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2338 if (!pjob
|| !server_info
) {
2339 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2340 (unsigned int)jobid
));
2341 werr
= WERR_INVALID_PARAM
;
2345 if (!pjob
->spooled
|| pjob
->sysjob
== -1) {
2346 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2347 (int)pjob
->sysjob
, (unsigned int)jobid
));
2348 werr
= WERR_INVALID_PARAM
;
2352 if (!is_owner(server_info
, lp_const_servicename(snum
), jobid
) &&
2353 !print_access_check(server_info
, msg_ctx
, snum
,
2354 JOB_ACCESS_ADMINISTER
)) {
2355 DEBUG(3, ("pause denied by security descriptor\n"));
2357 /* BEGIN_ADMIN_LOG */
2358 sys_adminlog( LOG_ERR
,
2359 "Permission denied-- user not allowed to delete, \
2360 pause, or resume print job. User name: %s. Printer name: %s.",
2361 uidtoname(server_info
->unix_token
->uid
),
2362 lp_printername(talloc_tos(), snum
) );
2365 werr
= WERR_ACCESS_DENIED
;
2369 /* need to pause the spooled entry */
2370 ret
= (*(current_printif
->job_pause
))(snum
, pjob
);
2373 werr
= WERR_INVALID_PARAM
;
2377 /* force update the database */
2378 print_cache_flush(lp_const_servicename(snum
));
2380 /* Send a printer notify message */
2382 notify_job_status(server_event_context(), msg_ctx
, sharename
, jobid
,
2385 /* how do we tell if this succeeded? */
2388 talloc_free(tmp_ctx
);
2392 /****************************************************************************
2394 ****************************************************************************/
2396 WERROR
print_job_resume(const struct auth_session_info
*server_info
,
2397 struct messaging_context
*msg_ctx
,
2398 int snum
, uint32 jobid
)
2400 const char *sharename
= lp_const_servicename(snum
);
2401 struct printjob
*pjob
;
2403 struct printif
*current_printif
= get_printer_fns( snum
);
2405 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2406 if (tmp_ctx
== NULL
)
2407 return WERR_NOT_ENOUGH_MEMORY
;
2409 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2410 if (!pjob
|| !server_info
) {
2411 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2412 (unsigned int)jobid
));
2413 werr
= WERR_INVALID_PARAM
;
2417 if (!pjob
->spooled
|| pjob
->sysjob
== -1) {
2418 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2419 (int)pjob
->sysjob
, (unsigned int)jobid
));
2420 werr
= WERR_INVALID_PARAM
;
2424 if (!is_owner(server_info
, lp_const_servicename(snum
), jobid
) &&
2425 !print_access_check(server_info
, msg_ctx
, snum
,
2426 JOB_ACCESS_ADMINISTER
)) {
2427 DEBUG(3, ("resume denied by security descriptor\n"));
2429 /* BEGIN_ADMIN_LOG */
2430 sys_adminlog( LOG_ERR
,
2431 "Permission denied-- user not allowed to delete, \
2432 pause, or resume print job. User name: %s. Printer name: %s.",
2433 uidtoname(server_info
->unix_token
->uid
),
2434 lp_printername(talloc_tos(), snum
) );
2436 werr
= WERR_ACCESS_DENIED
;
2440 ret
= (*(current_printif
->job_resume
))(snum
, pjob
);
2443 werr
= WERR_INVALID_PARAM
;
2447 /* force update the database */
2448 print_cache_flush(lp_const_servicename(snum
));
2450 /* Send a printer notify message */
2452 notify_job_status(server_event_context(), msg_ctx
, sharename
, jobid
,
2457 talloc_free(tmp_ctx
);
2461 /****************************************************************************
2462 Write to a print file.
2463 ****************************************************************************/
2465 ssize_t
print_job_write(struct tevent_context
*ev
,
2466 struct messaging_context
*msg_ctx
,
2467 int snum
, uint32 jobid
, const char *buf
, size_t size
)
2469 const char* sharename
= lp_const_servicename(snum
);
2470 ssize_t return_code
;
2471 struct printjob
*pjob
;
2472 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
2473 if (tmp_ctx
== NULL
) {
2477 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2483 /* don't allow another process to get this info - it is meaningless */
2484 if (pjob
->pid
!= getpid()) {
2489 /* if SMBD is spooling this can't be allowed */
2490 if (pjob
->status
== PJOB_SMBD_SPOOLING
) {
2495 return_code
= write_data(pjob
->fd
, buf
, size
);
2496 if (return_code
> 0) {
2498 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2501 talloc_free(tmp_ctx
);
2505 /****************************************************************************
2506 Get the queue status - do not update if db is out of date.
2507 ****************************************************************************/
2509 static int get_queue_status(const char* sharename
, print_status_struct
*status
)
2513 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2517 ZERO_STRUCTP(status
);
2524 fstr_sprintf(keystr
, "STATUS/%s", sharename
);
2525 data
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data(keystr
));
2527 if (data
.dsize
== sizeof(print_status_struct
))
2528 /* this memcpy is ok since the status struct was
2529 not packed before storing it in the tdb */
2530 memcpy(status
, data
.dptr
, sizeof(print_status_struct
));
2531 SAFE_FREE(data
.dptr
);
2534 len
= tdb_fetch_int32(pdb
->tdb
, "INFO/total_jobs");
2535 release_print_db(pdb
);
2536 return (len
== -1 ? 0 : len
);
2539 /****************************************************************************
2540 Determine the number of jobs in a queue.
2541 ****************************************************************************/
2543 int print_queue_length(struct messaging_context
*msg_ctx
, int snum
,
2544 print_status_struct
*pstatus
)
2546 const char* sharename
= lp_const_servicename( snum
);
2547 print_status_struct status
;
2550 ZERO_STRUCT( status
);
2552 /* make sure the database is up to date */
2553 if (print_cache_expired(lp_const_servicename(snum
), True
))
2554 print_queue_update(msg_ctx
, snum
, False
);
2556 /* also fetch the queue status */
2557 memset(&status
, 0, sizeof(status
));
2558 len
= get_queue_status(sharename
, &status
);
2566 /***************************************************************************
2567 Allocate a jobid. Hold the lock for as short a time as possible.
2568 ***************************************************************************/
2570 static WERROR
allocate_print_jobid(struct tdb_print_db
*pdb
, int snum
,
2571 const char *sharename
, uint32
*pjobid
)
2575 enum TDB_ERROR terr
;
2578 *pjobid
= (uint32
)-1;
2580 for (i
= 0; i
< 3; i
++) {
2581 /* Lock the database - only wait 20 seconds. */
2582 ret
= tdb_lock_bystring_with_timeout(pdb
->tdb
,
2583 "INFO/nextjob", 20);
2585 DEBUG(0, ("allocate_print_jobid: "
2586 "Failed to lock printing database %s\n",
2588 terr
= tdb_error(pdb
->tdb
);
2589 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2592 if (!tdb_fetch_uint32(pdb
->tdb
, "INFO/nextjob", &jobid
)) {
2593 terr
= tdb_error(pdb
->tdb
);
2594 if (terr
!= TDB_ERR_NOEXIST
) {
2595 DEBUG(0, ("allocate_print_jobid: "
2596 "Failed to fetch INFO/nextjob "
2597 "for print queue %s\n", sharename
));
2598 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2599 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2601 DEBUG(10, ("allocate_print_jobid: "
2602 "No existing jobid in %s\n", sharename
));
2606 DEBUG(10, ("allocate_print_jobid: "
2607 "Read jobid %u from %s\n", jobid
, sharename
));
2609 jobid
= NEXT_JOBID(jobid
);
2611 ret
= tdb_store_int32(pdb
->tdb
, "INFO/nextjob", jobid
);
2613 terr
= tdb_error(pdb
->tdb
);
2614 DEBUG(3, ("allocate_print_jobid: "
2615 "Failed to store INFO/nextjob.\n"));
2616 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2617 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2620 /* We've finished with the INFO/nextjob lock. */
2621 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2623 if (!print_job_exists(sharename
, jobid
)) {
2626 DEBUG(10, ("allocate_print_jobid: "
2627 "Found jobid %u in %s\n", jobid
, sharename
));
2631 DEBUG(0, ("allocate_print_jobid: "
2632 "Failed to allocate a print job for queue %s\n",
2634 /* Probably full... */
2635 return WERR_NO_SPOOL_SPACE
;
2638 /* Store a dummy placeholder. */
2644 if (tdb_store(pdb
->tdb
, print_key(jobid
, &tmp
), dum
,
2646 DEBUG(3, ("allocate_print_jobid: "
2647 "jobid (%d) failed to store placeholder.\n",
2649 terr
= tdb_error(pdb
->tdb
);
2650 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2658 /***************************************************************************
2659 Append a jobid to the 'jobs added' list.
2660 ***************************************************************************/
2662 static bool add_to_jobs_added(struct tdb_print_db
*pdb
, uint32 jobid
)
2667 SIVAL(&store_jobid
, 0, jobid
);
2668 data
.dptr
= (uint8
*)&store_jobid
;
2671 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid
));
2673 return (tdb_append(pdb
->tdb
, string_tdb_data("INFO/jobs_added"),
2678 /***************************************************************************
2679 Do all checks needed to determine if we can start a job.
2680 ***************************************************************************/
2682 static WERROR
print_job_checks(const struct auth_session_info
*server_info
,
2683 struct messaging_context
*msg_ctx
,
2684 int snum
, int *njobs
)
2686 const char *sharename
= lp_const_servicename(snum
);
2687 uint64_t dspace
, dsize
;
2691 if (!print_access_check(server_info
, msg_ctx
, snum
,
2692 PRINTER_ACCESS_USE
)) {
2693 DEBUG(3, ("print_job_checks: "
2694 "job start denied by security descriptor\n"));
2695 return WERR_ACCESS_DENIED
;
2698 if (!print_time_access_check(server_info
, msg_ctx
, sharename
)) {
2699 DEBUG(3, ("print_job_checks: "
2700 "job start denied by time check\n"));
2701 return WERR_ACCESS_DENIED
;
2704 /* see if we have sufficient disk space */
2705 if (lp_minprintspace(snum
)) {
2706 minspace
= lp_minprintspace(snum
);
2707 ret
= sys_fsusage(lp_pathname(talloc_tos(), snum
), &dspace
, &dsize
);
2708 if (ret
== 0 && dspace
< 2*minspace
) {
2709 DEBUG(3, ("print_job_checks: "
2710 "disk space check failed.\n"));
2711 return WERR_NO_SPOOL_SPACE
;
2715 /* for autoloaded printers, check that the printcap entry still exists */
2716 if (lp_autoloaded(snum
) && !pcap_printername_ok(sharename
)) {
2717 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2719 return WERR_ACCESS_DENIED
;
2722 /* Insure the maximum queue size is not violated */
2723 *njobs
= print_queue_length(msg_ctx
, snum
, NULL
);
2724 if (*njobs
> lp_maxprintjobs(snum
)) {
2725 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2726 "larger than max printjobs per queue (%d).\n",
2727 sharename
, *njobs
, lp_maxprintjobs(snum
)));
2728 return WERR_NO_SPOOL_SPACE
;
2734 /***************************************************************************
2736 ***************************************************************************/
2738 static WERROR
print_job_spool_file(int snum
, uint32_t jobid
,
2739 const char *output_file
,
2740 struct printjob
*pjob
)
2748 /* if this file is within the printer path, it means that smbd
2749 * is spooling it and will pass us control when it is finished.
2750 * Verify that the file name is ok, within path, and it is
2751 * already already there */
2753 path
= lp_pathname(talloc_tos(), snum
);
2755 if (strncmp(output_file
, path
, len
) == 0 &&
2756 (output_file
[len
- 1] == '/' || output_file
[len
] == '/')) {
2758 /* verify path is not too long */
2759 if (strlen(output_file
) >= sizeof(pjob
->filename
)) {
2760 return WERR_INVALID_NAME
;
2763 /* verify that the file exists */
2764 if (sys_stat(output_file
, &st
, false) != 0) {
2765 return WERR_INVALID_NAME
;
2768 fstrcpy(pjob
->filename
, output_file
);
2770 DEBUG(3, ("print_job_spool_file:"
2771 "External spooling activated\n"));
2773 /* we do not open the file until spooling is done */
2775 pjob
->status
= PJOB_SMBD_SPOOLING
;
2781 slprintf(pjob
->filename
, sizeof(pjob
->filename
)-1,
2782 "%s/%sXXXXXX", lp_pathname(talloc_tos(), snum
),
2783 PRINT_SPOOL_PREFIX
);
2784 mask
= umask(S_IRWXO
| S_IRWXG
);
2785 pjob
->fd
= mkstemp(pjob
->filename
);
2788 if (pjob
->fd
== -1) {
2789 werr
= map_werror_from_unix(errno
);
2790 if (W_ERROR_EQUAL(werr
, WERR_ACCESS_DENIED
)) {
2791 /* Common setup error, force a report. */
2792 DEBUG(0, ("print_job_spool_file: "
2793 "insufficient permissions to open spool "
2794 "file %s.\n", pjob
->filename
));
2796 /* Normal case, report at level 3 and above. */
2797 DEBUG(3, ("print_job_spool_file: "
2798 "can't open spool file %s\n",
2807 /***************************************************************************
2808 Start spooling a job - return the jobid.
2809 ***************************************************************************/
2811 WERROR
print_job_start(const struct auth_session_info
*server_info
,
2812 struct messaging_context
*msg_ctx
,
2813 const char *clientmachine
,
2814 int snum
, const char *docname
, const char *filename
,
2815 struct spoolss_DeviceMode
*devmode
, uint32_t *_jobid
)
2819 struct printjob pjob
;
2820 const char *sharename
= lp_const_servicename(snum
);
2821 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2826 return WERR_INTERNAL_DB_CORRUPTION
;
2829 path
= lp_pathname(talloc_tos(), snum
);
2831 werr
= print_job_checks(server_info
, msg_ctx
, snum
, &njobs
);
2832 if (!W_ERROR_IS_OK(werr
)) {
2833 release_print_db(pdb
);
2837 DEBUG(10, ("print_job_start: "
2838 "Queue %s number of jobs (%d), max printjobs = %d\n",
2839 sharename
, njobs
, lp_maxprintjobs(snum
)));
2841 werr
= allocate_print_jobid(pdb
, snum
, sharename
, &jobid
);
2842 if (!W_ERROR_IS_OK(werr
)) {
2846 /* create the database entry */
2850 pjob
.pid
= getpid();
2854 pjob
.starttime
= time(NULL
);
2855 pjob
.status
= LPQ_SPOOLING
;
2857 pjob
.spooled
= False
;
2859 pjob
.devmode
= devmode
;
2861 fstrcpy(pjob
.jobname
, docname
);
2863 fstrcpy(pjob
.clientmachine
, clientmachine
);
2865 fstrcpy(pjob
.user
, lp_printjob_username(snum
));
2866 standard_sub_advanced(sharename
, server_info
->unix_info
->sanitized_username
,
2867 path
, server_info
->unix_token
->gid
,
2868 server_info
->unix_info
->sanitized_username
,
2869 server_info
->info
->domain_name
,
2870 pjob
.user
, sizeof(pjob
.user
));
2872 fstrcpy(pjob
.queuename
, lp_const_servicename(snum
));
2874 /* we have a job entry - now create the spool file */
2875 werr
= print_job_spool_file(snum
, jobid
, filename
, &pjob
);
2876 if (!W_ERROR_IS_OK(werr
)) {
2880 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, &pjob
);
2882 /* Update the 'jobs added' entry used by print_queue_status. */
2883 add_to_jobs_added(pdb
, jobid
);
2885 /* Ensure we keep a rough count of the number of total jobs... */
2886 tdb_change_int32_atomic(pdb
->tdb
, "INFO/total_jobs", &njobs
, 1);
2888 release_print_db(pdb
);
2895 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
2898 release_print_db(pdb
);
2900 DEBUG(3, ("print_job_start: returning fail. "
2901 "Error = %s\n", win_errstr(werr
)));
2905 /****************************************************************************
2906 Update the number of pages spooled to jobid
2907 ****************************************************************************/
2909 void print_job_endpage(struct messaging_context
*msg_ctx
,
2910 int snum
, uint32 jobid
)
2912 const char* sharename
= lp_const_servicename(snum
);
2913 struct printjob
*pjob
;
2914 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2915 if (tmp_ctx
== NULL
) {
2919 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2923 /* don't allow another process to get this info - it is meaningless */
2924 if (pjob
->pid
!= getpid()) {
2929 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, pjob
);
2931 talloc_free(tmp_ctx
);
2934 /****************************************************************************
2935 Print a file - called on closing the file. This spools the job.
2936 If normal close is false then we're tearing down the jobs - treat as an
2938 ****************************************************************************/
2940 NTSTATUS
print_job_end(struct messaging_context
*msg_ctx
, int snum
,
2941 uint32 jobid
, enum file_close_type close_type
)
2943 const char* sharename
= lp_const_servicename(snum
);
2944 struct printjob
*pjob
;
2946 SMB_STRUCT_STAT sbuf
;
2947 struct printif
*current_printif
= get_printer_fns(snum
);
2948 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
2950 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2951 if (tmp_ctx
== NULL
) {
2952 return NT_STATUS_NO_MEMORY
;
2955 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2957 status
= NT_STATUS_PRINT_CANCELLED
;
2961 if (pjob
->spooled
|| pjob
->pid
!= getpid()) {
2962 status
= NT_STATUS_ACCESS_DENIED
;
2966 if (close_type
== NORMAL_CLOSE
|| close_type
== SHUTDOWN_CLOSE
) {
2967 if (pjob
->status
== PJOB_SMBD_SPOOLING
) {
2968 /* take over the file now, smbd is done */
2969 if (sys_stat(pjob
->filename
, &sbuf
, false) != 0) {
2970 status
= map_nt_error_from_unix(errno
);
2971 DEBUG(3, ("print_job_end: "
2972 "stat file failed for jobid %d\n",
2977 pjob
->status
= LPQ_SPOOLING
;
2981 if ((sys_fstat(pjob
->fd
, &sbuf
, false) != 0)) {
2982 status
= map_nt_error_from_unix(errno
);
2984 DEBUG(3, ("print_job_end: "
2985 "stat file failed for jobid %d\n",
2993 pjob
->size
= sbuf
.st_ex_size
;
2997 * Not a normal close, something has gone wrong. Cleanup.
2999 if (pjob
->fd
!= -1) {
3005 /* Technically, this is not quite right. If the printer has a separator
3006 * page turned on, the NT spooler prints the separator page even if the
3007 * print job is 0 bytes. 010215 JRR */
3008 if (pjob
->size
== 0 || pjob
->status
== LPQ_DELETING
) {
3009 /* don't bother spooling empty files or something being deleted. */
3010 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
3011 pjob
->filename
, pjob
->size
? "deleted" : "zero length" ));
3012 unlink(pjob
->filename
);
3013 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
3014 return NT_STATUS_OK
;
3017 /* don't strip out characters like '$' from the printername */
3018 lpq_cmd
= talloc_string_sub2(tmp_ctx
,
3019 lp_lpqcommand(talloc_tos(), snum
),
3021 lp_printername(talloc_tos(), snum
),
3022 false, false, false);
3023 if (lpq_cmd
== NULL
) {
3024 status
= NT_STATUS_PRINT_CANCELLED
;
3027 lpq_cmd
= talloc_sub_advanced(tmp_ctx
,
3028 lp_servicename(talloc_tos(), snum
),
3029 current_user_info
.unix_name
,
3031 current_user
.ut
.gid
,
3032 get_current_username(),
3033 current_user_info
.domain
,
3035 if (lpq_cmd
== NULL
) {
3036 status
= NT_STATUS_PRINT_CANCELLED
;
3040 ret
= (*(current_printif
->job_submit
))(snum
, pjob
,
3041 current_printif
->type
, lpq_cmd
);
3043 status
= NT_STATUS_PRINT_CANCELLED
;
3047 /* The print job has been successfully handed over to the back-end */
3049 pjob
->spooled
= True
;
3050 pjob
->status
= LPQ_QUEUED
;
3051 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, pjob
);
3053 /* make sure the database is up to date */
3054 if (print_cache_expired(lp_const_servicename(snum
), True
))
3055 print_queue_update(msg_ctx
, snum
, False
);
3057 return NT_STATUS_OK
;
3061 /* The print job was not successfully started. Cleanup */
3062 /* Still need to add proper error return propagation! 010122:JRR */
3064 unlink(pjob
->filename
);
3065 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
3067 talloc_free(tmp_ctx
);
3071 /****************************************************************************
3072 Get a snapshot of jobs in the system without traversing.
3073 ****************************************************************************/
3075 static bool get_stored_queue_info(struct messaging_context
*msg_ctx
,
3076 struct tdb_print_db
*pdb
, int snum
,
3077 int *pcount
, print_queue_struct
**ppqueue
)
3079 TDB_DATA data
, cgdata
, jcdata
;
3080 print_queue_struct
*queue
= NULL
;
3082 uint32 extra_count
= 0;
3083 uint32_t changed_count
= 0;
3084 int total_count
= 0;
3087 int max_reported_jobs
= lp_max_reported_jobs(snum
);
3089 const char* sharename
= lp_servicename(talloc_tos(), snum
);
3090 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
3091 if (tmp_ctx
== NULL
) {
3095 /* make sure the database is up to date */
3096 if (print_cache_expired(lp_const_servicename(snum
), True
))
3097 print_queue_update(msg_ctx
, snum
, False
);
3103 ZERO_STRUCT(cgdata
);
3105 /* Get the stored queue data. */
3106 data
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data("INFO/linear_queue_array"));
3108 if (data
.dptr
&& data
.dsize
>= sizeof(qcount
))
3109 len
+= tdb_unpack(data
.dptr
+ len
, data
.dsize
- len
, "d", &qcount
);
3111 /* Get the added jobs list. */
3112 cgdata
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data("INFO/jobs_added"));
3113 if (cgdata
.dptr
!= NULL
&& (cgdata
.dsize
% 4 == 0))
3114 extra_count
= cgdata
.dsize
/4;
3116 /* Get the changed jobs list. */
3117 jcdata
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data("INFO/jobs_changed"));
3118 if (jcdata
.dptr
!= NULL
&& (jcdata
.dsize
% 4 == 0))
3119 changed_count
= jcdata
.dsize
/ 4;
3121 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount
, (unsigned int)extra_count
));
3123 /* Allocate the queue size. */
3124 if (qcount
== 0 && extra_count
== 0)
3127 if ((queue
= SMB_MALLOC_ARRAY(print_queue_struct
, qcount
+ extra_count
)) == NULL
)
3130 /* Retrieve the linearised queue data. */
3132 for(i
= 0; i
< qcount
; i
++) {
3133 uint32 qjob
, qsize
, qpage_count
, qstatus
, qpriority
, qtime
;
3134 len
+= tdb_unpack(data
.dptr
+ len
, data
.dsize
- len
, "ddddddff",
3143 queue
[i
].sysjob
= qjob
;
3144 queue
[i
].size
= qsize
;
3145 queue
[i
].page_count
= qpage_count
;
3146 queue
[i
].status
= qstatus
;
3147 queue
[i
].priority
= qpriority
;
3148 queue
[i
].time
= qtime
;
3151 total_count
= qcount
;
3153 /* Add new jobids to the queue. */
3154 for (i
= 0; i
< extra_count
; i
++) {
3156 struct printjob
*pjob
;
3158 jobid
= IVAL(cgdata
.dptr
, i
*4);
3159 DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid
));
3160 pjob
= print_job_find(tmp_ctx
, lp_const_servicename(snum
), jobid
);
3162 DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid
));
3163 remove_from_jobs_added(sharename
, jobid
);
3167 queue
[total_count
].sysjob
= pjob
->sysjob
;
3168 queue
[total_count
].size
= pjob
->size
;
3169 queue
[total_count
].page_count
= pjob
->page_count
;
3170 queue
[total_count
].status
= pjob
->status
;
3171 queue
[total_count
].priority
= 1;
3172 queue
[total_count
].time
= pjob
->starttime
;
3173 fstrcpy(queue
[total_count
].fs_user
, pjob
->user
);
3174 fstrcpy(queue
[total_count
].fs_file
, pjob
->jobname
);
3179 /* Update the changed jobids. */
3180 for (i
= 0; i
< changed_count
; i
++) {
3181 uint32_t jobid
= IVAL(jcdata
.dptr
, i
* 4);
3182 struct printjob
*pjob
;
3186 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
3188 DEBUG(5,("get_stored_queue_info: failed to find "
3189 "changed job = %u\n",
3190 (unsigned int)jobid
));
3191 remove_from_jobs_changed(sharename
, jobid
);
3195 for (j
= 0; j
< total_count
; j
++) {
3196 if (queue
[j
].sysjob
== pjob
->sysjob
) {
3203 DEBUG(5,("get_stored_queue_info: changed job: %u\n",
3204 (unsigned int)jobid
));
3206 queue
[j
].sysjob
= pjob
->sysjob
;
3207 queue
[j
].size
= pjob
->size
;
3208 queue
[j
].page_count
= pjob
->page_count
;
3209 queue
[j
].status
= pjob
->status
;
3210 queue
[j
].priority
= 1;
3211 queue
[j
].time
= pjob
->starttime
;
3212 fstrcpy(queue
[j
].fs_user
, pjob
->user
);
3213 fstrcpy(queue
[j
].fs_file
, pjob
->jobname
);
3216 DEBUG(5,("updated queue[%u], jobid: %u, sysjob: %u, "
3218 (unsigned int)j
, (unsigned int)jobid
,
3219 (unsigned int)queue
[j
].sysjob
, pjob
->jobname
));
3222 remove_from_jobs_changed(sharename
, jobid
);
3225 /* Sort the queue by submission time otherwise they are displayed
3228 TYPESAFE_QSORT(queue
, total_count
, printjob_comp
);
3230 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count
));
3232 if (max_reported_jobs
&& total_count
> max_reported_jobs
)
3233 total_count
= max_reported_jobs
;
3236 *pcount
= total_count
;
3242 SAFE_FREE(data
.dptr
);
3243 SAFE_FREE(cgdata
.dptr
);
3244 talloc_free(tmp_ctx
);
3248 /****************************************************************************
3249 Get a printer queue listing.
3250 set queue = NULL and status = NULL if you just want to update the cache
3251 ****************************************************************************/
3253 int print_queue_status(struct messaging_context
*msg_ctx
, int snum
,
3254 print_queue_struct
**ppqueue
,
3255 print_status_struct
*status
)
3259 const char *sharename
;
3260 struct tdb_print_db
*pdb
;
3263 /* make sure the database is up to date */
3265 if (print_cache_expired(lp_const_servicename(snum
), True
))
3266 print_queue_update(msg_ctx
, snum
, False
);
3268 /* return if we are done */
3269 if ( !ppqueue
|| !status
)
3273 sharename
= lp_const_servicename(snum
);
3274 pdb
= get_print_db_byname(sharename
);
3280 * Fetch the queue status. We must do this first, as there may
3281 * be no jobs in the queue.
3284 ZERO_STRUCTP(status
);
3285 slprintf(keystr
, sizeof(keystr
)-1, "STATUS/%s", sharename
);
3286 key
= string_tdb_data(keystr
);
3288 data
= tdb_fetch_compat(pdb
->tdb
, key
);
3290 if (data
.dsize
== sizeof(*status
)) {
3291 /* this memcpy is ok since the status struct was
3292 not packed before storing it in the tdb */
3293 memcpy(status
, data
.dptr
, sizeof(*status
));
3295 SAFE_FREE(data
.dptr
);
3299 * Now, fetch the print queue information. We first count the number
3300 * of entries, and then only retrieve the queue if necessary.
3303 if (!get_stored_queue_info(msg_ctx
, pdb
, snum
, &count
, ppqueue
)) {
3304 release_print_db(pdb
);
3308 release_print_db(pdb
);
3312 /****************************************************************************
3314 ****************************************************************************/
3316 WERROR
print_queue_pause(const struct auth_session_info
*server_info
,
3317 struct messaging_context
*msg_ctx
, int snum
)
3320 struct printif
*current_printif
= get_printer_fns( snum
);
3322 if (!print_access_check(server_info
, msg_ctx
, snum
,
3323 PRINTER_ACCESS_ADMINISTER
)) {
3324 return WERR_ACCESS_DENIED
;
3330 ret
= (*(current_printif
->queue_pause
))(snum
);
3335 return WERR_INVALID_PARAM
;
3338 /* force update the database */
3339 print_cache_flush(lp_const_servicename(snum
));
3341 /* Send a printer notify message */
3343 notify_printer_status(server_event_context(), msg_ctx
, snum
,
3344 PRINTER_STATUS_PAUSED
);
3349 /****************************************************************************
3351 ****************************************************************************/
3353 WERROR
print_queue_resume(const struct auth_session_info
*server_info
,
3354 struct messaging_context
*msg_ctx
, int snum
)
3357 struct printif
*current_printif
= get_printer_fns( snum
);
3359 if (!print_access_check(server_info
, msg_ctx
, snum
,
3360 PRINTER_ACCESS_ADMINISTER
)) {
3361 return WERR_ACCESS_DENIED
;
3366 ret
= (*(current_printif
->queue_resume
))(snum
);
3371 return WERR_INVALID_PARAM
;
3374 /* make sure the database is up to date */
3375 if (print_cache_expired(lp_const_servicename(snum
), True
))
3376 print_queue_update(msg_ctx
, snum
, True
);
3378 /* Send a printer notify message */
3380 notify_printer_status(server_event_context(), msg_ctx
, snum
,
3386 /****************************************************************************
3387 Purge a queue - implemented by deleting all jobs that we can delete.
3388 ****************************************************************************/
3390 WERROR
print_queue_purge(const struct auth_session_info
*server_info
,
3391 struct messaging_context
*msg_ctx
, int snum
)
3393 print_queue_struct
*queue
;
3394 print_status_struct status
;
3398 /* Force and update so the count is accurate (i.e. not a cached count) */
3399 print_queue_update(msg_ctx
, snum
, True
);
3401 can_job_admin
= print_access_check(server_info
,
3404 JOB_ACCESS_ADMINISTER
);
3405 njobs
= print_queue_status(msg_ctx
, snum
, &queue
, &status
);
3407 if ( can_job_admin
)
3410 for (i
= 0; i
< njobs
; i
++) {
3411 struct tdb_print_db
*pdb
;
3414 pdb
= get_print_db_byname(lp_const_servicename(snum
));
3416 DEBUG(1, ("failed to find printdb for %s\n",
3417 lp_const_servicename(snum
)));
3420 jobid
= sysjob_to_jobid_pdb(pdb
, queue
[i
].sysjob
);
3421 if (jobid
== (uint32_t)-1) {
3422 DEBUG(2, ("jobid for system job %d not found\n",
3424 continue; /* unix job */
3426 owner
= is_owner(server_info
, lp_const_servicename(snum
),
3429 if (owner
|| can_job_admin
) {
3430 print_job_delete1(server_event_context(), msg_ctx
,
3435 if ( can_job_admin
)
3438 /* update the cache */
3439 print_queue_update(msg_ctx
, snum
, True
);