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"
32 #include "smbd/smbd.h"
36 extern struct current_user current_user
;
37 extern userdom_struct current_user_info
;
39 /* Current printer interface */
40 static bool remove_from_jobs_added(const char* sharename
, uint32 jobid
);
43 the printing backend revolves around a tdb database that stores the
44 SMB view of the print queue
46 The key for this database is a jobid - a internally generated number that
47 uniquely identifies a print job
49 reading the print queue involves two steps:
50 - possibly running lpq and updating the internal database from that
51 - reading entries from the database
53 jobids are assigned when a job starts spooling.
56 static TDB_CONTEXT
*rap_tdb
;
57 static uint16 next_rap_jobid
;
58 struct rap_jobid_key
{
63 /***************************************************************************
64 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
65 bit RPC jobids.... JRA.
66 ***************************************************************************/
68 uint16
pjobid_to_rap(const char* sharename
, uint32 jobid
)
72 struct rap_jobid_key jinfo
;
75 DEBUG(10,("pjobid_to_rap: called.\n"));
78 /* Create the in-memory tdb. */
79 rap_tdb
= tdb_open_log(NULL
, 0, TDB_INTERNAL
, (O_RDWR
|O_CREAT
), 0644);
85 fstrcpy( jinfo
.sharename
, sharename
);
87 key
.dptr
= (uint8
*)&jinfo
;
88 key
.dsize
= sizeof(jinfo
);
90 data
= tdb_fetch(rap_tdb
, key
);
91 if (data
.dptr
&& data
.dsize
== sizeof(uint16
)) {
92 rap_jobid
= SVAL(data
.dptr
, 0);
94 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
95 (unsigned int)jobid
, (unsigned int)rap_jobid
));
99 /* Not found - create and store mapping. */
100 rap_jobid
= ++next_rap_jobid
;
102 rap_jobid
= ++next_rap_jobid
;
103 SSVAL(buf
,0,rap_jobid
);
105 data
.dsize
= sizeof(rap_jobid
);
106 tdb_store(rap_tdb
, key
, data
, TDB_REPLACE
);
107 tdb_store(rap_tdb
, data
, key
, TDB_REPLACE
);
109 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
110 (unsigned int)jobid
, (unsigned int)rap_jobid
));
114 bool rap_to_pjobid(uint16 rap_jobid
, fstring sharename
, uint32
*pjobid
)
119 DEBUG(10,("rap_to_pjobid called.\n"));
124 SSVAL(buf
,0,rap_jobid
);
126 key
.dsize
= sizeof(rap_jobid
);
127 data
= tdb_fetch(rap_tdb
, key
);
128 if ( data
.dptr
&& data
.dsize
== sizeof(struct rap_jobid_key
) )
130 struct rap_jobid_key
*jinfo
= (struct rap_jobid_key
*)data
.dptr
;
131 if (sharename
!= NULL
) {
132 fstrcpy( sharename
, jinfo
->sharename
);
134 *pjobid
= jinfo
->jobid
;
135 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
136 (unsigned int)*pjobid
, (unsigned int)rap_jobid
));
137 SAFE_FREE(data
.dptr
);
141 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
142 (unsigned int)rap_jobid
));
143 SAFE_FREE(data
.dptr
);
147 void rap_jobid_delete(const char* sharename
, uint32 jobid
)
151 struct rap_jobid_key jinfo
;
154 DEBUG(10,("rap_jobid_delete: called.\n"));
159 ZERO_STRUCT( jinfo
);
160 fstrcpy( jinfo
.sharename
, sharename
);
162 key
.dptr
= (uint8
*)&jinfo
;
163 key
.dsize
= sizeof(jinfo
);
165 data
= tdb_fetch(rap_tdb
, key
);
166 if (!data
.dptr
|| (data
.dsize
!= sizeof(uint16
))) {
167 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
168 (unsigned int)jobid
));
169 SAFE_FREE(data
.dptr
);
173 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
174 (unsigned int)jobid
));
176 rap_jobid
= SVAL(data
.dptr
, 0);
177 SAFE_FREE(data
.dptr
);
178 SSVAL(buf
,0,rap_jobid
);
180 data
.dsize
= sizeof(rap_jobid
);
181 tdb_delete(rap_tdb
, key
);
182 tdb_delete(rap_tdb
, data
);
185 static int get_queue_status(const char* sharename
, print_status_struct
*);
187 /****************************************************************************
188 Initialise the printing backend. Called once at startup before the fork().
189 ****************************************************************************/
191 bool print_backend_init(struct messaging_context
*msg_ctx
)
193 const char *sversion
= "INFO/version";
194 int services
= lp_numservices();
197 unlink(cache_path("printing.tdb"));
198 mkdir(cache_path("printing"),0755);
200 /* handle a Samba upgrade */
202 for (snum
= 0; snum
< services
; snum
++) {
203 struct tdb_print_db
*pdb
;
204 if (!lp_print_ok(snum
))
207 pdb
= get_print_db_byname(lp_const_servicename(snum
));
210 if (tdb_lock_bystring(pdb
->tdb
, sversion
) == -1) {
211 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum
) ));
212 release_print_db(pdb
);
215 if (tdb_fetch_int32(pdb
->tdb
, sversion
) != PRINT_DATABASE_VERSION
) {
216 tdb_wipe_all(pdb
->tdb
);
217 tdb_store_int32(pdb
->tdb
, sversion
, PRINT_DATABASE_VERSION
);
219 tdb_unlock_bystring(pdb
->tdb
, sversion
);
220 release_print_db(pdb
);
223 close_all_print_db(); /* Don't leave any open. */
225 /* do NT print initialization... */
226 return nt_printing_init(msg_ctx
);
229 /****************************************************************************
230 Shut down printing backend. Called once at shutdown to close the tdb.
231 ****************************************************************************/
233 void printing_end(void)
235 close_all_print_db(); /* Don't leave any open. */
238 /****************************************************************************
239 Retrieve the set of printing functions for a given service. This allows
240 us to set the printer function table based on the value of the 'printing'
243 Use the generic interface as the default and only use cups interface only
244 when asked for (and only when supported)
245 ****************************************************************************/
247 static struct printif
*get_printer_fns_from_type( enum printing_types type
)
249 struct printif
*printer_fns
= &generic_printif
;
252 if ( type
== PRINT_CUPS
) {
253 printer_fns
= &cups_printif
;
255 #endif /* HAVE_CUPS */
258 if ( type
== PRINT_IPRINT
) {
259 printer_fns
= &iprint_printif
;
261 #endif /* HAVE_IPRINT */
263 printer_fns
->type
= type
;
268 static struct printif
*get_printer_fns( int snum
)
270 return get_printer_fns_from_type( (enum printing_types
)lp_printing(snum
) );
274 /****************************************************************************
275 Useful function to generate a tdb key.
276 ****************************************************************************/
278 static TDB_DATA
print_key(uint32 jobid
, uint32
*tmp
)
282 SIVAL(tmp
, 0, jobid
);
283 ret
.dptr
= (uint8
*)tmp
;
284 ret
.dsize
= sizeof(*tmp
);
288 /****************************************************************************
289 Pack the devicemode to store it in a tdb.
290 ****************************************************************************/
291 static int pack_devicemode(struct spoolss_DeviceMode
*devmode
, uint8
*buf
, int buflen
)
293 enum ndr_err_code ndr_err
;
298 ndr_err
= ndr_push_struct_blob(&blob
, talloc_tos(),
300 (ndr_push_flags_fn_t
)
301 ndr_push_spoolss_DeviceMode
);
302 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
303 DEBUG(10, ("pack_devicemode: "
304 "error encoding spoolss_DeviceMode\n"));
311 len
= tdb_pack(buf
, buflen
, "B", blob
.length
, blob
.data
);
314 DEBUG(8, ("Packed devicemode [%s]\n", devmode
->formname
));
321 /****************************************************************************
322 Unpack the devicemode to store it in a tdb.
323 ****************************************************************************/
324 static int unpack_devicemode(TALLOC_CTX
*mem_ctx
,
325 const uint8
*buf
, int buflen
,
326 struct spoolss_DeviceMode
**devmode
)
328 struct spoolss_DeviceMode
*dm
;
329 enum ndr_err_code ndr_err
;
337 len
= tdb_unpack(buf
, buflen
, "B", &data_len
, &data
);
342 dm
= talloc_zero(mem_ctx
, struct spoolss_DeviceMode
);
347 blob
= data_blob_const(data
, data_len
);
349 ndr_err
= ndr_pull_struct_blob(&blob
, dm
, dm
,
350 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_DeviceMode
);
351 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
352 DEBUG(10, ("unpack_devicemode: "
353 "error parsing spoolss_DeviceMode\n"));
357 DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
358 dm
->devicename
, dm
->formname
));
359 if (dm
->driverextra_data
.data
) {
360 DEBUG(8, ("with a private section of %d bytes\n",
361 dm
->__driverextra_length
));
371 /***********************************************************************
372 unpack a pjob from a tdb buffer
373 ***********************************************************************/
375 static int unpack_pjob( uint8
*buf
, int buflen
, struct printjob
*pjob
)
379 uint32 pjpid
, pjsysjob
, pjfd
, pjstarttime
, pjstatus
;
380 uint32 pjsize
, pjpage_count
, pjspooled
, pjsmbjob
;
385 len
+= tdb_unpack(buf
+len
, buflen
-len
, "dddddddddfffff",
404 used
= unpack_devicemode(NULL
, buf
+len
, buflen
-len
, &pjob
->devmode
);
412 pjob
->sysjob
= pjsysjob
;
414 pjob
->starttime
= pjstarttime
;
415 pjob
->status
= pjstatus
;
417 pjob
->page_count
= pjpage_count
;
418 pjob
->spooled
= pjspooled
;
419 pjob
->smbjob
= pjsmbjob
;
425 /****************************************************************************
426 Useful function to find a print job in the database.
427 ****************************************************************************/
429 static struct printjob
*print_job_find(const char *sharename
, uint32 jobid
)
431 static struct printjob pjob
;
434 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
436 DEBUG(10,("print_job_find: looking up job %u for share %s\n",
437 (unsigned int)jobid
, sharename
));
443 ret
= tdb_fetch(pdb
->tdb
, print_key(jobid
, &tmp
));
444 release_print_db(pdb
);
447 DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid
));
451 talloc_free(pjob
.devmode
);
455 if ( unpack_pjob( ret
.dptr
, ret
.dsize
, &pjob
) == -1 ) {
456 DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid
));
463 DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
464 (int)pjob
.sysjob
, (unsigned int)jobid
));
469 /* Convert a unix jobid to a smb jobid */
471 struct unixjob_traverse_state
{
473 uint32 sysjob_to_jobid_value
;
476 static int unixjob_traverse_fn(TDB_CONTEXT
*the_tdb
, TDB_DATA key
,
477 TDB_DATA data
, void *private_data
)
479 struct printjob
*pjob
;
480 struct unixjob_traverse_state
*state
=
481 (struct unixjob_traverse_state
*)private_data
;
483 if (!data
.dptr
|| data
.dsize
== 0)
486 pjob
= (struct printjob
*)data
.dptr
;
487 if (key
.dsize
!= sizeof(uint32
))
490 if (state
->sysjob
== pjob
->sysjob
) {
491 uint32 jobid
= IVAL(key
.dptr
,0);
493 state
->sysjob_to_jobid_value
= jobid
;
500 /****************************************************************************
501 This is a *horribly expensive call as we have to iterate through all the
502 current printer tdb's. Don't do this often ! JRA.
503 ****************************************************************************/
505 uint32
sysjob_to_jobid(int unix_jobid
)
507 int services
= lp_numservices();
509 struct unixjob_traverse_state state
;
511 state
.sysjob
= unix_jobid
;
512 state
.sysjob_to_jobid_value
= (uint32
)-1;
514 for (snum
= 0; snum
< services
; snum
++) {
515 struct tdb_print_db
*pdb
;
516 if (!lp_print_ok(snum
))
518 pdb
= get_print_db_byname(lp_const_servicename(snum
));
522 tdb_traverse(pdb
->tdb
, unixjob_traverse_fn
, &state
);
523 release_print_db(pdb
);
524 if (state
.sysjob_to_jobid_value
!= (uint32
)-1)
525 return state
.sysjob_to_jobid_value
;
530 /****************************************************************************
531 Send notifications based on what has changed after a pjob_store.
532 ****************************************************************************/
534 static const struct {
536 uint32_t spoolss_status
;
537 } lpq_to_spoolss_status_map
[] = {
538 { LPQ_QUEUED
, JOB_STATUS_QUEUED
},
539 { LPQ_PAUSED
, JOB_STATUS_PAUSED
},
540 { LPQ_SPOOLING
, JOB_STATUS_SPOOLING
},
541 { LPQ_PRINTING
, JOB_STATUS_PRINTING
},
542 { LPQ_DELETING
, JOB_STATUS_DELETING
},
543 { LPQ_OFFLINE
, JOB_STATUS_OFFLINE
},
544 { LPQ_PAPEROUT
, JOB_STATUS_PAPEROUT
},
545 { LPQ_PRINTED
, JOB_STATUS_PRINTED
},
546 { LPQ_DELETED
, JOB_STATUS_DELETED
},
547 { LPQ_BLOCKED
, JOB_STATUS_BLOCKED_DEVQ
},
548 { LPQ_USER_INTERVENTION
, JOB_STATUS_USER_INTERVENTION
},
552 /* Convert a lpq status value stored in printing.tdb into the
553 appropriate win32 API constant. */
555 static uint32
map_to_spoolss_status(uint32 lpq_status
)
559 while (lpq_to_spoolss_status_map
[i
].lpq_status
!= -1) {
560 if (lpq_to_spoolss_status_map
[i
].lpq_status
== lpq_status
)
561 return lpq_to_spoolss_status_map
[i
].spoolss_status
;
568 /***************************************************************************
569 Append a jobid to the 'jobs changed' list.
570 ***************************************************************************/
572 static bool add_to_jobs_changed(struct tdb_print_db
*pdb
, uint32_t jobid
)
575 uint32_t store_jobid
;
577 SIVAL(&store_jobid
, 0, jobid
);
578 data
.dptr
= (uint8
*) &store_jobid
;
581 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid
));
583 return (tdb_append(pdb
->tdb
, string_tdb_data("INFO/jobs_changed"),
587 /***************************************************************************
588 Remove a jobid from the 'jobs changed' list.
589 ***************************************************************************/
591 static bool remove_from_jobs_changed(const char* sharename
, uint32_t jobid
)
593 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
597 bool gotlock
= False
;
605 key
= string_tdb_data("INFO/jobs_changed");
607 if (tdb_chainlock_with_timeout(pdb
->tdb
, key
, 5) == -1)
612 data
= tdb_fetch(pdb
->tdb
, key
);
614 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0))
617 job_count
= data
.dsize
/ 4;
618 for (i
= 0; i
< job_count
; i
++) {
621 ch_jobid
= IVAL(data
.dptr
, i
*4);
622 if (ch_jobid
== jobid
) {
623 if (i
< job_count
-1 )
624 memmove(data
.dptr
+ (i
*4), data
.dptr
+ (i
*4) + 4, (job_count
- i
- 1)*4 );
626 if (tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
) == -1)
636 tdb_chainunlock(pdb
->tdb
, key
);
637 SAFE_FREE(data
.dptr
);
638 release_print_db(pdb
);
640 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid
));
642 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid
));
646 static void pjob_store_notify(struct tevent_context
*ev
,
647 struct messaging_context
*msg_ctx
,
648 const char* sharename
, uint32 jobid
,
649 struct printjob
*old_data
,
650 struct printjob
*new_data
,
653 bool new_job
= false;
654 bool changed
= false;
656 if (old_data
== NULL
) {
660 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
661 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
662 time first or else we'll end up with potential alignment
663 errors. I don't think the systemtime should be spooled as
664 a string, but this gets us around that error.
665 --jerry (i'll feel dirty for this) */
668 notify_job_submitted(ev
, msg_ctx
,
669 sharename
, jobid
, new_data
->starttime
);
670 notify_job_username(ev
, msg_ctx
,
671 sharename
, jobid
, new_data
->user
);
672 notify_job_name(ev
, msg_ctx
,
673 sharename
, jobid
, new_data
->jobname
);
674 notify_job_status(ev
, msg_ctx
,
675 sharename
, jobid
, map_to_spoolss_status(new_data
->status
));
676 notify_job_total_bytes(ev
, msg_ctx
,
677 sharename
, jobid
, new_data
->size
);
678 notify_job_total_pages(ev
, msg_ctx
,
679 sharename
, jobid
, new_data
->page_count
);
681 if (!strequal(old_data
->jobname
, new_data
->jobname
)) {
682 notify_job_name(ev
, msg_ctx
, sharename
,
683 jobid
, new_data
->jobname
);
687 if (old_data
->status
!= new_data
->status
) {
688 notify_job_status(ev
, msg_ctx
,
690 map_to_spoolss_status(new_data
->status
));
693 if (old_data
->size
!= new_data
->size
) {
694 notify_job_total_bytes(ev
, msg_ctx
,
695 sharename
, jobid
, new_data
->size
);
698 if (old_data
->page_count
!= new_data
->page_count
) {
699 notify_job_total_pages(ev
, msg_ctx
,
701 new_data
->page_count
);
708 /****************************************************************************
709 Store a job structure back to the database.
710 ****************************************************************************/
712 static bool pjob_store(struct tevent_context
*ev
,
713 struct messaging_context
*msg_ctx
,
714 const char* sharename
, uint32 jobid
,
715 struct printjob
*pjob
)
718 TDB_DATA old_data
, new_data
;
720 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
722 int len
, newlen
, buflen
;
730 old_data
= tdb_fetch(pdb
->tdb
, print_key(jobid
, &tmp
));
732 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
739 len
+= tdb_pack(buf
+len
, buflen
-len
, "dddddddddfffff",
741 (uint32
)pjob
->sysjob
,
743 (uint32
)pjob
->starttime
,
744 (uint32
)pjob
->status
,
746 (uint32
)pjob
->page_count
,
747 (uint32
)pjob
->spooled
,
748 (uint32
)pjob
->smbjob
,
755 len
+= pack_devicemode(pjob
->devmode
, buf
+len
, buflen
-len
);
758 buf
= (uint8
*)SMB_REALLOC(buf
, len
);
760 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
765 } while ( buflen
!= len
);
771 new_data
.dsize
= len
;
772 ret
= (tdb_store(pdb
->tdb
, print_key(jobid
, &tmp
), new_data
,
775 /* Send notify updates for what has changed */
778 bool changed
= false;
779 struct printjob old_pjob
;
781 if ( old_data
.dsize
)
783 if ( unpack_pjob( old_data
.dptr
, old_data
.dsize
, &old_pjob
) != -1 )
785 pjob_store_notify(server_event_context(),
787 sharename
, jobid
, &old_pjob
,
790 talloc_free(old_pjob
.devmode
);
793 add_to_jobs_changed(pdb
, jobid
);
800 pjob_store_notify(server_event_context(), msg_ctx
,
801 sharename
, jobid
, NULL
, pjob
,
806 release_print_db(pdb
);
808 SAFE_FREE( old_data
.dptr
);
814 /****************************************************************************
815 Remove a job structure from the database.
816 ****************************************************************************/
818 static void pjob_delete(struct tevent_context
*ev
,
819 struct messaging_context
*msg_ctx
,
820 const char* sharename
, uint32 jobid
)
823 struct printjob
*pjob
;
824 uint32 job_status
= 0;
825 struct tdb_print_db
*pdb
;
827 pdb
= get_print_db_byname( sharename
);
832 pjob
= print_job_find( sharename
, jobid
);
835 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
836 (unsigned int)jobid
));
837 release_print_db(pdb
);
841 /* We must cycle through JOB_STATUS_DELETING and
842 JOB_STATUS_DELETED for the port monitor to delete the job
845 job_status
= JOB_STATUS_DELETING
|JOB_STATUS_DELETED
;
846 notify_job_status(ev
, msg_ctx
, sharename
, jobid
, job_status
);
848 /* Remove from printing.tdb */
850 tdb_delete(pdb
->tdb
, print_key(jobid
, &tmp
));
851 remove_from_jobs_added(sharename
, jobid
);
852 release_print_db( pdb
);
853 rap_jobid_delete(sharename
, jobid
);
856 /****************************************************************************
857 List a unix job in the print database.
858 ****************************************************************************/
860 static void print_unix_job(struct tevent_context
*ev
,
861 struct messaging_context
*msg_ctx
,
862 const char *sharename
, print_queue_struct
*q
,
865 struct printjob pj
, *old_pj
;
867 if (jobid
== (uint32
)-1)
868 jobid
= q
->job
+ UNIX_JOB_START
;
870 /* Preserve the timestamp on an existing unix print job */
872 old_pj
= print_job_find(sharename
, jobid
);
879 pj
.starttime
= old_pj
? old_pj
->starttime
: q
->time
;
880 pj
.status
= q
->status
;
883 fstrcpy(pj
.filename
, old_pj
? old_pj
->filename
: "");
884 if (jobid
< UNIX_JOB_START
) {
886 fstrcpy(pj
.jobname
, old_pj
? old_pj
->jobname
: "Remote Downlevel Document");
889 fstrcpy(pj
.jobname
, old_pj
? old_pj
->jobname
: q
->fs_file
);
891 fstrcpy(pj
.user
, old_pj
? old_pj
->user
: q
->fs_user
);
892 fstrcpy(pj
.queuename
, old_pj
? old_pj
->queuename
: sharename
);
894 pjob_store(ev
, msg_ctx
, sharename
, jobid
, &pj
);
898 struct traverse_struct
{
899 print_queue_struct
*queue
;
900 int qcount
, snum
, maxcount
, total_jobs
;
901 const char *sharename
;
903 const char *lprm_command
;
904 struct printif
*print_if
;
905 struct tevent_context
*ev
;
906 struct messaging_context
*msg_ctx
;
909 /****************************************************************************
910 Utility fn to delete any jobs that are no longer active.
911 ****************************************************************************/
913 static int traverse_fn_delete(TDB_CONTEXT
*t
, TDB_DATA key
, TDB_DATA data
, void *state
)
915 struct traverse_struct
*ts
= (struct traverse_struct
*)state
;
916 struct printjob pjob
;
920 if ( key
.dsize
!= sizeof(jobid
) )
923 jobid
= IVAL(key
.dptr
, 0);
924 if ( unpack_pjob( data
.dptr
, data
.dsize
, &pjob
) == -1 )
926 talloc_free(pjob
.devmode
);
930 /* remove a unix job if it isn't in the system queue any more */
932 for (i
=0;i
<ts
->qcount
;i
++) {
933 uint32 u_jobid
= (ts
->queue
[i
].job
+ UNIX_JOB_START
);
934 if (jobid
== u_jobid
)
937 if (i
== ts
->qcount
) {
938 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
939 (unsigned int)jobid
));
940 pjob_delete(ts
->ev
, ts
->msg_ctx
,
941 ts
->sharename
, jobid
);
945 /* need to continue the the bottom of the function to
946 save the correct attributes */
949 /* maybe it hasn't been spooled yet */
951 /* if a job is not spooled and the process doesn't
952 exist then kill it. This cleans up after smbd
954 if (!process_exists_by_pid(pjob
.pid
)) {
955 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
956 (unsigned int)jobid
, (unsigned int)pjob
.pid
));
957 pjob_delete(ts
->ev
, ts
->msg_ctx
,
958 ts
->sharename
, jobid
);
964 /* this check only makes sense for jobs submitted from Windows clients */
967 for (i
=0;i
<ts
->qcount
;i
++) {
970 if ( pjob
.status
== LPQ_DELETED
)
973 curr_jobid
= print_parse_jobid(ts
->queue
[i
].fs_file
);
975 if (jobid
== curr_jobid
) {
977 /* try to clean up any jobs that need to be deleted */
979 if ( pjob
.status
== LPQ_DELETING
) {
982 result
= (*(ts
->print_if
->job_delete
))(
983 ts
->sharename
, ts
->lprm_command
, &pjob
);
986 /* if we can't delete, then reset the job status */
987 pjob
.status
= LPQ_QUEUED
;
988 pjob_store(ts
->ev
, ts
->msg_ctx
,
989 ts
->sharename
, jobid
, &pjob
);
992 /* if we deleted the job, the remove the tdb record */
995 ts
->sharename
, jobid
);
996 pjob
.status
= LPQ_DELETED
;
1006 /* The job isn't in the system queue - we have to assume it has
1007 completed, so delete the database entry. */
1009 if (i
== ts
->qcount
) {
1011 /* A race can occur between the time a job is spooled and
1012 when it appears in the lpq output. This happens when
1013 the job is added to printing.tdb when another smbd
1014 running print_queue_update() has completed a lpq and
1015 is currently traversing the printing tdb and deleting jobs.
1016 Don't delete the job if it was submitted after the lpq_time. */
1018 if (pjob
.starttime
< ts
->lpq_time
) {
1019 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
1020 (unsigned int)jobid
,
1021 (unsigned int)pjob
.starttime
,
1022 (unsigned int)ts
->lpq_time
));
1023 pjob_delete(ts
->ev
, ts
->msg_ctx
,
1024 ts
->sharename
, jobid
);
1030 /* Save the pjob attributes we will store.
1031 FIXME!!! This is the only place where queue->job
1032 represents the SMB jobid --jerry */
1034 ts
->queue
[i
].job
= jobid
;
1035 ts
->queue
[i
].size
= pjob
.size
;
1036 ts
->queue
[i
].page_count
= pjob
.page_count
;
1037 ts
->queue
[i
].status
= pjob
.status
;
1038 ts
->queue
[i
].priority
= 1;
1039 ts
->queue
[i
].time
= pjob
.starttime
;
1040 fstrcpy(ts
->queue
[i
].fs_user
, pjob
.user
);
1041 fstrcpy(ts
->queue
[i
].fs_file
, pjob
.jobname
);
1048 /****************************************************************************
1049 Check if the print queue has been updated recently enough.
1050 ****************************************************************************/
1052 static void print_cache_flush(const char *sharename
)
1055 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1059 slprintf(key
, sizeof(key
)-1, "CACHE/%s", sharename
);
1060 tdb_store_int32(pdb
->tdb
, key
, -1);
1061 release_print_db(pdb
);
1064 /****************************************************************************
1065 Check if someone already thinks they are doing the update.
1066 ****************************************************************************/
1068 static pid_t
get_updating_pid(const char *sharename
)
1073 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1077 slprintf(keystr
, sizeof(keystr
)-1, "UPDATING/%s", sharename
);
1078 key
= string_tdb_data(keystr
);
1080 data
= tdb_fetch(pdb
->tdb
, key
);
1081 release_print_db(pdb
);
1082 if (!data
.dptr
|| data
.dsize
!= sizeof(pid_t
)) {
1083 SAFE_FREE(data
.dptr
);
1087 updating_pid
= IVAL(data
.dptr
, 0);
1088 SAFE_FREE(data
.dptr
);
1090 if (process_exists_by_pid(updating_pid
))
1091 return updating_pid
;
1096 /****************************************************************************
1097 Set the fact that we're doing the update, or have finished doing the update
1099 ****************************************************************************/
1101 static void set_updating_pid(const fstring sharename
, bool updating
)
1106 pid_t updating_pid
= sys_getpid();
1109 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1114 slprintf(keystr
, sizeof(keystr
)-1, "UPDATING/%s", sharename
);
1115 key
= string_tdb_data(keystr
);
1117 DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
1118 updating
? "" : "not ",
1122 tdb_delete(pdb
->tdb
, key
);
1123 release_print_db(pdb
);
1127 SIVAL( buffer
, 0, updating_pid
);
1129 data
.dsize
= 4; /* we always assume this is a 4 byte value */
1131 tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
);
1132 release_print_db(pdb
);
1135 /****************************************************************************
1136 Sort print jobs by submittal time.
1137 ****************************************************************************/
1139 static int printjob_comp(print_queue_struct
*j1
, print_queue_struct
*j2
)
1150 /* Sort on job start time */
1152 if (j1
->time
== j2
->time
)
1154 return (j1
->time
> j2
->time
) ? 1 : -1;
1157 /****************************************************************************
1158 Store the sorted queue representation for later portmon retrieval.
1160 ****************************************************************************/
1162 static void store_queue_struct(struct tdb_print_db
*pdb
, struct traverse_struct
*pts
)
1165 int max_reported_jobs
= lp_max_reported_jobs(pts
->snum
);
1166 print_queue_struct
*queue
= pts
->queue
;
1169 unsigned int qcount
;
1171 if (max_reported_jobs
&& (max_reported_jobs
< pts
->qcount
))
1172 pts
->qcount
= max_reported_jobs
;
1175 /* Work out the size. */
1177 data
.dsize
+= tdb_pack(NULL
, 0, "d", qcount
);
1179 for (i
= 0; i
< pts
->qcount
; i
++) {
1180 if ( queue
[i
].status
== LPQ_DELETED
)
1184 data
.dsize
+= tdb_pack(NULL
, 0, "ddddddff",
1185 (uint32
)queue
[i
].job
,
1186 (uint32
)queue
[i
].size
,
1187 (uint32
)queue
[i
].page_count
,
1188 (uint32
)queue
[i
].status
,
1189 (uint32
)queue
[i
].priority
,
1190 (uint32
)queue
[i
].time
,
1195 if ((data
.dptr
= (uint8
*)SMB_MALLOC(data
.dsize
)) == NULL
)
1199 len
+= tdb_pack(data
.dptr
+ len
, data
.dsize
- len
, "d", qcount
);
1200 for (i
= 0; i
< pts
->qcount
; i
++) {
1201 if ( queue
[i
].status
== LPQ_DELETED
)
1204 len
+= tdb_pack(data
.dptr
+ len
, data
.dsize
- len
, "ddddddff",
1205 (uint32
)queue
[i
].job
,
1206 (uint32
)queue
[i
].size
,
1207 (uint32
)queue
[i
].page_count
,
1208 (uint32
)queue
[i
].status
,
1209 (uint32
)queue
[i
].priority
,
1210 (uint32
)queue
[i
].time
,
1215 tdb_store(pdb
->tdb
, string_tdb_data("INFO/linear_queue_array"), data
,
1217 SAFE_FREE(data
.dptr
);
1221 static TDB_DATA
get_jobs_added_data(struct tdb_print_db
*pdb
)
1227 data
= tdb_fetch(pdb
->tdb
, string_tdb_data("INFO/jobs_added"));
1228 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0)) {
1229 SAFE_FREE(data
.dptr
);
1236 static void check_job_added(const char *sharename
, TDB_DATA data
, uint32 jobid
)
1239 unsigned int job_count
= data
.dsize
/ 4;
1241 for (i
= 0; i
< job_count
; i
++) {
1244 ch_jobid
= IVAL(data
.dptr
, i
*4);
1245 if (ch_jobid
== jobid
)
1246 remove_from_jobs_added(sharename
, jobid
);
1250 /****************************************************************************
1251 Check if the print queue has been updated recently enough.
1252 ****************************************************************************/
1254 static bool print_cache_expired(const char *sharename
, bool check_pending
)
1257 time_t last_qscan_time
, time_now
= time(NULL
);
1258 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1259 bool result
= False
;
1264 snprintf(key
, sizeof(key
), "CACHE/%s", sharename
);
1265 last_qscan_time
= (time_t)tdb_fetch_int32(pdb
->tdb
, key
);
1268 * Invalidate the queue for 3 reasons.
1269 * (1). last queue scan time == -1.
1270 * (2). Current time - last queue scan time > allowed cache time.
1271 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1272 * This last test picks up machines for which the clock has been moved
1273 * forward, an lpq scan done and then the clock moved back. Otherwise
1274 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1277 if (last_qscan_time
== ((time_t)-1)
1278 || (time_now
- last_qscan_time
) >= lp_lpqcachetime()
1279 || last_qscan_time
> (time_now
+ MAX_CACHE_VALID_TIME
))
1282 time_t msg_pending_time
;
1284 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1285 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1286 sharename
, (int)last_qscan_time
, (int)time_now
,
1287 (int)lp_lpqcachetime() ));
1289 /* check if another smbd has already sent a message to update the
1290 queue. Give the pending message one minute to clear and
1291 then send another message anyways. Make sure to check for
1292 clocks that have been run forward and then back again. */
1294 snprintf(key
, sizeof(key
), "MSG_PENDING/%s", sharename
);
1297 && tdb_fetch_uint32( pdb
->tdb
, key
, &u
)
1298 && (msg_pending_time
=u
) > 0
1299 && msg_pending_time
<= time_now
1300 && (time_now
- msg_pending_time
) < 60 )
1302 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1311 release_print_db(pdb
);
1315 /****************************************************************************
1316 main work for updating the lpq cache for a printer queue
1317 ****************************************************************************/
1319 static void print_queue_update_internal( struct tevent_context
*ev
,
1320 struct messaging_context
*msg_ctx
,
1321 const char *sharename
,
1322 struct printif
*current_printif
,
1323 char *lpq_command
, char *lprm_command
)
1326 print_queue_struct
*queue
= NULL
;
1327 print_status_struct status
;
1328 print_status_struct old_status
;
1329 struct printjob
*pjob
;
1330 struct traverse_struct tstruct
;
1333 fstring keystr
, cachestr
;
1334 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1340 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1341 sharename
, current_printif
->type
, lpq_command
));
1344 * Update the cache time FIRST ! Stops others even
1345 * attempting to get the lock and doing this
1346 * if the lpq takes a long time.
1349 slprintf(cachestr
, sizeof(cachestr
)-1, "CACHE/%s", sharename
);
1350 tdb_store_int32(pdb
->tdb
, cachestr
, (int)time(NULL
));
1352 /* get the current queue using the appropriate interface */
1353 ZERO_STRUCT(status
);
1355 qcount
= (*(current_printif
->queue_get
))(sharename
,
1356 current_printif
->type
,
1357 lpq_command
, &queue
, &status
);
1359 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1360 qcount
, (qcount
!= 1) ? "s" : "", sharename
));
1362 /* Sort the queue by submission time otherwise they are displayed
1365 TYPESAFE_QSORT(queue
, qcount
, printjob_comp
);
1368 any job in the internal database that is marked as spooled
1369 and doesn't exist in the system queue is considered finished
1370 and removed from the database
1372 any job in the system database but not in the internal database
1373 is added as a unix job
1375 fill in any system job numbers as we go
1378 jcdata
= get_jobs_added_data(pdb
);
1380 for (i
=0; i
<qcount
; i
++) {
1381 uint32 jobid
= print_parse_jobid(queue
[i
].fs_file
);
1383 if (jobid
== (uint32
)-1) {
1384 /* assume its a unix print job */
1385 print_unix_job(ev
, msg_ctx
,
1386 sharename
, &queue
[i
], jobid
);
1390 /* we have an active SMB print job - update its status */
1391 pjob
= print_job_find(sharename
, jobid
);
1393 /* err, somethings wrong. Probably smbd was restarted
1394 with jobs in the queue. All we can do is treat them
1395 like unix jobs. Pity. */
1396 print_unix_job(ev
, msg_ctx
,
1397 sharename
, &queue
[i
], jobid
);
1401 pjob
->sysjob
= queue
[i
].job
;
1403 /* don't reset the status on jobs to be deleted */
1405 if ( pjob
->status
!= LPQ_DELETING
)
1406 pjob
->status
= queue
[i
].status
;
1408 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
1410 check_job_added(sharename
, jcdata
, jobid
);
1413 SAFE_FREE(jcdata
.dptr
);
1415 /* now delete any queued entries that don't appear in the
1417 tstruct
.queue
= queue
;
1418 tstruct
.qcount
= qcount
;
1420 tstruct
.total_jobs
= 0;
1421 tstruct
.lpq_time
= time(NULL
);
1422 tstruct
.sharename
= sharename
;
1423 tstruct
.lprm_command
= lprm_command
;
1424 tstruct
.print_if
= current_printif
;
1426 tstruct
.msg_ctx
= msg_ctx
;
1428 tdb_traverse(pdb
->tdb
, traverse_fn_delete
, (void *)&tstruct
);
1430 /* Store the linearised queue, max jobs only. */
1431 store_queue_struct(pdb
, &tstruct
);
1433 SAFE_FREE(tstruct
.queue
);
1435 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1436 sharename
, tstruct
.total_jobs
));
1438 tdb_store_int32(pdb
->tdb
, "INFO/total_jobs", tstruct
.total_jobs
);
1440 get_queue_status(sharename
, &old_status
);
1441 if (old_status
.qcount
!= qcount
)
1442 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1443 old_status
.qcount
, qcount
, sharename
));
1445 /* store the new queue status structure */
1446 slprintf(keystr
, sizeof(keystr
)-1, "STATUS/%s", sharename
);
1447 key
= string_tdb_data(keystr
);
1449 status
.qcount
= qcount
;
1450 data
.dptr
= (uint8
*)&status
;
1451 data
.dsize
= sizeof(status
);
1452 tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
);
1455 * Update the cache time again. We want to do this call
1456 * as little as possible...
1459 slprintf(keystr
, sizeof(keystr
)-1, "CACHE/%s", sharename
);
1460 tdb_store_int32(pdb
->tdb
, keystr
, (int32
)time(NULL
));
1462 /* clear the msg pending record for this queue */
1464 snprintf(keystr
, sizeof(keystr
), "MSG_PENDING/%s", sharename
);
1466 if ( !tdb_store_uint32( pdb
->tdb
, keystr
, 0 ) ) {
1467 /* log a message but continue on */
1469 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1473 release_print_db( pdb
);
1478 /****************************************************************************
1479 Update the internal database from the system print queue for a queue.
1480 obtain a lock on the print queue before proceeding (needed when mutiple
1481 smbd processes maytry to update the lpq cache concurrently).
1482 ****************************************************************************/
1484 static void print_queue_update_with_lock( struct tevent_context
*ev
,
1485 struct messaging_context
*msg_ctx
,
1486 const char *sharename
,
1487 struct printif
*current_printif
,
1488 char *lpq_command
, char *lprm_command
)
1491 struct tdb_print_db
*pdb
;
1493 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename
));
1494 pdb
= get_print_db_byname(sharename
);
1498 if ( !print_cache_expired(sharename
, False
) ) {
1499 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename
));
1500 release_print_db(pdb
);
1505 * Check to see if someone else is doing this update.
1506 * This is essentially a mutex on the update.
1509 if (get_updating_pid(sharename
) != -1) {
1510 release_print_db(pdb
);
1514 /* Lock the queue for the database update */
1516 slprintf(keystr
, sizeof(keystr
) - 1, "LOCK/%s", sharename
);
1517 /* Only wait 10 seconds for this. */
1518 if (tdb_lock_bystring_with_timeout(pdb
->tdb
, keystr
, 10) == -1) {
1519 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename
));
1520 release_print_db(pdb
);
1525 * Ensure that no one else got in here.
1526 * If the updating pid is still -1 then we are
1530 if (get_updating_pid(sharename
) != -1) {
1532 * Someone else is doing the update, exit.
1534 tdb_unlock_bystring(pdb
->tdb
, keystr
);
1535 release_print_db(pdb
);
1540 * We're going to do the update ourselves.
1543 /* Tell others we're doing the update. */
1544 set_updating_pid(sharename
, True
);
1547 * Allow others to enter and notice we're doing
1551 tdb_unlock_bystring(pdb
->tdb
, keystr
);
1553 /* do the main work now */
1555 print_queue_update_internal(ev
, msg_ctx
,
1556 sharename
, current_printif
,
1557 lpq_command
, lprm_command
);
1559 /* Delete our pid from the db. */
1560 set_updating_pid(sharename
, False
);
1561 release_print_db(pdb
);
1564 /****************************************************************************
1565 this is the receive function of the background lpq updater
1566 ****************************************************************************/
1567 void print_queue_receive(struct messaging_context
*msg
,
1570 struct server_id server_id
,
1574 char *lpqcommand
= NULL
, *lprmcommand
= NULL
;
1578 len
= tdb_unpack( (uint8
*)data
->data
, data
->length
, "fdPP",
1585 SAFE_FREE(lpqcommand
);
1586 SAFE_FREE(lprmcommand
);
1587 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1591 print_queue_update_with_lock(server_event_context(), msg
, sharename
,
1592 get_printer_fns_from_type((enum printing_types
)printing_type
),
1593 lpqcommand
, lprmcommand
);
1595 SAFE_FREE(lpqcommand
);
1596 SAFE_FREE(lprmcommand
);
1600 static void printing_pause_fd_handler(struct tevent_context
*ev
,
1601 struct tevent_fd
*fde
,
1606 * If pause_pipe[1] is closed it means the parent smbd
1607 * and children exited or aborted.
1609 exit_server_cleanly(NULL
);
1612 extern struct child_pid
*children
;
1613 extern int num_children
;
1615 static void add_child_pid(pid_t pid
)
1617 struct child_pid
*child
;
1619 child
= SMB_MALLOC_P(struct child_pid
);
1620 if (child
== NULL
) {
1621 DEBUG(0, ("Could not add child struct -- malloc failed\n"));
1625 DLIST_ADD(children
, child
);
1629 static pid_t background_lpq_updater_pid
= -1;
1631 /****************************************************************************
1632 main thread of the background lpq updater
1633 ****************************************************************************/
1634 void start_background_queue(struct tevent_context
*ev
,
1635 struct messaging_context
*msg_ctx
)
1637 /* Use local variables for this as we don't
1638 * need to save the parent side of this, just
1639 * ensure it closes when the process exits.
1643 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1645 if (pipe(pause_pipe
) == -1) {
1646 DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno
) ));
1650 background_lpq_updater_pid
= sys_fork();
1652 if (background_lpq_updater_pid
== -1) {
1653 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno
) ));
1657 /* Track the printing pid along with other smbd children */
1658 add_child_pid(background_lpq_updater_pid
);
1660 if(background_lpq_updater_pid
== 0) {
1661 struct tevent_fd
*fde
;
1666 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1668 close(pause_pipe
[0]);
1671 status
= reinit_after_fork(msg_ctx
, ev
, procid_self(), true);
1673 if (!NT_STATUS_IS_OK(status
)) {
1674 DEBUG(0,("reinit_after_fork() failed\n"));
1675 smb_panic("reinit_after_fork() failed");
1678 smbd_setup_sig_term_handler();
1679 smbd_setup_sig_hup_handler(ev
, msg_ctx
);
1681 if (!serverid_register(procid_self(),
1682 FLAG_MSG_GENERAL
|FLAG_MSG_SMBD
1683 |FLAG_MSG_PRINT_GENERAL
)) {
1687 if (!locking_init()) {
1691 messaging_register(msg_ctx
, NULL
, MSG_PRINTER_UPDATE
,
1692 print_queue_receive
);
1694 fde
= tevent_add_fd(ev
, ev
, pause_pipe
[1], TEVENT_FD_READ
,
1695 printing_pause_fd_handler
,
1698 DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
1699 smb_panic("tevent_add_fd() failed for pause_pipe");
1702 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1703 ret
= tevent_loop_wait(ev
);
1704 /* should not be reached */
1705 DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
1706 ret
, (ret
== 0) ? "out of events" : strerror(errno
)));
1710 close(pause_pipe
[1]);
1713 /****************************************************************************
1714 update the internal database from the system print queue for a queue
1715 ****************************************************************************/
1717 static void print_queue_update(struct messaging_context
*msg_ctx
,
1718 int snum
, bool force
)
1722 char *lpqcommand
= NULL
;
1723 char *lprmcommand
= NULL
;
1724 uint8
*buffer
= NULL
;
1727 struct tdb_print_db
*pdb
;
1729 struct printif
*current_printif
;
1730 TALLOC_CTX
*ctx
= talloc_tos();
1732 fstrcpy( sharename
, lp_const_servicename(snum
));
1734 /* don't strip out characters like '$' from the printername */
1736 lpqcommand
= talloc_string_sub2(ctx
,
1737 lp_lpqcommand(snum
),
1739 lp_printername(snum
),
1740 false, false, false);
1744 lpqcommand
= talloc_sub_advanced(ctx
,
1745 lp_servicename(snum
),
1746 current_user_info
.unix_name
,
1748 current_user
.ut
.gid
,
1749 get_current_username(),
1750 current_user_info
.domain
,
1756 lprmcommand
= talloc_string_sub2(ctx
,
1757 lp_lprmcommand(snum
),
1759 lp_printername(snum
),
1760 false, false, false);
1764 lprmcommand
= talloc_sub_advanced(ctx
,
1765 lp_servicename(snum
),
1766 current_user_info
.unix_name
,
1768 current_user
.ut
.gid
,
1769 get_current_username(),
1770 current_user_info
.domain
,
1777 * Make sure that the background queue process exists.
1778 * Otherwise just do the update ourselves
1781 if ( force
|| background_lpq_updater_pid
== -1 ) {
1782 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename
));
1783 current_printif
= get_printer_fns( snum
);
1784 print_queue_update_with_lock(server_event_context(), msg_ctx
,
1785 sharename
, current_printif
,
1786 lpqcommand
, lprmcommand
);
1791 type
= lp_printing(snum
);
1793 /* get the length */
1795 len
= tdb_pack( NULL
, 0, "fdPP",
1801 buffer
= SMB_XMALLOC_ARRAY( uint8
, len
);
1803 /* now pack the buffer */
1804 newlen
= tdb_pack( buffer
, len
, "fdPP",
1810 SMB_ASSERT( newlen
== len
);
1812 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1813 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1814 sharename
, type
, lpqcommand
, lprmcommand
));
1816 /* here we set a msg pending record for other smbd processes
1817 to throttle the number of duplicate print_queue_update msgs
1820 pdb
= get_print_db_byname(sharename
);
1826 snprintf(key
, sizeof(key
), "MSG_PENDING/%s", sharename
);
1828 if ( !tdb_store_uint32( pdb
->tdb
, key
, time(NULL
) ) ) {
1829 /* log a message but continue on */
1831 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1835 release_print_db( pdb
);
1837 /* finally send the message */
1839 messaging_send_buf(msg_ctx
, pid_to_procid(background_lpq_updater_pid
),
1840 MSG_PRINTER_UPDATE
, (uint8
*)buffer
, len
);
1842 SAFE_FREE( buffer
);
1847 /****************************************************************************
1848 Create/Update an entry in the print tdb that will allow us to send notify
1849 updates only to interested smbd's.
1850 ****************************************************************************/
1852 bool print_notify_register_pid(int snum
)
1855 struct tdb_print_db
*pdb
= NULL
;
1856 TDB_CONTEXT
*tdb
= NULL
;
1857 const char *printername
;
1858 uint32 mypid
= (uint32
)sys_getpid();
1862 /* if (snum == -1), then the change notify request was
1863 on a print server handle and we need to register on
1868 int num_services
= lp_numservices();
1871 for ( idx
=0; idx
<num_services
; idx
++ ) {
1872 if (lp_snum_ok(idx
) && lp_print_ok(idx
) )
1873 print_notify_register_pid(idx
);
1878 else /* register for a specific printer */
1880 printername
= lp_const_servicename(snum
);
1881 pdb
= get_print_db_byname(printername
);
1887 if (tdb_lock_bystring_with_timeout(tdb
, NOTIFY_PID_LIST_KEY
, 10) == -1) {
1888 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1891 release_print_db(pdb
);
1895 data
= get_printer_notify_pid_list( tdb
, printername
, True
);
1897 /* Add ourselves and increase the refcount. */
1899 for (i
= 0; i
< data
.dsize
; i
+= 8) {
1900 if (IVAL(data
.dptr
,i
) == mypid
) {
1901 uint32 new_refcount
= IVAL(data
.dptr
, i
+4) + 1;
1902 SIVAL(data
.dptr
, i
+4, new_refcount
);
1907 if (i
== data
.dsize
) {
1908 /* We weren't in the list. Realloc. */
1909 data
.dptr
= (uint8
*)SMB_REALLOC(data
.dptr
, data
.dsize
+ 8);
1911 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1916 SIVAL(data
.dptr
,data
.dsize
- 8,mypid
);
1917 SIVAL(data
.dptr
,data
.dsize
- 4,1); /* Refcount. */
1920 /* Store back the record. */
1921 if (tdb_store_bystring(tdb
, NOTIFY_PID_LIST_KEY
, data
, TDB_REPLACE
) == -1) {
1922 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1923 list for printer %s\n", printername
));
1931 tdb_unlock_bystring(tdb
, NOTIFY_PID_LIST_KEY
);
1933 release_print_db(pdb
);
1934 SAFE_FREE(data
.dptr
);
1938 /****************************************************************************
1939 Update an entry in the print tdb that will allow us to send notify
1940 updates only to interested smbd's.
1941 ****************************************************************************/
1943 bool print_notify_deregister_pid(int snum
)
1946 struct tdb_print_db
*pdb
= NULL
;
1947 TDB_CONTEXT
*tdb
= NULL
;
1948 const char *printername
;
1949 uint32 mypid
= (uint32
)sys_getpid();
1953 /* if ( snum == -1 ), we are deregister a print server handle
1954 which means to deregister on all print queues */
1958 int num_services
= lp_numservices();
1961 for ( idx
=0; idx
<num_services
; idx
++ ) {
1962 if ( lp_snum_ok(idx
) && lp_print_ok(idx
) )
1963 print_notify_deregister_pid(idx
);
1968 else /* deregister a specific printer */
1970 printername
= lp_const_servicename(snum
);
1971 pdb
= get_print_db_byname(printername
);
1977 if (tdb_lock_bystring_with_timeout(tdb
, NOTIFY_PID_LIST_KEY
, 10) == -1) {
1978 DEBUG(0,("print_notify_register_pid: Failed to lock \
1979 printer %s database\n", printername
));
1981 release_print_db(pdb
);
1985 data
= get_printer_notify_pid_list( tdb
, printername
, True
);
1987 /* Reduce refcount. Remove ourselves if zero. */
1989 for (i
= 0; i
< data
.dsize
; ) {
1990 if (IVAL(data
.dptr
,i
) == mypid
) {
1991 uint32 refcount
= IVAL(data
.dptr
, i
+4);
1995 if (refcount
== 0) {
1996 if (data
.dsize
- i
> 8)
1997 memmove( &data
.dptr
[i
], &data
.dptr
[i
+8], data
.dsize
- i
- 8);
2001 SIVAL(data
.dptr
, i
+4, refcount
);
2007 if (data
.dsize
== 0)
2008 SAFE_FREE(data
.dptr
);
2010 /* Store back the record. */
2011 if (tdb_store_bystring(tdb
, NOTIFY_PID_LIST_KEY
, data
, TDB_REPLACE
) == -1) {
2012 DEBUG(0,("print_notify_register_pid: Failed to update pid \
2013 list for printer %s\n", printername
));
2021 tdb_unlock_bystring(tdb
, NOTIFY_PID_LIST_KEY
);
2023 release_print_db(pdb
);
2024 SAFE_FREE(data
.dptr
);
2028 /****************************************************************************
2029 Check if a jobid is valid. It is valid if it exists in the database.
2030 ****************************************************************************/
2032 bool print_job_exists(const char* sharename
, uint32 jobid
)
2034 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2040 ret
= tdb_exists(pdb
->tdb
, print_key(jobid
, &tmp
));
2041 release_print_db(pdb
);
2045 /****************************************************************************
2046 Give the filename used for a jobid.
2047 Only valid for the process doing the spooling and when the job
2048 has not been spooled.
2049 ****************************************************************************/
2051 char *print_job_fname(const char* sharename
, uint32 jobid
)
2053 struct printjob
*pjob
= print_job_find(sharename
, jobid
);
2054 if (!pjob
|| pjob
->spooled
|| pjob
->pid
!= sys_getpid())
2056 return pjob
->filename
;
2060 /****************************************************************************
2061 Give the filename used for a jobid.
2062 Only valid for the process doing the spooling and when the job
2063 has not been spooled.
2064 ****************************************************************************/
2066 struct spoolss_DeviceMode
*print_job_devmode(const char* sharename
, uint32 jobid
)
2068 struct printjob
*pjob
= print_job_find(sharename
, jobid
);
2073 return pjob
->devmode
;
2076 /****************************************************************************
2077 Set the name of a job. Only possible for owner.
2078 ****************************************************************************/
2080 bool print_job_set_name(struct tevent_context
*ev
,
2081 struct messaging_context
*msg_ctx
,
2082 const char *sharename
, uint32 jobid
, const char *name
)
2084 struct printjob
*pjob
;
2086 pjob
= print_job_find(sharename
, jobid
);
2087 if (!pjob
|| pjob
->pid
!= sys_getpid())
2090 fstrcpy(pjob
->jobname
, name
);
2091 return pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2094 /****************************************************************************
2095 Get the name of a job. Only possible for owner.
2096 ****************************************************************************/
2098 bool print_job_get_name(TALLOC_CTX
*mem_ctx
, const char *sharename
, uint32_t jobid
, char **name
)
2100 struct printjob
*pjob
;
2102 pjob
= print_job_find(sharename
, jobid
);
2103 if (!pjob
|| pjob
->pid
!= sys_getpid()) {
2107 *name
= talloc_strdup(mem_ctx
, pjob
->jobname
);
2116 /***************************************************************************
2117 Remove a jobid from the 'jobs added' list.
2118 ***************************************************************************/
2120 static bool remove_from_jobs_added(const char* sharename
, uint32 jobid
)
2122 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2124 size_t job_count
, i
;
2126 bool gotlock
= False
;
2134 key
= string_tdb_data("INFO/jobs_added");
2136 if (tdb_chainlock_with_timeout(pdb
->tdb
, key
, 5) == -1)
2141 data
= tdb_fetch(pdb
->tdb
, key
);
2143 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0))
2146 job_count
= data
.dsize
/ 4;
2147 for (i
= 0; i
< job_count
; i
++) {
2150 ch_jobid
= IVAL(data
.dptr
, i
*4);
2151 if (ch_jobid
== jobid
) {
2152 if (i
< job_count
-1 )
2153 memmove(data
.dptr
+ (i
*4), data
.dptr
+ (i
*4) + 4, (job_count
- i
- 1)*4 );
2155 if (tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
) == -1)
2165 tdb_chainunlock(pdb
->tdb
, key
);
2166 SAFE_FREE(data
.dptr
);
2167 release_print_db(pdb
);
2169 DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid
));
2171 DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid
));
2175 /****************************************************************************
2176 Delete a print job - don't update queue.
2177 ****************************************************************************/
2179 static bool print_job_delete1(struct tevent_context
*ev
,
2180 struct messaging_context
*msg_ctx
,
2181 int snum
, uint32 jobid
)
2183 const char* sharename
= lp_const_servicename(snum
);
2184 struct printjob
*pjob
= print_job_find(sharename
, jobid
);
2186 struct printif
*current_printif
= get_printer_fns( snum
);
2192 * If already deleting just return.
2195 if (pjob
->status
== LPQ_DELETING
)
2198 /* Hrm - we need to be able to cope with deleting a job before it
2199 has reached the spooler. Just mark it as LPQ_DELETING and
2200 let the print_queue_update() code rmeove the record */
2203 if (pjob
->sysjob
== -1) {
2204 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid
));
2207 /* Set the tdb entry to be deleting. */
2209 pjob
->status
= LPQ_DELETING
;
2210 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2212 if (pjob
->spooled
&& pjob
->sysjob
!= -1)
2214 result
= (*(current_printif
->job_delete
))(
2215 lp_printername(snum
),
2216 lp_lprmcommand(snum
),
2219 /* Delete the tdb entry if the delete succeeded or the job hasn't
2223 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2228 pjob_delete(ev
, msg_ctx
, sharename
, jobid
);
2229 /* Ensure we keep a rough count of the number of total jobs... */
2230 tdb_change_int32_atomic(pdb
->tdb
, "INFO/total_jobs", &njobs
, -1);
2231 release_print_db(pdb
);
2235 remove_from_jobs_added( sharename
, jobid
);
2237 return (result
== 0);
2240 /****************************************************************************
2241 Return true if the current user owns the print job.
2242 ****************************************************************************/
2244 static bool is_owner(const struct auth_serversupplied_info
*server_info
,
2245 const char *servicename
,
2248 struct printjob
*pjob
= print_job_find(servicename
, jobid
);
2250 if (!pjob
|| !server_info
)
2253 return strequal(pjob
->user
, server_info
->sanitized_username
);
2256 /****************************************************************************
2258 ****************************************************************************/
2260 WERROR
print_job_delete(const struct auth_serversupplied_info
*server_info
,
2261 struct messaging_context
*msg_ctx
,
2262 int snum
, uint32_t jobid
)
2264 const char* sharename
= lp_const_servicename(snum
);
2265 struct printjob
*pjob
;
2269 owner
= is_owner(server_info
, lp_const_servicename(snum
), jobid
);
2271 /* Check access against security descriptor or whether the user
2275 !print_access_check(server_info
, msg_ctx
, snum
,
2276 JOB_ACCESS_ADMINISTER
)) {
2277 DEBUG(3, ("delete denied by security descriptor\n"));
2279 /* BEGIN_ADMIN_LOG */
2280 sys_adminlog( LOG_ERR
,
2281 "Permission denied-- user not allowed to delete, \
2282 pause, or resume print job. User name: %s. Printer name: %s.",
2283 uidtoname(server_info
->utok
.uid
),
2284 lp_printername(snum
) );
2287 return WERR_ACCESS_DENIED
;
2291 * get the spooled filename of the print job
2292 * if this works, then the file has not been spooled
2293 * to the underlying print system. Just delete the
2294 * spool file & return.
2297 fname
= print_job_fname(sharename
, jobid
);
2298 if (fname
!= NULL
) {
2299 /* remove the spool file */
2300 DEBUG(10, ("print_job_delete: "
2301 "Removing spool file [%s]\n", fname
));
2302 if (unlink(fname
) == -1) {
2303 return map_werror_from_unix(errno
);
2307 if (!print_job_delete1(server_event_context(), msg_ctx
, snum
, jobid
)) {
2308 return WERR_ACCESS_DENIED
;
2311 /* force update the database and say the delete failed if the
2314 print_queue_update(msg_ctx
, snum
, True
);
2316 pjob
= print_job_find(sharename
, jobid
);
2317 if (pjob
&& (pjob
->status
!= LPQ_DELETING
)) {
2318 return WERR_ACCESS_DENIED
;
2321 return WERR_PRINTER_HAS_JOBS_QUEUED
;
2324 /****************************************************************************
2326 ****************************************************************************/
2328 bool print_job_pause(const struct auth_serversupplied_info
*server_info
,
2329 struct messaging_context
*msg_ctx
,
2330 int snum
, uint32 jobid
, WERROR
*errcode
)
2332 const char* sharename
= lp_const_servicename(snum
);
2333 struct printjob
*pjob
;
2335 struct printif
*current_printif
= get_printer_fns( snum
);
2337 pjob
= print_job_find(sharename
, jobid
);
2339 if (!pjob
|| !server_info
) {
2340 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2341 (unsigned int)jobid
));
2345 if (!pjob
->spooled
|| pjob
->sysjob
== -1) {
2346 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2347 (int)pjob
->sysjob
, (unsigned int)jobid
));
2351 if (!is_owner(server_info
, lp_const_servicename(snum
), jobid
) &&
2352 !print_access_check(server_info
, msg_ctx
, snum
,
2353 JOB_ACCESS_ADMINISTER
)) {
2354 DEBUG(3, ("pause denied by security descriptor\n"));
2356 /* BEGIN_ADMIN_LOG */
2357 sys_adminlog( LOG_ERR
,
2358 "Permission denied-- user not allowed to delete, \
2359 pause, or resume print job. User name: %s. Printer name: %s.",
2360 uidtoname(server_info
->utok
.uid
),
2361 lp_printername(snum
) );
2364 *errcode
= WERR_ACCESS_DENIED
;
2368 /* need to pause the spooled entry */
2369 ret
= (*(current_printif
->job_pause
))(snum
, pjob
);
2372 *errcode
= WERR_INVALID_PARAM
;
2376 /* force update the database */
2377 print_cache_flush(lp_const_servicename(snum
));
2379 /* Send a printer notify message */
2381 notify_job_status(server_event_context(), msg_ctx
, sharename
, jobid
,
2384 /* how do we tell if this succeeded? */
2389 /****************************************************************************
2391 ****************************************************************************/
2393 bool print_job_resume(const struct auth_serversupplied_info
*server_info
,
2394 struct messaging_context
*msg_ctx
,
2395 int snum
, uint32 jobid
, WERROR
*errcode
)
2397 const char *sharename
= lp_const_servicename(snum
);
2398 struct printjob
*pjob
;
2400 struct printif
*current_printif
= get_printer_fns( snum
);
2402 pjob
= print_job_find(sharename
, jobid
);
2404 if (!pjob
|| !server_info
) {
2405 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2406 (unsigned int)jobid
));
2410 if (!pjob
->spooled
|| pjob
->sysjob
== -1) {
2411 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2412 (int)pjob
->sysjob
, (unsigned int)jobid
));
2416 if (!is_owner(server_info
, lp_const_servicename(snum
), jobid
) &&
2417 !print_access_check(server_info
, msg_ctx
, snum
,
2418 JOB_ACCESS_ADMINISTER
)) {
2419 DEBUG(3, ("resume denied by security descriptor\n"));
2420 *errcode
= WERR_ACCESS_DENIED
;
2422 /* BEGIN_ADMIN_LOG */
2423 sys_adminlog( LOG_ERR
,
2424 "Permission denied-- user not allowed to delete, \
2425 pause, or resume print job. User name: %s. Printer name: %s.",
2426 uidtoname(server_info
->utok
.uid
),
2427 lp_printername(snum
) );
2432 ret
= (*(current_printif
->job_resume
))(snum
, pjob
);
2435 *errcode
= WERR_INVALID_PARAM
;
2439 /* force update the database */
2440 print_cache_flush(lp_const_servicename(snum
));
2442 /* Send a printer notify message */
2444 notify_job_status(server_event_context(), msg_ctx
, sharename
, jobid
,
2450 /****************************************************************************
2451 Write to a print file.
2452 ****************************************************************************/
2454 ssize_t
print_job_write(struct tevent_context
*ev
,
2455 struct messaging_context
*msg_ctx
,
2456 int snum
, uint32 jobid
, const char *buf
, size_t size
)
2458 const char* sharename
= lp_const_servicename(snum
);
2459 ssize_t return_code
;
2460 struct printjob
*pjob
;
2462 pjob
= print_job_find(sharename
, jobid
);
2466 /* don't allow another process to get this info - it is meaningless */
2467 if (pjob
->pid
!= sys_getpid())
2470 /* if SMBD is spooling this can't be allowed */
2471 if (pjob
->status
== PJOB_SMBD_SPOOLING
) {
2475 return_code
= write_data(pjob
->fd
, buf
, size
);
2477 if (return_code
>0) {
2479 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2484 /****************************************************************************
2485 Get the queue status - do not update if db is out of date.
2486 ****************************************************************************/
2488 static int get_queue_status(const char* sharename
, print_status_struct
*status
)
2492 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2496 ZERO_STRUCTP(status
);
2503 fstr_sprintf(keystr
, "STATUS/%s", sharename
);
2504 data
= tdb_fetch(pdb
->tdb
, string_tdb_data(keystr
));
2506 if (data
.dsize
== sizeof(print_status_struct
))
2507 /* this memcpy is ok since the status struct was
2508 not packed before storing it in the tdb */
2509 memcpy(status
, data
.dptr
, sizeof(print_status_struct
));
2510 SAFE_FREE(data
.dptr
);
2513 len
= tdb_fetch_int32(pdb
->tdb
, "INFO/total_jobs");
2514 release_print_db(pdb
);
2515 return (len
== -1 ? 0 : len
);
2518 /****************************************************************************
2519 Determine the number of jobs in a queue.
2520 ****************************************************************************/
2522 int print_queue_length(struct messaging_context
*msg_ctx
, int snum
,
2523 print_status_struct
*pstatus
)
2525 const char* sharename
= lp_const_servicename( snum
);
2526 print_status_struct status
;
2529 ZERO_STRUCT( status
);
2531 /* make sure the database is up to date */
2532 if (print_cache_expired(lp_const_servicename(snum
), True
))
2533 print_queue_update(msg_ctx
, snum
, False
);
2535 /* also fetch the queue status */
2536 memset(&status
, 0, sizeof(status
));
2537 len
= get_queue_status(sharename
, &status
);
2545 /***************************************************************************
2546 Allocate a jobid. Hold the lock for as short a time as possible.
2547 ***************************************************************************/
2549 static WERROR
allocate_print_jobid(struct tdb_print_db
*pdb
, int snum
,
2550 const char *sharename
, uint32
*pjobid
)
2554 enum TDB_ERROR terr
;
2557 *pjobid
= (uint32
)-1;
2559 for (i
= 0; i
< 3; i
++) {
2560 /* Lock the database - only wait 20 seconds. */
2561 ret
= tdb_lock_bystring_with_timeout(pdb
->tdb
,
2562 "INFO/nextjob", 20);
2564 DEBUG(0, ("allocate_print_jobid: "
2565 "Failed to lock printing database %s\n",
2567 terr
= tdb_error(pdb
->tdb
);
2568 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2571 if (!tdb_fetch_uint32(pdb
->tdb
, "INFO/nextjob", &jobid
)) {
2572 terr
= tdb_error(pdb
->tdb
);
2573 if (terr
!= TDB_ERR_NOEXIST
) {
2574 DEBUG(0, ("allocate_print_jobid: "
2575 "Failed to fetch INFO/nextjob "
2576 "for print queue %s\n", sharename
));
2577 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2578 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2580 DEBUG(10, ("allocate_print_jobid: "
2581 "No existing jobid in %s\n", sharename
));
2585 DEBUG(10, ("allocate_print_jobid: "
2586 "Read jobid %u from %s\n", jobid
, sharename
));
2588 jobid
= NEXT_JOBID(jobid
);
2590 ret
= tdb_store_int32(pdb
->tdb
, "INFO/nextjob", jobid
);
2592 terr
= tdb_error(pdb
->tdb
);
2593 DEBUG(3, ("allocate_print_jobid: "
2594 "Failed to store INFO/nextjob.\n"));
2595 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2596 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2599 /* We've finished with the INFO/nextjob lock. */
2600 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2602 if (!print_job_exists(sharename
, jobid
)) {
2605 DEBUG(10, ("allocate_print_jobid: "
2606 "Found jobid %u in %s\n", jobid
, sharename
));
2610 DEBUG(0, ("allocate_print_jobid: "
2611 "Failed to allocate a print job for queue %s\n",
2613 /* Probably full... */
2614 return WERR_NO_SPOOL_SPACE
;
2617 /* Store a dummy placeholder. */
2623 if (tdb_store(pdb
->tdb
, print_key(jobid
, &tmp
), dum
,
2624 TDB_INSERT
) == -1) {
2625 DEBUG(3, ("allocate_print_jobid: "
2626 "jobid (%d) failed to store placeholder.\n",
2628 terr
= tdb_error(pdb
->tdb
);
2629 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2637 /***************************************************************************
2638 Append a jobid to the 'jobs added' list.
2639 ***************************************************************************/
2641 static bool add_to_jobs_added(struct tdb_print_db
*pdb
, uint32 jobid
)
2646 SIVAL(&store_jobid
, 0, jobid
);
2647 data
.dptr
= (uint8
*)&store_jobid
;
2650 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid
));
2652 return (tdb_append(pdb
->tdb
, string_tdb_data("INFO/jobs_added"),
2657 /***************************************************************************
2658 Do all checks needed to determine if we can start a job.
2659 ***************************************************************************/
2661 static WERROR
print_job_checks(const struct auth_serversupplied_info
*server_info
,
2662 struct messaging_context
*msg_ctx
,
2663 int snum
, int *njobs
)
2665 const char *sharename
= lp_const_servicename(snum
);
2666 uint64_t dspace
, dsize
;
2670 if (!print_access_check(server_info
, msg_ctx
, snum
,
2671 PRINTER_ACCESS_USE
)) {
2672 DEBUG(3, ("print_job_checks: "
2673 "job start denied by security descriptor\n"));
2674 return WERR_ACCESS_DENIED
;
2677 if (!print_time_access_check(server_info
, msg_ctx
, sharename
)) {
2678 DEBUG(3, ("print_job_checks: "
2679 "job start denied by time check\n"));
2680 return WERR_ACCESS_DENIED
;
2683 /* see if we have sufficient disk space */
2684 if (lp_minprintspace(snum
)) {
2685 minspace
= lp_minprintspace(snum
);
2686 ret
= sys_fsusage(lp_pathname(snum
), &dspace
, &dsize
);
2687 if (ret
== 0 && dspace
< 2*minspace
) {
2688 DEBUG(3, ("print_job_checks: "
2689 "disk space check failed.\n"));
2690 return WERR_NO_SPOOL_SPACE
;
2694 /* for autoloaded printers, check that the printcap entry still exists */
2695 if (lp_autoloaded(snum
) && !pcap_printername_ok(sharename
)) {
2696 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2698 return WERR_ACCESS_DENIED
;
2701 /* Insure the maximum queue size is not violated */
2702 *njobs
= print_queue_length(msg_ctx
, snum
, NULL
);
2703 if (*njobs
> lp_maxprintjobs(snum
)) {
2704 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2705 "larger than max printjobs per queue (%d).\n",
2706 sharename
, *njobs
, lp_maxprintjobs(snum
)));
2707 return WERR_NO_SPOOL_SPACE
;
2713 /***************************************************************************
2715 ***************************************************************************/
2717 static WERROR
print_job_spool_file(int snum
, uint32_t jobid
,
2718 const char *output_file
,
2719 struct printjob
*pjob
)
2726 /* if this file is within the printer path, it means that smbd
2727 * is spooling it and will pass us control when it is finished.
2728 * Verify that the file name is ok, within path, and it is
2729 * already already there */
2731 path
= lp_pathname(snum
);
2733 if (strncmp(output_file
, path
, len
) == 0 &&
2734 (output_file
[len
- 1] == '/' || output_file
[len
] == '/')) {
2736 /* verify path is not too long */
2737 if (strlen(output_file
) >= sizeof(pjob
->filename
)) {
2738 return WERR_INVALID_NAME
;
2741 /* verify that the file exists */
2742 if (sys_stat(output_file
, &st
, false) != 0) {
2743 return WERR_INVALID_NAME
;
2746 fstrcpy(pjob
->filename
, output_file
);
2748 DEBUG(3, ("print_job_spool_file:"
2749 "External spooling activated"));
2751 /* we do not open the file until spooling is done */
2753 pjob
->status
= PJOB_SMBD_SPOOLING
;
2759 slprintf(pjob
->filename
, sizeof(pjob
->filename
)-1,
2760 "%s/%s%.8u.XXXXXX", lp_pathname(snum
),
2761 PRINT_SPOOL_PREFIX
, (unsigned int)jobid
);
2762 pjob
->fd
= mkstemp(pjob
->filename
);
2764 if (pjob
->fd
== -1) {
2765 werr
= map_werror_from_unix(errno
);
2766 if (W_ERROR_EQUAL(werr
, WERR_ACCESS_DENIED
)) {
2767 /* Common setup error, force a report. */
2768 DEBUG(0, ("print_job_spool_file: "
2769 "insufficient permissions to open spool "
2770 "file %s.\n", pjob
->filename
));
2772 /* Normal case, report at level 3 and above. */
2773 DEBUG(3, ("print_job_spool_file: "
2774 "can't open spool file %s\n",
2783 /***************************************************************************
2784 Start spooling a job - return the jobid.
2785 ***************************************************************************/
2787 WERROR
print_job_start(const struct auth_serversupplied_info
*server_info
,
2788 struct messaging_context
*msg_ctx
,
2789 const char *clientmachine
,
2790 int snum
, const char *docname
, const char *filename
,
2791 struct spoolss_DeviceMode
*devmode
, uint32_t *_jobid
)
2795 struct printjob pjob
;
2796 const char *sharename
= lp_const_servicename(snum
);
2797 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2802 return WERR_INTERNAL_DB_CORRUPTION
;
2805 path
= lp_pathname(snum
);
2807 werr
= print_job_checks(server_info
, msg_ctx
, snum
, &njobs
);
2808 if (!W_ERROR_IS_OK(werr
)) {
2809 release_print_db(pdb
);
2813 DEBUG(10, ("print_job_start: "
2814 "Queue %s number of jobs (%d), max printjobs = %d\n",
2815 sharename
, njobs
, lp_maxprintjobs(snum
)));
2817 werr
= allocate_print_jobid(pdb
, snum
, sharename
, &jobid
);
2818 if (!W_ERROR_IS_OK(werr
)) {
2822 /* create the database entry */
2826 pjob
.pid
= sys_getpid();
2829 pjob
.starttime
= time(NULL
);
2830 pjob
.status
= LPQ_SPOOLING
;
2832 pjob
.spooled
= False
;
2834 pjob
.devmode
= devmode
;
2836 fstrcpy(pjob
.jobname
, docname
);
2838 fstrcpy(pjob
.clientmachine
, clientmachine
);
2840 fstrcpy(pjob
.user
, lp_printjob_username(snum
));
2841 standard_sub_advanced(sharename
, server_info
->sanitized_username
,
2842 path
, server_info
->utok
.gid
,
2843 server_info
->sanitized_username
,
2844 server_info
->info3
->base
.domain
.string
,
2845 pjob
.user
, sizeof(pjob
.user
)-1);
2846 /* ensure NULL termination */
2847 pjob
.user
[sizeof(pjob
.user
)-1] = '\0';
2849 fstrcpy(pjob
.queuename
, lp_const_servicename(snum
));
2851 /* we have a job entry - now create the spool file */
2852 werr
= print_job_spool_file(snum
, jobid
, filename
, &pjob
);
2853 if (!W_ERROR_IS_OK(werr
)) {
2857 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, &pjob
);
2859 /* Update the 'jobs added' entry used by print_queue_status. */
2860 add_to_jobs_added(pdb
, jobid
);
2862 /* Ensure we keep a rough count of the number of total jobs... */
2863 tdb_change_int32_atomic(pdb
->tdb
, "INFO/total_jobs", &njobs
, 1);
2865 release_print_db(pdb
);
2872 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
2875 release_print_db(pdb
);
2877 DEBUG(3, ("print_job_start: returning fail. "
2878 "Error = %s\n", win_errstr(werr
)));
2882 /****************************************************************************
2883 Update the number of pages spooled to jobid
2884 ****************************************************************************/
2886 void print_job_endpage(struct messaging_context
*msg_ctx
,
2887 int snum
, uint32 jobid
)
2889 const char* sharename
= lp_const_servicename(snum
);
2890 struct printjob
*pjob
;
2892 pjob
= print_job_find(sharename
, jobid
);
2895 /* don't allow another process to get this info - it is meaningless */
2896 if (pjob
->pid
!= sys_getpid())
2900 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, pjob
);
2903 /****************************************************************************
2904 Print a file - called on closing the file. This spools the job.
2905 If normal close is false then we're tearing down the jobs - treat as an
2907 ****************************************************************************/
2909 NTSTATUS
print_job_end(struct messaging_context
*msg_ctx
, int snum
,
2910 uint32 jobid
, enum file_close_type close_type
)
2912 const char* sharename
= lp_const_servicename(snum
);
2913 struct printjob
*pjob
;
2915 SMB_STRUCT_STAT sbuf
;
2916 struct printif
*current_printif
= get_printer_fns( snum
);
2917 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
2919 pjob
= print_job_find(sharename
, jobid
);
2922 return NT_STATUS_PRINT_CANCELLED
;
2925 if (pjob
->spooled
|| pjob
->pid
!= sys_getpid()) {
2926 return 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 ret
= (*(current_printif
->job_submit
))(snum
, pjob
);
2983 status
= NT_STATUS_PRINT_CANCELLED
;
2987 /* The print job has been successfully handed over to the back-end */
2989 pjob
->spooled
= True
;
2990 pjob
->status
= LPQ_QUEUED
;
2991 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, pjob
);
2993 /* make sure the database is up to date */
2994 if (print_cache_expired(lp_const_servicename(snum
), True
))
2995 print_queue_update(msg_ctx
, snum
, False
);
2997 return NT_STATUS_OK
;
3001 /* The print job was not successfully started. Cleanup */
3002 /* Still need to add proper error return propagation! 010122:JRR */
3004 unlink(pjob
->filename
);
3005 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
3009 /****************************************************************************
3010 Get a snapshot of jobs in the system without traversing.
3011 ****************************************************************************/
3013 static bool get_stored_queue_info(struct messaging_context
*msg_ctx
,
3014 struct tdb_print_db
*pdb
, int snum
,
3015 int *pcount
, print_queue_struct
**ppqueue
)
3017 TDB_DATA data
, cgdata
, jcdata
;
3018 print_queue_struct
*queue
= NULL
;
3020 uint32 extra_count
= 0;
3021 uint32_t changed_count
= 0;
3022 int total_count
= 0;
3025 int max_reported_jobs
= lp_max_reported_jobs(snum
);
3027 const char* sharename
= lp_servicename(snum
);
3029 /* make sure the database is up to date */
3030 if (print_cache_expired(lp_const_servicename(snum
), True
))
3031 print_queue_update(msg_ctx
, snum
, False
);
3037 ZERO_STRUCT(cgdata
);
3039 /* Get the stored queue data. */
3040 data
= tdb_fetch(pdb
->tdb
, string_tdb_data("INFO/linear_queue_array"));
3042 if (data
.dptr
&& data
.dsize
>= sizeof(qcount
))
3043 len
+= tdb_unpack(data
.dptr
+ len
, data
.dsize
- len
, "d", &qcount
);
3045 /* Get the added jobs list. */
3046 cgdata
= tdb_fetch(pdb
->tdb
, string_tdb_data("INFO/jobs_added"));
3047 if (cgdata
.dptr
!= NULL
&& (cgdata
.dsize
% 4 == 0))
3048 extra_count
= cgdata
.dsize
/4;
3050 /* Get the changed jobs list. */
3051 jcdata
= tdb_fetch(pdb
->tdb
, string_tdb_data("INFO/jobs_changed"));
3052 if (jcdata
.dptr
!= NULL
&& (jcdata
.dsize
% 4 == 0))
3053 changed_count
= jcdata
.dsize
/ 4;
3055 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount
, (unsigned int)extra_count
));
3057 /* Allocate the queue size. */
3058 if (qcount
== 0 && extra_count
== 0)
3061 if ((queue
= SMB_MALLOC_ARRAY(print_queue_struct
, qcount
+ extra_count
)) == NULL
)
3064 /* Retrieve the linearised queue data. */
3066 for( i
= 0; i
< qcount
; i
++) {
3067 uint32 qjob
, qsize
, qpage_count
, qstatus
, qpriority
, qtime
;
3068 len
+= tdb_unpack(data
.dptr
+ len
, data
.dsize
- len
, "ddddddff",
3077 queue
[i
].job
= qjob
;
3078 queue
[i
].size
= qsize
;
3079 queue
[i
].page_count
= qpage_count
;
3080 queue
[i
].status
= qstatus
;
3081 queue
[i
].priority
= qpriority
;
3082 queue
[i
].time
= qtime
;
3085 total_count
= qcount
;
3087 /* Add new jobids to the queue. */
3088 for( i
= 0; i
< extra_count
; i
++) {
3090 struct printjob
*pjob
;
3092 jobid
= IVAL(cgdata
.dptr
, i
*4);
3093 DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid
));
3094 pjob
= print_job_find(lp_const_servicename(snum
), jobid
);
3096 DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid
));
3097 remove_from_jobs_added(sharename
, jobid
);
3101 queue
[total_count
].job
= jobid
;
3102 queue
[total_count
].size
= pjob
->size
;
3103 queue
[total_count
].page_count
= pjob
->page_count
;
3104 queue
[total_count
].status
= pjob
->status
;
3105 queue
[total_count
].priority
= 1;
3106 queue
[total_count
].time
= pjob
->starttime
;
3107 fstrcpy(queue
[total_count
].fs_user
, pjob
->user
);
3108 fstrcpy(queue
[total_count
].fs_file
, pjob
->jobname
);
3112 /* Update the changed jobids. */
3113 for (i
= 0; i
< changed_count
; i
++) {
3114 uint32_t jobid
= IVAL(jcdata
.dptr
, i
* 4);
3118 for (j
= 0; j
< total_count
; j
++) {
3119 if (queue
[j
].job
== jobid
) {
3126 struct printjob
*pjob
;
3128 DEBUG(5,("get_stored_queue_info: changed job: %u\n",
3129 (unsigned int) jobid
));
3131 pjob
= print_job_find(sharename
, jobid
);
3133 DEBUG(5,("get_stored_queue_info: failed to find "
3134 "changed job = %u\n",
3135 (unsigned int) jobid
));
3136 remove_from_jobs_changed(sharename
, jobid
);
3140 queue
[j
].job
= jobid
;
3141 queue
[j
].size
= pjob
->size
;
3142 queue
[j
].page_count
= pjob
->page_count
;
3143 queue
[j
].status
= pjob
->status
;
3144 queue
[j
].priority
= 1;
3145 queue
[j
].time
= pjob
->starttime
;
3146 fstrcpy(queue
[j
].fs_user
, pjob
->user
);
3147 fstrcpy(queue
[j
].fs_file
, pjob
->jobname
);
3149 DEBUG(5,("get_stored_queue_info: updated queue[%u], jobid: %u, jobname: %s\n",
3150 (unsigned int) j
, (unsigned int) jobid
, pjob
->jobname
));
3153 remove_from_jobs_changed(sharename
, jobid
);
3156 /* Sort the queue by submission time otherwise they are displayed
3159 TYPESAFE_QSORT(queue
, total_count
, printjob_comp
);
3161 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count
));
3163 if (max_reported_jobs
&& total_count
> max_reported_jobs
)
3164 total_count
= max_reported_jobs
;
3167 *pcount
= total_count
;
3173 SAFE_FREE(data
.dptr
);
3174 SAFE_FREE(cgdata
.dptr
);
3178 /****************************************************************************
3179 Get a printer queue listing.
3180 set queue = NULL and status = NULL if you just want to update the cache
3181 ****************************************************************************/
3183 int print_queue_status(struct messaging_context
*msg_ctx
, int snum
,
3184 print_queue_struct
**ppqueue
,
3185 print_status_struct
*status
)
3189 const char *sharename
;
3190 struct tdb_print_db
*pdb
;
3193 /* make sure the database is up to date */
3195 if (print_cache_expired(lp_const_servicename(snum
), True
))
3196 print_queue_update(msg_ctx
, snum
, False
);
3198 /* return if we are done */
3199 if ( !ppqueue
|| !status
)
3203 sharename
= lp_const_servicename(snum
);
3204 pdb
= get_print_db_byname(sharename
);
3210 * Fetch the queue status. We must do this first, as there may
3211 * be no jobs in the queue.
3214 ZERO_STRUCTP(status
);
3215 slprintf(keystr
, sizeof(keystr
)-1, "STATUS/%s", sharename
);
3216 key
= string_tdb_data(keystr
);
3218 data
= tdb_fetch(pdb
->tdb
, key
);
3220 if (data
.dsize
== sizeof(*status
)) {
3221 /* this memcpy is ok since the status struct was
3222 not packed before storing it in the tdb */
3223 memcpy(status
, data
.dptr
, sizeof(*status
));
3225 SAFE_FREE(data
.dptr
);
3229 * Now, fetch the print queue information. We first count the number
3230 * of entries, and then only retrieve the queue if necessary.
3233 if (!get_stored_queue_info(msg_ctx
, pdb
, snum
, &count
, ppqueue
)) {
3234 release_print_db(pdb
);
3238 release_print_db(pdb
);
3242 /****************************************************************************
3244 ****************************************************************************/
3246 WERROR
print_queue_pause(const struct auth_serversupplied_info
*server_info
,
3247 struct messaging_context
*msg_ctx
, int snum
)
3250 struct printif
*current_printif
= get_printer_fns( snum
);
3252 if (!print_access_check(server_info
, msg_ctx
, snum
,
3253 PRINTER_ACCESS_ADMINISTER
)) {
3254 return WERR_ACCESS_DENIED
;
3260 ret
= (*(current_printif
->queue_pause
))(snum
);
3265 return WERR_INVALID_PARAM
;
3268 /* force update the database */
3269 print_cache_flush(lp_const_servicename(snum
));
3271 /* Send a printer notify message */
3273 notify_printer_status(server_event_context(), msg_ctx
, snum
,
3274 PRINTER_STATUS_PAUSED
);
3279 /****************************************************************************
3281 ****************************************************************************/
3283 WERROR
print_queue_resume(const struct auth_serversupplied_info
*server_info
,
3284 struct messaging_context
*msg_ctx
, int snum
)
3287 struct printif
*current_printif
= get_printer_fns( snum
);
3289 if (!print_access_check(server_info
, msg_ctx
, snum
,
3290 PRINTER_ACCESS_ADMINISTER
)) {
3291 return WERR_ACCESS_DENIED
;
3296 ret
= (*(current_printif
->queue_resume
))(snum
);
3301 return WERR_INVALID_PARAM
;
3304 /* make sure the database is up to date */
3305 if (print_cache_expired(lp_const_servicename(snum
), True
))
3306 print_queue_update(msg_ctx
, snum
, True
);
3308 /* Send a printer notify message */
3310 notify_printer_status(server_event_context(), msg_ctx
, snum
,
3316 /****************************************************************************
3317 Purge a queue - implemented by deleting all jobs that we can delete.
3318 ****************************************************************************/
3320 WERROR
print_queue_purge(const struct auth_serversupplied_info
*server_info
,
3321 struct messaging_context
*msg_ctx
, int snum
)
3323 print_queue_struct
*queue
;
3324 print_status_struct status
;
3328 /* Force and update so the count is accurate (i.e. not a cached count) */
3329 print_queue_update(msg_ctx
, snum
, True
);
3331 can_job_admin
= print_access_check(server_info
,
3334 JOB_ACCESS_ADMINISTER
);
3335 njobs
= print_queue_status(msg_ctx
, snum
, &queue
, &status
);
3337 if ( can_job_admin
)
3340 for (i
=0;i
<njobs
;i
++) {
3341 bool owner
= is_owner(server_info
, lp_const_servicename(snum
),
3344 if (owner
|| can_job_admin
) {
3345 print_job_delete1(server_event_context(), msg_ctx
,
3346 snum
, queue
[i
].job
);
3350 if ( can_job_admin
)
3353 /* update the cache */
3354 print_queue_update(msg_ctx
, snum
, True
);