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_changed(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 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
, "dddddddddffff",
396 used
= unpack_devicemode(NULL
, buf
+len
, buflen
-len
, &pjob
->devmode
);
404 pjob
->sysjob
= pjsysjob
;
406 pjob
->starttime
= pjstarttime
;
407 pjob
->status
= pjstatus
;
409 pjob
->page_count
= pjpage_count
;
410 pjob
->spooled
= pjspooled
;
411 pjob
->smbjob
= pjsmbjob
;
417 /****************************************************************************
418 Useful function to find a print job in the database.
419 ****************************************************************************/
421 static struct printjob
*print_job_find(const char *sharename
, uint32 jobid
)
423 static struct printjob pjob
;
426 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
428 DEBUG(10,("print_job_find: looking up job %u for share %s\n",
429 (unsigned int)jobid
, sharename
));
435 ret
= tdb_fetch(pdb
->tdb
, print_key(jobid
, &tmp
));
436 release_print_db(pdb
);
439 DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid
));
443 talloc_free(pjob
.devmode
);
447 if ( unpack_pjob( ret
.dptr
, ret
.dsize
, &pjob
) == -1 ) {
448 DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid
));
455 DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
456 (int)pjob
.sysjob
, (unsigned int)jobid
));
461 /* Convert a unix jobid to a smb jobid */
463 struct unixjob_traverse_state
{
465 uint32 sysjob_to_jobid_value
;
468 static int unixjob_traverse_fn(TDB_CONTEXT
*the_tdb
, TDB_DATA key
,
469 TDB_DATA data
, void *private_data
)
471 struct printjob
*pjob
;
472 struct unixjob_traverse_state
*state
=
473 (struct unixjob_traverse_state
*)private_data
;
475 if (!data
.dptr
|| data
.dsize
== 0)
478 pjob
= (struct printjob
*)data
.dptr
;
479 if (key
.dsize
!= sizeof(uint32
))
482 if (state
->sysjob
== pjob
->sysjob
) {
483 uint32 jobid
= IVAL(key
.dptr
,0);
485 state
->sysjob_to_jobid_value
= jobid
;
492 /****************************************************************************
493 This is a *horribly expensive call as we have to iterate through all the
494 current printer tdb's. Don't do this often ! JRA.
495 ****************************************************************************/
497 uint32
sysjob_to_jobid(int unix_jobid
)
499 int services
= lp_numservices();
501 struct unixjob_traverse_state state
;
503 state
.sysjob
= unix_jobid
;
504 state
.sysjob_to_jobid_value
= (uint32
)-1;
506 for (snum
= 0; snum
< services
; snum
++) {
507 struct tdb_print_db
*pdb
;
508 if (!lp_print_ok(snum
))
510 pdb
= get_print_db_byname(lp_const_servicename(snum
));
514 tdb_traverse(pdb
->tdb
, unixjob_traverse_fn
, &state
);
515 release_print_db(pdb
);
516 if (state
.sysjob_to_jobid_value
!= (uint32
)-1)
517 return state
.sysjob_to_jobid_value
;
522 /****************************************************************************
523 Send notifications based on what has changed after a pjob_store.
524 ****************************************************************************/
526 static const struct {
528 uint32 spoolss_status
;
529 } lpq_to_spoolss_status_map
[] = {
530 { LPQ_QUEUED
, JOB_STATUS_QUEUED
},
531 { LPQ_PAUSED
, JOB_STATUS_PAUSED
},
532 { LPQ_SPOOLING
, JOB_STATUS_SPOOLING
},
533 { LPQ_PRINTING
, JOB_STATUS_PRINTING
},
534 { LPQ_DELETING
, JOB_STATUS_DELETING
},
535 { LPQ_OFFLINE
, JOB_STATUS_OFFLINE
},
536 { LPQ_PAPEROUT
, JOB_STATUS_PAPEROUT
},
537 { LPQ_PRINTED
, JOB_STATUS_PRINTED
},
538 { LPQ_DELETED
, JOB_STATUS_DELETED
},
539 { LPQ_BLOCKED
, JOB_STATUS_BLOCKED_DEVQ
},
540 { LPQ_USER_INTERVENTION
, JOB_STATUS_USER_INTERVENTION
},
544 /* Convert a lpq status value stored in printing.tdb into the
545 appropriate win32 API constant. */
547 static uint32
map_to_spoolss_status(uint32 lpq_status
)
551 while (lpq_to_spoolss_status_map
[i
].lpq_status
!= -1) {
552 if (lpq_to_spoolss_status_map
[i
].lpq_status
== lpq_status
)
553 return lpq_to_spoolss_status_map
[i
].spoolss_status
;
560 static void pjob_store_notify(const char* sharename
, uint32 jobid
, struct printjob
*old_data
,
561 struct printjob
*new_data
)
563 bool new_job
= False
;
568 /* Job attributes that can't be changed. We only send
569 notification for these on a new job. */
571 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
572 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
573 time first or else we'll end up with potential alignment
574 errors. I don't think the systemtime should be spooled as
575 a string, but this gets us around that error.
576 --jerry (i'll feel dirty for this) */
579 notify_job_submitted(sharename
, jobid
, new_data
->starttime
);
580 notify_job_username(server_event_context(),
581 server_messaging_context(),
582 sharename
, jobid
, new_data
->user
);
585 if (new_job
|| !strequal(old_data
->jobname
, new_data
->jobname
))
586 notify_job_name(sharename
, jobid
, new_data
->jobname
);
588 /* Job attributes of a new job or attributes that can be
591 if (new_job
|| !strequal(old_data
->jobname
, new_data
->jobname
))
592 notify_job_name(sharename
, jobid
, new_data
->jobname
);
594 if (new_job
|| old_data
->status
!= new_data
->status
)
595 notify_job_status(server_event_context(),
596 server_messaging_context(),
598 map_to_spoolss_status(new_data
->status
));
600 if (new_job
|| old_data
->size
!= new_data
->size
)
601 notify_job_total_bytes(server_event_context(),
602 server_messaging_context(),
603 sharename
, jobid
, new_data
->size
);
605 if (new_job
|| old_data
->page_count
!= new_data
->page_count
)
606 notify_job_total_pages(server_event_context(),
607 server_messaging_context(),
608 sharename
, jobid
, new_data
->page_count
);
611 /****************************************************************************
612 Store a job structure back to the database.
613 ****************************************************************************/
615 static bool pjob_store(const char* sharename
, uint32 jobid
, struct printjob
*pjob
)
618 TDB_DATA old_data
, new_data
;
620 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
622 int len
, newlen
, buflen
;
630 old_data
= tdb_fetch(pdb
->tdb
, print_key(jobid
, &tmp
));
632 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
639 len
+= tdb_pack(buf
+len
, buflen
-len
, "dddddddddffff",
641 (uint32
)pjob
->sysjob
,
643 (uint32
)pjob
->starttime
,
644 (uint32
)pjob
->status
,
646 (uint32
)pjob
->page_count
,
647 (uint32
)pjob
->spooled
,
648 (uint32
)pjob
->smbjob
,
654 len
+= pack_devicemode(pjob
->devmode
, buf
+len
, buflen
-len
);
657 buf
= (uint8
*)SMB_REALLOC(buf
, len
);
659 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
664 } while ( buflen
!= len
);
670 new_data
.dsize
= len
;
671 ret
= (tdb_store(pdb
->tdb
, print_key(jobid
, &tmp
), new_data
,
674 release_print_db(pdb
);
676 /* Send notify updates for what has changed */
679 struct printjob old_pjob
;
681 if ( old_data
.dsize
)
683 if ( unpack_pjob( old_data
.dptr
, old_data
.dsize
, &old_pjob
) != -1 )
685 pjob_store_notify( sharename
, jobid
, &old_pjob
, pjob
);
686 talloc_free(old_pjob
.devmode
);
691 pjob_store_notify( sharename
, jobid
, NULL
, pjob
);
696 SAFE_FREE( old_data
.dptr
);
702 /****************************************************************************
703 Remove a job structure from the database.
704 ****************************************************************************/
706 void pjob_delete(const char* sharename
, uint32 jobid
)
709 struct printjob
*pjob
;
710 uint32 job_status
= 0;
711 struct tdb_print_db
*pdb
;
713 pdb
= get_print_db_byname( sharename
);
718 pjob
= print_job_find( sharename
, jobid
);
721 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
722 (unsigned int)jobid
));
723 release_print_db(pdb
);
727 /* We must cycle through JOB_STATUS_DELETING and
728 JOB_STATUS_DELETED for the port monitor to delete the job
731 job_status
= JOB_STATUS_DELETING
|JOB_STATUS_DELETED
;
732 notify_job_status(server_event_context(),
733 server_messaging_context(),
734 sharename
, jobid
, job_status
);
736 /* Remove from printing.tdb */
738 tdb_delete(pdb
->tdb
, print_key(jobid
, &tmp
));
739 remove_from_jobs_changed(sharename
, jobid
);
740 release_print_db( pdb
);
741 rap_jobid_delete(sharename
, jobid
);
744 /****************************************************************************
745 List a unix job in the print database.
746 ****************************************************************************/
748 static void print_unix_job(const char *sharename
, print_queue_struct
*q
, uint32 jobid
)
750 struct printjob pj
, *old_pj
;
752 if (jobid
== (uint32
)-1)
753 jobid
= q
->job
+ UNIX_JOB_START
;
755 /* Preserve the timestamp on an existing unix print job */
757 old_pj
= print_job_find(sharename
, jobid
);
764 pj
.starttime
= old_pj
? old_pj
->starttime
: q
->time
;
765 pj
.status
= q
->status
;
768 fstrcpy(pj
.filename
, old_pj
? old_pj
->filename
: "");
769 if (jobid
< UNIX_JOB_START
) {
771 fstrcpy(pj
.jobname
, old_pj
? old_pj
->jobname
: "Remote Downlevel Document");
774 fstrcpy(pj
.jobname
, old_pj
? old_pj
->jobname
: q
->fs_file
);
776 fstrcpy(pj
.user
, old_pj
? old_pj
->user
: q
->fs_user
);
777 fstrcpy(pj
.queuename
, old_pj
? old_pj
->queuename
: sharename
);
779 pjob_store(sharename
, jobid
, &pj
);
783 struct traverse_struct
{
784 print_queue_struct
*queue
;
785 int qcount
, snum
, maxcount
, total_jobs
;
786 const char *sharename
;
788 const char *lprm_command
;
789 struct printif
*print_if
;
792 /****************************************************************************
793 Utility fn to delete any jobs that are no longer active.
794 ****************************************************************************/
796 static int traverse_fn_delete(TDB_CONTEXT
*t
, TDB_DATA key
, TDB_DATA data
, void *state
)
798 struct traverse_struct
*ts
= (struct traverse_struct
*)state
;
799 struct printjob pjob
;
803 if ( key
.dsize
!= sizeof(jobid
) )
806 jobid
= IVAL(key
.dptr
, 0);
807 if ( unpack_pjob( data
.dptr
, data
.dsize
, &pjob
) == -1 )
809 talloc_free(pjob
.devmode
);
813 /* remove a unix job if it isn't in the system queue any more */
815 for (i
=0;i
<ts
->qcount
;i
++) {
816 uint32 u_jobid
= (ts
->queue
[i
].job
+ UNIX_JOB_START
);
817 if (jobid
== u_jobid
)
820 if (i
== ts
->qcount
) {
821 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
822 (unsigned int)jobid
));
823 pjob_delete(ts
->sharename
, jobid
);
827 /* need to continue the the bottom of the function to
828 save the correct attributes */
831 /* maybe it hasn't been spooled yet */
833 /* if a job is not spooled and the process doesn't
834 exist then kill it. This cleans up after smbd
836 if (!process_exists_by_pid(pjob
.pid
)) {
837 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
838 (unsigned int)jobid
, (unsigned int)pjob
.pid
));
839 pjob_delete(ts
->sharename
, jobid
);
845 /* this check only makes sense for jobs submitted from Windows clients */
848 for (i
=0;i
<ts
->qcount
;i
++) {
851 if ( pjob
.status
== LPQ_DELETED
)
854 curr_jobid
= print_parse_jobid(ts
->queue
[i
].fs_file
);
856 if (jobid
== curr_jobid
) {
858 /* try to clean up any jobs that need to be deleted */
860 if ( pjob
.status
== LPQ_DELETING
) {
863 result
= (*(ts
->print_if
->job_delete
))(
864 ts
->sharename
, ts
->lprm_command
, &pjob
);
867 /* if we can't delete, then reset the job status */
868 pjob
.status
= LPQ_QUEUED
;
869 pjob_store(ts
->sharename
, jobid
, &pjob
);
872 /* if we deleted the job, the remove the tdb record */
873 pjob_delete(ts
->sharename
, jobid
);
874 pjob
.status
= LPQ_DELETED
;
884 /* The job isn't in the system queue - we have to assume it has
885 completed, so delete the database entry. */
887 if (i
== ts
->qcount
) {
889 /* A race can occur between the time a job is spooled and
890 when it appears in the lpq output. This happens when
891 the job is added to printing.tdb when another smbd
892 running print_queue_update() has completed a lpq and
893 is currently traversing the printing tdb and deleting jobs.
894 Don't delete the job if it was submitted after the lpq_time. */
896 if (pjob
.starttime
< ts
->lpq_time
) {
897 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
899 (unsigned int)pjob
.starttime
,
900 (unsigned int)ts
->lpq_time
));
901 pjob_delete(ts
->sharename
, jobid
);
907 /* Save the pjob attributes we will store.
908 FIXME!!! This is the only place where queue->job
909 represents the SMB jobid --jerry */
911 ts
->queue
[i
].job
= jobid
;
912 ts
->queue
[i
].size
= pjob
.size
;
913 ts
->queue
[i
].page_count
= pjob
.page_count
;
914 ts
->queue
[i
].status
= pjob
.status
;
915 ts
->queue
[i
].priority
= 1;
916 ts
->queue
[i
].time
= pjob
.starttime
;
917 fstrcpy(ts
->queue
[i
].fs_user
, pjob
.user
);
918 fstrcpy(ts
->queue
[i
].fs_file
, pjob
.jobname
);
925 /****************************************************************************
926 Check if the print queue has been updated recently enough.
927 ****************************************************************************/
929 static void print_cache_flush(const char *sharename
)
932 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
936 slprintf(key
, sizeof(key
)-1, "CACHE/%s", sharename
);
937 tdb_store_int32(pdb
->tdb
, key
, -1);
938 release_print_db(pdb
);
941 /****************************************************************************
942 Check if someone already thinks they are doing the update.
943 ****************************************************************************/
945 static pid_t
get_updating_pid(const char *sharename
)
950 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
954 slprintf(keystr
, sizeof(keystr
)-1, "UPDATING/%s", sharename
);
955 key
= string_tdb_data(keystr
);
957 data
= tdb_fetch(pdb
->tdb
, key
);
958 release_print_db(pdb
);
959 if (!data
.dptr
|| data
.dsize
!= sizeof(pid_t
)) {
960 SAFE_FREE(data
.dptr
);
964 updating_pid
= IVAL(data
.dptr
, 0);
965 SAFE_FREE(data
.dptr
);
967 if (process_exists_by_pid(updating_pid
))
973 /****************************************************************************
974 Set the fact that we're doing the update, or have finished doing the update
976 ****************************************************************************/
978 static void set_updating_pid(const fstring sharename
, bool updating
)
983 pid_t updating_pid
= sys_getpid();
986 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
991 slprintf(keystr
, sizeof(keystr
)-1, "UPDATING/%s", sharename
);
992 key
= string_tdb_data(keystr
);
994 DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
995 updating
? "" : "not ",
999 tdb_delete(pdb
->tdb
, key
);
1000 release_print_db(pdb
);
1004 SIVAL( buffer
, 0, updating_pid
);
1006 data
.dsize
= 4; /* we always assume this is a 4 byte value */
1008 tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
);
1009 release_print_db(pdb
);
1012 /****************************************************************************
1013 Sort print jobs by submittal time.
1014 ****************************************************************************/
1016 static int printjob_comp(print_queue_struct
*j1
, print_queue_struct
*j2
)
1027 /* Sort on job start time */
1029 if (j1
->time
== j2
->time
)
1031 return (j1
->time
> j2
->time
) ? 1 : -1;
1034 /****************************************************************************
1035 Store the sorted queue representation for later portmon retrieval.
1037 ****************************************************************************/
1039 static void store_queue_struct(struct tdb_print_db
*pdb
, struct traverse_struct
*pts
)
1042 int max_reported_jobs
= lp_max_reported_jobs(pts
->snum
);
1043 print_queue_struct
*queue
= pts
->queue
;
1046 unsigned int qcount
;
1048 if (max_reported_jobs
&& (max_reported_jobs
< pts
->qcount
))
1049 pts
->qcount
= max_reported_jobs
;
1052 /* Work out the size. */
1054 data
.dsize
+= tdb_pack(NULL
, 0, "d", qcount
);
1056 for (i
= 0; i
< pts
->qcount
; i
++) {
1057 if ( queue
[i
].status
== LPQ_DELETED
)
1061 data
.dsize
+= tdb_pack(NULL
, 0, "ddddddff",
1062 (uint32
)queue
[i
].job
,
1063 (uint32
)queue
[i
].size
,
1064 (uint32
)queue
[i
].page_count
,
1065 (uint32
)queue
[i
].status
,
1066 (uint32
)queue
[i
].priority
,
1067 (uint32
)queue
[i
].time
,
1072 if ((data
.dptr
= (uint8
*)SMB_MALLOC(data
.dsize
)) == NULL
)
1076 len
+= tdb_pack(data
.dptr
+ len
, data
.dsize
- len
, "d", qcount
);
1077 for (i
= 0; i
< pts
->qcount
; i
++) {
1078 if ( queue
[i
].status
== LPQ_DELETED
)
1081 len
+= tdb_pack(data
.dptr
+ len
, data
.dsize
- len
, "ddddddff",
1082 (uint32
)queue
[i
].job
,
1083 (uint32
)queue
[i
].size
,
1084 (uint32
)queue
[i
].page_count
,
1085 (uint32
)queue
[i
].status
,
1086 (uint32
)queue
[i
].priority
,
1087 (uint32
)queue
[i
].time
,
1092 tdb_store(pdb
->tdb
, string_tdb_data("INFO/linear_queue_array"), data
,
1094 SAFE_FREE(data
.dptr
);
1098 static TDB_DATA
get_jobs_changed_data(struct tdb_print_db
*pdb
)
1104 data
= tdb_fetch(pdb
->tdb
, string_tdb_data("INFO/jobs_changed"));
1105 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0)) {
1106 SAFE_FREE(data
.dptr
);
1113 static void check_job_changed(const char *sharename
, TDB_DATA data
, uint32 jobid
)
1116 unsigned int job_count
= data
.dsize
/ 4;
1118 for (i
= 0; i
< job_count
; i
++) {
1121 ch_jobid
= IVAL(data
.dptr
, i
*4);
1122 if (ch_jobid
== jobid
)
1123 remove_from_jobs_changed(sharename
, jobid
);
1127 /****************************************************************************
1128 Check if the print queue has been updated recently enough.
1129 ****************************************************************************/
1131 static bool print_cache_expired(const char *sharename
, bool check_pending
)
1134 time_t last_qscan_time
, time_now
= time(NULL
);
1135 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1136 bool result
= False
;
1141 snprintf(key
, sizeof(key
), "CACHE/%s", sharename
);
1142 last_qscan_time
= (time_t)tdb_fetch_int32(pdb
->tdb
, key
);
1145 * Invalidate the queue for 3 reasons.
1146 * (1). last queue scan time == -1.
1147 * (2). Current time - last queue scan time > allowed cache time.
1148 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1149 * This last test picks up machines for which the clock has been moved
1150 * forward, an lpq scan done and then the clock moved back. Otherwise
1151 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1154 if (last_qscan_time
== ((time_t)-1)
1155 || (time_now
- last_qscan_time
) >= lp_lpqcachetime()
1156 || last_qscan_time
> (time_now
+ MAX_CACHE_VALID_TIME
))
1159 time_t msg_pending_time
;
1161 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1162 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1163 sharename
, (int)last_qscan_time
, (int)time_now
,
1164 (int)lp_lpqcachetime() ));
1166 /* check if another smbd has already sent a message to update the
1167 queue. Give the pending message one minute to clear and
1168 then send another message anyways. Make sure to check for
1169 clocks that have been run forward and then back again. */
1171 snprintf(key
, sizeof(key
), "MSG_PENDING/%s", sharename
);
1174 && tdb_fetch_uint32( pdb
->tdb
, key
, &u
)
1175 && (msg_pending_time
=u
) > 0
1176 && msg_pending_time
<= time_now
1177 && (time_now
- msg_pending_time
) < 60 )
1179 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1188 release_print_db(pdb
);
1192 /****************************************************************************
1193 main work for updating the lpq cahe for a printer queue
1194 ****************************************************************************/
1196 static void print_queue_update_internal( const char *sharename
,
1197 struct printif
*current_printif
,
1198 char *lpq_command
, char *lprm_command
)
1201 print_queue_struct
*queue
= NULL
;
1202 print_status_struct status
;
1203 print_status_struct old_status
;
1204 struct printjob
*pjob
;
1205 struct traverse_struct tstruct
;
1208 fstring keystr
, cachestr
;
1209 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1215 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1216 sharename
, current_printif
->type
, lpq_command
));
1219 * Update the cache time FIRST ! Stops others even
1220 * attempting to get the lock and doing this
1221 * if the lpq takes a long time.
1224 slprintf(cachestr
, sizeof(cachestr
)-1, "CACHE/%s", sharename
);
1225 tdb_store_int32(pdb
->tdb
, cachestr
, (int)time(NULL
));
1227 /* get the current queue using the appropriate interface */
1228 ZERO_STRUCT(status
);
1230 qcount
= (*(current_printif
->queue_get
))(sharename
,
1231 current_printif
->type
,
1232 lpq_command
, &queue
, &status
);
1234 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1235 qcount
, (qcount
!= 1) ? "s" : "", sharename
));
1237 /* Sort the queue by submission time otherwise they are displayed
1240 TYPESAFE_QSORT(queue
, qcount
, printjob_comp
);
1243 any job in the internal database that is marked as spooled
1244 and doesn't exist in the system queue is considered finished
1245 and removed from the database
1247 any job in the system database but not in the internal database
1248 is added as a unix job
1250 fill in any system job numbers as we go
1253 jcdata
= get_jobs_changed_data(pdb
);
1255 for (i
=0; i
<qcount
; i
++) {
1256 uint32 jobid
= print_parse_jobid(queue
[i
].fs_file
);
1258 if (jobid
== (uint32
)-1) {
1259 /* assume its a unix print job */
1260 print_unix_job(sharename
, &queue
[i
], jobid
);
1264 /* we have an active SMB print job - update its status */
1265 pjob
= print_job_find(sharename
, jobid
);
1267 /* err, somethings wrong. Probably smbd was restarted
1268 with jobs in the queue. All we can do is treat them
1269 like unix jobs. Pity. */
1270 print_unix_job(sharename
, &queue
[i
], jobid
);
1274 pjob
->sysjob
= queue
[i
].job
;
1276 /* don't reset the status on jobs to be deleted */
1278 if ( pjob
->status
!= LPQ_DELETING
)
1279 pjob
->status
= queue
[i
].status
;
1281 pjob_store(sharename
, jobid
, pjob
);
1283 check_job_changed(sharename
, jcdata
, jobid
);
1286 SAFE_FREE(jcdata
.dptr
);
1288 /* now delete any queued entries that don't appear in the
1290 tstruct
.queue
= queue
;
1291 tstruct
.qcount
= qcount
;
1293 tstruct
.total_jobs
= 0;
1294 tstruct
.lpq_time
= time(NULL
);
1295 tstruct
.sharename
= sharename
;
1296 tstruct
.lprm_command
= lprm_command
;
1297 tstruct
.print_if
= current_printif
;
1299 tdb_traverse(pdb
->tdb
, traverse_fn_delete
, (void *)&tstruct
);
1301 /* Store the linearised queue, max jobs only. */
1302 store_queue_struct(pdb
, &tstruct
);
1304 SAFE_FREE(tstruct
.queue
);
1306 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1307 sharename
, tstruct
.total_jobs
));
1309 tdb_store_int32(pdb
->tdb
, "INFO/total_jobs", tstruct
.total_jobs
);
1311 get_queue_status(sharename
, &old_status
);
1312 if (old_status
.qcount
!= qcount
)
1313 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1314 old_status
.qcount
, qcount
, sharename
));
1316 /* store the new queue status structure */
1317 slprintf(keystr
, sizeof(keystr
)-1, "STATUS/%s", sharename
);
1318 key
= string_tdb_data(keystr
);
1320 status
.qcount
= qcount
;
1321 data
.dptr
= (uint8
*)&status
;
1322 data
.dsize
= sizeof(status
);
1323 tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
);
1326 * Update the cache time again. We want to do this call
1327 * as little as possible...
1330 slprintf(keystr
, sizeof(keystr
)-1, "CACHE/%s", sharename
);
1331 tdb_store_int32(pdb
->tdb
, keystr
, (int32
)time(NULL
));
1333 /* clear the msg pending record for this queue */
1335 snprintf(keystr
, sizeof(keystr
), "MSG_PENDING/%s", sharename
);
1337 if ( !tdb_store_uint32( pdb
->tdb
, keystr
, 0 ) ) {
1338 /* log a message but continue on */
1340 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1344 release_print_db( pdb
);
1349 /****************************************************************************
1350 Update the internal database from the system print queue for a queue.
1351 obtain a lock on the print queue before proceeding (needed when mutiple
1352 smbd processes maytry to update the lpq cache concurrently).
1353 ****************************************************************************/
1355 static void print_queue_update_with_lock( const char *sharename
,
1356 struct printif
*current_printif
,
1357 char *lpq_command
, char *lprm_command
)
1360 struct tdb_print_db
*pdb
;
1362 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename
));
1363 pdb
= get_print_db_byname(sharename
);
1367 if ( !print_cache_expired(sharename
, False
) ) {
1368 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename
));
1369 release_print_db(pdb
);
1374 * Check to see if someone else is doing this update.
1375 * This is essentially a mutex on the update.
1378 if (get_updating_pid(sharename
) != -1) {
1379 release_print_db(pdb
);
1383 /* Lock the queue for the database update */
1385 slprintf(keystr
, sizeof(keystr
) - 1, "LOCK/%s", sharename
);
1386 /* Only wait 10 seconds for this. */
1387 if (tdb_lock_bystring_with_timeout(pdb
->tdb
, keystr
, 10) == -1) {
1388 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename
));
1389 release_print_db(pdb
);
1394 * Ensure that no one else got in here.
1395 * If the updating pid is still -1 then we are
1399 if (get_updating_pid(sharename
) != -1) {
1401 * Someone else is doing the update, exit.
1403 tdb_unlock_bystring(pdb
->tdb
, keystr
);
1404 release_print_db(pdb
);
1409 * We're going to do the update ourselves.
1412 /* Tell others we're doing the update. */
1413 set_updating_pid(sharename
, True
);
1416 * Allow others to enter and notice we're doing
1420 tdb_unlock_bystring(pdb
->tdb
, keystr
);
1422 /* do the main work now */
1424 print_queue_update_internal( sharename
, current_printif
,
1425 lpq_command
, lprm_command
);
1427 /* Delete our pid from the db. */
1428 set_updating_pid(sharename
, False
);
1429 release_print_db(pdb
);
1432 /****************************************************************************
1433 this is the receive function of the background lpq updater
1434 ****************************************************************************/
1435 static void print_queue_receive(struct messaging_context
*msg
,
1438 struct server_id server_id
,
1442 char *lpqcommand
= NULL
, *lprmcommand
= NULL
;
1446 len
= tdb_unpack( (uint8
*)data
->data
, data
->length
, "fdPP",
1453 SAFE_FREE(lpqcommand
);
1454 SAFE_FREE(lprmcommand
);
1455 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1459 print_queue_update_with_lock(sharename
,
1460 get_printer_fns_from_type((enum printing_types
)printing_type
),
1461 lpqcommand
, lprmcommand
);
1463 SAFE_FREE(lpqcommand
);
1464 SAFE_FREE(lprmcommand
);
1468 static void printing_pause_fd_handler(struct tevent_context
*ev
,
1469 struct tevent_fd
*fde
,
1474 * If pause_pipe[1] is closed it means the parent smbd
1475 * and children exited or aborted.
1477 exit_server_cleanly(NULL
);
1480 extern struct child_pid
*children
;
1481 extern int num_children
;
1483 static void add_child_pid(pid_t pid
)
1485 struct child_pid
*child
;
1487 child
= SMB_MALLOC_P(struct child_pid
);
1488 if (child
== NULL
) {
1489 DEBUG(0, ("Could not add child struct -- malloc failed\n"));
1493 DLIST_ADD(children
, child
);
1497 static pid_t background_lpq_updater_pid
= -1;
1499 /****************************************************************************
1500 main thread of the background lpq updater
1501 ****************************************************************************/
1502 void start_background_queue(struct tevent_context
*ev
,
1503 struct messaging_context
*msg_ctx
)
1505 /* Use local variables for this as we don't
1506 * need to save the parent side of this, just
1507 * ensure it closes when the process exits.
1511 DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1513 if (pipe(pause_pipe
) == -1) {
1514 DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno
) ));
1518 background_lpq_updater_pid
= sys_fork();
1520 if (background_lpq_updater_pid
== -1) {
1521 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno
) ));
1525 /* Track the printing pid along with other smbd children */
1526 add_child_pid(background_lpq_updater_pid
);
1528 if(background_lpq_updater_pid
== 0) {
1529 struct tevent_fd
*fde
;
1534 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1536 close(pause_pipe
[0]);
1539 status
= reinit_after_fork(msg_ctx
, ev
, procid_self(), true);
1541 if (!NT_STATUS_IS_OK(status
)) {
1542 DEBUG(0,("reinit_after_fork() failed\n"));
1543 smb_panic("reinit_after_fork() failed");
1546 smbd_setup_sig_term_handler();
1547 smbd_setup_sig_hup_handler(ev
, msg_ctx
);
1549 if (!serverid_register(procid_self(),
1550 FLAG_MSG_GENERAL
|FLAG_MSG_SMBD
1551 |FLAG_MSG_PRINT_GENERAL
)) {
1555 if (!locking_init()) {
1559 messaging_register(msg_ctx
, NULL
, MSG_PRINTER_UPDATE
,
1560 print_queue_receive
);
1562 fde
= tevent_add_fd(ev
, ev
, pause_pipe
[1], TEVENT_FD_READ
,
1563 printing_pause_fd_handler
,
1566 DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
1567 smb_panic("tevent_add_fd() failed for pause_pipe");
1570 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1571 ret
= tevent_loop_wait(ev
);
1572 /* should not be reached */
1573 DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
1574 ret
, (ret
== 0) ? "out of events" : strerror(errno
)));
1578 close(pause_pipe
[1]);
1581 /****************************************************************************
1582 update the internal database from the system print queue for a queue
1583 ****************************************************************************/
1585 static void print_queue_update(struct messaging_context
*msg_ctx
,
1586 int snum
, bool force
)
1590 char *lpqcommand
= NULL
;
1591 char *lprmcommand
= NULL
;
1592 uint8
*buffer
= NULL
;
1595 struct tdb_print_db
*pdb
;
1597 struct printif
*current_printif
;
1598 TALLOC_CTX
*ctx
= talloc_tos();
1600 fstrcpy( sharename
, lp_const_servicename(snum
));
1602 /* don't strip out characters like '$' from the printername */
1604 lpqcommand
= talloc_string_sub2(ctx
,
1605 lp_lpqcommand(snum
),
1607 lp_printername(snum
),
1608 false, false, false);
1612 lpqcommand
= talloc_sub_advanced(ctx
,
1613 lp_servicename(snum
),
1614 current_user_info
.unix_name
,
1616 current_user
.ut
.gid
,
1617 get_current_username(),
1618 current_user_info
.domain
,
1624 lprmcommand
= talloc_string_sub2(ctx
,
1625 lp_lprmcommand(snum
),
1627 lp_printername(snum
),
1628 false, false, false);
1632 lprmcommand
= talloc_sub_advanced(ctx
,
1633 lp_servicename(snum
),
1634 current_user_info
.unix_name
,
1636 current_user
.ut
.gid
,
1637 get_current_username(),
1638 current_user_info
.domain
,
1645 * Make sure that the background queue process exists.
1646 * Otherwise just do the update ourselves
1649 if ( force
|| background_lpq_updater_pid
== -1 ) {
1650 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename
));
1651 current_printif
= get_printer_fns( snum
);
1652 print_queue_update_with_lock( sharename
, current_printif
, lpqcommand
, lprmcommand
);
1657 type
= lp_printing(snum
);
1659 /* get the length */
1661 len
= tdb_pack( NULL
, 0, "fdPP",
1667 buffer
= SMB_XMALLOC_ARRAY( uint8
, len
);
1669 /* now pack the buffer */
1670 newlen
= tdb_pack( buffer
, len
, "fdPP",
1676 SMB_ASSERT( newlen
== len
);
1678 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1679 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1680 sharename
, type
, lpqcommand
, lprmcommand
));
1682 /* here we set a msg pending record for other smbd processes
1683 to throttle the number of duplicate print_queue_update msgs
1686 pdb
= get_print_db_byname(sharename
);
1692 snprintf(key
, sizeof(key
), "MSG_PENDING/%s", sharename
);
1694 if ( !tdb_store_uint32( pdb
->tdb
, key
, time(NULL
) ) ) {
1695 /* log a message but continue on */
1697 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1701 release_print_db( pdb
);
1703 /* finally send the message */
1705 messaging_send_buf(msg_ctx
, pid_to_procid(background_lpq_updater_pid
),
1706 MSG_PRINTER_UPDATE
, (uint8
*)buffer
, len
);
1708 SAFE_FREE( buffer
);
1713 /****************************************************************************
1714 Create/Update an entry in the print tdb that will allow us to send notify
1715 updates only to interested smbd's.
1716 ****************************************************************************/
1718 bool print_notify_register_pid(int snum
)
1721 struct tdb_print_db
*pdb
= NULL
;
1722 TDB_CONTEXT
*tdb
= NULL
;
1723 const char *printername
;
1724 uint32 mypid
= (uint32
)sys_getpid();
1728 /* if (snum == -1), then the change notify request was
1729 on a print server handle and we need to register on
1734 int num_services
= lp_numservices();
1737 for ( idx
=0; idx
<num_services
; idx
++ ) {
1738 if (lp_snum_ok(idx
) && lp_print_ok(idx
) )
1739 print_notify_register_pid(idx
);
1744 else /* register for a specific printer */
1746 printername
= lp_const_servicename(snum
);
1747 pdb
= get_print_db_byname(printername
);
1753 if (tdb_lock_bystring_with_timeout(tdb
, NOTIFY_PID_LIST_KEY
, 10) == -1) {
1754 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1757 release_print_db(pdb
);
1761 data
= get_printer_notify_pid_list( tdb
, printername
, True
);
1763 /* Add ourselves and increase the refcount. */
1765 for (i
= 0; i
< data
.dsize
; i
+= 8) {
1766 if (IVAL(data
.dptr
,i
) == mypid
) {
1767 uint32 new_refcount
= IVAL(data
.dptr
, i
+4) + 1;
1768 SIVAL(data
.dptr
, i
+4, new_refcount
);
1773 if (i
== data
.dsize
) {
1774 /* We weren't in the list. Realloc. */
1775 data
.dptr
= (uint8
*)SMB_REALLOC(data
.dptr
, data
.dsize
+ 8);
1777 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1782 SIVAL(data
.dptr
,data
.dsize
- 8,mypid
);
1783 SIVAL(data
.dptr
,data
.dsize
- 4,1); /* Refcount. */
1786 /* Store back the record. */
1787 if (tdb_store_bystring(tdb
, NOTIFY_PID_LIST_KEY
, data
, TDB_REPLACE
) == -1) {
1788 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1789 list for printer %s\n", printername
));
1797 tdb_unlock_bystring(tdb
, NOTIFY_PID_LIST_KEY
);
1799 release_print_db(pdb
);
1800 SAFE_FREE(data
.dptr
);
1804 /****************************************************************************
1805 Update an entry in the print tdb that will allow us to send notify
1806 updates only to interested smbd's.
1807 ****************************************************************************/
1809 bool print_notify_deregister_pid(int snum
)
1812 struct tdb_print_db
*pdb
= NULL
;
1813 TDB_CONTEXT
*tdb
= NULL
;
1814 const char *printername
;
1815 uint32 mypid
= (uint32
)sys_getpid();
1819 /* if ( snum == -1 ), we are deregister a print server handle
1820 which means to deregister on all print queues */
1824 int num_services
= lp_numservices();
1827 for ( idx
=0; idx
<num_services
; idx
++ ) {
1828 if ( lp_snum_ok(idx
) && lp_print_ok(idx
) )
1829 print_notify_deregister_pid(idx
);
1834 else /* deregister a specific printer */
1836 printername
= lp_const_servicename(snum
);
1837 pdb
= get_print_db_byname(printername
);
1843 if (tdb_lock_bystring_with_timeout(tdb
, NOTIFY_PID_LIST_KEY
, 10) == -1) {
1844 DEBUG(0,("print_notify_register_pid: Failed to lock \
1845 printer %s database\n", printername
));
1847 release_print_db(pdb
);
1851 data
= get_printer_notify_pid_list( tdb
, printername
, True
);
1853 /* Reduce refcount. Remove ourselves if zero. */
1855 for (i
= 0; i
< data
.dsize
; ) {
1856 if (IVAL(data
.dptr
,i
) == mypid
) {
1857 uint32 refcount
= IVAL(data
.dptr
, i
+4);
1861 if (refcount
== 0) {
1862 if (data
.dsize
- i
> 8)
1863 memmove( &data
.dptr
[i
], &data
.dptr
[i
+8], data
.dsize
- i
- 8);
1867 SIVAL(data
.dptr
, i
+4, refcount
);
1873 if (data
.dsize
== 0)
1874 SAFE_FREE(data
.dptr
);
1876 /* Store back the record. */
1877 if (tdb_store_bystring(tdb
, NOTIFY_PID_LIST_KEY
, data
, TDB_REPLACE
) == -1) {
1878 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1879 list for printer %s\n", printername
));
1887 tdb_unlock_bystring(tdb
, NOTIFY_PID_LIST_KEY
);
1889 release_print_db(pdb
);
1890 SAFE_FREE(data
.dptr
);
1894 /****************************************************************************
1895 Check if a jobid is valid. It is valid if it exists in the database.
1896 ****************************************************************************/
1898 bool print_job_exists(const char* sharename
, uint32 jobid
)
1900 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1906 ret
= tdb_exists(pdb
->tdb
, print_key(jobid
, &tmp
));
1907 release_print_db(pdb
);
1911 /****************************************************************************
1912 Give the filename used for a jobid.
1913 Only valid for the process doing the spooling and when the job
1914 has not been spooled.
1915 ****************************************************************************/
1917 char *print_job_fname(const char* sharename
, uint32 jobid
)
1919 struct printjob
*pjob
= print_job_find(sharename
, jobid
);
1920 if (!pjob
|| pjob
->spooled
|| pjob
->pid
!= sys_getpid())
1922 return pjob
->filename
;
1926 /****************************************************************************
1927 Give the filename used for a jobid.
1928 Only valid for the process doing the spooling and when the job
1929 has not been spooled.
1930 ****************************************************************************/
1932 struct spoolss_DeviceMode
*print_job_devmode(const char* sharename
, uint32 jobid
)
1934 struct printjob
*pjob
= print_job_find(sharename
, jobid
);
1939 return pjob
->devmode
;
1942 /****************************************************************************
1943 Set the name of a job. Only possible for owner.
1944 ****************************************************************************/
1946 bool print_job_set_name(const char *sharename
, uint32 jobid
, const char *name
)
1948 struct printjob
*pjob
;
1950 pjob
= print_job_find(sharename
, jobid
);
1951 if (!pjob
|| pjob
->pid
!= sys_getpid())
1954 fstrcpy(pjob
->jobname
, name
);
1955 return pjob_store(sharename
, jobid
, pjob
);
1958 /****************************************************************************
1959 Get the name of a job. Only possible for owner.
1960 ****************************************************************************/
1962 bool print_job_get_name(TALLOC_CTX
*mem_ctx
, const char *sharename
, uint32_t jobid
, char **name
)
1964 struct printjob
*pjob
;
1966 pjob
= print_job_find(sharename
, jobid
);
1967 if (!pjob
|| pjob
->pid
!= sys_getpid()) {
1971 *name
= talloc_strdup(mem_ctx
, pjob
->jobname
);
1980 /***************************************************************************
1981 Remove a jobid from the 'jobs changed' list.
1982 ***************************************************************************/
1984 static bool remove_from_jobs_changed(const char* sharename
, uint32 jobid
)
1986 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
1988 size_t job_count
, i
;
1990 bool gotlock
= False
;
1998 key
= string_tdb_data("INFO/jobs_changed");
2000 if (tdb_chainlock_with_timeout(pdb
->tdb
, key
, 5) == -1)
2005 data
= tdb_fetch(pdb
->tdb
, key
);
2007 if (data
.dptr
== NULL
|| data
.dsize
== 0 || (data
.dsize
% 4 != 0))
2010 job_count
= data
.dsize
/ 4;
2011 for (i
= 0; i
< job_count
; i
++) {
2014 ch_jobid
= IVAL(data
.dptr
, i
*4);
2015 if (ch_jobid
== jobid
) {
2016 if (i
< job_count
-1 )
2017 memmove(data
.dptr
+ (i
*4), data
.dptr
+ (i
*4) + 4, (job_count
- i
- 1)*4 );
2019 if (tdb_store(pdb
->tdb
, key
, data
, TDB_REPLACE
) == -1)
2029 tdb_chainunlock(pdb
->tdb
, key
);
2030 SAFE_FREE(data
.dptr
);
2031 release_print_db(pdb
);
2033 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid
));
2035 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid
));
2039 /****************************************************************************
2040 Delete a print job - don't update queue.
2041 ****************************************************************************/
2043 static bool print_job_delete1(int snum
, uint32 jobid
)
2045 const char* sharename
= lp_const_servicename(snum
);
2046 struct printjob
*pjob
= print_job_find(sharename
, jobid
);
2048 struct printif
*current_printif
= get_printer_fns( snum
);
2054 * If already deleting just return.
2057 if (pjob
->status
== LPQ_DELETING
)
2060 /* Hrm - we need to be able to cope with deleting a job before it
2061 has reached the spooler. Just mark it as LPQ_DELETING and
2062 let the print_queue_update() code rmeove the record */
2065 if (pjob
->sysjob
== -1) {
2066 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid
));
2069 /* Set the tdb entry to be deleting. */
2071 pjob
->status
= LPQ_DELETING
;
2072 pjob_store(sharename
, jobid
, pjob
);
2074 if (pjob
->spooled
&& pjob
->sysjob
!= -1)
2076 result
= (*(current_printif
->job_delete
))(
2077 lp_printername(snum
),
2078 lp_lprmcommand(snum
),
2081 /* Delete the tdb entry if the delete succeeded or the job hasn't
2085 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2090 pjob_delete(sharename
, jobid
);
2091 /* Ensure we keep a rough count of the number of total jobs... */
2092 tdb_change_int32_atomic(pdb
->tdb
, "INFO/total_jobs", &njobs
, -1);
2093 release_print_db(pdb
);
2097 remove_from_jobs_changed( sharename
, jobid
);
2099 return (result
== 0);
2102 /****************************************************************************
2103 Return true if the current user owns the print job.
2104 ****************************************************************************/
2106 static bool is_owner(struct auth_serversupplied_info
*server_info
,
2107 const char *servicename
,
2110 struct printjob
*pjob
= print_job_find(servicename
, jobid
);
2112 if (!pjob
|| !server_info
)
2115 return strequal(pjob
->user
, server_info
->sanitized_username
);
2118 /****************************************************************************
2120 ****************************************************************************/
2122 WERROR
print_job_delete(struct auth_serversupplied_info
*server_info
,
2123 struct messaging_context
*msg_ctx
,
2124 int snum
, uint32_t jobid
)
2126 const char* sharename
= lp_const_servicename(snum
);
2127 struct printjob
*pjob
;
2131 owner
= is_owner(server_info
, lp_const_servicename(snum
), jobid
);
2133 /* Check access against security descriptor or whether the user
2137 !print_access_check(server_info
, msg_ctx
, snum
,
2138 JOB_ACCESS_ADMINISTER
)) {
2139 DEBUG(3, ("delete denied by security descriptor\n"));
2141 /* BEGIN_ADMIN_LOG */
2142 sys_adminlog( LOG_ERR
,
2143 "Permission denied-- user not allowed to delete, \
2144 pause, or resume print job. User name: %s. Printer name: %s.",
2145 uidtoname(server_info
->utok
.uid
),
2146 lp_printername(snum
) );
2149 return WERR_ACCESS_DENIED
;
2153 * get the spooled filename of the print job
2154 * if this works, then the file has not been spooled
2155 * to the underlying print system. Just delete the
2156 * spool file & return.
2159 fname
= print_job_fname(sharename
, jobid
);
2160 if (fname
!= NULL
) {
2161 /* remove the spool file */
2162 DEBUG(10, ("print_job_delete: "
2163 "Removing spool file [%s]\n", fname
));
2164 if (unlink(fname
) == -1) {
2165 return map_werror_from_unix(errno
);
2169 if (!print_job_delete1(snum
, jobid
)) {
2170 return WERR_ACCESS_DENIED
;
2173 /* force update the database and say the delete failed if the
2176 print_queue_update(msg_ctx
, snum
, True
);
2178 pjob
= print_job_find(sharename
, jobid
);
2179 if (pjob
&& (pjob
->status
!= LPQ_DELETING
)) {
2180 return WERR_ACCESS_DENIED
;
2183 return WERR_PRINTER_HAS_JOBS_QUEUED
;
2186 /****************************************************************************
2188 ****************************************************************************/
2190 bool print_job_pause(struct auth_serversupplied_info
*server_info
,
2191 struct messaging_context
*msg_ctx
,
2192 int snum
, uint32 jobid
, WERROR
*errcode
)
2194 const char* sharename
= lp_const_servicename(snum
);
2195 struct printjob
*pjob
;
2197 struct printif
*current_printif
= get_printer_fns( snum
);
2199 pjob
= print_job_find(sharename
, jobid
);
2201 if (!pjob
|| !server_info
) {
2202 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2203 (unsigned int)jobid
));
2207 if (!pjob
->spooled
|| pjob
->sysjob
== -1) {
2208 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2209 (int)pjob
->sysjob
, (unsigned int)jobid
));
2213 if (!is_owner(server_info
, lp_const_servicename(snum
), jobid
) &&
2214 !print_access_check(server_info
, msg_ctx
, snum
,
2215 JOB_ACCESS_ADMINISTER
)) {
2216 DEBUG(3, ("pause denied by security descriptor\n"));
2218 /* BEGIN_ADMIN_LOG */
2219 sys_adminlog( LOG_ERR
,
2220 "Permission denied-- user not allowed to delete, \
2221 pause, or resume print job. User name: %s. Printer name: %s.",
2222 uidtoname(server_info
->utok
.uid
),
2223 lp_printername(snum
) );
2226 *errcode
= WERR_ACCESS_DENIED
;
2230 /* need to pause the spooled entry */
2231 ret
= (*(current_printif
->job_pause
))(snum
, pjob
);
2234 *errcode
= WERR_INVALID_PARAM
;
2238 /* force update the database */
2239 print_cache_flush(lp_const_servicename(snum
));
2241 /* Send a printer notify message */
2243 notify_job_status(server_event_context(), msg_ctx
, sharename
, jobid
,
2246 /* how do we tell if this succeeded? */
2251 /****************************************************************************
2253 ****************************************************************************/
2255 bool print_job_resume(struct auth_serversupplied_info
*server_info
,
2256 struct messaging_context
*msg_ctx
,
2257 int snum
, uint32 jobid
, WERROR
*errcode
)
2259 const char *sharename
= lp_const_servicename(snum
);
2260 struct printjob
*pjob
;
2262 struct printif
*current_printif
= get_printer_fns( snum
);
2264 pjob
= print_job_find(sharename
, jobid
);
2266 if (!pjob
|| !server_info
) {
2267 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2268 (unsigned int)jobid
));
2272 if (!pjob
->spooled
|| pjob
->sysjob
== -1) {
2273 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2274 (int)pjob
->sysjob
, (unsigned int)jobid
));
2278 if (!is_owner(server_info
, lp_const_servicename(snum
), jobid
) &&
2279 !print_access_check(server_info
, msg_ctx
, snum
,
2280 JOB_ACCESS_ADMINISTER
)) {
2281 DEBUG(3, ("resume denied by security descriptor\n"));
2282 *errcode
= WERR_ACCESS_DENIED
;
2284 /* BEGIN_ADMIN_LOG */
2285 sys_adminlog( LOG_ERR
,
2286 "Permission denied-- user not allowed to delete, \
2287 pause, or resume print job. User name: %s. Printer name: %s.",
2288 uidtoname(server_info
->utok
.uid
),
2289 lp_printername(snum
) );
2294 ret
= (*(current_printif
->job_resume
))(snum
, pjob
);
2297 *errcode
= WERR_INVALID_PARAM
;
2301 /* force update the database */
2302 print_cache_flush(lp_const_servicename(snum
));
2304 /* Send a printer notify message */
2306 notify_job_status(server_event_context(), msg_ctx
, sharename
, jobid
,
2312 /****************************************************************************
2313 Write to a print file.
2314 ****************************************************************************/
2316 ssize_t
print_job_write(int snum
, uint32 jobid
, const char *buf
, SMB_OFF_T pos
, size_t size
)
2318 const char* sharename
= lp_const_servicename(snum
);
2319 ssize_t return_code
;
2320 struct printjob
*pjob
;
2322 pjob
= print_job_find(sharename
, jobid
);
2326 /* don't allow another process to get this info - it is meaningless */
2327 if (pjob
->pid
!= sys_getpid())
2330 /* if SMBD is spooling this can't be allowed */
2331 if (pjob
->status
== PJOB_SMBD_SPOOLING
) {
2335 return_code
= write_data_at_offset(pjob
->fd
, buf
, size
, pos
);
2337 if (return_code
>0) {
2339 pjob_store(sharename
, jobid
, pjob
);
2344 /****************************************************************************
2345 Get the queue status - do not update if db is out of date.
2346 ****************************************************************************/
2348 static int get_queue_status(const char* sharename
, print_status_struct
*status
)
2352 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2356 ZERO_STRUCTP(status
);
2363 fstr_sprintf(keystr
, "STATUS/%s", sharename
);
2364 data
= tdb_fetch(pdb
->tdb
, string_tdb_data(keystr
));
2366 if (data
.dsize
== sizeof(print_status_struct
))
2367 /* this memcpy is ok since the status struct was
2368 not packed before storing it in the tdb */
2369 memcpy(status
, data
.dptr
, sizeof(print_status_struct
));
2370 SAFE_FREE(data
.dptr
);
2373 len
= tdb_fetch_int32(pdb
->tdb
, "INFO/total_jobs");
2374 release_print_db(pdb
);
2375 return (len
== -1 ? 0 : len
);
2378 /****************************************************************************
2379 Determine the number of jobs in a queue.
2380 ****************************************************************************/
2382 int print_queue_length(struct messaging_context
*msg_ctx
, int snum
,
2383 print_status_struct
*pstatus
)
2385 const char* sharename
= lp_const_servicename( snum
);
2386 print_status_struct status
;
2389 ZERO_STRUCT( status
);
2391 /* make sure the database is up to date */
2392 if (print_cache_expired(lp_const_servicename(snum
), True
))
2393 print_queue_update(msg_ctx
, snum
, False
);
2395 /* also fetch the queue status */
2396 memset(&status
, 0, sizeof(status
));
2397 len
= get_queue_status(sharename
, &status
);
2405 /***************************************************************************
2406 Allocate a jobid. Hold the lock for as short a time as possible.
2407 ***************************************************************************/
2409 static WERROR
allocate_print_jobid(struct tdb_print_db
*pdb
, int snum
,
2410 const char *sharename
, uint32
*pjobid
)
2414 enum TDB_ERROR terr
;
2417 *pjobid
= (uint32
)-1;
2419 for (i
= 0; i
< 3; i
++) {
2420 /* Lock the database - only wait 20 seconds. */
2421 ret
= tdb_lock_bystring_with_timeout(pdb
->tdb
,
2422 "INFO/nextjob", 20);
2424 DEBUG(0, ("allocate_print_jobid: "
2425 "Failed to lock printing database %s\n",
2427 terr
= tdb_error(pdb
->tdb
);
2428 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2431 if (!tdb_fetch_uint32(pdb
->tdb
, "INFO/nextjob", &jobid
)) {
2432 terr
= tdb_error(pdb
->tdb
);
2433 if (terr
!= TDB_ERR_NOEXIST
) {
2434 DEBUG(0, ("allocate_print_jobid: "
2435 "Failed to fetch INFO/nextjob "
2436 "for print queue %s\n", sharename
));
2437 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2438 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2440 DEBUG(10, ("allocate_print_jobid: "
2441 "No existing jobid in %s\n", sharename
));
2445 DEBUG(10, ("allocate_print_jobid: "
2446 "Read jobid %u from %s\n", jobid
, sharename
));
2448 jobid
= NEXT_JOBID(jobid
);
2450 ret
= tdb_store_int32(pdb
->tdb
, "INFO/nextjob", jobid
);
2452 terr
= tdb_error(pdb
->tdb
);
2453 DEBUG(3, ("allocate_print_jobid: "
2454 "Failed to store INFO/nextjob.\n"));
2455 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2456 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2459 /* We've finished with the INFO/nextjob lock. */
2460 tdb_unlock_bystring(pdb
->tdb
, "INFO/nextjob");
2462 if (!print_job_exists(sharename
, jobid
)) {
2465 DEBUG(10, ("allocate_print_jobid: "
2466 "Found jobid %u in %s\n", jobid
, sharename
));
2470 DEBUG(0, ("allocate_print_jobid: "
2471 "Failed to allocate a print job for queue %s\n",
2473 /* Probably full... */
2474 return WERR_NO_SPOOL_SPACE
;
2477 /* Store a dummy placeholder. */
2483 if (tdb_store(pdb
->tdb
, print_key(jobid
, &tmp
), dum
,
2484 TDB_INSERT
) == -1) {
2485 DEBUG(3, ("allocate_print_jobid: "
2486 "jobid (%d) failed to store placeholder.\n",
2488 terr
= tdb_error(pdb
->tdb
);
2489 return ntstatus_to_werror(map_nt_error_from_tdb(terr
));
2497 /***************************************************************************
2498 Append a jobid to the 'jobs changed' list.
2499 ***************************************************************************/
2501 static bool add_to_jobs_changed(struct tdb_print_db
*pdb
, uint32 jobid
)
2506 SIVAL(&store_jobid
, 0, jobid
);
2507 data
.dptr
= (uint8
*)&store_jobid
;
2510 DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid
));
2512 return (tdb_append(pdb
->tdb
, string_tdb_data("INFO/jobs_changed"),
2517 /***************************************************************************
2518 Do all checks needed to determine if we can start a job.
2519 ***************************************************************************/
2521 static WERROR
print_job_checks(struct auth_serversupplied_info
*server_info
,
2522 struct messaging_context
*msg_ctx
,
2523 int snum
, int *njobs
)
2525 const char *sharename
= lp_const_servicename(snum
);
2526 uint64_t dspace
, dsize
;
2530 if (!print_access_check(server_info
, msg_ctx
, snum
,
2531 PRINTER_ACCESS_USE
)) {
2532 DEBUG(3, ("print_job_checks: "
2533 "job start denied by security descriptor\n"));
2534 return WERR_ACCESS_DENIED
;
2537 if (!print_time_access_check(server_info
, msg_ctx
, sharename
)) {
2538 DEBUG(3, ("print_job_checks: "
2539 "job start denied by time check\n"));
2540 return WERR_ACCESS_DENIED
;
2543 /* see if we have sufficient disk space */
2544 if (lp_minprintspace(snum
)) {
2545 minspace
= lp_minprintspace(snum
);
2546 ret
= sys_fsusage(lp_pathname(snum
), &dspace
, &dsize
);
2547 if (ret
== 0 && dspace
< 2*minspace
) {
2548 DEBUG(3, ("print_job_checks: "
2549 "disk space check failed.\n"));
2550 return WERR_NO_SPOOL_SPACE
;
2554 /* for autoloaded printers, check that the printcap entry still exists */
2555 if (lp_autoloaded(snum
) && !pcap_printername_ok(sharename
)) {
2556 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2558 return WERR_ACCESS_DENIED
;
2561 /* Insure the maximum queue size is not violated */
2562 *njobs
= print_queue_length(msg_ctx
, snum
, NULL
);
2563 if (*njobs
> lp_maxprintjobs(snum
)) {
2564 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2565 "larger than max printjobs per queue (%d).\n",
2566 sharename
, *njobs
, lp_maxprintjobs(snum
)));
2567 return WERR_NO_SPOOL_SPACE
;
2573 /***************************************************************************
2575 ***************************************************************************/
2577 static WERROR
print_job_spool_file(int snum
, uint32_t jobid
,
2578 const char *output_file
,
2579 struct printjob
*pjob
)
2586 /* if this file is within the printer path, it means that smbd
2587 * is spooling it and will pass us control when it is finished.
2588 * Verify that the file name is ok, within path, and it is
2589 * already already there */
2591 path
= lp_pathname(snum
);
2593 if (strncmp(output_file
, path
, len
) == 0 &&
2594 (output_file
[len
- 1] == '/' || output_file
[len
] == '/')) {
2596 /* verify path is not too long */
2597 if (strlen(output_file
) >= sizeof(pjob
->filename
)) {
2598 return WERR_INVALID_NAME
;
2601 /* verify that the file exists */
2602 if (sys_stat(output_file
, &st
, false) != 0) {
2603 return WERR_INVALID_NAME
;
2606 fstrcpy(pjob
->filename
, output_file
);
2608 DEBUG(3, ("print_job_spool_file:"
2609 "External spooling activated"));
2611 /* we do not open the file until spooling is done */
2613 pjob
->status
= PJOB_SMBD_SPOOLING
;
2619 slprintf(pjob
->filename
, sizeof(pjob
->filename
)-1,
2620 "%s/%s%.8u.XXXXXX", lp_pathname(snum
),
2621 PRINT_SPOOL_PREFIX
, (unsigned int)jobid
);
2622 pjob
->fd
= mkstemp(pjob
->filename
);
2624 if (pjob
->fd
== -1) {
2625 werr
= map_werror_from_unix(errno
);
2626 if (W_ERROR_EQUAL(werr
, WERR_ACCESS_DENIED
)) {
2627 /* Common setup error, force a report. */
2628 DEBUG(0, ("print_job_spool_file: "
2629 "insufficient permissions to open spool "
2630 "file %s.\n", pjob
->filename
));
2632 /* Normal case, report at level 3 and above. */
2633 DEBUG(3, ("print_job_spool_file: "
2634 "can't open spool file %s\n",
2643 /***************************************************************************
2644 Start spooling a job - return the jobid.
2645 ***************************************************************************/
2647 WERROR
print_job_start(struct auth_serversupplied_info
*server_info
,
2648 struct messaging_context
*msg_ctx
,
2649 int snum
, const char *docname
, const char *filename
,
2650 struct spoolss_DeviceMode
*devmode
, uint32_t *_jobid
)
2654 struct printjob pjob
;
2655 const char *sharename
= lp_const_servicename(snum
);
2656 struct tdb_print_db
*pdb
= get_print_db_byname(sharename
);
2661 return WERR_INTERNAL_DB_CORRUPTION
;
2664 path
= lp_pathname(snum
);
2666 werr
= print_job_checks(server_info
, msg_ctx
, snum
, &njobs
);
2667 if (!W_ERROR_IS_OK(werr
)) {
2668 release_print_db(pdb
);
2672 DEBUG(10, ("print_job_start: "
2673 "Queue %s number of jobs (%d), max printjobs = %d\n",
2674 sharename
, njobs
, lp_maxprintjobs(snum
)));
2676 werr
= allocate_print_jobid(pdb
, snum
, sharename
, &jobid
);
2677 if (!W_ERROR_IS_OK(werr
)) {
2681 /* create the database entry */
2685 pjob
.pid
= sys_getpid();
2688 pjob
.starttime
= time(NULL
);
2689 pjob
.status
= LPQ_SPOOLING
;
2691 pjob
.spooled
= False
;
2693 pjob
.devmode
= devmode
;
2695 fstrcpy(pjob
.jobname
, docname
);
2697 fstrcpy(pjob
.user
, lp_printjob_username(snum
));
2698 standard_sub_advanced(sharename
, server_info
->sanitized_username
,
2699 path
, server_info
->utok
.gid
,
2700 server_info
->sanitized_username
,
2701 server_info
->info3
->base
.domain
.string
,
2702 pjob
.user
, sizeof(pjob
.user
)-1);
2703 /* ensure NULL termination */
2704 pjob
.user
[sizeof(pjob
.user
)-1] = '\0';
2706 fstrcpy(pjob
.queuename
, lp_const_servicename(snum
));
2708 /* we have a job entry - now create the spool file */
2709 werr
= print_job_spool_file(snum
, jobid
, filename
, &pjob
);
2710 if (!W_ERROR_IS_OK(werr
)) {
2714 pjob_store(sharename
, jobid
, &pjob
);
2716 /* Update the 'jobs changed' entry used by print_queue_status. */
2717 add_to_jobs_changed(pdb
, jobid
);
2719 /* Ensure we keep a rough count of the number of total jobs... */
2720 tdb_change_int32_atomic(pdb
->tdb
, "INFO/total_jobs", &njobs
, 1);
2722 release_print_db(pdb
);
2729 pjob_delete(sharename
, jobid
);
2732 release_print_db(pdb
);
2734 DEBUG(3, ("print_job_start: returning fail. "
2735 "Error = %s\n", win_errstr(werr
)));
2739 /****************************************************************************
2740 Update the number of pages spooled to jobid
2741 ****************************************************************************/
2743 void print_job_endpage(int snum
, uint32 jobid
)
2745 const char* sharename
= lp_const_servicename(snum
);
2746 struct printjob
*pjob
;
2748 pjob
= print_job_find(sharename
, jobid
);
2751 /* don't allow another process to get this info - it is meaningless */
2752 if (pjob
->pid
!= sys_getpid())
2756 pjob_store(sharename
, jobid
, pjob
);
2759 /****************************************************************************
2760 Print a file - called on closing the file. This spools the job.
2761 If normal close is false then we're tearing down the jobs - treat as an
2763 ****************************************************************************/
2765 NTSTATUS
print_job_end(struct messaging_context
*msg_ctx
, int snum
,
2766 uint32 jobid
, enum file_close_type close_type
)
2768 const char* sharename
= lp_const_servicename(snum
);
2769 struct printjob
*pjob
;
2771 SMB_STRUCT_STAT sbuf
;
2772 struct printif
*current_printif
= get_printer_fns( snum
);
2773 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
2775 pjob
= print_job_find(sharename
, jobid
);
2778 return NT_STATUS_PRINT_CANCELLED
;
2781 if (pjob
->spooled
|| pjob
->pid
!= sys_getpid()) {
2782 return NT_STATUS_ACCESS_DENIED
;
2785 if (close_type
== NORMAL_CLOSE
|| close_type
== SHUTDOWN_CLOSE
) {
2786 if (pjob
->status
== PJOB_SMBD_SPOOLING
) {
2787 /* take over the file now, smbd is done */
2788 if (sys_stat(pjob
->filename
, &sbuf
, false) != 0) {
2789 status
= map_nt_error_from_unix(errno
);
2790 DEBUG(3, ("print_job_end: "
2791 "stat file failed for jobid %d\n",
2796 pjob
->status
= LPQ_SPOOLING
;
2800 if ((sys_fstat(pjob
->fd
, &sbuf
, false) != 0)) {
2801 status
= map_nt_error_from_unix(errno
);
2803 DEBUG(3, ("print_job_end: "
2804 "stat file failed for jobid %d\n",
2812 pjob
->size
= sbuf
.st_ex_size
;
2816 * Not a normal close, something has gone wrong. Cleanup.
2818 if (pjob
->fd
!= -1) {
2824 /* Technically, this is not quite right. If the printer has a separator
2825 * page turned on, the NT spooler prints the separator page even if the
2826 * print job is 0 bytes. 010215 JRR */
2827 if (pjob
->size
== 0 || pjob
->status
== LPQ_DELETING
) {
2828 /* don't bother spooling empty files or something being deleted. */
2829 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2830 pjob
->filename
, pjob
->size
? "deleted" : "zero length" ));
2831 unlink(pjob
->filename
);
2832 pjob_delete(sharename
, jobid
);
2833 return NT_STATUS_OK
;
2836 ret
= (*(current_printif
->job_submit
))(snum
, pjob
);
2839 status
= NT_STATUS_PRINT_CANCELLED
;
2843 /* The print job has been successfully handed over to the back-end */
2845 pjob
->spooled
= True
;
2846 pjob
->status
= LPQ_QUEUED
;
2847 pjob_store(sharename
, jobid
, pjob
);
2849 /* make sure the database is up to date */
2850 if (print_cache_expired(lp_const_servicename(snum
), True
))
2851 print_queue_update(msg_ctx
, snum
, False
);
2853 return NT_STATUS_OK
;
2857 /* The print job was not successfully started. Cleanup */
2858 /* Still need to add proper error return propagation! 010122:JRR */
2860 unlink(pjob
->filename
);
2861 pjob_delete(sharename
, jobid
);
2865 /****************************************************************************
2866 Get a snapshot of jobs in the system without traversing.
2867 ****************************************************************************/
2869 static bool get_stored_queue_info(struct messaging_context
*msg_ctx
,
2870 struct tdb_print_db
*pdb
, int snum
,
2871 int *pcount
, print_queue_struct
**ppqueue
)
2873 TDB_DATA data
, cgdata
;
2874 print_queue_struct
*queue
= NULL
;
2876 uint32 extra_count
= 0;
2877 int total_count
= 0;
2880 int max_reported_jobs
= lp_max_reported_jobs(snum
);
2882 const char* sharename
= lp_servicename(snum
);
2884 /* make sure the database is up to date */
2885 if (print_cache_expired(lp_const_servicename(snum
), True
))
2886 print_queue_update(msg_ctx
, snum
, False
);
2892 ZERO_STRUCT(cgdata
);
2894 /* Get the stored queue data. */
2895 data
= tdb_fetch(pdb
->tdb
, string_tdb_data("INFO/linear_queue_array"));
2897 if (data
.dptr
&& data
.dsize
>= sizeof(qcount
))
2898 len
+= tdb_unpack(data
.dptr
+ len
, data
.dsize
- len
, "d", &qcount
);
2900 /* Get the changed jobs list. */
2901 cgdata
= tdb_fetch(pdb
->tdb
, string_tdb_data("INFO/jobs_changed"));
2902 if (cgdata
.dptr
!= NULL
&& (cgdata
.dsize
% 4 == 0))
2903 extra_count
= cgdata
.dsize
/4;
2905 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount
, (unsigned int)extra_count
));
2907 /* Allocate the queue size. */
2908 if (qcount
== 0 && extra_count
== 0)
2911 if ((queue
= SMB_MALLOC_ARRAY(print_queue_struct
, qcount
+ extra_count
)) == NULL
)
2914 /* Retrieve the linearised queue data. */
2916 for( i
= 0; i
< qcount
; i
++) {
2917 uint32 qjob
, qsize
, qpage_count
, qstatus
, qpriority
, qtime
;
2918 len
+= tdb_unpack(data
.dptr
+ len
, data
.dsize
- len
, "ddddddff",
2927 queue
[i
].job
= qjob
;
2928 queue
[i
].size
= qsize
;
2929 queue
[i
].page_count
= qpage_count
;
2930 queue
[i
].status
= qstatus
;
2931 queue
[i
].priority
= qpriority
;
2932 queue
[i
].time
= qtime
;
2935 total_count
= qcount
;
2937 /* Add in the changed jobids. */
2938 for( i
= 0; i
< extra_count
; i
++) {
2940 struct printjob
*pjob
;
2942 jobid
= IVAL(cgdata
.dptr
, i
*4);
2943 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid
));
2944 pjob
= print_job_find(lp_const_servicename(snum
), jobid
);
2946 DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid
));
2947 remove_from_jobs_changed(sharename
, jobid
);
2951 queue
[total_count
].job
= jobid
;
2952 queue
[total_count
].size
= pjob
->size
;
2953 queue
[total_count
].page_count
= pjob
->page_count
;
2954 queue
[total_count
].status
= pjob
->status
;
2955 queue
[total_count
].priority
= 1;
2956 queue
[total_count
].time
= pjob
->starttime
;
2957 fstrcpy(queue
[total_count
].fs_user
, pjob
->user
);
2958 fstrcpy(queue
[total_count
].fs_file
, pjob
->jobname
);
2962 /* Sort the queue by submission time otherwise they are displayed
2965 TYPESAFE_QSORT(queue
, total_count
, printjob_comp
);
2967 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count
));
2969 if (max_reported_jobs
&& total_count
> max_reported_jobs
)
2970 total_count
= max_reported_jobs
;
2973 *pcount
= total_count
;
2979 SAFE_FREE(data
.dptr
);
2980 SAFE_FREE(cgdata
.dptr
);
2984 /****************************************************************************
2985 Get a printer queue listing.
2986 set queue = NULL and status = NULL if you just want to update the cache
2987 ****************************************************************************/
2989 int print_queue_status(struct messaging_context
*msg_ctx
, int snum
,
2990 print_queue_struct
**ppqueue
,
2991 print_status_struct
*status
)
2995 const char *sharename
;
2996 struct tdb_print_db
*pdb
;
2999 /* make sure the database is up to date */
3001 if (print_cache_expired(lp_const_servicename(snum
), True
))
3002 print_queue_update(msg_ctx
, snum
, False
);
3004 /* return if we are done */
3005 if ( !ppqueue
|| !status
)
3009 sharename
= lp_const_servicename(snum
);
3010 pdb
= get_print_db_byname(sharename
);
3016 * Fetch the queue status. We must do this first, as there may
3017 * be no jobs in the queue.
3020 ZERO_STRUCTP(status
);
3021 slprintf(keystr
, sizeof(keystr
)-1, "STATUS/%s", sharename
);
3022 key
= string_tdb_data(keystr
);
3024 data
= tdb_fetch(pdb
->tdb
, key
);
3026 if (data
.dsize
== sizeof(*status
)) {
3027 /* this memcpy is ok since the status struct was
3028 not packed before storing it in the tdb */
3029 memcpy(status
, data
.dptr
, sizeof(*status
));
3031 SAFE_FREE(data
.dptr
);
3035 * Now, fetch the print queue information. We first count the number
3036 * of entries, and then only retrieve the queue if necessary.
3039 if (!get_stored_queue_info(msg_ctx
, pdb
, snum
, &count
, ppqueue
)) {
3040 release_print_db(pdb
);
3044 release_print_db(pdb
);
3048 /****************************************************************************
3050 ****************************************************************************/
3052 WERROR
print_queue_pause(struct auth_serversupplied_info
*server_info
,
3053 struct messaging_context
*msg_ctx
, int snum
)
3056 struct printif
*current_printif
= get_printer_fns( snum
);
3058 if (!print_access_check(server_info
, msg_ctx
, snum
,
3059 PRINTER_ACCESS_ADMINISTER
)) {
3060 return WERR_ACCESS_DENIED
;
3066 ret
= (*(current_printif
->queue_pause
))(snum
);
3071 return WERR_INVALID_PARAM
;
3074 /* force update the database */
3075 print_cache_flush(lp_const_servicename(snum
));
3077 /* Send a printer notify message */
3079 notify_printer_status(server_event_context(), msg_ctx
, snum
,
3080 PRINTER_STATUS_PAUSED
);
3085 /****************************************************************************
3087 ****************************************************************************/
3089 WERROR
print_queue_resume(struct auth_serversupplied_info
*server_info
,
3090 struct messaging_context
*msg_ctx
, int snum
)
3093 struct printif
*current_printif
= get_printer_fns( snum
);
3095 if (!print_access_check(server_info
, msg_ctx
, snum
,
3096 PRINTER_ACCESS_ADMINISTER
)) {
3097 return WERR_ACCESS_DENIED
;
3102 ret
= (*(current_printif
->queue_resume
))(snum
);
3107 return WERR_INVALID_PARAM
;
3110 /* make sure the database is up to date */
3111 if (print_cache_expired(lp_const_servicename(snum
), True
))
3112 print_queue_update(msg_ctx
, snum
, True
);
3114 /* Send a printer notify message */
3116 notify_printer_status(server_event_context(), msg_ctx
, snum
,
3122 /****************************************************************************
3123 Purge a queue - implemented by deleting all jobs that we can delete.
3124 ****************************************************************************/
3126 WERROR
print_queue_purge(struct auth_serversupplied_info
*server_info
,
3127 struct messaging_context
*msg_ctx
, int snum
)
3129 print_queue_struct
*queue
;
3130 print_status_struct status
;
3134 /* Force and update so the count is accurate (i.e. not a cached count) */
3135 print_queue_update(msg_ctx
, snum
, True
);
3137 can_job_admin
= print_access_check(server_info
,
3140 JOB_ACCESS_ADMINISTER
);
3141 njobs
= print_queue_status(msg_ctx
, snum
, &queue
, &status
);
3143 if ( can_job_admin
)
3146 for (i
=0;i
<njobs
;i
++) {
3147 bool owner
= is_owner(server_info
, lp_const_servicename(snum
),
3150 if (owner
|| can_job_admin
) {
3151 print_job_delete1(snum
, queue
[i
].job
);
3155 if ( can_job_admin
)
3158 /* update the cache */
3159 print_queue_update(msg_ctx
, snum
, True
);