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"
39 #include "lib/sys_rw_data.h"
41 extern struct current_user current_user
;
42 extern userdom_struct current_user_info
;
44 /* Current printer interface */
45 static bool remove_from_jobs_added(const char* sharename
, uint32 jobid
);
48 the printing backend revolves around a tdb database that stores the
49 SMB view of the print queue
51 The key for this database is a jobid - a internally generated number that
52 uniquely identifies a print job
54 reading the print queue involves two steps:
55 - possibly running lpq and updating the internal database from that
56 - reading entries from the database
58 jobids are assigned when a job starts spooling.
61 static TDB_CONTEXT
*rap_tdb
;
62 static uint16 next_rap_jobid
;
63 struct rap_jobid_key
{
68 /***************************************************************************
69 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
70 bit RPC jobids.... JRA.
71 ***************************************************************************/
73 uint16
pjobid_to_rap(const char* sharename
, uint32 jobid
)
77 struct rap_jobid_key jinfo
;
80 DEBUG(10,("pjobid_to_rap: called.\n"));
83 /* Create the in-memory tdb. */
84 rap_tdb
= tdb_open_log(NULL
, 0, TDB_INTERNAL
, (O_RDWR
|O_CREAT
), 0644);
90 fstrcpy( jinfo
.sharename
, sharename
);
92 key
.dptr
= (uint8
*)&jinfo
;
93 key
.dsize
= sizeof(jinfo
);
95 data
= tdb_fetch_compat(rap_tdb
, key
);
96 if (data
.dptr
&& data
.dsize
== sizeof(uint16
)) {
97 rap_jobid
= SVAL(data
.dptr
, 0);
99 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
100 (unsigned int)jobid
, (unsigned int)rap_jobid
));
103 SAFE_FREE(data
.dptr
);
104 /* Not found - create and store mapping. */
105 rap_jobid
= ++next_rap_jobid
;
107 rap_jobid
= ++next_rap_jobid
;
108 SSVAL(buf
,0,rap_jobid
);
110 data
.dsize
= sizeof(rap_jobid
);
111 tdb_store(rap_tdb
, key
, data
, TDB_REPLACE
);
112 tdb_store(rap_tdb
, data
, key
, TDB_REPLACE
);
114 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
115 (unsigned int)jobid
, (unsigned int)rap_jobid
));
119 bool rap_to_pjobid(uint16 rap_jobid
, fstring sharename
, uint32
*pjobid
)
124 DEBUG(10,("rap_to_pjobid called.\n"));
129 SSVAL(buf
,0,rap_jobid
);
131 key
.dsize
= sizeof(rap_jobid
);
132 data
= tdb_fetch_compat(rap_tdb
, key
);
133 if ( data
.dptr
&& data
.dsize
== sizeof(struct rap_jobid_key
) )
135 struct rap_jobid_key
*jinfo
= (struct rap_jobid_key
*)data
.dptr
;
136 if (sharename
!= NULL
) {
137 fstrcpy( sharename
, jinfo
->sharename
);
139 *pjobid
= jinfo
->jobid
;
140 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
141 (unsigned int)*pjobid
, (unsigned int)rap_jobid
));
142 SAFE_FREE(data
.dptr
);
146 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
147 (unsigned int)rap_jobid
));
148 SAFE_FREE(data
.dptr
);
152 void rap_jobid_delete(const char* sharename
, uint32 jobid
)
156 struct rap_jobid_key jinfo
;
159 DEBUG(10,("rap_jobid_delete: called.\n"));
164 ZERO_STRUCT( jinfo
);
165 fstrcpy( jinfo
.sharename
, sharename
);
167 key
.dptr
= (uint8
*)&jinfo
;
168 key
.dsize
= sizeof(jinfo
);
170 data
= tdb_fetch_compat(rap_tdb
, key
);
171 if (!data
.dptr
|| (data
.dsize
!= sizeof(uint16
))) {
172 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
173 (unsigned int)jobid
));
174 SAFE_FREE(data
.dptr
);
178 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
179 (unsigned int)jobid
));
181 rap_jobid
= SVAL(data
.dptr
, 0);
182 SAFE_FREE(data
.dptr
);
183 SSVAL(buf
,0,rap_jobid
);
185 data
.dsize
= sizeof(rap_jobid
);
186 tdb_delete(rap_tdb
, key
);
187 tdb_delete(rap_tdb
, data
);
190 static int get_queue_status(const char* sharename
, print_status_struct
*);
192 /****************************************************************************
193 Initialise the printing backend. Called once at startup before the fork().
194 ****************************************************************************/
196 bool print_backend_init(struct messaging_context
*msg_ctx
)
198 const char *sversion
= "INFO/version";
199 int services
= lp_numservices();
202 char *print_cache_path
;
204 if (!printer_list_parent_init()) {
208 print_cache_path
= cache_path("printing");
209 if (print_cache_path
== NULL
) {
212 ok
= directory_create_or_exist(print_cache_path
, 0755);
213 TALLOC_FREE(print_cache_path
);
218 print_cache_path
= cache_path("printing.tdb");
219 if (print_cache_path
== NULL
) {
222 unlink(print_cache_path
);
223 TALLOC_FREE(print_cache_path
);
225 /* handle a Samba upgrade */
227 for (snum
= 0; snum
< services
; snum
++) {
228 struct tdb_print_db
*pdb
;
229 if (!lp_printable(snum
))
232 pdb
= get_print_db_byname(lp_const_servicename(snum
));
235 if (tdb_lock_bystring(pdb
->tdb
, sversion
) != 0) {
236 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum
) ));
237 release_print_db(pdb
);
240 if (tdb_fetch_int32(pdb
->tdb
, sversion
) != PRINT_DATABASE_VERSION
) {
241 tdb_wipe_all(pdb
->tdb
);
242 tdb_store_int32(pdb
->tdb
, sversion
, PRINT_DATABASE_VERSION
);
244 tdb_unlock_bystring(pdb
->tdb
, sversion
);
245 release_print_db(pdb
);
248 close_all_print_db(); /* Don't leave any open. */
250 /* do NT print initialization... */
251 return nt_printing_init(msg_ctx
);
254 /****************************************************************************
255 Shut down printing backend. Called once at shutdown to close the tdb.
256 ****************************************************************************/
258 void printing_end(void)
260 close_all_print_db(); /* Don't leave any open. */
263 /****************************************************************************
264 Retrieve the set of printing functions for a given service. This allows
265 us to set the printer function table based on the value of the 'printing'
268 Use the generic interface as the default and only use cups interface only
269 when asked for (and only when supported)
270 ****************************************************************************/
272 static struct printif
*get_printer_fns_from_type( enum printing_types type
)
274 struct printif
*printer_fns
= &generic_printif
;
277 if ( type
== PRINT_CUPS
) {
278 printer_fns
= &cups_printif
;
280 #endif /* HAVE_CUPS */
283 if ( type
== PRINT_IPRINT
) {
284 printer_fns
= &iprint_printif
;
286 #endif /* HAVE_IPRINT */
288 printer_fns
->type
= type
;
293 static struct printif
*get_printer_fns( int snum
)
295 return get_printer_fns_from_type( (enum printing_types
)lp_printing(snum
) );
299 /****************************************************************************
300 Useful function to generate a tdb key.
301 ****************************************************************************/
303 static TDB_DATA
print_key(uint32 jobid
, uint32
*tmp
)
307 SIVAL(tmp
, 0, jobid
);
308 ret
.dptr
= (uint8
*)tmp
;
309 ret
.dsize
= sizeof(*tmp
);
313 /****************************************************************************
314 Pack the devicemode to store it in a tdb.
315 ****************************************************************************/
316 static int pack_devicemode(struct spoolss_DeviceMode
*devmode
, uint8
*buf
, int buflen
)
318 enum ndr_err_code ndr_err
;
323 ndr_err
= ndr_push_struct_blob(&blob
, talloc_tos(),
325 (ndr_push_flags_fn_t
)
326 ndr_push_spoolss_DeviceMode
);
327 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
328 DEBUG(10, ("pack_devicemode: "
329 "error encoding spoolss_DeviceMode\n"));
336 len
= tdb_pack(buf
, buflen
, "B", blob
.length
, blob
.data
);
339 DEBUG(8, ("Packed devicemode [%s]\n", devmode
->formname
));
346 /****************************************************************************
347 Unpack the devicemode to store it in a tdb.
348 ****************************************************************************/
349 static int unpack_devicemode(TALLOC_CTX
*mem_ctx
,
350 const uint8
*buf
, int buflen
,
351 struct spoolss_DeviceMode
**devmode
)
353 struct spoolss_DeviceMode
*dm
;
354 enum ndr_err_code ndr_err
;
362 len
= tdb_unpack(buf
, buflen
, "B", &data_len
, &data
);
367 dm
= talloc_zero(mem_ctx
, struct spoolss_DeviceMode
);
372 blob
= data_blob_const(data
, data_len
);
374 ndr_err
= ndr_pull_struct_blob(&blob
, dm
, dm
,
375 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_DeviceMode
);
376 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
377 DEBUG(10, ("unpack_devicemode: "
378 "error parsing spoolss_DeviceMode\n"));
382 DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
383 dm
->devicename
, dm
->formname
));
384 if (dm
->driverextra_data
.data
) {
385 DEBUG(8, ("with a private section of %d bytes\n",
386 dm
->__driverextra_length
));
396 /***********************************************************************
397 unpack a pjob from a tdb buffer
398 ***********************************************************************/
400 static int unpack_pjob(TALLOC_CTX
*mem_ctx
, uint8
*buf
, int buflen
,
401 struct printjob
*pjob
)
405 uint32 pjpid
, pjjobid
, pjsysjob
, pjfd
, pjstarttime
, pjstatus
;
406 uint32 pjsize
, pjpage_count
, pjspooled
, pjsmbjob
;
412 len
+= tdb_unpack(buf
+len
, buflen
-len
, "ddddddddddfffff",
433 used
= unpack_devicemode(mem_ctx
, buf
+len
, buflen
-len
, &pjob
->devmode
);
441 pjob
->jobid
= pjjobid
;
442 pjob
->sysjob
= pjsysjob
;
444 pjob
->starttime
= pjstarttime
;
445 pjob
->status
= pjstatus
;
447 pjob
->page_count
= pjpage_count
;
448 pjob
->spooled
= pjspooled
;
449 pjob
->smbjob
= pjsmbjob
;
455 /****************************************************************************
456 Useful function to find a print job in the database.
457 ****************************************************************************/
459 static struct printjob
*print_job_find(TALLOC_CTX
*mem_ctx
,
460 const char *sharename
,
463 struct printjob
*pjob
;
466 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
468 DEBUG(10,("print_job_find: looking up job %u for share %s\n",
469 (unsigned int)jobid
, sharename
));
475 ret
= tdb_fetch_compat(pdb
->tdb
, print_key(jobid
, &tmp
));
476 release_print_db(pdb
);
479 DEBUG(10, ("print_job_find: failed to find jobid %u.\n",
484 pjob
= talloc_zero(mem_ctx
, struct printjob
);
489 if (unpack_pjob(mem_ctx
, ret
.dptr
, ret
.dsize
, pjob
) == -1) {
490 DEBUG(10, ("failed to unpack jobid %u.\n", jobid
));
496 DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
497 pjob
->sysjob
, jobid
));
498 SMB_ASSERT(pjob
->jobid
== jobid
);
505 struct job_traverse_state
{
510 /* find spoolss jobid based on sysjob */
511 static int sysjob_to_jobid_traverse_fn(TDB_CONTEXT
*the_tdb
, TDB_DATA key
,
512 TDB_DATA data
, void *private_data
)
514 struct printjob
*pjob
;
515 struct job_traverse_state
*state
=
516 (struct job_traverse_state
*)private_data
;
518 if (!data
.dptr
|| data
.dsize
== 0)
521 pjob
= (struct printjob
*)data
.dptr
;
522 if (key
.dsize
!= sizeof(uint32
))
525 if (state
->sysjob
== pjob
->sysjob
) {
526 state
->jobid
= pjob
->jobid
;
533 uint32
sysjob_to_jobid_pdb(struct tdb_print_db
*pdb
, int sysjob
)
535 struct job_traverse_state state
;
537 state
.sysjob
= sysjob
;
538 state
.jobid
= (uint32_t)-1;
540 tdb_traverse(pdb
->tdb
, sysjob_to_jobid_traverse_fn
, &state
);
545 /****************************************************************************
546 This is a *horribly expensive call as we have to iterate through all the
547 current printer tdb's. Don't do this often ! JRA.
548 ****************************************************************************/
550 uint32
sysjob_to_jobid(int unix_jobid
)
552 int services
= lp_numservices();
554 struct job_traverse_state state
;
556 state
.sysjob
= unix_jobid
;
557 state
.jobid
= (uint32_t)-1;
559 for (snum
= 0; snum
< services
; snum
++) {
560 struct tdb_print_db
*pdb
;
561 if (!lp_printable(snum
))
563 pdb
= get_print_db_byname(lp_const_servicename(snum
));
567 tdb_traverse(pdb
->tdb
, sysjob_to_jobid_traverse_fn
, &state
);
568 release_print_db(pdb
);
569 if (state
.jobid
!= (uint32_t)-1)
575 /* find sysjob based on spoolss jobid */
576 static int jobid_to_sysjob_traverse_fn(TDB_CONTEXT
*the_tdb
, TDB_DATA key
,
577 TDB_DATA data
, void *private_data
)
579 struct printjob
*pjob
;
580 struct job_traverse_state
*state
=
581 (struct job_traverse_state
*)private_data
;
583 if (!data
.dptr
|| data
.dsize
== 0)
586 pjob
= (struct printjob
*)data
.dptr
;
587 if (key
.dsize
!= sizeof(uint32_t))
590 if (state
->jobid
== pjob
->jobid
) {
591 state
->sysjob
= pjob
->sysjob
;
598 int jobid_to_sysjob_pdb(struct tdb_print_db
*pdb
, uint32_t jobid
)
600 struct job_traverse_state state
;
605 tdb_traverse(pdb
->tdb
, jobid_to_sysjob_traverse_fn
, &state
);
610 /****************************************************************************
611 Send notifications based on what has changed after a pjob_store.
612 ****************************************************************************/
614 static const struct {
616 uint32_t spoolss_status
;
617 } lpq_to_spoolss_status_map
[] = {
618 { LPQ_QUEUED
, JOB_STATUS_QUEUED
},
619 { LPQ_PAUSED
, JOB_STATUS_PAUSED
},
620 { LPQ_SPOOLING
, JOB_STATUS_SPOOLING
},
621 { LPQ_PRINTING
, JOB_STATUS_PRINTING
},
622 { LPQ_DELETING
, JOB_STATUS_DELETING
},
623 { LPQ_OFFLINE
, JOB_STATUS_OFFLINE
},
624 { LPQ_PAPEROUT
, JOB_STATUS_PAPEROUT
},
625 { LPQ_PRINTED
, JOB_STATUS_PRINTED
},
626 { LPQ_DELETED
, JOB_STATUS_DELETED
},
627 { LPQ_BLOCKED
, JOB_STATUS_BLOCKED_DEVQ
},
628 { LPQ_USER_INTERVENTION
, JOB_STATUS_USER_INTERVENTION
},
632 /* Convert a lpq status value stored in printing.tdb into the
633 appropriate win32 API constant. */
635 static uint32
map_to_spoolss_status(uint32 lpq_status
)
639 while (lpq_to_spoolss_status_map
[i
].lpq_status
!= -1) {
640 if (lpq_to_spoolss_status_map
[i
].lpq_status
== lpq_status
)
641 return lpq_to_spoolss_status_map
[i
].spoolss_status
;
648 /***************************************************************************
649 Append a jobid to the 'jobs changed' list.
650 ***************************************************************************/
652 static bool add_to_jobs_changed(struct tdb_print_db
*pdb
, uint32_t jobid
)
655 uint32_t store_jobid
;
657 SIVAL(&store_jobid
, 0, jobid
);
658 data
.dptr
= (uint8
*) &store_jobid
;
661 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid
));
663 return (tdb_append(pdb
->tdb
, string_tdb_data("INFO/jobs_changed"),
667 /***************************************************************************
668 Remove a jobid from the 'jobs changed' list.
669 ***************************************************************************/
671 static bool remove_from_jobs_changed(const char* sharename
, uint32_t jobid
)
673 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
677 bool gotlock
= False
;
685 key
= string_tdb_data("INFO/jobs_changed");
687 if (tdb_chainlock_with_timeout(pdb
->tdb
, key
, 5) != 0)
692 data
= tdb_fetch_compat(pdb
->tdb
, key
);
694 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0))
697 job_count
= data
.dsize
/ 4;
698 for (i
= 0; i
< job_count
; i
++) {
701 ch_jobid
= IVAL(data
.dptr
, i
*4);
702 if (ch_jobid
== jobid
) {
703 if (i
< job_count
-1 )
704 memmove(data
.dptr
+ (i
*4), data
.dptr
+ (i
*4) + 4, (job_count
- i
- 1)*4 );
706 if (tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
) != 0)
716 tdb_chainunlock(pdb
->tdb
, key
);
717 SAFE_FREE(data
.dptr
);
718 release_print_db(pdb
);
720 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid
));
722 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid
));
726 static void pjob_store_notify(struct tevent_context
*ev
,
727 struct messaging_context
*msg_ctx
,
728 const char* sharename
, uint32 jobid
,
729 struct printjob
*old_data
,
730 struct printjob
*new_data
,
733 bool new_job
= false;
734 bool changed
= false;
736 if (old_data
== NULL
) {
740 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
741 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
742 time first or else we'll end up with potential alignment
743 errors. I don't think the systemtime should be spooled as
744 a string, but this gets us around that error.
745 --jerry (i'll feel dirty for this) */
748 notify_job_submitted(ev
, msg_ctx
,
749 sharename
, jobid
, new_data
->starttime
);
750 notify_job_username(ev
, msg_ctx
,
751 sharename
, jobid
, new_data
->user
);
752 notify_job_name(ev
, msg_ctx
,
753 sharename
, jobid
, new_data
->jobname
);
754 notify_job_status(ev
, msg_ctx
,
755 sharename
, jobid
, map_to_spoolss_status(new_data
->status
));
756 notify_job_total_bytes(ev
, msg_ctx
,
757 sharename
, jobid
, new_data
->size
);
758 notify_job_total_pages(ev
, msg_ctx
,
759 sharename
, jobid
, new_data
->page_count
);
761 if (!strequal(old_data
->jobname
, new_data
->jobname
)) {
762 notify_job_name(ev
, msg_ctx
, sharename
,
763 jobid
, new_data
->jobname
);
767 if (old_data
->status
!= new_data
->status
) {
768 notify_job_status(ev
, msg_ctx
,
770 map_to_spoolss_status(new_data
->status
));
773 if (old_data
->size
!= new_data
->size
) {
774 notify_job_total_bytes(ev
, msg_ctx
,
775 sharename
, jobid
, new_data
->size
);
778 if (old_data
->page_count
!= new_data
->page_count
) {
779 notify_job_total_pages(ev
, msg_ctx
,
781 new_data
->page_count
);
788 /****************************************************************************
789 Store a job structure back to the database.
790 ****************************************************************************/
792 static bool pjob_store(struct tevent_context
*ev
,
793 struct messaging_context
*msg_ctx
,
794 const char* sharename
, uint32 jobid
,
795 struct printjob
*pjob
)
798 TDB_DATA old_data
, new_data
;
800 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
802 int len
, newlen
, buflen
;
810 old_data
= tdb_fetch_compat(pdb
->tdb
, print_key(jobid
, &tmp
));
812 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
819 len
+= tdb_pack(buf
+len
, buflen
-len
, "ddddddddddfffff",
822 (uint32
)pjob
->sysjob
,
824 (uint32
)pjob
->starttime
,
825 (uint32
)pjob
->status
,
827 (uint32
)pjob
->page_count
,
828 (uint32
)pjob
->spooled
,
829 (uint32
)pjob
->smbjob
,
836 len
+= pack_devicemode(pjob
->devmode
, buf
+len
, buflen
-len
);
839 buf
= (uint8
*)SMB_REALLOC(buf
, len
);
841 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
846 } while ( buflen
!= len
);
852 new_data
.dsize
= len
;
853 ret
= (tdb_store(pdb
->tdb
, print_key(jobid
, &tmp
), new_data
,
856 /* Send notify updates for what has changed */
859 bool changed
= false;
860 struct printjob old_pjob
;
862 if (old_data
.dsize
) {
863 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
867 len
= unpack_pjob(tmp_ctx
, old_data
.dptr
,
868 old_data
.dsize
, &old_pjob
);
870 pjob_store_notify(ev
,
872 sharename
, jobid
, &old_pjob
,
876 add_to_jobs_changed(pdb
, jobid
);
879 talloc_free(tmp_ctx
);
883 pjob_store_notify(ev
, msg_ctx
,
884 sharename
, jobid
, NULL
, pjob
,
890 release_print_db(pdb
);
891 SAFE_FREE( old_data
.dptr
);
897 /****************************************************************************
898 Remove a job structure from the database.
899 ****************************************************************************/
901 static void pjob_delete(struct tevent_context
*ev
,
902 struct messaging_context
*msg_ctx
,
903 const char* sharename
, uint32 jobid
)
906 struct printjob
*pjob
;
907 uint32 job_status
= 0;
908 struct tdb_print_db
*pdb
;
909 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
910 if (tmp_ctx
== NULL
) {
914 pdb
= get_print_db_byname(sharename
);
919 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
921 DEBUG(5, ("we were asked to delete nonexistent job %u\n",
926 /* We must cycle through JOB_STATUS_DELETING and
927 JOB_STATUS_DELETED for the port monitor to delete the job
930 job_status
= JOB_STATUS_DELETING
|JOB_STATUS_DELETED
;
931 notify_job_status(ev
, msg_ctx
, sharename
, jobid
, job_status
);
933 /* Remove from printing.tdb */
935 tdb_delete(pdb
->tdb
, print_key(jobid
, &tmp
));
936 remove_from_jobs_added(sharename
, jobid
);
937 rap_jobid_delete(sharename
, jobid
);
939 release_print_db(pdb
);
941 talloc_free(tmp_ctx
);
944 /****************************************************************************
945 List a unix job in the print database.
946 ****************************************************************************/
948 static void print_unix_job(struct tevent_context
*ev
,
949 struct messaging_context
*msg_ctx
,
950 const char *sharename
, print_queue_struct
*q
,
953 struct printjob pj
, *old_pj
;
954 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
955 if (tmp_ctx
== NULL
) {
959 if (jobid
== (uint32
)-1) {
960 jobid
= q
->sysjob
+ UNIX_JOB_START
;
963 /* Preserve the timestamp on an existing unix print job */
965 old_pj
= print_job_find(tmp_ctx
, sharename
, jobid
);
971 pj
.sysjob
= q
->sysjob
;
973 pj
.starttime
= old_pj
? old_pj
->starttime
: q
->time
;
974 pj
.status
= q
->status
;
977 fstrcpy(pj
.filename
, old_pj
? old_pj
->filename
: "");
978 if (jobid
< UNIX_JOB_START
) {
980 fstrcpy(pj
.jobname
, old_pj
? old_pj
->jobname
: "Remote Downlevel Document");
983 fstrcpy(pj
.jobname
, old_pj
? old_pj
->jobname
: q
->fs_file
);
985 fstrcpy(pj
.user
, old_pj
? old_pj
->user
: q
->fs_user
);
986 fstrcpy(pj
.queuename
, old_pj
? old_pj
->queuename
: sharename
);
988 pjob_store(ev
, msg_ctx
, sharename
, jobid
, &pj
);
989 talloc_free(tmp_ctx
);
993 struct traverse_struct
{
994 print_queue_struct
*queue
;
995 int qcount
, snum
, maxcount
, total_jobs
;
996 const char *sharename
;
998 const char *lprm_command
;
999 struct printif
*print_if
;
1000 struct tevent_context
*ev
;
1001 struct messaging_context
*msg_ctx
;
1002 TALLOC_CTX
*mem_ctx
;
1005 /****************************************************************************
1006 Utility fn to delete any jobs that are no longer active.
1007 ****************************************************************************/
1009 static int traverse_fn_delete(TDB_CONTEXT
*t
, TDB_DATA key
, TDB_DATA data
, void *state
)
1011 struct traverse_struct
*ts
= (struct traverse_struct
*)state
;
1012 struct printjob pjob
;
1016 if ( key
.dsize
!= sizeof(jobid
) )
1019 if (unpack_pjob(ts
->mem_ctx
, data
.dptr
, data
.dsize
, &pjob
) == -1)
1021 talloc_free(pjob
.devmode
);
1025 /* remove a unix job if it isn't in the system queue any more */
1026 for (i
=0;i
<ts
->qcount
;i
++) {
1027 if (ts
->queue
[i
].sysjob
== pjob
.sysjob
) {
1031 if (i
== ts
->qcount
) {
1032 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
1033 (unsigned int)jobid
));
1034 pjob_delete(ts
->ev
, ts
->msg_ctx
,
1035 ts
->sharename
, jobid
);
1039 /* need to continue the the bottom of the function to
1040 save the correct attributes */
1043 /* maybe it hasn't been spooled yet */
1044 if (!pjob
.spooled
) {
1045 /* if a job is not spooled and the process doesn't
1046 exist then kill it. This cleans up after smbd
1048 if (!process_exists_by_pid(pjob
.pid
)) {
1049 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
1050 (unsigned int)jobid
, (unsigned int)pjob
.pid
));
1051 pjob_delete(ts
->ev
, ts
->msg_ctx
,
1052 ts
->sharename
, jobid
);
1058 /* this check only makes sense for jobs submitted from Windows clients */
1061 for (i
=0;i
<ts
->qcount
;i
++) {
1062 if ( pjob
.status
== LPQ_DELETED
)
1065 if (ts
->queue
[i
].sysjob
== pjob
.sysjob
) {
1067 /* try to clean up any jobs that need to be deleted */
1069 if ( pjob
.status
== LPQ_DELETING
) {
1072 result
= (*(ts
->print_if
->job_delete
))(
1073 ts
->sharename
, ts
->lprm_command
, &pjob
);
1075 if ( result
!= 0 ) {
1076 /* if we can't delete, then reset the job status */
1077 pjob
.status
= LPQ_QUEUED
;
1078 pjob_store(ts
->ev
, ts
->msg_ctx
,
1079 ts
->sharename
, jobid
, &pjob
);
1082 /* if we deleted the job, the remove the tdb record */
1085 ts
->sharename
, jobid
);
1086 pjob
.status
= LPQ_DELETED
;
1096 /* The job isn't in the system queue - we have to assume it has
1097 completed, so delete the database entry. */
1099 if (i
== ts
->qcount
) {
1101 /* A race can occur between the time a job is spooled and
1102 when it appears in the lpq output. This happens when
1103 the job is added to printing.tdb when another smbd
1104 running print_queue_update() has completed a lpq and
1105 is currently traversing the printing tdb and deleting jobs.
1106 Don't delete the job if it was submitted after the lpq_time. */
1108 if (pjob
.starttime
< ts
->lpq_time
) {
1109 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
1110 (unsigned int)jobid
,
1111 (unsigned int)pjob
.starttime
,
1112 (unsigned int)ts
->lpq_time
));
1113 pjob_delete(ts
->ev
, ts
->msg_ctx
,
1114 ts
->sharename
, jobid
);
1120 /* Save the pjob attributes we will store. */
1121 ts
->queue
[i
].sysjob
= pjob
.sysjob
;
1122 ts
->queue
[i
].size
= pjob
.size
;
1123 ts
->queue
[i
].page_count
= pjob
.page_count
;
1124 ts
->queue
[i
].status
= pjob
.status
;
1125 ts
->queue
[i
].priority
= 1;
1126 ts
->queue
[i
].time
= pjob
.starttime
;
1127 fstrcpy(ts
->queue
[i
].fs_user
, pjob
.user
);
1128 fstrcpy(ts
->queue
[i
].fs_file
, pjob
.jobname
);
1135 /****************************************************************************
1136 Check if the print queue has been updated recently enough.
1137 ****************************************************************************/
1139 static void print_cache_flush(const char *sharename
)
1142 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1146 slprintf(key
, sizeof(key
)-1, "CACHE/%s", sharename
);
1147 tdb_store_int32(pdb
->tdb
, key
, -1);
1148 release_print_db(pdb
);
1151 /****************************************************************************
1152 Check if someone already thinks they are doing the update.
1153 ****************************************************************************/
1155 static pid_t
get_updating_pid(const char *sharename
)
1160 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1164 slprintf(keystr
, sizeof(keystr
)-1, "UPDATING/%s", sharename
);
1165 key
= string_tdb_data(keystr
);
1167 data
= tdb_fetch_compat(pdb
->tdb
, key
);
1168 release_print_db(pdb
);
1169 if (!data
.dptr
|| data
.dsize
!= sizeof(pid_t
)) {
1170 SAFE_FREE(data
.dptr
);
1174 updating_pid
= IVAL(data
.dptr
, 0);
1175 SAFE_FREE(data
.dptr
);
1177 if (process_exists_by_pid(updating_pid
))
1178 return updating_pid
;
1183 /****************************************************************************
1184 Set the fact that we're doing the update, or have finished doing the update
1186 ****************************************************************************/
1188 static void set_updating_pid(const fstring sharename
, bool updating
)
1193 pid_t updating_pid
= getpid();
1196 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1201 slprintf(keystr
, sizeof(keystr
)-1, "UPDATING/%s", sharename
);
1202 key
= string_tdb_data(keystr
);
1204 DEBUG(5, ("set_updating_pid: %supdating lpq cache for print share %s\n",
1205 updating
? "" : "not ",
1209 tdb_delete(pdb
->tdb
, key
);
1210 release_print_db(pdb
);
1214 SIVAL( buffer
, 0, updating_pid
);
1216 data
.dsize
= 4; /* we always assume this is a 4 byte value */
1218 tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
);
1219 release_print_db(pdb
);
1222 /****************************************************************************
1223 Sort print jobs by submittal time.
1224 ****************************************************************************/
1226 static int printjob_comp(print_queue_struct
*j1
, print_queue_struct
*j2
)
1237 /* Sort on job start time */
1239 if (j1
->time
== j2
->time
)
1241 return (j1
->time
> j2
->time
) ? 1 : -1;
1244 /****************************************************************************
1245 Store the sorted queue representation for later portmon retrieval.
1247 ****************************************************************************/
1249 static void store_queue_struct(struct tdb_print_db
*pdb
, struct traverse_struct
*pts
)
1252 int max_reported_jobs
= lp_max_reported_print_jobs(pts
->snum
);
1253 print_queue_struct
*queue
= pts
->queue
;
1256 unsigned int qcount
;
1258 if (max_reported_jobs
&& (max_reported_jobs
< pts
->qcount
))
1259 pts
->qcount
= max_reported_jobs
;
1262 /* Work out the size. */
1264 data
.dsize
+= tdb_pack(NULL
, 0, "d", qcount
);
1266 for (i
= 0; i
< pts
->qcount
; i
++) {
1267 if ( queue
[i
].status
== LPQ_DELETED
)
1271 data
.dsize
+= tdb_pack(NULL
, 0, "ddddddff",
1272 (uint32
)queue
[i
].sysjob
,
1273 (uint32
)queue
[i
].size
,
1274 (uint32
)queue
[i
].page_count
,
1275 (uint32
)queue
[i
].status
,
1276 (uint32
)queue
[i
].priority
,
1277 (uint32
)queue
[i
].time
,
1282 if ((data
.dptr
= (uint8
*)SMB_MALLOC(data
.dsize
)) == NULL
)
1286 len
+= tdb_pack(data
.dptr
+ len
, data
.dsize
- len
, "d", qcount
);
1287 for (i
= 0; i
< pts
->qcount
; i
++) {
1288 if ( queue
[i
].status
== LPQ_DELETED
)
1291 len
+= tdb_pack(data
.dptr
+ len
, data
.dsize
- len
, "ddddddff",
1292 (uint32
)queue
[i
].sysjob
,
1293 (uint32
)queue
[i
].size
,
1294 (uint32
)queue
[i
].page_count
,
1295 (uint32
)queue
[i
].status
,
1296 (uint32
)queue
[i
].priority
,
1297 (uint32
)queue
[i
].time
,
1302 tdb_store(pdb
->tdb
, string_tdb_data("INFO/linear_queue_array"), data
,
1304 SAFE_FREE(data
.dptr
);
1308 static TDB_DATA
get_jobs_added_data(struct tdb_print_db
*pdb
)
1314 data
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data("INFO/jobs_added"));
1315 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0)) {
1316 SAFE_FREE(data
.dptr
);
1323 static void check_job_added(const char *sharename
, TDB_DATA data
, uint32 jobid
)
1326 unsigned int job_count
= data
.dsize
/ 4;
1328 for (i
= 0; i
< job_count
; i
++) {
1331 ch_jobid
= IVAL(data
.dptr
, i
*4);
1332 if (ch_jobid
== jobid
)
1333 remove_from_jobs_added(sharename
, jobid
);
1337 /****************************************************************************
1338 Check if the print queue has been updated recently enough.
1339 ****************************************************************************/
1341 static bool print_cache_expired(const char *sharename
, bool check_pending
)
1344 time_t last_qscan_time
, time_now
= time(NULL
);
1345 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1346 bool result
= False
;
1351 snprintf(key
, sizeof(key
), "CACHE/%s", sharename
);
1352 last_qscan_time
= (time_t)tdb_fetch_int32(pdb
->tdb
, key
);
1355 * Invalidate the queue for 3 reasons.
1356 * (1). last queue scan time == -1.
1357 * (2). Current time - last queue scan time > allowed cache time.
1358 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1359 * This last test picks up machines for which the clock has been moved
1360 * forward, an lpq scan done and then the clock moved back. Otherwise
1361 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1364 if (last_qscan_time
== ((time_t)-1)
1365 || (time_now
- last_qscan_time
) >= lp_lpq_cache_time()
1366 || last_qscan_time
> (time_now
+ MAX_CACHE_VALID_TIME
))
1369 time_t msg_pending_time
;
1371 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1372 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1373 sharename
, (int)last_qscan_time
, (int)time_now
,
1374 (int)lp_lpq_cache_time() ));
1376 /* check if another smbd has already sent a message to update the
1377 queue. Give the pending message one minute to clear and
1378 then send another message anyways. Make sure to check for
1379 clocks that have been run forward and then back again. */
1381 snprintf(key
, sizeof(key
), "MSG_PENDING/%s", sharename
);
1384 && tdb_fetch_uint32( pdb
->tdb
, key
, &u
)
1385 && (msg_pending_time
=u
) > 0
1386 && msg_pending_time
<= time_now
1387 && (time_now
- msg_pending_time
) < 60 )
1389 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1398 release_print_db(pdb
);
1402 /****************************************************************************
1403 main work for updating the lpq cache for a printer queue
1404 ****************************************************************************/
1406 static void print_queue_update_internal(struct tevent_context
*ev
,
1407 struct messaging_context
*msg_ctx
,
1408 const char *sharename
,
1409 struct printif
*current_printif
,
1410 char *lpq_command
, char *lprm_command
)
1413 print_queue_struct
*queue
= NULL
;
1414 print_status_struct status
;
1415 print_status_struct old_status
;
1416 struct printjob
*pjob
;
1417 struct traverse_struct tstruct
;
1420 fstring keystr
, cachestr
;
1421 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1422 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
1424 if ((pdb
== NULL
) || (tmp_ctx
== NULL
)) {
1428 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1429 sharename
, current_printif
->type
, lpq_command
));
1432 * Update the cache time FIRST ! Stops others even
1433 * attempting to get the lock and doing this
1434 * if the lpq takes a long time.
1437 slprintf(cachestr
, sizeof(cachestr
)-1, "CACHE/%s", sharename
);
1438 tdb_store_int32(pdb
->tdb
, cachestr
, (int)time(NULL
));
1440 /* get the current queue using the appropriate interface */
1441 ZERO_STRUCT(status
);
1443 qcount
= (*(current_printif
->queue_get
))(sharename
,
1444 current_printif
->type
,
1445 lpq_command
, &queue
, &status
);
1447 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1448 qcount
, (qcount
!= 1) ? "s" : "", sharename
));
1450 /* Sort the queue by submission time otherwise they are displayed
1453 TYPESAFE_QSORT(queue
, qcount
, printjob_comp
);
1456 any job in the internal database that is marked as spooled
1457 and doesn't exist in the system queue is considered finished
1458 and removed from the database
1460 any job in the system database but not in the internal database
1461 is added as a unix job
1463 fill in any system job numbers as we go
1465 jcdata
= get_jobs_added_data(pdb
);
1467 for (i
=0; i
<qcount
; i
++) {
1468 uint32 jobid
= sysjob_to_jobid_pdb(pdb
, queue
[i
].sysjob
);
1469 if (jobid
== (uint32
)-1) {
1470 /* assume its a unix print job */
1471 print_unix_job(ev
, msg_ctx
,
1472 sharename
, &queue
[i
], jobid
);
1476 /* we have an active SMB print job - update its status */
1477 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
1479 /* err, somethings wrong. Probably smbd was restarted
1480 with jobs in the queue. All we can do is treat them
1481 like unix jobs. Pity. */
1482 DEBUG(1, ("queued print job %d not found in jobs list, "
1483 "assuming unix job\n", jobid
));
1484 print_unix_job(ev
, msg_ctx
,
1485 sharename
, &queue
[i
], jobid
);
1489 /* don't reset the status on jobs to be deleted */
1491 if ( pjob
->status
!= LPQ_DELETING
)
1492 pjob
->status
= queue
[i
].status
;
1494 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
1496 check_job_added(sharename
, jcdata
, jobid
);
1499 SAFE_FREE(jcdata
.dptr
);
1501 /* now delete any queued entries that don't appear in the
1503 tstruct
.queue
= queue
;
1504 tstruct
.qcount
= qcount
;
1506 tstruct
.total_jobs
= 0;
1507 tstruct
.lpq_time
= time(NULL
);
1508 tstruct
.sharename
= sharename
;
1509 tstruct
.lprm_command
= lprm_command
;
1510 tstruct
.print_if
= current_printif
;
1512 tstruct
.msg_ctx
= msg_ctx
;
1513 tstruct
.mem_ctx
= tmp_ctx
;
1515 tdb_traverse(pdb
->tdb
, traverse_fn_delete
, (void *)&tstruct
);
1517 /* Store the linearised queue, max jobs only. */
1518 store_queue_struct(pdb
, &tstruct
);
1520 SAFE_FREE(tstruct
.queue
);
1521 talloc_free(tmp_ctx
);
1523 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1524 sharename
, tstruct
.total_jobs
));
1526 tdb_store_int32(pdb
->tdb
, "INFO/total_jobs", tstruct
.total_jobs
);
1528 get_queue_status(sharename
, &old_status
);
1529 if (old_status
.qcount
!= qcount
)
1530 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1531 old_status
.qcount
, qcount
, sharename
));
1533 /* store the new queue status structure */
1534 slprintf(keystr
, sizeof(keystr
)-1, "STATUS/%s", sharename
);
1535 key
= string_tdb_data(keystr
);
1537 status
.qcount
= qcount
;
1538 data
.dptr
= (uint8
*)&status
;
1539 data
.dsize
= sizeof(status
);
1540 tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
);
1543 * Update the cache time again. We want to do this call
1544 * as little as possible...
1547 slprintf(keystr
, sizeof(keystr
)-1, "CACHE/%s", sharename
);
1548 tdb_store_int32(pdb
->tdb
, keystr
, (int32
)time(NULL
));
1550 /* clear the msg pending record for this queue */
1552 snprintf(keystr
, sizeof(keystr
), "MSG_PENDING/%s", sharename
);
1554 if ( !tdb_store_uint32( pdb
->tdb
, keystr
, 0 ) ) {
1555 /* log a message but continue on */
1557 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1561 release_print_db( pdb
);
1566 /****************************************************************************
1567 Update the internal database from the system print queue for a queue.
1568 obtain a lock on the print queue before proceeding (needed when mutiple
1569 smbd processes maytry to update the lpq cache concurrently).
1570 ****************************************************************************/
1572 static void print_queue_update_with_lock( struct tevent_context
*ev
,
1573 struct messaging_context
*msg_ctx
,
1574 const char *sharename
,
1575 struct printif
*current_printif
,
1576 char *lpq_command
, char *lprm_command
)
1579 struct tdb_print_db
*pdb
;
1581 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename
));
1582 pdb
= get_print_db_byname(sharename
);
1586 if ( !print_cache_expired(sharename
, False
) ) {
1587 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename
));
1588 release_print_db(pdb
);
1593 * Check to see if someone else is doing this update.
1594 * This is essentially a mutex on the update.
1597 if (get_updating_pid(sharename
) != -1) {
1598 release_print_db(pdb
);
1602 /* Lock the queue for the database update */
1604 slprintf(keystr
, sizeof(keystr
) - 1, "LOCK/%s", sharename
);
1605 /* Only wait 10 seconds for this. */
1606 if (tdb_lock_bystring_with_timeout(pdb
->tdb
, keystr
, 10) != 0) {
1607 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename
));
1608 release_print_db(pdb
);
1613 * Ensure that no one else got in here.
1614 * If the updating pid is still -1 then we are
1618 if (get_updating_pid(sharename
) != -1) {
1620 * Someone else is doing the update, exit.
1622 tdb_unlock_bystring(pdb
->tdb
, keystr
);
1623 release_print_db(pdb
);
1628 * We're going to do the update ourselves.
1631 /* Tell others we're doing the update. */
1632 set_updating_pid(sharename
, True
);
1635 * Allow others to enter and notice we're doing
1639 tdb_unlock_bystring(pdb
->tdb
, keystr
);
1641 /* do the main work now */
1643 print_queue_update_internal(ev
, msg_ctx
,
1644 sharename
, current_printif
,
1645 lpq_command
, lprm_command
);
1647 /* Delete our pid from the db. */
1648 set_updating_pid(sharename
, False
);
1649 release_print_db(pdb
);
1652 /****************************************************************************
1653 this is the receive function of the background lpq updater
1654 ****************************************************************************/
1655 void print_queue_receive(struct messaging_context
*msg
,
1658 struct server_id server_id
,
1662 char *lpqcommand
= NULL
, *lprmcommand
= NULL
;
1666 len
= tdb_unpack( (uint8
*)data
->data
, data
->length
, "fdPP",
1673 SAFE_FREE(lpqcommand
);
1674 SAFE_FREE(lprmcommand
);
1675 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1679 print_queue_update_with_lock(server_event_context(), msg
, sharename
,
1680 get_printer_fns_from_type((enum printing_types
)printing_type
),
1681 lpqcommand
, lprmcommand
);
1683 SAFE_FREE(lpqcommand
);
1684 SAFE_FREE(lprmcommand
);
1688 /****************************************************************************
1689 update the internal database from the system print queue for a queue
1690 ****************************************************************************/
1692 extern pid_t background_lpq_updater_pid
;
1694 static void print_queue_update(struct messaging_context
*msg_ctx
,
1695 int snum
, bool force
)
1699 char *lpqcommand
= NULL
;
1700 char *lprmcommand
= NULL
;
1701 uint8
*buffer
= NULL
;
1704 struct tdb_print_db
*pdb
;
1706 struct printif
*current_printif
;
1707 TALLOC_CTX
*ctx
= talloc_tos();
1709 fstrcpy( sharename
, lp_const_servicename(snum
));
1711 /* don't strip out characters like '$' from the printername */
1713 lpqcommand
= talloc_string_sub2(ctx
,
1714 lp_lpq_command(talloc_tos(), snum
),
1716 lp_printername(talloc_tos(), snum
),
1717 false, false, false);
1721 lpqcommand
= talloc_sub_advanced(ctx
,
1722 lp_servicename(talloc_tos(), snum
),
1723 current_user_info
.unix_name
,
1725 current_user
.ut
.gid
,
1726 get_current_username(),
1727 current_user_info
.domain
,
1733 lprmcommand
= talloc_string_sub2(ctx
,
1734 lp_lprm_command(talloc_tos(), snum
),
1736 lp_printername(talloc_tos(), snum
),
1737 false, false, false);
1741 lprmcommand
= talloc_sub_advanced(ctx
,
1742 lp_servicename(talloc_tos(), snum
),
1743 current_user_info
.unix_name
,
1745 current_user
.ut
.gid
,
1746 get_current_username(),
1747 current_user_info
.domain
,
1754 * Make sure that the background queue process exists.
1755 * Otherwise just do the update ourselves
1758 if ( force
|| background_lpq_updater_pid
== -1 ) {
1759 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename
));
1760 current_printif
= get_printer_fns( snum
);
1761 print_queue_update_with_lock(server_event_context(), msg_ctx
,
1762 sharename
, current_printif
,
1763 lpqcommand
, lprmcommand
);
1768 type
= lp_printing(snum
);
1770 /* get the length */
1772 len
= tdb_pack( NULL
, 0, "fdPP",
1778 buffer
= SMB_XMALLOC_ARRAY( uint8
, len
);
1780 /* now pack the buffer */
1781 newlen
= tdb_pack( buffer
, len
, "fdPP",
1787 SMB_ASSERT( newlen
== len
);
1789 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1790 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1791 sharename
, type
, lpqcommand
, lprmcommand
));
1793 /* here we set a msg pending record for other smbd processes
1794 to throttle the number of duplicate print_queue_update msgs
1797 pdb
= get_print_db_byname(sharename
);
1803 snprintf(key
, sizeof(key
), "MSG_PENDING/%s", sharename
);
1805 if ( !tdb_store_uint32( pdb
->tdb
, key
, time(NULL
) ) ) {
1806 /* log a message but continue on */
1808 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1812 release_print_db( pdb
);
1814 /* finally send the message */
1816 messaging_send_buf(msg_ctx
, pid_to_procid(background_lpq_updater_pid
),
1817 MSG_PRINTER_UPDATE
, (uint8
*)buffer
, len
);
1819 SAFE_FREE( buffer
);
1824 /****************************************************************************
1825 Create/Update an entry in the print tdb that will allow us to send notify
1826 updates only to interested smbd's.
1827 ****************************************************************************/
1829 bool print_notify_register_pid(int snum
)
1832 struct tdb_print_db
*pdb
= NULL
;
1833 TDB_CONTEXT
*tdb
= NULL
;
1834 const char *printername
;
1835 uint32_t mypid
= (uint32_t)getpid();
1839 /* if (snum == -1), then the change notify request was
1840 on a print server handle and we need to register on
1845 int num_services
= lp_numservices();
1848 for ( idx
=0; idx
<num_services
; idx
++ ) {
1849 if (lp_snum_ok(idx
) && lp_printable(idx
) )
1850 print_notify_register_pid(idx
);
1855 else /* register for a specific printer */
1857 printername
= lp_const_servicename(snum
);
1858 pdb
= get_print_db_byname(printername
);
1864 if (tdb_lock_bystring_with_timeout(tdb
, NOTIFY_PID_LIST_KEY
, 10) != 0) {
1865 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1868 release_print_db(pdb
);
1872 data
= get_printer_notify_pid_list( tdb
, printername
, True
);
1874 /* Add ourselves and increase the refcount. */
1876 for (i
= 0; i
< data
.dsize
; i
+= 8) {
1877 if (IVAL(data
.dptr
,i
) == mypid
) {
1878 uint32 new_refcount
= IVAL(data
.dptr
, i
+4) + 1;
1879 SIVAL(data
.dptr
, i
+4, new_refcount
);
1884 if (i
== data
.dsize
) {
1885 /* We weren't in the list. Realloc. */
1886 data
.dptr
= (uint8
*)SMB_REALLOC(data
.dptr
, data
.dsize
+ 8);
1888 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1893 SIVAL(data
.dptr
,data
.dsize
- 8,mypid
);
1894 SIVAL(data
.dptr
,data
.dsize
- 4,1); /* Refcount. */
1897 /* Store back the record. */
1898 if (tdb_store_bystring(tdb
, NOTIFY_PID_LIST_KEY
, data
, TDB_REPLACE
) != 0) {
1899 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1900 list for printer %s\n", printername
));
1908 tdb_unlock_bystring(tdb
, NOTIFY_PID_LIST_KEY
);
1910 release_print_db(pdb
);
1911 SAFE_FREE(data
.dptr
);
1915 /****************************************************************************
1916 Update an entry in the print tdb that will allow us to send notify
1917 updates only to interested smbd's.
1918 ****************************************************************************/
1920 bool print_notify_deregister_pid(int snum
)
1923 struct tdb_print_db
*pdb
= NULL
;
1924 TDB_CONTEXT
*tdb
= NULL
;
1925 const char *printername
;
1926 uint32_t mypid
= (uint32_t)getpid();
1930 /* if ( snum == -1 ), we are deregister a print server handle
1931 which means to deregister on all print queues */
1935 int num_services
= lp_numservices();
1938 for ( idx
=0; idx
<num_services
; idx
++ ) {
1939 if ( lp_snum_ok(idx
) && lp_printable(idx
) )
1940 print_notify_deregister_pid(idx
);
1945 else /* deregister a specific printer */
1947 printername
= lp_const_servicename(snum
);
1948 pdb
= get_print_db_byname(printername
);
1954 if (tdb_lock_bystring_with_timeout(tdb
, NOTIFY_PID_LIST_KEY
, 10) != 0) {
1955 DEBUG(0,("print_notify_register_pid: Failed to lock \
1956 printer %s database\n", printername
));
1958 release_print_db(pdb
);
1962 data
= get_printer_notify_pid_list( tdb
, printername
, True
);
1964 /* Reduce refcount. Remove ourselves if zero. */
1966 for (i
= 0; i
< data
.dsize
; ) {
1967 if (IVAL(data
.dptr
,i
) == mypid
) {
1968 uint32 refcount
= IVAL(data
.dptr
, i
+4);
1972 if (refcount
== 0) {
1973 if (data
.dsize
- i
> 8)
1974 memmove( &data
.dptr
[i
], &data
.dptr
[i
+8], data
.dsize
- i
- 8);
1978 SIVAL(data
.dptr
, i
+4, refcount
);
1984 if (data
.dsize
== 0)
1985 SAFE_FREE(data
.dptr
);
1987 /* Store back the record. */
1988 if (tdb_store_bystring(tdb
, NOTIFY_PID_LIST_KEY
, data
, TDB_REPLACE
) != 0) {
1989 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1990 list for printer %s\n", printername
));
1998 tdb_unlock_bystring(tdb
, NOTIFY_PID_LIST_KEY
);
2000 release_print_db(pdb
);
2001 SAFE_FREE(data
.dptr
);
2005 /****************************************************************************
2006 Check if a jobid is valid. It is valid if it exists in the database.
2007 ****************************************************************************/
2009 bool print_job_exists(const char* sharename
, uint32 jobid
)
2011 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2017 ret
= tdb_exists(pdb
->tdb
, print_key(jobid
, &tmp
));
2018 release_print_db(pdb
);
2022 /****************************************************************************
2023 Return the device mode asigned to a specific print job.
2024 Only valid for the process doing the spooling and when the job
2025 has not been spooled.
2026 ****************************************************************************/
2028 struct spoolss_DeviceMode
*print_job_devmode(TALLOC_CTX
*mem_ctx
,
2029 const char *sharename
,
2032 struct printjob
*pjob
= print_job_find(mem_ctx
, sharename
, jobid
);
2037 return pjob
->devmode
;
2040 /****************************************************************************
2041 Set the name of a job. Only possible for owner.
2042 ****************************************************************************/
2044 bool print_job_set_name(struct tevent_context
*ev
,
2045 struct messaging_context
*msg_ctx
,
2046 const char *sharename
, uint32 jobid
, const char *name
)
2048 struct printjob
*pjob
;
2050 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
2051 if (tmp_ctx
== NULL
) {
2055 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2056 if (!pjob
|| pjob
->pid
!= getpid()) {
2061 fstrcpy(pjob
->jobname
, name
);
2062 ret
= pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2064 talloc_free(tmp_ctx
);
2068 /****************************************************************************
2069 Get the name of a job. Only possible for owner.
2070 ****************************************************************************/
2072 bool print_job_get_name(TALLOC_CTX
*mem_ctx
, const char *sharename
, uint32_t jobid
, char **name
)
2074 struct printjob
*pjob
;
2076 pjob
= print_job_find(mem_ctx
, sharename
, jobid
);
2077 if (!pjob
|| pjob
->pid
!= getpid()) {
2081 *name
= pjob
->jobname
;
2086 /***************************************************************************
2087 Remove a jobid from the 'jobs added' list.
2088 ***************************************************************************/
2090 static bool remove_from_jobs_added(const char* sharename
, uint32 jobid
)
2092 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2094 size_t job_count
, i
;
2096 bool gotlock
= False
;
2104 key
= string_tdb_data("INFO/jobs_added");
2106 if (tdb_chainlock_with_timeout(pdb
->tdb
, key
, 5) != 0)
2111 data
= tdb_fetch_compat(pdb
->tdb
, key
);
2113 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0))
2116 job_count
= data
.dsize
/ 4;
2117 for (i
= 0; i
< job_count
; i
++) {
2120 ch_jobid
= IVAL(data
.dptr
, i
*4);
2121 if (ch_jobid
== jobid
) {
2122 if (i
< job_count
-1 )
2123 memmove(data
.dptr
+ (i
*4), data
.dptr
+ (i
*4) + 4, (job_count
- i
- 1)*4 );
2125 if (tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
) != 0)
2135 tdb_chainunlock(pdb
->tdb
, key
);
2136 SAFE_FREE(data
.dptr
);
2137 release_print_db(pdb
);
2139 DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid
));
2141 DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid
));
2145 /****************************************************************************
2146 Delete a print job - don't update queue.
2147 ****************************************************************************/
2149 static bool print_job_delete1(struct tevent_context
*ev
,
2150 struct messaging_context
*msg_ctx
,
2151 int snum
, uint32 jobid
)
2153 const char* sharename
= lp_const_servicename(snum
);
2154 struct printjob
*pjob
;
2156 struct printif
*current_printif
= get_printer_fns( snum
);
2158 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
2159 if (tmp_ctx
== NULL
) {
2163 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2170 * If already deleting just return.
2173 if (pjob
->status
== LPQ_DELETING
) {
2178 /* Hrm - we need to be able to cope with deleting a job before it
2179 has reached the spooler. Just mark it as LPQ_DELETING and
2180 let the print_queue_update() code rmeove the record */
2183 if (pjob
->sysjob
== -1) {
2184 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid
));
2187 /* Set the tdb entry to be deleting. */
2189 pjob
->status
= LPQ_DELETING
;
2190 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2192 if (pjob
->spooled
&& pjob
->sysjob
!= -1)
2194 result
= (*(current_printif
->job_delete
))(
2195 lp_printername(talloc_tos(), snum
),
2196 lp_lprm_command(talloc_tos(), snum
),
2199 /* Delete the tdb entry if the delete succeeded or the job hasn't
2203 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2210 pjob_delete(ev
, msg_ctx
, sharename
, jobid
);
2211 /* Ensure we keep a rough count of the number of total jobs... */
2212 tdb_change_int32_atomic(pdb
->tdb
, "INFO/total_jobs", &njobs
, -1);
2213 release_print_db(pdb
);
2217 remove_from_jobs_added( sharename
, jobid
);
2219 ret
= (result
== 0);
2221 talloc_free(tmp_ctx
);
2225 /****************************************************************************
2226 Return true if the current user owns the print job.
2227 ****************************************************************************/
2229 static bool is_owner(const struct auth_session_info
*server_info
,
2230 const char *servicename
,
2233 struct printjob
*pjob
;
2235 TALLOC_CTX
*tmp_ctx
= talloc_new(server_info
);
2236 if (tmp_ctx
== NULL
) {
2240 pjob
= print_job_find(tmp_ctx
, servicename
, jobid
);
2241 if (!pjob
|| !server_info
) {
2246 ret
= strequal(pjob
->user
, server_info
->unix_info
->sanitized_username
);
2248 talloc_free(tmp_ctx
);
2252 /****************************************************************************
2254 ****************************************************************************/
2256 WERROR
print_job_delete(const struct auth_session_info
*server_info
,
2257 struct messaging_context
*msg_ctx
,
2258 int snum
, uint32_t jobid
)
2260 const char* sharename
= lp_const_servicename(snum
);
2261 struct printjob
*pjob
;
2264 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2265 if (tmp_ctx
== NULL
) {
2266 return WERR_NOT_ENOUGH_MEMORY
;
2269 owner
= is_owner(server_info
, lp_const_servicename(snum
), jobid
);
2271 /* Check access against security descriptor or whether the user
2275 !W_ERROR_IS_OK(print_access_check(server_info
, msg_ctx
, snum
,
2276 JOB_ACCESS_ADMINISTER
))) {
2277 DEBUG(0, ("print job delete denied."
2278 "User name: %s, Printer name: %s.",
2279 uidtoname(server_info
->unix_token
->uid
),
2280 lp_printername(tmp_ctx
, snum
)));
2282 werr
= WERR_ACCESS_DENIED
;
2287 * get the spooled filename of the print job
2288 * if this works, then the file has not been spooled
2289 * to the underlying print system. Just delete the
2290 * spool file & return.
2293 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2294 if (!pjob
|| pjob
->spooled
|| pjob
->pid
!= getpid()) {
2295 DEBUG(10, ("Skipping spool file removal for job %u\n", jobid
));
2297 DEBUG(10, ("Removing spool file [%s]\n", pjob
->filename
));
2298 if (unlink(pjob
->filename
) == -1) {
2299 werr
= map_werror_from_unix(errno
);
2304 if (!print_job_delete1(server_event_context(), msg_ctx
, snum
, jobid
)) {
2305 werr
= WERR_ACCESS_DENIED
;
2309 /* force update the database and say the delete failed if the
2312 print_queue_update(msg_ctx
, snum
, True
);
2314 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2315 if (pjob
&& (pjob
->status
!= LPQ_DELETING
)) {
2316 werr
= WERR_ACCESS_DENIED
;
2319 werr
= WERR_PRINTER_HAS_JOBS_QUEUED
;
2322 talloc_free(tmp_ctx
);
2326 /****************************************************************************
2328 ****************************************************************************/
2330 WERROR
print_job_pause(const struct auth_session_info
*server_info
,
2331 struct messaging_context
*msg_ctx
,
2332 int snum
, uint32 jobid
)
2334 const char* sharename
= lp_const_servicename(snum
);
2335 struct printjob
*pjob
;
2337 struct printif
*current_printif
= get_printer_fns( snum
);
2339 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2340 if (tmp_ctx
== NULL
) {
2341 return WERR_NOT_ENOUGH_MEMORY
;
2344 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2345 if (!pjob
|| !server_info
) {
2346 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2347 (unsigned int)jobid
));
2348 werr
= WERR_INVALID_PARAM
;
2352 if (!pjob
->spooled
|| pjob
->sysjob
== -1) {
2353 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2354 (int)pjob
->sysjob
, (unsigned int)jobid
));
2355 werr
= WERR_INVALID_PARAM
;
2359 if (!is_owner(server_info
, lp_const_servicename(snum
), jobid
) &&
2360 !W_ERROR_IS_OK(print_access_check(server_info
, msg_ctx
, snum
,
2361 JOB_ACCESS_ADMINISTER
))) {
2362 DEBUG(0, ("print job pause denied."
2363 "User name: %s, Printer name: %s.",
2364 uidtoname(server_info
->unix_token
->uid
),
2365 lp_printername(tmp_ctx
, snum
)));
2367 werr
= WERR_ACCESS_DENIED
;
2371 /* need to pause the spooled entry */
2372 ret
= (*(current_printif
->job_pause
))(snum
, pjob
);
2375 werr
= WERR_INVALID_PARAM
;
2379 /* force update the database */
2380 print_cache_flush(lp_const_servicename(snum
));
2382 /* Send a printer notify message */
2384 notify_job_status(server_event_context(), msg_ctx
, sharename
, jobid
,
2387 /* how do we tell if this succeeded? */
2390 talloc_free(tmp_ctx
);
2394 /****************************************************************************
2396 ****************************************************************************/
2398 WERROR
print_job_resume(const struct auth_session_info
*server_info
,
2399 struct messaging_context
*msg_ctx
,
2400 int snum
, uint32 jobid
)
2402 const char *sharename
= lp_const_servicename(snum
);
2403 struct printjob
*pjob
;
2405 struct printif
*current_printif
= get_printer_fns( snum
);
2407 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2408 if (tmp_ctx
== NULL
)
2409 return WERR_NOT_ENOUGH_MEMORY
;
2411 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2412 if (!pjob
|| !server_info
) {
2413 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2414 (unsigned int)jobid
));
2415 werr
= WERR_INVALID_PARAM
;
2419 if (!pjob
->spooled
|| pjob
->sysjob
== -1) {
2420 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2421 (int)pjob
->sysjob
, (unsigned int)jobid
));
2422 werr
= WERR_INVALID_PARAM
;
2426 if (!is_owner(server_info
, lp_const_servicename(snum
), jobid
) &&
2427 !W_ERROR_IS_OK(print_access_check(server_info
, msg_ctx
, snum
,
2428 JOB_ACCESS_ADMINISTER
))) {
2429 DEBUG(0, ("print job resume denied."
2430 "User name: %s, Printer name: %s.",
2431 uidtoname(server_info
->unix_token
->uid
),
2432 lp_printername(tmp_ctx
, snum
)));
2434 werr
= WERR_ACCESS_DENIED
;
2438 ret
= (*(current_printif
->job_resume
))(snum
, pjob
);
2441 werr
= WERR_INVALID_PARAM
;
2445 /* force update the database */
2446 print_cache_flush(lp_const_servicename(snum
));
2448 /* Send a printer notify message */
2450 notify_job_status(server_event_context(), msg_ctx
, sharename
, jobid
,
2455 talloc_free(tmp_ctx
);
2459 /****************************************************************************
2460 Write to a print file.
2461 ****************************************************************************/
2463 ssize_t
print_job_write(struct tevent_context
*ev
,
2464 struct messaging_context
*msg_ctx
,
2465 int snum
, uint32 jobid
, const char *buf
, size_t size
)
2467 const char* sharename
= lp_const_servicename(snum
);
2468 ssize_t return_code
;
2469 struct printjob
*pjob
;
2470 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
2471 if (tmp_ctx
== NULL
) {
2475 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2481 /* don't allow another process to get this info - it is meaningless */
2482 if (pjob
->pid
!= getpid()) {
2487 /* if SMBD is spooling this can't be allowed */
2488 if (pjob
->status
== PJOB_SMBD_SPOOLING
) {
2493 return_code
= write_data(pjob
->fd
, buf
, size
);
2494 if (return_code
> 0) {
2496 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2499 talloc_free(tmp_ctx
);
2503 /****************************************************************************
2504 Get the queue status - do not update if db is out of date.
2505 ****************************************************************************/
2507 static int get_queue_status(const char* sharename
, print_status_struct
*status
)
2511 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2515 ZERO_STRUCTP(status
);
2522 fstr_sprintf(keystr
, "STATUS/%s", sharename
);
2523 data
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data(keystr
));
2525 if (data
.dsize
== sizeof(print_status_struct
))
2526 /* this memcpy is ok since the status struct was
2527 not packed before storing it in the tdb */
2528 memcpy(status
, data
.dptr
, sizeof(print_status_struct
));
2529 SAFE_FREE(data
.dptr
);
2532 len
= tdb_fetch_int32(pdb
->tdb
, "INFO/total_jobs");
2533 release_print_db(pdb
);
2534 return (len
== -1 ? 0 : len
);
2537 /****************************************************************************
2538 Determine the number of jobs in a queue.
2539 ****************************************************************************/
2541 int print_queue_length(struct messaging_context
*msg_ctx
, int snum
,
2542 print_status_struct
*pstatus
)
2544 const char* sharename
= lp_const_servicename( snum
);
2545 print_status_struct status
;
2548 ZERO_STRUCT( status
);
2550 /* make sure the database is up to date */
2551 if (print_cache_expired(lp_const_servicename(snum
), True
))
2552 print_queue_update(msg_ctx
, snum
, False
);
2554 /* also fetch the queue status */
2555 memset(&status
, 0, sizeof(status
));
2556 len
= get_queue_status(sharename
, &status
);
2564 /***************************************************************************
2565 Allocate a jobid. Hold the lock for as short a time as possible.
2566 ***************************************************************************/
2568 static WERROR
allocate_print_jobid(struct tdb_print_db
*pdb
, int snum
,
2569 const char *sharename
, uint32
*pjobid
)
2573 enum TDB_ERROR terr
;
2576 *pjobid
= (uint32
)-1;
2578 for (i
= 0; i
< 3; i
++) {
2579 /* Lock the database - only wait 20 seconds. */
2580 ret
= tdb_lock_bystring_with_timeout(pdb
->tdb
,
2581 "INFO/nextjob", 20);
2583 DEBUG(0, ("allocate_print_jobid: "
2584 "Failed to lock printing database %s\n",
2586 terr
= tdb_error(pdb
->tdb
);
2587 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2590 if (!tdb_fetch_uint32(pdb
->tdb
, "INFO/nextjob", &jobid
)) {
2591 terr
= tdb_error(pdb
->tdb
);
2592 if (terr
!= TDB_ERR_NOEXIST
) {
2593 DEBUG(0, ("allocate_print_jobid: "
2594 "Failed to fetch INFO/nextjob "
2595 "for print queue %s\n", sharename
));
2596 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2597 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2599 DEBUG(10, ("allocate_print_jobid: "
2600 "No existing jobid in %s\n", sharename
));
2604 DEBUG(10, ("allocate_print_jobid: "
2605 "Read jobid %u from %s\n", jobid
, sharename
));
2607 jobid
= NEXT_JOBID(jobid
);
2609 ret
= tdb_store_int32(pdb
->tdb
, "INFO/nextjob", jobid
);
2611 terr
= tdb_error(pdb
->tdb
);
2612 DEBUG(3, ("allocate_print_jobid: "
2613 "Failed to store INFO/nextjob.\n"));
2614 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2615 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2618 /* We've finished with the INFO/nextjob lock. */
2619 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2621 if (!print_job_exists(sharename
, jobid
)) {
2624 DEBUG(10, ("allocate_print_jobid: "
2625 "Found jobid %u in %s\n", jobid
, sharename
));
2629 DEBUG(0, ("allocate_print_jobid: "
2630 "Failed to allocate a print job for queue %s\n",
2632 /* Probably full... */
2633 return WERR_NO_SPOOL_SPACE
;
2636 /* Store a dummy placeholder. */
2642 if (tdb_store(pdb
->tdb
, print_key(jobid
, &tmp
), dum
,
2644 DEBUG(3, ("allocate_print_jobid: "
2645 "jobid (%d) failed to store placeholder.\n",
2647 terr
= tdb_error(pdb
->tdb
);
2648 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2656 /***************************************************************************
2657 Append a jobid to the 'jobs added' list.
2658 ***************************************************************************/
2660 static bool add_to_jobs_added(struct tdb_print_db
*pdb
, uint32 jobid
)
2665 SIVAL(&store_jobid
, 0, jobid
);
2666 data
.dptr
= (uint8
*)&store_jobid
;
2669 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid
));
2671 return (tdb_append(pdb
->tdb
, string_tdb_data("INFO/jobs_added"),
2676 /***************************************************************************
2677 Do all checks needed to determine if we can start a job.
2678 ***************************************************************************/
2680 static WERROR
print_job_checks(const struct auth_session_info
*server_info
,
2681 struct messaging_context
*msg_ctx
,
2682 int snum
, int *njobs
)
2684 const char *sharename
= lp_const_servicename(snum
);
2685 uint64_t dspace
, dsize
;
2689 if (!W_ERROR_IS_OK(print_access_check(server_info
, msg_ctx
, snum
,
2690 PRINTER_ACCESS_USE
))) {
2691 DEBUG(3, ("print_job_checks: "
2692 "job start denied by security descriptor\n"));
2693 return WERR_ACCESS_DENIED
;
2696 if (!print_time_access_check(server_info
, msg_ctx
, sharename
)) {
2697 DEBUG(3, ("print_job_checks: "
2698 "job start denied by time check\n"));
2699 return WERR_ACCESS_DENIED
;
2702 /* see if we have sufficient disk space */
2703 if (lp_min_print_space(snum
)) {
2704 minspace
= lp_min_print_space(snum
);
2705 ret
= sys_fsusage(lp_path(talloc_tos(), snum
), &dspace
, &dsize
);
2706 if (ret
== 0 && dspace
< 2*minspace
) {
2707 DEBUG(3, ("print_job_checks: "
2708 "disk space check failed.\n"));
2709 return WERR_NO_SPOOL_SPACE
;
2713 /* for autoloaded printers, check that the printcap entry still exists */
2714 if (lp_autoloaded(snum
) && !pcap_printername_ok(sharename
)) {
2715 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2717 return WERR_ACCESS_DENIED
;
2720 /* Insure the maximum queue size is not violated */
2721 *njobs
= print_queue_length(msg_ctx
, snum
, NULL
);
2722 if (*njobs
> lp_maxprintjobs(snum
)) {
2723 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2724 "larger than max printjobs per queue (%d).\n",
2725 sharename
, *njobs
, lp_maxprintjobs(snum
)));
2726 return WERR_NO_SPOOL_SPACE
;
2732 /***************************************************************************
2734 ***************************************************************************/
2736 static WERROR
print_job_spool_file(int snum
, uint32_t jobid
,
2737 const char *output_file
,
2738 struct printjob
*pjob
)
2746 /* if this file is within the printer path, it means that smbd
2747 * is spooling it and will pass us control when it is finished.
2748 * Verify that the file name is ok, within path, and it is
2749 * already already there */
2751 path
= lp_path(talloc_tos(), snum
);
2753 if (strncmp(output_file
, path
, len
) == 0 &&
2754 (output_file
[len
- 1] == '/' || output_file
[len
] == '/')) {
2756 /* verify path is not too long */
2757 if (strlen(output_file
) >= sizeof(pjob
->filename
)) {
2758 return WERR_INVALID_NAME
;
2761 /* verify that the file exists */
2762 if (sys_stat(output_file
, &st
, false) != 0) {
2763 return WERR_INVALID_NAME
;
2766 fstrcpy(pjob
->filename
, output_file
);
2768 DEBUG(3, ("print_job_spool_file:"
2769 "External spooling activated\n"));
2771 /* we do not open the file until spooling is done */
2773 pjob
->status
= PJOB_SMBD_SPOOLING
;
2779 slprintf(pjob
->filename
, sizeof(pjob
->filename
)-1,
2780 "%s/%sXXXXXX", lp_path(talloc_tos(), snum
),
2781 PRINT_SPOOL_PREFIX
);
2782 mask
= umask(S_IRWXO
| S_IRWXG
);
2783 pjob
->fd
= mkstemp(pjob
->filename
);
2786 if (pjob
->fd
== -1) {
2787 werr
= map_werror_from_unix(errno
);
2788 if (W_ERROR_EQUAL(werr
, WERR_ACCESS_DENIED
)) {
2789 /* Common setup error, force a report. */
2790 DEBUG(0, ("print_job_spool_file: "
2791 "insufficient permissions to open spool "
2792 "file %s.\n", pjob
->filename
));
2794 /* Normal case, report at level 3 and above. */
2795 DEBUG(3, ("print_job_spool_file: "
2796 "can't open spool file %s\n",
2805 /***************************************************************************
2806 Start spooling a job - return the jobid.
2807 ***************************************************************************/
2809 WERROR
print_job_start(const struct auth_session_info
*server_info
,
2810 struct messaging_context
*msg_ctx
,
2811 const char *clientmachine
,
2812 int snum
, const char *docname
, const char *filename
,
2813 struct spoolss_DeviceMode
*devmode
, uint32_t *_jobid
)
2817 struct printjob pjob
;
2818 const char *sharename
= lp_const_servicename(snum
);
2819 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2824 return WERR_INTERNAL_DB_CORRUPTION
;
2827 path
= lp_path(talloc_tos(), snum
);
2829 werr
= print_job_checks(server_info
, msg_ctx
, snum
, &njobs
);
2830 if (!W_ERROR_IS_OK(werr
)) {
2831 release_print_db(pdb
);
2835 DEBUG(10, ("print_job_start: "
2836 "Queue %s number of jobs (%d), max printjobs = %d\n",
2837 sharename
, njobs
, lp_maxprintjobs(snum
)));
2839 werr
= allocate_print_jobid(pdb
, snum
, sharename
, &jobid
);
2840 if (!W_ERROR_IS_OK(werr
)) {
2844 /* create the database entry */
2848 pjob
.pid
= getpid();
2852 pjob
.starttime
= time(NULL
);
2853 pjob
.status
= LPQ_SPOOLING
;
2855 pjob
.spooled
= False
;
2857 pjob
.devmode
= devmode
;
2859 fstrcpy(pjob
.jobname
, docname
);
2861 fstrcpy(pjob
.clientmachine
, clientmachine
);
2863 fstrcpy(pjob
.user
, lp_printjob_username(snum
));
2864 standard_sub_advanced(sharename
, server_info
->unix_info
->sanitized_username
,
2865 path
, server_info
->unix_token
->gid
,
2866 server_info
->unix_info
->sanitized_username
,
2867 server_info
->info
->domain_name
,
2868 pjob
.user
, sizeof(pjob
.user
));
2870 fstrcpy(pjob
.queuename
, lp_const_servicename(snum
));
2872 /* we have a job entry - now create the spool file */
2873 werr
= print_job_spool_file(snum
, jobid
, filename
, &pjob
);
2874 if (!W_ERROR_IS_OK(werr
)) {
2878 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, &pjob
);
2880 /* Update the 'jobs added' entry used by print_queue_status. */
2881 add_to_jobs_added(pdb
, jobid
);
2883 /* Ensure we keep a rough count of the number of total jobs... */
2884 tdb_change_int32_atomic(pdb
->tdb
, "INFO/total_jobs", &njobs
, 1);
2886 release_print_db(pdb
);
2893 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
2896 release_print_db(pdb
);
2898 DEBUG(3, ("print_job_start: returning fail. "
2899 "Error = %s\n", win_errstr(werr
)));
2903 /****************************************************************************
2904 Update the number of pages spooled to jobid
2905 ****************************************************************************/
2907 void print_job_endpage(struct messaging_context
*msg_ctx
,
2908 int snum
, uint32 jobid
)
2910 const char* sharename
= lp_const_servicename(snum
);
2911 struct printjob
*pjob
;
2912 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2913 if (tmp_ctx
== NULL
) {
2917 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2921 /* don't allow another process to get this info - it is meaningless */
2922 if (pjob
->pid
!= getpid()) {
2927 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, pjob
);
2929 talloc_free(tmp_ctx
);
2932 /****************************************************************************
2933 Print a file - called on closing the file. This spools the job.
2934 If normal close is false then we're tearing down the jobs - treat as an
2936 ****************************************************************************/
2938 NTSTATUS
print_job_end(struct messaging_context
*msg_ctx
, int snum
,
2939 uint32 jobid
, enum file_close_type close_type
)
2941 const char* sharename
= lp_const_servicename(snum
);
2942 struct printjob
*pjob
;
2944 SMB_STRUCT_STAT sbuf
;
2945 struct printif
*current_printif
= get_printer_fns(snum
);
2946 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
2948 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2949 if (tmp_ctx
== NULL
) {
2950 return NT_STATUS_NO_MEMORY
;
2953 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2955 status
= NT_STATUS_PRINT_CANCELLED
;
2959 if (pjob
->spooled
|| pjob
->pid
!= getpid()) {
2960 status
= NT_STATUS_ACCESS_DENIED
;
2964 if (close_type
== NORMAL_CLOSE
|| close_type
== SHUTDOWN_CLOSE
) {
2965 if (pjob
->status
== PJOB_SMBD_SPOOLING
) {
2966 /* take over the file now, smbd is done */
2967 if (sys_stat(pjob
->filename
, &sbuf
, false) != 0) {
2968 status
= map_nt_error_from_unix(errno
);
2969 DEBUG(3, ("print_job_end: "
2970 "stat file failed for jobid %d\n",
2975 pjob
->status
= LPQ_SPOOLING
;
2979 if ((sys_fstat(pjob
->fd
, &sbuf
, false) != 0)) {
2980 status
= map_nt_error_from_unix(errno
);
2982 DEBUG(3, ("print_job_end: "
2983 "stat file failed for jobid %d\n",
2991 pjob
->size
= sbuf
.st_ex_size
;
2995 * Not a normal close, something has gone wrong. Cleanup.
2997 if (pjob
->fd
!= -1) {
3003 /* Technically, this is not quite right. If the printer has a separator
3004 * page turned on, the NT spooler prints the separator page even if the
3005 * print job is 0 bytes. 010215 JRR */
3006 if (pjob
->size
== 0 || pjob
->status
== LPQ_DELETING
) {
3007 /* don't bother spooling empty files or something being deleted. */
3008 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
3009 pjob
->filename
, pjob
->size
? "deleted" : "zero length" ));
3010 unlink(pjob
->filename
);
3011 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
3012 return NT_STATUS_OK
;
3015 /* don't strip out characters like '$' from the printername */
3016 lpq_cmd
= talloc_string_sub2(tmp_ctx
,
3017 lp_lpq_command(talloc_tos(), snum
),
3019 lp_printername(talloc_tos(), snum
),
3020 false, false, false);
3021 if (lpq_cmd
== NULL
) {
3022 status
= NT_STATUS_PRINT_CANCELLED
;
3025 lpq_cmd
= talloc_sub_advanced(tmp_ctx
,
3026 lp_servicename(talloc_tos(), snum
),
3027 current_user_info
.unix_name
,
3029 current_user
.ut
.gid
,
3030 get_current_username(),
3031 current_user_info
.domain
,
3033 if (lpq_cmd
== NULL
) {
3034 status
= NT_STATUS_PRINT_CANCELLED
;
3038 ret
= (*(current_printif
->job_submit
))(snum
, pjob
,
3039 current_printif
->type
, lpq_cmd
);
3041 status
= NT_STATUS_PRINT_CANCELLED
;
3045 /* The print job has been successfully handed over to the back-end */
3047 pjob
->spooled
= True
;
3048 pjob
->status
= LPQ_QUEUED
;
3049 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, pjob
);
3051 /* make sure the database is up to date */
3052 if (print_cache_expired(lp_const_servicename(snum
), True
))
3053 print_queue_update(msg_ctx
, snum
, False
);
3055 return NT_STATUS_OK
;
3059 /* The print job was not successfully started. Cleanup */
3060 /* Still need to add proper error return propagation! 010122:JRR */
3062 unlink(pjob
->filename
);
3063 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
3065 talloc_free(tmp_ctx
);
3069 /****************************************************************************
3070 Get a snapshot of jobs in the system without traversing.
3071 ****************************************************************************/
3073 static bool get_stored_queue_info(struct messaging_context
*msg_ctx
,
3074 struct tdb_print_db
*pdb
, int snum
,
3075 int *pcount
, print_queue_struct
**ppqueue
)
3077 TDB_DATA data
, cgdata
, jcdata
;
3078 print_queue_struct
*queue
= NULL
;
3080 uint32 extra_count
= 0;
3081 uint32_t changed_count
= 0;
3082 int total_count
= 0;
3085 int max_reported_jobs
= lp_max_reported_print_jobs(snum
);
3087 const char* sharename
= lp_servicename(talloc_tos(), snum
);
3088 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
3089 if (tmp_ctx
== NULL
) {
3093 /* make sure the database is up to date */
3094 if (print_cache_expired(lp_const_servicename(snum
), True
))
3095 print_queue_update(msg_ctx
, snum
, False
);
3101 ZERO_STRUCT(cgdata
);
3103 /* Get the stored queue data. */
3104 data
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data("INFO/linear_queue_array"));
3106 if (data
.dptr
&& data
.dsize
>= sizeof(qcount
))
3107 len
+= tdb_unpack(data
.dptr
+ len
, data
.dsize
- len
, "d", &qcount
);
3109 /* Get the added jobs list. */
3110 cgdata
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data("INFO/jobs_added"));
3111 if (cgdata
.dptr
!= NULL
&& (cgdata
.dsize
% 4 == 0))
3112 extra_count
= cgdata
.dsize
/4;
3114 /* Get the changed jobs list. */
3115 jcdata
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data("INFO/jobs_changed"));
3116 if (jcdata
.dptr
!= NULL
&& (jcdata
.dsize
% 4 == 0))
3117 changed_count
= jcdata
.dsize
/ 4;
3119 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount
, (unsigned int)extra_count
));
3121 /* Allocate the queue size. */
3122 if (qcount
== 0 && extra_count
== 0)
3125 if ((queue
= SMB_MALLOC_ARRAY(print_queue_struct
, qcount
+ extra_count
)) == NULL
)
3128 /* Retrieve the linearised queue data. */
3130 for(i
= 0; i
< qcount
; i
++) {
3131 uint32 qjob
, qsize
, qpage_count
, qstatus
, qpriority
, qtime
;
3132 len
+= tdb_unpack(data
.dptr
+ len
, data
.dsize
- len
, "ddddddff",
3141 queue
[i
].sysjob
= qjob
;
3142 queue
[i
].size
= qsize
;
3143 queue
[i
].page_count
= qpage_count
;
3144 queue
[i
].status
= qstatus
;
3145 queue
[i
].priority
= qpriority
;
3146 queue
[i
].time
= qtime
;
3149 total_count
= qcount
;
3151 /* Add new jobids to the queue. */
3152 for (i
= 0; i
< extra_count
; i
++) {
3154 struct printjob
*pjob
;
3156 jobid
= IVAL(cgdata
.dptr
, i
*4);
3157 DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid
));
3158 pjob
= print_job_find(tmp_ctx
, lp_const_servicename(snum
), jobid
);
3160 DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid
));
3161 remove_from_jobs_added(sharename
, jobid
);
3165 queue
[total_count
].sysjob
= pjob
->sysjob
;
3166 queue
[total_count
].size
= pjob
->size
;
3167 queue
[total_count
].page_count
= pjob
->page_count
;
3168 queue
[total_count
].status
= pjob
->status
;
3169 queue
[total_count
].priority
= 1;
3170 queue
[total_count
].time
= pjob
->starttime
;
3171 fstrcpy(queue
[total_count
].fs_user
, pjob
->user
);
3172 fstrcpy(queue
[total_count
].fs_file
, pjob
->jobname
);
3177 /* Update the changed jobids. */
3178 for (i
= 0; i
< changed_count
; i
++) {
3179 uint32_t jobid
= IVAL(jcdata
.dptr
, i
* 4);
3180 struct printjob
*pjob
;
3184 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
3186 DEBUG(5,("get_stored_queue_info: failed to find "
3187 "changed job = %u\n",
3188 (unsigned int)jobid
));
3189 remove_from_jobs_changed(sharename
, jobid
);
3193 for (j
= 0; j
< total_count
; j
++) {
3194 if (queue
[j
].sysjob
== pjob
->sysjob
) {
3201 DEBUG(5,("get_stored_queue_info: changed job: %u\n",
3202 (unsigned int)jobid
));
3204 queue
[j
].sysjob
= pjob
->sysjob
;
3205 queue
[j
].size
= pjob
->size
;
3206 queue
[j
].page_count
= pjob
->page_count
;
3207 queue
[j
].status
= pjob
->status
;
3208 queue
[j
].priority
= 1;
3209 queue
[j
].time
= pjob
->starttime
;
3210 fstrcpy(queue
[j
].fs_user
, pjob
->user
);
3211 fstrcpy(queue
[j
].fs_file
, pjob
->jobname
);
3214 DEBUG(5,("updated queue[%u], jobid: %u, sysjob: %u, "
3216 (unsigned int)j
, (unsigned int)jobid
,
3217 (unsigned int)queue
[j
].sysjob
, pjob
->jobname
));
3220 remove_from_jobs_changed(sharename
, jobid
);
3223 /* Sort the queue by submission time otherwise they are displayed
3226 TYPESAFE_QSORT(queue
, total_count
, printjob_comp
);
3228 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count
));
3230 if (max_reported_jobs
&& total_count
> max_reported_jobs
)
3231 total_count
= max_reported_jobs
;
3234 *pcount
= total_count
;
3240 SAFE_FREE(data
.dptr
);
3241 SAFE_FREE(cgdata
.dptr
);
3242 talloc_free(tmp_ctx
);
3246 /****************************************************************************
3247 Get a printer queue listing.
3248 set queue = NULL and status = NULL if you just want to update the cache
3249 ****************************************************************************/
3251 int print_queue_status(struct messaging_context
*msg_ctx
, int snum
,
3252 print_queue_struct
**ppqueue
,
3253 print_status_struct
*status
)
3257 const char *sharename
;
3258 struct tdb_print_db
*pdb
;
3261 /* make sure the database is up to date */
3263 if (print_cache_expired(lp_const_servicename(snum
), True
))
3264 print_queue_update(msg_ctx
, snum
, False
);
3266 /* return if we are done */
3267 if ( !ppqueue
|| !status
)
3271 sharename
= lp_const_servicename(snum
);
3272 pdb
= get_print_db_byname(sharename
);
3278 * Fetch the queue status. We must do this first, as there may
3279 * be no jobs in the queue.
3282 ZERO_STRUCTP(status
);
3283 slprintf(keystr
, sizeof(keystr
)-1, "STATUS/%s", sharename
);
3284 key
= string_tdb_data(keystr
);
3286 data
= tdb_fetch_compat(pdb
->tdb
, key
);
3288 if (data
.dsize
== sizeof(*status
)) {
3289 /* this memcpy is ok since the status struct was
3290 not packed before storing it in the tdb */
3291 memcpy(status
, data
.dptr
, sizeof(*status
));
3293 SAFE_FREE(data
.dptr
);
3297 * Now, fetch the print queue information. We first count the number
3298 * of entries, and then only retrieve the queue if necessary.
3301 if (!get_stored_queue_info(msg_ctx
, pdb
, snum
, &count
, ppqueue
)) {
3302 release_print_db(pdb
);
3306 release_print_db(pdb
);
3310 /****************************************************************************
3312 ****************************************************************************/
3314 WERROR
print_queue_pause(const struct auth_session_info
*server_info
,
3315 struct messaging_context
*msg_ctx
, int snum
)
3318 struct printif
*current_printif
= get_printer_fns( snum
);
3320 if (!W_ERROR_IS_OK(print_access_check(server_info
, msg_ctx
, snum
,
3321 PRINTER_ACCESS_ADMINISTER
))) {
3322 return WERR_ACCESS_DENIED
;
3328 ret
= (*(current_printif
->queue_pause
))(snum
);
3333 return WERR_INVALID_PARAM
;
3336 /* force update the database */
3337 print_cache_flush(lp_const_servicename(snum
));
3339 /* Send a printer notify message */
3341 notify_printer_status(server_event_context(), msg_ctx
, snum
,
3342 PRINTER_STATUS_PAUSED
);
3347 /****************************************************************************
3349 ****************************************************************************/
3351 WERROR
print_queue_resume(const struct auth_session_info
*server_info
,
3352 struct messaging_context
*msg_ctx
, int snum
)
3355 struct printif
*current_printif
= get_printer_fns( snum
);
3357 if (!W_ERROR_IS_OK(print_access_check(server_info
, msg_ctx
, snum
,
3358 PRINTER_ACCESS_ADMINISTER
))) {
3359 return WERR_ACCESS_DENIED
;
3364 ret
= (*(current_printif
->queue_resume
))(snum
);
3369 return WERR_INVALID_PARAM
;
3372 /* make sure the database is up to date */
3373 if (print_cache_expired(lp_const_servicename(snum
), True
))
3374 print_queue_update(msg_ctx
, snum
, True
);
3376 /* Send a printer notify message */
3378 notify_printer_status(server_event_context(), msg_ctx
, snum
,
3384 /****************************************************************************
3385 Purge a queue - implemented by deleting all jobs that we can delete.
3386 ****************************************************************************/
3388 WERROR
print_queue_purge(const struct auth_session_info
*server_info
,
3389 struct messaging_context
*msg_ctx
, int snum
)
3391 print_queue_struct
*queue
;
3392 print_status_struct status
;
3396 /* Force and update so the count is accurate (i.e. not a cached count) */
3397 print_queue_update(msg_ctx
, snum
, True
);
3399 can_job_admin
= W_ERROR_IS_OK(print_access_check(server_info
,
3402 JOB_ACCESS_ADMINISTER
));
3403 njobs
= print_queue_status(msg_ctx
, snum
, &queue
, &status
);
3405 if ( can_job_admin
)
3408 for (i
= 0; i
< njobs
; i
++) {
3409 struct tdb_print_db
*pdb
;
3412 pdb
= get_print_db_byname(lp_const_servicename(snum
));
3414 DEBUG(1, ("failed to find printdb for %s\n",
3415 lp_const_servicename(snum
)));
3418 jobid
= sysjob_to_jobid_pdb(pdb
, queue
[i
].sysjob
);
3419 if (jobid
== (uint32_t)-1) {
3420 DEBUG(2, ("jobid for system job %d not found\n",
3422 continue; /* unix job */
3424 owner
= is_owner(server_info
, lp_const_servicename(snum
),
3427 if (owner
|| can_job_admin
) {
3428 print_job_delete1(server_event_context(), msg_ctx
,
3433 if ( can_job_admin
)
3436 /* update the cache */
3437 print_queue_update(msg_ctx
, snum
, True
);