2 Unix SMB/Netbios implementation.
4 printing backend routines
5 Copyright (C) Andrew Tridgell 1992-2000
6 Copyright (C) Jeremy Allison 2002
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "system/syslog.h"
24 #include "system/filesys.h"
26 #include "../librpc/gen_ndr/ndr_spoolss.h"
27 #include "nt_printing.h"
28 #include "../librpc/gen_ndr/netlogon.h"
29 #include "printing/notify.h"
30 #include "printing/pcap.h"
31 #include "printing/printer_list.h"
32 #include "printing/queue_process.h"
34 #include "smbd/smbd.h"
38 #include "lib/param/loadparm.h"
40 extern struct current_user current_user
;
41 extern userdom_struct current_user_info
;
43 /* Current printer interface */
44 static bool remove_from_jobs_added(const char* sharename
, uint32 jobid
);
47 the printing backend revolves around a tdb database that stores the
48 SMB view of the print queue
50 The key for this database is a jobid - a internally generated number that
51 uniquely identifies a print job
53 reading the print queue involves two steps:
54 - possibly running lpq and updating the internal database from that
55 - reading entries from the database
57 jobids are assigned when a job starts spooling.
60 static TDB_CONTEXT
*rap_tdb
;
61 static uint16 next_rap_jobid
;
62 struct rap_jobid_key
{
67 /***************************************************************************
68 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
69 bit RPC jobids.... JRA.
70 ***************************************************************************/
72 uint16
pjobid_to_rap(const char* sharename
, uint32 jobid
)
76 struct rap_jobid_key jinfo
;
79 DEBUG(10,("pjobid_to_rap: called.\n"));
82 /* Create the in-memory tdb. */
83 rap_tdb
= tdb_open_log(NULL
, 0, TDB_INTERNAL
, (O_RDWR
|O_CREAT
), 0644);
89 fstrcpy( jinfo
.sharename
, sharename
);
91 key
.dptr
= (uint8
*)&jinfo
;
92 key
.dsize
= sizeof(jinfo
);
94 data
= tdb_fetch_compat(rap_tdb
, key
);
95 if (data
.dptr
&& data
.dsize
== sizeof(uint16
)) {
96 rap_jobid
= SVAL(data
.dptr
, 0);
98 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
99 (unsigned int)jobid
, (unsigned int)rap_jobid
));
102 SAFE_FREE(data
.dptr
);
103 /* Not found - create and store mapping. */
104 rap_jobid
= ++next_rap_jobid
;
106 rap_jobid
= ++next_rap_jobid
;
107 SSVAL(buf
,0,rap_jobid
);
109 data
.dsize
= sizeof(rap_jobid
);
110 tdb_store(rap_tdb
, key
, data
, TDB_REPLACE
);
111 tdb_store(rap_tdb
, data
, key
, TDB_REPLACE
);
113 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
114 (unsigned int)jobid
, (unsigned int)rap_jobid
));
118 bool rap_to_pjobid(uint16 rap_jobid
, fstring sharename
, uint32
*pjobid
)
123 DEBUG(10,("rap_to_pjobid called.\n"));
128 SSVAL(buf
,0,rap_jobid
);
130 key
.dsize
= sizeof(rap_jobid
);
131 data
= tdb_fetch_compat(rap_tdb
, key
);
132 if ( data
.dptr
&& data
.dsize
== sizeof(struct rap_jobid_key
) )
134 struct rap_jobid_key
*jinfo
= (struct rap_jobid_key
*)data
.dptr
;
135 if (sharename
!= NULL
) {
136 fstrcpy( sharename
, jinfo
->sharename
);
138 *pjobid
= jinfo
->jobid
;
139 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
140 (unsigned int)*pjobid
, (unsigned int)rap_jobid
));
141 SAFE_FREE(data
.dptr
);
145 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
146 (unsigned int)rap_jobid
));
147 SAFE_FREE(data
.dptr
);
151 void rap_jobid_delete(const char* sharename
, uint32 jobid
)
155 struct rap_jobid_key jinfo
;
158 DEBUG(10,("rap_jobid_delete: called.\n"));
163 ZERO_STRUCT( jinfo
);
164 fstrcpy( jinfo
.sharename
, sharename
);
166 key
.dptr
= (uint8
*)&jinfo
;
167 key
.dsize
= sizeof(jinfo
);
169 data
= tdb_fetch_compat(rap_tdb
, key
);
170 if (!data
.dptr
|| (data
.dsize
!= sizeof(uint16
))) {
171 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
172 (unsigned int)jobid
));
173 SAFE_FREE(data
.dptr
);
177 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
178 (unsigned int)jobid
));
180 rap_jobid
= SVAL(data
.dptr
, 0);
181 SAFE_FREE(data
.dptr
);
182 SSVAL(buf
,0,rap_jobid
);
184 data
.dsize
= sizeof(rap_jobid
);
185 tdb_delete(rap_tdb
, key
);
186 tdb_delete(rap_tdb
, data
);
189 static int get_queue_status(const char* sharename
, print_status_struct
*);
191 /****************************************************************************
192 Initialise the printing backend. Called once at startup before the fork().
193 ****************************************************************************/
195 bool print_backend_init(struct messaging_context
*msg_ctx
)
197 const char *sversion
= "INFO/version";
198 int services
= lp_numservices();
201 char *print_cache_path
;
203 if (!printer_list_parent_init()) {
207 print_cache_path
= cache_path("printing");
208 if (print_cache_path
== NULL
) {
211 ok
= directory_create_or_exist(print_cache_path
, 0755);
212 TALLOC_FREE(print_cache_path
);
217 print_cache_path
= cache_path("printing.tdb");
218 if (print_cache_path
== NULL
) {
221 unlink(print_cache_path
);
222 TALLOC_FREE(print_cache_path
);
224 /* handle a Samba upgrade */
226 for (snum
= 0; snum
< services
; snum
++) {
227 struct tdb_print_db
*pdb
;
228 if (!lp_printable(snum
))
231 pdb
= get_print_db_byname(lp_const_servicename(snum
));
234 if (tdb_lock_bystring(pdb
->tdb
, sversion
) != 0) {
235 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum
) ));
236 release_print_db(pdb
);
239 if (tdb_fetch_int32(pdb
->tdb
, sversion
) != PRINT_DATABASE_VERSION
) {
240 tdb_wipe_all(pdb
->tdb
);
241 tdb_store_int32(pdb
->tdb
, sversion
, PRINT_DATABASE_VERSION
);
243 tdb_unlock_bystring(pdb
->tdb
, sversion
);
244 release_print_db(pdb
);
247 close_all_print_db(); /* Don't leave any open. */
249 /* do NT print initialization... */
250 return nt_printing_init(msg_ctx
);
253 /****************************************************************************
254 Shut down printing backend. Called once at shutdown to close the tdb.
255 ****************************************************************************/
257 void printing_end(void)
259 close_all_print_db(); /* Don't leave any open. */
262 /****************************************************************************
263 Retrieve the set of printing functions for a given service. This allows
264 us to set the printer function table based on the value of the 'printing'
267 Use the generic interface as the default and only use cups interface only
268 when asked for (and only when supported)
269 ****************************************************************************/
271 static struct printif
*get_printer_fns_from_type( enum printing_types type
)
273 struct printif
*printer_fns
= &generic_printif
;
276 if ( type
== PRINT_CUPS
) {
277 printer_fns
= &cups_printif
;
279 #endif /* HAVE_CUPS */
282 if ( type
== PRINT_IPRINT
) {
283 printer_fns
= &iprint_printif
;
285 #endif /* HAVE_IPRINT */
287 printer_fns
->type
= type
;
292 static struct printif
*get_printer_fns( int snum
)
294 return get_printer_fns_from_type( (enum printing_types
)lp_printing(snum
) );
298 /****************************************************************************
299 Useful function to generate a tdb key.
300 ****************************************************************************/
302 static TDB_DATA
print_key(uint32 jobid
, uint32
*tmp
)
306 SIVAL(tmp
, 0, jobid
);
307 ret
.dptr
= (uint8
*)tmp
;
308 ret
.dsize
= sizeof(*tmp
);
312 /****************************************************************************
313 Pack the devicemode to store it in a tdb.
314 ****************************************************************************/
315 static int pack_devicemode(struct spoolss_DeviceMode
*devmode
, uint8
*buf
, int buflen
)
317 enum ndr_err_code ndr_err
;
322 ndr_err
= ndr_push_struct_blob(&blob
, talloc_tos(),
324 (ndr_push_flags_fn_t
)
325 ndr_push_spoolss_DeviceMode
);
326 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
327 DEBUG(10, ("pack_devicemode: "
328 "error encoding spoolss_DeviceMode\n"));
335 len
= tdb_pack(buf
, buflen
, "B", blob
.length
, blob
.data
);
338 DEBUG(8, ("Packed devicemode [%s]\n", devmode
->formname
));
345 /****************************************************************************
346 Unpack the devicemode to store it in a tdb.
347 ****************************************************************************/
348 static int unpack_devicemode(TALLOC_CTX
*mem_ctx
,
349 const uint8
*buf
, int buflen
,
350 struct spoolss_DeviceMode
**devmode
)
352 struct spoolss_DeviceMode
*dm
;
353 enum ndr_err_code ndr_err
;
361 len
= tdb_unpack(buf
, buflen
, "B", &data_len
, &data
);
366 dm
= talloc_zero(mem_ctx
, struct spoolss_DeviceMode
);
371 blob
= data_blob_const(data
, data_len
);
373 ndr_err
= ndr_pull_struct_blob(&blob
, dm
, dm
,
374 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_DeviceMode
);
375 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
376 DEBUG(10, ("unpack_devicemode: "
377 "error parsing spoolss_DeviceMode\n"));
381 DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
382 dm
->devicename
, dm
->formname
));
383 if (dm
->driverextra_data
.data
) {
384 DEBUG(8, ("with a private section of %d bytes\n",
385 dm
->__driverextra_length
));
395 /***********************************************************************
396 unpack a pjob from a tdb buffer
397 ***********************************************************************/
399 static int unpack_pjob(TALLOC_CTX
*mem_ctx
, uint8
*buf
, int buflen
,
400 struct printjob
*pjob
)
404 uint32 pjpid
, pjjobid
, pjsysjob
, pjfd
, pjstarttime
, pjstatus
;
405 uint32 pjsize
, pjpage_count
, pjspooled
, pjsmbjob
;
411 len
+= tdb_unpack(buf
+len
, buflen
-len
, "ddddddddddfffff",
432 used
= unpack_devicemode(mem_ctx
, buf
+len
, buflen
-len
, &pjob
->devmode
);
440 pjob
->jobid
= pjjobid
;
441 pjob
->sysjob
= pjsysjob
;
443 pjob
->starttime
= pjstarttime
;
444 pjob
->status
= pjstatus
;
446 pjob
->page_count
= pjpage_count
;
447 pjob
->spooled
= pjspooled
;
448 pjob
->smbjob
= pjsmbjob
;
454 /****************************************************************************
455 Useful function to find a print job in the database.
456 ****************************************************************************/
458 static struct printjob
*print_job_find(TALLOC_CTX
*mem_ctx
,
459 const char *sharename
,
462 struct printjob
*pjob
;
465 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
467 DEBUG(10,("print_job_find: looking up job %u for share %s\n",
468 (unsigned int)jobid
, sharename
));
474 ret
= tdb_fetch_compat(pdb
->tdb
, print_key(jobid
, &tmp
));
475 release_print_db(pdb
);
478 DEBUG(10, ("print_job_find: failed to find jobid %u.\n",
483 pjob
= talloc_zero(mem_ctx
, struct printjob
);
488 if (unpack_pjob(mem_ctx
, ret
.dptr
, ret
.dsize
, pjob
) == -1) {
489 DEBUG(10, ("failed to unpack jobid %u.\n", jobid
));
495 DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
496 pjob
->sysjob
, jobid
));
497 SMB_ASSERT(pjob
->jobid
== jobid
);
504 /* Convert a unix jobid to a smb jobid */
506 struct unixjob_traverse_state
{
508 uint32 sysjob_to_jobid_value
;
511 static int unixjob_traverse_fn(TDB_CONTEXT
*the_tdb
, TDB_DATA key
,
512 TDB_DATA data
, void *private_data
)
514 struct printjob
*pjob
;
515 struct unixjob_traverse_state
*state
=
516 (struct unixjob_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
->sysjob_to_jobid_value
= pjob
->jobid
;
533 uint32
sysjob_to_jobid_pdb(struct tdb_print_db
*pdb
, int sysjob
)
535 struct unixjob_traverse_state state
;
537 state
.sysjob
= sysjob
;
538 state
.sysjob_to_jobid_value
= (uint32
)-1;
540 tdb_traverse(pdb
->tdb
, unixjob_traverse_fn
, &state
);
542 return state
.sysjob_to_jobid_value
;
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 unixjob_traverse_state state
;
556 state
.sysjob
= unix_jobid
;
557 state
.sysjob_to_jobid_value
= (uint32
)-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
, unixjob_traverse_fn
, &state
);
568 release_print_db(pdb
);
569 if (state
.sysjob_to_jobid_value
!= (uint32
)-1)
570 return state
.sysjob_to_jobid_value
;
575 /****************************************************************************
576 Send notifications based on what has changed after a pjob_store.
577 ****************************************************************************/
579 static const struct {
581 uint32_t spoolss_status
;
582 } lpq_to_spoolss_status_map
[] = {
583 { LPQ_QUEUED
, JOB_STATUS_QUEUED
},
584 { LPQ_PAUSED
, JOB_STATUS_PAUSED
},
585 { LPQ_SPOOLING
, JOB_STATUS_SPOOLING
},
586 { LPQ_PRINTING
, JOB_STATUS_PRINTING
},
587 { LPQ_DELETING
, JOB_STATUS_DELETING
},
588 { LPQ_OFFLINE
, JOB_STATUS_OFFLINE
},
589 { LPQ_PAPEROUT
, JOB_STATUS_PAPEROUT
},
590 { LPQ_PRINTED
, JOB_STATUS_PRINTED
},
591 { LPQ_DELETED
, JOB_STATUS_DELETED
},
592 { LPQ_BLOCKED
, JOB_STATUS_BLOCKED_DEVQ
},
593 { LPQ_USER_INTERVENTION
, JOB_STATUS_USER_INTERVENTION
},
597 /* Convert a lpq status value stored in printing.tdb into the
598 appropriate win32 API constant. */
600 static uint32
map_to_spoolss_status(uint32 lpq_status
)
604 while (lpq_to_spoolss_status_map
[i
].lpq_status
!= -1) {
605 if (lpq_to_spoolss_status_map
[i
].lpq_status
== lpq_status
)
606 return lpq_to_spoolss_status_map
[i
].spoolss_status
;
613 /***************************************************************************
614 Append a jobid to the 'jobs changed' list.
615 ***************************************************************************/
617 static bool add_to_jobs_changed(struct tdb_print_db
*pdb
, uint32_t jobid
)
620 uint32_t store_jobid
;
622 SIVAL(&store_jobid
, 0, jobid
);
623 data
.dptr
= (uint8
*) &store_jobid
;
626 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid
));
628 return (tdb_append(pdb
->tdb
, string_tdb_data("INFO/jobs_changed"),
632 /***************************************************************************
633 Remove a jobid from the 'jobs changed' list.
634 ***************************************************************************/
636 static bool remove_from_jobs_changed(const char* sharename
, uint32_t jobid
)
638 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
642 bool gotlock
= False
;
650 key
= string_tdb_data("INFO/jobs_changed");
652 if (tdb_chainlock_with_timeout(pdb
->tdb
, key
, 5) != 0)
657 data
= tdb_fetch_compat(pdb
->tdb
, key
);
659 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0))
662 job_count
= data
.dsize
/ 4;
663 for (i
= 0; i
< job_count
; i
++) {
666 ch_jobid
= IVAL(data
.dptr
, i
*4);
667 if (ch_jobid
== jobid
) {
668 if (i
< job_count
-1 )
669 memmove(data
.dptr
+ (i
*4), data
.dptr
+ (i
*4) + 4, (job_count
- i
- 1)*4 );
671 if (tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
) != 0)
681 tdb_chainunlock(pdb
->tdb
, key
);
682 SAFE_FREE(data
.dptr
);
683 release_print_db(pdb
);
685 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid
));
687 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid
));
691 static void pjob_store_notify(struct tevent_context
*ev
,
692 struct messaging_context
*msg_ctx
,
693 const char* sharename
, uint32 jobid
,
694 struct printjob
*old_data
,
695 struct printjob
*new_data
,
698 bool new_job
= false;
699 bool changed
= false;
701 if (old_data
== NULL
) {
705 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
706 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
707 time first or else we'll end up with potential alignment
708 errors. I don't think the systemtime should be spooled as
709 a string, but this gets us around that error.
710 --jerry (i'll feel dirty for this) */
713 notify_job_submitted(ev
, msg_ctx
,
714 sharename
, jobid
, new_data
->starttime
);
715 notify_job_username(ev
, msg_ctx
,
716 sharename
, jobid
, new_data
->user
);
717 notify_job_name(ev
, msg_ctx
,
718 sharename
, jobid
, new_data
->jobname
);
719 notify_job_status(ev
, msg_ctx
,
720 sharename
, jobid
, map_to_spoolss_status(new_data
->status
));
721 notify_job_total_bytes(ev
, msg_ctx
,
722 sharename
, jobid
, new_data
->size
);
723 notify_job_total_pages(ev
, msg_ctx
,
724 sharename
, jobid
, new_data
->page_count
);
726 if (!strequal(old_data
->jobname
, new_data
->jobname
)) {
727 notify_job_name(ev
, msg_ctx
, sharename
,
728 jobid
, new_data
->jobname
);
732 if (old_data
->status
!= new_data
->status
) {
733 notify_job_status(ev
, msg_ctx
,
735 map_to_spoolss_status(new_data
->status
));
738 if (old_data
->size
!= new_data
->size
) {
739 notify_job_total_bytes(ev
, msg_ctx
,
740 sharename
, jobid
, new_data
->size
);
743 if (old_data
->page_count
!= new_data
->page_count
) {
744 notify_job_total_pages(ev
, msg_ctx
,
746 new_data
->page_count
);
753 /****************************************************************************
754 Store a job structure back to the database.
755 ****************************************************************************/
757 static bool pjob_store(struct tevent_context
*ev
,
758 struct messaging_context
*msg_ctx
,
759 const char* sharename
, uint32 jobid
,
760 struct printjob
*pjob
)
763 TDB_DATA old_data
, new_data
;
765 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
767 int len
, newlen
, buflen
;
775 old_data
= tdb_fetch_compat(pdb
->tdb
, print_key(jobid
, &tmp
));
777 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
784 len
+= tdb_pack(buf
+len
, buflen
-len
, "ddddddddddfffff",
787 (uint32
)pjob
->sysjob
,
789 (uint32
)pjob
->starttime
,
790 (uint32
)pjob
->status
,
792 (uint32
)pjob
->page_count
,
793 (uint32
)pjob
->spooled
,
794 (uint32
)pjob
->smbjob
,
801 len
+= pack_devicemode(pjob
->devmode
, buf
+len
, buflen
-len
);
804 buf
= (uint8
*)SMB_REALLOC(buf
, len
);
806 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
811 } while ( buflen
!= len
);
817 new_data
.dsize
= len
;
818 ret
= (tdb_store(pdb
->tdb
, print_key(jobid
, &tmp
), new_data
,
821 /* Send notify updates for what has changed */
824 bool changed
= false;
825 struct printjob old_pjob
;
827 if (old_data
.dsize
) {
828 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
832 len
= unpack_pjob(tmp_ctx
, old_data
.dptr
,
833 old_data
.dsize
, &old_pjob
);
835 pjob_store_notify(ev
,
837 sharename
, jobid
, &old_pjob
,
841 add_to_jobs_changed(pdb
, jobid
);
844 talloc_free(tmp_ctx
);
848 pjob_store_notify(ev
, msg_ctx
,
849 sharename
, jobid
, NULL
, pjob
,
855 release_print_db(pdb
);
856 SAFE_FREE( old_data
.dptr
);
862 /****************************************************************************
863 Remove a job structure from the database.
864 ****************************************************************************/
866 static void pjob_delete(struct tevent_context
*ev
,
867 struct messaging_context
*msg_ctx
,
868 const char* sharename
, uint32 jobid
)
871 struct printjob
*pjob
;
872 uint32 job_status
= 0;
873 struct tdb_print_db
*pdb
;
874 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
875 if (tmp_ctx
== NULL
) {
879 pdb
= get_print_db_byname(sharename
);
884 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
886 DEBUG(5, ("we were asked to delete nonexistent job %u\n",
891 /* We must cycle through JOB_STATUS_DELETING and
892 JOB_STATUS_DELETED for the port monitor to delete the job
895 job_status
= JOB_STATUS_DELETING
|JOB_STATUS_DELETED
;
896 notify_job_status(ev
, msg_ctx
, sharename
, jobid
, job_status
);
898 /* Remove from printing.tdb */
900 tdb_delete(pdb
->tdb
, print_key(jobid
, &tmp
));
901 remove_from_jobs_added(sharename
, jobid
);
902 rap_jobid_delete(sharename
, jobid
);
904 release_print_db(pdb
);
906 talloc_free(tmp_ctx
);
909 /****************************************************************************
910 List a unix job in the print database.
911 ****************************************************************************/
913 static void print_unix_job(struct tevent_context
*ev
,
914 struct messaging_context
*msg_ctx
,
915 const char *sharename
, print_queue_struct
*q
,
918 struct printjob pj
, *old_pj
;
919 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
920 if (tmp_ctx
== NULL
) {
924 if (jobid
== (uint32
)-1) {
925 jobid
= q
->sysjob
+ UNIX_JOB_START
;
928 /* Preserve the timestamp on an existing unix print job */
930 old_pj
= print_job_find(tmp_ctx
, sharename
, jobid
);
936 pj
.sysjob
= q
->sysjob
;
938 pj
.starttime
= old_pj
? old_pj
->starttime
: q
->time
;
939 pj
.status
= q
->status
;
942 fstrcpy(pj
.filename
, old_pj
? old_pj
->filename
: "");
943 if (jobid
< UNIX_JOB_START
) {
945 fstrcpy(pj
.jobname
, old_pj
? old_pj
->jobname
: "Remote Downlevel Document");
948 fstrcpy(pj
.jobname
, old_pj
? old_pj
->jobname
: q
->fs_file
);
950 fstrcpy(pj
.user
, old_pj
? old_pj
->user
: q
->fs_user
);
951 fstrcpy(pj
.queuename
, old_pj
? old_pj
->queuename
: sharename
);
953 pjob_store(ev
, msg_ctx
, sharename
, jobid
, &pj
);
954 talloc_free(tmp_ctx
);
958 struct traverse_struct
{
959 print_queue_struct
*queue
;
960 int qcount
, snum
, maxcount
, total_jobs
;
961 const char *sharename
;
963 const char *lprm_command
;
964 struct printif
*print_if
;
965 struct tevent_context
*ev
;
966 struct messaging_context
*msg_ctx
;
970 /****************************************************************************
971 Utility fn to delete any jobs that are no longer active.
972 ****************************************************************************/
974 static int traverse_fn_delete(TDB_CONTEXT
*t
, TDB_DATA key
, TDB_DATA data
, void *state
)
976 struct traverse_struct
*ts
= (struct traverse_struct
*)state
;
977 struct printjob pjob
;
981 if ( key
.dsize
!= sizeof(jobid
) )
984 if (unpack_pjob(ts
->mem_ctx
, data
.dptr
, data
.dsize
, &pjob
) == -1)
986 talloc_free(pjob
.devmode
);
990 /* remove a unix job if it isn't in the system queue any more */
991 for (i
=0;i
<ts
->qcount
;i
++) {
992 if (ts
->queue
[i
].sysjob
== pjob
.sysjob
) {
996 if (i
== ts
->qcount
) {
997 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
998 (unsigned int)jobid
));
999 pjob_delete(ts
->ev
, ts
->msg_ctx
,
1000 ts
->sharename
, jobid
);
1004 /* need to continue the the bottom of the function to
1005 save the correct attributes */
1008 /* maybe it hasn't been spooled yet */
1009 if (!pjob
.spooled
) {
1010 /* if a job is not spooled and the process doesn't
1011 exist then kill it. This cleans up after smbd
1013 if (!process_exists_by_pid(pjob
.pid
)) {
1014 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
1015 (unsigned int)jobid
, (unsigned int)pjob
.pid
));
1016 pjob_delete(ts
->ev
, ts
->msg_ctx
,
1017 ts
->sharename
, jobid
);
1023 /* this check only makes sense for jobs submitted from Windows clients */
1026 for (i
=0;i
<ts
->qcount
;i
++) {
1027 if ( pjob
.status
== LPQ_DELETED
)
1030 if (ts
->queue
[i
].sysjob
== pjob
.sysjob
) {
1032 /* try to clean up any jobs that need to be deleted */
1034 if ( pjob
.status
== LPQ_DELETING
) {
1037 result
= (*(ts
->print_if
->job_delete
))(
1038 ts
->sharename
, ts
->lprm_command
, &pjob
);
1040 if ( result
!= 0 ) {
1041 /* if we can't delete, then reset the job status */
1042 pjob
.status
= LPQ_QUEUED
;
1043 pjob_store(ts
->ev
, ts
->msg_ctx
,
1044 ts
->sharename
, jobid
, &pjob
);
1047 /* if we deleted the job, the remove the tdb record */
1050 ts
->sharename
, jobid
);
1051 pjob
.status
= LPQ_DELETED
;
1061 /* The job isn't in the system queue - we have to assume it has
1062 completed, so delete the database entry. */
1064 if (i
== ts
->qcount
) {
1066 /* A race can occur between the time a job is spooled and
1067 when it appears in the lpq output. This happens when
1068 the job is added to printing.tdb when another smbd
1069 running print_queue_update() has completed a lpq and
1070 is currently traversing the printing tdb and deleting jobs.
1071 Don't delete the job if it was submitted after the lpq_time. */
1073 if (pjob
.starttime
< ts
->lpq_time
) {
1074 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
1075 (unsigned int)jobid
,
1076 (unsigned int)pjob
.starttime
,
1077 (unsigned int)ts
->lpq_time
));
1078 pjob_delete(ts
->ev
, ts
->msg_ctx
,
1079 ts
->sharename
, jobid
);
1085 /* Save the pjob attributes we will store. */
1086 ts
->queue
[i
].sysjob
= pjob
.sysjob
;
1087 ts
->queue
[i
].size
= pjob
.size
;
1088 ts
->queue
[i
].page_count
= pjob
.page_count
;
1089 ts
->queue
[i
].status
= pjob
.status
;
1090 ts
->queue
[i
].priority
= 1;
1091 ts
->queue
[i
].time
= pjob
.starttime
;
1092 fstrcpy(ts
->queue
[i
].fs_user
, pjob
.user
);
1093 fstrcpy(ts
->queue
[i
].fs_file
, pjob
.jobname
);
1100 /****************************************************************************
1101 Check if the print queue has been updated recently enough.
1102 ****************************************************************************/
1104 static void print_cache_flush(const char *sharename
)
1107 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1111 slprintf(key
, sizeof(key
)-1, "CACHE/%s", sharename
);
1112 tdb_store_int32(pdb
->tdb
, key
, -1);
1113 release_print_db(pdb
);
1116 /****************************************************************************
1117 Check if someone already thinks they are doing the update.
1118 ****************************************************************************/
1120 static pid_t
get_updating_pid(const char *sharename
)
1125 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1129 slprintf(keystr
, sizeof(keystr
)-1, "UPDATING/%s", sharename
);
1130 key
= string_tdb_data(keystr
);
1132 data
= tdb_fetch_compat(pdb
->tdb
, key
);
1133 release_print_db(pdb
);
1134 if (!data
.dptr
|| data
.dsize
!= sizeof(pid_t
)) {
1135 SAFE_FREE(data
.dptr
);
1139 updating_pid
= IVAL(data
.dptr
, 0);
1140 SAFE_FREE(data
.dptr
);
1142 if (process_exists_by_pid(updating_pid
))
1143 return updating_pid
;
1148 /****************************************************************************
1149 Set the fact that we're doing the update, or have finished doing the update
1151 ****************************************************************************/
1153 static void set_updating_pid(const fstring sharename
, bool updating
)
1158 pid_t updating_pid
= getpid();
1161 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1166 slprintf(keystr
, sizeof(keystr
)-1, "UPDATING/%s", sharename
);
1167 key
= string_tdb_data(keystr
);
1169 DEBUG(5, ("set_updating_pid: %supdating lpq cache for print share %s\n",
1170 updating
? "" : "not ",
1174 tdb_delete(pdb
->tdb
, key
);
1175 release_print_db(pdb
);
1179 SIVAL( buffer
, 0, updating_pid
);
1181 data
.dsize
= 4; /* we always assume this is a 4 byte value */
1183 tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
);
1184 release_print_db(pdb
);
1187 /****************************************************************************
1188 Sort print jobs by submittal time.
1189 ****************************************************************************/
1191 static int printjob_comp(print_queue_struct
*j1
, print_queue_struct
*j2
)
1202 /* Sort on job start time */
1204 if (j1
->time
== j2
->time
)
1206 return (j1
->time
> j2
->time
) ? 1 : -1;
1209 /****************************************************************************
1210 Store the sorted queue representation for later portmon retrieval.
1212 ****************************************************************************/
1214 static void store_queue_struct(struct tdb_print_db
*pdb
, struct traverse_struct
*pts
)
1217 int max_reported_jobs
= lp_max_reported_print_jobs(pts
->snum
);
1218 print_queue_struct
*queue
= pts
->queue
;
1221 unsigned int qcount
;
1223 if (max_reported_jobs
&& (max_reported_jobs
< pts
->qcount
))
1224 pts
->qcount
= max_reported_jobs
;
1227 /* Work out the size. */
1229 data
.dsize
+= tdb_pack(NULL
, 0, "d", qcount
);
1231 for (i
= 0; i
< pts
->qcount
; i
++) {
1232 if ( queue
[i
].status
== LPQ_DELETED
)
1236 data
.dsize
+= tdb_pack(NULL
, 0, "ddddddff",
1237 (uint32
)queue
[i
].sysjob
,
1238 (uint32
)queue
[i
].size
,
1239 (uint32
)queue
[i
].page_count
,
1240 (uint32
)queue
[i
].status
,
1241 (uint32
)queue
[i
].priority
,
1242 (uint32
)queue
[i
].time
,
1247 if ((data
.dptr
= (uint8
*)SMB_MALLOC(data
.dsize
)) == NULL
)
1251 len
+= tdb_pack(data
.dptr
+ len
, data
.dsize
- len
, "d", qcount
);
1252 for (i
= 0; i
< pts
->qcount
; i
++) {
1253 if ( queue
[i
].status
== LPQ_DELETED
)
1256 len
+= tdb_pack(data
.dptr
+ len
, data
.dsize
- len
, "ddddddff",
1257 (uint32
)queue
[i
].sysjob
,
1258 (uint32
)queue
[i
].size
,
1259 (uint32
)queue
[i
].page_count
,
1260 (uint32
)queue
[i
].status
,
1261 (uint32
)queue
[i
].priority
,
1262 (uint32
)queue
[i
].time
,
1267 tdb_store(pdb
->tdb
, string_tdb_data("INFO/linear_queue_array"), data
,
1269 SAFE_FREE(data
.dptr
);
1273 static TDB_DATA
get_jobs_added_data(struct tdb_print_db
*pdb
)
1279 data
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data("INFO/jobs_added"));
1280 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0)) {
1281 SAFE_FREE(data
.dptr
);
1288 static void check_job_added(const char *sharename
, TDB_DATA data
, uint32 jobid
)
1291 unsigned int job_count
= data
.dsize
/ 4;
1293 for (i
= 0; i
< job_count
; i
++) {
1296 ch_jobid
= IVAL(data
.dptr
, i
*4);
1297 if (ch_jobid
== jobid
)
1298 remove_from_jobs_added(sharename
, jobid
);
1302 /****************************************************************************
1303 Check if the print queue has been updated recently enough.
1304 ****************************************************************************/
1306 static bool print_cache_expired(const char *sharename
, bool check_pending
)
1309 time_t last_qscan_time
, time_now
= time(NULL
);
1310 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1311 bool result
= False
;
1316 snprintf(key
, sizeof(key
), "CACHE/%s", sharename
);
1317 last_qscan_time
= (time_t)tdb_fetch_int32(pdb
->tdb
, key
);
1320 * Invalidate the queue for 3 reasons.
1321 * (1). last queue scan time == -1.
1322 * (2). Current time - last queue scan time > allowed cache time.
1323 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1324 * This last test picks up machines for which the clock has been moved
1325 * forward, an lpq scan done and then the clock moved back. Otherwise
1326 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1329 if (last_qscan_time
== ((time_t)-1)
1330 || (time_now
- last_qscan_time
) >= lp_lpq_cache_time()
1331 || last_qscan_time
> (time_now
+ MAX_CACHE_VALID_TIME
))
1334 time_t msg_pending_time
;
1336 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1337 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1338 sharename
, (int)last_qscan_time
, (int)time_now
,
1339 (int)lp_lpq_cache_time() ));
1341 /* check if another smbd has already sent a message to update the
1342 queue. Give the pending message one minute to clear and
1343 then send another message anyways. Make sure to check for
1344 clocks that have been run forward and then back again. */
1346 snprintf(key
, sizeof(key
), "MSG_PENDING/%s", sharename
);
1349 && tdb_fetch_uint32( pdb
->tdb
, key
, &u
)
1350 && (msg_pending_time
=u
) > 0
1351 && msg_pending_time
<= time_now
1352 && (time_now
- msg_pending_time
) < 60 )
1354 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1363 release_print_db(pdb
);
1367 /****************************************************************************
1368 main work for updating the lpq cache for a printer queue
1369 ****************************************************************************/
1371 static void print_queue_update_internal(struct tevent_context
*ev
,
1372 struct messaging_context
*msg_ctx
,
1373 const char *sharename
,
1374 struct printif
*current_printif
,
1375 char *lpq_command
, char *lprm_command
)
1378 print_queue_struct
*queue
= NULL
;
1379 print_status_struct status
;
1380 print_status_struct old_status
;
1381 struct printjob
*pjob
;
1382 struct traverse_struct tstruct
;
1385 fstring keystr
, cachestr
;
1386 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1387 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
1389 if ((pdb
== NULL
) || (tmp_ctx
== NULL
)) {
1393 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1394 sharename
, current_printif
->type
, lpq_command
));
1397 * Update the cache time FIRST ! Stops others even
1398 * attempting to get the lock and doing this
1399 * if the lpq takes a long time.
1402 slprintf(cachestr
, sizeof(cachestr
)-1, "CACHE/%s", sharename
);
1403 tdb_store_int32(pdb
->tdb
, cachestr
, (int)time(NULL
));
1405 /* get the current queue using the appropriate interface */
1406 ZERO_STRUCT(status
);
1408 qcount
= (*(current_printif
->queue_get
))(sharename
,
1409 current_printif
->type
,
1410 lpq_command
, &queue
, &status
);
1412 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1413 qcount
, (qcount
!= 1) ? "s" : "", sharename
));
1415 /* Sort the queue by submission time otherwise they are displayed
1418 TYPESAFE_QSORT(queue
, qcount
, printjob_comp
);
1421 any job in the internal database that is marked as spooled
1422 and doesn't exist in the system queue is considered finished
1423 and removed from the database
1425 any job in the system database but not in the internal database
1426 is added as a unix job
1428 fill in any system job numbers as we go
1430 jcdata
= get_jobs_added_data(pdb
);
1432 for (i
=0; i
<qcount
; i
++) {
1433 uint32 jobid
= sysjob_to_jobid_pdb(pdb
, queue
[i
].sysjob
);
1434 if (jobid
== (uint32
)-1) {
1435 /* assume its a unix print job */
1436 print_unix_job(ev
, msg_ctx
,
1437 sharename
, &queue
[i
], jobid
);
1441 /* we have an active SMB print job - update its status */
1442 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
1444 /* err, somethings wrong. Probably smbd was restarted
1445 with jobs in the queue. All we can do is treat them
1446 like unix jobs. Pity. */
1447 DEBUG(1, ("queued print job %d not found in jobs list, "
1448 "assuming unix job\n", jobid
));
1449 print_unix_job(ev
, msg_ctx
,
1450 sharename
, &queue
[i
], jobid
);
1454 /* don't reset the status on jobs to be deleted */
1456 if ( pjob
->status
!= LPQ_DELETING
)
1457 pjob
->status
= queue
[i
].status
;
1459 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
1461 check_job_added(sharename
, jcdata
, jobid
);
1464 SAFE_FREE(jcdata
.dptr
);
1466 /* now delete any queued entries that don't appear in the
1468 tstruct
.queue
= queue
;
1469 tstruct
.qcount
= qcount
;
1471 tstruct
.total_jobs
= 0;
1472 tstruct
.lpq_time
= time(NULL
);
1473 tstruct
.sharename
= sharename
;
1474 tstruct
.lprm_command
= lprm_command
;
1475 tstruct
.print_if
= current_printif
;
1477 tstruct
.msg_ctx
= msg_ctx
;
1478 tstruct
.mem_ctx
= tmp_ctx
;
1480 tdb_traverse(pdb
->tdb
, traverse_fn_delete
, (void *)&tstruct
);
1482 /* Store the linearised queue, max jobs only. */
1483 store_queue_struct(pdb
, &tstruct
);
1485 SAFE_FREE(tstruct
.queue
);
1486 talloc_free(tmp_ctx
);
1488 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1489 sharename
, tstruct
.total_jobs
));
1491 tdb_store_int32(pdb
->tdb
, "INFO/total_jobs", tstruct
.total_jobs
);
1493 get_queue_status(sharename
, &old_status
);
1494 if (old_status
.qcount
!= qcount
)
1495 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1496 old_status
.qcount
, qcount
, sharename
));
1498 /* store the new queue status structure */
1499 slprintf(keystr
, sizeof(keystr
)-1, "STATUS/%s", sharename
);
1500 key
= string_tdb_data(keystr
);
1502 status
.qcount
= qcount
;
1503 data
.dptr
= (uint8
*)&status
;
1504 data
.dsize
= sizeof(status
);
1505 tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
);
1508 * Update the cache time again. We want to do this call
1509 * as little as possible...
1512 slprintf(keystr
, sizeof(keystr
)-1, "CACHE/%s", sharename
);
1513 tdb_store_int32(pdb
->tdb
, keystr
, (int32
)time(NULL
));
1515 /* clear the msg pending record for this queue */
1517 snprintf(keystr
, sizeof(keystr
), "MSG_PENDING/%s", sharename
);
1519 if ( !tdb_store_uint32( pdb
->tdb
, keystr
, 0 ) ) {
1520 /* log a message but continue on */
1522 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1526 release_print_db( pdb
);
1531 /****************************************************************************
1532 Update the internal database from the system print queue for a queue.
1533 obtain a lock on the print queue before proceeding (needed when mutiple
1534 smbd processes maytry to update the lpq cache concurrently).
1535 ****************************************************************************/
1537 static void print_queue_update_with_lock( struct tevent_context
*ev
,
1538 struct messaging_context
*msg_ctx
,
1539 const char *sharename
,
1540 struct printif
*current_printif
,
1541 char *lpq_command
, char *lprm_command
)
1544 struct tdb_print_db
*pdb
;
1546 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename
));
1547 pdb
= get_print_db_byname(sharename
);
1551 if ( !print_cache_expired(sharename
, False
) ) {
1552 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename
));
1553 release_print_db(pdb
);
1558 * Check to see if someone else is doing this update.
1559 * This is essentially a mutex on the update.
1562 if (get_updating_pid(sharename
) != -1) {
1563 release_print_db(pdb
);
1567 /* Lock the queue for the database update */
1569 slprintf(keystr
, sizeof(keystr
) - 1, "LOCK/%s", sharename
);
1570 /* Only wait 10 seconds for this. */
1571 if (tdb_lock_bystring_with_timeout(pdb
->tdb
, keystr
, 10) != 0) {
1572 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename
));
1573 release_print_db(pdb
);
1578 * Ensure that no one else got in here.
1579 * If the updating pid is still -1 then we are
1583 if (get_updating_pid(sharename
) != -1) {
1585 * Someone else is doing the update, exit.
1587 tdb_unlock_bystring(pdb
->tdb
, keystr
);
1588 release_print_db(pdb
);
1593 * We're going to do the update ourselves.
1596 /* Tell others we're doing the update. */
1597 set_updating_pid(sharename
, True
);
1600 * Allow others to enter and notice we're doing
1604 tdb_unlock_bystring(pdb
->tdb
, keystr
);
1606 /* do the main work now */
1608 print_queue_update_internal(ev
, msg_ctx
,
1609 sharename
, current_printif
,
1610 lpq_command
, lprm_command
);
1612 /* Delete our pid from the db. */
1613 set_updating_pid(sharename
, False
);
1614 release_print_db(pdb
);
1617 /****************************************************************************
1618 this is the receive function of the background lpq updater
1619 ****************************************************************************/
1620 void print_queue_receive(struct messaging_context
*msg
,
1623 struct server_id server_id
,
1627 char *lpqcommand
= NULL
, *lprmcommand
= NULL
;
1631 len
= tdb_unpack( (uint8
*)data
->data
, data
->length
, "fdPP",
1638 SAFE_FREE(lpqcommand
);
1639 SAFE_FREE(lprmcommand
);
1640 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1644 print_queue_update_with_lock(server_event_context(), msg
, sharename
,
1645 get_printer_fns_from_type((enum printing_types
)printing_type
),
1646 lpqcommand
, lprmcommand
);
1648 SAFE_FREE(lpqcommand
);
1649 SAFE_FREE(lprmcommand
);
1653 /****************************************************************************
1654 update the internal database from the system print queue for a queue
1655 ****************************************************************************/
1657 extern pid_t background_lpq_updater_pid
;
1659 static void print_queue_update(struct messaging_context
*msg_ctx
,
1660 int snum
, bool force
)
1664 char *lpqcommand
= NULL
;
1665 char *lprmcommand
= NULL
;
1666 uint8
*buffer
= NULL
;
1669 struct tdb_print_db
*pdb
;
1671 struct printif
*current_printif
;
1672 TALLOC_CTX
*ctx
= talloc_tos();
1674 fstrcpy( sharename
, lp_const_servicename(snum
));
1676 /* don't strip out characters like '$' from the printername */
1678 lpqcommand
= talloc_string_sub2(ctx
,
1679 lp_lpq_command(talloc_tos(), snum
),
1681 lp_printername(talloc_tos(), snum
),
1682 false, false, false);
1686 lpqcommand
= talloc_sub_advanced(ctx
,
1687 lp_servicename(talloc_tos(), snum
),
1688 current_user_info
.unix_name
,
1690 current_user
.ut
.gid
,
1691 get_current_username(),
1692 current_user_info
.domain
,
1698 lprmcommand
= talloc_string_sub2(ctx
,
1699 lp_lprm_command(talloc_tos(), snum
),
1701 lp_printername(talloc_tos(), snum
),
1702 false, false, false);
1706 lprmcommand
= talloc_sub_advanced(ctx
,
1707 lp_servicename(talloc_tos(), snum
),
1708 current_user_info
.unix_name
,
1710 current_user
.ut
.gid
,
1711 get_current_username(),
1712 current_user_info
.domain
,
1719 * Make sure that the background queue process exists.
1720 * Otherwise just do the update ourselves
1723 if ( force
|| background_lpq_updater_pid
== -1 ) {
1724 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename
));
1725 current_printif
= get_printer_fns( snum
);
1726 print_queue_update_with_lock(server_event_context(), msg_ctx
,
1727 sharename
, current_printif
,
1728 lpqcommand
, lprmcommand
);
1733 type
= lp_printing(snum
);
1735 /* get the length */
1737 len
= tdb_pack( NULL
, 0, "fdPP",
1743 buffer
= SMB_XMALLOC_ARRAY( uint8
, len
);
1745 /* now pack the buffer */
1746 newlen
= tdb_pack( buffer
, len
, "fdPP",
1752 SMB_ASSERT( newlen
== len
);
1754 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1755 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1756 sharename
, type
, lpqcommand
, lprmcommand
));
1758 /* here we set a msg pending record for other smbd processes
1759 to throttle the number of duplicate print_queue_update msgs
1762 pdb
= get_print_db_byname(sharename
);
1768 snprintf(key
, sizeof(key
), "MSG_PENDING/%s", sharename
);
1770 if ( !tdb_store_uint32( pdb
->tdb
, key
, time(NULL
) ) ) {
1771 /* log a message but continue on */
1773 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1777 release_print_db( pdb
);
1779 /* finally send the message */
1781 messaging_send_buf(msg_ctx
, pid_to_procid(background_lpq_updater_pid
),
1782 MSG_PRINTER_UPDATE
, (uint8
*)buffer
, len
);
1784 SAFE_FREE( buffer
);
1789 /****************************************************************************
1790 Create/Update an entry in the print tdb that will allow us to send notify
1791 updates only to interested smbd's.
1792 ****************************************************************************/
1794 bool print_notify_register_pid(int snum
)
1797 struct tdb_print_db
*pdb
= NULL
;
1798 TDB_CONTEXT
*tdb
= NULL
;
1799 const char *printername
;
1800 uint32_t mypid
= (uint32_t)getpid();
1804 /* if (snum == -1), then the change notify request was
1805 on a print server handle and we need to register on
1810 int num_services
= lp_numservices();
1813 for ( idx
=0; idx
<num_services
; idx
++ ) {
1814 if (lp_snum_ok(idx
) && lp_printable(idx
) )
1815 print_notify_register_pid(idx
);
1820 else /* register for a specific printer */
1822 printername
= lp_const_servicename(snum
);
1823 pdb
= get_print_db_byname(printername
);
1829 if (tdb_lock_bystring_with_timeout(tdb
, NOTIFY_PID_LIST_KEY
, 10) != 0) {
1830 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1833 release_print_db(pdb
);
1837 data
= get_printer_notify_pid_list( tdb
, printername
, True
);
1839 /* Add ourselves and increase the refcount. */
1841 for (i
= 0; i
< data
.dsize
; i
+= 8) {
1842 if (IVAL(data
.dptr
,i
) == mypid
) {
1843 uint32 new_refcount
= IVAL(data
.dptr
, i
+4) + 1;
1844 SIVAL(data
.dptr
, i
+4, new_refcount
);
1849 if (i
== data
.dsize
) {
1850 /* We weren't in the list. Realloc. */
1851 data
.dptr
= (uint8
*)SMB_REALLOC(data
.dptr
, data
.dsize
+ 8);
1853 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1858 SIVAL(data
.dptr
,data
.dsize
- 8,mypid
);
1859 SIVAL(data
.dptr
,data
.dsize
- 4,1); /* Refcount. */
1862 /* Store back the record. */
1863 if (tdb_store_bystring(tdb
, NOTIFY_PID_LIST_KEY
, data
, TDB_REPLACE
) != 0) {
1864 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1865 list for printer %s\n", printername
));
1873 tdb_unlock_bystring(tdb
, NOTIFY_PID_LIST_KEY
);
1875 release_print_db(pdb
);
1876 SAFE_FREE(data
.dptr
);
1880 /****************************************************************************
1881 Update an entry in the print tdb that will allow us to send notify
1882 updates only to interested smbd's.
1883 ****************************************************************************/
1885 bool print_notify_deregister_pid(int snum
)
1888 struct tdb_print_db
*pdb
= NULL
;
1889 TDB_CONTEXT
*tdb
= NULL
;
1890 const char *printername
;
1891 uint32_t mypid
= (uint32_t)getpid();
1895 /* if ( snum == -1 ), we are deregister a print server handle
1896 which means to deregister on all print queues */
1900 int num_services
= lp_numservices();
1903 for ( idx
=0; idx
<num_services
; idx
++ ) {
1904 if ( lp_snum_ok(idx
) && lp_printable(idx
) )
1905 print_notify_deregister_pid(idx
);
1910 else /* deregister a specific printer */
1912 printername
= lp_const_servicename(snum
);
1913 pdb
= get_print_db_byname(printername
);
1919 if (tdb_lock_bystring_with_timeout(tdb
, NOTIFY_PID_LIST_KEY
, 10) != 0) {
1920 DEBUG(0,("print_notify_register_pid: Failed to lock \
1921 printer %s database\n", printername
));
1923 release_print_db(pdb
);
1927 data
= get_printer_notify_pid_list( tdb
, printername
, True
);
1929 /* Reduce refcount. Remove ourselves if zero. */
1931 for (i
= 0; i
< data
.dsize
; ) {
1932 if (IVAL(data
.dptr
,i
) == mypid
) {
1933 uint32 refcount
= IVAL(data
.dptr
, i
+4);
1937 if (refcount
== 0) {
1938 if (data
.dsize
- i
> 8)
1939 memmove( &data
.dptr
[i
], &data
.dptr
[i
+8], data
.dsize
- i
- 8);
1943 SIVAL(data
.dptr
, i
+4, refcount
);
1949 if (data
.dsize
== 0)
1950 SAFE_FREE(data
.dptr
);
1952 /* Store back the record. */
1953 if (tdb_store_bystring(tdb
, NOTIFY_PID_LIST_KEY
, data
, TDB_REPLACE
) != 0) {
1954 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1955 list for printer %s\n", printername
));
1963 tdb_unlock_bystring(tdb
, NOTIFY_PID_LIST_KEY
);
1965 release_print_db(pdb
);
1966 SAFE_FREE(data
.dptr
);
1970 /****************************************************************************
1971 Check if a jobid is valid. It is valid if it exists in the database.
1972 ****************************************************************************/
1974 bool print_job_exists(const char* sharename
, uint32 jobid
)
1976 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1982 ret
= tdb_exists(pdb
->tdb
, print_key(jobid
, &tmp
));
1983 release_print_db(pdb
);
1987 /****************************************************************************
1988 Return the device mode asigned to a specific print job.
1989 Only valid for the process doing the spooling and when the job
1990 has not been spooled.
1991 ****************************************************************************/
1993 struct spoolss_DeviceMode
*print_job_devmode(TALLOC_CTX
*mem_ctx
,
1994 const char *sharename
,
1997 struct printjob
*pjob
= print_job_find(mem_ctx
, sharename
, jobid
);
2002 return pjob
->devmode
;
2005 /****************************************************************************
2006 Set the name of a job. Only possible for owner.
2007 ****************************************************************************/
2009 bool print_job_set_name(struct tevent_context
*ev
,
2010 struct messaging_context
*msg_ctx
,
2011 const char *sharename
, uint32 jobid
, const char *name
)
2013 struct printjob
*pjob
;
2015 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
2016 if (tmp_ctx
== NULL
) {
2020 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2021 if (!pjob
|| pjob
->pid
!= getpid()) {
2026 fstrcpy(pjob
->jobname
, name
);
2027 ret
= pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2029 talloc_free(tmp_ctx
);
2033 /****************************************************************************
2034 Get the name of a job. Only possible for owner.
2035 ****************************************************************************/
2037 bool print_job_get_name(TALLOC_CTX
*mem_ctx
, const char *sharename
, uint32_t jobid
, char **name
)
2039 struct printjob
*pjob
;
2041 pjob
= print_job_find(mem_ctx
, sharename
, jobid
);
2042 if (!pjob
|| pjob
->pid
!= getpid()) {
2046 *name
= pjob
->jobname
;
2051 /***************************************************************************
2052 Remove a jobid from the 'jobs added' list.
2053 ***************************************************************************/
2055 static bool remove_from_jobs_added(const char* sharename
, uint32 jobid
)
2057 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2059 size_t job_count
, i
;
2061 bool gotlock
= False
;
2069 key
= string_tdb_data("INFO/jobs_added");
2071 if (tdb_chainlock_with_timeout(pdb
->tdb
, key
, 5) != 0)
2076 data
= tdb_fetch_compat(pdb
->tdb
, key
);
2078 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0))
2081 job_count
= data
.dsize
/ 4;
2082 for (i
= 0; i
< job_count
; i
++) {
2085 ch_jobid
= IVAL(data
.dptr
, i
*4);
2086 if (ch_jobid
== jobid
) {
2087 if (i
< job_count
-1 )
2088 memmove(data
.dptr
+ (i
*4), data
.dptr
+ (i
*4) + 4, (job_count
- i
- 1)*4 );
2090 if (tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
) != 0)
2100 tdb_chainunlock(pdb
->tdb
, key
);
2101 SAFE_FREE(data
.dptr
);
2102 release_print_db(pdb
);
2104 DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid
));
2106 DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid
));
2110 /****************************************************************************
2111 Delete a print job - don't update queue.
2112 ****************************************************************************/
2114 static bool print_job_delete1(struct tevent_context
*ev
,
2115 struct messaging_context
*msg_ctx
,
2116 int snum
, uint32 jobid
)
2118 const char* sharename
= lp_const_servicename(snum
);
2119 struct printjob
*pjob
;
2121 struct printif
*current_printif
= get_printer_fns( snum
);
2123 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
2124 if (tmp_ctx
== NULL
) {
2128 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2135 * If already deleting just return.
2138 if (pjob
->status
== LPQ_DELETING
) {
2143 /* Hrm - we need to be able to cope with deleting a job before it
2144 has reached the spooler. Just mark it as LPQ_DELETING and
2145 let the print_queue_update() code rmeove the record */
2148 if (pjob
->sysjob
== -1) {
2149 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid
));
2152 /* Set the tdb entry to be deleting. */
2154 pjob
->status
= LPQ_DELETING
;
2155 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2157 if (pjob
->spooled
&& pjob
->sysjob
!= -1)
2159 result
= (*(current_printif
->job_delete
))(
2160 lp_printername(talloc_tos(), snum
),
2161 lp_lprm_command(talloc_tos(), snum
),
2164 /* Delete the tdb entry if the delete succeeded or the job hasn't
2168 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2175 pjob_delete(ev
, msg_ctx
, sharename
, jobid
);
2176 /* Ensure we keep a rough count of the number of total jobs... */
2177 tdb_change_int32_atomic(pdb
->tdb
, "INFO/total_jobs", &njobs
, -1);
2178 release_print_db(pdb
);
2182 remove_from_jobs_added( sharename
, jobid
);
2184 ret
= (result
== 0);
2186 talloc_free(tmp_ctx
);
2190 /****************************************************************************
2191 Return true if the current user owns the print job.
2192 ****************************************************************************/
2194 static bool is_owner(const struct auth_session_info
*server_info
,
2195 const char *servicename
,
2198 struct printjob
*pjob
;
2200 TALLOC_CTX
*tmp_ctx
= talloc_new(server_info
);
2201 if (tmp_ctx
== NULL
) {
2205 pjob
= print_job_find(tmp_ctx
, servicename
, jobid
);
2206 if (!pjob
|| !server_info
) {
2211 ret
= strequal(pjob
->user
, server_info
->unix_info
->sanitized_username
);
2213 talloc_free(tmp_ctx
);
2217 /****************************************************************************
2219 ****************************************************************************/
2221 WERROR
print_job_delete(const struct auth_session_info
*server_info
,
2222 struct messaging_context
*msg_ctx
,
2223 int snum
, uint32_t jobid
)
2225 const char* sharename
= lp_const_servicename(snum
);
2226 struct printjob
*pjob
;
2229 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2230 if (tmp_ctx
== NULL
) {
2231 return WERR_NOT_ENOUGH_MEMORY
;
2234 owner
= is_owner(server_info
, lp_const_servicename(snum
), jobid
);
2236 /* Check access against security descriptor or whether the user
2240 !W_ERROR_IS_OK(print_access_check(server_info
, msg_ctx
, snum
,
2241 JOB_ACCESS_ADMINISTER
))) {
2242 DEBUG(0, ("print job delete denied."
2243 "User name: %s, Printer name: %s.",
2244 uidtoname(server_info
->unix_token
->uid
),
2245 lp_printername(tmp_ctx
, snum
)));
2247 werr
= WERR_ACCESS_DENIED
;
2252 * get the spooled filename of the print job
2253 * if this works, then the file has not been spooled
2254 * to the underlying print system. Just delete the
2255 * spool file & return.
2258 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2259 if (!pjob
|| pjob
->spooled
|| pjob
->pid
!= getpid()) {
2260 DEBUG(10, ("Skipping spool file removal for job %u\n", jobid
));
2262 DEBUG(10, ("Removing spool file [%s]\n", pjob
->filename
));
2263 if (unlink(pjob
->filename
) == -1) {
2264 werr
= map_werror_from_unix(errno
);
2269 if (!print_job_delete1(server_event_context(), msg_ctx
, snum
, jobid
)) {
2270 werr
= WERR_ACCESS_DENIED
;
2274 /* force update the database and say the delete failed if the
2277 print_queue_update(msg_ctx
, snum
, True
);
2279 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2280 if (pjob
&& (pjob
->status
!= LPQ_DELETING
)) {
2281 werr
= WERR_ACCESS_DENIED
;
2284 werr
= WERR_PRINTER_HAS_JOBS_QUEUED
;
2287 talloc_free(tmp_ctx
);
2291 /****************************************************************************
2293 ****************************************************************************/
2295 WERROR
print_job_pause(const struct auth_session_info
*server_info
,
2296 struct messaging_context
*msg_ctx
,
2297 int snum
, uint32 jobid
)
2299 const char* sharename
= lp_const_servicename(snum
);
2300 struct printjob
*pjob
;
2302 struct printif
*current_printif
= get_printer_fns( snum
);
2304 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2305 if (tmp_ctx
== NULL
) {
2306 return WERR_NOT_ENOUGH_MEMORY
;
2309 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2310 if (!pjob
|| !server_info
) {
2311 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2312 (unsigned int)jobid
));
2313 werr
= WERR_INVALID_PARAM
;
2317 if (!pjob
->spooled
|| pjob
->sysjob
== -1) {
2318 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2319 (int)pjob
->sysjob
, (unsigned int)jobid
));
2320 werr
= WERR_INVALID_PARAM
;
2324 if (!is_owner(server_info
, lp_const_servicename(snum
), jobid
) &&
2325 !W_ERROR_IS_OK(print_access_check(server_info
, msg_ctx
, snum
,
2326 JOB_ACCESS_ADMINISTER
))) {
2327 DEBUG(0, ("print job pause denied."
2328 "User name: %s, Printer name: %s.",
2329 uidtoname(server_info
->unix_token
->uid
),
2330 lp_printername(tmp_ctx
, snum
)));
2332 werr
= WERR_ACCESS_DENIED
;
2336 /* need to pause the spooled entry */
2337 ret
= (*(current_printif
->job_pause
))(snum
, pjob
);
2340 werr
= WERR_INVALID_PARAM
;
2344 /* force update the database */
2345 print_cache_flush(lp_const_servicename(snum
));
2347 /* Send a printer notify message */
2349 notify_job_status(server_event_context(), msg_ctx
, sharename
, jobid
,
2352 /* how do we tell if this succeeded? */
2355 talloc_free(tmp_ctx
);
2359 /****************************************************************************
2361 ****************************************************************************/
2363 WERROR
print_job_resume(const struct auth_session_info
*server_info
,
2364 struct messaging_context
*msg_ctx
,
2365 int snum
, uint32 jobid
)
2367 const char *sharename
= lp_const_servicename(snum
);
2368 struct printjob
*pjob
;
2370 struct printif
*current_printif
= get_printer_fns( snum
);
2372 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2373 if (tmp_ctx
== NULL
)
2374 return WERR_NOT_ENOUGH_MEMORY
;
2376 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2377 if (!pjob
|| !server_info
) {
2378 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2379 (unsigned int)jobid
));
2380 werr
= WERR_INVALID_PARAM
;
2384 if (!pjob
->spooled
|| pjob
->sysjob
== -1) {
2385 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2386 (int)pjob
->sysjob
, (unsigned int)jobid
));
2387 werr
= WERR_INVALID_PARAM
;
2391 if (!is_owner(server_info
, lp_const_servicename(snum
), jobid
) &&
2392 !W_ERROR_IS_OK(print_access_check(server_info
, msg_ctx
, snum
,
2393 JOB_ACCESS_ADMINISTER
))) {
2394 DEBUG(0, ("print job resume denied."
2395 "User name: %s, Printer name: %s.",
2396 uidtoname(server_info
->unix_token
->uid
),
2397 lp_printername(tmp_ctx
, snum
)));
2399 werr
= WERR_ACCESS_DENIED
;
2403 ret
= (*(current_printif
->job_resume
))(snum
, pjob
);
2406 werr
= WERR_INVALID_PARAM
;
2410 /* force update the database */
2411 print_cache_flush(lp_const_servicename(snum
));
2413 /* Send a printer notify message */
2415 notify_job_status(server_event_context(), msg_ctx
, sharename
, jobid
,
2420 talloc_free(tmp_ctx
);
2424 /****************************************************************************
2425 Write to a print file.
2426 ****************************************************************************/
2428 ssize_t
print_job_write(struct tevent_context
*ev
,
2429 struct messaging_context
*msg_ctx
,
2430 int snum
, uint32 jobid
, const char *buf
, size_t size
)
2432 const char* sharename
= lp_const_servicename(snum
);
2433 ssize_t return_code
;
2434 struct printjob
*pjob
;
2435 TALLOC_CTX
*tmp_ctx
= talloc_new(ev
);
2436 if (tmp_ctx
== NULL
) {
2440 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2446 /* don't allow another process to get this info - it is meaningless */
2447 if (pjob
->pid
!= getpid()) {
2452 /* if SMBD is spooling this can't be allowed */
2453 if (pjob
->status
== PJOB_SMBD_SPOOLING
) {
2458 return_code
= write_data(pjob
->fd
, buf
, size
);
2459 if (return_code
> 0) {
2461 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2464 talloc_free(tmp_ctx
);
2468 /****************************************************************************
2469 Get the queue status - do not update if db is out of date.
2470 ****************************************************************************/
2472 static int get_queue_status(const char* sharename
, print_status_struct
*status
)
2476 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2480 ZERO_STRUCTP(status
);
2487 fstr_sprintf(keystr
, "STATUS/%s", sharename
);
2488 data
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data(keystr
));
2490 if (data
.dsize
== sizeof(print_status_struct
))
2491 /* this memcpy is ok since the status struct was
2492 not packed before storing it in the tdb */
2493 memcpy(status
, data
.dptr
, sizeof(print_status_struct
));
2494 SAFE_FREE(data
.dptr
);
2497 len
= tdb_fetch_int32(pdb
->tdb
, "INFO/total_jobs");
2498 release_print_db(pdb
);
2499 return (len
== -1 ? 0 : len
);
2502 /****************************************************************************
2503 Determine the number of jobs in a queue.
2504 ****************************************************************************/
2506 int print_queue_length(struct messaging_context
*msg_ctx
, int snum
,
2507 print_status_struct
*pstatus
)
2509 const char* sharename
= lp_const_servicename( snum
);
2510 print_status_struct status
;
2513 ZERO_STRUCT( status
);
2515 /* make sure the database is up to date */
2516 if (print_cache_expired(lp_const_servicename(snum
), True
))
2517 print_queue_update(msg_ctx
, snum
, False
);
2519 /* also fetch the queue status */
2520 memset(&status
, 0, sizeof(status
));
2521 len
= get_queue_status(sharename
, &status
);
2529 /***************************************************************************
2530 Allocate a jobid. Hold the lock for as short a time as possible.
2531 ***************************************************************************/
2533 static WERROR
allocate_print_jobid(struct tdb_print_db
*pdb
, int snum
,
2534 const char *sharename
, uint32
*pjobid
)
2538 enum TDB_ERROR terr
;
2541 *pjobid
= (uint32
)-1;
2543 for (i
= 0; i
< 3; i
++) {
2544 /* Lock the database - only wait 20 seconds. */
2545 ret
= tdb_lock_bystring_with_timeout(pdb
->tdb
,
2546 "INFO/nextjob", 20);
2548 DEBUG(0, ("allocate_print_jobid: "
2549 "Failed to lock printing database %s\n",
2551 terr
= tdb_error(pdb
->tdb
);
2552 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2555 if (!tdb_fetch_uint32(pdb
->tdb
, "INFO/nextjob", &jobid
)) {
2556 terr
= tdb_error(pdb
->tdb
);
2557 if (terr
!= TDB_ERR_NOEXIST
) {
2558 DEBUG(0, ("allocate_print_jobid: "
2559 "Failed to fetch INFO/nextjob "
2560 "for print queue %s\n", sharename
));
2561 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2562 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2564 DEBUG(10, ("allocate_print_jobid: "
2565 "No existing jobid in %s\n", sharename
));
2569 DEBUG(10, ("allocate_print_jobid: "
2570 "Read jobid %u from %s\n", jobid
, sharename
));
2572 jobid
= NEXT_JOBID(jobid
);
2574 ret
= tdb_store_int32(pdb
->tdb
, "INFO/nextjob", jobid
);
2576 terr
= tdb_error(pdb
->tdb
);
2577 DEBUG(3, ("allocate_print_jobid: "
2578 "Failed to store INFO/nextjob.\n"));
2579 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2580 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2583 /* We've finished with the INFO/nextjob lock. */
2584 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2586 if (!print_job_exists(sharename
, jobid
)) {
2589 DEBUG(10, ("allocate_print_jobid: "
2590 "Found jobid %u in %s\n", jobid
, sharename
));
2594 DEBUG(0, ("allocate_print_jobid: "
2595 "Failed to allocate a print job for queue %s\n",
2597 /* Probably full... */
2598 return WERR_NO_SPOOL_SPACE
;
2601 /* Store a dummy placeholder. */
2607 if (tdb_store(pdb
->tdb
, print_key(jobid
, &tmp
), dum
,
2609 DEBUG(3, ("allocate_print_jobid: "
2610 "jobid (%d) failed to store placeholder.\n",
2612 terr
= tdb_error(pdb
->tdb
);
2613 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2621 /***************************************************************************
2622 Append a jobid to the 'jobs added' list.
2623 ***************************************************************************/
2625 static bool add_to_jobs_added(struct tdb_print_db
*pdb
, uint32 jobid
)
2630 SIVAL(&store_jobid
, 0, jobid
);
2631 data
.dptr
= (uint8
*)&store_jobid
;
2634 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid
));
2636 return (tdb_append(pdb
->tdb
, string_tdb_data("INFO/jobs_added"),
2641 /***************************************************************************
2642 Do all checks needed to determine if we can start a job.
2643 ***************************************************************************/
2645 static WERROR
print_job_checks(const struct auth_session_info
*server_info
,
2646 struct messaging_context
*msg_ctx
,
2647 int snum
, int *njobs
)
2649 const char *sharename
= lp_const_servicename(snum
);
2650 uint64_t dspace
, dsize
;
2654 if (!W_ERROR_IS_OK(print_access_check(server_info
, msg_ctx
, snum
,
2655 PRINTER_ACCESS_USE
))) {
2656 DEBUG(3, ("print_job_checks: "
2657 "job start denied by security descriptor\n"));
2658 return WERR_ACCESS_DENIED
;
2661 if (!print_time_access_check(server_info
, msg_ctx
, sharename
)) {
2662 DEBUG(3, ("print_job_checks: "
2663 "job start denied by time check\n"));
2664 return WERR_ACCESS_DENIED
;
2667 /* see if we have sufficient disk space */
2668 if (lp_min_print_space(snum
)) {
2669 minspace
= lp_min_print_space(snum
);
2670 ret
= sys_fsusage(lp_path(talloc_tos(), snum
), &dspace
, &dsize
);
2671 if (ret
== 0 && dspace
< 2*minspace
) {
2672 DEBUG(3, ("print_job_checks: "
2673 "disk space check failed.\n"));
2674 return WERR_NO_SPOOL_SPACE
;
2678 /* for autoloaded printers, check that the printcap entry still exists */
2679 if (lp_autoloaded(snum
) && !pcap_printername_ok(sharename
)) {
2680 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2682 return WERR_ACCESS_DENIED
;
2685 /* Insure the maximum queue size is not violated */
2686 *njobs
= print_queue_length(msg_ctx
, snum
, NULL
);
2687 if (*njobs
> lp_maxprintjobs(snum
)) {
2688 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2689 "larger than max printjobs per queue (%d).\n",
2690 sharename
, *njobs
, lp_maxprintjobs(snum
)));
2691 return WERR_NO_SPOOL_SPACE
;
2697 /***************************************************************************
2699 ***************************************************************************/
2701 static WERROR
print_job_spool_file(int snum
, uint32_t jobid
,
2702 const char *output_file
,
2703 struct printjob
*pjob
)
2711 /* if this file is within the printer path, it means that smbd
2712 * is spooling it and will pass us control when it is finished.
2713 * Verify that the file name is ok, within path, and it is
2714 * already already there */
2716 path
= lp_path(talloc_tos(), snum
);
2718 if (strncmp(output_file
, path
, len
) == 0 &&
2719 (output_file
[len
- 1] == '/' || output_file
[len
] == '/')) {
2721 /* verify path is not too long */
2722 if (strlen(output_file
) >= sizeof(pjob
->filename
)) {
2723 return WERR_INVALID_NAME
;
2726 /* verify that the file exists */
2727 if (sys_stat(output_file
, &st
, false) != 0) {
2728 return WERR_INVALID_NAME
;
2731 fstrcpy(pjob
->filename
, output_file
);
2733 DEBUG(3, ("print_job_spool_file:"
2734 "External spooling activated\n"));
2736 /* we do not open the file until spooling is done */
2738 pjob
->status
= PJOB_SMBD_SPOOLING
;
2744 slprintf(pjob
->filename
, sizeof(pjob
->filename
)-1,
2745 "%s/%sXXXXXX", lp_path(talloc_tos(), snum
),
2746 PRINT_SPOOL_PREFIX
);
2747 mask
= umask(S_IRWXO
| S_IRWXG
);
2748 pjob
->fd
= mkstemp(pjob
->filename
);
2751 if (pjob
->fd
== -1) {
2752 werr
= map_werror_from_unix(errno
);
2753 if (W_ERROR_EQUAL(werr
, WERR_ACCESS_DENIED
)) {
2754 /* Common setup error, force a report. */
2755 DEBUG(0, ("print_job_spool_file: "
2756 "insufficient permissions to open spool "
2757 "file %s.\n", pjob
->filename
));
2759 /* Normal case, report at level 3 and above. */
2760 DEBUG(3, ("print_job_spool_file: "
2761 "can't open spool file %s\n",
2770 /***************************************************************************
2771 Start spooling a job - return the jobid.
2772 ***************************************************************************/
2774 WERROR
print_job_start(const struct auth_session_info
*server_info
,
2775 struct messaging_context
*msg_ctx
,
2776 const char *clientmachine
,
2777 int snum
, const char *docname
, const char *filename
,
2778 struct spoolss_DeviceMode
*devmode
, uint32_t *_jobid
)
2782 struct printjob pjob
;
2783 const char *sharename
= lp_const_servicename(snum
);
2784 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2789 return WERR_INTERNAL_DB_CORRUPTION
;
2792 path
= lp_path(talloc_tos(), snum
);
2794 werr
= print_job_checks(server_info
, msg_ctx
, snum
, &njobs
);
2795 if (!W_ERROR_IS_OK(werr
)) {
2796 release_print_db(pdb
);
2800 DEBUG(10, ("print_job_start: "
2801 "Queue %s number of jobs (%d), max printjobs = %d\n",
2802 sharename
, njobs
, lp_maxprintjobs(snum
)));
2804 werr
= allocate_print_jobid(pdb
, snum
, sharename
, &jobid
);
2805 if (!W_ERROR_IS_OK(werr
)) {
2809 /* create the database entry */
2813 pjob
.pid
= getpid();
2817 pjob
.starttime
= time(NULL
);
2818 pjob
.status
= LPQ_SPOOLING
;
2820 pjob
.spooled
= False
;
2822 pjob
.devmode
= devmode
;
2824 fstrcpy(pjob
.jobname
, docname
);
2826 fstrcpy(pjob
.clientmachine
, clientmachine
);
2828 fstrcpy(pjob
.user
, lp_printjob_username(snum
));
2829 standard_sub_advanced(sharename
, server_info
->unix_info
->sanitized_username
,
2830 path
, server_info
->unix_token
->gid
,
2831 server_info
->unix_info
->sanitized_username
,
2832 server_info
->info
->domain_name
,
2833 pjob
.user
, sizeof(pjob
.user
));
2835 fstrcpy(pjob
.queuename
, lp_const_servicename(snum
));
2837 /* we have a job entry - now create the spool file */
2838 werr
= print_job_spool_file(snum
, jobid
, filename
, &pjob
);
2839 if (!W_ERROR_IS_OK(werr
)) {
2843 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, &pjob
);
2845 /* Update the 'jobs added' entry used by print_queue_status. */
2846 add_to_jobs_added(pdb
, jobid
);
2848 /* Ensure we keep a rough count of the number of total jobs... */
2849 tdb_change_int32_atomic(pdb
->tdb
, "INFO/total_jobs", &njobs
, 1);
2851 release_print_db(pdb
);
2858 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
2861 release_print_db(pdb
);
2863 DEBUG(3, ("print_job_start: returning fail. "
2864 "Error = %s\n", win_errstr(werr
)));
2868 /****************************************************************************
2869 Update the number of pages spooled to jobid
2870 ****************************************************************************/
2872 void print_job_endpage(struct messaging_context
*msg_ctx
,
2873 int snum
, uint32 jobid
)
2875 const char* sharename
= lp_const_servicename(snum
);
2876 struct printjob
*pjob
;
2877 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2878 if (tmp_ctx
== NULL
) {
2882 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2886 /* don't allow another process to get this info - it is meaningless */
2887 if (pjob
->pid
!= getpid()) {
2892 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, pjob
);
2894 talloc_free(tmp_ctx
);
2897 /****************************************************************************
2898 Print a file - called on closing the file. This spools the job.
2899 If normal close is false then we're tearing down the jobs - treat as an
2901 ****************************************************************************/
2903 NTSTATUS
print_job_end(struct messaging_context
*msg_ctx
, int snum
,
2904 uint32 jobid
, enum file_close_type close_type
)
2906 const char* sharename
= lp_const_servicename(snum
);
2907 struct printjob
*pjob
;
2909 SMB_STRUCT_STAT sbuf
;
2910 struct printif
*current_printif
= get_printer_fns(snum
);
2911 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
2913 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
2914 if (tmp_ctx
== NULL
) {
2915 return NT_STATUS_NO_MEMORY
;
2918 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
2920 status
= NT_STATUS_PRINT_CANCELLED
;
2924 if (pjob
->spooled
|| pjob
->pid
!= getpid()) {
2925 status
= NT_STATUS_ACCESS_DENIED
;
2929 if (close_type
== NORMAL_CLOSE
|| close_type
== SHUTDOWN_CLOSE
) {
2930 if (pjob
->status
== PJOB_SMBD_SPOOLING
) {
2931 /* take over the file now, smbd is done */
2932 if (sys_stat(pjob
->filename
, &sbuf
, false) != 0) {
2933 status
= map_nt_error_from_unix(errno
);
2934 DEBUG(3, ("print_job_end: "
2935 "stat file failed for jobid %d\n",
2940 pjob
->status
= LPQ_SPOOLING
;
2944 if ((sys_fstat(pjob
->fd
, &sbuf
, false) != 0)) {
2945 status
= map_nt_error_from_unix(errno
);
2947 DEBUG(3, ("print_job_end: "
2948 "stat file failed for jobid %d\n",
2956 pjob
->size
= sbuf
.st_ex_size
;
2960 * Not a normal close, something has gone wrong. Cleanup.
2962 if (pjob
->fd
!= -1) {
2968 /* Technically, this is not quite right. If the printer has a separator
2969 * page turned on, the NT spooler prints the separator page even if the
2970 * print job is 0 bytes. 010215 JRR */
2971 if (pjob
->size
== 0 || pjob
->status
== LPQ_DELETING
) {
2972 /* don't bother spooling empty files or something being deleted. */
2973 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2974 pjob
->filename
, pjob
->size
? "deleted" : "zero length" ));
2975 unlink(pjob
->filename
);
2976 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
2977 return NT_STATUS_OK
;
2980 /* don't strip out characters like '$' from the printername */
2981 lpq_cmd
= talloc_string_sub2(tmp_ctx
,
2982 lp_lpq_command(talloc_tos(), snum
),
2984 lp_printername(talloc_tos(), snum
),
2985 false, false, false);
2986 if (lpq_cmd
== NULL
) {
2987 status
= NT_STATUS_PRINT_CANCELLED
;
2990 lpq_cmd
= talloc_sub_advanced(tmp_ctx
,
2991 lp_servicename(talloc_tos(), snum
),
2992 current_user_info
.unix_name
,
2994 current_user
.ut
.gid
,
2995 get_current_username(),
2996 current_user_info
.domain
,
2998 if (lpq_cmd
== NULL
) {
2999 status
= NT_STATUS_PRINT_CANCELLED
;
3003 ret
= (*(current_printif
->job_submit
))(snum
, pjob
,
3004 current_printif
->type
, lpq_cmd
);
3006 status
= NT_STATUS_PRINT_CANCELLED
;
3010 /* The print job has been successfully handed over to the back-end */
3012 pjob
->spooled
= True
;
3013 pjob
->status
= LPQ_QUEUED
;
3014 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, pjob
);
3016 /* make sure the database is up to date */
3017 if (print_cache_expired(lp_const_servicename(snum
), True
))
3018 print_queue_update(msg_ctx
, snum
, False
);
3020 return NT_STATUS_OK
;
3024 /* The print job was not successfully started. Cleanup */
3025 /* Still need to add proper error return propagation! 010122:JRR */
3027 unlink(pjob
->filename
);
3028 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
3030 talloc_free(tmp_ctx
);
3034 /****************************************************************************
3035 Get a snapshot of jobs in the system without traversing.
3036 ****************************************************************************/
3038 static bool get_stored_queue_info(struct messaging_context
*msg_ctx
,
3039 struct tdb_print_db
*pdb
, int snum
,
3040 int *pcount
, print_queue_struct
**ppqueue
)
3042 TDB_DATA data
, cgdata
, jcdata
;
3043 print_queue_struct
*queue
= NULL
;
3045 uint32 extra_count
= 0;
3046 uint32_t changed_count
= 0;
3047 int total_count
= 0;
3050 int max_reported_jobs
= lp_max_reported_print_jobs(snum
);
3052 const char* sharename
= lp_servicename(talloc_tos(), snum
);
3053 TALLOC_CTX
*tmp_ctx
= talloc_new(msg_ctx
);
3054 if (tmp_ctx
== NULL
) {
3058 /* make sure the database is up to date */
3059 if (print_cache_expired(lp_const_servicename(snum
), True
))
3060 print_queue_update(msg_ctx
, snum
, False
);
3066 ZERO_STRUCT(cgdata
);
3068 /* Get the stored queue data. */
3069 data
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data("INFO/linear_queue_array"));
3071 if (data
.dptr
&& data
.dsize
>= sizeof(qcount
))
3072 len
+= tdb_unpack(data
.dptr
+ len
, data
.dsize
- len
, "d", &qcount
);
3074 /* Get the added jobs list. */
3075 cgdata
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data("INFO/jobs_added"));
3076 if (cgdata
.dptr
!= NULL
&& (cgdata
.dsize
% 4 == 0))
3077 extra_count
= cgdata
.dsize
/4;
3079 /* Get the changed jobs list. */
3080 jcdata
= tdb_fetch_compat(pdb
->tdb
, string_tdb_data("INFO/jobs_changed"));
3081 if (jcdata
.dptr
!= NULL
&& (jcdata
.dsize
% 4 == 0))
3082 changed_count
= jcdata
.dsize
/ 4;
3084 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount
, (unsigned int)extra_count
));
3086 /* Allocate the queue size. */
3087 if (qcount
== 0 && extra_count
== 0)
3090 if ((queue
= SMB_MALLOC_ARRAY(print_queue_struct
, qcount
+ extra_count
)) == NULL
)
3093 /* Retrieve the linearised queue data. */
3095 for(i
= 0; i
< qcount
; i
++) {
3096 uint32 qjob
, qsize
, qpage_count
, qstatus
, qpriority
, qtime
;
3097 len
+= tdb_unpack(data
.dptr
+ len
, data
.dsize
- len
, "ddddddff",
3106 queue
[i
].sysjob
= qjob
;
3107 queue
[i
].size
= qsize
;
3108 queue
[i
].page_count
= qpage_count
;
3109 queue
[i
].status
= qstatus
;
3110 queue
[i
].priority
= qpriority
;
3111 queue
[i
].time
= qtime
;
3114 total_count
= qcount
;
3116 /* Add new jobids to the queue. */
3117 for (i
= 0; i
< extra_count
; i
++) {
3119 struct printjob
*pjob
;
3121 jobid
= IVAL(cgdata
.dptr
, i
*4);
3122 DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid
));
3123 pjob
= print_job_find(tmp_ctx
, lp_const_servicename(snum
), jobid
);
3125 DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid
));
3126 remove_from_jobs_added(sharename
, jobid
);
3130 queue
[total_count
].sysjob
= pjob
->sysjob
;
3131 queue
[total_count
].size
= pjob
->size
;
3132 queue
[total_count
].page_count
= pjob
->page_count
;
3133 queue
[total_count
].status
= pjob
->status
;
3134 queue
[total_count
].priority
= 1;
3135 queue
[total_count
].time
= pjob
->starttime
;
3136 fstrcpy(queue
[total_count
].fs_user
, pjob
->user
);
3137 fstrcpy(queue
[total_count
].fs_file
, pjob
->jobname
);
3142 /* Update the changed jobids. */
3143 for (i
= 0; i
< changed_count
; i
++) {
3144 uint32_t jobid
= IVAL(jcdata
.dptr
, i
* 4);
3145 struct printjob
*pjob
;
3149 pjob
= print_job_find(tmp_ctx
, sharename
, jobid
);
3151 DEBUG(5,("get_stored_queue_info: failed to find "
3152 "changed job = %u\n",
3153 (unsigned int)jobid
));
3154 remove_from_jobs_changed(sharename
, jobid
);
3158 for (j
= 0; j
< total_count
; j
++) {
3159 if (queue
[j
].sysjob
== pjob
->sysjob
) {
3166 DEBUG(5,("get_stored_queue_info: changed job: %u\n",
3167 (unsigned int)jobid
));
3169 queue
[j
].sysjob
= pjob
->sysjob
;
3170 queue
[j
].size
= pjob
->size
;
3171 queue
[j
].page_count
= pjob
->page_count
;
3172 queue
[j
].status
= pjob
->status
;
3173 queue
[j
].priority
= 1;
3174 queue
[j
].time
= pjob
->starttime
;
3175 fstrcpy(queue
[j
].fs_user
, pjob
->user
);
3176 fstrcpy(queue
[j
].fs_file
, pjob
->jobname
);
3179 DEBUG(5,("updated queue[%u], jobid: %u, sysjob: %u, "
3181 (unsigned int)j
, (unsigned int)jobid
,
3182 (unsigned int)queue
[j
].sysjob
, pjob
->jobname
));
3185 remove_from_jobs_changed(sharename
, jobid
);
3188 /* Sort the queue by submission time otherwise they are displayed
3191 TYPESAFE_QSORT(queue
, total_count
, printjob_comp
);
3193 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count
));
3195 if (max_reported_jobs
&& total_count
> max_reported_jobs
)
3196 total_count
= max_reported_jobs
;
3199 *pcount
= total_count
;
3205 SAFE_FREE(data
.dptr
);
3206 SAFE_FREE(cgdata
.dptr
);
3207 talloc_free(tmp_ctx
);
3211 /****************************************************************************
3212 Get a printer queue listing.
3213 set queue = NULL and status = NULL if you just want to update the cache
3214 ****************************************************************************/
3216 int print_queue_status(struct messaging_context
*msg_ctx
, int snum
,
3217 print_queue_struct
**ppqueue
,
3218 print_status_struct
*status
)
3222 const char *sharename
;
3223 struct tdb_print_db
*pdb
;
3226 /* make sure the database is up to date */
3228 if (print_cache_expired(lp_const_servicename(snum
), True
))
3229 print_queue_update(msg_ctx
, snum
, False
);
3231 /* return if we are done */
3232 if ( !ppqueue
|| !status
)
3236 sharename
= lp_const_servicename(snum
);
3237 pdb
= get_print_db_byname(sharename
);
3243 * Fetch the queue status. We must do this first, as there may
3244 * be no jobs in the queue.
3247 ZERO_STRUCTP(status
);
3248 slprintf(keystr
, sizeof(keystr
)-1, "STATUS/%s", sharename
);
3249 key
= string_tdb_data(keystr
);
3251 data
= tdb_fetch_compat(pdb
->tdb
, key
);
3253 if (data
.dsize
== sizeof(*status
)) {
3254 /* this memcpy is ok since the status struct was
3255 not packed before storing it in the tdb */
3256 memcpy(status
, data
.dptr
, sizeof(*status
));
3258 SAFE_FREE(data
.dptr
);
3262 * Now, fetch the print queue information. We first count the number
3263 * of entries, and then only retrieve the queue if necessary.
3266 if (!get_stored_queue_info(msg_ctx
, pdb
, snum
, &count
, ppqueue
)) {
3267 release_print_db(pdb
);
3271 release_print_db(pdb
);
3275 /****************************************************************************
3277 ****************************************************************************/
3279 WERROR
print_queue_pause(const struct auth_session_info
*server_info
,
3280 struct messaging_context
*msg_ctx
, int snum
)
3283 struct printif
*current_printif
= get_printer_fns( snum
);
3285 if (!W_ERROR_IS_OK(print_access_check(server_info
, msg_ctx
, snum
,
3286 PRINTER_ACCESS_ADMINISTER
))) {
3287 return WERR_ACCESS_DENIED
;
3293 ret
= (*(current_printif
->queue_pause
))(snum
);
3298 return WERR_INVALID_PARAM
;
3301 /* force update the database */
3302 print_cache_flush(lp_const_servicename(snum
));
3304 /* Send a printer notify message */
3306 notify_printer_status(server_event_context(), msg_ctx
, snum
,
3307 PRINTER_STATUS_PAUSED
);
3312 /****************************************************************************
3314 ****************************************************************************/
3316 WERROR
print_queue_resume(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 (!W_ERROR_IS_OK(print_access_check(server_info
, msg_ctx
, snum
,
3323 PRINTER_ACCESS_ADMINISTER
))) {
3324 return WERR_ACCESS_DENIED
;
3329 ret
= (*(current_printif
->queue_resume
))(snum
);
3334 return WERR_INVALID_PARAM
;
3337 /* make sure the database is up to date */
3338 if (print_cache_expired(lp_const_servicename(snum
), True
))
3339 print_queue_update(msg_ctx
, snum
, True
);
3341 /* Send a printer notify message */
3343 notify_printer_status(server_event_context(), msg_ctx
, snum
,
3349 /****************************************************************************
3350 Purge a queue - implemented by deleting all jobs that we can delete.
3351 ****************************************************************************/
3353 WERROR
print_queue_purge(const struct auth_session_info
*server_info
,
3354 struct messaging_context
*msg_ctx
, int snum
)
3356 print_queue_struct
*queue
;
3357 print_status_struct status
;
3361 /* Force and update so the count is accurate (i.e. not a cached count) */
3362 print_queue_update(msg_ctx
, snum
, True
);
3364 can_job_admin
= W_ERROR_IS_OK(print_access_check(server_info
,
3367 JOB_ACCESS_ADMINISTER
));
3368 njobs
= print_queue_status(msg_ctx
, snum
, &queue
, &status
);
3370 if ( can_job_admin
)
3373 for (i
= 0; i
< njobs
; i
++) {
3374 struct tdb_print_db
*pdb
;
3377 pdb
= get_print_db_byname(lp_const_servicename(snum
));
3379 DEBUG(1, ("failed to find printdb for %s\n",
3380 lp_const_servicename(snum
)));
3383 jobid
= sysjob_to_jobid_pdb(pdb
, queue
[i
].sysjob
);
3384 if (jobid
== (uint32_t)-1) {
3385 DEBUG(2, ("jobid for system job %d not found\n",
3387 continue; /* unix job */
3389 owner
= is_owner(server_info
, lp_const_servicename(snum
),
3392 if (owner
|| can_job_admin
) {
3393 print_job_delete1(server_event_context(), msg_ctx
,
3398 if ( can_job_admin
)
3401 /* update the cache */
3402 print_queue_update(msg_ctx
, snum
, True
);