source: trunk/server/source3/printing/printing.c@ 854

Last change on this file since 854 was 751, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.9

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