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