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"
37 extern struct current_user current_user
;
38 extern userdom_struct current_user_info
;
40 /* Current printer interface */
41 static bool remove_from_jobs_added(const char* sharename
, uint32 jobid
);
44 the printing backend revolves around a tdb database that stores the
45 SMB view of the print queue
47 The key for this database is a jobid - a internally generated number that
48 uniquely identifies a print job
50 reading the print queue involves two steps:
51 - possibly running lpq and updating the internal database from that
52 - reading entries from the database
54 jobids are assigned when a job starts spooling.
57 static TDB_CONTEXT
*rap_tdb
;
58 static uint16 next_rap_jobid
;
59 struct rap_jobid_key
{
64 /***************************************************************************
65 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
66 bit RPC jobids.... JRA.
67 ***************************************************************************/
69 uint16
pjobid_to_rap(const char* sharename
, uint32 jobid
)
73 struct rap_jobid_key jinfo
;
76 DEBUG(10,("pjobid_to_rap: called.\n"));
79 /* Create the in-memory tdb. */
80 rap_tdb
= tdb_open_log(NULL
, 0, TDB_INTERNAL
, (O_RDWR
|O_CREAT
), 0644);
86 fstrcpy( jinfo
.sharename
, sharename
);
88 key
.dptr
= (uint8
*)&jinfo
;
89 key
.dsize
= sizeof(jinfo
);
91 data
= tdb_fetch(rap_tdb
, key
);
92 if (data
.dptr
&& data
.dsize
== sizeof(uint16
)) {
93 rap_jobid
= SVAL(data
.dptr
, 0);
95 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
96 (unsigned int)jobid
, (unsigned int)rap_jobid
));
100 /* Not found - create and store mapping. */
101 rap_jobid
= ++next_rap_jobid
;
103 rap_jobid
= ++next_rap_jobid
;
104 SSVAL(buf
,0,rap_jobid
);
106 data
.dsize
= sizeof(rap_jobid
);
107 tdb_store(rap_tdb
, key
, data
, TDB_REPLACE
);
108 tdb_store(rap_tdb
, data
, key
, TDB_REPLACE
);
110 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
111 (unsigned int)jobid
, (unsigned int)rap_jobid
));
115 bool rap_to_pjobid(uint16 rap_jobid
, fstring sharename
, uint32
*pjobid
)
120 DEBUG(10,("rap_to_pjobid called.\n"));
125 SSVAL(buf
,0,rap_jobid
);
127 key
.dsize
= sizeof(rap_jobid
);
128 data
= tdb_fetch(rap_tdb
, key
);
129 if ( data
.dptr
&& data
.dsize
== sizeof(struct rap_jobid_key
) )
131 struct rap_jobid_key
*jinfo
= (struct rap_jobid_key
*)data
.dptr
;
132 if (sharename
!= NULL
) {
133 fstrcpy( sharename
, jinfo
->sharename
);
135 *pjobid
= jinfo
->jobid
;
136 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
137 (unsigned int)*pjobid
, (unsigned int)rap_jobid
));
138 SAFE_FREE(data
.dptr
);
142 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
143 (unsigned int)rap_jobid
));
144 SAFE_FREE(data
.dptr
);
148 void rap_jobid_delete(const char* sharename
, uint32 jobid
)
152 struct rap_jobid_key jinfo
;
155 DEBUG(10,("rap_jobid_delete: called.\n"));
160 ZERO_STRUCT( jinfo
);
161 fstrcpy( jinfo
.sharename
, sharename
);
163 key
.dptr
= (uint8
*)&jinfo
;
164 key
.dsize
= sizeof(jinfo
);
166 data
= tdb_fetch(rap_tdb
, key
);
167 if (!data
.dptr
|| (data
.dsize
!= sizeof(uint16
))) {
168 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
169 (unsigned int)jobid
));
170 SAFE_FREE(data
.dptr
);
174 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
175 (unsigned int)jobid
));
177 rap_jobid
= SVAL(data
.dptr
, 0);
178 SAFE_FREE(data
.dptr
);
179 SSVAL(buf
,0,rap_jobid
);
181 data
.dsize
= sizeof(rap_jobid
);
182 tdb_delete(rap_tdb
, key
);
183 tdb_delete(rap_tdb
, data
);
186 static int get_queue_status(const char* sharename
, print_status_struct
*);
188 /****************************************************************************
189 Initialise the printing backend. Called once at startup before the fork().
190 ****************************************************************************/
192 bool print_backend_init(struct messaging_context
*msg_ctx
)
194 const char *sversion
= "INFO/version";
195 int services
= lp_numservices();
198 unlink(cache_path("printing.tdb"));
199 mkdir(cache_path("printing"),0755);
201 /* handle a Samba upgrade */
203 for (snum
= 0; snum
< services
; snum
++) {
204 struct tdb_print_db
*pdb
;
205 if (!lp_print_ok(snum
))
208 pdb
= get_print_db_byname(lp_const_servicename(snum
));
211 if (tdb_lock_bystring(pdb
->tdb
, sversion
) == -1) {
212 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum
) ));
213 release_print_db(pdb
);
216 if (tdb_fetch_int32(pdb
->tdb
, sversion
) != PRINT_DATABASE_VERSION
) {
217 tdb_wipe_all(pdb
->tdb
);
218 tdb_store_int32(pdb
->tdb
, sversion
, PRINT_DATABASE_VERSION
);
220 tdb_unlock_bystring(pdb
->tdb
, sversion
);
221 release_print_db(pdb
);
224 close_all_print_db(); /* Don't leave any open. */
226 /* do NT print initialization... */
227 return nt_printing_init(msg_ctx
);
230 /****************************************************************************
231 Shut down printing backend. Called once at shutdown to close the tdb.
232 ****************************************************************************/
234 void printing_end(void)
236 close_all_print_db(); /* Don't leave any open. */
239 /****************************************************************************
240 Retrieve the set of printing functions for a given service. This allows
241 us to set the printer function table based on the value of the 'printing'
244 Use the generic interface as the default and only use cups interface only
245 when asked for (and only when supported)
246 ****************************************************************************/
248 static struct printif
*get_printer_fns_from_type( enum printing_types type
)
250 struct printif
*printer_fns
= &generic_printif
;
253 if ( type
== PRINT_CUPS
) {
254 printer_fns
= &cups_printif
;
256 #endif /* HAVE_CUPS */
259 if ( type
== PRINT_IPRINT
) {
260 printer_fns
= &iprint_printif
;
262 #endif /* HAVE_IPRINT */
264 printer_fns
->type
= type
;
269 static struct printif
*get_printer_fns( int snum
)
271 return get_printer_fns_from_type( (enum printing_types
)lp_printing(snum
) );
275 /****************************************************************************
276 Useful function to generate a tdb key.
277 ****************************************************************************/
279 static TDB_DATA
print_key(uint32 jobid
, uint32
*tmp
)
283 SIVAL(tmp
, 0, jobid
);
284 ret
.dptr
= (uint8
*)tmp
;
285 ret
.dsize
= sizeof(*tmp
);
289 /****************************************************************************
290 Pack the devicemode to store it in a tdb.
291 ****************************************************************************/
292 static int pack_devicemode(struct spoolss_DeviceMode
*devmode
, uint8
*buf
, int buflen
)
294 enum ndr_err_code ndr_err
;
299 ndr_err
= ndr_push_struct_blob(&blob
, talloc_tos(),
301 (ndr_push_flags_fn_t
)
302 ndr_push_spoolss_DeviceMode
);
303 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
304 DEBUG(10, ("pack_devicemode: "
305 "error encoding spoolss_DeviceMode\n"));
312 len
= tdb_pack(buf
, buflen
, "B", blob
.length
, blob
.data
);
315 DEBUG(8, ("Packed devicemode [%s]\n", devmode
->formname
));
322 /****************************************************************************
323 Unpack the devicemode to store it in a tdb.
324 ****************************************************************************/
325 static int unpack_devicemode(TALLOC_CTX
*mem_ctx
,
326 const uint8
*buf
, int buflen
,
327 struct spoolss_DeviceMode
**devmode
)
329 struct spoolss_DeviceMode
*dm
;
330 enum ndr_err_code ndr_err
;
338 len
= tdb_unpack(buf
, buflen
, "B", &data_len
, &data
);
343 dm
= talloc_zero(mem_ctx
, struct spoolss_DeviceMode
);
348 blob
= data_blob_const(data
, data_len
);
350 ndr_err
= ndr_pull_struct_blob(&blob
, dm
, dm
,
351 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_DeviceMode
);
352 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
353 DEBUG(10, ("unpack_devicemode: "
354 "error parsing spoolss_DeviceMode\n"));
358 DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
359 dm
->devicename
, dm
->formname
));
360 if (dm
->driverextra_data
.data
) {
361 DEBUG(8, ("with a private section of %d bytes\n",
362 dm
->__driverextra_length
));
372 /***********************************************************************
373 unpack a pjob from a tdb buffer
374 ***********************************************************************/
376 static int unpack_pjob( uint8
*buf
, int buflen
, struct printjob
*pjob
)
380 uint32 pjpid
, pjsysjob
, pjfd
, pjstarttime
, pjstatus
;
381 uint32 pjsize
, pjpage_count
, pjspooled
, pjsmbjob
;
386 len
+= tdb_unpack(buf
+len
, buflen
-len
, "dddddddddfffff",
405 used
= unpack_devicemode(NULL
, buf
+len
, buflen
-len
, &pjob
->devmode
);
413 pjob
->sysjob
= pjsysjob
;
415 pjob
->starttime
= pjstarttime
;
416 pjob
->status
= pjstatus
;
418 pjob
->page_count
= pjpage_count
;
419 pjob
->spooled
= pjspooled
;
420 pjob
->smbjob
= pjsmbjob
;
426 /****************************************************************************
427 Useful function to find a print job in the database.
428 ****************************************************************************/
430 static struct printjob
*print_job_find(const char *sharename
, uint32 jobid
)
432 static struct printjob pjob
;
435 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
437 DEBUG(10,("print_job_find: looking up job %u for share %s\n",
438 (unsigned int)jobid
, sharename
));
444 ret
= tdb_fetch(pdb
->tdb
, print_key(jobid
, &tmp
));
445 release_print_db(pdb
);
448 DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid
));
452 talloc_free(pjob
.devmode
);
456 if ( unpack_pjob( ret
.dptr
, ret
.dsize
, &pjob
) == -1 ) {
457 DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid
));
464 DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
465 (int)pjob
.sysjob
, (unsigned int)jobid
));
470 /* Convert a unix jobid to a smb jobid */
472 struct unixjob_traverse_state
{
474 uint32 sysjob_to_jobid_value
;
477 static int unixjob_traverse_fn(TDB_CONTEXT
*the_tdb
, TDB_DATA key
,
478 TDB_DATA data
, void *private_data
)
480 struct printjob
*pjob
;
481 struct unixjob_traverse_state
*state
=
482 (struct unixjob_traverse_state
*)private_data
;
484 if (!data
.dptr
|| data
.dsize
== 0)
487 pjob
= (struct printjob
*)data
.dptr
;
488 if (key
.dsize
!= sizeof(uint32
))
491 if (state
->sysjob
== pjob
->sysjob
) {
492 uint32 jobid
= IVAL(key
.dptr
,0);
494 state
->sysjob_to_jobid_value
= jobid
;
501 /****************************************************************************
502 This is a *horribly expensive call as we have to iterate through all the
503 current printer tdb's. Don't do this often ! JRA.
504 ****************************************************************************/
506 uint32
sysjob_to_jobid(int unix_jobid
)
508 int services
= lp_numservices();
510 struct unixjob_traverse_state state
;
512 state
.sysjob
= unix_jobid
;
513 state
.sysjob_to_jobid_value
= (uint32
)-1;
515 for (snum
= 0; snum
< services
; snum
++) {
516 struct tdb_print_db
*pdb
;
517 if (!lp_print_ok(snum
))
519 pdb
= get_print_db_byname(lp_const_servicename(snum
));
523 tdb_traverse(pdb
->tdb
, unixjob_traverse_fn
, &state
);
524 release_print_db(pdb
);
525 if (state
.sysjob_to_jobid_value
!= (uint32
)-1)
526 return state
.sysjob_to_jobid_value
;
531 /****************************************************************************
532 Send notifications based on what has changed after a pjob_store.
533 ****************************************************************************/
535 static const struct {
537 uint32_t spoolss_status
;
538 } lpq_to_spoolss_status_map
[] = {
539 { LPQ_QUEUED
, JOB_STATUS_QUEUED
},
540 { LPQ_PAUSED
, JOB_STATUS_PAUSED
},
541 { LPQ_SPOOLING
, JOB_STATUS_SPOOLING
},
542 { LPQ_PRINTING
, JOB_STATUS_PRINTING
},
543 { LPQ_DELETING
, JOB_STATUS_DELETING
},
544 { LPQ_OFFLINE
, JOB_STATUS_OFFLINE
},
545 { LPQ_PAPEROUT
, JOB_STATUS_PAPEROUT
},
546 { LPQ_PRINTED
, JOB_STATUS_PRINTED
},
547 { LPQ_DELETED
, JOB_STATUS_DELETED
},
548 { LPQ_BLOCKED
, JOB_STATUS_BLOCKED_DEVQ
},
549 { LPQ_USER_INTERVENTION
, JOB_STATUS_USER_INTERVENTION
},
553 /* Convert a lpq status value stored in printing.tdb into the
554 appropriate win32 API constant. */
556 static uint32
map_to_spoolss_status(uint32 lpq_status
)
560 while (lpq_to_spoolss_status_map
[i
].lpq_status
!= -1) {
561 if (lpq_to_spoolss_status_map
[i
].lpq_status
== lpq_status
)
562 return lpq_to_spoolss_status_map
[i
].spoolss_status
;
569 /***************************************************************************
570 Append a jobid to the 'jobs changed' list.
571 ***************************************************************************/
573 static bool add_to_jobs_changed(struct tdb_print_db
*pdb
, uint32_t jobid
)
576 uint32_t store_jobid
;
578 SIVAL(&store_jobid
, 0, jobid
);
579 data
.dptr
= (uint8
*) &store_jobid
;
582 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid
));
584 return (tdb_append(pdb
->tdb
, string_tdb_data("INFO/jobs_changed"),
588 /***************************************************************************
589 Remove a jobid from the 'jobs changed' list.
590 ***************************************************************************/
592 static bool remove_from_jobs_changed(const char* sharename
, uint32_t jobid
)
594 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
598 bool gotlock
= False
;
606 key
= string_tdb_data("INFO/jobs_changed");
608 if (tdb_chainlock_with_timeout(pdb
->tdb
, key
, 5) == -1)
613 data
= tdb_fetch(pdb
->tdb
, key
);
615 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0))
618 job_count
= data
.dsize
/ 4;
619 for (i
= 0; i
< job_count
; i
++) {
622 ch_jobid
= IVAL(data
.dptr
, i
*4);
623 if (ch_jobid
== jobid
) {
624 if (i
< job_count
-1 )
625 memmove(data
.dptr
+ (i
*4), data
.dptr
+ (i
*4) + 4, (job_count
- i
- 1)*4 );
627 if (tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
) == -1)
637 tdb_chainunlock(pdb
->tdb
, key
);
638 SAFE_FREE(data
.dptr
);
639 release_print_db(pdb
);
641 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid
));
643 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid
));
647 static void pjob_store_notify(struct tevent_context
*ev
,
648 struct messaging_context
*msg_ctx
,
649 const char* sharename
, uint32 jobid
,
650 struct printjob
*old_data
,
651 struct printjob
*new_data
,
654 bool new_job
= false;
655 bool changed
= false;
657 if (old_data
== NULL
) {
661 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
662 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
663 time first or else we'll end up with potential alignment
664 errors. I don't think the systemtime should be spooled as
665 a string, but this gets us around that error.
666 --jerry (i'll feel dirty for this) */
669 notify_job_submitted(ev
, msg_ctx
,
670 sharename
, jobid
, new_data
->starttime
);
671 notify_job_username(ev
, msg_ctx
,
672 sharename
, jobid
, new_data
->user
);
673 notify_job_name(ev
, msg_ctx
,
674 sharename
, jobid
, new_data
->jobname
);
675 notify_job_status(ev
, msg_ctx
,
676 sharename
, jobid
, map_to_spoolss_status(new_data
->status
));
677 notify_job_total_bytes(ev
, msg_ctx
,
678 sharename
, jobid
, new_data
->size
);
679 notify_job_total_pages(ev
, msg_ctx
,
680 sharename
, jobid
, new_data
->page_count
);
682 if (!strequal(old_data
->jobname
, new_data
->jobname
)) {
683 notify_job_name(ev
, msg_ctx
, sharename
,
684 jobid
, new_data
->jobname
);
688 if (old_data
->status
!= new_data
->status
) {
689 notify_job_status(ev
, msg_ctx
,
691 map_to_spoolss_status(new_data
->status
));
694 if (old_data
->size
!= new_data
->size
) {
695 notify_job_total_bytes(ev
, msg_ctx
,
696 sharename
, jobid
, new_data
->size
);
699 if (old_data
->page_count
!= new_data
->page_count
) {
700 notify_job_total_pages(ev
, msg_ctx
,
702 new_data
->page_count
);
709 /****************************************************************************
710 Store a job structure back to the database.
711 ****************************************************************************/
713 static bool pjob_store(struct tevent_context
*ev
,
714 struct messaging_context
*msg_ctx
,
715 const char* sharename
, uint32 jobid
,
716 struct printjob
*pjob
)
719 TDB_DATA old_data
, new_data
;
721 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
723 int len
, newlen
, buflen
;
731 old_data
= tdb_fetch(pdb
->tdb
, print_key(jobid
, &tmp
));
733 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
740 len
+= tdb_pack(buf
+len
, buflen
-len
, "dddddddddfffff",
742 (uint32
)pjob
->sysjob
,
744 (uint32
)pjob
->starttime
,
745 (uint32
)pjob
->status
,
747 (uint32
)pjob
->page_count
,
748 (uint32
)pjob
->spooled
,
749 (uint32
)pjob
->smbjob
,
756 len
+= pack_devicemode(pjob
->devmode
, buf
+len
, buflen
-len
);
759 buf
= (uint8
*)SMB_REALLOC(buf
, len
);
761 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
766 } while ( buflen
!= len
);
772 new_data
.dsize
= len
;
773 ret
= (tdb_store(pdb
->tdb
, print_key(jobid
, &tmp
), new_data
,
776 /* Send notify updates for what has changed */
779 bool changed
= false;
780 struct printjob old_pjob
;
782 if ( old_data
.dsize
)
784 if ( unpack_pjob( old_data
.dptr
, old_data
.dsize
, &old_pjob
) != -1 )
786 pjob_store_notify(server_event_context(),
788 sharename
, jobid
, &old_pjob
,
791 talloc_free(old_pjob
.devmode
);
794 add_to_jobs_changed(pdb
, jobid
);
801 pjob_store_notify(server_event_context(), msg_ctx
,
802 sharename
, jobid
, NULL
, pjob
,
807 release_print_db(pdb
);
809 SAFE_FREE( old_data
.dptr
);
815 /****************************************************************************
816 Remove a job structure from the database.
817 ****************************************************************************/
819 static void pjob_delete(struct tevent_context
*ev
,
820 struct messaging_context
*msg_ctx
,
821 const char* sharename
, uint32 jobid
)
824 struct printjob
*pjob
;
825 uint32 job_status
= 0;
826 struct tdb_print_db
*pdb
;
828 pdb
= get_print_db_byname( sharename
);
833 pjob
= print_job_find( sharename
, jobid
);
836 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
837 (unsigned int)jobid
));
838 release_print_db(pdb
);
842 /* We must cycle through JOB_STATUS_DELETING and
843 JOB_STATUS_DELETED for the port monitor to delete the job
846 job_status
= JOB_STATUS_DELETING
|JOB_STATUS_DELETED
;
847 notify_job_status(ev
, msg_ctx
, sharename
, jobid
, job_status
);
849 /* Remove from printing.tdb */
851 tdb_delete(pdb
->tdb
, print_key(jobid
, &tmp
));
852 remove_from_jobs_added(sharename
, jobid
);
853 release_print_db( pdb
);
854 rap_jobid_delete(sharename
, jobid
);
857 /****************************************************************************
858 List a unix job in the print database.
859 ****************************************************************************/
861 static void print_unix_job(struct tevent_context
*ev
,
862 struct messaging_context
*msg_ctx
,
863 const char *sharename
, print_queue_struct
*q
,
866 struct printjob pj
, *old_pj
;
868 if (jobid
== (uint32
)-1)
869 jobid
= q
->job
+ UNIX_JOB_START
;
871 /* Preserve the timestamp on an existing unix print job */
873 old_pj
= print_job_find(sharename
, jobid
);
880 pj
.starttime
= old_pj
? old_pj
->starttime
: q
->time
;
881 pj
.status
= q
->status
;
884 fstrcpy(pj
.filename
, old_pj
? old_pj
->filename
: "");
885 if (jobid
< UNIX_JOB_START
) {
887 fstrcpy(pj
.jobname
, old_pj
? old_pj
->jobname
: "Remote Downlevel Document");
890 fstrcpy(pj
.jobname
, old_pj
? old_pj
->jobname
: q
->fs_file
);
892 fstrcpy(pj
.user
, old_pj
? old_pj
->user
: q
->fs_user
);
893 fstrcpy(pj
.queuename
, old_pj
? old_pj
->queuename
: sharename
);
895 pjob_store(ev
, msg_ctx
, sharename
, jobid
, &pj
);
899 struct traverse_struct
{
900 print_queue_struct
*queue
;
901 int qcount
, snum
, maxcount
, total_jobs
;
902 const char *sharename
;
904 const char *lprm_command
;
905 struct printif
*print_if
;
906 struct tevent_context
*ev
;
907 struct messaging_context
*msg_ctx
;
910 /****************************************************************************
911 Utility fn to delete any jobs that are no longer active.
912 ****************************************************************************/
914 static int traverse_fn_delete(TDB_CONTEXT
*t
, TDB_DATA key
, TDB_DATA data
, void *state
)
916 struct traverse_struct
*ts
= (struct traverse_struct
*)state
;
917 struct printjob pjob
;
921 if ( key
.dsize
!= sizeof(jobid
) )
924 jobid
= IVAL(key
.dptr
, 0);
925 if ( unpack_pjob( data
.dptr
, data
.dsize
, &pjob
) == -1 )
927 talloc_free(pjob
.devmode
);
931 /* remove a unix job if it isn't in the system queue any more */
933 for (i
=0;i
<ts
->qcount
;i
++) {
934 uint32 u_jobid
= (ts
->queue
[i
].job
+ UNIX_JOB_START
);
935 if (jobid
== u_jobid
)
938 if (i
== ts
->qcount
) {
939 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
940 (unsigned int)jobid
));
941 pjob_delete(ts
->ev
, ts
->msg_ctx
,
942 ts
->sharename
, jobid
);
946 /* need to continue the the bottom of the function to
947 save the correct attributes */
950 /* maybe it hasn't been spooled yet */
952 /* if a job is not spooled and the process doesn't
953 exist then kill it. This cleans up after smbd
955 if (!process_exists_by_pid(pjob
.pid
)) {
956 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
957 (unsigned int)jobid
, (unsigned int)pjob
.pid
));
958 pjob_delete(ts
->ev
, ts
->msg_ctx
,
959 ts
->sharename
, jobid
);
965 /* this check only makes sense for jobs submitted from Windows clients */
968 for (i
=0;i
<ts
->qcount
;i
++) {
971 if ( pjob
.status
== LPQ_DELETED
)
974 curr_jobid
= print_parse_jobid(ts
->queue
[i
].fs_file
);
976 if (jobid
== curr_jobid
) {
978 /* try to clean up any jobs that need to be deleted */
980 if ( pjob
.status
== LPQ_DELETING
) {
983 result
= (*(ts
->print_if
->job_delete
))(
984 ts
->sharename
, ts
->lprm_command
, &pjob
);
987 /* if we can't delete, then reset the job status */
988 pjob
.status
= LPQ_QUEUED
;
989 pjob_store(ts
->ev
, ts
->msg_ctx
,
990 ts
->sharename
, jobid
, &pjob
);
993 /* if we deleted the job, the remove the tdb record */
996 ts
->sharename
, jobid
);
997 pjob
.status
= LPQ_DELETED
;
1007 /* The job isn't in the system queue - we have to assume it has
1008 completed, so delete the database entry. */
1010 if (i
== ts
->qcount
) {
1012 /* A race can occur between the time a job is spooled and
1013 when it appears in the lpq output. This happens when
1014 the job is added to printing.tdb when another smbd
1015 running print_queue_update() has completed a lpq and
1016 is currently traversing the printing tdb and deleting jobs.
1017 Don't delete the job if it was submitted after the lpq_time. */
1019 if (pjob
.starttime
< ts
->lpq_time
) {
1020 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
1021 (unsigned int)jobid
,
1022 (unsigned int)pjob
.starttime
,
1023 (unsigned int)ts
->lpq_time
));
1024 pjob_delete(ts
->ev
, ts
->msg_ctx
,
1025 ts
->sharename
, jobid
);
1031 /* Save the pjob attributes we will store.
1032 FIXME!!! This is the only place where queue->job
1033 represents the SMB jobid --jerry */
1035 ts
->queue
[i
].job
= jobid
;
1036 ts
->queue
[i
].size
= pjob
.size
;
1037 ts
->queue
[i
].page_count
= pjob
.page_count
;
1038 ts
->queue
[i
].status
= pjob
.status
;
1039 ts
->queue
[i
].priority
= 1;
1040 ts
->queue
[i
].time
= pjob
.starttime
;
1041 fstrcpy(ts
->queue
[i
].fs_user
, pjob
.user
);
1042 fstrcpy(ts
->queue
[i
].fs_file
, pjob
.jobname
);
1049 /****************************************************************************
1050 Check if the print queue has been updated recently enough.
1051 ****************************************************************************/
1053 static void print_cache_flush(const char *sharename
)
1056 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1060 slprintf(key
, sizeof(key
)-1, "CACHE/%s", sharename
);
1061 tdb_store_int32(pdb
->tdb
, key
, -1);
1062 release_print_db(pdb
);
1065 /****************************************************************************
1066 Check if someone already thinks they are doing the update.
1067 ****************************************************************************/
1069 static pid_t
get_updating_pid(const char *sharename
)
1074 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1078 slprintf(keystr
, sizeof(keystr
)-1, "UPDATING/%s", sharename
);
1079 key
= string_tdb_data(keystr
);
1081 data
= tdb_fetch(pdb
->tdb
, key
);
1082 release_print_db(pdb
);
1083 if (!data
.dptr
|| data
.dsize
!= sizeof(pid_t
)) {
1084 SAFE_FREE(data
.dptr
);
1088 updating_pid
= IVAL(data
.dptr
, 0);
1089 SAFE_FREE(data
.dptr
);
1091 if (process_exists_by_pid(updating_pid
))
1092 return updating_pid
;
1097 /****************************************************************************
1098 Set the fact that we're doing the update, or have finished doing the update
1100 ****************************************************************************/
1102 static void set_updating_pid(const fstring sharename
, bool updating
)
1107 pid_t updating_pid
= sys_getpid();
1110 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1115 slprintf(keystr
, sizeof(keystr
)-1, "UPDATING/%s", sharename
);
1116 key
= string_tdb_data(keystr
);
1118 DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
1119 updating
? "" : "not ",
1123 tdb_delete(pdb
->tdb
, key
);
1124 release_print_db(pdb
);
1128 SIVAL( buffer
, 0, updating_pid
);
1130 data
.dsize
= 4; /* we always assume this is a 4 byte value */
1132 tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
);
1133 release_print_db(pdb
);
1136 /****************************************************************************
1137 Sort print jobs by submittal time.
1138 ****************************************************************************/
1140 static int printjob_comp(print_queue_struct
*j1
, print_queue_struct
*j2
)
1151 /* Sort on job start time */
1153 if (j1
->time
== j2
->time
)
1155 return (j1
->time
> j2
->time
) ? 1 : -1;
1158 /****************************************************************************
1159 Store the sorted queue representation for later portmon retrieval.
1161 ****************************************************************************/
1163 static void store_queue_struct(struct tdb_print_db
*pdb
, struct traverse_struct
*pts
)
1166 int max_reported_jobs
= lp_max_reported_jobs(pts
->snum
);
1167 print_queue_struct
*queue
= pts
->queue
;
1170 unsigned int qcount
;
1172 if (max_reported_jobs
&& (max_reported_jobs
< pts
->qcount
))
1173 pts
->qcount
= max_reported_jobs
;
1176 /* Work out the size. */
1178 data
.dsize
+= tdb_pack(NULL
, 0, "d", qcount
);
1180 for (i
= 0; i
< pts
->qcount
; i
++) {
1181 if ( queue
[i
].status
== LPQ_DELETED
)
1185 data
.dsize
+= tdb_pack(NULL
, 0, "ddddddff",
1186 (uint32
)queue
[i
].job
,
1187 (uint32
)queue
[i
].size
,
1188 (uint32
)queue
[i
].page_count
,
1189 (uint32
)queue
[i
].status
,
1190 (uint32
)queue
[i
].priority
,
1191 (uint32
)queue
[i
].time
,
1196 if ((data
.dptr
= (uint8
*)SMB_MALLOC(data
.dsize
)) == NULL
)
1200 len
+= tdb_pack(data
.dptr
+ len
, data
.dsize
- len
, "d", qcount
);
1201 for (i
= 0; i
< pts
->qcount
; i
++) {
1202 if ( queue
[i
].status
== LPQ_DELETED
)
1205 len
+= tdb_pack(data
.dptr
+ len
, data
.dsize
- len
, "ddddddff",
1206 (uint32
)queue
[i
].job
,
1207 (uint32
)queue
[i
].size
,
1208 (uint32
)queue
[i
].page_count
,
1209 (uint32
)queue
[i
].status
,
1210 (uint32
)queue
[i
].priority
,
1211 (uint32
)queue
[i
].time
,
1216 tdb_store(pdb
->tdb
, string_tdb_data("INFO/linear_queue_array"), data
,
1218 SAFE_FREE(data
.dptr
);
1222 static TDB_DATA
get_jobs_added_data(struct tdb_print_db
*pdb
)
1228 data
= tdb_fetch(pdb
->tdb
, string_tdb_data("INFO/jobs_added"));
1229 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0)) {
1230 SAFE_FREE(data
.dptr
);
1237 static void check_job_added(const char *sharename
, TDB_DATA data
, uint32 jobid
)
1240 unsigned int job_count
= data
.dsize
/ 4;
1242 for (i
= 0; i
< job_count
; i
++) {
1245 ch_jobid
= IVAL(data
.dptr
, i
*4);
1246 if (ch_jobid
== jobid
)
1247 remove_from_jobs_added(sharename
, jobid
);
1251 /****************************************************************************
1252 Check if the print queue has been updated recently enough.
1253 ****************************************************************************/
1255 static bool print_cache_expired(const char *sharename
, bool check_pending
)
1258 time_t last_qscan_time
, time_now
= time(NULL
);
1259 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1260 bool result
= False
;
1265 snprintf(key
, sizeof(key
), "CACHE/%s", sharename
);
1266 last_qscan_time
= (time_t)tdb_fetch_int32(pdb
->tdb
, key
);
1269 * Invalidate the queue for 3 reasons.
1270 * (1). last queue scan time == -1.
1271 * (2). Current time - last queue scan time > allowed cache time.
1272 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1273 * This last test picks up machines for which the clock has been moved
1274 * forward, an lpq scan done and then the clock moved back. Otherwise
1275 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1278 if (last_qscan_time
== ((time_t)-1)
1279 || (time_now
- last_qscan_time
) >= lp_lpqcachetime()
1280 || last_qscan_time
> (time_now
+ MAX_CACHE_VALID_TIME
))
1283 time_t msg_pending_time
;
1285 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1286 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1287 sharename
, (int)last_qscan_time
, (int)time_now
,
1288 (int)lp_lpqcachetime() ));
1290 /* check if another smbd has already sent a message to update the
1291 queue. Give the pending message one minute to clear and
1292 then send another message anyways. Make sure to check for
1293 clocks that have been run forward and then back again. */
1295 snprintf(key
, sizeof(key
), "MSG_PENDING/%s", sharename
);
1298 && tdb_fetch_uint32( pdb
->tdb
, key
, &u
)
1299 && (msg_pending_time
=u
) > 0
1300 && msg_pending_time
<= time_now
1301 && (time_now
- msg_pending_time
) < 60 )
1303 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1312 release_print_db(pdb
);
1316 /****************************************************************************
1317 main work for updating the lpq cache for a printer queue
1318 ****************************************************************************/
1320 static void print_queue_update_internal( struct tevent_context
*ev
,
1321 struct messaging_context
*msg_ctx
,
1322 const char *sharename
,
1323 struct printif
*current_printif
,
1324 char *lpq_command
, char *lprm_command
)
1327 print_queue_struct
*queue
= NULL
;
1328 print_status_struct status
;
1329 print_status_struct old_status
;
1330 struct printjob
*pjob
;
1331 struct traverse_struct tstruct
;
1334 fstring keystr
, cachestr
;
1335 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1341 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1342 sharename
, current_printif
->type
, lpq_command
));
1345 * Update the cache time FIRST ! Stops others even
1346 * attempting to get the lock and doing this
1347 * if the lpq takes a long time.
1350 slprintf(cachestr
, sizeof(cachestr
)-1, "CACHE/%s", sharename
);
1351 tdb_store_int32(pdb
->tdb
, cachestr
, (int)time(NULL
));
1353 /* get the current queue using the appropriate interface */
1354 ZERO_STRUCT(status
);
1356 qcount
= (*(current_printif
->queue_get
))(sharename
,
1357 current_printif
->type
,
1358 lpq_command
, &queue
, &status
);
1360 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1361 qcount
, (qcount
!= 1) ? "s" : "", sharename
));
1363 /* Sort the queue by submission time otherwise they are displayed
1366 TYPESAFE_QSORT(queue
, qcount
, printjob_comp
);
1369 any job in the internal database that is marked as spooled
1370 and doesn't exist in the system queue is considered finished
1371 and removed from the database
1373 any job in the system database but not in the internal database
1374 is added as a unix job
1376 fill in any system job numbers as we go
1379 jcdata
= get_jobs_added_data(pdb
);
1381 for (i
=0; i
<qcount
; i
++) {
1382 uint32 jobid
= print_parse_jobid(queue
[i
].fs_file
);
1384 if (jobid
== (uint32
)-1) {
1385 /* assume its a unix print job */
1386 print_unix_job(ev
, msg_ctx
,
1387 sharename
, &queue
[i
], jobid
);
1391 /* we have an active SMB print job - update its status */
1392 pjob
= print_job_find(sharename
, jobid
);
1394 /* err, somethings wrong. Probably smbd was restarted
1395 with jobs in the queue. All we can do is treat them
1396 like unix jobs. Pity. */
1397 print_unix_job(ev
, msg_ctx
,
1398 sharename
, &queue
[i
], jobid
);
1402 pjob
->sysjob
= queue
[i
].job
;
1404 /* don't reset the status on jobs to be deleted */
1406 if ( pjob
->status
!= LPQ_DELETING
)
1407 pjob
->status
= queue
[i
].status
;
1409 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
1411 check_job_added(sharename
, jcdata
, jobid
);
1414 SAFE_FREE(jcdata
.dptr
);
1416 /* now delete any queued entries that don't appear in the
1418 tstruct
.queue
= queue
;
1419 tstruct
.qcount
= qcount
;
1421 tstruct
.total_jobs
= 0;
1422 tstruct
.lpq_time
= time(NULL
);
1423 tstruct
.sharename
= sharename
;
1424 tstruct
.lprm_command
= lprm_command
;
1425 tstruct
.print_if
= current_printif
;
1427 tstruct
.msg_ctx
= msg_ctx
;
1429 tdb_traverse(pdb
->tdb
, traverse_fn_delete
, (void *)&tstruct
);
1431 /* Store the linearised queue, max jobs only. */
1432 store_queue_struct(pdb
, &tstruct
);
1434 SAFE_FREE(tstruct
.queue
);
1436 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1437 sharename
, tstruct
.total_jobs
));
1439 tdb_store_int32(pdb
->tdb
, "INFO/total_jobs", tstruct
.total_jobs
);
1441 get_queue_status(sharename
, &old_status
);
1442 if (old_status
.qcount
!= qcount
)
1443 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1444 old_status
.qcount
, qcount
, sharename
));
1446 /* store the new queue status structure */
1447 slprintf(keystr
, sizeof(keystr
)-1, "STATUS/%s", sharename
);
1448 key
= string_tdb_data(keystr
);
1450 status
.qcount
= qcount
;
1451 data
.dptr
= (uint8
*)&status
;
1452 data
.dsize
= sizeof(status
);
1453 tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
);
1456 * Update the cache time again. We want to do this call
1457 * as little as possible...
1460 slprintf(keystr
, sizeof(keystr
)-1, "CACHE/%s", sharename
);
1461 tdb_store_int32(pdb
->tdb
, keystr
, (int32
)time(NULL
));
1463 /* clear the msg pending record for this queue */
1465 snprintf(keystr
, sizeof(keystr
), "MSG_PENDING/%s", sharename
);
1467 if ( !tdb_store_uint32( pdb
->tdb
, keystr
, 0 ) ) {
1468 /* log a message but continue on */
1470 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1474 release_print_db( pdb
);
1479 /****************************************************************************
1480 Update the internal database from the system print queue for a queue.
1481 obtain a lock on the print queue before proceeding (needed when mutiple
1482 smbd processes maytry to update the lpq cache concurrently).
1483 ****************************************************************************/
1485 static void print_queue_update_with_lock( struct tevent_context
*ev
,
1486 struct messaging_context
*msg_ctx
,
1487 const char *sharename
,
1488 struct printif
*current_printif
,
1489 char *lpq_command
, char *lprm_command
)
1492 struct tdb_print_db
*pdb
;
1494 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename
));
1495 pdb
= get_print_db_byname(sharename
);
1499 if ( !print_cache_expired(sharename
, False
) ) {
1500 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename
));
1501 release_print_db(pdb
);
1506 * Check to see if someone else is doing this update.
1507 * This is essentially a mutex on the update.
1510 if (get_updating_pid(sharename
) != -1) {
1511 release_print_db(pdb
);
1515 /* Lock the queue for the database update */
1517 slprintf(keystr
, sizeof(keystr
) - 1, "LOCK/%s", sharename
);
1518 /* Only wait 10 seconds for this. */
1519 if (tdb_lock_bystring_with_timeout(pdb
->tdb
, keystr
, 10) == -1) {
1520 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename
));
1521 release_print_db(pdb
);
1526 * Ensure that no one else got in here.
1527 * If the updating pid is still -1 then we are
1531 if (get_updating_pid(sharename
) != -1) {
1533 * Someone else is doing the update, exit.
1535 tdb_unlock_bystring(pdb
->tdb
, keystr
);
1536 release_print_db(pdb
);
1541 * We're going to do the update ourselves.
1544 /* Tell others we're doing the update. */
1545 set_updating_pid(sharename
, True
);
1548 * Allow others to enter and notice we're doing
1552 tdb_unlock_bystring(pdb
->tdb
, keystr
);
1554 /* do the main work now */
1556 print_queue_update_internal(ev
, msg_ctx
,
1557 sharename
, current_printif
,
1558 lpq_command
, lprm_command
);
1560 /* Delete our pid from the db. */
1561 set_updating_pid(sharename
, False
);
1562 release_print_db(pdb
);
1565 /****************************************************************************
1566 this is the receive function of the background lpq updater
1567 ****************************************************************************/
1568 void print_queue_receive(struct messaging_context
*msg
,
1571 struct server_id server_id
,
1575 char *lpqcommand
= NULL
, *lprmcommand
= NULL
;
1579 len
= tdb_unpack( (uint8
*)data
->data
, data
->length
, "fdPP",
1586 SAFE_FREE(lpqcommand
);
1587 SAFE_FREE(lprmcommand
);
1588 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1592 print_queue_update_with_lock(server_event_context(), msg
, sharename
,
1593 get_printer_fns_from_type((enum printing_types
)printing_type
),
1594 lpqcommand
, lprmcommand
);
1596 SAFE_FREE(lpqcommand
);
1597 SAFE_FREE(lprmcommand
);
1601 static void printing_pause_fd_handler(struct tevent_context
*ev
,
1602 struct tevent_fd
*fde
,
1607 * If pause_pipe[1] is closed it means the parent smbd
1608 * and children exited or aborted.
1610 exit_server_cleanly(NULL
);
1613 extern struct child_pid
*children
;
1614 extern int num_children
;
1616 static void add_child_pid(pid_t pid
)
1618 struct child_pid
*child
;
1620 child
= SMB_MALLOC_P(struct child_pid
);
1621 if (child
== NULL
) {
1622 DEBUG(0, ("Could not add child struct -- malloc failed\n"));
1626 DLIST_ADD(children
, child
);
1630 static pid_t background_lpq_updater_pid
= -1;
1632 /****************************************************************************
1633 main thread of the background lpq updater
1634 ****************************************************************************/
1635 void start_background_queue(struct tevent_context
*ev
,
1636 struct messaging_context
*msg_ctx
)
1638 /* Use local variables for this as we don't
1639 * need to save the parent side of this, just
1640 * ensure it closes when the process exits.
1644 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1646 if (pipe(pause_pipe
) == -1) {
1647 DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno
) ));
1651 background_lpq_updater_pid
= sys_fork();
1653 if (background_lpq_updater_pid
== -1) {
1654 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno
) ));
1658 /* Track the printing pid along with other smbd children */
1659 add_child_pid(background_lpq_updater_pid
);
1661 if(background_lpq_updater_pid
== 0) {
1662 struct tevent_fd
*fde
;
1667 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1669 close(pause_pipe
[0]);
1672 status
= reinit_after_fork(msg_ctx
, ev
, procid_self(), true);
1674 if (!NT_STATUS_IS_OK(status
)) {
1675 DEBUG(0,("reinit_after_fork() failed\n"));
1676 smb_panic("reinit_after_fork() failed");
1679 smbd_setup_sig_term_handler();
1680 smbd_setup_sig_hup_handler(ev
, msg_ctx
);
1682 if (!serverid_register(procid_self(),
1683 FLAG_MSG_GENERAL
|FLAG_MSG_SMBD
1684 |FLAG_MSG_PRINT_GENERAL
)) {
1688 if (!locking_init()) {
1692 messaging_register(msg_ctx
, NULL
, MSG_PRINTER_UPDATE
,
1693 print_queue_receive
);
1695 fde
= tevent_add_fd(ev
, ev
, pause_pipe
[1], TEVENT_FD_READ
,
1696 printing_pause_fd_handler
,
1699 DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
1700 smb_panic("tevent_add_fd() failed for pause_pipe");
1703 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1704 ret
= tevent_loop_wait(ev
);
1705 /* should not be reached */
1706 DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
1707 ret
, (ret
== 0) ? "out of events" : strerror(errno
)));
1711 close(pause_pipe
[1]);
1714 /****************************************************************************
1715 update the internal database from the system print queue for a queue
1716 ****************************************************************************/
1718 static void print_queue_update(struct messaging_context
*msg_ctx
,
1719 int snum
, bool force
)
1723 char *lpqcommand
= NULL
;
1724 char *lprmcommand
= NULL
;
1725 uint8
*buffer
= NULL
;
1728 struct tdb_print_db
*pdb
;
1730 struct printif
*current_printif
;
1731 TALLOC_CTX
*ctx
= talloc_tos();
1733 fstrcpy( sharename
, lp_const_servicename(snum
));
1735 /* don't strip out characters like '$' from the printername */
1737 lpqcommand
= talloc_string_sub2(ctx
,
1738 lp_lpqcommand(snum
),
1740 lp_printername(snum
),
1741 false, false, false);
1745 lpqcommand
= talloc_sub_advanced(ctx
,
1746 lp_servicename(snum
),
1747 current_user_info
.unix_name
,
1749 current_user
.ut
.gid
,
1750 get_current_username(),
1751 current_user_info
.domain
,
1757 lprmcommand
= talloc_string_sub2(ctx
,
1758 lp_lprmcommand(snum
),
1760 lp_printername(snum
),
1761 false, false, false);
1765 lprmcommand
= talloc_sub_advanced(ctx
,
1766 lp_servicename(snum
),
1767 current_user_info
.unix_name
,
1769 current_user
.ut
.gid
,
1770 get_current_username(),
1771 current_user_info
.domain
,
1778 * Make sure that the background queue process exists.
1779 * Otherwise just do the update ourselves
1782 if ( force
|| background_lpq_updater_pid
== -1 ) {
1783 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename
));
1784 current_printif
= get_printer_fns( snum
);
1785 print_queue_update_with_lock(server_event_context(), msg_ctx
,
1786 sharename
, current_printif
,
1787 lpqcommand
, lprmcommand
);
1792 type
= lp_printing(snum
);
1794 /* get the length */
1796 len
= tdb_pack( NULL
, 0, "fdPP",
1802 buffer
= SMB_XMALLOC_ARRAY( uint8
, len
);
1804 /* now pack the buffer */
1805 newlen
= tdb_pack( buffer
, len
, "fdPP",
1811 SMB_ASSERT( newlen
== len
);
1813 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1814 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1815 sharename
, type
, lpqcommand
, lprmcommand
));
1817 /* here we set a msg pending record for other smbd processes
1818 to throttle the number of duplicate print_queue_update msgs
1821 pdb
= get_print_db_byname(sharename
);
1827 snprintf(key
, sizeof(key
), "MSG_PENDING/%s", sharename
);
1829 if ( !tdb_store_uint32( pdb
->tdb
, key
, time(NULL
) ) ) {
1830 /* log a message but continue on */
1832 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1836 release_print_db( pdb
);
1838 /* finally send the message */
1840 messaging_send_buf(msg_ctx
, pid_to_procid(background_lpq_updater_pid
),
1841 MSG_PRINTER_UPDATE
, (uint8
*)buffer
, len
);
1843 SAFE_FREE( buffer
);
1848 /****************************************************************************
1849 Create/Update an entry in the print tdb that will allow us to send notify
1850 updates only to interested smbd's.
1851 ****************************************************************************/
1853 bool print_notify_register_pid(int snum
)
1856 struct tdb_print_db
*pdb
= NULL
;
1857 TDB_CONTEXT
*tdb
= NULL
;
1858 const char *printername
;
1859 uint32 mypid
= (uint32
)sys_getpid();
1863 /* if (snum == -1), then the change notify request was
1864 on a print server handle and we need to register on
1869 int num_services
= lp_numservices();
1872 for ( idx
=0; idx
<num_services
; idx
++ ) {
1873 if (lp_snum_ok(idx
) && lp_print_ok(idx
) )
1874 print_notify_register_pid(idx
);
1879 else /* register for a specific printer */
1881 printername
= lp_const_servicename(snum
);
1882 pdb
= get_print_db_byname(printername
);
1888 if (tdb_lock_bystring_with_timeout(tdb
, NOTIFY_PID_LIST_KEY
, 10) == -1) {
1889 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1892 release_print_db(pdb
);
1896 data
= get_printer_notify_pid_list( tdb
, printername
, True
);
1898 /* Add ourselves and increase the refcount. */
1900 for (i
= 0; i
< data
.dsize
; i
+= 8) {
1901 if (IVAL(data
.dptr
,i
) == mypid
) {
1902 uint32 new_refcount
= IVAL(data
.dptr
, i
+4) + 1;
1903 SIVAL(data
.dptr
, i
+4, new_refcount
);
1908 if (i
== data
.dsize
) {
1909 /* We weren't in the list. Realloc. */
1910 data
.dptr
= (uint8
*)SMB_REALLOC(data
.dptr
, data
.dsize
+ 8);
1912 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1917 SIVAL(data
.dptr
,data
.dsize
- 8,mypid
);
1918 SIVAL(data
.dptr
,data
.dsize
- 4,1); /* Refcount. */
1921 /* Store back the record. */
1922 if (tdb_store_bystring(tdb
, NOTIFY_PID_LIST_KEY
, data
, TDB_REPLACE
) == -1) {
1923 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1924 list for printer %s\n", printername
));
1932 tdb_unlock_bystring(tdb
, NOTIFY_PID_LIST_KEY
);
1934 release_print_db(pdb
);
1935 SAFE_FREE(data
.dptr
);
1939 /****************************************************************************
1940 Update an entry in the print tdb that will allow us to send notify
1941 updates only to interested smbd's.
1942 ****************************************************************************/
1944 bool print_notify_deregister_pid(int snum
)
1947 struct tdb_print_db
*pdb
= NULL
;
1948 TDB_CONTEXT
*tdb
= NULL
;
1949 const char *printername
;
1950 uint32 mypid
= (uint32
)sys_getpid();
1954 /* if ( snum == -1 ), we are deregister a print server handle
1955 which means to deregister on all print queues */
1959 int num_services
= lp_numservices();
1962 for ( idx
=0; idx
<num_services
; idx
++ ) {
1963 if ( lp_snum_ok(idx
) && lp_print_ok(idx
) )
1964 print_notify_deregister_pid(idx
);
1969 else /* deregister a specific printer */
1971 printername
= lp_const_servicename(snum
);
1972 pdb
= get_print_db_byname(printername
);
1978 if (tdb_lock_bystring_with_timeout(tdb
, NOTIFY_PID_LIST_KEY
, 10) == -1) {
1979 DEBUG(0,("print_notify_register_pid: Failed to lock \
1980 printer %s database\n", printername
));
1982 release_print_db(pdb
);
1986 data
= get_printer_notify_pid_list( tdb
, printername
, True
);
1988 /* Reduce refcount. Remove ourselves if zero. */
1990 for (i
= 0; i
< data
.dsize
; ) {
1991 if (IVAL(data
.dptr
,i
) == mypid
) {
1992 uint32 refcount
= IVAL(data
.dptr
, i
+4);
1996 if (refcount
== 0) {
1997 if (data
.dsize
- i
> 8)
1998 memmove( &data
.dptr
[i
], &data
.dptr
[i
+8], data
.dsize
- i
- 8);
2002 SIVAL(data
.dptr
, i
+4, refcount
);
2008 if (data
.dsize
== 0)
2009 SAFE_FREE(data
.dptr
);
2011 /* Store back the record. */
2012 if (tdb_store_bystring(tdb
, NOTIFY_PID_LIST_KEY
, data
, TDB_REPLACE
) == -1) {
2013 DEBUG(0,("print_notify_register_pid: Failed to update pid \
2014 list for printer %s\n", printername
));
2022 tdb_unlock_bystring(tdb
, NOTIFY_PID_LIST_KEY
);
2024 release_print_db(pdb
);
2025 SAFE_FREE(data
.dptr
);
2029 /****************************************************************************
2030 Check if a jobid is valid. It is valid if it exists in the database.
2031 ****************************************************************************/
2033 bool print_job_exists(const char* sharename
, uint32 jobid
)
2035 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2041 ret
= tdb_exists(pdb
->tdb
, print_key(jobid
, &tmp
));
2042 release_print_db(pdb
);
2046 /****************************************************************************
2047 Give the filename used for a jobid.
2048 Only valid for the process doing the spooling and when the job
2049 has not been spooled.
2050 ****************************************************************************/
2052 char *print_job_fname(const char* sharename
, uint32 jobid
)
2054 struct printjob
*pjob
= print_job_find(sharename
, jobid
);
2055 if (!pjob
|| pjob
->spooled
|| pjob
->pid
!= sys_getpid())
2057 return pjob
->filename
;
2061 /****************************************************************************
2062 Give the filename used for a jobid.
2063 Only valid for the process doing the spooling and when the job
2064 has not been spooled.
2065 ****************************************************************************/
2067 struct spoolss_DeviceMode
*print_job_devmode(const char* sharename
, uint32 jobid
)
2069 struct printjob
*pjob
= print_job_find(sharename
, jobid
);
2074 return pjob
->devmode
;
2077 /****************************************************************************
2078 Set the name of a job. Only possible for owner.
2079 ****************************************************************************/
2081 bool print_job_set_name(struct tevent_context
*ev
,
2082 struct messaging_context
*msg_ctx
,
2083 const char *sharename
, uint32 jobid
, const char *name
)
2085 struct printjob
*pjob
;
2087 pjob
= print_job_find(sharename
, jobid
);
2088 if (!pjob
|| pjob
->pid
!= sys_getpid())
2091 fstrcpy(pjob
->jobname
, name
);
2092 return pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2095 /****************************************************************************
2096 Get the name of a job. Only possible for owner.
2097 ****************************************************************************/
2099 bool print_job_get_name(TALLOC_CTX
*mem_ctx
, const char *sharename
, uint32_t jobid
, char **name
)
2101 struct printjob
*pjob
;
2103 pjob
= print_job_find(sharename
, jobid
);
2104 if (!pjob
|| pjob
->pid
!= sys_getpid()) {
2108 *name
= talloc_strdup(mem_ctx
, pjob
->jobname
);
2117 /***************************************************************************
2118 Remove a jobid from the 'jobs added' list.
2119 ***************************************************************************/
2121 static bool remove_from_jobs_added(const char* sharename
, uint32 jobid
)
2123 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2125 size_t job_count
, i
;
2127 bool gotlock
= False
;
2135 key
= string_tdb_data("INFO/jobs_added");
2137 if (tdb_chainlock_with_timeout(pdb
->tdb
, key
, 5) == -1)
2142 data
= tdb_fetch(pdb
->tdb
, key
);
2144 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0))
2147 job_count
= data
.dsize
/ 4;
2148 for (i
= 0; i
< job_count
; i
++) {
2151 ch_jobid
= IVAL(data
.dptr
, i
*4);
2152 if (ch_jobid
== jobid
) {
2153 if (i
< job_count
-1 )
2154 memmove(data
.dptr
+ (i
*4), data
.dptr
+ (i
*4) + 4, (job_count
- i
- 1)*4 );
2156 if (tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
) == -1)
2166 tdb_chainunlock(pdb
->tdb
, key
);
2167 SAFE_FREE(data
.dptr
);
2168 release_print_db(pdb
);
2170 DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid
));
2172 DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid
));
2176 /****************************************************************************
2177 Delete a print job - don't update queue.
2178 ****************************************************************************/
2180 static bool print_job_delete1(struct tevent_context
*ev
,
2181 struct messaging_context
*msg_ctx
,
2182 int snum
, uint32 jobid
)
2184 const char* sharename
= lp_const_servicename(snum
);
2185 struct printjob
*pjob
= print_job_find(sharename
, jobid
);
2187 struct printif
*current_printif
= get_printer_fns( snum
);
2193 * If already deleting just return.
2196 if (pjob
->status
== LPQ_DELETING
)
2199 /* Hrm - we need to be able to cope with deleting a job before it
2200 has reached the spooler. Just mark it as LPQ_DELETING and
2201 let the print_queue_update() code rmeove the record */
2204 if (pjob
->sysjob
== -1) {
2205 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid
));
2208 /* Set the tdb entry to be deleting. */
2210 pjob
->status
= LPQ_DELETING
;
2211 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2213 if (pjob
->spooled
&& pjob
->sysjob
!= -1)
2215 result
= (*(current_printif
->job_delete
))(
2216 lp_printername(snum
),
2217 lp_lprmcommand(snum
),
2220 /* Delete the tdb entry if the delete succeeded or the job hasn't
2224 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2229 pjob_delete(ev
, msg_ctx
, sharename
, jobid
);
2230 /* Ensure we keep a rough count of the number of total jobs... */
2231 tdb_change_int32_atomic(pdb
->tdb
, "INFO/total_jobs", &njobs
, -1);
2232 release_print_db(pdb
);
2236 remove_from_jobs_added( sharename
, jobid
);
2238 return (result
== 0);
2241 /****************************************************************************
2242 Return true if the current user owns the print job.
2243 ****************************************************************************/
2245 static bool is_owner(const struct auth_serversupplied_info
*server_info
,
2246 const char *servicename
,
2249 struct printjob
*pjob
= print_job_find(servicename
, jobid
);
2251 if (!pjob
|| !server_info
)
2254 return strequal(pjob
->user
, server_info
->sanitized_username
);
2257 /****************************************************************************
2259 ****************************************************************************/
2261 WERROR
print_job_delete(const struct auth_serversupplied_info
*server_info
,
2262 struct messaging_context
*msg_ctx
,
2263 int snum
, uint32_t jobid
)
2265 const char* sharename
= lp_const_servicename(snum
);
2266 struct printjob
*pjob
;
2270 owner
= is_owner(server_info
, lp_const_servicename(snum
), jobid
);
2272 /* Check access against security descriptor or whether the user
2276 !print_access_check(server_info
, msg_ctx
, snum
,
2277 JOB_ACCESS_ADMINISTER
)) {
2278 DEBUG(3, ("delete denied by security descriptor\n"));
2280 /* BEGIN_ADMIN_LOG */
2281 sys_adminlog( LOG_ERR
,
2282 "Permission denied-- user not allowed to delete, \
2283 pause, or resume print job. User name: %s. Printer name: %s.",
2284 uidtoname(server_info
->utok
.uid
),
2285 lp_printername(snum
) );
2288 return WERR_ACCESS_DENIED
;
2292 * get the spooled filename of the print job
2293 * if this works, then the file has not been spooled
2294 * to the underlying print system. Just delete the
2295 * spool file & return.
2298 fname
= print_job_fname(sharename
, jobid
);
2299 if (fname
!= NULL
) {
2300 /* remove the spool file */
2301 DEBUG(10, ("print_job_delete: "
2302 "Removing spool file [%s]\n", fname
));
2303 if (unlink(fname
) == -1) {
2304 return map_werror_from_unix(errno
);
2308 if (!print_job_delete1(server_event_context(), msg_ctx
, snum
, jobid
)) {
2309 return WERR_ACCESS_DENIED
;
2312 /* force update the database and say the delete failed if the
2315 print_queue_update(msg_ctx
, snum
, True
);
2317 pjob
= print_job_find(sharename
, jobid
);
2318 if (pjob
&& (pjob
->status
!= LPQ_DELETING
)) {
2319 return WERR_ACCESS_DENIED
;
2322 return WERR_PRINTER_HAS_JOBS_QUEUED
;
2325 /****************************************************************************
2327 ****************************************************************************/
2329 bool print_job_pause(const struct auth_serversupplied_info
*server_info
,
2330 struct messaging_context
*msg_ctx
,
2331 int snum
, uint32 jobid
, WERROR
*errcode
)
2333 const char* sharename
= lp_const_servicename(snum
);
2334 struct printjob
*pjob
;
2336 struct printif
*current_printif
= get_printer_fns( snum
);
2338 pjob
= print_job_find(sharename
, jobid
);
2340 if (!pjob
|| !server_info
) {
2341 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2342 (unsigned int)jobid
));
2346 if (!pjob
->spooled
|| pjob
->sysjob
== -1) {
2347 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2348 (int)pjob
->sysjob
, (unsigned int)jobid
));
2352 if (!is_owner(server_info
, lp_const_servicename(snum
), jobid
) &&
2353 !print_access_check(server_info
, msg_ctx
, snum
,
2354 JOB_ACCESS_ADMINISTER
)) {
2355 DEBUG(3, ("pause denied by security descriptor\n"));
2357 /* BEGIN_ADMIN_LOG */
2358 sys_adminlog( LOG_ERR
,
2359 "Permission denied-- user not allowed to delete, \
2360 pause, or resume print job. User name: %s. Printer name: %s.",
2361 uidtoname(server_info
->utok
.uid
),
2362 lp_printername(snum
) );
2365 *errcode
= WERR_ACCESS_DENIED
;
2369 /* need to pause the spooled entry */
2370 ret
= (*(current_printif
->job_pause
))(snum
, pjob
);
2373 *errcode
= WERR_INVALID_PARAM
;
2377 /* force update the database */
2378 print_cache_flush(lp_const_servicename(snum
));
2380 /* Send a printer notify message */
2382 notify_job_status(server_event_context(), msg_ctx
, sharename
, jobid
,
2385 /* how do we tell if this succeeded? */
2390 /****************************************************************************
2392 ****************************************************************************/
2394 bool print_job_resume(const struct auth_serversupplied_info
*server_info
,
2395 struct messaging_context
*msg_ctx
,
2396 int snum
, uint32 jobid
, WERROR
*errcode
)
2398 const char *sharename
= lp_const_servicename(snum
);
2399 struct printjob
*pjob
;
2401 struct printif
*current_printif
= get_printer_fns( snum
);
2403 pjob
= print_job_find(sharename
, jobid
);
2405 if (!pjob
|| !server_info
) {
2406 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2407 (unsigned int)jobid
));
2411 if (!pjob
->spooled
|| pjob
->sysjob
== -1) {
2412 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2413 (int)pjob
->sysjob
, (unsigned int)jobid
));
2417 if (!is_owner(server_info
, lp_const_servicename(snum
), jobid
) &&
2418 !print_access_check(server_info
, msg_ctx
, snum
,
2419 JOB_ACCESS_ADMINISTER
)) {
2420 DEBUG(3, ("resume denied by security descriptor\n"));
2421 *errcode
= WERR_ACCESS_DENIED
;
2423 /* BEGIN_ADMIN_LOG */
2424 sys_adminlog( LOG_ERR
,
2425 "Permission denied-- user not allowed to delete, \
2426 pause, or resume print job. User name: %s. Printer name: %s.",
2427 uidtoname(server_info
->utok
.uid
),
2428 lp_printername(snum
) );
2433 ret
= (*(current_printif
->job_resume
))(snum
, pjob
);
2436 *errcode
= WERR_INVALID_PARAM
;
2440 /* force update the database */
2441 print_cache_flush(lp_const_servicename(snum
));
2443 /* Send a printer notify message */
2445 notify_job_status(server_event_context(), msg_ctx
, sharename
, jobid
,
2451 /****************************************************************************
2452 Write to a print file.
2453 ****************************************************************************/
2455 ssize_t
print_job_write(struct tevent_context
*ev
,
2456 struct messaging_context
*msg_ctx
,
2457 int snum
, uint32 jobid
, const char *buf
, size_t size
)
2459 const char* sharename
= lp_const_servicename(snum
);
2460 ssize_t return_code
;
2461 struct printjob
*pjob
;
2463 pjob
= print_job_find(sharename
, jobid
);
2467 /* don't allow another process to get this info - it is meaningless */
2468 if (pjob
->pid
!= sys_getpid())
2471 /* if SMBD is spooling this can't be allowed */
2472 if (pjob
->status
== PJOB_SMBD_SPOOLING
) {
2476 return_code
= write_data(pjob
->fd
, buf
, size
);
2478 if (return_code
>0) {
2480 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2485 /****************************************************************************
2486 Get the queue status - do not update if db is out of date.
2487 ****************************************************************************/
2489 static int get_queue_status(const char* sharename
, print_status_struct
*status
)
2493 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2497 ZERO_STRUCTP(status
);
2504 fstr_sprintf(keystr
, "STATUS/%s", sharename
);
2505 data
= tdb_fetch(pdb
->tdb
, string_tdb_data(keystr
));
2507 if (data
.dsize
== sizeof(print_status_struct
))
2508 /* this memcpy is ok since the status struct was
2509 not packed before storing it in the tdb */
2510 memcpy(status
, data
.dptr
, sizeof(print_status_struct
));
2511 SAFE_FREE(data
.dptr
);
2514 len
= tdb_fetch_int32(pdb
->tdb
, "INFO/total_jobs");
2515 release_print_db(pdb
);
2516 return (len
== -1 ? 0 : len
);
2519 /****************************************************************************
2520 Determine the number of jobs in a queue.
2521 ****************************************************************************/
2523 int print_queue_length(struct messaging_context
*msg_ctx
, int snum
,
2524 print_status_struct
*pstatus
)
2526 const char* sharename
= lp_const_servicename( snum
);
2527 print_status_struct status
;
2530 ZERO_STRUCT( status
);
2532 /* make sure the database is up to date */
2533 if (print_cache_expired(lp_const_servicename(snum
), True
))
2534 print_queue_update(msg_ctx
, snum
, False
);
2536 /* also fetch the queue status */
2537 memset(&status
, 0, sizeof(status
));
2538 len
= get_queue_status(sharename
, &status
);
2546 /***************************************************************************
2547 Allocate a jobid. Hold the lock for as short a time as possible.
2548 ***************************************************************************/
2550 static WERROR
allocate_print_jobid(struct tdb_print_db
*pdb
, int snum
,
2551 const char *sharename
, uint32
*pjobid
)
2555 enum TDB_ERROR terr
;
2558 *pjobid
= (uint32
)-1;
2560 for (i
= 0; i
< 3; i
++) {
2561 /* Lock the database - only wait 20 seconds. */
2562 ret
= tdb_lock_bystring_with_timeout(pdb
->tdb
,
2563 "INFO/nextjob", 20);
2565 DEBUG(0, ("allocate_print_jobid: "
2566 "Failed to lock printing database %s\n",
2568 terr
= tdb_error(pdb
->tdb
);
2569 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2572 if (!tdb_fetch_uint32(pdb
->tdb
, "INFO/nextjob", &jobid
)) {
2573 terr
= tdb_error(pdb
->tdb
);
2574 if (terr
!= TDB_ERR_NOEXIST
) {
2575 DEBUG(0, ("allocate_print_jobid: "
2576 "Failed to fetch INFO/nextjob "
2577 "for print queue %s\n", sharename
));
2578 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2579 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2581 DEBUG(10, ("allocate_print_jobid: "
2582 "No existing jobid in %s\n", sharename
));
2586 DEBUG(10, ("allocate_print_jobid: "
2587 "Read jobid %u from %s\n", jobid
, sharename
));
2589 jobid
= NEXT_JOBID(jobid
);
2591 ret
= tdb_store_int32(pdb
->tdb
, "INFO/nextjob", jobid
);
2593 terr
= tdb_error(pdb
->tdb
);
2594 DEBUG(3, ("allocate_print_jobid: "
2595 "Failed to store INFO/nextjob.\n"));
2596 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2597 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2600 /* We've finished with the INFO/nextjob lock. */
2601 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2603 if (!print_job_exists(sharename
, jobid
)) {
2606 DEBUG(10, ("allocate_print_jobid: "
2607 "Found jobid %u in %s\n", jobid
, sharename
));
2611 DEBUG(0, ("allocate_print_jobid: "
2612 "Failed to allocate a print job for queue %s\n",
2614 /* Probably full... */
2615 return WERR_NO_SPOOL_SPACE
;
2618 /* Store a dummy placeholder. */
2624 if (tdb_store(pdb
->tdb
, print_key(jobid
, &tmp
), dum
,
2625 TDB_INSERT
) == -1) {
2626 DEBUG(3, ("allocate_print_jobid: "
2627 "jobid (%d) failed to store placeholder.\n",
2629 terr
= tdb_error(pdb
->tdb
);
2630 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2638 /***************************************************************************
2639 Append a jobid to the 'jobs added' list.
2640 ***************************************************************************/
2642 static bool add_to_jobs_added(struct tdb_print_db
*pdb
, uint32 jobid
)
2647 SIVAL(&store_jobid
, 0, jobid
);
2648 data
.dptr
= (uint8
*)&store_jobid
;
2651 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid
));
2653 return (tdb_append(pdb
->tdb
, string_tdb_data("INFO/jobs_added"),
2658 /***************************************************************************
2659 Do all checks needed to determine if we can start a job.
2660 ***************************************************************************/
2662 static WERROR
print_job_checks(const struct auth_serversupplied_info
*server_info
,
2663 struct messaging_context
*msg_ctx
,
2664 int snum
, int *njobs
)
2666 const char *sharename
= lp_const_servicename(snum
);
2667 uint64_t dspace
, dsize
;
2671 if (!print_access_check(server_info
, msg_ctx
, snum
,
2672 PRINTER_ACCESS_USE
)) {
2673 DEBUG(3, ("print_job_checks: "
2674 "job start denied by security descriptor\n"));
2675 return WERR_ACCESS_DENIED
;
2678 if (!print_time_access_check(server_info
, msg_ctx
, sharename
)) {
2679 DEBUG(3, ("print_job_checks: "
2680 "job start denied by time check\n"));
2681 return WERR_ACCESS_DENIED
;
2684 /* see if we have sufficient disk space */
2685 if (lp_minprintspace(snum
)) {
2686 minspace
= lp_minprintspace(snum
);
2687 ret
= sys_fsusage(lp_pathname(snum
), &dspace
, &dsize
);
2688 if (ret
== 0 && dspace
< 2*minspace
) {
2689 DEBUG(3, ("print_job_checks: "
2690 "disk space check failed.\n"));
2691 return WERR_NO_SPOOL_SPACE
;
2695 /* for autoloaded printers, check that the printcap entry still exists */
2696 if (lp_autoloaded(snum
) && !pcap_printername_ok(sharename
)) {
2697 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2699 return WERR_ACCESS_DENIED
;
2702 /* Insure the maximum queue size is not violated */
2703 *njobs
= print_queue_length(msg_ctx
, snum
, NULL
);
2704 if (*njobs
> lp_maxprintjobs(snum
)) {
2705 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2706 "larger than max printjobs per queue (%d).\n",
2707 sharename
, *njobs
, lp_maxprintjobs(snum
)));
2708 return WERR_NO_SPOOL_SPACE
;
2714 /***************************************************************************
2716 ***************************************************************************/
2718 static WERROR
print_job_spool_file(int snum
, uint32_t jobid
,
2719 const char *output_file
,
2720 struct printjob
*pjob
)
2727 /* if this file is within the printer path, it means that smbd
2728 * is spooling it and will pass us control when it is finished.
2729 * Verify that the file name is ok, within path, and it is
2730 * already already there */
2732 path
= lp_pathname(snum
);
2734 if (strncmp(output_file
, path
, len
) == 0 &&
2735 (output_file
[len
- 1] == '/' || output_file
[len
] == '/')) {
2737 /* verify path is not too long */
2738 if (strlen(output_file
) >= sizeof(pjob
->filename
)) {
2739 return WERR_INVALID_NAME
;
2742 /* verify that the file exists */
2743 if (sys_stat(output_file
, &st
, false) != 0) {
2744 return WERR_INVALID_NAME
;
2747 fstrcpy(pjob
->filename
, output_file
);
2749 DEBUG(3, ("print_job_spool_file:"
2750 "External spooling activated"));
2752 /* we do not open the file until spooling is done */
2754 pjob
->status
= PJOB_SMBD_SPOOLING
;
2760 slprintf(pjob
->filename
, sizeof(pjob
->filename
)-1,
2761 "%s/%s%.8u.XXXXXX", lp_pathname(snum
),
2762 PRINT_SPOOL_PREFIX
, (unsigned int)jobid
);
2763 pjob
->fd
= mkstemp(pjob
->filename
);
2765 if (pjob
->fd
== -1) {
2766 werr
= map_werror_from_unix(errno
);
2767 if (W_ERROR_EQUAL(werr
, WERR_ACCESS_DENIED
)) {
2768 /* Common setup error, force a report. */
2769 DEBUG(0, ("print_job_spool_file: "
2770 "insufficient permissions to open spool "
2771 "file %s.\n", pjob
->filename
));
2773 /* Normal case, report at level 3 and above. */
2774 DEBUG(3, ("print_job_spool_file: "
2775 "can't open spool file %s\n",
2784 /***************************************************************************
2785 Start spooling a job - return the jobid.
2786 ***************************************************************************/
2788 WERROR
print_job_start(const struct auth_serversupplied_info
*server_info
,
2789 struct messaging_context
*msg_ctx
,
2790 const char *clientmachine
,
2791 int snum
, const char *docname
, const char *filename
,
2792 struct spoolss_DeviceMode
*devmode
, uint32_t *_jobid
)
2796 struct printjob pjob
;
2797 const char *sharename
= lp_const_servicename(snum
);
2798 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2803 return WERR_INTERNAL_DB_CORRUPTION
;
2806 path
= lp_pathname(snum
);
2808 werr
= print_job_checks(server_info
, msg_ctx
, snum
, &njobs
);
2809 if (!W_ERROR_IS_OK(werr
)) {
2810 release_print_db(pdb
);
2814 DEBUG(10, ("print_job_start: "
2815 "Queue %s number of jobs (%d), max printjobs = %d\n",
2816 sharename
, njobs
, lp_maxprintjobs(snum
)));
2818 werr
= allocate_print_jobid(pdb
, snum
, sharename
, &jobid
);
2819 if (!W_ERROR_IS_OK(werr
)) {
2823 /* create the database entry */
2827 pjob
.pid
= sys_getpid();
2830 pjob
.starttime
= time(NULL
);
2831 pjob
.status
= LPQ_SPOOLING
;
2833 pjob
.spooled
= False
;
2835 pjob
.devmode
= devmode
;
2837 fstrcpy(pjob
.jobname
, docname
);
2839 fstrcpy(pjob
.clientmachine
, clientmachine
);
2841 fstrcpy(pjob
.user
, lp_printjob_username(snum
));
2842 standard_sub_advanced(sharename
, server_info
->sanitized_username
,
2843 path
, server_info
->utok
.gid
,
2844 server_info
->sanitized_username
,
2845 server_info
->info3
->base
.domain
.string
,
2846 pjob
.user
, sizeof(pjob
.user
)-1);
2847 /* ensure NULL termination */
2848 pjob
.user
[sizeof(pjob
.user
)-1] = '\0';
2850 fstrcpy(pjob
.queuename
, lp_const_servicename(snum
));
2852 /* we have a job entry - now create the spool file */
2853 werr
= print_job_spool_file(snum
, jobid
, filename
, &pjob
);
2854 if (!W_ERROR_IS_OK(werr
)) {
2858 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, &pjob
);
2860 /* Update the 'jobs added' entry used by print_queue_status. */
2861 add_to_jobs_added(pdb
, jobid
);
2863 /* Ensure we keep a rough count of the number of total jobs... */
2864 tdb_change_int32_atomic(pdb
->tdb
, "INFO/total_jobs", &njobs
, 1);
2866 release_print_db(pdb
);
2873 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
2876 release_print_db(pdb
);
2878 DEBUG(3, ("print_job_start: returning fail. "
2879 "Error = %s\n", win_errstr(werr
)));
2883 /****************************************************************************
2884 Update the number of pages spooled to jobid
2885 ****************************************************************************/
2887 void print_job_endpage(struct messaging_context
*msg_ctx
,
2888 int snum
, uint32 jobid
)
2890 const char* sharename
= lp_const_servicename(snum
);
2891 struct printjob
*pjob
;
2893 pjob
= print_job_find(sharename
, jobid
);
2896 /* don't allow another process to get this info - it is meaningless */
2897 if (pjob
->pid
!= sys_getpid())
2901 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, pjob
);
2904 /****************************************************************************
2905 Print a file - called on closing the file. This spools the job.
2906 If normal close is false then we're tearing down the jobs - treat as an
2908 ****************************************************************************/
2910 NTSTATUS
print_job_end(struct messaging_context
*msg_ctx
, int snum
,
2911 uint32 jobid
, enum file_close_type close_type
)
2913 const char* sharename
= lp_const_servicename(snum
);
2914 struct printjob
*pjob
;
2916 SMB_STRUCT_STAT sbuf
;
2917 struct printif
*current_printif
= get_printer_fns( snum
);
2918 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
2920 pjob
= print_job_find(sharename
, jobid
);
2923 return NT_STATUS_PRINT_CANCELLED
;
2926 if (pjob
->spooled
|| pjob
->pid
!= sys_getpid()) {
2927 return NT_STATUS_ACCESS_DENIED
;
2930 if (close_type
== NORMAL_CLOSE
|| close_type
== SHUTDOWN_CLOSE
) {
2931 if (pjob
->status
== PJOB_SMBD_SPOOLING
) {
2932 /* take over the file now, smbd is done */
2933 if (sys_stat(pjob
->filename
, &sbuf
, false) != 0) {
2934 status
= map_nt_error_from_unix(errno
);
2935 DEBUG(3, ("print_job_end: "
2936 "stat file failed for jobid %d\n",
2941 pjob
->status
= LPQ_SPOOLING
;
2945 if ((sys_fstat(pjob
->fd
, &sbuf
, false) != 0)) {
2946 status
= map_nt_error_from_unix(errno
);
2948 DEBUG(3, ("print_job_end: "
2949 "stat file failed for jobid %d\n",
2957 pjob
->size
= sbuf
.st_ex_size
;
2961 * Not a normal close, something has gone wrong. Cleanup.
2963 if (pjob
->fd
!= -1) {
2969 /* Technically, this is not quite right. If the printer has a separator
2970 * page turned on, the NT spooler prints the separator page even if the
2971 * print job is 0 bytes. 010215 JRR */
2972 if (pjob
->size
== 0 || pjob
->status
== LPQ_DELETING
) {
2973 /* don't bother spooling empty files or something being deleted. */
2974 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2975 pjob
->filename
, pjob
->size
? "deleted" : "zero length" ));
2976 unlink(pjob
->filename
);
2977 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
2978 return NT_STATUS_OK
;
2981 ret
= (*(current_printif
->job_submit
))(snum
, pjob
);
2984 status
= NT_STATUS_PRINT_CANCELLED
;
2988 /* The print job has been successfully handed over to the back-end */
2990 pjob
->spooled
= True
;
2991 pjob
->status
= LPQ_QUEUED
;
2992 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, pjob
);
2994 /* make sure the database is up to date */
2995 if (print_cache_expired(lp_const_servicename(snum
), True
))
2996 print_queue_update(msg_ctx
, snum
, False
);
2998 return NT_STATUS_OK
;
3002 /* The print job was not successfully started. Cleanup */
3003 /* Still need to add proper error return propagation! 010122:JRR */
3005 unlink(pjob
->filename
);
3006 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
3010 /****************************************************************************
3011 Get a snapshot of jobs in the system without traversing.
3012 ****************************************************************************/
3014 static bool get_stored_queue_info(struct messaging_context
*msg_ctx
,
3015 struct tdb_print_db
*pdb
, int snum
,
3016 int *pcount
, print_queue_struct
**ppqueue
)
3018 TDB_DATA data
, cgdata
, jcdata
;
3019 print_queue_struct
*queue
= NULL
;
3021 uint32 extra_count
= 0;
3022 uint32_t changed_count
= 0;
3023 int total_count
= 0;
3026 int max_reported_jobs
= lp_max_reported_jobs(snum
);
3028 const char* sharename
= lp_servicename(snum
);
3030 /* make sure the database is up to date */
3031 if (print_cache_expired(lp_const_servicename(snum
), True
))
3032 print_queue_update(msg_ctx
, snum
, False
);
3038 ZERO_STRUCT(cgdata
);
3040 /* Get the stored queue data. */
3041 data
= tdb_fetch(pdb
->tdb
, string_tdb_data("INFO/linear_queue_array"));
3043 if (data
.dptr
&& data
.dsize
>= sizeof(qcount
))
3044 len
+= tdb_unpack(data
.dptr
+ len
, data
.dsize
- len
, "d", &qcount
);
3046 /* Get the added jobs list. */
3047 cgdata
= tdb_fetch(pdb
->tdb
, string_tdb_data("INFO/jobs_added"));
3048 if (cgdata
.dptr
!= NULL
&& (cgdata
.dsize
% 4 == 0))
3049 extra_count
= cgdata
.dsize
/4;
3051 /* Get the changed jobs list. */
3052 jcdata
= tdb_fetch(pdb
->tdb
, string_tdb_data("INFO/jobs_changed"));
3053 if (jcdata
.dptr
!= NULL
&& (jcdata
.dsize
% 4 == 0))
3054 changed_count
= jcdata
.dsize
/ 4;
3056 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount
, (unsigned int)extra_count
));
3058 /* Allocate the queue size. */
3059 if (qcount
== 0 && extra_count
== 0)
3062 if ((queue
= SMB_MALLOC_ARRAY(print_queue_struct
, qcount
+ extra_count
)) == NULL
)
3065 /* Retrieve the linearised queue data. */
3067 for( i
= 0; i
< qcount
; i
++) {
3068 uint32 qjob
, qsize
, qpage_count
, qstatus
, qpriority
, qtime
;
3069 len
+= tdb_unpack(data
.dptr
+ len
, data
.dsize
- len
, "ddddddff",
3078 queue
[i
].job
= qjob
;
3079 queue
[i
].size
= qsize
;
3080 queue
[i
].page_count
= qpage_count
;
3081 queue
[i
].status
= qstatus
;
3082 queue
[i
].priority
= qpriority
;
3083 queue
[i
].time
= qtime
;
3086 total_count
= qcount
;
3088 /* Add new jobids to the queue. */
3089 for( i
= 0; i
< extra_count
; i
++) {
3091 struct printjob
*pjob
;
3093 jobid
= IVAL(cgdata
.dptr
, i
*4);
3094 DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid
));
3095 pjob
= print_job_find(lp_const_servicename(snum
), jobid
);
3097 DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid
));
3098 remove_from_jobs_added(sharename
, jobid
);
3102 queue
[total_count
].job
= jobid
;
3103 queue
[total_count
].size
= pjob
->size
;
3104 queue
[total_count
].page_count
= pjob
->page_count
;
3105 queue
[total_count
].status
= pjob
->status
;
3106 queue
[total_count
].priority
= 1;
3107 queue
[total_count
].time
= pjob
->starttime
;
3108 fstrcpy(queue
[total_count
].fs_user
, pjob
->user
);
3109 fstrcpy(queue
[total_count
].fs_file
, pjob
->jobname
);
3113 /* Update the changed jobids. */
3114 for (i
= 0; i
< changed_count
; i
++) {
3115 uint32_t jobid
= IVAL(jcdata
.dptr
, i
* 4);
3119 for (j
= 0; j
< total_count
; j
++) {
3120 if (queue
[j
].job
== jobid
) {
3127 struct printjob
*pjob
;
3129 DEBUG(5,("get_stored_queue_info: changed job: %u\n",
3130 (unsigned int) jobid
));
3132 pjob
= print_job_find(sharename
, jobid
);
3134 DEBUG(5,("get_stored_queue_info: failed to find "
3135 "changed job = %u\n",
3136 (unsigned int) jobid
));
3137 remove_from_jobs_changed(sharename
, jobid
);
3141 queue
[j
].job
= jobid
;
3142 queue
[j
].size
= pjob
->size
;
3143 queue
[j
].page_count
= pjob
->page_count
;
3144 queue
[j
].status
= pjob
->status
;
3145 queue
[j
].priority
= 1;
3146 queue
[j
].time
= pjob
->starttime
;
3147 fstrcpy(queue
[j
].fs_user
, pjob
->user
);
3148 fstrcpy(queue
[j
].fs_file
, pjob
->jobname
);
3150 DEBUG(5,("get_stored_queue_info: updated queue[%u], jobid: %u, jobname: %s\n",
3151 (unsigned int) j
, (unsigned int) jobid
, pjob
->jobname
));
3154 remove_from_jobs_changed(sharename
, jobid
);
3157 /* Sort the queue by submission time otherwise they are displayed
3160 TYPESAFE_QSORT(queue
, total_count
, printjob_comp
);
3162 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count
));
3164 if (max_reported_jobs
&& total_count
> max_reported_jobs
)
3165 total_count
= max_reported_jobs
;
3168 *pcount
= total_count
;
3174 SAFE_FREE(data
.dptr
);
3175 SAFE_FREE(cgdata
.dptr
);
3179 /****************************************************************************
3180 Get a printer queue listing.
3181 set queue = NULL and status = NULL if you just want to update the cache
3182 ****************************************************************************/
3184 int print_queue_status(struct messaging_context
*msg_ctx
, int snum
,
3185 print_queue_struct
**ppqueue
,
3186 print_status_struct
*status
)
3190 const char *sharename
;
3191 struct tdb_print_db
*pdb
;
3194 /* make sure the database is up to date */
3196 if (print_cache_expired(lp_const_servicename(snum
), True
))
3197 print_queue_update(msg_ctx
, snum
, False
);
3199 /* return if we are done */
3200 if ( !ppqueue
|| !status
)
3204 sharename
= lp_const_servicename(snum
);
3205 pdb
= get_print_db_byname(sharename
);
3211 * Fetch the queue status. We must do this first, as there may
3212 * be no jobs in the queue.
3215 ZERO_STRUCTP(status
);
3216 slprintf(keystr
, sizeof(keystr
)-1, "STATUS/%s", sharename
);
3217 key
= string_tdb_data(keystr
);
3219 data
= tdb_fetch(pdb
->tdb
, key
);
3221 if (data
.dsize
== sizeof(*status
)) {
3222 /* this memcpy is ok since the status struct was
3223 not packed before storing it in the tdb */
3224 memcpy(status
, data
.dptr
, sizeof(*status
));
3226 SAFE_FREE(data
.dptr
);
3230 * Now, fetch the print queue information. We first count the number
3231 * of entries, and then only retrieve the queue if necessary.
3234 if (!get_stored_queue_info(msg_ctx
, pdb
, snum
, &count
, ppqueue
)) {
3235 release_print_db(pdb
);
3239 release_print_db(pdb
);
3243 /****************************************************************************
3245 ****************************************************************************/
3247 WERROR
print_queue_pause(const struct auth_serversupplied_info
*server_info
,
3248 struct messaging_context
*msg_ctx
, int snum
)
3251 struct printif
*current_printif
= get_printer_fns( snum
);
3253 if (!print_access_check(server_info
, msg_ctx
, snum
,
3254 PRINTER_ACCESS_ADMINISTER
)) {
3255 return WERR_ACCESS_DENIED
;
3261 ret
= (*(current_printif
->queue_pause
))(snum
);
3266 return WERR_INVALID_PARAM
;
3269 /* force update the database */
3270 print_cache_flush(lp_const_servicename(snum
));
3272 /* Send a printer notify message */
3274 notify_printer_status(server_event_context(), msg_ctx
, snum
,
3275 PRINTER_STATUS_PAUSED
);
3280 /****************************************************************************
3282 ****************************************************************************/
3284 WERROR
print_queue_resume(const struct auth_serversupplied_info
*server_info
,
3285 struct messaging_context
*msg_ctx
, int snum
)
3288 struct printif
*current_printif
= get_printer_fns( snum
);
3290 if (!print_access_check(server_info
, msg_ctx
, snum
,
3291 PRINTER_ACCESS_ADMINISTER
)) {
3292 return WERR_ACCESS_DENIED
;
3297 ret
= (*(current_printif
->queue_resume
))(snum
);
3302 return WERR_INVALID_PARAM
;
3305 /* make sure the database is up to date */
3306 if (print_cache_expired(lp_const_servicename(snum
), True
))
3307 print_queue_update(msg_ctx
, snum
, True
);
3309 /* Send a printer notify message */
3311 notify_printer_status(server_event_context(), msg_ctx
, snum
,
3317 /****************************************************************************
3318 Purge a queue - implemented by deleting all jobs that we can delete.
3319 ****************************************************************************/
3321 WERROR
print_queue_purge(const struct auth_serversupplied_info
*server_info
,
3322 struct messaging_context
*msg_ctx
, int snum
)
3324 print_queue_struct
*queue
;
3325 print_status_struct status
;
3329 /* Force and update so the count is accurate (i.e. not a cached count) */
3330 print_queue_update(msg_ctx
, snum
, True
);
3332 can_job_admin
= print_access_check(server_info
,
3335 JOB_ACCESS_ADMINISTER
);
3336 njobs
= print_queue_status(msg_ctx
, snum
, &queue
, &status
);
3338 if ( can_job_admin
)
3341 for (i
=0;i
<njobs
;i
++) {
3342 bool owner
= is_owner(server_info
, lp_const_servicename(snum
),
3345 if (owner
|| can_job_admin
) {
3346 print_job_delete1(server_event_context(), msg_ctx
,
3347 snum
, queue
[i
].job
);
3351 if ( can_job_admin
)
3354 /* update the cache */
3355 print_queue_update(msg_ctx
, snum
, True
);