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