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