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/>.
24 #include "librpc/gen_ndr/messaging.h"
25 #include "../librpc/gen_ndr/ndr_spoolss.h"
26 #include "nt_printing.h"
27 #include "../librpc/gen_ndr/netlogon.h"
29 extern struct current_user current_user
;
30 extern userdom_struct current_user_info
;
32 /* Current printer interface */
33 static bool remove_from_jobs_added(const char* sharename
, uint32 jobid
);
36 the printing backend revolves around a tdb database that stores the
37 SMB view of the print queue
39 The key for this database is a jobid - a internally generated number that
40 uniquely identifies a print job
42 reading the print queue involves two steps:
43 - possibly running lpq and updating the internal database from that
44 - reading entries from the database
46 jobids are assigned when a job starts spooling.
49 static TDB_CONTEXT
*rap_tdb
;
50 static uint16 next_rap_jobid
;
51 struct rap_jobid_key
{
56 /***************************************************************************
57 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
58 bit RPC jobids.... JRA.
59 ***************************************************************************/
61 uint16
pjobid_to_rap(const char* sharename
, uint32 jobid
)
65 struct rap_jobid_key jinfo
;
68 DEBUG(10,("pjobid_to_rap: called.\n"));
71 /* Create the in-memory tdb. */
72 rap_tdb
= tdb_open_log(NULL
, 0, TDB_INTERNAL
, (O_RDWR
|O_CREAT
), 0644);
78 fstrcpy( jinfo
.sharename
, sharename
);
80 key
.dptr
= (uint8
*)&jinfo
;
81 key
.dsize
= sizeof(jinfo
);
83 data
= tdb_fetch(rap_tdb
, key
);
84 if (data
.dptr
&& data
.dsize
== sizeof(uint16
)) {
85 rap_jobid
= SVAL(data
.dptr
, 0);
87 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
88 (unsigned int)jobid
, (unsigned int)rap_jobid
));
92 /* Not found - create and store mapping. */
93 rap_jobid
= ++next_rap_jobid
;
95 rap_jobid
= ++next_rap_jobid
;
96 SSVAL(buf
,0,rap_jobid
);
98 data
.dsize
= sizeof(rap_jobid
);
99 tdb_store(rap_tdb
, key
, data
, TDB_REPLACE
);
100 tdb_store(rap_tdb
, data
, key
, TDB_REPLACE
);
102 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
103 (unsigned int)jobid
, (unsigned int)rap_jobid
));
107 bool rap_to_pjobid(uint16 rap_jobid
, fstring sharename
, uint32
*pjobid
)
112 DEBUG(10,("rap_to_pjobid called.\n"));
117 SSVAL(buf
,0,rap_jobid
);
119 key
.dsize
= sizeof(rap_jobid
);
120 data
= tdb_fetch(rap_tdb
, key
);
121 if ( data
.dptr
&& data
.dsize
== sizeof(struct rap_jobid_key
) )
123 struct rap_jobid_key
*jinfo
= (struct rap_jobid_key
*)data
.dptr
;
124 if (sharename
!= NULL
) {
125 fstrcpy( sharename
, jinfo
->sharename
);
127 *pjobid
= jinfo
->jobid
;
128 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
129 (unsigned int)*pjobid
, (unsigned int)rap_jobid
));
130 SAFE_FREE(data
.dptr
);
134 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
135 (unsigned int)rap_jobid
));
136 SAFE_FREE(data
.dptr
);
140 void rap_jobid_delete(const char* sharename
, uint32 jobid
)
144 struct rap_jobid_key jinfo
;
147 DEBUG(10,("rap_jobid_delete: called.\n"));
152 ZERO_STRUCT( jinfo
);
153 fstrcpy( jinfo
.sharename
, sharename
);
155 key
.dptr
= (uint8
*)&jinfo
;
156 key
.dsize
= sizeof(jinfo
);
158 data
= tdb_fetch(rap_tdb
, key
);
159 if (!data
.dptr
|| (data
.dsize
!= sizeof(uint16
))) {
160 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
161 (unsigned int)jobid
));
162 SAFE_FREE(data
.dptr
);
166 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
167 (unsigned int)jobid
));
169 rap_jobid
= SVAL(data
.dptr
, 0);
170 SAFE_FREE(data
.dptr
);
171 SSVAL(buf
,0,rap_jobid
);
173 data
.dsize
= sizeof(rap_jobid
);
174 tdb_delete(rap_tdb
, key
);
175 tdb_delete(rap_tdb
, data
);
178 static int get_queue_status(const char* sharename
, print_status_struct
*);
180 /****************************************************************************
181 Initialise the printing backend. Called once at startup before the fork().
182 ****************************************************************************/
184 bool print_backend_init(struct messaging_context
*msg_ctx
)
186 const char *sversion
= "INFO/version";
187 int services
= lp_numservices();
190 unlink(cache_path("printing.tdb"));
191 mkdir(cache_path("printing"),0755);
193 /* handle a Samba upgrade */
195 for (snum
= 0; snum
< services
; snum
++) {
196 struct tdb_print_db
*pdb
;
197 if (!lp_print_ok(snum
))
200 pdb
= get_print_db_byname(lp_const_servicename(snum
));
203 if (tdb_lock_bystring(pdb
->tdb
, sversion
) == -1) {
204 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum
) ));
205 release_print_db(pdb
);
208 if (tdb_fetch_int32(pdb
->tdb
, sversion
) != PRINT_DATABASE_VERSION
) {
209 tdb_wipe_all(pdb
->tdb
);
210 tdb_store_int32(pdb
->tdb
, sversion
, PRINT_DATABASE_VERSION
);
212 tdb_unlock_bystring(pdb
->tdb
, sversion
);
213 release_print_db(pdb
);
216 close_all_print_db(); /* Don't leave any open. */
218 /* do NT print initialization... */
219 return nt_printing_init(msg_ctx
);
222 /****************************************************************************
223 Shut down printing backend. Called once at shutdown to close the tdb.
224 ****************************************************************************/
226 void printing_end(void)
228 close_all_print_db(); /* Don't leave any open. */
231 /****************************************************************************
232 Retrieve the set of printing functions for a given service. This allows
233 us to set the printer function table based on the value of the 'printing'
236 Use the generic interface as the default and only use cups interface only
237 when asked for (and only when supported)
238 ****************************************************************************/
240 static struct printif
*get_printer_fns_from_type( enum printing_types type
)
242 struct printif
*printer_fns
= &generic_printif
;
245 if ( type
== PRINT_CUPS
) {
246 printer_fns
= &cups_printif
;
248 #endif /* HAVE_CUPS */
251 if ( type
== PRINT_IPRINT
) {
252 printer_fns
= &iprint_printif
;
254 #endif /* HAVE_IPRINT */
256 printer_fns
->type
= type
;
261 static struct printif
*get_printer_fns( int snum
)
263 return get_printer_fns_from_type( (enum printing_types
)lp_printing(snum
) );
267 /****************************************************************************
268 Useful function to generate a tdb key.
269 ****************************************************************************/
271 static TDB_DATA
print_key(uint32 jobid
, uint32
*tmp
)
275 SIVAL(tmp
, 0, jobid
);
276 ret
.dptr
= (uint8
*)tmp
;
277 ret
.dsize
= sizeof(*tmp
);
281 /****************************************************************************
282 Pack the devicemode to store it in a tdb.
283 ****************************************************************************/
284 static int pack_devicemode(struct spoolss_DeviceMode
*devmode
, uint8
*buf
, int buflen
)
286 enum ndr_err_code ndr_err
;
291 ndr_err
= ndr_push_struct_blob(&blob
, talloc_tos(),
293 (ndr_push_flags_fn_t
)
294 ndr_push_spoolss_DeviceMode
);
295 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
296 DEBUG(10, ("pack_devicemode: "
297 "error encoding spoolss_DeviceMode\n"));
304 len
= tdb_pack(buf
, buflen
, "B", blob
.length
, blob
.data
);
307 DEBUG(8, ("Packed devicemode [%s]\n", devmode
->formname
));
314 /****************************************************************************
315 Unpack the devicemode to store it in a tdb.
316 ****************************************************************************/
317 static int unpack_devicemode(TALLOC_CTX
*mem_ctx
,
318 const uint8
*buf
, int buflen
,
319 struct spoolss_DeviceMode
**devmode
)
321 struct spoolss_DeviceMode
*dm
;
322 enum ndr_err_code ndr_err
;
330 len
= tdb_unpack(buf
, buflen
, "B", &data_len
, &data
);
335 dm
= talloc_zero(mem_ctx
, struct spoolss_DeviceMode
);
340 blob
= data_blob_const(data
, data_len
);
342 ndr_err
= ndr_pull_struct_blob(&blob
, dm
, dm
,
343 (ndr_pull_flags_fn_t
)ndr_pull_spoolss_DeviceMode
);
344 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
345 DEBUG(10, ("unpack_devicemode: "
346 "error parsing spoolss_DeviceMode\n"));
350 DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
351 dm
->devicename
, dm
->formname
));
352 if (dm
->driverextra_data
.data
) {
353 DEBUG(8, ("with a private section of %d bytes\n",
354 dm
->__driverextra_length
));
364 /***********************************************************************
365 unpack a pjob from a tdb buffer
366 ***********************************************************************/
368 static int unpack_pjob( uint8
*buf
, int buflen
, struct printjob
*pjob
)
372 uint32 pjpid
, pjsysjob
, pjfd
, pjstarttime
, pjstatus
;
373 uint32 pjsize
, pjpage_count
, pjspooled
, pjsmbjob
;
378 len
+= tdb_unpack(buf
+len
, buflen
-len
, "dddddddddfffff",
397 used
= unpack_devicemode(NULL
, buf
+len
, buflen
-len
, &pjob
->devmode
);
405 pjob
->sysjob
= pjsysjob
;
407 pjob
->starttime
= pjstarttime
;
408 pjob
->status
= pjstatus
;
410 pjob
->page_count
= pjpage_count
;
411 pjob
->spooled
= pjspooled
;
412 pjob
->smbjob
= pjsmbjob
;
418 /****************************************************************************
419 Useful function to find a print job in the database.
420 ****************************************************************************/
422 static struct printjob
*print_job_find(const char *sharename
, uint32 jobid
)
424 static struct printjob pjob
;
427 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
429 DEBUG(10,("print_job_find: looking up job %u for share %s\n",
430 (unsigned int)jobid
, sharename
));
436 ret
= tdb_fetch(pdb
->tdb
, print_key(jobid
, &tmp
));
437 release_print_db(pdb
);
440 DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid
));
444 talloc_free(pjob
.devmode
);
448 if ( unpack_pjob( ret
.dptr
, ret
.dsize
, &pjob
) == -1 ) {
449 DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid
));
456 DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
457 (int)pjob
.sysjob
, (unsigned int)jobid
));
462 /* Convert a unix jobid to a smb jobid */
464 struct unixjob_traverse_state
{
466 uint32 sysjob_to_jobid_value
;
469 static int unixjob_traverse_fn(TDB_CONTEXT
*the_tdb
, TDB_DATA key
,
470 TDB_DATA data
, void *private_data
)
472 struct printjob
*pjob
;
473 struct unixjob_traverse_state
*state
=
474 (struct unixjob_traverse_state
*)private_data
;
476 if (!data
.dptr
|| data
.dsize
== 0)
479 pjob
= (struct printjob
*)data
.dptr
;
480 if (key
.dsize
!= sizeof(uint32
))
483 if (state
->sysjob
== pjob
->sysjob
) {
484 uint32 jobid
= IVAL(key
.dptr
,0);
486 state
->sysjob_to_jobid_value
= jobid
;
493 /****************************************************************************
494 This is a *horribly expensive call as we have to iterate through all the
495 current printer tdb's. Don't do this often ! JRA.
496 ****************************************************************************/
498 uint32
sysjob_to_jobid(int unix_jobid
)
500 int services
= lp_numservices();
502 struct unixjob_traverse_state state
;
504 state
.sysjob
= unix_jobid
;
505 state
.sysjob_to_jobid_value
= (uint32
)-1;
507 for (snum
= 0; snum
< services
; snum
++) {
508 struct tdb_print_db
*pdb
;
509 if (!lp_print_ok(snum
))
511 pdb
= get_print_db_byname(lp_const_servicename(snum
));
515 tdb_traverse(pdb
->tdb
, unixjob_traverse_fn
, &state
);
516 release_print_db(pdb
);
517 if (state
.sysjob_to_jobid_value
!= (uint32
)-1)
518 return state
.sysjob_to_jobid_value
;
523 /****************************************************************************
524 Send notifications based on what has changed after a pjob_store.
525 ****************************************************************************/
527 static const struct {
529 uint32 spoolss_status
;
530 } lpq_to_spoolss_status_map
[] = {
531 { LPQ_QUEUED
, JOB_STATUS_QUEUED
},
532 { LPQ_PAUSED
, JOB_STATUS_PAUSED
},
533 { LPQ_SPOOLING
, JOB_STATUS_SPOOLING
},
534 { LPQ_PRINTING
, JOB_STATUS_PRINTING
},
535 { LPQ_DELETING
, JOB_STATUS_DELETING
},
536 { LPQ_OFFLINE
, JOB_STATUS_OFFLINE
},
537 { LPQ_PAPEROUT
, JOB_STATUS_PAPEROUT
},
538 { LPQ_PRINTED
, JOB_STATUS_PRINTED
},
539 { LPQ_DELETED
, JOB_STATUS_DELETED
},
540 { LPQ_BLOCKED
, JOB_STATUS_BLOCKED_DEVQ
},
541 { LPQ_USER_INTERVENTION
, JOB_STATUS_USER_INTERVENTION
},
545 /* Convert a lpq status value stored in printing.tdb into the
546 appropriate win32 API constant. */
548 static uint32
map_to_spoolss_status(uint32 lpq_status
)
552 while (lpq_to_spoolss_status_map
[i
].lpq_status
!= -1) {
553 if (lpq_to_spoolss_status_map
[i
].lpq_status
== lpq_status
)
554 return lpq_to_spoolss_status_map
[i
].spoolss_status
;
561 /***************************************************************************
562 Append a jobid to the 'jobs changed' list.
563 ***************************************************************************/
565 static bool add_to_jobs_changed(struct tdb_print_db
*pdb
, uint32_t jobid
)
568 uint32_t store_jobid
;
570 SIVAL(&store_jobid
, 0, jobid
);
571 data
.dptr
= (uint8
*) &store_jobid
;
574 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid
));
576 return (tdb_append(pdb
->tdb
, string_tdb_data("INFO/jobs_changed"),
580 /***************************************************************************
581 Remove a jobid from the 'jobs changed' list.
582 ***************************************************************************/
584 static bool remove_from_jobs_changed(const char* sharename
, uint32_t jobid
)
586 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
590 bool gotlock
= False
;
598 key
= string_tdb_data("INFO/jobs_changed");
600 if (tdb_chainlock_with_timeout(pdb
->tdb
, key
, 5) == -1)
605 data
= tdb_fetch(pdb
->tdb
, key
);
607 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0))
610 job_count
= data
.dsize
/ 4;
611 for (i
= 0; i
< job_count
; i
++) {
614 ch_jobid
= IVAL(data
.dptr
, i
*4);
615 if (ch_jobid
== jobid
) {
616 if (i
< job_count
-1 )
617 memmove(data
.dptr
+ (i
*4), data
.dptr
+ (i
*4) + 4, (job_count
- i
- 1)*4 );
619 if (tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
) == -1)
629 tdb_chainunlock(pdb
->tdb
, key
);
630 SAFE_FREE(data
.dptr
);
631 release_print_db(pdb
);
633 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid
));
635 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid
));
639 static void pjob_store_notify(struct tevent_context
*ev
,
640 struct messaging_context
*msg_ctx
,
641 const char* sharename
, uint32 jobid
,
642 struct printjob
*old_data
,
643 struct printjob
*new_data
,
646 bool new_job
= false;
647 bool changed
= false;
649 if (old_data
== NULL
) {
653 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
654 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
655 time first or else we'll end up with potential alignment
656 errors. I don't think the systemtime should be spooled as
657 a string, but this gets us around that error.
658 --jerry (i'll feel dirty for this) */
661 notify_job_submitted(ev
, msg_ctx
,
662 sharename
, jobid
, new_data
->starttime
);
663 notify_job_username(ev
, msg_ctx
,
664 sharename
, jobid
, new_data
->user
);
665 notify_job_name(ev
, msg_ctx
,
666 sharename
, jobid
, new_data
->jobname
);
667 notify_job_status(ev
, msg_ctx
,
668 sharename
, jobid
, map_to_spoolss_status(new_data
->status
));
669 notify_job_total_bytes(ev
, msg_ctx
,
670 sharename
, jobid
, new_data
->size
);
671 notify_job_total_pages(ev
, msg_ctx
,
672 sharename
, jobid
, new_data
->page_count
);
674 if (!strequal(old_data
->jobname
, new_data
->jobname
)) {
675 notify_job_name(ev
, msg_ctx
, sharename
,
676 jobid
, new_data
->jobname
);
680 if (old_data
->status
!= new_data
->status
) {
681 notify_job_status(ev
, msg_ctx
,
683 map_to_spoolss_status(new_data
->status
));
686 if (old_data
->size
!= new_data
->size
) {
687 notify_job_total_bytes(ev
, msg_ctx
,
688 sharename
, jobid
, new_data
->size
);
691 if (old_data
->page_count
!= new_data
->page_count
) {
692 notify_job_total_pages(ev
, msg_ctx
,
694 new_data
->page_count
);
701 /****************************************************************************
702 Store a job structure back to the database.
703 ****************************************************************************/
705 static bool pjob_store(struct tevent_context
*ev
,
706 struct messaging_context
*msg_ctx
,
707 const char* sharename
, uint32 jobid
,
708 struct printjob
*pjob
)
711 TDB_DATA old_data
, new_data
;
713 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
715 int len
, newlen
, buflen
;
723 old_data
= tdb_fetch(pdb
->tdb
, print_key(jobid
, &tmp
));
725 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
732 len
+= tdb_pack(buf
+len
, buflen
-len
, "dddddddddfffff",
734 (uint32
)pjob
->sysjob
,
736 (uint32
)pjob
->starttime
,
737 (uint32
)pjob
->status
,
739 (uint32
)pjob
->page_count
,
740 (uint32
)pjob
->spooled
,
741 (uint32
)pjob
->smbjob
,
748 len
+= pack_devicemode(pjob
->devmode
, buf
+len
, buflen
-len
);
751 buf
= (uint8
*)SMB_REALLOC(buf
, len
);
753 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
758 } while ( buflen
!= len
);
764 new_data
.dsize
= len
;
765 ret
= (tdb_store(pdb
->tdb
, print_key(jobid
, &tmp
), new_data
,
768 /* Send notify updates for what has changed */
771 bool changed
= false;
772 struct printjob old_pjob
;
774 if ( old_data
.dsize
)
776 if ( unpack_pjob( old_data
.dptr
, old_data
.dsize
, &old_pjob
) != -1 )
778 pjob_store_notify(server_event_context(),
780 sharename
, jobid
, &old_pjob
,
783 talloc_free(old_pjob
.devmode
);
786 add_to_jobs_changed(pdb
, jobid
);
793 pjob_store_notify(server_event_context(), msg_ctx
,
794 sharename
, jobid
, NULL
, pjob
,
799 release_print_db(pdb
);
801 SAFE_FREE( old_data
.dptr
);
807 /****************************************************************************
808 Remove a job structure from the database.
809 ****************************************************************************/
811 static void pjob_delete(struct tevent_context
*ev
,
812 struct messaging_context
*msg_ctx
,
813 const char* sharename
, uint32 jobid
)
816 struct printjob
*pjob
;
817 uint32 job_status
= 0;
818 struct tdb_print_db
*pdb
;
820 pdb
= get_print_db_byname( sharename
);
825 pjob
= print_job_find( sharename
, jobid
);
828 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
829 (unsigned int)jobid
));
830 release_print_db(pdb
);
834 /* We must cycle through JOB_STATUS_DELETING and
835 JOB_STATUS_DELETED for the port monitor to delete the job
838 job_status
= JOB_STATUS_DELETING
|JOB_STATUS_DELETED
;
839 notify_job_status(ev
, msg_ctx
, sharename
, jobid
, job_status
);
841 /* Remove from printing.tdb */
843 tdb_delete(pdb
->tdb
, print_key(jobid
, &tmp
));
844 remove_from_jobs_added(sharename
, jobid
);
845 release_print_db( pdb
);
846 rap_jobid_delete(sharename
, jobid
);
849 /****************************************************************************
850 List a unix job in the print database.
851 ****************************************************************************/
853 static void print_unix_job(struct tevent_context
*ev
,
854 struct messaging_context
*msg_ctx
,
855 const char *sharename
, print_queue_struct
*q
,
858 struct printjob pj
, *old_pj
;
860 if (jobid
== (uint32
)-1)
861 jobid
= q
->job
+ UNIX_JOB_START
;
863 /* Preserve the timestamp on an existing unix print job */
865 old_pj
= print_job_find(sharename
, jobid
);
872 pj
.starttime
= old_pj
? old_pj
->starttime
: q
->time
;
873 pj
.status
= q
->status
;
876 fstrcpy(pj
.filename
, old_pj
? old_pj
->filename
: "");
877 if (jobid
< UNIX_JOB_START
) {
879 fstrcpy(pj
.jobname
, old_pj
? old_pj
->jobname
: "Remote Downlevel Document");
882 fstrcpy(pj
.jobname
, old_pj
? old_pj
->jobname
: q
->fs_file
);
884 fstrcpy(pj
.user
, old_pj
? old_pj
->user
: q
->fs_user
);
885 fstrcpy(pj
.queuename
, old_pj
? old_pj
->queuename
: sharename
);
887 pjob_store(ev
, msg_ctx
, sharename
, jobid
, &pj
);
891 struct traverse_struct
{
892 print_queue_struct
*queue
;
893 int qcount
, snum
, maxcount
, total_jobs
;
894 const char *sharename
;
896 const char *lprm_command
;
897 struct printif
*print_if
;
898 struct tevent_context
*ev
;
899 struct messaging_context
*msg_ctx
;
902 /****************************************************************************
903 Utility fn to delete any jobs that are no longer active.
904 ****************************************************************************/
906 static int traverse_fn_delete(TDB_CONTEXT
*t
, TDB_DATA key
, TDB_DATA data
, void *state
)
908 struct traverse_struct
*ts
= (struct traverse_struct
*)state
;
909 struct printjob pjob
;
913 if ( key
.dsize
!= sizeof(jobid
) )
916 jobid
= IVAL(key
.dptr
, 0);
917 if ( unpack_pjob( data
.dptr
, data
.dsize
, &pjob
) == -1 )
919 talloc_free(pjob
.devmode
);
923 /* remove a unix job if it isn't in the system queue any more */
925 for (i
=0;i
<ts
->qcount
;i
++) {
926 uint32 u_jobid
= (ts
->queue
[i
].job
+ UNIX_JOB_START
);
927 if (jobid
== u_jobid
)
930 if (i
== ts
->qcount
) {
931 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
932 (unsigned int)jobid
));
933 pjob_delete(ts
->ev
, ts
->msg_ctx
,
934 ts
->sharename
, jobid
);
938 /* need to continue the the bottom of the function to
939 save the correct attributes */
942 /* maybe it hasn't been spooled yet */
944 /* if a job is not spooled and the process doesn't
945 exist then kill it. This cleans up after smbd
947 if (!process_exists_by_pid(pjob
.pid
)) {
948 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
949 (unsigned int)jobid
, (unsigned int)pjob
.pid
));
950 pjob_delete(ts
->ev
, ts
->msg_ctx
,
951 ts
->sharename
, jobid
);
957 /* this check only makes sense for jobs submitted from Windows clients */
960 for (i
=0;i
<ts
->qcount
;i
++) {
963 if ( pjob
.status
== LPQ_DELETED
)
966 curr_jobid
= print_parse_jobid(ts
->queue
[i
].fs_file
);
968 if (jobid
== curr_jobid
) {
970 /* try to clean up any jobs that need to be deleted */
972 if ( pjob
.status
== LPQ_DELETING
) {
975 result
= (*(ts
->print_if
->job_delete
))(
976 ts
->sharename
, ts
->lprm_command
, &pjob
);
979 /* if we can't delete, then reset the job status */
980 pjob
.status
= LPQ_QUEUED
;
981 pjob_store(ts
->ev
, ts
->msg_ctx
,
982 ts
->sharename
, jobid
, &pjob
);
985 /* if we deleted the job, the remove the tdb record */
988 ts
->sharename
, jobid
);
989 pjob
.status
= LPQ_DELETED
;
999 /* The job isn't in the system queue - we have to assume it has
1000 completed, so delete the database entry. */
1002 if (i
== ts
->qcount
) {
1004 /* A race can occur between the time a job is spooled and
1005 when it appears in the lpq output. This happens when
1006 the job is added to printing.tdb when another smbd
1007 running print_queue_update() has completed a lpq and
1008 is currently traversing the printing tdb and deleting jobs.
1009 Don't delete the job if it was submitted after the lpq_time. */
1011 if (pjob
.starttime
< ts
->lpq_time
) {
1012 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
1013 (unsigned int)jobid
,
1014 (unsigned int)pjob
.starttime
,
1015 (unsigned int)ts
->lpq_time
));
1016 pjob_delete(ts
->ev
, ts
->msg_ctx
,
1017 ts
->sharename
, jobid
);
1023 /* Save the pjob attributes we will store.
1024 FIXME!!! This is the only place where queue->job
1025 represents the SMB jobid --jerry */
1027 ts
->queue
[i
].job
= jobid
;
1028 ts
->queue
[i
].size
= pjob
.size
;
1029 ts
->queue
[i
].page_count
= pjob
.page_count
;
1030 ts
->queue
[i
].status
= pjob
.status
;
1031 ts
->queue
[i
].priority
= 1;
1032 ts
->queue
[i
].time
= pjob
.starttime
;
1033 fstrcpy(ts
->queue
[i
].fs_user
, pjob
.user
);
1034 fstrcpy(ts
->queue
[i
].fs_file
, pjob
.jobname
);
1041 /****************************************************************************
1042 Check if the print queue has been updated recently enough.
1043 ****************************************************************************/
1045 static void print_cache_flush(const char *sharename
)
1048 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1052 slprintf(key
, sizeof(key
)-1, "CACHE/%s", sharename
);
1053 tdb_store_int32(pdb
->tdb
, key
, -1);
1054 release_print_db(pdb
);
1057 /****************************************************************************
1058 Check if someone already thinks they are doing the update.
1059 ****************************************************************************/
1061 static pid_t
get_updating_pid(const char *sharename
)
1066 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1070 slprintf(keystr
, sizeof(keystr
)-1, "UPDATING/%s", sharename
);
1071 key
= string_tdb_data(keystr
);
1073 data
= tdb_fetch(pdb
->tdb
, key
);
1074 release_print_db(pdb
);
1075 if (!data
.dptr
|| data
.dsize
!= sizeof(pid_t
)) {
1076 SAFE_FREE(data
.dptr
);
1080 updating_pid
= IVAL(data
.dptr
, 0);
1081 SAFE_FREE(data
.dptr
);
1083 if (process_exists_by_pid(updating_pid
))
1084 return updating_pid
;
1089 /****************************************************************************
1090 Set the fact that we're doing the update, or have finished doing the update
1092 ****************************************************************************/
1094 static void set_updating_pid(const fstring sharename
, bool updating
)
1099 pid_t updating_pid
= sys_getpid();
1102 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1107 slprintf(keystr
, sizeof(keystr
)-1, "UPDATING/%s", sharename
);
1108 key
= string_tdb_data(keystr
);
1110 DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
1111 updating
? "" : "not ",
1115 tdb_delete(pdb
->tdb
, key
);
1116 release_print_db(pdb
);
1120 SIVAL( buffer
, 0, updating_pid
);
1122 data
.dsize
= 4; /* we always assume this is a 4 byte value */
1124 tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
);
1125 release_print_db(pdb
);
1128 /****************************************************************************
1129 Sort print jobs by submittal time.
1130 ****************************************************************************/
1132 static int printjob_comp(print_queue_struct
*j1
, print_queue_struct
*j2
)
1143 /* Sort on job start time */
1145 if (j1
->time
== j2
->time
)
1147 return (j1
->time
> j2
->time
) ? 1 : -1;
1150 /****************************************************************************
1151 Store the sorted queue representation for later portmon retrieval.
1153 ****************************************************************************/
1155 static void store_queue_struct(struct tdb_print_db
*pdb
, struct traverse_struct
*pts
)
1158 int max_reported_jobs
= lp_max_reported_jobs(pts
->snum
);
1159 print_queue_struct
*queue
= pts
->queue
;
1162 unsigned int qcount
;
1164 if (max_reported_jobs
&& (max_reported_jobs
< pts
->qcount
))
1165 pts
->qcount
= max_reported_jobs
;
1168 /* Work out the size. */
1170 data
.dsize
+= tdb_pack(NULL
, 0, "d", qcount
);
1172 for (i
= 0; i
< pts
->qcount
; i
++) {
1173 if ( queue
[i
].status
== LPQ_DELETED
)
1177 data
.dsize
+= tdb_pack(NULL
, 0, "ddddddff",
1178 (uint32
)queue
[i
].job
,
1179 (uint32
)queue
[i
].size
,
1180 (uint32
)queue
[i
].page_count
,
1181 (uint32
)queue
[i
].status
,
1182 (uint32
)queue
[i
].priority
,
1183 (uint32
)queue
[i
].time
,
1188 if ((data
.dptr
= (uint8
*)SMB_MALLOC(data
.dsize
)) == NULL
)
1192 len
+= tdb_pack(data
.dptr
+ len
, data
.dsize
- len
, "d", qcount
);
1193 for (i
= 0; i
< pts
->qcount
; i
++) {
1194 if ( queue
[i
].status
== LPQ_DELETED
)
1197 len
+= tdb_pack(data
.dptr
+ len
, data
.dsize
- len
, "ddddddff",
1198 (uint32
)queue
[i
].job
,
1199 (uint32
)queue
[i
].size
,
1200 (uint32
)queue
[i
].page_count
,
1201 (uint32
)queue
[i
].status
,
1202 (uint32
)queue
[i
].priority
,
1203 (uint32
)queue
[i
].time
,
1208 tdb_store(pdb
->tdb
, string_tdb_data("INFO/linear_queue_array"), data
,
1210 SAFE_FREE(data
.dptr
);
1214 static TDB_DATA
get_jobs_added_data(struct tdb_print_db
*pdb
)
1220 data
= tdb_fetch(pdb
->tdb
, string_tdb_data("INFO/jobs_added"));
1221 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0)) {
1222 SAFE_FREE(data
.dptr
);
1229 static void check_job_added(const char *sharename
, TDB_DATA data
, uint32 jobid
)
1232 unsigned int job_count
= data
.dsize
/ 4;
1234 for (i
= 0; i
< job_count
; i
++) {
1237 ch_jobid
= IVAL(data
.dptr
, i
*4);
1238 if (ch_jobid
== jobid
)
1239 remove_from_jobs_added(sharename
, jobid
);
1243 /****************************************************************************
1244 Check if the print queue has been updated recently enough.
1245 ****************************************************************************/
1247 static bool print_cache_expired(const char *sharename
, bool check_pending
)
1250 time_t last_qscan_time
, time_now
= time(NULL
);
1251 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1252 bool result
= False
;
1257 snprintf(key
, sizeof(key
), "CACHE/%s", sharename
);
1258 last_qscan_time
= (time_t)tdb_fetch_int32(pdb
->tdb
, key
);
1261 * Invalidate the queue for 3 reasons.
1262 * (1). last queue scan time == -1.
1263 * (2). Current time - last queue scan time > allowed cache time.
1264 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1265 * This last test picks up machines for which the clock has been moved
1266 * forward, an lpq scan done and then the clock moved back. Otherwise
1267 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1270 if (last_qscan_time
== ((time_t)-1)
1271 || (time_now
- last_qscan_time
) >= lp_lpqcachetime()
1272 || last_qscan_time
> (time_now
+ MAX_CACHE_VALID_TIME
))
1275 time_t msg_pending_time
;
1277 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1278 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1279 sharename
, (int)last_qscan_time
, (int)time_now
,
1280 (int)lp_lpqcachetime() ));
1282 /* check if another smbd has already sent a message to update the
1283 queue. Give the pending message one minute to clear and
1284 then send another message anyways. Make sure to check for
1285 clocks that have been run forward and then back again. */
1287 snprintf(key
, sizeof(key
), "MSG_PENDING/%s", sharename
);
1290 && tdb_fetch_uint32( pdb
->tdb
, key
, &u
)
1291 && (msg_pending_time
=u
) > 0
1292 && msg_pending_time
<= time_now
1293 && (time_now
- msg_pending_time
) < 60 )
1295 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1304 release_print_db(pdb
);
1308 /****************************************************************************
1309 main work for updating the lpq cahe for a printer queue
1310 ****************************************************************************/
1312 static void print_queue_update_internal( struct tevent_context
*ev
,
1313 struct messaging_context
*msg_ctx
,
1314 const char *sharename
,
1315 struct printif
*current_printif
,
1316 char *lpq_command
, char *lprm_command
)
1319 print_queue_struct
*queue
= NULL
;
1320 print_status_struct status
;
1321 print_status_struct old_status
;
1322 struct printjob
*pjob
;
1323 struct traverse_struct tstruct
;
1326 fstring keystr
, cachestr
;
1327 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1333 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1334 sharename
, current_printif
->type
, lpq_command
));
1337 * Update the cache time FIRST ! Stops others even
1338 * attempting to get the lock and doing this
1339 * if the lpq takes a long time.
1342 slprintf(cachestr
, sizeof(cachestr
)-1, "CACHE/%s", sharename
);
1343 tdb_store_int32(pdb
->tdb
, cachestr
, (int)time(NULL
));
1345 /* get the current queue using the appropriate interface */
1346 ZERO_STRUCT(status
);
1348 qcount
= (*(current_printif
->queue_get
))(sharename
,
1349 current_printif
->type
,
1350 lpq_command
, &queue
, &status
);
1352 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1353 qcount
, (qcount
!= 1) ? "s" : "", sharename
));
1355 /* Sort the queue by submission time otherwise they are displayed
1358 TYPESAFE_QSORT(queue
, qcount
, printjob_comp
);
1361 any job in the internal database that is marked as spooled
1362 and doesn't exist in the system queue is considered finished
1363 and removed from the database
1365 any job in the system database but not in the internal database
1366 is added as a unix job
1368 fill in any system job numbers as we go
1371 jcdata
= get_jobs_added_data(pdb
);
1373 for (i
=0; i
<qcount
; i
++) {
1374 uint32 jobid
= print_parse_jobid(queue
[i
].fs_file
);
1376 if (jobid
== (uint32
)-1) {
1377 /* assume its a unix print job */
1378 print_unix_job(ev
, msg_ctx
,
1379 sharename
, &queue
[i
], jobid
);
1383 /* we have an active SMB print job - update its status */
1384 pjob
= print_job_find(sharename
, jobid
);
1386 /* err, somethings wrong. Probably smbd was restarted
1387 with jobs in the queue. All we can do is treat them
1388 like unix jobs. Pity. */
1389 print_unix_job(ev
, msg_ctx
,
1390 sharename
, &queue
[i
], jobid
);
1394 pjob
->sysjob
= queue
[i
].job
;
1396 /* don't reset the status on jobs to be deleted */
1398 if ( pjob
->status
!= LPQ_DELETING
)
1399 pjob
->status
= queue
[i
].status
;
1401 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
1403 check_job_added(sharename
, jcdata
, jobid
);
1406 SAFE_FREE(jcdata
.dptr
);
1408 /* now delete any queued entries that don't appear in the
1410 tstruct
.queue
= queue
;
1411 tstruct
.qcount
= qcount
;
1413 tstruct
.total_jobs
= 0;
1414 tstruct
.lpq_time
= time(NULL
);
1415 tstruct
.sharename
= sharename
;
1416 tstruct
.lprm_command
= lprm_command
;
1417 tstruct
.print_if
= current_printif
;
1419 tstruct
.msg_ctx
= msg_ctx
;
1421 tdb_traverse(pdb
->tdb
, traverse_fn_delete
, (void *)&tstruct
);
1423 /* Store the linearised queue, max jobs only. */
1424 store_queue_struct(pdb
, &tstruct
);
1426 SAFE_FREE(tstruct
.queue
);
1428 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1429 sharename
, tstruct
.total_jobs
));
1431 tdb_store_int32(pdb
->tdb
, "INFO/total_jobs", tstruct
.total_jobs
);
1433 get_queue_status(sharename
, &old_status
);
1434 if (old_status
.qcount
!= qcount
)
1435 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1436 old_status
.qcount
, qcount
, sharename
));
1438 /* store the new queue status structure */
1439 slprintf(keystr
, sizeof(keystr
)-1, "STATUS/%s", sharename
);
1440 key
= string_tdb_data(keystr
);
1442 status
.qcount
= qcount
;
1443 data
.dptr
= (uint8
*)&status
;
1444 data
.dsize
= sizeof(status
);
1445 tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
);
1448 * Update the cache time again. We want to do this call
1449 * as little as possible...
1452 slprintf(keystr
, sizeof(keystr
)-1, "CACHE/%s", sharename
);
1453 tdb_store_int32(pdb
->tdb
, keystr
, (int32
)time(NULL
));
1455 /* clear the msg pending record for this queue */
1457 snprintf(keystr
, sizeof(keystr
), "MSG_PENDING/%s", sharename
);
1459 if ( !tdb_store_uint32( pdb
->tdb
, keystr
, 0 ) ) {
1460 /* log a message but continue on */
1462 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1466 release_print_db( pdb
);
1471 /****************************************************************************
1472 Update the internal database from the system print queue for a queue.
1473 obtain a lock on the print queue before proceeding (needed when mutiple
1474 smbd processes maytry to update the lpq cache concurrently).
1475 ****************************************************************************/
1477 static void print_queue_update_with_lock( struct tevent_context
*ev
,
1478 struct messaging_context
*msg_ctx
,
1479 const char *sharename
,
1480 struct printif
*current_printif
,
1481 char *lpq_command
, char *lprm_command
)
1484 struct tdb_print_db
*pdb
;
1486 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename
));
1487 pdb
= get_print_db_byname(sharename
);
1491 if ( !print_cache_expired(sharename
, False
) ) {
1492 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename
));
1493 release_print_db(pdb
);
1498 * Check to see if someone else is doing this update.
1499 * This is essentially a mutex on the update.
1502 if (get_updating_pid(sharename
) != -1) {
1503 release_print_db(pdb
);
1507 /* Lock the queue for the database update */
1509 slprintf(keystr
, sizeof(keystr
) - 1, "LOCK/%s", sharename
);
1510 /* Only wait 10 seconds for this. */
1511 if (tdb_lock_bystring_with_timeout(pdb
->tdb
, keystr
, 10) == -1) {
1512 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename
));
1513 release_print_db(pdb
);
1518 * Ensure that no one else got in here.
1519 * If the updating pid is still -1 then we are
1523 if (get_updating_pid(sharename
) != -1) {
1525 * Someone else is doing the update, exit.
1527 tdb_unlock_bystring(pdb
->tdb
, keystr
);
1528 release_print_db(pdb
);
1533 * We're going to do the update ourselves.
1536 /* Tell others we're doing the update. */
1537 set_updating_pid(sharename
, True
);
1540 * Allow others to enter and notice we're doing
1544 tdb_unlock_bystring(pdb
->tdb
, keystr
);
1546 /* do the main work now */
1548 print_queue_update_internal(ev
, msg_ctx
,
1549 sharename
, current_printif
,
1550 lpq_command
, lprm_command
);
1552 /* Delete our pid from the db. */
1553 set_updating_pid(sharename
, False
);
1554 release_print_db(pdb
);
1557 /****************************************************************************
1558 this is the receive function of the background lpq updater
1559 ****************************************************************************/
1560 static void print_queue_receive(struct messaging_context
*msg
,
1563 struct server_id server_id
,
1567 char *lpqcommand
= NULL
, *lprmcommand
= NULL
;
1571 len
= tdb_unpack( (uint8
*)data
->data
, data
->length
, "fdPP",
1578 SAFE_FREE(lpqcommand
);
1579 SAFE_FREE(lprmcommand
);
1580 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1584 print_queue_update_with_lock(server_event_context(), msg
, sharename
,
1585 get_printer_fns_from_type((enum printing_types
)printing_type
),
1586 lpqcommand
, lprmcommand
);
1588 SAFE_FREE(lpqcommand
);
1589 SAFE_FREE(lprmcommand
);
1593 static void printing_pause_fd_handler(struct tevent_context
*ev
,
1594 struct tevent_fd
*fde
,
1599 * If pause_pipe[1] is closed it means the parent smbd
1600 * and children exited or aborted.
1602 exit_server_cleanly(NULL
);
1605 extern struct child_pid
*children
;
1606 extern int num_children
;
1608 static void add_child_pid(pid_t pid
)
1610 struct child_pid
*child
;
1612 child
= SMB_MALLOC_P(struct child_pid
);
1613 if (child
== NULL
) {
1614 DEBUG(0, ("Could not add child struct -- malloc failed\n"));
1618 DLIST_ADD(children
, child
);
1622 static pid_t background_lpq_updater_pid
= -1;
1624 /****************************************************************************
1625 main thread of the background lpq updater
1626 ****************************************************************************/
1627 void start_background_queue(struct tevent_context
*ev
,
1628 struct messaging_context
*msg_ctx
)
1630 /* Use local variables for this as we don't
1631 * need to save the parent side of this, just
1632 * ensure it closes when the process exits.
1636 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1638 if (pipe(pause_pipe
) == -1) {
1639 DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno
) ));
1643 background_lpq_updater_pid
= sys_fork();
1645 if (background_lpq_updater_pid
== -1) {
1646 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno
) ));
1650 /* Track the printing pid along with other smbd children */
1651 add_child_pid(background_lpq_updater_pid
);
1653 if(background_lpq_updater_pid
== 0) {
1654 struct tevent_fd
*fde
;
1659 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1661 close(pause_pipe
[0]);
1664 status
= reinit_after_fork(msg_ctx
, ev
, procid_self(), true);
1666 if (!NT_STATUS_IS_OK(status
)) {
1667 DEBUG(0,("reinit_after_fork() failed\n"));
1668 smb_panic("reinit_after_fork() failed");
1671 smbd_setup_sig_term_handler();
1672 smbd_setup_sig_hup_handler(ev
, msg_ctx
);
1674 if (!serverid_register(procid_self(),
1675 FLAG_MSG_GENERAL
|FLAG_MSG_SMBD
1676 |FLAG_MSG_PRINT_GENERAL
)) {
1680 if (!locking_init()) {
1684 messaging_register(msg_ctx
, NULL
, MSG_PRINTER_UPDATE
,
1685 print_queue_receive
);
1687 fde
= tevent_add_fd(ev
, ev
, pause_pipe
[1], TEVENT_FD_READ
,
1688 printing_pause_fd_handler
,
1691 DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
1692 smb_panic("tevent_add_fd() failed for pause_pipe");
1695 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1696 ret
= tevent_loop_wait(ev
);
1697 /* should not be reached */
1698 DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
1699 ret
, (ret
== 0) ? "out of events" : strerror(errno
)));
1703 close(pause_pipe
[1]);
1706 /****************************************************************************
1707 update the internal database from the system print queue for a queue
1708 ****************************************************************************/
1710 static void print_queue_update(struct messaging_context
*msg_ctx
,
1711 int snum
, bool force
)
1715 char *lpqcommand
= NULL
;
1716 char *lprmcommand
= NULL
;
1717 uint8
*buffer
= NULL
;
1720 struct tdb_print_db
*pdb
;
1722 struct printif
*current_printif
;
1723 TALLOC_CTX
*ctx
= talloc_tos();
1725 fstrcpy( sharename
, lp_const_servicename(snum
));
1727 /* don't strip out characters like '$' from the printername */
1729 lpqcommand
= talloc_string_sub2(ctx
,
1730 lp_lpqcommand(snum
),
1732 lp_printername(snum
),
1733 false, false, false);
1737 lpqcommand
= talloc_sub_advanced(ctx
,
1738 lp_servicename(snum
),
1739 current_user_info
.unix_name
,
1741 current_user
.ut
.gid
,
1742 get_current_username(),
1743 current_user_info
.domain
,
1749 lprmcommand
= talloc_string_sub2(ctx
,
1750 lp_lprmcommand(snum
),
1752 lp_printername(snum
),
1753 false, false, false);
1757 lprmcommand
= talloc_sub_advanced(ctx
,
1758 lp_servicename(snum
),
1759 current_user_info
.unix_name
,
1761 current_user
.ut
.gid
,
1762 get_current_username(),
1763 current_user_info
.domain
,
1770 * Make sure that the background queue process exists.
1771 * Otherwise just do the update ourselves
1774 if ( force
|| background_lpq_updater_pid
== -1 ) {
1775 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename
));
1776 current_printif
= get_printer_fns( snum
);
1777 print_queue_update_with_lock(server_event_context(), msg_ctx
,
1778 sharename
, current_printif
,
1779 lpqcommand
, lprmcommand
);
1784 type
= lp_printing(snum
);
1786 /* get the length */
1788 len
= tdb_pack( NULL
, 0, "fdPP",
1794 buffer
= SMB_XMALLOC_ARRAY( uint8
, len
);
1796 /* now pack the buffer */
1797 newlen
= tdb_pack( buffer
, len
, "fdPP",
1803 SMB_ASSERT( newlen
== len
);
1805 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1806 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1807 sharename
, type
, lpqcommand
, lprmcommand
));
1809 /* here we set a msg pending record for other smbd processes
1810 to throttle the number of duplicate print_queue_update msgs
1813 pdb
= get_print_db_byname(sharename
);
1819 snprintf(key
, sizeof(key
), "MSG_PENDING/%s", sharename
);
1821 if ( !tdb_store_uint32( pdb
->tdb
, key
, time(NULL
) ) ) {
1822 /* log a message but continue on */
1824 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1828 release_print_db( pdb
);
1830 /* finally send the message */
1832 messaging_send_buf(msg_ctx
, pid_to_procid(background_lpq_updater_pid
),
1833 MSG_PRINTER_UPDATE
, (uint8
*)buffer
, len
);
1835 SAFE_FREE( buffer
);
1840 /****************************************************************************
1841 Create/Update an entry in the print tdb that will allow us to send notify
1842 updates only to interested smbd's.
1843 ****************************************************************************/
1845 bool print_notify_register_pid(int snum
)
1848 struct tdb_print_db
*pdb
= NULL
;
1849 TDB_CONTEXT
*tdb
= NULL
;
1850 const char *printername
;
1851 uint32 mypid
= (uint32
)sys_getpid();
1855 /* if (snum == -1), then the change notify request was
1856 on a print server handle and we need to register on
1861 int num_services
= lp_numservices();
1864 for ( idx
=0; idx
<num_services
; idx
++ ) {
1865 if (lp_snum_ok(idx
) && lp_print_ok(idx
) )
1866 print_notify_register_pid(idx
);
1871 else /* register for a specific printer */
1873 printername
= lp_const_servicename(snum
);
1874 pdb
= get_print_db_byname(printername
);
1880 if (tdb_lock_bystring_with_timeout(tdb
, NOTIFY_PID_LIST_KEY
, 10) == -1) {
1881 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1884 release_print_db(pdb
);
1888 data
= get_printer_notify_pid_list( tdb
, printername
, True
);
1890 /* Add ourselves and increase the refcount. */
1892 for (i
= 0; i
< data
.dsize
; i
+= 8) {
1893 if (IVAL(data
.dptr
,i
) == mypid
) {
1894 uint32 new_refcount
= IVAL(data
.dptr
, i
+4) + 1;
1895 SIVAL(data
.dptr
, i
+4, new_refcount
);
1900 if (i
== data
.dsize
) {
1901 /* We weren't in the list. Realloc. */
1902 data
.dptr
= (uint8
*)SMB_REALLOC(data
.dptr
, data
.dsize
+ 8);
1904 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1909 SIVAL(data
.dptr
,data
.dsize
- 8,mypid
);
1910 SIVAL(data
.dptr
,data
.dsize
- 4,1); /* Refcount. */
1913 /* Store back the record. */
1914 if (tdb_store_bystring(tdb
, NOTIFY_PID_LIST_KEY
, data
, TDB_REPLACE
) == -1) {
1915 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1916 list for printer %s\n", printername
));
1924 tdb_unlock_bystring(tdb
, NOTIFY_PID_LIST_KEY
);
1926 release_print_db(pdb
);
1927 SAFE_FREE(data
.dptr
);
1931 /****************************************************************************
1932 Update an entry in the print tdb that will allow us to send notify
1933 updates only to interested smbd's.
1934 ****************************************************************************/
1936 bool print_notify_deregister_pid(int snum
)
1939 struct tdb_print_db
*pdb
= NULL
;
1940 TDB_CONTEXT
*tdb
= NULL
;
1941 const char *printername
;
1942 uint32 mypid
= (uint32
)sys_getpid();
1946 /* if ( snum == -1 ), we are deregister a print server handle
1947 which means to deregister on all print queues */
1951 int num_services
= lp_numservices();
1954 for ( idx
=0; idx
<num_services
; idx
++ ) {
1955 if ( lp_snum_ok(idx
) && lp_print_ok(idx
) )
1956 print_notify_deregister_pid(idx
);
1961 else /* deregister a specific printer */
1963 printername
= lp_const_servicename(snum
);
1964 pdb
= get_print_db_byname(printername
);
1970 if (tdb_lock_bystring_with_timeout(tdb
, NOTIFY_PID_LIST_KEY
, 10) == -1) {
1971 DEBUG(0,("print_notify_register_pid: Failed to lock \
1972 printer %s database\n", printername
));
1974 release_print_db(pdb
);
1978 data
= get_printer_notify_pid_list( tdb
, printername
, True
);
1980 /* Reduce refcount. Remove ourselves if zero. */
1982 for (i
= 0; i
< data
.dsize
; ) {
1983 if (IVAL(data
.dptr
,i
) == mypid
) {
1984 uint32 refcount
= IVAL(data
.dptr
, i
+4);
1988 if (refcount
== 0) {
1989 if (data
.dsize
- i
> 8)
1990 memmove( &data
.dptr
[i
], &data
.dptr
[i
+8], data
.dsize
- i
- 8);
1994 SIVAL(data
.dptr
, i
+4, refcount
);
2000 if (data
.dsize
== 0)
2001 SAFE_FREE(data
.dptr
);
2003 /* Store back the record. */
2004 if (tdb_store_bystring(tdb
, NOTIFY_PID_LIST_KEY
, data
, TDB_REPLACE
) == -1) {
2005 DEBUG(0,("print_notify_register_pid: Failed to update pid \
2006 list for printer %s\n", printername
));
2014 tdb_unlock_bystring(tdb
, NOTIFY_PID_LIST_KEY
);
2016 release_print_db(pdb
);
2017 SAFE_FREE(data
.dptr
);
2021 /****************************************************************************
2022 Check if a jobid is valid. It is valid if it exists in the database.
2023 ****************************************************************************/
2025 bool print_job_exists(const char* sharename
, uint32 jobid
)
2027 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2033 ret
= tdb_exists(pdb
->tdb
, print_key(jobid
, &tmp
));
2034 release_print_db(pdb
);
2038 /****************************************************************************
2039 Give the filename used for a jobid.
2040 Only valid for the process doing the spooling and when the job
2041 has not been spooled.
2042 ****************************************************************************/
2044 char *print_job_fname(const char* sharename
, uint32 jobid
)
2046 struct printjob
*pjob
= print_job_find(sharename
, jobid
);
2047 if (!pjob
|| pjob
->spooled
|| pjob
->pid
!= sys_getpid())
2049 return pjob
->filename
;
2053 /****************************************************************************
2054 Give the filename used for a jobid.
2055 Only valid for the process doing the spooling and when the job
2056 has not been spooled.
2057 ****************************************************************************/
2059 struct spoolss_DeviceMode
*print_job_devmode(const char* sharename
, uint32 jobid
)
2061 struct printjob
*pjob
= print_job_find(sharename
, jobid
);
2066 return pjob
->devmode
;
2069 /****************************************************************************
2070 Set the name of a job. Only possible for owner.
2071 ****************************************************************************/
2073 bool print_job_set_name(struct tevent_context
*ev
,
2074 struct messaging_context
*msg_ctx
,
2075 const char *sharename
, uint32 jobid
, const char *name
)
2077 struct printjob
*pjob
;
2079 pjob
= print_job_find(sharename
, jobid
);
2080 if (!pjob
|| pjob
->pid
!= sys_getpid())
2083 fstrcpy(pjob
->jobname
, name
);
2084 return pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2087 /****************************************************************************
2088 Get the name of a job. Only possible for owner.
2089 ****************************************************************************/
2091 bool print_job_get_name(TALLOC_CTX
*mem_ctx
, const char *sharename
, uint32_t jobid
, char **name
)
2093 struct printjob
*pjob
;
2095 pjob
= print_job_find(sharename
, jobid
);
2096 if (!pjob
|| pjob
->pid
!= sys_getpid()) {
2100 *name
= talloc_strdup(mem_ctx
, pjob
->jobname
);
2109 /***************************************************************************
2110 Remove a jobid from the 'jobs added' list.
2111 ***************************************************************************/
2113 static bool remove_from_jobs_added(const char* sharename
, uint32 jobid
)
2115 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2117 size_t job_count
, i
;
2119 bool gotlock
= False
;
2127 key
= string_tdb_data("INFO/jobs_added");
2129 if (tdb_chainlock_with_timeout(pdb
->tdb
, key
, 5) == -1)
2134 data
= tdb_fetch(pdb
->tdb
, key
);
2136 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0))
2139 job_count
= data
.dsize
/ 4;
2140 for (i
= 0; i
< job_count
; i
++) {
2143 ch_jobid
= IVAL(data
.dptr
, i
*4);
2144 if (ch_jobid
== jobid
) {
2145 if (i
< job_count
-1 )
2146 memmove(data
.dptr
+ (i
*4), data
.dptr
+ (i
*4) + 4, (job_count
- i
- 1)*4 );
2148 if (tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
) == -1)
2158 tdb_chainunlock(pdb
->tdb
, key
);
2159 SAFE_FREE(data
.dptr
);
2160 release_print_db(pdb
);
2162 DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid
));
2164 DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid
));
2168 /****************************************************************************
2169 Delete a print job - don't update queue.
2170 ****************************************************************************/
2172 static bool print_job_delete1(struct tevent_context
*ev
,
2173 struct messaging_context
*msg_ctx
,
2174 int snum
, uint32 jobid
)
2176 const char* sharename
= lp_const_servicename(snum
);
2177 struct printjob
*pjob
= print_job_find(sharename
, jobid
);
2179 struct printif
*current_printif
= get_printer_fns( snum
);
2185 * If already deleting just return.
2188 if (pjob
->status
== LPQ_DELETING
)
2191 /* Hrm - we need to be able to cope with deleting a job before it
2192 has reached the spooler. Just mark it as LPQ_DELETING and
2193 let the print_queue_update() code rmeove the record */
2196 if (pjob
->sysjob
== -1) {
2197 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid
));
2200 /* Set the tdb entry to be deleting. */
2202 pjob
->status
= LPQ_DELETING
;
2203 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2205 if (pjob
->spooled
&& pjob
->sysjob
!= -1)
2207 result
= (*(current_printif
->job_delete
))(
2208 lp_printername(snum
),
2209 lp_lprmcommand(snum
),
2212 /* Delete the tdb entry if the delete succeeded or the job hasn't
2216 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2221 pjob_delete(ev
, msg_ctx
, sharename
, jobid
);
2222 /* Ensure we keep a rough count of the number of total jobs... */
2223 tdb_change_int32_atomic(pdb
->tdb
, "INFO/total_jobs", &njobs
, -1);
2224 release_print_db(pdb
);
2228 remove_from_jobs_added( sharename
, jobid
);
2230 return (result
== 0);
2233 /****************************************************************************
2234 Return true if the current user owns the print job.
2235 ****************************************************************************/
2237 static bool is_owner(const struct auth_serversupplied_info
*server_info
,
2238 const char *servicename
,
2241 struct printjob
*pjob
= print_job_find(servicename
, jobid
);
2243 if (!pjob
|| !server_info
)
2246 return strequal(pjob
->user
, server_info
->sanitized_username
);
2249 /****************************************************************************
2251 ****************************************************************************/
2253 WERROR
print_job_delete(const struct auth_serversupplied_info
*server_info
,
2254 struct messaging_context
*msg_ctx
,
2255 int snum
, uint32_t jobid
)
2257 const char* sharename
= lp_const_servicename(snum
);
2258 struct printjob
*pjob
;
2262 owner
= is_owner(server_info
, lp_const_servicename(snum
), jobid
);
2264 /* Check access against security descriptor or whether the user
2268 !print_access_check(server_info
, msg_ctx
, snum
,
2269 JOB_ACCESS_ADMINISTER
)) {
2270 DEBUG(3, ("delete denied by security descriptor\n"));
2272 /* BEGIN_ADMIN_LOG */
2273 sys_adminlog( LOG_ERR
,
2274 "Permission denied-- user not allowed to delete, \
2275 pause, or resume print job. User name: %s. Printer name: %s.",
2276 uidtoname(server_info
->utok
.uid
),
2277 lp_printername(snum
) );
2280 return WERR_ACCESS_DENIED
;
2284 * get the spooled filename of the print job
2285 * if this works, then the file has not been spooled
2286 * to the underlying print system. Just delete the
2287 * spool file & return.
2290 fname
= print_job_fname(sharename
, jobid
);
2291 if (fname
!= NULL
) {
2292 /* remove the spool file */
2293 DEBUG(10, ("print_job_delete: "
2294 "Removing spool file [%s]\n", fname
));
2295 if (unlink(fname
) == -1) {
2296 return map_werror_from_unix(errno
);
2300 if (!print_job_delete1(server_event_context(), msg_ctx
, snum
, jobid
)) {
2301 return WERR_ACCESS_DENIED
;
2304 /* force update the database and say the delete failed if the
2307 print_queue_update(msg_ctx
, snum
, True
);
2309 pjob
= print_job_find(sharename
, jobid
);
2310 if (pjob
&& (pjob
->status
!= LPQ_DELETING
)) {
2311 return WERR_ACCESS_DENIED
;
2314 return WERR_PRINTER_HAS_JOBS_QUEUED
;
2317 /****************************************************************************
2319 ****************************************************************************/
2321 bool print_job_pause(const struct auth_serversupplied_info
*server_info
,
2322 struct messaging_context
*msg_ctx
,
2323 int snum
, uint32 jobid
, WERROR
*errcode
)
2325 const char* sharename
= lp_const_servicename(snum
);
2326 struct printjob
*pjob
;
2328 struct printif
*current_printif
= get_printer_fns( snum
);
2330 pjob
= print_job_find(sharename
, jobid
);
2332 if (!pjob
|| !server_info
) {
2333 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2334 (unsigned int)jobid
));
2338 if (!pjob
->spooled
|| pjob
->sysjob
== -1) {
2339 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2340 (int)pjob
->sysjob
, (unsigned int)jobid
));
2344 if (!is_owner(server_info
, lp_const_servicename(snum
), jobid
) &&
2345 !print_access_check(server_info
, msg_ctx
, snum
,
2346 JOB_ACCESS_ADMINISTER
)) {
2347 DEBUG(3, ("pause denied by security descriptor\n"));
2349 /* BEGIN_ADMIN_LOG */
2350 sys_adminlog( LOG_ERR
,
2351 "Permission denied-- user not allowed to delete, \
2352 pause, or resume print job. User name: %s. Printer name: %s.",
2353 uidtoname(server_info
->utok
.uid
),
2354 lp_printername(snum
) );
2357 *errcode
= WERR_ACCESS_DENIED
;
2361 /* need to pause the spooled entry */
2362 ret
= (*(current_printif
->job_pause
))(snum
, pjob
);
2365 *errcode
= WERR_INVALID_PARAM
;
2369 /* force update the database */
2370 print_cache_flush(lp_const_servicename(snum
));
2372 /* Send a printer notify message */
2374 notify_job_status(server_event_context(), msg_ctx
, sharename
, jobid
,
2377 /* how do we tell if this succeeded? */
2382 /****************************************************************************
2384 ****************************************************************************/
2386 bool print_job_resume(const struct auth_serversupplied_info
*server_info
,
2387 struct messaging_context
*msg_ctx
,
2388 int snum
, uint32 jobid
, WERROR
*errcode
)
2390 const char *sharename
= lp_const_servicename(snum
);
2391 struct printjob
*pjob
;
2393 struct printif
*current_printif
= get_printer_fns( snum
);
2395 pjob
= print_job_find(sharename
, jobid
);
2397 if (!pjob
|| !server_info
) {
2398 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2399 (unsigned int)jobid
));
2403 if (!pjob
->spooled
|| pjob
->sysjob
== -1) {
2404 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2405 (int)pjob
->sysjob
, (unsigned int)jobid
));
2409 if (!is_owner(server_info
, lp_const_servicename(snum
), jobid
) &&
2410 !print_access_check(server_info
, msg_ctx
, snum
,
2411 JOB_ACCESS_ADMINISTER
)) {
2412 DEBUG(3, ("resume denied by security descriptor\n"));
2413 *errcode
= WERR_ACCESS_DENIED
;
2415 /* BEGIN_ADMIN_LOG */
2416 sys_adminlog( LOG_ERR
,
2417 "Permission denied-- user not allowed to delete, \
2418 pause, or resume print job. User name: %s. Printer name: %s.",
2419 uidtoname(server_info
->utok
.uid
),
2420 lp_printername(snum
) );
2425 ret
= (*(current_printif
->job_resume
))(snum
, pjob
);
2428 *errcode
= WERR_INVALID_PARAM
;
2432 /* force update the database */
2433 print_cache_flush(lp_const_servicename(snum
));
2435 /* Send a printer notify message */
2437 notify_job_status(server_event_context(), msg_ctx
, sharename
, jobid
,
2443 /****************************************************************************
2444 Write to a print file.
2445 ****************************************************************************/
2447 ssize_t
print_job_write(struct tevent_context
*ev
,
2448 struct messaging_context
*msg_ctx
,
2449 int snum
, uint32 jobid
, const char *buf
, size_t size
)
2451 const char* sharename
= lp_const_servicename(snum
);
2452 ssize_t return_code
;
2453 struct printjob
*pjob
;
2455 pjob
= print_job_find(sharename
, jobid
);
2459 /* don't allow another process to get this info - it is meaningless */
2460 if (pjob
->pid
!= sys_getpid())
2463 /* if SMBD is spooling this can't be allowed */
2464 if (pjob
->status
== PJOB_SMBD_SPOOLING
) {
2468 return_code
= write_data(pjob
->fd
, buf
, size
);
2470 if (return_code
>0) {
2472 pjob_store(ev
, msg_ctx
, sharename
, jobid
, pjob
);
2477 /****************************************************************************
2478 Get the queue status - do not update if db is out of date.
2479 ****************************************************************************/
2481 static int get_queue_status(const char* sharename
, print_status_struct
*status
)
2485 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2489 ZERO_STRUCTP(status
);
2496 fstr_sprintf(keystr
, "STATUS/%s", sharename
);
2497 data
= tdb_fetch(pdb
->tdb
, string_tdb_data(keystr
));
2499 if (data
.dsize
== sizeof(print_status_struct
))
2500 /* this memcpy is ok since the status struct was
2501 not packed before storing it in the tdb */
2502 memcpy(status
, data
.dptr
, sizeof(print_status_struct
));
2503 SAFE_FREE(data
.dptr
);
2506 len
= tdb_fetch_int32(pdb
->tdb
, "INFO/total_jobs");
2507 release_print_db(pdb
);
2508 return (len
== -1 ? 0 : len
);
2511 /****************************************************************************
2512 Determine the number of jobs in a queue.
2513 ****************************************************************************/
2515 int print_queue_length(struct messaging_context
*msg_ctx
, int snum
,
2516 print_status_struct
*pstatus
)
2518 const char* sharename
= lp_const_servicename( snum
);
2519 print_status_struct status
;
2522 ZERO_STRUCT( status
);
2524 /* make sure the database is up to date */
2525 if (print_cache_expired(lp_const_servicename(snum
), True
))
2526 print_queue_update(msg_ctx
, snum
, False
);
2528 /* also fetch the queue status */
2529 memset(&status
, 0, sizeof(status
));
2530 len
= get_queue_status(sharename
, &status
);
2538 /***************************************************************************
2539 Allocate a jobid. Hold the lock for as short a time as possible.
2540 ***************************************************************************/
2542 static WERROR
allocate_print_jobid(struct tdb_print_db
*pdb
, int snum
,
2543 const char *sharename
, uint32
*pjobid
)
2547 enum TDB_ERROR terr
;
2550 *pjobid
= (uint32
)-1;
2552 for (i
= 0; i
< 3; i
++) {
2553 /* Lock the database - only wait 20 seconds. */
2554 ret
= tdb_lock_bystring_with_timeout(pdb
->tdb
,
2555 "INFO/nextjob", 20);
2557 DEBUG(0, ("allocate_print_jobid: "
2558 "Failed to lock printing database %s\n",
2560 terr
= tdb_error(pdb
->tdb
);
2561 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2564 if (!tdb_fetch_uint32(pdb
->tdb
, "INFO/nextjob", &jobid
)) {
2565 terr
= tdb_error(pdb
->tdb
);
2566 if (terr
!= TDB_ERR_NOEXIST
) {
2567 DEBUG(0, ("allocate_print_jobid: "
2568 "Failed to fetch INFO/nextjob "
2569 "for print queue %s\n", sharename
));
2570 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2571 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2573 DEBUG(10, ("allocate_print_jobid: "
2574 "No existing jobid in %s\n", sharename
));
2578 DEBUG(10, ("allocate_print_jobid: "
2579 "Read jobid %u from %s\n", jobid
, sharename
));
2581 jobid
= NEXT_JOBID(jobid
);
2583 ret
= tdb_store_int32(pdb
->tdb
, "INFO/nextjob", jobid
);
2585 terr
= tdb_error(pdb
->tdb
);
2586 DEBUG(3, ("allocate_print_jobid: "
2587 "Failed to store INFO/nextjob.\n"));
2588 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2589 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2592 /* We've finished with the INFO/nextjob lock. */
2593 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2595 if (!print_job_exists(sharename
, jobid
)) {
2598 DEBUG(10, ("allocate_print_jobid: "
2599 "Found jobid %u in %s\n", jobid
, sharename
));
2603 DEBUG(0, ("allocate_print_jobid: "
2604 "Failed to allocate a print job for queue %s\n",
2606 /* Probably full... */
2607 return WERR_NO_SPOOL_SPACE
;
2610 /* Store a dummy placeholder. */
2616 if (tdb_store(pdb
->tdb
, print_key(jobid
, &tmp
), dum
,
2617 TDB_INSERT
) == -1) {
2618 DEBUG(3, ("allocate_print_jobid: "
2619 "jobid (%d) failed to store placeholder.\n",
2621 terr
= tdb_error(pdb
->tdb
);
2622 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2630 /***************************************************************************
2631 Append a jobid to the 'jobs added' list.
2632 ***************************************************************************/
2634 static bool add_to_jobs_added(struct tdb_print_db
*pdb
, uint32 jobid
)
2639 SIVAL(&store_jobid
, 0, jobid
);
2640 data
.dptr
= (uint8
*)&store_jobid
;
2643 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid
));
2645 return (tdb_append(pdb
->tdb
, string_tdb_data("INFO/jobs_added"),
2650 /***************************************************************************
2651 Do all checks needed to determine if we can start a job.
2652 ***************************************************************************/
2654 static WERROR
print_job_checks(const struct auth_serversupplied_info
*server_info
,
2655 struct messaging_context
*msg_ctx
,
2656 int snum
, int *njobs
)
2658 const char *sharename
= lp_const_servicename(snum
);
2659 uint64_t dspace
, dsize
;
2663 if (!print_access_check(server_info
, msg_ctx
, snum
,
2664 PRINTER_ACCESS_USE
)) {
2665 DEBUG(3, ("print_job_checks: "
2666 "job start denied by security descriptor\n"));
2667 return WERR_ACCESS_DENIED
;
2670 if (!print_time_access_check(server_info
, msg_ctx
, sharename
)) {
2671 DEBUG(3, ("print_job_checks: "
2672 "job start denied by time check\n"));
2673 return WERR_ACCESS_DENIED
;
2676 /* see if we have sufficient disk space */
2677 if (lp_minprintspace(snum
)) {
2678 minspace
= lp_minprintspace(snum
);
2679 ret
= sys_fsusage(lp_pathname(snum
), &dspace
, &dsize
);
2680 if (ret
== 0 && dspace
< 2*minspace
) {
2681 DEBUG(3, ("print_job_checks: "
2682 "disk space check failed.\n"));
2683 return WERR_NO_SPOOL_SPACE
;
2687 /* for autoloaded printers, check that the printcap entry still exists */
2688 if (lp_autoloaded(snum
) && !pcap_printername_ok(sharename
)) {
2689 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2691 return WERR_ACCESS_DENIED
;
2694 /* Insure the maximum queue size is not violated */
2695 *njobs
= print_queue_length(msg_ctx
, snum
, NULL
);
2696 if (*njobs
> lp_maxprintjobs(snum
)) {
2697 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2698 "larger than max printjobs per queue (%d).\n",
2699 sharename
, *njobs
, lp_maxprintjobs(snum
)));
2700 return WERR_NO_SPOOL_SPACE
;
2706 /***************************************************************************
2708 ***************************************************************************/
2710 static WERROR
print_job_spool_file(int snum
, uint32_t jobid
,
2711 const char *output_file
,
2712 struct printjob
*pjob
)
2719 /* if this file is within the printer path, it means that smbd
2720 * is spooling it and will pass us control when it is finished.
2721 * Verify that the file name is ok, within path, and it is
2722 * already already there */
2724 path
= lp_pathname(snum
);
2726 if (strncmp(output_file
, path
, len
) == 0 &&
2727 (output_file
[len
- 1] == '/' || output_file
[len
] == '/')) {
2729 /* verify path is not too long */
2730 if (strlen(output_file
) >= sizeof(pjob
->filename
)) {
2731 return WERR_INVALID_NAME
;
2734 /* verify that the file exists */
2735 if (sys_stat(output_file
, &st
, false) != 0) {
2736 return WERR_INVALID_NAME
;
2739 fstrcpy(pjob
->filename
, output_file
);
2741 DEBUG(3, ("print_job_spool_file:"
2742 "External spooling activated"));
2744 /* we do not open the file until spooling is done */
2746 pjob
->status
= PJOB_SMBD_SPOOLING
;
2752 slprintf(pjob
->filename
, sizeof(pjob
->filename
)-1,
2753 "%s/%s%.8u.XXXXXX", lp_pathname(snum
),
2754 PRINT_SPOOL_PREFIX
, (unsigned int)jobid
);
2755 pjob
->fd
= mkstemp(pjob
->filename
);
2757 if (pjob
->fd
== -1) {
2758 werr
= map_werror_from_unix(errno
);
2759 if (W_ERROR_EQUAL(werr
, WERR_ACCESS_DENIED
)) {
2760 /* Common setup error, force a report. */
2761 DEBUG(0, ("print_job_spool_file: "
2762 "insufficient permissions to open spool "
2763 "file %s.\n", pjob
->filename
));
2765 /* Normal case, report at level 3 and above. */
2766 DEBUG(3, ("print_job_spool_file: "
2767 "can't open spool file %s\n",
2776 /***************************************************************************
2777 Start spooling a job - return the jobid.
2778 ***************************************************************************/
2780 WERROR
print_job_start(const struct auth_serversupplied_info
*server_info
,
2781 struct messaging_context
*msg_ctx
,
2782 const char *clientmachine
,
2783 int snum
, const char *docname
, const char *filename
,
2784 struct spoolss_DeviceMode
*devmode
, uint32_t *_jobid
)
2788 struct printjob pjob
;
2789 const char *sharename
= lp_const_servicename(snum
);
2790 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2795 return WERR_INTERNAL_DB_CORRUPTION
;
2798 path
= lp_pathname(snum
);
2800 werr
= print_job_checks(server_info
, msg_ctx
, snum
, &njobs
);
2801 if (!W_ERROR_IS_OK(werr
)) {
2802 release_print_db(pdb
);
2806 DEBUG(10, ("print_job_start: "
2807 "Queue %s number of jobs (%d), max printjobs = %d\n",
2808 sharename
, njobs
, lp_maxprintjobs(snum
)));
2810 werr
= allocate_print_jobid(pdb
, snum
, sharename
, &jobid
);
2811 if (!W_ERROR_IS_OK(werr
)) {
2815 /* create the database entry */
2819 pjob
.pid
= sys_getpid();
2822 pjob
.starttime
= time(NULL
);
2823 pjob
.status
= LPQ_SPOOLING
;
2825 pjob
.spooled
= False
;
2827 pjob
.devmode
= devmode
;
2829 fstrcpy(pjob
.jobname
, docname
);
2831 fstrcpy(pjob
.clientmachine
, clientmachine
);
2833 fstrcpy(pjob
.user
, lp_printjob_username(snum
));
2834 standard_sub_advanced(sharename
, server_info
->sanitized_username
,
2835 path
, server_info
->utok
.gid
,
2836 server_info
->sanitized_username
,
2837 server_info
->info3
->base
.domain
.string
,
2838 pjob
.user
, sizeof(pjob
.user
)-1);
2839 /* ensure NULL termination */
2840 pjob
.user
[sizeof(pjob
.user
)-1] = '\0';
2842 fstrcpy(pjob
.queuename
, lp_const_servicename(snum
));
2844 /* we have a job entry - now create the spool file */
2845 werr
= print_job_spool_file(snum
, jobid
, filename
, &pjob
);
2846 if (!W_ERROR_IS_OK(werr
)) {
2850 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, &pjob
);
2852 /* Update the 'jobs added' entry used by print_queue_status. */
2853 add_to_jobs_added(pdb
, jobid
);
2855 /* Ensure we keep a rough count of the number of total jobs... */
2856 tdb_change_int32_atomic(pdb
->tdb
, "INFO/total_jobs", &njobs
, 1);
2858 release_print_db(pdb
);
2865 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
2868 release_print_db(pdb
);
2870 DEBUG(3, ("print_job_start: returning fail. "
2871 "Error = %s\n", win_errstr(werr
)));
2875 /****************************************************************************
2876 Update the number of pages spooled to jobid
2877 ****************************************************************************/
2879 void print_job_endpage(struct messaging_context
*msg_ctx
,
2880 int snum
, uint32 jobid
)
2882 const char* sharename
= lp_const_servicename(snum
);
2883 struct printjob
*pjob
;
2885 pjob
= print_job_find(sharename
, jobid
);
2888 /* don't allow another process to get this info - it is meaningless */
2889 if (pjob
->pid
!= sys_getpid())
2893 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, pjob
);
2896 /****************************************************************************
2897 Print a file - called on closing the file. This spools the job.
2898 If normal close is false then we're tearing down the jobs - treat as an
2900 ****************************************************************************/
2902 NTSTATUS
print_job_end(struct messaging_context
*msg_ctx
, int snum
,
2903 uint32 jobid
, enum file_close_type close_type
)
2905 const char* sharename
= lp_const_servicename(snum
);
2906 struct printjob
*pjob
;
2908 SMB_STRUCT_STAT sbuf
;
2909 struct printif
*current_printif
= get_printer_fns( snum
);
2910 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
2912 pjob
= print_job_find(sharename
, jobid
);
2915 return NT_STATUS_PRINT_CANCELLED
;
2918 if (pjob
->spooled
|| pjob
->pid
!= sys_getpid()) {
2919 return NT_STATUS_ACCESS_DENIED
;
2922 if (close_type
== NORMAL_CLOSE
|| close_type
== SHUTDOWN_CLOSE
) {
2923 if (pjob
->status
== PJOB_SMBD_SPOOLING
) {
2924 /* take over the file now, smbd is done */
2925 if (sys_stat(pjob
->filename
, &sbuf
, false) != 0) {
2926 status
= map_nt_error_from_unix(errno
);
2927 DEBUG(3, ("print_job_end: "
2928 "stat file failed for jobid %d\n",
2933 pjob
->status
= LPQ_SPOOLING
;
2937 if ((sys_fstat(pjob
->fd
, &sbuf
, false) != 0)) {
2938 status
= map_nt_error_from_unix(errno
);
2940 DEBUG(3, ("print_job_end: "
2941 "stat file failed for jobid %d\n",
2949 pjob
->size
= sbuf
.st_ex_size
;
2953 * Not a normal close, something has gone wrong. Cleanup.
2955 if (pjob
->fd
!= -1) {
2961 /* Technically, this is not quite right. If the printer has a separator
2962 * page turned on, the NT spooler prints the separator page even if the
2963 * print job is 0 bytes. 010215 JRR */
2964 if (pjob
->size
== 0 || pjob
->status
== LPQ_DELETING
) {
2965 /* don't bother spooling empty files or something being deleted. */
2966 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2967 pjob
->filename
, pjob
->size
? "deleted" : "zero length" ));
2968 unlink(pjob
->filename
);
2969 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
2970 return NT_STATUS_OK
;
2973 ret
= (*(current_printif
->job_submit
))(snum
, pjob
);
2976 status
= NT_STATUS_PRINT_CANCELLED
;
2980 /* The print job has been successfully handed over to the back-end */
2982 pjob
->spooled
= True
;
2983 pjob
->status
= LPQ_QUEUED
;
2984 pjob_store(server_event_context(), msg_ctx
, sharename
, jobid
, pjob
);
2986 /* make sure the database is up to date */
2987 if (print_cache_expired(lp_const_servicename(snum
), True
))
2988 print_queue_update(msg_ctx
, snum
, False
);
2990 return NT_STATUS_OK
;
2994 /* The print job was not successfully started. Cleanup */
2995 /* Still need to add proper error return propagation! 010122:JRR */
2997 unlink(pjob
->filename
);
2998 pjob_delete(server_event_context(), msg_ctx
, sharename
, jobid
);
3002 /****************************************************************************
3003 Get a snapshot of jobs in the system without traversing.
3004 ****************************************************************************/
3006 static bool get_stored_queue_info(struct messaging_context
*msg_ctx
,
3007 struct tdb_print_db
*pdb
, int snum
,
3008 int *pcount
, print_queue_struct
**ppqueue
)
3010 TDB_DATA data
, cgdata
, jcdata
;
3011 print_queue_struct
*queue
= NULL
;
3013 uint32 extra_count
= 0;
3014 uint32_t changed_count
= 0;
3015 int total_count
= 0;
3018 int max_reported_jobs
= lp_max_reported_jobs(snum
);
3020 const char* sharename
= lp_servicename(snum
);
3022 /* make sure the database is up to date */
3023 if (print_cache_expired(lp_const_servicename(snum
), True
))
3024 print_queue_update(msg_ctx
, snum
, False
);
3030 ZERO_STRUCT(cgdata
);
3032 /* Get the stored queue data. */
3033 data
= tdb_fetch(pdb
->tdb
, string_tdb_data("INFO/linear_queue_array"));
3035 if (data
.dptr
&& data
.dsize
>= sizeof(qcount
))
3036 len
+= tdb_unpack(data
.dptr
+ len
, data
.dsize
- len
, "d", &qcount
);
3038 /* Get the added jobs list. */
3039 cgdata
= tdb_fetch(pdb
->tdb
, string_tdb_data("INFO/jobs_added"));
3040 if (cgdata
.dptr
!= NULL
&& (cgdata
.dsize
% 4 == 0))
3041 extra_count
= cgdata
.dsize
/4;
3043 /* Get the changed jobs list. */
3044 jcdata
= tdb_fetch(pdb
->tdb
, string_tdb_data("INFO/jobs_changed"));
3045 if (jcdata
.dptr
!= NULL
&& (jcdata
.dsize
% 4 == 0))
3046 changed_count
= jcdata
.dsize
/ 4;
3048 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount
, (unsigned int)extra_count
));
3050 /* Allocate the queue size. */
3051 if (qcount
== 0 && extra_count
== 0)
3054 if ((queue
= SMB_MALLOC_ARRAY(print_queue_struct
, qcount
+ extra_count
)) == NULL
)
3057 /* Retrieve the linearised queue data. */
3059 for( i
= 0; i
< qcount
; i
++) {
3060 uint32 qjob
, qsize
, qpage_count
, qstatus
, qpriority
, qtime
;
3061 len
+= tdb_unpack(data
.dptr
+ len
, data
.dsize
- len
, "ddddddff",
3070 queue
[i
].job
= qjob
;
3071 queue
[i
].size
= qsize
;
3072 queue
[i
].page_count
= qpage_count
;
3073 queue
[i
].status
= qstatus
;
3074 queue
[i
].priority
= qpriority
;
3075 queue
[i
].time
= qtime
;
3078 total_count
= qcount
;
3080 /* Add new jobids to the queue. */
3081 for( i
= 0; i
< extra_count
; i
++) {
3083 struct printjob
*pjob
;
3085 jobid
= IVAL(cgdata
.dptr
, i
*4);
3086 DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid
));
3087 pjob
= print_job_find(lp_const_servicename(snum
), jobid
);
3089 DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid
));
3090 remove_from_jobs_added(sharename
, jobid
);
3094 queue
[total_count
].job
= jobid
;
3095 queue
[total_count
].size
= pjob
->size
;
3096 queue
[total_count
].page_count
= pjob
->page_count
;
3097 queue
[total_count
].status
= pjob
->status
;
3098 queue
[total_count
].priority
= 1;
3099 queue
[total_count
].time
= pjob
->starttime
;
3100 fstrcpy(queue
[total_count
].fs_user
, pjob
->user
);
3101 fstrcpy(queue
[total_count
].fs_file
, pjob
->jobname
);
3105 /* Update the changed jobids. */
3106 for (i
= 0; i
< changed_count
; i
++) {
3107 uint32_t jobid
= IVAL(jcdata
.dptr
, i
* 4);
3111 for (j
= 0; j
< total_count
; j
++) {
3112 if (queue
[j
].job
== jobid
) {
3119 struct printjob
*pjob
;
3121 DEBUG(5,("get_stored_queue_info: changed job: %u\n",
3122 (unsigned int) jobid
));
3124 pjob
= print_job_find(sharename
, jobid
);
3126 DEBUG(5,("get_stored_queue_info: failed to find "
3127 "changed job = %u\n",
3128 (unsigned int) jobid
));
3129 remove_from_jobs_changed(sharename
, jobid
);
3133 queue
[j
].job
= jobid
;
3134 queue
[j
].size
= pjob
->size
;
3135 queue
[j
].page_count
= pjob
->page_count
;
3136 queue
[j
].status
= pjob
->status
;
3137 queue
[j
].priority
= 1;
3138 queue
[j
].time
= pjob
->starttime
;
3139 fstrcpy(queue
[j
].fs_user
, pjob
->user
);
3140 fstrcpy(queue
[j
].fs_file
, pjob
->jobname
);
3142 DEBUG(5,("get_stored_queue_info: updated queue[%u], jobid: %u, jobname: %s\n",
3143 (unsigned int) j
, (unsigned int) jobid
, pjob
->jobname
));
3146 remove_from_jobs_changed(sharename
, jobid
);
3149 /* Sort the queue by submission time otherwise they are displayed
3152 TYPESAFE_QSORT(queue
, total_count
, printjob_comp
);
3154 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count
));
3156 if (max_reported_jobs
&& total_count
> max_reported_jobs
)
3157 total_count
= max_reported_jobs
;
3160 *pcount
= total_count
;
3166 SAFE_FREE(data
.dptr
);
3167 SAFE_FREE(cgdata
.dptr
);
3171 /****************************************************************************
3172 Get a printer queue listing.
3173 set queue = NULL and status = NULL if you just want to update the cache
3174 ****************************************************************************/
3176 int print_queue_status(struct messaging_context
*msg_ctx
, int snum
,
3177 print_queue_struct
**ppqueue
,
3178 print_status_struct
*status
)
3182 const char *sharename
;
3183 struct tdb_print_db
*pdb
;
3186 /* make sure the database is up to date */
3188 if (print_cache_expired(lp_const_servicename(snum
), True
))
3189 print_queue_update(msg_ctx
, snum
, False
);
3191 /* return if we are done */
3192 if ( !ppqueue
|| !status
)
3196 sharename
= lp_const_servicename(snum
);
3197 pdb
= get_print_db_byname(sharename
);
3203 * Fetch the queue status. We must do this first, as there may
3204 * be no jobs in the queue.
3207 ZERO_STRUCTP(status
);
3208 slprintf(keystr
, sizeof(keystr
)-1, "STATUS/%s", sharename
);
3209 key
= string_tdb_data(keystr
);
3211 data
= tdb_fetch(pdb
->tdb
, key
);
3213 if (data
.dsize
== sizeof(*status
)) {
3214 /* this memcpy is ok since the status struct was
3215 not packed before storing it in the tdb */
3216 memcpy(status
, data
.dptr
, sizeof(*status
));
3218 SAFE_FREE(data
.dptr
);
3222 * Now, fetch the print queue information. We first count the number
3223 * of entries, and then only retrieve the queue if necessary.
3226 if (!get_stored_queue_info(msg_ctx
, pdb
, snum
, &count
, ppqueue
)) {
3227 release_print_db(pdb
);
3231 release_print_db(pdb
);
3235 /****************************************************************************
3237 ****************************************************************************/
3239 WERROR
print_queue_pause(const struct auth_serversupplied_info
*server_info
,
3240 struct messaging_context
*msg_ctx
, int snum
)
3243 struct printif
*current_printif
= get_printer_fns( snum
);
3245 if (!print_access_check(server_info
, msg_ctx
, snum
,
3246 PRINTER_ACCESS_ADMINISTER
)) {
3247 return WERR_ACCESS_DENIED
;
3253 ret
= (*(current_printif
->queue_pause
))(snum
);
3258 return WERR_INVALID_PARAM
;
3261 /* force update the database */
3262 print_cache_flush(lp_const_servicename(snum
));
3264 /* Send a printer notify message */
3266 notify_printer_status(server_event_context(), msg_ctx
, snum
,
3267 PRINTER_STATUS_PAUSED
);
3272 /****************************************************************************
3274 ****************************************************************************/
3276 WERROR
print_queue_resume(const struct auth_serversupplied_info
*server_info
,
3277 struct messaging_context
*msg_ctx
, int snum
)
3280 struct printif
*current_printif
= get_printer_fns( snum
);
3282 if (!print_access_check(server_info
, msg_ctx
, snum
,
3283 PRINTER_ACCESS_ADMINISTER
)) {
3284 return WERR_ACCESS_DENIED
;
3289 ret
= (*(current_printif
->queue_resume
))(snum
);
3294 return WERR_INVALID_PARAM
;
3297 /* make sure the database is up to date */
3298 if (print_cache_expired(lp_const_servicename(snum
), True
))
3299 print_queue_update(msg_ctx
, snum
, True
);
3301 /* Send a printer notify message */
3303 notify_printer_status(server_event_context(), msg_ctx
, snum
,
3309 /****************************************************************************
3310 Purge a queue - implemented by deleting all jobs that we can delete.
3311 ****************************************************************************/
3313 WERROR
print_queue_purge(const struct auth_serversupplied_info
*server_info
,
3314 struct messaging_context
*msg_ctx
, int snum
)
3316 print_queue_struct
*queue
;
3317 print_status_struct status
;
3321 /* Force and update so the count is accurate (i.e. not a cached count) */
3322 print_queue_update(msg_ctx
, snum
, True
);
3324 can_job_admin
= print_access_check(server_info
,
3327 JOB_ACCESS_ADMINISTER
);
3328 njobs
= print_queue_status(msg_ctx
, snum
, &queue
, &status
);
3330 if ( can_job_admin
)
3333 for (i
=0;i
<njobs
;i
++) {
3334 bool owner
= is_owner(server_info
, lp_const_servicename(snum
),
3337 if (owner
|| can_job_admin
) {
3338 print_job_delete1(server_event_context(), msg_ctx
,
3339 snum
, queue
[i
].job
);
3343 if ( can_job_admin
)
3346 /* update the cache */
3347 print_queue_update(msg_ctx
, snum
, True
);