source: vendor/current/source3/printing/printing.c

Last change on this file was 988, checked in by Silvan Scherrer, 9 years ago

Samba Server: update vendor to version 4.4.3

File size: 89.7 KB
Line 
1/*
2 Unix SMB/Netbios implementation.
3 Version 3.0
4 printing backend routines
5 Copyright (C) Andrew Tridgell 1992-2000
6 Copyright (C) Jeremy Allison 2002
7
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.
12
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.
17
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/>.
20*/
21
22#include "includes.h"
23#include "system/syslog.h"
24#include "system/filesys.h"
25#include "printing.h"
26#include "../librpc/gen_ndr/ndr_spoolss.h"
27#include "nt_printing.h"
28#include "../librpc/gen_ndr/netlogon.h"
29#include "printing/notify.h"
30#include "printing/pcap.h"
31#include "printing/printer_list.h"
32#include "printing/queue_process.h"
33#include "serverid.h"
34#include "smbd/smbd.h"
35#include "auth.h"
36#include "messages.h"
37#include "util_tdb.h"
38#include "lib/param/loadparm.h"
39#include "lib/util/sys_rw_data.h"
40
41extern struct current_user current_user;
42extern userdom_struct current_user_info;
43
44/* Current printer interface */
45static bool remove_from_jobs_added(const char* sharename, uint32_t jobid);
46
47/*
48 the printing backend revolves around a tdb database that stores the
49 SMB view of the print queue
50
51 The key for this database is a jobid - a internally generated number that
52 uniquely identifies a print job
53
54 reading the print queue involves two steps:
55 - possibly running lpq and updating the internal database from that
56 - reading entries from the database
57
58 jobids are assigned when a job starts spooling.
59*/
60
61static TDB_CONTEXT *rap_tdb;
62static uint16_t next_rap_jobid;
63struct rap_jobid_key {
64 fstring sharename;
65 uint32_t jobid;
66};
67
68/***************************************************************************
69 Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
70 bit RPC jobids.... JRA.
71***************************************************************************/
72
73uint16_t pjobid_to_rap(const char* sharename, uint32_t jobid)
74{
75 uint16_t rap_jobid;
76 TDB_DATA data, key;
77 struct rap_jobid_key jinfo;
78 uint8_t buf[2];
79
80 DEBUG(10,("pjobid_to_rap: called.\n"));
81
82 if (!rap_tdb) {
83 /* Create the in-memory tdb. */
84 rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
85 if (!rap_tdb)
86 return 0;
87 }
88
89 ZERO_STRUCT( jinfo );
90 fstrcpy( jinfo.sharename, sharename );
91 jinfo.jobid = jobid;
92 key.dptr = (uint8_t *)&jinfo;
93 key.dsize = sizeof(jinfo);
94
95 data = tdb_fetch(rap_tdb, key);
96 if (data.dptr && data.dsize == sizeof(uint16_t)) {
97 rap_jobid = SVAL(data.dptr, 0);
98 SAFE_FREE(data.dptr);
99 DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
100 (unsigned int)jobid, (unsigned int)rap_jobid));
101 return rap_jobid;
102 }
103 SAFE_FREE(data.dptr);
104 /* Not found - create and store mapping. */
105 rap_jobid = ++next_rap_jobid;
106 if (rap_jobid == 0)
107 rap_jobid = ++next_rap_jobid;
108 SSVAL(buf,0,rap_jobid);
109 data.dptr = buf;
110 data.dsize = sizeof(rap_jobid);
111 tdb_store(rap_tdb, key, data, TDB_REPLACE);
112 tdb_store(rap_tdb, data, key, TDB_REPLACE);
113
114 DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
115 (unsigned int)jobid, (unsigned int)rap_jobid));
116 return rap_jobid;
117}
118
119bool rap_to_pjobid(uint16_t rap_jobid, fstring sharename, uint32_t *pjobid)
120{
121 TDB_DATA data, key;
122 uint8_t buf[2];
123
124 DEBUG(10,("rap_to_pjobid called.\n"));
125
126 if (!rap_tdb)
127 return False;
128
129 SSVAL(buf,0,rap_jobid);
130 key.dptr = buf;
131 key.dsize = sizeof(rap_jobid);
132 data = tdb_fetch(rap_tdb, key);
133 if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) )
134 {
135 struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
136 if (sharename != NULL) {
137 fstrcpy( sharename, jinfo->sharename );
138 }
139 *pjobid = jinfo->jobid;
140 DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
141 (unsigned int)*pjobid, (unsigned int)rap_jobid));
142 SAFE_FREE(data.dptr);
143 return True;
144 }
145
146 DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
147 (unsigned int)rap_jobid));
148 SAFE_FREE(data.dptr);
149 return False;
150}
151
152void rap_jobid_delete(const char* sharename, uint32_t jobid)
153{
154 TDB_DATA key, data;
155 uint16_t rap_jobid;
156 struct rap_jobid_key jinfo;
157 uint8_t buf[2];
158
159 DEBUG(10,("rap_jobid_delete: called.\n"));
160
161 if (!rap_tdb)
162 return;
163
164 ZERO_STRUCT( jinfo );
165 fstrcpy( jinfo.sharename, sharename );
166 jinfo.jobid = jobid;
167 key.dptr = (uint8_t *)&jinfo;
168 key.dsize = sizeof(jinfo);
169
170 data = tdb_fetch(rap_tdb, key);
171 if (!data.dptr || (data.dsize != sizeof(uint16_t))) {
172 DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
173 (unsigned int)jobid ));
174 SAFE_FREE(data.dptr);
175 return;
176 }
177
178 DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
179 (unsigned int)jobid ));
180
181 rap_jobid = SVAL(data.dptr, 0);
182 SAFE_FREE(data.dptr);
183 SSVAL(buf,0,rap_jobid);
184 data.dptr = buf;
185 data.dsize = sizeof(rap_jobid);
186 tdb_delete(rap_tdb, key);
187 tdb_delete(rap_tdb, data);
188}
189
190static int get_queue_status(const char* sharename, print_status_struct *);
191
192/****************************************************************************
193 Initialise the printing backend. Called once at startup before the fork().
194****************************************************************************/
195
196bool print_backend_init(struct messaging_context *msg_ctx)
197{
198 const char *sversion = "INFO/version";
199 int services = lp_numservices();
200 int snum;
201 bool ok;
202 char *print_cache_path;
203
204 if (!printer_list_parent_init()) {
205 return false;
206 }
207
208 print_cache_path = cache_path("printing");
209 if (print_cache_path == NULL) {
210 return false;
211 }
212 ok = directory_create_or_exist(print_cache_path, 0755);
213 TALLOC_FREE(print_cache_path);
214 if (!ok) {
215 return false;
216 }
217
218 print_cache_path = cache_path("printing.tdb");
219 if (print_cache_path == NULL) {
220 return false;
221 }
222 unlink(print_cache_path);
223 TALLOC_FREE(print_cache_path);
224
225 /* handle a Samba upgrade */
226
227 for (snum = 0; snum < services; snum++) {
228 struct tdb_print_db *pdb;
229 if (!lp_printable(snum))
230 continue;
231
232 pdb = get_print_db_byname(lp_const_servicename(snum));
233 if (!pdb)
234 continue;
235 if (tdb_lock_bystring(pdb->tdb, sversion) != 0) {
236 DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
237 release_print_db(pdb);
238 return False;
239 }
240 if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
241 tdb_wipe_all(pdb->tdb);
242 tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
243 }
244 tdb_unlock_bystring(pdb->tdb, sversion);
245 release_print_db(pdb);
246 }
247
248 close_all_print_db(); /* Don't leave any open. */
249
250 /* do NT print initialization... */
251 return nt_printing_init(msg_ctx);
252}
253
254/****************************************************************************
255 Shut down printing backend. Called once at shutdown to close the tdb.
256****************************************************************************/
257
258void printing_end(void)
259{
260 close_all_print_db(); /* Don't leave any open. */
261}
262
263/****************************************************************************
264 Retrieve the set of printing functions for a given service. This allows
265 us to set the printer function table based on the value of the 'printing'
266 service parameter.
267
268 Use the generic interface as the default and only use cups interface only
269 when asked for (and only when supported)
270****************************************************************************/
271
272static struct printif *get_printer_fns_from_type( enum printing_types type )
273{
274 struct printif *printer_fns = &generic_printif;
275
276#ifdef HAVE_CUPS
277 if ( type == PRINT_CUPS ) {
278 printer_fns = &cups_printif;
279 }
280#endif /* HAVE_CUPS */
281
282#ifdef HAVE_IPRINT
283 if ( type == PRINT_IPRINT ) {
284 printer_fns = &iprint_printif;
285 }
286#endif /* HAVE_IPRINT */
287
288 printer_fns->type = type;
289
290 return printer_fns;
291}
292
293static struct printif *get_printer_fns( int snum )
294{
295 return get_printer_fns_from_type( (enum printing_types)lp_printing(snum) );
296}
297
298
299/****************************************************************************
300 Useful function to generate a tdb key.
301****************************************************************************/
302
303static TDB_DATA print_key(uint32_t jobid, uint32_t *tmp)
304{
305 TDB_DATA ret;
306
307 SIVAL(tmp, 0, jobid);
308 ret.dptr = (uint8_t *)tmp;
309 ret.dsize = sizeof(*tmp);
310 return ret;
311}
312
313/****************************************************************************
314 Pack the devicemode to store it in a tdb.
315****************************************************************************/
316static int pack_devicemode(struct spoolss_DeviceMode *devmode, uint8_t *buf, int buflen)
317{
318 enum ndr_err_code ndr_err;
319 DATA_BLOB blob;
320 int len = 0;
321
322 if (devmode) {
323 ndr_err = ndr_push_struct_blob(&blob, talloc_tos(),
324 devmode,
325 (ndr_push_flags_fn_t)
326 ndr_push_spoolss_DeviceMode);
327 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
328 DEBUG(10, ("pack_devicemode: "
329 "error encoding spoolss_DeviceMode\n"));
330 goto done;
331 }
332 } else {
333 ZERO_STRUCT(blob);
334 }
335
336 len = tdb_pack(buf, buflen, "B", blob.length, blob.data);
337
338 if (devmode) {
339 DEBUG(8, ("Packed devicemode [%s]\n", devmode->formname));
340 }
341
342done:
343 return len;
344}
345
346/****************************************************************************
347 Unpack the devicemode to store it in a tdb.
348****************************************************************************/
349static int unpack_devicemode(TALLOC_CTX *mem_ctx,
350 const uint8_t *buf, int buflen,
351 struct spoolss_DeviceMode **devmode)
352{
353 struct spoolss_DeviceMode *dm;
354 enum ndr_err_code ndr_err;
355 char *data = NULL;
356 int data_len = 0;
357 DATA_BLOB blob;
358 int len = 0;
359
360 *devmode = NULL;
361
362 len = tdb_unpack(buf, buflen, "B", &data_len, &data);
363 if (!data) {
364 return len;
365 }
366
367 dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
368 if (!dm) {
369 goto done;
370 }
371
372 blob = data_blob_const(data, data_len);
373
374 ndr_err = ndr_pull_struct_blob(&blob, dm, dm,
375 (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);
376 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
377 DEBUG(10, ("unpack_devicemode: "
378 "error parsing spoolss_DeviceMode\n"));
379 goto done;
380 }
381
382 DEBUG(8, ("Unpacked devicemode [%s](%s)\n",
383 dm->devicename, dm->formname));
384 if (dm->driverextra_data.data) {
385 DEBUG(8, ("with a private section of %d bytes\n",
386 dm->__driverextra_length));
387 }
388
389 *devmode = dm;
390
391done:
392 SAFE_FREE(data);
393 return len;
394}
395
396/***********************************************************************
397 unpack a pjob from a tdb buffer
398***********************************************************************/
399
400static int unpack_pjob(TALLOC_CTX *mem_ctx, uint8_t *buf, int buflen,
401 struct printjob *pjob)
402{
403 int len = 0;
404 int used;
405 uint32_t pjpid, pjjobid, pjsysjob, pjfd, pjstarttime, pjstatus;
406 uint32_t pjsize, pjpage_count, pjspooled, pjsmbjob;
407
408 if (!buf || !pjob) {
409 return -1;
410 }
411
412 len += tdb_unpack(buf+len, buflen-len, "ddddddddddfffff",
413 &pjpid,
414 &pjjobid,
415 &pjsysjob,
416 &pjfd,
417 &pjstarttime,
418 &pjstatus,
419 &pjsize,
420 &pjpage_count,
421 &pjspooled,
422 &pjsmbjob,
423 pjob->filename,
424 pjob->jobname,
425 pjob->user,
426 pjob->clientmachine,
427 pjob->queuename);
428
429 if (len == -1) {
430 return -1;
431 }
432
433 used = unpack_devicemode(mem_ctx, buf+len, buflen-len, &pjob->devmode);
434 if (used == -1) {
435 return -1;
436 }
437
438 len += used;
439
440 pjob->pid = pjpid;
441 pjob->jobid = pjjobid;
442 pjob->sysjob = pjsysjob;
443 pjob->fd = pjfd;
444 pjob->starttime = pjstarttime;
445 pjob->status = pjstatus;
446 pjob->size = pjsize;
447 pjob->page_count = pjpage_count;
448 pjob->spooled = pjspooled;
449 pjob->smbjob = pjsmbjob;
450
451 return len;
452
453}
454
455/****************************************************************************
456 Useful function to find a print job in the database.
457****************************************************************************/
458
459static struct printjob *print_job_find(TALLOC_CTX *mem_ctx,
460 const char *sharename,
461 uint32_t jobid)
462{
463 struct printjob *pjob;
464 uint32_t tmp;
465 TDB_DATA ret;
466 struct tdb_print_db *pdb = get_print_db_byname(sharename);
467
468 DEBUG(10,("print_job_find: looking up job %u for share %s\n",
469 (unsigned int)jobid, sharename ));
470
471 if (!pdb) {
472 return NULL;
473 }
474
475 ret = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
476 release_print_db(pdb);
477
478 if (!ret.dptr) {
479 DEBUG(10, ("print_job_find: failed to find jobid %u.\n",
480 jobid));
481 return NULL;
482 }
483
484 pjob = talloc_zero(mem_ctx, struct printjob);
485 if (pjob == NULL) {
486 goto err_out;
487 }
488
489 if (unpack_pjob(mem_ctx, ret.dptr, ret.dsize, pjob) == -1) {
490 DEBUG(10, ("failed to unpack jobid %u.\n", jobid));
491 talloc_free(pjob);
492 pjob = NULL;
493 goto err_out;
494 }
495
496 DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
497 pjob->sysjob, jobid));
498 SMB_ASSERT(pjob->jobid == jobid);
499
500err_out:
501 SAFE_FREE(ret.dptr);
502 return pjob;
503}
504
505struct job_traverse_state {
506 int sysjob;
507 uint32_t jobid;
508};
509
510/* find spoolss jobid based on sysjob */
511static int sysjob_to_jobid_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
512 TDB_DATA data, void *private_data)
513{
514 struct printjob *pjob;
515 struct job_traverse_state *state =
516 (struct job_traverse_state *)private_data;
517
518 if (!data.dptr || data.dsize == 0)
519 return 0;
520
521 pjob = (struct printjob *)data.dptr;
522 if (key.dsize != sizeof(uint32_t))
523 return 0;
524
525 if (state->sysjob == pjob->sysjob) {
526 state->jobid = pjob->jobid;
527 return 1;
528 }
529
530 return 0;
531}
532
533uint32_t sysjob_to_jobid_pdb(struct tdb_print_db *pdb, int sysjob)
534{
535 struct job_traverse_state state;
536
537 state.sysjob = sysjob;
538 state.jobid = (uint32_t)-1;
539
540 tdb_traverse(pdb->tdb, sysjob_to_jobid_traverse_fn, &state);
541
542 return state.jobid;
543}
544
545/****************************************************************************
546 This is a *horribly expensive call as we have to iterate through all the
547 current printer tdb's. Don't do this often ! JRA.
548****************************************************************************/
549
550uint32_t sysjob_to_jobid(int unix_jobid)
551{
552 int services = lp_numservices();
553 int snum;
554 struct job_traverse_state state;
555
556 state.sysjob = unix_jobid;
557 state.jobid = (uint32_t)-1;
558
559 for (snum = 0; snum < services; snum++) {
560 struct tdb_print_db *pdb;
561 if (!lp_printable(snum))
562 continue;
563 pdb = get_print_db_byname(lp_const_servicename(snum));
564 if (!pdb) {
565 continue;
566 }
567 tdb_traverse(pdb->tdb, sysjob_to_jobid_traverse_fn, &state);
568 release_print_db(pdb);
569 if (state.jobid != (uint32_t)-1)
570 return state.jobid;
571 }
572 return (uint32_t)-1;
573}
574
575/* find sysjob based on spoolss jobid */
576static int jobid_to_sysjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
577 TDB_DATA data, void *private_data)
578{
579 struct printjob *pjob;
580 struct job_traverse_state *state =
581 (struct job_traverse_state *)private_data;
582
583 if (!data.dptr || data.dsize == 0)
584 return 0;
585
586 pjob = (struct printjob *)data.dptr;
587 if (key.dsize != sizeof(uint32_t))
588 return 0;
589
590 if (state->jobid == pjob->jobid) {
591 state->sysjob = pjob->sysjob;
592 return 1;
593 }
594
595 return 0;
596}
597
598int jobid_to_sysjob_pdb(struct tdb_print_db *pdb, uint32_t jobid)
599{
600 struct job_traverse_state state;
601
602 state.sysjob = -1;
603 state.jobid = jobid;
604
605 tdb_traverse(pdb->tdb, jobid_to_sysjob_traverse_fn, &state);
606
607 return state.sysjob;
608}
609
610/****************************************************************************
611 Send notifications based on what has changed after a pjob_store.
612****************************************************************************/
613
614static const struct {
615 uint32_t lpq_status;
616 uint32_t spoolss_status;
617} lpq_to_spoolss_status_map[] = {
618 { LPQ_QUEUED, JOB_STATUS_QUEUED },
619 { LPQ_PAUSED, JOB_STATUS_PAUSED },
620 { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
621 { LPQ_PRINTING, JOB_STATUS_PRINTING },
622 { LPQ_DELETING, JOB_STATUS_DELETING },
623 { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
624 { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
625 { LPQ_PRINTED, JOB_STATUS_PRINTED },
626 { LPQ_DELETED, JOB_STATUS_DELETED },
627 { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ },
628 { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
629 { (uint32_t)-1, 0 }
630};
631
632/* Convert a lpq status value stored in printing.tdb into the
633 appropriate win32 API constant. */
634
635static uint32_t map_to_spoolss_status(uint32_t lpq_status)
636{
637 int i = 0;
638
639 while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
640 if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
641 return lpq_to_spoolss_status_map[i].spoolss_status;
642 i++;
643 }
644
645 return 0;
646}
647
648/***************************************************************************
649 Append a jobid to the 'jobs changed' list.
650***************************************************************************/
651
652static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32_t jobid)
653{
654 TDB_DATA data;
655 uint32_t store_jobid;
656
657 SIVAL(&store_jobid, 0, jobid);
658 data.dptr = (uint8_t *) &store_jobid;
659 data.dsize = 4;
660
661 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid ));
662
663 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
664 data) == 0);
665}
666
667/***************************************************************************
668 Remove a jobid from the 'jobs changed' list.
669***************************************************************************/
670
671static bool remove_from_jobs_changed(const char* sharename, uint32_t jobid)
672{
673 struct tdb_print_db *pdb = get_print_db_byname(sharename);
674 TDB_DATA data, key;
675 size_t job_count, i;
676 bool ret = False;
677 bool gotlock = False;
678
679 if (!pdb) {
680 return False;
681 }
682
683 ZERO_STRUCT(data);
684
685 key = string_tdb_data("INFO/jobs_changed");
686
687 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) != 0)
688 goto out;
689
690 gotlock = True;
691
692 data = tdb_fetch(pdb->tdb, key);
693
694 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
695 goto out;
696
697 job_count = data.dsize / 4;
698 for (i = 0; i < job_count; i++) {
699 uint32_t ch_jobid;
700
701 ch_jobid = IVAL(data.dptr, i*4);
702 if (ch_jobid == jobid) {
703 if (i < job_count -1 )
704 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
705 data.dsize -= 4;
706 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) != 0)
707 goto out;
708 break;
709 }
710 }
711
712 ret = True;
713 out:
714
715 if (gotlock)
716 tdb_chainunlock(pdb->tdb, key);
717 SAFE_FREE(data.dptr);
718 release_print_db(pdb);
719 if (ret)
720 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
721 else
722 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
723 return ret;
724}
725
726static void pjob_store_notify(struct tevent_context *ev,
727 struct messaging_context *msg_ctx,
728 const char* sharename, uint32_t jobid,
729 struct printjob *old_data,
730 struct printjob *new_data,
731 bool *pchanged)
732{
733 bool new_job = false;
734 bool changed = false;
735
736 if (old_data == NULL) {
737 new_job = true;
738 }
739
740 /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
741 NOTIFY_INFO_DATA buffer, we *have* to send the job submission
742 time first or else we'll end up with potential alignment
743 errors. I don't think the systemtime should be spooled as
744 a string, but this gets us around that error.
745 --jerry (i'll feel dirty for this) */
746
747 if (new_job) {
748 notify_job_submitted(ev, msg_ctx,
749 sharename, jobid, new_data->starttime);
750 notify_job_username(ev, msg_ctx,
751 sharename, jobid, new_data->user);
752 notify_job_name(ev, msg_ctx,
753 sharename, jobid, new_data->jobname);
754 notify_job_status(ev, msg_ctx,
755 sharename, jobid, map_to_spoolss_status(new_data->status));
756 notify_job_total_bytes(ev, msg_ctx,
757 sharename, jobid, new_data->size);
758 notify_job_total_pages(ev, msg_ctx,
759 sharename, jobid, new_data->page_count);
760 } else {
761 if (!strequal(old_data->jobname, new_data->jobname)) {
762 notify_job_name(ev, msg_ctx, sharename,
763 jobid, new_data->jobname);
764 changed = true;
765 }
766
767 if (old_data->status != new_data->status) {
768 notify_job_status(ev, msg_ctx,
769 sharename, jobid,
770 map_to_spoolss_status(new_data->status));
771 }
772
773 if (old_data->size != new_data->size) {
774 notify_job_total_bytes(ev, msg_ctx,
775 sharename, jobid, new_data->size);
776 }
777
778 if (old_data->page_count != new_data->page_count) {
779 notify_job_total_pages(ev, msg_ctx,
780 sharename, jobid,
781 new_data->page_count);
782 }
783 }
784
785 *pchanged = changed;
786}
787
788/****************************************************************************
789 Store a job structure back to the database.
790****************************************************************************/
791
792static bool pjob_store(struct tevent_context *ev,
793 struct messaging_context *msg_ctx,
794 const char* sharename, uint32_t jobid,
795 struct printjob *pjob)
796{
797 uint32_t tmp;
798 TDB_DATA old_data, new_data;
799 bool ret = False;
800 struct tdb_print_db *pdb = get_print_db_byname(sharename);
801 uint8_t *buf = NULL;
802 int len, newlen, buflen;
803
804
805 if (!pdb)
806 return False;
807
808 /* Get old data */
809
810 old_data = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
811
812 /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
813
814 newlen = 0;
815
816 do {
817 len = 0;
818 buflen = newlen;
819 len += tdb_pack(buf+len, buflen-len, "ddddddddddfffff",
820 (uint32_t)pjob->pid,
821 (uint32_t)pjob->jobid,
822 (uint32_t)pjob->sysjob,
823 (uint32_t)pjob->fd,
824 (uint32_t)pjob->starttime,
825 (uint32_t)pjob->status,
826 (uint32_t)pjob->size,
827 (uint32_t)pjob->page_count,
828 (uint32_t)pjob->spooled,
829 (uint32_t)pjob->smbjob,
830 pjob->filename,
831 pjob->jobname,
832 pjob->user,
833 pjob->clientmachine,
834 pjob->queuename);
835
836 len += pack_devicemode(pjob->devmode, buf+len, buflen-len);
837
838 if (buflen != len) {
839 buf = (uint8_t *)SMB_REALLOC(buf, len);
840 if (!buf) {
841 DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
842 goto done;
843 }
844 newlen = len;
845 }
846 } while ( buflen != len );
847
848
849 /* Store new data */
850
851 new_data.dptr = buf;
852 new_data.dsize = len;
853 ret = (tdb_store(pdb->tdb, print_key(jobid, &tmp), new_data,
854 TDB_REPLACE) == 0);
855
856 /* Send notify updates for what has changed */
857
858 if (ret) {
859 bool changed = false;
860 struct printjob old_pjob;
861
862 if (old_data.dsize) {
863 TALLOC_CTX *tmp_ctx = talloc_new(ev);
864 if (tmp_ctx == NULL)
865 goto done;
866
867 len = unpack_pjob(tmp_ctx, old_data.dptr,
868 old_data.dsize, &old_pjob);
869 if (len != -1 ) {
870 pjob_store_notify(ev,
871 msg_ctx,
872 sharename, jobid, &old_pjob,
873 pjob,
874 &changed);
875 if (changed) {
876 add_to_jobs_changed(pdb, jobid);
877 }
878 }
879 talloc_free(tmp_ctx);
880
881 } else {
882 /* new job */
883 pjob_store_notify(ev, msg_ctx,
884 sharename, jobid, NULL, pjob,
885 &changed);
886 }
887 }
888
889done:
890 release_print_db(pdb);
891 SAFE_FREE( old_data.dptr );
892 SAFE_FREE( buf );
893
894 return ret;
895}
896
897/****************************************************************************
898 Remove a job structure from the database.
899****************************************************************************/
900
901static void pjob_delete(struct tevent_context *ev,
902 struct messaging_context *msg_ctx,
903 const char* sharename, uint32_t jobid)
904{
905 uint32_t tmp;
906 struct printjob *pjob;
907 uint32_t job_status = 0;
908 struct tdb_print_db *pdb;
909 TALLOC_CTX *tmp_ctx = talloc_new(ev);
910 if (tmp_ctx == NULL) {
911 return;
912 }
913
914 pdb = get_print_db_byname(sharename);
915 if (!pdb) {
916 goto err_out;
917 }
918
919 pjob = print_job_find(tmp_ctx, sharename, jobid);
920 if (!pjob) {
921 DEBUG(5, ("we were asked to delete nonexistent job %u\n",
922 jobid));
923 goto err_release;
924 }
925
926 /* We must cycle through JOB_STATUS_DELETING and
927 JOB_STATUS_DELETED for the port monitor to delete the job
928 properly. */
929
930 job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
931 notify_job_status(ev, msg_ctx, sharename, jobid, job_status);
932
933 /* Remove from printing.tdb */
934
935 tdb_delete(pdb->tdb, print_key(jobid, &tmp));
936 remove_from_jobs_added(sharename, jobid);
937 rap_jobid_delete(sharename, jobid);
938err_release:
939 release_print_db(pdb);
940err_out:
941 talloc_free(tmp_ctx);
942}
943
944/****************************************************************************
945 List a unix job in the print database.
946****************************************************************************/
947
948static void print_unix_job(struct tevent_context *ev,
949 struct messaging_context *msg_ctx,
950 const char *sharename, print_queue_struct *q,
951 uint32_t jobid)
952{
953 struct printjob pj, *old_pj;
954 TALLOC_CTX *tmp_ctx = talloc_new(ev);
955 if (tmp_ctx == NULL) {
956 return;
957 }
958
959 if (jobid == (uint32_t)-1) {
960 jobid = q->sysjob + UNIX_JOB_START;
961 }
962
963 /* Preserve the timestamp on an existing unix print job */
964
965 old_pj = print_job_find(tmp_ctx, sharename, jobid);
966
967 ZERO_STRUCT(pj);
968
969 pj.pid = (pid_t)-1;
970 pj.jobid = jobid;
971 pj.sysjob = q->sysjob;
972 pj.fd = -1;
973 pj.starttime = old_pj ? old_pj->starttime : q->time;
974 pj.status = q->status;
975 pj.size = q->size;
976 pj.spooled = True;
977 fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
978 if (jobid < UNIX_JOB_START) {
979 pj.smbjob = True;
980 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
981 } else {
982 pj.smbjob = False;
983 fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
984 }
985 fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
986 fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
987
988 pjob_store(ev, msg_ctx, sharename, jobid, &pj);
989 talloc_free(tmp_ctx);
990}
991
992
993struct traverse_struct {
994 print_queue_struct *queue;
995 int qcount, snum, maxcount, total_jobs;
996 const char *sharename;
997 time_t lpq_time;
998 const char *lprm_command;
999 struct printif *print_if;
1000 struct tevent_context *ev;
1001 struct messaging_context *msg_ctx;
1002 TALLOC_CTX *mem_ctx;
1003};
1004
1005/****************************************************************************
1006 Utility fn to delete any jobs that are no longer active.
1007****************************************************************************/
1008
1009static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
1010{
1011 struct traverse_struct *ts = (struct traverse_struct *)state;
1012 struct printjob pjob;
1013 uint32_t jobid;
1014 int i = 0;
1015
1016 if ( key.dsize != sizeof(jobid) )
1017 return 0;
1018
1019 if (unpack_pjob(ts->mem_ctx, data.dptr, data.dsize, &pjob) == -1)
1020 return 0;
1021 talloc_free(pjob.devmode);
1022 jobid = pjob.jobid;
1023
1024 if (!pjob.smbjob) {
1025 /* remove a unix job if it isn't in the system queue any more */
1026 for (i=0;i<ts->qcount;i++) {
1027 if (ts->queue[i].sysjob == pjob.sysjob) {
1028 break;
1029 }
1030 }
1031 if (i == ts->qcount) {
1032 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
1033 (unsigned int)jobid ));
1034 pjob_delete(ts->ev, ts->msg_ctx,
1035 ts->sharename, jobid);
1036 return 0;
1037 }
1038
1039 /* need to continue the the bottom of the function to
1040 save the correct attributes */
1041 }
1042
1043 /* maybe it hasn't been spooled yet */
1044 if (!pjob.spooled) {
1045 /* if a job is not spooled and the process doesn't
1046 exist then kill it. This cleans up after smbd
1047 deaths */
1048 if (!process_exists_by_pid(pjob.pid)) {
1049 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
1050 (unsigned int)jobid, (unsigned int)pjob.pid ));
1051 pjob_delete(ts->ev, ts->msg_ctx,
1052 ts->sharename, jobid);
1053 } else
1054 ts->total_jobs++;
1055 return 0;
1056 }
1057
1058 /* this check only makes sense for jobs submitted from Windows clients */
1059
1060 if (pjob.smbjob) {
1061 for (i=0;i<ts->qcount;i++) {
1062 if ( pjob.status == LPQ_DELETED )
1063 continue;
1064
1065 if (ts->queue[i].sysjob == pjob.sysjob) {
1066
1067 /* try to clean up any jobs that need to be deleted */
1068
1069 if ( pjob.status == LPQ_DELETING ) {
1070 int result;
1071
1072 result = (*(ts->print_if->job_delete))(
1073 ts->sharename, ts->lprm_command, &pjob );
1074
1075 if ( result != 0 ) {
1076 /* if we can't delete, then reset the job status */
1077 pjob.status = LPQ_QUEUED;
1078 pjob_store(ts->ev, ts->msg_ctx,
1079 ts->sharename, jobid, &pjob);
1080 }
1081 else {
1082 /* if we deleted the job, the remove the tdb record */
1083 pjob_delete(ts->ev,
1084 ts->msg_ctx,
1085 ts->sharename, jobid);
1086 pjob.status = LPQ_DELETED;
1087 }
1088
1089 }
1090
1091 break;
1092 }
1093 }
1094 }
1095
1096 /* The job isn't in the system queue - we have to assume it has
1097 completed, so delete the database entry. */
1098
1099 if (i == ts->qcount) {
1100
1101 /* A race can occur between the time a job is spooled and
1102 when it appears in the lpq output. This happens when
1103 the job is added to printing.tdb when another smbd
1104 running print_queue_update() has completed a lpq and
1105 is currently traversing the printing tdb and deleting jobs.
1106 Don't delete the job if it was submitted after the lpq_time. */
1107
1108 if (pjob.starttime < ts->lpq_time) {
1109 DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
1110 (unsigned int)jobid,
1111 (unsigned int)pjob.starttime,
1112 (unsigned int)ts->lpq_time ));
1113 pjob_delete(ts->ev, ts->msg_ctx,
1114 ts->sharename, jobid);
1115 } else
1116 ts->total_jobs++;
1117 return 0;
1118 }
1119
1120 /* Save the pjob attributes we will store. */
1121 ts->queue[i].sysjob = pjob.sysjob;
1122 ts->queue[i].size = pjob.size;
1123 ts->queue[i].page_count = pjob.page_count;
1124 ts->queue[i].status = pjob.status;
1125 ts->queue[i].priority = 1;
1126 ts->queue[i].time = pjob.starttime;
1127 fstrcpy(ts->queue[i].fs_user, pjob.user);
1128 fstrcpy(ts->queue[i].fs_file, pjob.jobname);
1129
1130 ts->total_jobs++;
1131
1132 return 0;
1133}
1134
1135/****************************************************************************
1136 Check if the print queue has been updated recently enough.
1137****************************************************************************/
1138
1139static void print_cache_flush(const char *sharename)
1140{
1141 fstring key;
1142 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1143
1144 if (!pdb)
1145 return;
1146 slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
1147 tdb_store_int32(pdb->tdb, key, -1);
1148 release_print_db(pdb);
1149}
1150
1151/****************************************************************************
1152 Check if someone already thinks they are doing the update.
1153****************************************************************************/
1154
1155static pid_t get_updating_pid(const char *sharename)
1156{
1157 fstring keystr;
1158 TDB_DATA data, key;
1159 pid_t updating_pid;
1160 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1161
1162 if (!pdb)
1163 return (pid_t)-1;
1164 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
1165 key = string_tdb_data(keystr);
1166
1167 data = tdb_fetch(pdb->tdb, key);
1168 release_print_db(pdb);
1169 if (!data.dptr || data.dsize != sizeof(pid_t)) {
1170 SAFE_FREE(data.dptr);
1171 return (pid_t)-1;
1172 }
1173
1174 updating_pid = IVAL(data.dptr, 0);
1175 SAFE_FREE(data.dptr);
1176
1177 if (process_exists_by_pid(updating_pid))
1178 return updating_pid;
1179
1180 return (pid_t)-1;
1181}
1182
1183/****************************************************************************
1184 Set the fact that we're doing the update, or have finished doing the update
1185 in the tdb.
1186****************************************************************************/
1187
1188static void set_updating_pid(const fstring sharename, bool updating)
1189{
1190 fstring keystr;
1191 TDB_DATA key;
1192 TDB_DATA data;
1193 pid_t updating_pid = getpid();
1194 uint8_t buffer[4];
1195
1196 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1197
1198 if (!pdb)
1199 return;
1200
1201 slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
1202 key = string_tdb_data(keystr);
1203
1204 DEBUG(5, ("set_updating_pid: %supdating lpq cache for print share %s\n",
1205 updating ? "" : "not ",
1206 sharename ));
1207
1208 if ( !updating ) {
1209 tdb_delete(pdb->tdb, key);
1210 release_print_db(pdb);
1211 return;
1212 }
1213
1214 SIVAL( buffer, 0, updating_pid);
1215 data.dptr = buffer;
1216 data.dsize = 4; /* we always assume this is a 4 byte value */
1217
1218 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1219 release_print_db(pdb);
1220}
1221
1222/****************************************************************************
1223 Sort print jobs by submittal time.
1224****************************************************************************/
1225
1226static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
1227{
1228 /* Silly cases */
1229
1230 if (!j1 && !j2)
1231 return 0;
1232 if (!j1)
1233 return -1;
1234 if (!j2)
1235 return 1;
1236
1237 /* Sort on job start time */
1238
1239 if (j1->time == j2->time)
1240 return 0;
1241 return (j1->time > j2->time) ? 1 : -1;
1242}
1243
1244/****************************************************************************
1245 Store the sorted queue representation for later portmon retrieval.
1246 Skip deleted jobs
1247****************************************************************************/
1248
1249static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
1250{
1251 TDB_DATA data;
1252 int max_reported_jobs = lp_max_reported_print_jobs(pts->snum);
1253 print_queue_struct *queue = pts->queue;
1254 size_t len;
1255 size_t i;
1256 unsigned int qcount;
1257
1258 if (max_reported_jobs && (max_reported_jobs < pts->qcount))
1259 pts->qcount = max_reported_jobs;
1260 qcount = 0;
1261
1262 /* Work out the size. */
1263 data.dsize = 0;
1264 data.dsize += tdb_pack(NULL, 0, "d", qcount);
1265
1266 for (i = 0; i < pts->qcount; i++) {
1267 if ( queue[i].status == LPQ_DELETED )
1268 continue;
1269
1270 qcount++;
1271 data.dsize += tdb_pack(NULL, 0, "ddddddff",
1272 (uint32_t)queue[i].sysjob,
1273 (uint32_t)queue[i].size,
1274 (uint32_t)queue[i].page_count,
1275 (uint32_t)queue[i].status,
1276 (uint32_t)queue[i].priority,
1277 (uint32_t)queue[i].time,
1278 queue[i].fs_user,
1279 queue[i].fs_file);
1280 }
1281
1282 if ((data.dptr = (uint8_t *)SMB_MALLOC(data.dsize)) == NULL)
1283 return;
1284
1285 len = 0;
1286 len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
1287 for (i = 0; i < pts->qcount; i++) {
1288 if ( queue[i].status == LPQ_DELETED )
1289 continue;
1290
1291 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
1292 (uint32_t)queue[i].sysjob,
1293 (uint32_t)queue[i].size,
1294 (uint32_t)queue[i].page_count,
1295 (uint32_t)queue[i].status,
1296 (uint32_t)queue[i].priority,
1297 (uint32_t)queue[i].time,
1298 queue[i].fs_user,
1299 queue[i].fs_file);
1300 }
1301
1302 tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
1303 TDB_REPLACE);
1304 SAFE_FREE(data.dptr);
1305 return;
1306}
1307
1308static TDB_DATA get_jobs_added_data(struct tdb_print_db *pdb)
1309{
1310 TDB_DATA data;
1311
1312 ZERO_STRUCT(data);
1313
1314 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added"));
1315 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
1316 SAFE_FREE(data.dptr);
1317 ZERO_STRUCT(data);
1318 }
1319
1320 return data;
1321}
1322
1323static void check_job_added(const char *sharename, TDB_DATA data, uint32_t jobid)
1324{
1325 unsigned int i;
1326 unsigned int job_count = data.dsize / 4;
1327
1328 for (i = 0; i < job_count; i++) {
1329 uint32_t ch_jobid;
1330
1331 ch_jobid = IVAL(data.dptr, i*4);
1332 if (ch_jobid == jobid)
1333 remove_from_jobs_added(sharename, jobid);
1334 }
1335}
1336
1337/****************************************************************************
1338 Check if the print queue has been updated recently enough.
1339****************************************************************************/
1340
1341static bool print_cache_expired(const char *sharename, bool check_pending)
1342{
1343 fstring key;
1344 time_t last_qscan_time, time_now = time(NULL);
1345 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1346 bool result = False;
1347
1348 if (!pdb)
1349 return False;
1350
1351 snprintf(key, sizeof(key), "CACHE/%s", sharename);
1352 last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1353
1354 /*
1355 * Invalidate the queue for 3 reasons.
1356 * (1). last queue scan time == -1.
1357 * (2). Current time - last queue scan time > allowed cache time.
1358 * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1359 * This last test picks up machines for which the clock has been moved
1360 * forward, an lpq scan done and then the clock moved back. Otherwise
1361 * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1362 */
1363
1364 if (last_qscan_time == ((time_t)-1)
1365 || (time_now - last_qscan_time) >= lp_lpq_cache_time()
1366 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
1367 {
1368 uint32_t u;
1369 time_t msg_pending_time;
1370
1371 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1372 "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1373 sharename, (int)last_qscan_time, (int)time_now,
1374 (int)lp_lpq_cache_time() ));
1375
1376 /* check if another smbd has already sent a message to update the
1377 queue. Give the pending message one minute to clear and
1378 then send another message anyways. Make sure to check for
1379 clocks that have been run forward and then back again. */
1380
1381 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1382
1383 if ( check_pending
1384 && tdb_fetch_uint32( pdb->tdb, key, &u )
1385 && (msg_pending_time=u) > 0
1386 && msg_pending_time <= time_now
1387 && (time_now - msg_pending_time) < 60 )
1388 {
1389 DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
1390 sharename));
1391 goto done;
1392 }
1393
1394 result = True;
1395 }
1396
1397done:
1398 release_print_db(pdb);
1399 return result;
1400}
1401
1402/****************************************************************************
1403 main work for updating the lpq cache for a printer queue
1404****************************************************************************/
1405
1406static void print_queue_update_internal(struct tevent_context *ev,
1407 struct messaging_context *msg_ctx,
1408 const char *sharename,
1409 struct printif *current_printif,
1410 char *lpq_command, char *lprm_command)
1411{
1412 int i, qcount;
1413 print_queue_struct *queue = NULL;
1414 print_status_struct status;
1415 print_status_struct old_status;
1416 struct printjob *pjob;
1417 struct traverse_struct tstruct;
1418 TDB_DATA data, key;
1419 TDB_DATA jcdata;
1420 fstring keystr, cachestr;
1421 struct tdb_print_db *pdb = get_print_db_byname(sharename);
1422 TALLOC_CTX *tmp_ctx = talloc_new(ev);
1423
1424 if ((pdb == NULL) || (tmp_ctx == NULL)) {
1425 return;
1426 }
1427
1428 DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1429 sharename, current_printif->type, lpq_command));
1430
1431 /*
1432 * Update the cache time FIRST ! Stops others even
1433 * attempting to get the lock and doing this
1434 * if the lpq takes a long time.
1435 */
1436
1437 slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1438 tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1439
1440 /* get the current queue using the appropriate interface */
1441 ZERO_STRUCT(status);
1442
1443 qcount = (*(current_printif->queue_get))(sharename,
1444 current_printif->type,
1445 lpq_command, &queue, &status);
1446
1447 DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1448 qcount, (qcount != 1) ? "s" : "", sharename));
1449
1450 /* Sort the queue by submission time otherwise they are displayed
1451 in hash order. */
1452
1453 TYPESAFE_QSORT(queue, qcount, printjob_comp);
1454
1455 /*
1456 any job in the internal database that is marked as spooled
1457 and doesn't exist in the system queue is considered finished
1458 and removed from the database
1459
1460 any job in the system database but not in the internal database
1461 is added as a unix job
1462
1463 fill in any system job numbers as we go
1464 */
1465 jcdata = get_jobs_added_data(pdb);
1466
1467 for (i=0; i<qcount; i++) {
1468 uint32_t jobid = sysjob_to_jobid_pdb(pdb, queue[i].sysjob);
1469 if (jobid == (uint32_t)-1) {
1470 /* assume its a unix print job */
1471 print_unix_job(ev, msg_ctx,
1472 sharename, &queue[i], jobid);
1473 continue;
1474 }
1475
1476 /* we have an active SMB print job - update its status */
1477 pjob = print_job_find(tmp_ctx, sharename, jobid);
1478 if (!pjob) {
1479 /* err, somethings wrong. Probably smbd was restarted
1480 with jobs in the queue. All we can do is treat them
1481 like unix jobs. Pity. */
1482 DEBUG(1, ("queued print job %d not found in jobs list, "
1483 "assuming unix job\n", jobid));
1484 print_unix_job(ev, msg_ctx,
1485 sharename, &queue[i], jobid);
1486 continue;
1487 }
1488
1489 /* don't reset the status on jobs to be deleted */
1490
1491 if ( pjob->status != LPQ_DELETING )
1492 pjob->status = queue[i].status;
1493
1494 pjob_store(ev, msg_ctx, sharename, jobid, pjob);
1495
1496 check_job_added(sharename, jcdata, jobid);
1497 }
1498
1499 SAFE_FREE(jcdata.dptr);
1500
1501 /* now delete any queued entries that don't appear in the
1502 system queue */
1503 tstruct.queue = queue;
1504 tstruct.qcount = qcount;
1505 tstruct.snum = -1;
1506 tstruct.total_jobs = 0;
1507 tstruct.lpq_time = time(NULL);
1508 tstruct.sharename = sharename;
1509 tstruct.lprm_command = lprm_command;
1510 tstruct.print_if = current_printif;
1511 tstruct.ev = ev;
1512 tstruct.msg_ctx = msg_ctx;
1513 tstruct.mem_ctx = tmp_ctx;
1514
1515 tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1516
1517 /* Store the linearised queue, max jobs only. */
1518 store_queue_struct(pdb, &tstruct);
1519
1520 SAFE_FREE(tstruct.queue);
1521 talloc_free(tmp_ctx);
1522
1523 DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1524 sharename, tstruct.total_jobs ));
1525
1526 tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1527
1528 get_queue_status(sharename, &old_status);
1529 if (old_status.qcount != qcount)
1530 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1531 old_status.qcount, qcount, sharename));
1532
1533 /* store the new queue status structure */
1534 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1535 key = string_tdb_data(keystr);
1536
1537 status.qcount = qcount;
1538 data.dptr = (uint8_t *)&status;
1539 data.dsize = sizeof(status);
1540 tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1541
1542 /*
1543 * Update the cache time again. We want to do this call
1544 * as little as possible...
1545 */
1546
1547 slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1548 tdb_store_int32(pdb->tdb, keystr, (int32_t)time(NULL));
1549
1550 /* clear the msg pending record for this queue */
1551
1552 snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1553
1554 if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1555 /* log a message but continue on */
1556
1557 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1558 sharename));
1559 }
1560
1561 release_print_db( pdb );
1562
1563 return;
1564}
1565
1566/****************************************************************************
1567 Update the internal database from the system print queue for a queue.
1568 obtain a lock on the print queue before proceeding (needed when mutiple
1569 smbd processes maytry to update the lpq cache concurrently).
1570****************************************************************************/
1571
1572static void print_queue_update_with_lock( struct tevent_context *ev,
1573 struct messaging_context *msg_ctx,
1574 const char *sharename,
1575 struct printif *current_printif,
1576 char *lpq_command, char *lprm_command )
1577{
1578 fstring keystr;
1579 struct tdb_print_db *pdb;
1580
1581 DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1582 pdb = get_print_db_byname(sharename);
1583 if (!pdb)
1584 return;
1585
1586 if ( !print_cache_expired(sharename, False) ) {
1587 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1588 release_print_db(pdb);
1589 return;
1590 }
1591
1592 /*
1593 * Check to see if someone else is doing this update.
1594 * This is essentially a mutex on the update.
1595 */
1596
1597 if (get_updating_pid(sharename) != -1) {
1598 release_print_db(pdb);
1599 return;
1600 }
1601
1602 /* Lock the queue for the database update */
1603
1604 slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1605 /* Only wait 10 seconds for this. */
1606 if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) != 0) {
1607 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1608 release_print_db(pdb);
1609 return;
1610 }
1611
1612 /*
1613 * Ensure that no one else got in here.
1614 * If the updating pid is still -1 then we are
1615 * the winner.
1616 */
1617
1618 if (get_updating_pid(sharename) != -1) {
1619 /*
1620 * Someone else is doing the update, exit.
1621 */
1622 tdb_unlock_bystring(pdb->tdb, keystr);
1623 release_print_db(pdb);
1624 return;
1625 }
1626
1627 /*
1628 * We're going to do the update ourselves.
1629 */
1630
1631 /* Tell others we're doing the update. */
1632 set_updating_pid(sharename, True);
1633
1634 /*
1635 * Allow others to enter and notice we're doing
1636 * the update.
1637 */
1638
1639 tdb_unlock_bystring(pdb->tdb, keystr);
1640
1641 /* do the main work now */
1642
1643 print_queue_update_internal(ev, msg_ctx,
1644 sharename, current_printif,
1645 lpq_command, lprm_command);
1646
1647 /* Delete our pid from the db. */
1648 set_updating_pid(sharename, False);
1649 release_print_db(pdb);
1650}
1651
1652/****************************************************************************
1653this is the receive function of the background lpq updater
1654****************************************************************************/
1655void print_queue_receive(struct messaging_context *msg,
1656 void *private_data,
1657 uint32_t msg_type,
1658 struct server_id server_id,
1659 DATA_BLOB *data)
1660{
1661 fstring sharename;
1662 char *lpqcommand = NULL, *lprmcommand = NULL;
1663 int printing_type;
1664 size_t len;
1665
1666 len = tdb_unpack( (uint8_t *)data->data, data->length, "fdPP",
1667 sharename,
1668 &printing_type,
1669 &lpqcommand,
1670 &lprmcommand );
1671
1672 if ( len == -1 ) {
1673 SAFE_FREE(lpqcommand);
1674 SAFE_FREE(lprmcommand);
1675 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1676 return;
1677 }
1678
1679 print_queue_update_with_lock(server_event_context(), msg, sharename,
1680 get_printer_fns_from_type((enum printing_types)printing_type),
1681 lpqcommand, lprmcommand );
1682
1683 SAFE_FREE(lpqcommand);
1684 SAFE_FREE(lprmcommand);
1685 return;
1686}
1687
1688/****************************************************************************
1689update the internal database from the system print queue for a queue
1690****************************************************************************/
1691
1692extern pid_t background_lpq_updater_pid;
1693
1694static void print_queue_update(struct messaging_context *msg_ctx,
1695 int snum, bool force)
1696{
1697 fstring key;
1698 fstring sharename;
1699 char *lpqcommand = NULL;
1700 char *lprmcommand = NULL;
1701 uint8_t *buffer = NULL;
1702 size_t len = 0;
1703 size_t newlen;
1704 struct tdb_print_db *pdb;
1705 int type;
1706 struct printif *current_printif;
1707 TALLOC_CTX *ctx = talloc_tos();
1708
1709 fstrcpy( sharename, lp_const_servicename(snum));
1710
1711 /* don't strip out characters like '$' from the printername */
1712
1713 lpqcommand = talloc_string_sub2(ctx,
1714 lp_lpq_command(talloc_tos(), snum),
1715 "%p",
1716 lp_printername(talloc_tos(), snum),
1717 false, false, false);
1718 if (!lpqcommand) {
1719 return;
1720 }
1721 lpqcommand = talloc_sub_advanced(ctx,
1722 lp_servicename(talloc_tos(), snum),
1723 current_user_info.unix_name,
1724 "",
1725 current_user.ut.gid,
1726 get_current_username(),
1727 current_user_info.domain,
1728 lpqcommand);
1729 if (!lpqcommand) {
1730 return;
1731 }
1732
1733 lprmcommand = talloc_string_sub2(ctx,
1734 lp_lprm_command(talloc_tos(), snum),
1735 "%p",
1736 lp_printername(talloc_tos(), snum),
1737 false, false, false);
1738 if (!lprmcommand) {
1739 return;
1740 }
1741 lprmcommand = talloc_sub_advanced(ctx,
1742 lp_servicename(talloc_tos(), snum),
1743 current_user_info.unix_name,
1744 "",
1745 current_user.ut.gid,
1746 get_current_username(),
1747 current_user_info.domain,
1748 lprmcommand);
1749 if (!lprmcommand) {
1750 return;
1751 }
1752
1753 /*
1754 * Make sure that the background queue process exists.
1755 * Otherwise just do the update ourselves
1756 */
1757
1758 if ( force || background_lpq_updater_pid == -1 ) {
1759 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1760 current_printif = get_printer_fns( snum );
1761 print_queue_update_with_lock(server_event_context(), msg_ctx,
1762 sharename, current_printif,
1763 lpqcommand, lprmcommand);
1764
1765 return;
1766 }
1767
1768 type = lp_printing(snum);
1769
1770 /* get the length */
1771
1772 len = tdb_pack( NULL, 0, "fdPP",
1773 sharename,
1774 type,
1775 lpqcommand,
1776 lprmcommand );
1777
1778 buffer = SMB_XMALLOC_ARRAY( uint8_t, len );
1779
1780 /* now pack the buffer */
1781 newlen = tdb_pack( buffer, len, "fdPP",
1782 sharename,
1783 type,
1784 lpqcommand,
1785 lprmcommand );
1786
1787 SMB_ASSERT( newlen == len );
1788
1789 DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1790 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1791 sharename, type, lpqcommand, lprmcommand ));
1792
1793 /* here we set a msg pending record for other smbd processes
1794 to throttle the number of duplicate print_queue_update msgs
1795 sent. */
1796
1797 pdb = get_print_db_byname(sharename);
1798 if (!pdb) {
1799 SAFE_FREE(buffer);
1800 return;
1801 }
1802
1803 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1804
1805 if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1806 /* log a message but continue on */
1807
1808 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1809 sharename));
1810 }
1811
1812 release_print_db( pdb );
1813
1814 /* finally send the message */
1815
1816 messaging_send_buf(msg_ctx, pid_to_procid(background_lpq_updater_pid),
1817 MSG_PRINTER_UPDATE, (uint8_t *)buffer, len);
1818
1819 SAFE_FREE( buffer );
1820
1821 return;
1822}
1823
1824/****************************************************************************
1825 Create/Update an entry in the print tdb that will allow us to send notify
1826 updates only to interested smbd's.
1827****************************************************************************/
1828
1829bool print_notify_register_pid(int snum)
1830{
1831 TDB_DATA data;
1832 struct tdb_print_db *pdb = NULL;
1833 TDB_CONTEXT *tdb = NULL;
1834 const char *printername;
1835 uint32_t mypid = (uint32_t)getpid();
1836 bool ret = False;
1837 size_t i;
1838
1839 /* if (snum == -1), then the change notify request was
1840 on a print server handle and we need to register on
1841 all print queus */
1842
1843 if (snum == -1)
1844 {
1845 int num_services = lp_numservices();
1846 int idx;
1847
1848 for ( idx=0; idx<num_services; idx++ ) {
1849 if (lp_snum_ok(idx) && lp_printable(idx) )
1850 print_notify_register_pid(idx);
1851 }
1852
1853 return True;
1854 }
1855 else /* register for a specific printer */
1856 {
1857 printername = lp_const_servicename(snum);
1858 pdb = get_print_db_byname(printername);
1859 if (!pdb)
1860 return False;
1861 tdb = pdb->tdb;
1862 }
1863
1864 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) != 0) {
1865 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1866 printername));
1867 if (pdb)
1868 release_print_db(pdb);
1869 return False;
1870 }
1871
1872 data = get_printer_notify_pid_list( tdb, printername, True );
1873
1874 /* Add ourselves and increase the refcount. */
1875
1876 for (i = 0; i < data.dsize; i += 8) {
1877 if (IVAL(data.dptr,i) == mypid) {
1878 uint32_t new_refcount = IVAL(data.dptr, i+4) + 1;
1879 SIVAL(data.dptr, i+4, new_refcount);
1880 break;
1881 }
1882 }
1883
1884 if (i == data.dsize) {
1885 /* We weren't in the list. Realloc. */
1886 data.dptr = (uint8_t *)SMB_REALLOC(data.dptr, data.dsize + 8);
1887 if (!data.dptr) {
1888 DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1889 printername));
1890 goto done;
1891 }
1892 data.dsize += 8;
1893 SIVAL(data.dptr,data.dsize - 8,mypid);
1894 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1895 }
1896
1897 /* Store back the record. */
1898 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) != 0) {
1899 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1900list for printer %s\n", printername));
1901 goto done;
1902 }
1903
1904 ret = True;
1905
1906 done:
1907
1908 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1909 if (pdb)
1910 release_print_db(pdb);
1911 SAFE_FREE(data.dptr);
1912 return ret;
1913}
1914
1915/****************************************************************************
1916 Update an entry in the print tdb that will allow us to send notify
1917 updates only to interested smbd's.
1918****************************************************************************/
1919
1920bool print_notify_deregister_pid(int snum)
1921{
1922 TDB_DATA data;
1923 struct tdb_print_db *pdb = NULL;
1924 TDB_CONTEXT *tdb = NULL;
1925 const char *printername;
1926 uint32_t mypid = (uint32_t)getpid();
1927 size_t i;
1928 bool ret = False;
1929
1930 /* if ( snum == -1 ), we are deregister a print server handle
1931 which means to deregister on all print queues */
1932
1933 if (snum == -1)
1934 {
1935 int num_services = lp_numservices();
1936 int idx;
1937
1938 for ( idx=0; idx<num_services; idx++ ) {
1939 if ( lp_snum_ok(idx) && lp_printable(idx) )
1940 print_notify_deregister_pid(idx);
1941 }
1942
1943 return True;
1944 }
1945 else /* deregister a specific printer */
1946 {
1947 printername = lp_const_servicename(snum);
1948 pdb = get_print_db_byname(printername);
1949 if (!pdb)
1950 return False;
1951 tdb = pdb->tdb;
1952 }
1953
1954 if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) != 0) {
1955 DEBUG(0,("print_notify_register_pid: Failed to lock \
1956printer %s database\n", printername));
1957 if (pdb)
1958 release_print_db(pdb);
1959 return False;
1960 }
1961
1962 data = get_printer_notify_pid_list( tdb, printername, True );
1963
1964 /* Reduce refcount. Remove ourselves if zero. */
1965
1966 for (i = 0; i < data.dsize; ) {
1967 if (IVAL(data.dptr,i) == mypid) {
1968 uint32_t refcount = IVAL(data.dptr, i+4);
1969
1970 refcount--;
1971
1972 if (refcount == 0) {
1973 if (data.dsize - i > 8)
1974 memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1975 data.dsize -= 8;
1976 continue;
1977 }
1978 SIVAL(data.dptr, i+4, refcount);
1979 }
1980
1981 i += 8;
1982 }
1983
1984 if (data.dsize == 0)
1985 SAFE_FREE(data.dptr);
1986
1987 /* Store back the record. */
1988 if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) != 0) {
1989 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1990list for printer %s\n", printername));
1991 goto done;
1992 }
1993
1994 ret = True;
1995
1996 done:
1997
1998 tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1999 if (pdb)
2000 release_print_db(pdb);
2001 SAFE_FREE(data.dptr);
2002 return ret;
2003}
2004
2005/****************************************************************************
2006 Check if a jobid is valid. It is valid if it exists in the database.
2007****************************************************************************/
2008
2009bool print_job_exists(const char* sharename, uint32_t jobid)
2010{
2011 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2012 bool ret;
2013 uint32_t tmp;
2014
2015 if (!pdb)
2016 return False;
2017 ret = tdb_exists(pdb->tdb, print_key(jobid, &tmp));
2018 release_print_db(pdb);
2019 return ret;
2020}
2021
2022/****************************************************************************
2023 Return the device mode asigned to a specific print job.
2024 Only valid for the process doing the spooling and when the job
2025 has not been spooled.
2026****************************************************************************/
2027
2028struct spoolss_DeviceMode *print_job_devmode(TALLOC_CTX *mem_ctx,
2029 const char *sharename,
2030 uint32_t jobid)
2031{
2032 struct printjob *pjob = print_job_find(mem_ctx, sharename, jobid);
2033 if (pjob == NULL) {
2034 return NULL;
2035 }
2036
2037 return pjob->devmode;
2038}
2039
2040/****************************************************************************
2041 Set the name of a job. Only possible for owner.
2042****************************************************************************/
2043
2044bool print_job_set_name(struct tevent_context *ev,
2045 struct messaging_context *msg_ctx,
2046 const char *sharename, uint32_t jobid, const char *name)
2047{
2048 struct printjob *pjob;
2049 bool ret;
2050 TALLOC_CTX *tmp_ctx = talloc_new(ev);
2051 if (tmp_ctx == NULL) {
2052 return false;
2053 }
2054
2055 pjob = print_job_find(tmp_ctx, sharename, jobid);
2056 if (!pjob || pjob->pid != getpid()) {
2057 ret = false;
2058 goto err_out;
2059 }
2060
2061 fstrcpy(pjob->jobname, name);
2062 ret = pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2063err_out:
2064 talloc_free(tmp_ctx);
2065 return ret;
2066}
2067
2068/****************************************************************************
2069 Get the name of a job. Only possible for owner.
2070****************************************************************************/
2071
2072bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t jobid, char **name)
2073{
2074 struct printjob *pjob;
2075
2076 pjob = print_job_find(mem_ctx, sharename, jobid);
2077 if (!pjob || pjob->pid != getpid()) {
2078 return false;
2079 }
2080
2081 *name = pjob->jobname;
2082 return true;
2083}
2084
2085
2086/***************************************************************************
2087 Remove a jobid from the 'jobs added' list.
2088***************************************************************************/
2089
2090static bool remove_from_jobs_added(const char* sharename, uint32_t jobid)
2091{
2092 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2093 TDB_DATA data, key;
2094 size_t job_count, i;
2095 bool ret = False;
2096 bool gotlock = False;
2097
2098 if (!pdb) {
2099 return False;
2100 }
2101
2102 ZERO_STRUCT(data);
2103
2104 key = string_tdb_data("INFO/jobs_added");
2105
2106 if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) != 0)
2107 goto out;
2108
2109 gotlock = True;
2110
2111 data = tdb_fetch(pdb->tdb, key);
2112
2113 if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
2114 goto out;
2115
2116 job_count = data.dsize / 4;
2117 for (i = 0; i < job_count; i++) {
2118 uint32_t ch_jobid;
2119
2120 ch_jobid = IVAL(data.dptr, i*4);
2121 if (ch_jobid == jobid) {
2122 if (i < job_count -1 )
2123 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
2124 data.dsize -= 4;
2125 if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) != 0)
2126 goto out;
2127 break;
2128 }
2129 }
2130
2131 ret = True;
2132 out:
2133
2134 if (gotlock)
2135 tdb_chainunlock(pdb->tdb, key);
2136 SAFE_FREE(data.dptr);
2137 release_print_db(pdb);
2138 if (ret)
2139 DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid ));
2140 else
2141 DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid ));
2142 return ret;
2143}
2144
2145/****************************************************************************
2146 Delete a print job - don't update queue.
2147****************************************************************************/
2148
2149static bool print_job_delete1(struct tevent_context *ev,
2150 struct messaging_context *msg_ctx,
2151 int snum, uint32_t jobid)
2152{
2153 const char* sharename = lp_const_servicename(snum);
2154 struct printjob *pjob;
2155 int result = 0;
2156 struct printif *current_printif = get_printer_fns( snum );
2157 bool ret;
2158 TALLOC_CTX *tmp_ctx = talloc_new(ev);
2159 if (tmp_ctx == NULL) {
2160 return false;
2161 }
2162
2163 pjob = print_job_find(tmp_ctx, sharename, jobid);
2164 if (!pjob) {
2165 ret = false;
2166 goto err_out;
2167 }
2168
2169 /*
2170 * If already deleting just return.
2171 */
2172
2173 if (pjob->status == LPQ_DELETING) {
2174 ret = true;
2175 goto err_out;
2176 }
2177
2178 /* Hrm - we need to be able to cope with deleting a job before it
2179 has reached the spooler. Just mark it as LPQ_DELETING and
2180 let the print_queue_update() code rmeove the record */
2181
2182
2183 if (pjob->sysjob == -1) {
2184 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
2185 }
2186
2187 /* Set the tdb entry to be deleting. */
2188
2189 pjob->status = LPQ_DELETING;
2190 pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2191
2192 if (pjob->spooled && pjob->sysjob != -1)
2193 {
2194 result = (*(current_printif->job_delete))(
2195 lp_printername(talloc_tos(), snum),
2196 lp_lprm_command(talloc_tos(), snum),
2197 pjob);
2198
2199 /* Delete the tdb entry if the delete succeeded or the job hasn't
2200 been spooled. */
2201
2202 if (result == 0) {
2203 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2204 int njobs = 1;
2205
2206 if (!pdb) {
2207 ret = false;
2208 goto err_out;
2209 }
2210 pjob_delete(ev, msg_ctx, sharename, jobid);
2211 /* Ensure we keep a rough count of the number of total jobs... */
2212 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
2213 release_print_db(pdb);
2214 }
2215 }
2216
2217 remove_from_jobs_added( sharename, jobid );
2218
2219 ret = (result == 0);
2220err_out:
2221 talloc_free(tmp_ctx);
2222 return ret;
2223}
2224
2225/****************************************************************************
2226 Return true if the current user owns the print job.
2227****************************************************************************/
2228
2229static bool is_owner(const struct auth_session_info *server_info,
2230 const char *servicename,
2231 uint32_t jobid)
2232{
2233 struct printjob *pjob;
2234 bool ret;
2235 TALLOC_CTX *tmp_ctx = talloc_new(server_info);
2236 if (tmp_ctx == NULL) {
2237 return false;
2238 }
2239
2240 pjob = print_job_find(tmp_ctx, servicename, jobid);
2241 if (!pjob || !server_info) {
2242 ret = false;
2243 goto err_out;
2244 }
2245
2246 ret = strequal(pjob->user, server_info->unix_info->sanitized_username);
2247err_out:
2248 talloc_free(tmp_ctx);
2249 return ret;
2250}
2251
2252/****************************************************************************
2253 Delete a print job.
2254****************************************************************************/
2255
2256WERROR print_job_delete(const struct auth_session_info *server_info,
2257 struct messaging_context *msg_ctx,
2258 int snum, uint32_t jobid)
2259{
2260 const char* sharename = lp_const_servicename(snum);
2261 struct printjob *pjob;
2262 bool owner;
2263 WERROR werr;
2264 TALLOC_CTX *tmp_ctx = talloc_new(msg_ctx);
2265 if (tmp_ctx == NULL) {
2266 return WERR_NOT_ENOUGH_MEMORY;
2267 }
2268
2269 owner = is_owner(server_info, lp_const_servicename(snum), jobid);
2270
2271 /* Check access against security descriptor or whether the user
2272 owns their job. */
2273
2274 if (!owner &&
2275 !W_ERROR_IS_OK(print_access_check(server_info, msg_ctx, snum,
2276 JOB_ACCESS_ADMINISTER))) {
2277 DEBUG(0, ("print job delete denied."
2278 "User name: %s, Printer name: %s.",
2279 uidtoname(server_info->unix_token->uid),
2280 lp_printername(tmp_ctx, snum)));
2281
2282 werr = WERR_ACCESS_DENIED;
2283 goto err_out;
2284 }
2285
2286 /*
2287 * get the spooled filename of the print job
2288 * if this works, then the file has not been spooled
2289 * to the underlying print system. Just delete the
2290 * spool file & return.
2291 */
2292
2293 pjob = print_job_find(tmp_ctx, sharename, jobid);
2294 if (!pjob || pjob->spooled || pjob->pid != getpid()) {
2295 DEBUG(10, ("Skipping spool file removal for job %u\n", jobid));
2296 } else {
2297 DEBUG(10, ("Removing spool file [%s]\n", pjob->filename));
2298 if (unlink(pjob->filename) == -1) {
2299 werr = map_werror_from_unix(errno);
2300 goto err_out;
2301 }
2302 }
2303
2304 if (!print_job_delete1(server_event_context(), msg_ctx, snum, jobid)) {
2305 werr = WERR_ACCESS_DENIED;
2306 goto err_out;
2307 }
2308
2309 /* force update the database and say the delete failed if the
2310 job still exists */
2311
2312 print_queue_update(msg_ctx, snum, True);
2313
2314 pjob = print_job_find(tmp_ctx, sharename, jobid);
2315 if (pjob && (pjob->status != LPQ_DELETING)) {
2316 werr = WERR_ACCESS_DENIED;
2317 goto err_out;
2318 }
2319 werr = WERR_PRINTER_HAS_JOBS_QUEUED;
2320
2321err_out:
2322 talloc_free(tmp_ctx);
2323 return werr;
2324}
2325
2326/****************************************************************************
2327 Pause a job.
2328****************************************************************************/
2329
2330WERROR print_job_pause(const struct auth_session_info *server_info,
2331 struct messaging_context *msg_ctx,
2332 int snum, uint32_t jobid)
2333{
2334 const char* sharename = lp_const_servicename(snum);
2335 struct printjob *pjob;
2336 int ret = -1;
2337 struct printif *current_printif = get_printer_fns( snum );
2338 WERROR werr;
2339 TALLOC_CTX *tmp_ctx = talloc_new(msg_ctx);
2340 if (tmp_ctx == NULL) {
2341 return WERR_NOT_ENOUGH_MEMORY;
2342 }
2343
2344 pjob = print_job_find(tmp_ctx, sharename, jobid);
2345 if (!pjob || !server_info) {
2346 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2347 (unsigned int)jobid ));
2348 werr = WERR_INVALID_PARAM;
2349 goto err_out;
2350 }
2351
2352 if (!pjob->spooled || pjob->sysjob == -1) {
2353 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2354 (int)pjob->sysjob, (unsigned int)jobid ));
2355 werr = WERR_INVALID_PARAM;
2356 goto err_out;
2357 }
2358
2359 if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2360 !W_ERROR_IS_OK(print_access_check(server_info, msg_ctx, snum,
2361 JOB_ACCESS_ADMINISTER))) {
2362 DEBUG(0, ("print job pause denied."
2363 "User name: %s, Printer name: %s.",
2364 uidtoname(server_info->unix_token->uid),
2365 lp_printername(tmp_ctx, snum)));
2366
2367 werr = WERR_ACCESS_DENIED;
2368 goto err_out;
2369 }
2370
2371 /* need to pause the spooled entry */
2372 ret = (*(current_printif->job_pause))(snum, pjob);
2373
2374 if (ret != 0) {
2375 werr = WERR_INVALID_PARAM;
2376 goto err_out;
2377 }
2378
2379 /* force update the database */
2380 print_cache_flush(lp_const_servicename(snum));
2381
2382 /* Send a printer notify message */
2383
2384 notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2385 JOB_STATUS_PAUSED);
2386
2387 /* how do we tell if this succeeded? */
2388 werr = WERR_OK;
2389err_out:
2390 talloc_free(tmp_ctx);
2391 return werr;
2392}
2393
2394/****************************************************************************
2395 Resume a job.
2396****************************************************************************/
2397
2398WERROR print_job_resume(const struct auth_session_info *server_info,
2399 struct messaging_context *msg_ctx,
2400 int snum, uint32_t jobid)
2401{
2402 const char *sharename = lp_const_servicename(snum);
2403 struct printjob *pjob;
2404 int ret;
2405 struct printif *current_printif = get_printer_fns( snum );
2406 WERROR werr;
2407 TALLOC_CTX *tmp_ctx = talloc_new(msg_ctx);
2408 if (tmp_ctx == NULL)
2409 return WERR_NOT_ENOUGH_MEMORY;
2410
2411 pjob = print_job_find(tmp_ctx, sharename, jobid);
2412 if (!pjob || !server_info) {
2413 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2414 (unsigned int)jobid ));
2415 werr = WERR_INVALID_PARAM;
2416 goto err_out;
2417 }
2418
2419 if (!pjob->spooled || pjob->sysjob == -1) {
2420 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2421 (int)pjob->sysjob, (unsigned int)jobid ));
2422 werr = WERR_INVALID_PARAM;
2423 goto err_out;
2424 }
2425
2426 if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2427 !W_ERROR_IS_OK(print_access_check(server_info, msg_ctx, snum,
2428 JOB_ACCESS_ADMINISTER))) {
2429 DEBUG(0, ("print job resume denied."
2430 "User name: %s, Printer name: %s.",
2431 uidtoname(server_info->unix_token->uid),
2432 lp_printername(tmp_ctx, snum)));
2433
2434 werr = WERR_ACCESS_DENIED;
2435 goto err_out;
2436 }
2437
2438 ret = (*(current_printif->job_resume))(snum, pjob);
2439
2440 if (ret != 0) {
2441 werr = WERR_INVALID_PARAM;
2442 goto err_out;
2443 }
2444
2445 /* force update the database */
2446 print_cache_flush(lp_const_servicename(snum));
2447
2448 /* Send a printer notify message */
2449
2450 notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2451 JOB_STATUS_QUEUED);
2452
2453 werr = WERR_OK;
2454err_out:
2455 talloc_free(tmp_ctx);
2456 return werr;
2457}
2458
2459/****************************************************************************
2460 Write to a print file.
2461****************************************************************************/
2462
2463ssize_t print_job_write(struct tevent_context *ev,
2464 struct messaging_context *msg_ctx,
2465 int snum, uint32_t jobid, const char *buf, size_t size)
2466{
2467 const char* sharename = lp_const_servicename(snum);
2468 ssize_t return_code;
2469 struct printjob *pjob;
2470 TALLOC_CTX *tmp_ctx = talloc_new(ev);
2471 if (tmp_ctx == NULL) {
2472 return -1;
2473 }
2474
2475 pjob = print_job_find(tmp_ctx, sharename, jobid);
2476 if (!pjob) {
2477 return_code = -1;
2478 goto err_out;
2479 }
2480
2481 /* don't allow another process to get this info - it is meaningless */
2482 if (pjob->pid != getpid()) {
2483 return_code = -1;
2484 goto err_out;
2485 }
2486
2487 /* if SMBD is spooling this can't be allowed */
2488 if (pjob->status == PJOB_SMBD_SPOOLING) {
2489 return_code = -1;
2490 goto err_out;
2491 }
2492
2493 return_code = write_data(pjob->fd, buf, size);
2494 if (return_code > 0) {
2495 pjob->size += size;
2496 pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2497 }
2498err_out:
2499 talloc_free(tmp_ctx);
2500 return return_code;
2501}
2502
2503/****************************************************************************
2504 Get the queue status - do not update if db is out of date.
2505****************************************************************************/
2506
2507static int get_queue_status(const char* sharename, print_status_struct *status)
2508{
2509 fstring keystr;
2510 TDB_DATA data;
2511 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2512 int len;
2513
2514 if (status) {
2515 ZERO_STRUCTP(status);
2516 }
2517
2518 if (!pdb)
2519 return 0;
2520
2521 if (status) {
2522 fstr_sprintf(keystr, "STATUS/%s", sharename);
2523 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2524 if (data.dptr) {
2525 if (data.dsize == sizeof(print_status_struct))
2526 /* this memcpy is ok since the status struct was
2527 not packed before storing it in the tdb */
2528 memcpy(status, data.dptr, sizeof(print_status_struct));
2529 SAFE_FREE(data.dptr);
2530 }
2531 }
2532 len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2533 release_print_db(pdb);
2534 return (len == -1 ? 0 : len);
2535}
2536
2537/****************************************************************************
2538 Determine the number of jobs in a queue.
2539****************************************************************************/
2540
2541int print_queue_length(struct messaging_context *msg_ctx, int snum,
2542 print_status_struct *pstatus)
2543{
2544 const char* sharename = lp_const_servicename( snum );
2545 print_status_struct status;
2546 int len;
2547
2548 ZERO_STRUCT( status );
2549
2550 /* make sure the database is up to date */
2551 if (print_cache_expired(lp_const_servicename(snum), True))
2552 print_queue_update(msg_ctx, snum, False);
2553
2554 /* also fetch the queue status */
2555 memset(&status, 0, sizeof(status));
2556 len = get_queue_status(sharename, &status);
2557
2558 if (pstatus)
2559 *pstatus = status;
2560
2561 return len;
2562}
2563
2564/***************************************************************************
2565 Allocate a jobid. Hold the lock for as short a time as possible.
2566***************************************************************************/
2567
2568static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum,
2569 const char *sharename, uint32_t *pjobid)
2570{
2571 int i;
2572 uint32_t jobid;
2573 enum TDB_ERROR terr;
2574 int ret;
2575
2576 *pjobid = (uint32_t)-1;
2577
2578 for (i = 0; i < 3; i++) {
2579 /* Lock the database - only wait 20 seconds. */
2580 ret = tdb_lock_bystring_with_timeout(pdb->tdb,
2581 "INFO/nextjob", 20);
2582 if (ret != 0) {
2583 DEBUG(0, ("allocate_print_jobid: "
2584 "Failed to lock printing database %s\n",
2585 sharename));
2586 terr = tdb_error(pdb->tdb);
2587 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2588 }
2589
2590 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2591 terr = tdb_error(pdb->tdb);
2592 if (terr != TDB_ERR_NOEXIST) {
2593 DEBUG(0, ("allocate_print_jobid: "
2594 "Failed to fetch INFO/nextjob "
2595 "for print queue %s\n", sharename));
2596 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2597 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2598 }
2599 DEBUG(10, ("allocate_print_jobid: "
2600 "No existing jobid in %s\n", sharename));
2601 jobid = 0;
2602 }
2603
2604 DEBUG(10, ("allocate_print_jobid: "
2605 "Read jobid %u from %s\n", jobid, sharename));
2606
2607 jobid = NEXT_JOBID(jobid);
2608
2609 ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid);
2610 if (ret != 0) {
2611 terr = tdb_error(pdb->tdb);
2612 DEBUG(3, ("allocate_print_jobid: "
2613 "Failed to store INFO/nextjob.\n"));
2614 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2615 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2616 }
2617
2618 /* We've finished with the INFO/nextjob lock. */
2619 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2620
2621 if (!print_job_exists(sharename, jobid)) {
2622 break;
2623 }
2624 DEBUG(10, ("allocate_print_jobid: "
2625 "Found jobid %u in %s\n", jobid, sharename));
2626 }
2627
2628 if (i > 2) {
2629 DEBUG(0, ("allocate_print_jobid: "
2630 "Failed to allocate a print job for queue %s\n",
2631 sharename));
2632 /* Probably full... */
2633 return WERR_NO_SPOOL_SPACE;
2634 }
2635
2636 /* Store a dummy placeholder. */
2637 {
2638 uint32_t tmp;
2639 TDB_DATA dum;
2640 dum.dptr = NULL;
2641 dum.dsize = 0;
2642 if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
2643 TDB_INSERT) != 0) {
2644 DEBUG(3, ("allocate_print_jobid: "
2645 "jobid (%d) failed to store placeholder.\n",
2646 jobid ));
2647 terr = tdb_error(pdb->tdb);
2648 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2649 }
2650 }
2651
2652 *pjobid = jobid;
2653 return WERR_OK;
2654}
2655
2656/***************************************************************************
2657 Append a jobid to the 'jobs added' list.
2658***************************************************************************/
2659
2660static bool add_to_jobs_added(struct tdb_print_db *pdb, uint32_t jobid)
2661{
2662 TDB_DATA data;
2663 uint32_t store_jobid;
2664
2665 SIVAL(&store_jobid, 0, jobid);
2666 data.dptr = (uint8_t *)&store_jobid;
2667 data.dsize = 4;
2668
2669 DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid ));
2670
2671 return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_added"),
2672 data) == 0);
2673}
2674
2675
2676/***************************************************************************
2677 Do all checks needed to determine if we can start a job.
2678***************************************************************************/
2679
2680static WERROR print_job_checks(const struct auth_session_info *server_info,
2681 struct messaging_context *msg_ctx,
2682 int snum, int *njobs)
2683{
2684 const char *sharename = lp_const_servicename(snum);
2685 uint64_t dspace, dsize;
2686 uint64_t minspace;
2687 int ret;
2688
2689 if (!W_ERROR_IS_OK(print_access_check(server_info, msg_ctx, snum,
2690 PRINTER_ACCESS_USE))) {
2691 DEBUG(3, ("print_job_checks: "
2692 "job start denied by security descriptor\n"));
2693 return WERR_ACCESS_DENIED;
2694 }
2695
2696 if (!print_time_access_check(server_info, msg_ctx, sharename)) {
2697 DEBUG(3, ("print_job_checks: "
2698 "job start denied by time check\n"));
2699 return WERR_ACCESS_DENIED;
2700 }
2701
2702 /* see if we have sufficient disk space */
2703 if (lp_min_print_space(snum)) {
2704 minspace = lp_min_print_space(snum);
2705 ret = sys_fsusage(lp_path(talloc_tos(), snum), &dspace, &dsize);
2706 if (ret == 0 && dspace < 2*minspace) {
2707 DEBUG(3, ("print_job_checks: "
2708 "disk space check failed.\n"));
2709 return WERR_NO_SPOOL_SPACE;
2710 }
2711 }
2712
2713 /* for autoloaded printers, check that the printcap entry still exists */
2714 if (lp_autoloaded(snum) && !pcap_printername_ok(sharename)) {
2715 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2716 sharename));
2717 return WERR_ACCESS_DENIED;
2718 }
2719
2720 /* Insure the maximum queue size is not violated */
2721 *njobs = print_queue_length(msg_ctx, snum, NULL);
2722 if (*njobs > lp_maxprintjobs(snum)) {
2723 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2724 "larger than max printjobs per queue (%d).\n",
2725 sharename, *njobs, lp_maxprintjobs(snum)));
2726 return WERR_NO_SPOOL_SPACE;
2727 }
2728
2729 return WERR_OK;
2730}
2731
2732/***************************************************************************
2733 Create a job file.
2734***************************************************************************/
2735
2736static WERROR print_job_spool_file(int snum, uint32_t jobid,
2737 const char *output_file,
2738 struct printjob *pjob)
2739{
2740 WERROR werr;
2741 SMB_STRUCT_STAT st;
2742 const char *path;
2743 int len;
2744 mode_t mask;
2745
2746 /* if this file is within the printer path, it means that smbd
2747 * is spooling it and will pass us control when it is finished.
2748 * Verify that the file name is ok, within path, and it is
2749 * already already there */
2750 if (output_file) {
2751 path = lp_path(talloc_tos(), snum);
2752 len = strlen(path);
2753 if (strncmp(output_file, path, len) == 0 &&
2754 (output_file[len - 1] == '/' || output_file[len] == '/')) {
2755
2756 /* verify path is not too long */
2757 if (strlen(output_file) >= sizeof(pjob->filename)) {
2758 return WERR_INVALID_NAME;
2759 }
2760
2761 /* verify that the file exists */
2762 if (sys_stat(output_file, &st, false) != 0) {
2763 return WERR_INVALID_NAME;
2764 }
2765
2766 fstrcpy(pjob->filename, output_file);
2767
2768 DEBUG(3, ("print_job_spool_file:"
2769 "External spooling activated\n"));
2770
2771 /* we do not open the file until spooling is done */
2772 pjob->fd = -1;
2773 pjob->status = PJOB_SMBD_SPOOLING;
2774
2775 return WERR_OK;
2776 }
2777 }
2778
2779 slprintf(pjob->filename, sizeof(pjob->filename)-1,
2780 "%s/%sXXXXXX", lp_path(talloc_tos(), snum),
2781 PRINT_SPOOL_PREFIX);
2782 mask = umask(S_IRWXO | S_IRWXG);
2783 pjob->fd = mkstemp(pjob->filename);
2784 umask(mask);
2785
2786 if (pjob->fd == -1) {
2787 werr = map_werror_from_unix(errno);
2788 if (W_ERROR_EQUAL(werr, WERR_ACCESS_DENIED)) {
2789 /* Common setup error, force a report. */
2790 DEBUG(0, ("print_job_spool_file: "
2791 "insufficient permissions to open spool "
2792 "file %s.\n", pjob->filename));
2793 } else {
2794 /* Normal case, report at level 3 and above. */
2795 DEBUG(3, ("print_job_spool_file: "
2796 "can't open spool file %s\n",
2797 pjob->filename));
2798 }
2799 return werr;
2800 }
2801
2802 return WERR_OK;
2803}
2804
2805/***************************************************************************
2806 Start spooling a job - return the jobid.
2807***************************************************************************/
2808
2809WERROR print_job_start(const struct auth_session_info *server_info,
2810 struct messaging_context *msg_ctx,
2811 const char *clientmachine,
2812 int snum, const char *docname, const char *filename,
2813 struct spoolss_DeviceMode *devmode, uint32_t *_jobid)
2814{
2815 uint32_t jobid;
2816 char *path;
2817 struct printjob pjob;
2818 const char *sharename = lp_const_servicename(snum);
2819 struct tdb_print_db *pdb = get_print_db_byname(sharename);
2820 int njobs;
2821 WERROR werr;
2822
2823 if (!pdb) {
2824 return WERR_INTERNAL_DB_CORRUPTION;
2825 }
2826
2827 path = lp_path(talloc_tos(), snum);
2828
2829 werr = print_job_checks(server_info, msg_ctx, snum, &njobs);
2830 if (!W_ERROR_IS_OK(werr)) {
2831 release_print_db(pdb);
2832 return werr;
2833 }
2834
2835 DEBUG(10, ("print_job_start: "
2836 "Queue %s number of jobs (%d), max printjobs = %d\n",
2837 sharename, njobs, lp_maxprintjobs(snum)));
2838
2839 werr = allocate_print_jobid(pdb, snum, sharename, &jobid);
2840 if (!W_ERROR_IS_OK(werr)) {
2841 goto fail;
2842 }
2843
2844 /* create the database entry */
2845
2846 ZERO_STRUCT(pjob);
2847
2848 pjob.pid = getpid();
2849 pjob.jobid = jobid;
2850 pjob.sysjob = -1;
2851 pjob.fd = -1;
2852 pjob.starttime = time(NULL);
2853 pjob.status = LPQ_SPOOLING;
2854 pjob.size = 0;
2855 pjob.spooled = False;
2856 pjob.smbjob = True;
2857 pjob.devmode = devmode;
2858
2859 fstrcpy(pjob.jobname, docname);
2860
2861 fstrcpy(pjob.clientmachine, clientmachine);
2862
2863 fstrcpy(pjob.user, lp_printjob_username(snum));
2864 standard_sub_advanced(sharename, server_info->unix_info->sanitized_username,
2865 path, server_info->unix_token->gid,
2866 server_info->unix_info->sanitized_username,
2867 server_info->info->domain_name,
2868 pjob.user, sizeof(pjob.user));
2869
2870 fstrcpy(pjob.queuename, lp_const_servicename(snum));
2871
2872 /* we have a job entry - now create the spool file */
2873 werr = print_job_spool_file(snum, jobid, filename, &pjob);
2874 if (!W_ERROR_IS_OK(werr)) {
2875 goto fail;
2876 }
2877
2878 pjob_store(server_event_context(), msg_ctx, sharename, jobid, &pjob);
2879
2880 /* Update the 'jobs added' entry used by print_queue_status. */
2881 add_to_jobs_added(pdb, jobid);
2882
2883 /* Ensure we keep a rough count of the number of total jobs... */
2884 tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2885
2886 release_print_db(pdb);
2887
2888 *_jobid = jobid;
2889 return WERR_OK;
2890
2891fail:
2892 if (jobid != -1) {
2893 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
2894 }
2895
2896 release_print_db(pdb);
2897
2898 DEBUG(3, ("print_job_start: returning fail. "
2899 "Error = %s\n", win_errstr(werr)));
2900 return werr;
2901}
2902
2903/****************************************************************************
2904 Update the number of pages spooled to jobid
2905****************************************************************************/
2906
2907void print_job_endpage(struct messaging_context *msg_ctx,
2908 int snum, uint32_t jobid)
2909{
2910 const char* sharename = lp_const_servicename(snum);
2911 struct printjob *pjob;
2912 TALLOC_CTX *tmp_ctx = talloc_new(msg_ctx);
2913 if (tmp_ctx == NULL) {
2914 return;
2915 }
2916
2917 pjob = print_job_find(tmp_ctx, sharename, jobid);
2918 if (!pjob) {
2919 goto err_out;
2920 }
2921 /* don't allow another process to get this info - it is meaningless */
2922 if (pjob->pid != getpid()) {
2923 goto err_out;
2924 }
2925
2926 pjob->page_count++;
2927 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
2928err_out:
2929 talloc_free(tmp_ctx);
2930}
2931
2932/****************************************************************************
2933 Print a file - called on closing the file. This spools the job.
2934 If normal close is false then we're tearing down the jobs - treat as an
2935 error.
2936****************************************************************************/
2937
2938NTSTATUS print_job_end(struct messaging_context *msg_ctx, int snum,
2939 uint32_t jobid, enum file_close_type close_type)
2940{
2941 const char* sharename = lp_const_servicename(snum);
2942 struct printjob *pjob;
2943 int ret;
2944 SMB_STRUCT_STAT sbuf;
2945 struct printif *current_printif = get_printer_fns(snum);
2946 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2947 char *lpq_cmd;
2948 TALLOC_CTX *tmp_ctx = talloc_new(msg_ctx);
2949 if (tmp_ctx == NULL) {
2950 return NT_STATUS_NO_MEMORY;
2951 }
2952
2953 pjob = print_job_find(tmp_ctx, sharename, jobid);
2954 if (!pjob) {
2955 status = NT_STATUS_PRINT_CANCELLED;
2956 goto err_out;
2957 }
2958
2959 if (pjob->spooled || pjob->pid != getpid()) {
2960 status = NT_STATUS_ACCESS_DENIED;
2961 goto err_out;
2962 }
2963
2964 if (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) {
2965 if (pjob->status == PJOB_SMBD_SPOOLING) {
2966 /* take over the file now, smbd is done */
2967 if (sys_stat(pjob->filename, &sbuf, false) != 0) {
2968 status = map_nt_error_from_unix(errno);
2969 DEBUG(3, ("print_job_end: "
2970 "stat file failed for jobid %d\n",
2971 jobid));
2972 goto fail;
2973 }
2974
2975 pjob->status = LPQ_SPOOLING;
2976
2977 } else {
2978
2979 if ((sys_fstat(pjob->fd, &sbuf, false) != 0)) {
2980 status = map_nt_error_from_unix(errno);
2981 close(pjob->fd);
2982 DEBUG(3, ("print_job_end: "
2983 "stat file failed for jobid %d\n",
2984 jobid));
2985 goto fail;
2986 }
2987
2988 close(pjob->fd);
2989 }
2990
2991 pjob->size = sbuf.st_ex_size;
2992 } else {
2993
2994 /*
2995 * Not a normal close, something has gone wrong. Cleanup.
2996 */
2997 if (pjob->fd != -1) {
2998 close(pjob->fd);
2999 }
3000 goto fail;
3001 }
3002
3003 /* Technically, this is not quite right. If the printer has a separator
3004 * page turned on, the NT spooler prints the separator page even if the
3005 * print job is 0 bytes. 010215 JRR */
3006 if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
3007 /* don't bother spooling empty files or something being deleted. */
3008 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
3009 pjob->filename, pjob->size ? "deleted" : "zero length" ));
3010 unlink(pjob->filename);
3011 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
3012 return NT_STATUS_OK;
3013 }
3014
3015 /* don't strip out characters like '$' from the printername */
3016 lpq_cmd = talloc_string_sub2(tmp_ctx,
3017 lp_lpq_command(talloc_tos(), snum),
3018 "%p",
3019 lp_printername(talloc_tos(), snum),
3020 false, false, false);
3021 if (lpq_cmd == NULL) {
3022 status = NT_STATUS_PRINT_CANCELLED;
3023 goto fail;
3024 }
3025 lpq_cmd = talloc_sub_advanced(tmp_ctx,
3026 lp_servicename(talloc_tos(), snum),
3027 current_user_info.unix_name,
3028 "",
3029 current_user.ut.gid,
3030 get_current_username(),
3031 current_user_info.domain,
3032 lpq_cmd);
3033 if (lpq_cmd == NULL) {
3034 status = NT_STATUS_PRINT_CANCELLED;
3035 goto fail;
3036 }
3037
3038 ret = (*(current_printif->job_submit))(snum, pjob,
3039 current_printif->type, lpq_cmd);
3040 if (ret) {
3041 status = NT_STATUS_PRINT_CANCELLED;
3042 goto fail;
3043 }
3044
3045 /* The print job has been successfully handed over to the back-end */
3046
3047 pjob->spooled = True;
3048 pjob->status = LPQ_QUEUED;
3049 pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
3050
3051 /* make sure the database is up to date */
3052 if (print_cache_expired(lp_const_servicename(snum), True))
3053 print_queue_update(msg_ctx, snum, False);
3054
3055 return NT_STATUS_OK;
3056
3057fail:
3058
3059 /* The print job was not successfully started. Cleanup */
3060 /* Still need to add proper error return propagation! 010122:JRR */
3061 pjob->fd = -1;
3062 unlink(pjob->filename);
3063 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
3064err_out:
3065 talloc_free(tmp_ctx);
3066 return status;
3067}
3068
3069/****************************************************************************
3070 Get a snapshot of jobs in the system without traversing.
3071****************************************************************************/
3072
3073static bool get_stored_queue_info(struct messaging_context *msg_ctx,
3074 struct tdb_print_db *pdb, int snum,
3075 int *pcount, print_queue_struct **ppqueue)
3076{
3077 TDB_DATA data, cgdata, jcdata;
3078 print_queue_struct *queue = NULL;
3079 uint32_t qcount = 0;
3080 uint32_t extra_count = 0;
3081 uint32_t changed_count = 0;
3082 int total_count = 0;
3083 size_t len = 0;
3084 uint32_t i;
3085 int max_reported_jobs = lp_max_reported_print_jobs(snum);
3086 bool ret = false;
3087 const char* sharename = lp_servicename(talloc_tos(), snum);
3088 TALLOC_CTX *tmp_ctx = talloc_new(msg_ctx);
3089 if (tmp_ctx == NULL) {
3090 return false;
3091 }
3092
3093 /* make sure the database is up to date */
3094 if (print_cache_expired(lp_const_servicename(snum), True))
3095 print_queue_update(msg_ctx, snum, False);
3096
3097 *pcount = 0;
3098 *ppqueue = NULL;
3099
3100 ZERO_STRUCT(data);
3101 ZERO_STRUCT(cgdata);
3102
3103 /* Get the stored queue data. */
3104 data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
3105
3106 if (data.dptr && data.dsize >= sizeof(qcount))
3107 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
3108
3109 /* Get the added jobs list. */
3110 cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added"));
3111 if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
3112 extra_count = cgdata.dsize/4;
3113
3114 /* Get the changed jobs list. */
3115 jcdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
3116 if (jcdata.dptr != NULL && (jcdata.dsize % 4 == 0))
3117 changed_count = jcdata.dsize / 4;
3118
3119 DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
3120
3121 /* Allocate the queue size. */
3122 if (qcount == 0 && extra_count == 0)
3123 goto out;
3124
3125 if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
3126 goto out;
3127
3128 /* Retrieve the linearised queue data. */
3129
3130 for(i = 0; i < qcount; i++) {
3131 uint32_t qjob, qsize, qpage_count, qstatus, qpriority, qtime;
3132 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
3133 &qjob,
3134 &qsize,
3135 &qpage_count,
3136 &qstatus,
3137 &qpriority,
3138 &qtime,
3139 queue[i].fs_user,
3140 queue[i].fs_file);
3141 queue[i].sysjob = qjob;
3142 queue[i].size = qsize;
3143 queue[i].page_count = qpage_count;
3144 queue[i].status = qstatus;
3145 queue[i].priority = qpriority;
3146 queue[i].time = qtime;
3147 }
3148
3149 total_count = qcount;
3150
3151 /* Add new jobids to the queue. */
3152 for (i = 0; i < extra_count; i++) {
3153 uint32_t jobid;
3154 struct printjob *pjob;
3155
3156 jobid = IVAL(cgdata.dptr, i*4);
3157 DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid));
3158 pjob = print_job_find(tmp_ctx, lp_const_servicename(snum), jobid);
3159 if (!pjob) {
3160 DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid));
3161 remove_from_jobs_added(sharename, jobid);
3162 continue;
3163 }
3164
3165 queue[total_count].sysjob = pjob->sysjob;
3166 queue[total_count].size = pjob->size;
3167 queue[total_count].page_count = pjob->page_count;
3168 queue[total_count].status = pjob->status;
3169 queue[total_count].priority = 1;
3170 queue[total_count].time = pjob->starttime;
3171 fstrcpy(queue[total_count].fs_user, pjob->user);
3172 fstrcpy(queue[total_count].fs_file, pjob->jobname);
3173 total_count++;
3174 talloc_free(pjob);
3175 }
3176
3177 /* Update the changed jobids. */
3178 for (i = 0; i < changed_count; i++) {
3179 uint32_t jobid = IVAL(jcdata.dptr, i * 4);
3180 struct printjob *pjob;
3181 uint32_t j;
3182 bool found = false;
3183
3184 pjob = print_job_find(tmp_ctx, sharename, jobid);
3185 if (pjob == NULL) {
3186 DEBUG(5,("get_stored_queue_info: failed to find "
3187 "changed job = %u\n",
3188 (unsigned int)jobid));
3189 remove_from_jobs_changed(sharename, jobid);
3190 continue;
3191 }
3192
3193 for (j = 0; j < total_count; j++) {
3194 if (queue[j].sysjob == pjob->sysjob) {
3195 found = true;
3196 break;
3197 }
3198 }
3199
3200 if (found) {
3201 DEBUG(5,("get_stored_queue_info: changed job: %u\n",
3202 (unsigned int)jobid));
3203
3204 queue[j].sysjob = pjob->sysjob;
3205 queue[j].size = pjob->size;
3206 queue[j].page_count = pjob->page_count;
3207 queue[j].status = pjob->status;
3208 queue[j].priority = 1;
3209 queue[j].time = pjob->starttime;
3210 fstrcpy(queue[j].fs_user, pjob->user);
3211 fstrcpy(queue[j].fs_file, pjob->jobname);
3212 talloc_free(pjob);
3213
3214 DEBUG(5,("updated queue[%u], jobid: %u, sysjob: %u, "
3215 "jobname: %s\n",
3216 (unsigned int)j, (unsigned int)jobid,
3217 (unsigned int)queue[j].sysjob, pjob->jobname));
3218 }
3219
3220 remove_from_jobs_changed(sharename, jobid);
3221 }
3222
3223 /* Sort the queue by submission time otherwise they are displayed
3224 in hash order. */
3225
3226 TYPESAFE_QSORT(queue, total_count, printjob_comp);
3227
3228 DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
3229
3230 if (max_reported_jobs && total_count > max_reported_jobs)
3231 total_count = max_reported_jobs;
3232
3233 *ppqueue = queue;
3234 *pcount = total_count;
3235
3236 ret = true;
3237
3238 out:
3239
3240 SAFE_FREE(data.dptr);
3241 SAFE_FREE(cgdata.dptr);
3242 talloc_free(tmp_ctx);
3243 return ret;
3244}
3245
3246/****************************************************************************
3247 Get a printer queue listing.
3248 set queue = NULL and status = NULL if you just want to update the cache
3249****************************************************************************/
3250
3251int print_queue_status(struct messaging_context *msg_ctx, int snum,
3252 print_queue_struct **ppqueue,
3253 print_status_struct *status)
3254{
3255 fstring keystr;
3256 TDB_DATA data, key;
3257 const char *sharename;
3258 struct tdb_print_db *pdb;
3259 int count = 0;
3260
3261 /* make sure the database is up to date */
3262
3263 if (print_cache_expired(lp_const_servicename(snum), True))
3264 print_queue_update(msg_ctx, snum, False);
3265
3266 /* return if we are done */
3267 if ( !ppqueue || !status )
3268 return 0;
3269
3270 *ppqueue = NULL;
3271 sharename = lp_const_servicename(snum);
3272 pdb = get_print_db_byname(sharename);
3273
3274 if (!pdb)
3275 return 0;
3276
3277 /*
3278 * Fetch the queue status. We must do this first, as there may
3279 * be no jobs in the queue.
3280 */
3281
3282 ZERO_STRUCTP(status);
3283 slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
3284 key = string_tdb_data(keystr);
3285
3286 data = tdb_fetch(pdb->tdb, key);
3287 if (data.dptr) {
3288 if (data.dsize == sizeof(*status)) {
3289 /* this memcpy is ok since the status struct was
3290 not packed before storing it in the tdb */
3291 memcpy(status, data.dptr, sizeof(*status));
3292 }
3293 SAFE_FREE(data.dptr);
3294 }
3295
3296 /*
3297 * Now, fetch the print queue information. We first count the number
3298 * of entries, and then only retrieve the queue if necessary.
3299 */
3300
3301 if (!get_stored_queue_info(msg_ctx, pdb, snum, &count, ppqueue)) {
3302 release_print_db(pdb);
3303 return 0;
3304 }
3305
3306 release_print_db(pdb);
3307 return count;
3308}
3309
3310/****************************************************************************
3311 Pause a queue.
3312****************************************************************************/
3313
3314WERROR print_queue_pause(const struct auth_session_info *server_info,
3315 struct messaging_context *msg_ctx, int snum)
3316{
3317 int ret;
3318 struct printif *current_printif = get_printer_fns( snum );
3319
3320 if (!W_ERROR_IS_OK(print_access_check(server_info, msg_ctx, snum,
3321 PRINTER_ACCESS_ADMINISTER))) {
3322 return WERR_ACCESS_DENIED;
3323 }
3324
3325
3326 become_root();
3327
3328 ret = (*(current_printif->queue_pause))(snum);
3329
3330 unbecome_root();
3331
3332 if (ret != 0) {
3333 return WERR_INVALID_PARAM;
3334 }
3335
3336 /* force update the database */
3337 print_cache_flush(lp_const_servicename(snum));
3338
3339 /* Send a printer notify message */
3340
3341 notify_printer_status(server_event_context(), msg_ctx, snum,
3342 PRINTER_STATUS_PAUSED);
3343
3344 return WERR_OK;
3345}
3346
3347/****************************************************************************
3348 Resume a queue.
3349****************************************************************************/
3350
3351WERROR print_queue_resume(const struct auth_session_info *server_info,
3352 struct messaging_context *msg_ctx, int snum)
3353{
3354 int ret;
3355 struct printif *current_printif = get_printer_fns( snum );
3356
3357 if (!W_ERROR_IS_OK(print_access_check(server_info, msg_ctx, snum,
3358 PRINTER_ACCESS_ADMINISTER))) {
3359 return WERR_ACCESS_DENIED;
3360 }
3361
3362 become_root();
3363
3364 ret = (*(current_printif->queue_resume))(snum);
3365
3366 unbecome_root();
3367
3368 if (ret != 0) {
3369 return WERR_INVALID_PARAM;
3370 }
3371
3372 /* make sure the database is up to date */
3373 if (print_cache_expired(lp_const_servicename(snum), True))
3374 print_queue_update(msg_ctx, snum, True);
3375
3376 /* Send a printer notify message */
3377
3378 notify_printer_status(server_event_context(), msg_ctx, snum,
3379 PRINTER_STATUS_OK);
3380
3381 return WERR_OK;
3382}
3383
3384/****************************************************************************
3385 Purge a queue - implemented by deleting all jobs that we can delete.
3386****************************************************************************/
3387
3388WERROR print_queue_purge(const struct auth_session_info *server_info,
3389 struct messaging_context *msg_ctx, int snum)
3390{
3391 print_queue_struct *queue;
3392 print_status_struct status;
3393 int njobs, i;
3394 bool can_job_admin;
3395
3396 /* Force and update so the count is accurate (i.e. not a cached count) */
3397 print_queue_update(msg_ctx, snum, True);
3398
3399 can_job_admin = W_ERROR_IS_OK(print_access_check(server_info,
3400 msg_ctx,
3401 snum,
3402 JOB_ACCESS_ADMINISTER));
3403 njobs = print_queue_status(msg_ctx, snum, &queue, &status);
3404
3405 if ( can_job_admin )
3406 become_root();
3407
3408 for (i = 0; i < njobs; i++) {
3409 struct tdb_print_db *pdb;
3410 int jobid;
3411 bool owner;
3412 pdb = get_print_db_byname(lp_const_servicename(snum));
3413 if (pdb == NULL) {
3414 DEBUG(1, ("failed to find printdb for %s\n",
3415 lp_const_servicename(snum)));
3416 continue;
3417 }
3418 jobid = sysjob_to_jobid_pdb(pdb, queue[i].sysjob);
3419 if (jobid == (uint32_t)-1) {
3420 DEBUG(2, ("jobid for system job %d not found\n",
3421 queue[i].sysjob));
3422 continue; /* unix job */
3423 }
3424 owner = is_owner(server_info, lp_const_servicename(snum),
3425 jobid);
3426
3427 if (owner || can_job_admin) {
3428 print_job_delete1(server_event_context(), msg_ctx,
3429 snum, jobid);
3430 }
3431 }
3432
3433 if ( can_job_admin )
3434 unbecome_root();
3435
3436 /* update the cache */
3437 print_queue_update(msg_ctx, snum, True);
3438
3439 SAFE_FREE(queue);
3440
3441 return WERR_OK;
3442}
Note: See TracBrowser for help on using the repository browser.