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

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

Samba Server: updated trunk to 3.6.0

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