b3f0673e1009a71c3b26821f2ea4265b261bfe98
[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( const char *sharename,
1217                                          struct printif *current_printif,
1218                                          char *lpq_command, char *lprm_command )
1219 {
1220         int i, qcount;
1221         print_queue_struct *queue = NULL;
1222         print_status_struct status;
1223         print_status_struct old_status;
1224         struct printjob *pjob;
1225         struct traverse_struct tstruct;
1226         TDB_DATA data, key;
1227         TDB_DATA jcdata;
1228         fstring keystr, cachestr;
1229         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1230
1231         if (!pdb) {
1232                 return;
1233         }
1234
1235         DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1236                 sharename, current_printif->type, lpq_command));
1237
1238         /*
1239          * Update the cache time FIRST ! Stops others even
1240          * attempting to get the lock and doing this
1241          * if the lpq takes a long time.
1242          */
1243
1244         slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1245         tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1246
1247         /* get the current queue using the appropriate interface */
1248         ZERO_STRUCT(status);
1249
1250         qcount = (*(current_printif->queue_get))(sharename,
1251                 current_printif->type,
1252                 lpq_command, &queue, &status);
1253
1254         DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1255                 qcount, (qcount != 1) ? "s" : "", sharename));
1256
1257         /* Sort the queue by submission time otherwise they are displayed
1258            in hash order. */
1259
1260         TYPESAFE_QSORT(queue, qcount, printjob_comp);
1261
1262         /*
1263           any job in the internal database that is marked as spooled
1264           and doesn't exist in the system queue is considered finished
1265           and removed from the database
1266
1267           any job in the system database but not in the internal database
1268           is added as a unix job
1269
1270           fill in any system job numbers as we go
1271         */
1272
1273         jcdata = get_jobs_changed_data(pdb);
1274
1275         for (i=0; i<qcount; i++) {
1276                 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1277
1278                 if (jobid == (uint32)-1) {
1279                         /* assume its a unix print job */
1280                         print_unix_job(server_event_context(),
1281                                        server_messaging_context(),
1282                                        sharename, &queue[i], jobid);
1283                         continue;
1284                 }
1285
1286                 /* we have an active SMB print job - update its status */
1287                 pjob = print_job_find(sharename, jobid);
1288                 if (!pjob) {
1289                         /* err, somethings wrong. Probably smbd was restarted
1290                            with jobs in the queue. All we can do is treat them
1291                            like unix jobs. Pity. */
1292                         print_unix_job(server_event_context(),
1293                                        server_messaging_context(),
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(server_event_context(), server_messaging_context(),
1306                            sharename, jobid, pjob);
1307
1308                 check_job_changed(sharename, jcdata, jobid);
1309         }
1310
1311         SAFE_FREE(jcdata.dptr);
1312
1313         /* now delete any queued entries that don't appear in the
1314            system queue */
1315         tstruct.queue = queue;
1316         tstruct.qcount = qcount;
1317         tstruct.snum = -1;
1318         tstruct.total_jobs = 0;
1319         tstruct.lpq_time = time(NULL);
1320         tstruct.sharename = sharename;
1321         tstruct.lprm_command = lprm_command;
1322         tstruct.print_if = current_printif;
1323         tstruct.ev = server_event_context();
1324         tstruct.msg_ctx = server_messaging_context();
1325
1326         tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1327
1328         /* Store the linearised queue, max jobs only. */
1329         store_queue_struct(pdb, &tstruct);
1330
1331         SAFE_FREE(tstruct.queue);
1332
1333         DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1334                                 sharename, tstruct.total_jobs ));
1335
1336         tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1337
1338         get_queue_status(sharename, &old_status);
1339         if (old_status.qcount != qcount)
1340                 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1341                                         old_status.qcount, qcount, sharename));
1342
1343         /* store the new queue status structure */
1344         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1345         key = string_tdb_data(keystr);
1346
1347         status.qcount = qcount;
1348         data.dptr = (uint8 *)&status;
1349         data.dsize = sizeof(status);
1350         tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1351
1352         /*
1353          * Update the cache time again. We want to do this call
1354          * as little as possible...
1355          */
1356
1357         slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1358         tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1359
1360         /* clear the msg pending record for this queue */
1361
1362         snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1363
1364         if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1365                 /* log a message but continue on */
1366
1367                 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1368                         sharename));
1369         }
1370
1371         release_print_db( pdb );
1372
1373         return;
1374 }
1375
1376 /****************************************************************************
1377  Update the internal database from the system print queue for a queue.
1378  obtain a lock on the print queue before proceeding (needed when mutiple
1379  smbd processes maytry to update the lpq cache concurrently).
1380 ****************************************************************************/
1381
1382 static void print_queue_update_with_lock( const char *sharename,
1383                                           struct printif *current_printif,
1384                                           char *lpq_command, char *lprm_command )
1385 {
1386         fstring keystr;
1387         struct tdb_print_db *pdb;
1388
1389         DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1390         pdb = get_print_db_byname(sharename);
1391         if (!pdb)
1392                 return;
1393
1394         if ( !print_cache_expired(sharename, False) ) {
1395                 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1396                 release_print_db(pdb);
1397                 return;
1398         }
1399
1400         /*
1401          * Check to see if someone else is doing this update.
1402          * This is essentially a mutex on the update.
1403          */
1404
1405         if (get_updating_pid(sharename) != -1) {
1406                 release_print_db(pdb);
1407                 return;
1408         }
1409
1410         /* Lock the queue for the database update */
1411
1412         slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1413         /* Only wait 10 seconds for this. */
1414         if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
1415                 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1416                 release_print_db(pdb);
1417                 return;
1418         }
1419
1420         /*
1421          * Ensure that no one else got in here.
1422          * If the updating pid is still -1 then we are
1423          * the winner.
1424          */
1425
1426         if (get_updating_pid(sharename) != -1) {
1427                 /*
1428                  * Someone else is doing the update, exit.
1429                  */
1430                 tdb_unlock_bystring(pdb->tdb, keystr);
1431                 release_print_db(pdb);
1432                 return;
1433         }
1434
1435         /*
1436          * We're going to do the update ourselves.
1437          */
1438
1439         /* Tell others we're doing the update. */
1440         set_updating_pid(sharename, True);
1441
1442         /*
1443          * Allow others to enter and notice we're doing
1444          * the update.
1445          */
1446
1447         tdb_unlock_bystring(pdb->tdb, keystr);
1448
1449         /* do the main work now */
1450
1451         print_queue_update_internal( sharename, current_printif,
1452                 lpq_command, lprm_command );
1453
1454         /* Delete our pid from the db. */
1455         set_updating_pid(sharename, False);
1456         release_print_db(pdb);
1457 }
1458
1459 /****************************************************************************
1460 this is the receive function of the background lpq updater
1461 ****************************************************************************/
1462 static void print_queue_receive(struct messaging_context *msg,
1463                                 void *private_data,
1464                                 uint32_t msg_type,
1465                                 struct server_id server_id,
1466                                 DATA_BLOB *data)
1467 {
1468         fstring sharename;
1469         char *lpqcommand = NULL, *lprmcommand = NULL;
1470         int printing_type;
1471         size_t len;
1472
1473         len = tdb_unpack( (uint8 *)data->data, data->length, "fdPP",
1474                 sharename,
1475                 &printing_type,
1476                 &lpqcommand,
1477                 &lprmcommand );
1478
1479         if ( len == -1 ) {
1480                 SAFE_FREE(lpqcommand);
1481                 SAFE_FREE(lprmcommand);
1482                 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1483                 return;
1484         }
1485
1486         print_queue_update_with_lock(sharename,
1487                 get_printer_fns_from_type((enum printing_types)printing_type),
1488                 lpqcommand, lprmcommand );
1489
1490         SAFE_FREE(lpqcommand);
1491         SAFE_FREE(lprmcommand);
1492         return;
1493 }
1494
1495 static void printing_pause_fd_handler(struct tevent_context *ev,
1496                                       struct tevent_fd *fde,
1497                                       uint16_t flags,
1498                                       void *private_data)
1499 {
1500         /*
1501          * If pause_pipe[1] is closed it means the parent smbd
1502          * and children exited or aborted.
1503          */
1504         exit_server_cleanly(NULL);
1505 }
1506
1507 extern struct child_pid *children;
1508 extern int num_children;
1509
1510 static void add_child_pid(pid_t pid)
1511 {
1512         struct child_pid *child;
1513
1514         child = SMB_MALLOC_P(struct child_pid);
1515         if (child == NULL) {
1516                 DEBUG(0, ("Could not add child struct -- malloc failed\n"));
1517                 return;
1518         }
1519         child->pid = pid;
1520         DLIST_ADD(children, child);
1521         num_children += 1;
1522 }
1523
1524 static pid_t background_lpq_updater_pid = -1;
1525
1526 /****************************************************************************
1527 main thread of the background lpq updater
1528 ****************************************************************************/
1529 void start_background_queue(struct tevent_context *ev,
1530                             struct messaging_context *msg_ctx)
1531 {
1532         /* Use local variables for this as we don't
1533          * need to save the parent side of this, just
1534          * ensure it closes when the process exits.
1535          */
1536         int pause_pipe[2];
1537
1538         DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1539
1540         if (pipe(pause_pipe) == -1) {
1541                 DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno) ));
1542                 exit(1);
1543         }
1544
1545         background_lpq_updater_pid = sys_fork();
1546
1547         if (background_lpq_updater_pid == -1) {
1548                 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1549                 exit(1);
1550         }
1551
1552         /* Track the printing pid along with other smbd children */
1553         add_child_pid(background_lpq_updater_pid);
1554
1555         if(background_lpq_updater_pid == 0) {
1556                 struct tevent_fd *fde;
1557                 int ret;
1558                 NTSTATUS status;
1559
1560                 /* Child. */
1561                 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1562
1563                 close(pause_pipe[0]);
1564                 pause_pipe[0] = -1;
1565
1566                 status = reinit_after_fork(msg_ctx, ev, procid_self(), true);
1567
1568                 if (!NT_STATUS_IS_OK(status)) {
1569                         DEBUG(0,("reinit_after_fork() failed\n"));
1570                         smb_panic("reinit_after_fork() failed");
1571                 }
1572
1573                 smbd_setup_sig_term_handler();
1574                 smbd_setup_sig_hup_handler(ev, msg_ctx);
1575
1576                 if (!serverid_register(procid_self(),
1577                                        FLAG_MSG_GENERAL|FLAG_MSG_SMBD
1578                                        |FLAG_MSG_PRINT_GENERAL)) {
1579                         exit(1);
1580                 }
1581
1582                 if (!locking_init()) {
1583                         exit(1);
1584                 }
1585
1586                 messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE,
1587                                    print_queue_receive);
1588
1589                 fde = tevent_add_fd(ev, ev, pause_pipe[1], TEVENT_FD_READ,
1590                                     printing_pause_fd_handler,
1591                                     NULL);
1592                 if (!fde) {
1593                         DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
1594                         smb_panic("tevent_add_fd() failed for pause_pipe");
1595                 }
1596
1597                 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1598                 ret = tevent_loop_wait(ev);
1599                 /* should not be reached */
1600                 DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
1601                          ret, (ret == 0) ? "out of events" : strerror(errno)));
1602                 exit(1);
1603         }
1604
1605         close(pause_pipe[1]);
1606 }
1607
1608 /****************************************************************************
1609 update the internal database from the system print queue for a queue
1610 ****************************************************************************/
1611
1612 static void print_queue_update(struct messaging_context *msg_ctx,
1613                                int snum, bool force)
1614 {
1615         fstring key;
1616         fstring sharename;
1617         char *lpqcommand = NULL;
1618         char *lprmcommand = NULL;
1619         uint8 *buffer = NULL;
1620         size_t len = 0;
1621         size_t newlen;
1622         struct tdb_print_db *pdb;
1623         int type;
1624         struct printif *current_printif;
1625         TALLOC_CTX *ctx = talloc_tos();
1626
1627         fstrcpy( sharename, lp_const_servicename(snum));
1628
1629         /* don't strip out characters like '$' from the printername */
1630
1631         lpqcommand = talloc_string_sub2(ctx,
1632                         lp_lpqcommand(snum),
1633                         "%p",
1634                         lp_printername(snum),
1635                         false, false, false);
1636         if (!lpqcommand) {
1637                 return;
1638         }
1639         lpqcommand = talloc_sub_advanced(ctx,
1640                         lp_servicename(snum),
1641                         current_user_info.unix_name,
1642                         "",
1643                         current_user.ut.gid,
1644                         get_current_username(),
1645                         current_user_info.domain,
1646                         lpqcommand);
1647         if (!lpqcommand) {
1648                 return;
1649         }
1650
1651         lprmcommand = talloc_string_sub2(ctx,
1652                         lp_lprmcommand(snum),
1653                         "%p",
1654                         lp_printername(snum),
1655                         false, false, false);
1656         if (!lprmcommand) {
1657                 return;
1658         }
1659         lprmcommand = talloc_sub_advanced(ctx,
1660                         lp_servicename(snum),
1661                         current_user_info.unix_name,
1662                         "",
1663                         current_user.ut.gid,
1664                         get_current_username(),
1665                         current_user_info.domain,
1666                         lprmcommand);
1667         if (!lprmcommand) {
1668                 return;
1669         }
1670
1671         /*
1672          * Make sure that the background queue process exists.
1673          * Otherwise just do the update ourselves
1674          */
1675
1676         if ( force || background_lpq_updater_pid == -1 ) {
1677                 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1678                 current_printif = get_printer_fns( snum );
1679                 print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand );
1680
1681                 return;
1682         }
1683
1684         type = lp_printing(snum);
1685
1686         /* get the length */
1687
1688         len = tdb_pack( NULL, 0, "fdPP",
1689                 sharename,
1690                 type,
1691                 lpqcommand,
1692                 lprmcommand );
1693
1694         buffer = SMB_XMALLOC_ARRAY( uint8, len );
1695
1696         /* now pack the buffer */
1697         newlen = tdb_pack( buffer, len, "fdPP",
1698                 sharename,
1699                 type,
1700                 lpqcommand,
1701                 lprmcommand );
1702
1703         SMB_ASSERT( newlen == len );
1704
1705         DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1706                 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1707                 sharename, type, lpqcommand, lprmcommand ));
1708
1709         /* here we set a msg pending record for other smbd processes
1710            to throttle the number of duplicate print_queue_update msgs
1711            sent.  */
1712
1713         pdb = get_print_db_byname(sharename);
1714         if (!pdb) {
1715                 SAFE_FREE(buffer);
1716                 return;
1717         }
1718
1719         snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1720
1721         if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1722                 /* log a message but continue on */
1723
1724                 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1725                         sharename));
1726         }
1727
1728         release_print_db( pdb );
1729
1730         /* finally send the message */
1731
1732         messaging_send_buf(msg_ctx, pid_to_procid(background_lpq_updater_pid),
1733                            MSG_PRINTER_UPDATE, (uint8 *)buffer, len);
1734
1735         SAFE_FREE( buffer );
1736
1737         return;
1738 }
1739
1740 /****************************************************************************
1741  Create/Update an entry in the print tdb that will allow us to send notify
1742  updates only to interested smbd's.
1743 ****************************************************************************/
1744
1745 bool print_notify_register_pid(int snum)
1746 {
1747         TDB_DATA data;
1748         struct tdb_print_db *pdb = NULL;
1749         TDB_CONTEXT *tdb = NULL;
1750         const char *printername;
1751         uint32 mypid = (uint32)sys_getpid();
1752         bool ret = False;
1753         size_t i;
1754
1755         /* if (snum == -1), then the change notify request was
1756            on a print server handle and we need to register on
1757            all print queus */
1758
1759         if (snum == -1)
1760         {
1761                 int num_services = lp_numservices();
1762                 int idx;
1763
1764                 for ( idx=0; idx<num_services; idx++ ) {
1765                         if (lp_snum_ok(idx) && lp_print_ok(idx) )
1766                                 print_notify_register_pid(idx);
1767                 }
1768
1769                 return True;
1770         }
1771         else /* register for a specific printer */
1772         {
1773                 printername = lp_const_servicename(snum);
1774                 pdb = get_print_db_byname(printername);
1775                 if (!pdb)
1776                         return False;
1777                 tdb = pdb->tdb;
1778         }
1779
1780         if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1781                 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1782                                         printername));
1783                 if (pdb)
1784                         release_print_db(pdb);
1785                 return False;
1786         }
1787
1788         data = get_printer_notify_pid_list( tdb, printername, True );
1789
1790         /* Add ourselves and increase the refcount. */
1791
1792         for (i = 0; i < data.dsize; i += 8) {
1793                 if (IVAL(data.dptr,i) == mypid) {
1794                         uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1795                         SIVAL(data.dptr, i+4, new_refcount);
1796                         break;
1797                 }
1798         }
1799
1800         if (i == data.dsize) {
1801                 /* We weren't in the list. Realloc. */
1802                 data.dptr = (uint8 *)SMB_REALLOC(data.dptr, data.dsize + 8);
1803                 if (!data.dptr) {
1804                         DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1805                                                 printername));
1806                         goto done;
1807                 }
1808                 data.dsize += 8;
1809                 SIVAL(data.dptr,data.dsize - 8,mypid);
1810                 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1811         }
1812
1813         /* Store back the record. */
1814         if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1815                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1816 list for printer %s\n", printername));
1817                 goto done;
1818         }
1819
1820         ret = True;
1821
1822  done:
1823
1824         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1825         if (pdb)
1826                 release_print_db(pdb);
1827         SAFE_FREE(data.dptr);
1828         return ret;
1829 }
1830
1831 /****************************************************************************
1832  Update an entry in the print tdb that will allow us to send notify
1833  updates only to interested smbd's.
1834 ****************************************************************************/
1835
1836 bool print_notify_deregister_pid(int snum)
1837 {
1838         TDB_DATA data;
1839         struct tdb_print_db *pdb = NULL;
1840         TDB_CONTEXT *tdb = NULL;
1841         const char *printername;
1842         uint32 mypid = (uint32)sys_getpid();
1843         size_t i;
1844         bool ret = False;
1845
1846         /* if ( snum == -1 ), we are deregister a print server handle
1847            which means to deregister on all print queues */
1848
1849         if (snum == -1)
1850         {
1851                 int num_services = lp_numservices();
1852                 int idx;
1853
1854                 for ( idx=0; idx<num_services; idx++ ) {
1855                         if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1856                                 print_notify_deregister_pid(idx);
1857                 }
1858
1859                 return True;
1860         }
1861         else /* deregister a specific printer */
1862         {
1863                 printername = lp_const_servicename(snum);
1864                 pdb = get_print_db_byname(printername);
1865                 if (!pdb)
1866                         return False;
1867                 tdb = pdb->tdb;
1868         }
1869
1870         if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1871                 DEBUG(0,("print_notify_register_pid: Failed to lock \
1872 printer %s database\n", printername));
1873                 if (pdb)
1874                         release_print_db(pdb);
1875                 return False;
1876         }
1877
1878         data = get_printer_notify_pid_list( tdb, printername, True );
1879
1880         /* Reduce refcount. Remove ourselves if zero. */
1881
1882         for (i = 0; i < data.dsize; ) {
1883                 if (IVAL(data.dptr,i) == mypid) {
1884                         uint32 refcount = IVAL(data.dptr, i+4);
1885
1886                         refcount--;
1887
1888                         if (refcount == 0) {
1889                                 if (data.dsize - i > 8)
1890                                         memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1891                                 data.dsize -= 8;
1892                                 continue;
1893                         }
1894                         SIVAL(data.dptr, i+4, refcount);
1895                 }
1896
1897                 i += 8;
1898         }
1899
1900         if (data.dsize == 0)
1901                 SAFE_FREE(data.dptr);
1902
1903         /* Store back the record. */
1904         if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1905                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1906 list for printer %s\n", printername));
1907                 goto done;
1908         }
1909
1910         ret = True;
1911
1912   done:
1913
1914         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1915         if (pdb)
1916                 release_print_db(pdb);
1917         SAFE_FREE(data.dptr);
1918         return ret;
1919 }
1920
1921 /****************************************************************************
1922  Check if a jobid is valid. It is valid if it exists in the database.
1923 ****************************************************************************/
1924
1925 bool print_job_exists(const char* sharename, uint32 jobid)
1926 {
1927         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1928         bool ret;
1929         uint32_t tmp;
1930
1931         if (!pdb)
1932                 return False;
1933         ret = tdb_exists(pdb->tdb, print_key(jobid, &tmp));
1934         release_print_db(pdb);
1935         return ret;
1936 }
1937
1938 /****************************************************************************
1939  Give the filename used for a jobid.
1940  Only valid for the process doing the spooling and when the job
1941  has not been spooled.
1942 ****************************************************************************/
1943
1944 char *print_job_fname(const char* sharename, uint32 jobid)
1945 {
1946         struct printjob *pjob = print_job_find(sharename, jobid);
1947         if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
1948                 return NULL;
1949         return pjob->filename;
1950 }
1951
1952
1953 /****************************************************************************
1954  Give the filename used for a jobid.
1955  Only valid for the process doing the spooling and when the job
1956  has not been spooled.
1957 ****************************************************************************/
1958
1959 struct spoolss_DeviceMode *print_job_devmode(const char* sharename, uint32 jobid)
1960 {
1961         struct printjob *pjob = print_job_find(sharename, jobid);
1962
1963         if ( !pjob )
1964                 return NULL;
1965
1966         return pjob->devmode;
1967 }
1968
1969 /****************************************************************************
1970  Set the name of a job. Only possible for owner.
1971 ****************************************************************************/
1972
1973 bool print_job_set_name(const char *sharename, uint32 jobid, const char *name)
1974 {
1975         struct printjob *pjob;
1976
1977         pjob = print_job_find(sharename, jobid);
1978         if (!pjob || pjob->pid != sys_getpid())
1979                 return False;
1980
1981         fstrcpy(pjob->jobname, name);
1982         return pjob_store(server_event_context(), server_messaging_context(),
1983                           sharename, jobid, pjob);
1984 }
1985
1986 /****************************************************************************
1987  Get the name of a job. Only possible for owner.
1988 ****************************************************************************/
1989
1990 bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t jobid, char **name)
1991 {
1992         struct printjob *pjob;
1993
1994         pjob = print_job_find(sharename, jobid);
1995         if (!pjob || pjob->pid != sys_getpid()) {
1996                 return false;
1997         }
1998
1999         *name = talloc_strdup(mem_ctx, pjob->jobname);
2000         if (!*name) {
2001                 return false;
2002         }
2003
2004         return true;
2005 }
2006
2007
2008 /***************************************************************************
2009  Remove a jobid from the 'jobs changed' list.
2010 ***************************************************************************/
2011
2012 static bool remove_from_jobs_changed(const char* sharename, uint32 jobid)
2013 {
2014         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2015         TDB_DATA data, key;
2016         size_t job_count, i;
2017         bool ret = False;
2018         bool gotlock = False;
2019
2020         if (!pdb) {
2021                 return False;
2022         }
2023
2024         ZERO_STRUCT(data);
2025
2026         key = string_tdb_data("INFO/jobs_changed");
2027
2028         if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
2029                 goto out;
2030
2031         gotlock = True;
2032
2033         data = tdb_fetch(pdb->tdb, key);
2034
2035         if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
2036                 goto out;
2037
2038         job_count = data.dsize / 4;
2039         for (i = 0; i < job_count; i++) {
2040                 uint32 ch_jobid;
2041
2042                 ch_jobid = IVAL(data.dptr, i*4);
2043                 if (ch_jobid == jobid) {
2044                         if (i < job_count -1 )
2045                                 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
2046                         data.dsize -= 4;
2047                         if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
2048                                 goto out;
2049                         break;
2050                 }
2051         }
2052
2053         ret = True;
2054   out:
2055
2056         if (gotlock)
2057                 tdb_chainunlock(pdb->tdb, key);
2058         SAFE_FREE(data.dptr);
2059         release_print_db(pdb);
2060         if (ret)
2061                 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
2062         else
2063                 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
2064         return ret;
2065 }
2066
2067 /****************************************************************************
2068  Delete a print job - don't update queue.
2069 ****************************************************************************/
2070
2071 static bool print_job_delete1(int snum, uint32 jobid)
2072 {
2073         const char* sharename = lp_const_servicename(snum);
2074         struct printjob *pjob = print_job_find(sharename, jobid);
2075         int result = 0;
2076         struct printif *current_printif = get_printer_fns( snum );
2077
2078         if (!pjob)
2079                 return False;
2080
2081         /*
2082          * If already deleting just return.
2083          */
2084
2085         if (pjob->status == LPQ_DELETING)
2086                 return True;
2087
2088         /* Hrm - we need to be able to cope with deleting a job before it
2089            has reached the spooler.  Just mark it as LPQ_DELETING and
2090            let the print_queue_update() code rmeove the record */
2091
2092
2093         if (pjob->sysjob == -1) {
2094                 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
2095         }
2096
2097         /* Set the tdb entry to be deleting. */
2098
2099         pjob->status = LPQ_DELETING;
2100         pjob_store(server_event_context(), server_messaging_context(),
2101                    sharename, jobid, pjob);
2102
2103         if (pjob->spooled && pjob->sysjob != -1)
2104         {
2105                 result = (*(current_printif->job_delete))(
2106                         lp_printername(snum),
2107                         lp_lprmcommand(snum),
2108                         pjob);
2109
2110                 /* Delete the tdb entry if the delete succeeded or the job hasn't
2111                    been spooled. */
2112
2113                 if (result == 0) {
2114                         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2115                         int njobs = 1;
2116
2117                         if (!pdb)
2118                                 return False;
2119                         pjob_delete(server_event_context(),
2120                                     server_messaging_context(),
2121                                     sharename, jobid);
2122                         /* Ensure we keep a rough count of the number of total jobs... */
2123                         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
2124                         release_print_db(pdb);
2125                 }
2126         }
2127
2128         remove_from_jobs_changed( sharename, jobid );
2129
2130         return (result == 0);
2131 }
2132
2133 /****************************************************************************
2134  Return true if the current user owns the print job.
2135 ****************************************************************************/
2136
2137 static bool is_owner(struct auth_serversupplied_info *server_info,
2138                      const char *servicename,
2139                      uint32 jobid)
2140 {
2141         struct printjob *pjob = print_job_find(servicename, jobid);
2142
2143         if (!pjob || !server_info)
2144                 return False;
2145
2146         return strequal(pjob->user, server_info->sanitized_username);
2147 }
2148
2149 /****************************************************************************
2150  Delete a print job.
2151 ****************************************************************************/
2152
2153 WERROR print_job_delete(struct auth_serversupplied_info *server_info,
2154                         struct messaging_context *msg_ctx,
2155                         int snum, uint32_t jobid)
2156 {
2157         const char* sharename = lp_const_servicename(snum);
2158         struct printjob *pjob;
2159         bool    owner;
2160         char    *fname;
2161
2162         owner = is_owner(server_info, lp_const_servicename(snum), jobid);
2163
2164         /* Check access against security descriptor or whether the user
2165            owns their job. */
2166
2167         if (!owner &&
2168             !print_access_check(server_info, msg_ctx, snum,
2169                                 JOB_ACCESS_ADMINISTER)) {
2170                 DEBUG(3, ("delete denied by security descriptor\n"));
2171
2172                 /* BEGIN_ADMIN_LOG */
2173                 sys_adminlog( LOG_ERR,
2174                               "Permission denied-- user not allowed to delete, \
2175 pause, or resume print job. User name: %s. Printer name: %s.",
2176                               uidtoname(server_info->utok.uid),
2177                               lp_printername(snum) );
2178                 /* END_ADMIN_LOG */
2179
2180                 return WERR_ACCESS_DENIED;
2181         }
2182
2183         /*
2184          * get the spooled filename of the print job
2185          * if this works, then the file has not been spooled
2186          * to the underlying print system.  Just delete the
2187          * spool file & return.
2188          */
2189
2190         fname = print_job_fname(sharename, jobid);
2191         if (fname != NULL) {
2192                 /* remove the spool file */
2193                 DEBUG(10, ("print_job_delete: "
2194                            "Removing spool file [%s]\n", fname));
2195                 if (unlink(fname) == -1) {
2196                         return map_werror_from_unix(errno);
2197                 }
2198         }
2199
2200         if (!print_job_delete1(snum, jobid)) {
2201                 return WERR_ACCESS_DENIED;
2202         }
2203
2204         /* force update the database and say the delete failed if the
2205            job still exists */
2206
2207         print_queue_update(msg_ctx, snum, True);
2208
2209         pjob = print_job_find(sharename, jobid);
2210         if (pjob && (pjob->status != LPQ_DELETING)) {
2211                 return WERR_ACCESS_DENIED;
2212         }
2213
2214         return WERR_PRINTER_HAS_JOBS_QUEUED;
2215 }
2216
2217 /****************************************************************************
2218  Pause a job.
2219 ****************************************************************************/
2220
2221 bool print_job_pause(struct auth_serversupplied_info *server_info,
2222                      struct messaging_context *msg_ctx,
2223                      int snum, uint32 jobid, WERROR *errcode)
2224 {
2225         const char* sharename = lp_const_servicename(snum);
2226         struct printjob *pjob;
2227         int ret = -1;
2228         struct printif *current_printif = get_printer_fns( snum );
2229
2230         pjob = print_job_find(sharename, jobid);
2231
2232         if (!pjob || !server_info) {
2233                 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2234                         (unsigned int)jobid ));
2235                 return False;
2236         }
2237
2238         if (!pjob->spooled || pjob->sysjob == -1) {
2239                 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2240                         (int)pjob->sysjob, (unsigned int)jobid ));
2241                 return False;
2242         }
2243
2244         if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2245             !print_access_check(server_info, msg_ctx, snum,
2246                                 JOB_ACCESS_ADMINISTER)) {
2247                 DEBUG(3, ("pause denied by security descriptor\n"));
2248
2249                 /* BEGIN_ADMIN_LOG */
2250                 sys_adminlog( LOG_ERR,
2251                         "Permission denied-- user not allowed to delete, \
2252 pause, or resume print job. User name: %s. Printer name: %s.",
2253                               uidtoname(server_info->utok.uid),
2254                               lp_printername(snum) );
2255                 /* END_ADMIN_LOG */
2256
2257                 *errcode = WERR_ACCESS_DENIED;
2258                 return False;
2259         }
2260
2261         /* need to pause the spooled entry */
2262         ret = (*(current_printif->job_pause))(snum, pjob);
2263
2264         if (ret != 0) {
2265                 *errcode = WERR_INVALID_PARAM;
2266                 return False;
2267         }
2268
2269         /* force update the database */
2270         print_cache_flush(lp_const_servicename(snum));
2271
2272         /* Send a printer notify message */
2273
2274         notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2275                           JOB_STATUS_PAUSED);
2276
2277         /* how do we tell if this succeeded? */
2278
2279         return True;
2280 }
2281
2282 /****************************************************************************
2283  Resume a job.
2284 ****************************************************************************/
2285
2286 bool print_job_resume(struct auth_serversupplied_info *server_info,
2287                       struct messaging_context *msg_ctx,
2288                       int snum, uint32 jobid, WERROR *errcode)
2289 {
2290         const char *sharename = lp_const_servicename(snum);
2291         struct printjob *pjob;
2292         int ret;
2293         struct printif *current_printif = get_printer_fns( snum );
2294
2295         pjob = print_job_find(sharename, jobid);
2296
2297         if (!pjob || !server_info) {
2298                 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2299                         (unsigned int)jobid ));
2300                 return False;
2301         }
2302
2303         if (!pjob->spooled || pjob->sysjob == -1) {
2304                 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2305                         (int)pjob->sysjob, (unsigned int)jobid ));
2306                 return False;
2307         }
2308
2309         if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2310             !print_access_check(server_info, msg_ctx, snum,
2311                                 JOB_ACCESS_ADMINISTER)) {
2312                 DEBUG(3, ("resume denied by security descriptor\n"));
2313                 *errcode = WERR_ACCESS_DENIED;
2314
2315                 /* BEGIN_ADMIN_LOG */
2316                 sys_adminlog( LOG_ERR,
2317                          "Permission denied-- user not allowed to delete, \
2318 pause, or resume print job. User name: %s. Printer name: %s.",
2319                               uidtoname(server_info->utok.uid),
2320                               lp_printername(snum) );
2321                 /* END_ADMIN_LOG */
2322                 return False;
2323         }
2324
2325         ret = (*(current_printif->job_resume))(snum, pjob);
2326
2327         if (ret != 0) {
2328                 *errcode = WERR_INVALID_PARAM;
2329                 return False;
2330         }
2331
2332         /* force update the database */
2333         print_cache_flush(lp_const_servicename(snum));
2334
2335         /* Send a printer notify message */
2336
2337         notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2338                           JOB_STATUS_QUEUED);
2339
2340         return True;
2341 }
2342
2343 /****************************************************************************
2344  Write to a print file.
2345 ****************************************************************************/
2346
2347 ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size)
2348 {
2349         const char* sharename = lp_const_servicename(snum);
2350         ssize_t return_code;
2351         struct printjob *pjob;
2352
2353         pjob = print_job_find(sharename, jobid);
2354
2355         if (!pjob)
2356                 return -1;
2357         /* don't allow another process to get this info - it is meaningless */
2358         if (pjob->pid != sys_getpid())
2359                 return -1;
2360
2361         /* if SMBD is spooling this can't be allowed */
2362         if (pjob->status == PJOB_SMBD_SPOOLING) {
2363                 return -1;
2364         }
2365
2366         return_code = write_data_at_offset(pjob->fd, buf, size, pos);
2367
2368         if (return_code>0) {
2369                 pjob->size += size;
2370                 pjob_store(server_event_context(), server_messaging_context(),
2371                            sharename, jobid, pjob);
2372         }
2373         return return_code;
2374 }
2375
2376 /****************************************************************************
2377  Get the queue status - do not update if db is out of date.
2378 ****************************************************************************/
2379
2380 static int get_queue_status(const char* sharename, print_status_struct *status)
2381 {
2382         fstring keystr;
2383         TDB_DATA data;
2384         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2385         int len;
2386
2387         if (status) {
2388                 ZERO_STRUCTP(status);
2389         }
2390
2391         if (!pdb)
2392                 return 0;
2393
2394         if (status) {
2395                 fstr_sprintf(keystr, "STATUS/%s", sharename);
2396                 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2397                 if (data.dptr) {
2398                         if (data.dsize == sizeof(print_status_struct))
2399                                 /* this memcpy is ok since the status struct was
2400                                    not packed before storing it in the tdb */
2401                                 memcpy(status, data.dptr, sizeof(print_status_struct));
2402                         SAFE_FREE(data.dptr);
2403                 }
2404         }
2405         len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2406         release_print_db(pdb);
2407         return (len == -1 ? 0 : len);
2408 }
2409
2410 /****************************************************************************
2411  Determine the number of jobs in a queue.
2412 ****************************************************************************/
2413
2414 int print_queue_length(struct messaging_context *msg_ctx, int snum,
2415                        print_status_struct *pstatus)
2416 {
2417         const char* sharename = lp_const_servicename( snum );
2418         print_status_struct status;
2419         int len;
2420
2421         ZERO_STRUCT( status );
2422
2423         /* make sure the database is up to date */
2424         if (print_cache_expired(lp_const_servicename(snum), True))
2425                 print_queue_update(msg_ctx, snum, False);
2426
2427         /* also fetch the queue status */
2428         memset(&status, 0, sizeof(status));
2429         len = get_queue_status(sharename, &status);
2430
2431         if (pstatus)
2432                 *pstatus = status;
2433
2434         return len;
2435 }
2436
2437 /***************************************************************************
2438  Allocate a jobid. Hold the lock for as short a time as possible.
2439 ***************************************************************************/
2440
2441 static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum,
2442                                    const char *sharename, uint32 *pjobid)
2443 {
2444         int i;
2445         uint32 jobid;
2446         enum TDB_ERROR terr;
2447         int ret;
2448
2449         *pjobid = (uint32)-1;
2450
2451         for (i = 0; i < 3; i++) {
2452                 /* Lock the database - only wait 20 seconds. */
2453                 ret = tdb_lock_bystring_with_timeout(pdb->tdb,
2454                                                      "INFO/nextjob", 20);
2455                 if (ret == -1) {
2456                         DEBUG(0, ("allocate_print_jobid: "
2457                                   "Failed to lock printing database %s\n",
2458                                   sharename));
2459                         terr = tdb_error(pdb->tdb);
2460                         return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2461                 }
2462
2463                 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2464                         terr = tdb_error(pdb->tdb);
2465                         if (terr != TDB_ERR_NOEXIST) {
2466                                 DEBUG(0, ("allocate_print_jobid: "
2467                                           "Failed to fetch INFO/nextjob "
2468                                           "for print queue %s\n", sharename));
2469                                 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2470                                 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2471                         }
2472                         DEBUG(10, ("allocate_print_jobid: "
2473                                    "No existing jobid in %s\n", sharename));
2474                         jobid = 0;
2475                 }
2476
2477                 DEBUG(10, ("allocate_print_jobid: "
2478                            "Read jobid %u from %s\n", jobid, sharename));
2479
2480                 jobid = NEXT_JOBID(jobid);
2481
2482                 ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid);
2483                 if (ret == -1) {
2484                         terr = tdb_error(pdb->tdb);
2485                         DEBUG(3, ("allocate_print_jobid: "
2486                                   "Failed to store INFO/nextjob.\n"));
2487                         tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2488                         return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2489                 }
2490
2491                 /* We've finished with the INFO/nextjob lock. */
2492                 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2493
2494                 if (!print_job_exists(sharename, jobid)) {
2495                         break;
2496                 }
2497                 DEBUG(10, ("allocate_print_jobid: "
2498                            "Found jobid %u in %s\n", jobid, sharename));
2499         }
2500
2501         if (i > 2) {
2502                 DEBUG(0, ("allocate_print_jobid: "
2503                           "Failed to allocate a print job for queue %s\n",
2504                           sharename));
2505                 /* Probably full... */
2506                 return WERR_NO_SPOOL_SPACE;
2507         }
2508
2509         /* Store a dummy placeholder. */
2510         {
2511                 uint32_t tmp;
2512                 TDB_DATA dum;
2513                 dum.dptr = NULL;
2514                 dum.dsize = 0;
2515                 if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
2516                               TDB_INSERT) == -1) {
2517                         DEBUG(3, ("allocate_print_jobid: "
2518                                   "jobid (%d) failed to store placeholder.\n",
2519                                   jobid ));
2520                         terr = tdb_error(pdb->tdb);
2521                         return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2522                 }
2523         }
2524
2525         *pjobid = jobid;
2526         return WERR_OK;
2527 }
2528
2529 /***************************************************************************
2530  Append a jobid to the 'jobs changed' list.
2531 ***************************************************************************/
2532
2533 static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
2534 {
2535         TDB_DATA data;
2536         uint32 store_jobid;
2537
2538         SIVAL(&store_jobid, 0, jobid);
2539         data.dptr = (uint8 *)&store_jobid;
2540         data.dsize = 4;
2541
2542         DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
2543
2544         return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
2545                            data) == 0);
2546 }
2547
2548
2549 /***************************************************************************
2550  Do all checks needed to determine if we can start a job.
2551 ***************************************************************************/
2552
2553 static WERROR print_job_checks(struct auth_serversupplied_info *server_info,
2554                                struct messaging_context *msg_ctx,
2555                                int snum, int *njobs)
2556 {
2557         const char *sharename = lp_const_servicename(snum);
2558         uint64_t dspace, dsize;
2559         uint64_t minspace;
2560         int ret;
2561
2562         if (!print_access_check(server_info, msg_ctx, snum,
2563                                 PRINTER_ACCESS_USE)) {
2564                 DEBUG(3, ("print_job_checks: "
2565                           "job start denied by security descriptor\n"));
2566                 return WERR_ACCESS_DENIED;
2567         }
2568
2569         if (!print_time_access_check(server_info, msg_ctx, sharename)) {
2570                 DEBUG(3, ("print_job_checks: "
2571                           "job start denied by time check\n"));
2572                 return WERR_ACCESS_DENIED;
2573         }
2574
2575         /* see if we have sufficient disk space */
2576         if (lp_minprintspace(snum)) {
2577                 minspace = lp_minprintspace(snum);
2578                 ret = sys_fsusage(lp_pathname(snum), &dspace, &dsize);
2579                 if (ret == 0 && dspace < 2*minspace) {
2580                         DEBUG(3, ("print_job_checks: "
2581                                   "disk space check failed.\n"));
2582                         return WERR_NO_SPOOL_SPACE;
2583                 }
2584         }
2585
2586         /* for autoloaded printers, check that the printcap entry still exists */
2587         if (lp_autoloaded(snum) && !pcap_printername_ok(sharename)) {
2588                 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2589                           sharename));
2590                 return WERR_ACCESS_DENIED;
2591         }
2592
2593         /* Insure the maximum queue size is not violated */
2594         *njobs = print_queue_length(msg_ctx, snum, NULL);
2595         if (*njobs > lp_maxprintjobs(snum)) {
2596                 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2597                           "larger than max printjobs per queue (%d).\n",
2598                           sharename, *njobs, lp_maxprintjobs(snum)));
2599                 return WERR_NO_SPOOL_SPACE;
2600         }
2601
2602         return WERR_OK;
2603 }
2604
2605 /***************************************************************************
2606  Create a job file.
2607 ***************************************************************************/
2608
2609 static WERROR print_job_spool_file(int snum, uint32_t jobid,
2610                                    const char *output_file,
2611                                    struct printjob *pjob)
2612 {
2613         WERROR werr;
2614         SMB_STRUCT_STAT st;
2615         const char *path;
2616         int len;
2617
2618         /* if this file is within the printer path, it means that smbd
2619          * is spooling it and will pass us control when it is finished.
2620          * Verify that the file name is ok, within path, and it is
2621          * already already there */
2622         if (output_file) {
2623                 path = lp_pathname(snum);
2624                 len = strlen(path);
2625                 if (strncmp(output_file, path, len) == 0 &&
2626                     (output_file[len - 1] == '/' || output_file[len] == '/')) {
2627
2628                         /* verify path is not too long */
2629                         if (strlen(output_file) >= sizeof(pjob->filename)) {
2630                                 return WERR_INVALID_NAME;
2631                         }
2632
2633                         /* verify that the file exists */
2634                         if (sys_stat(output_file, &st, false) != 0) {
2635                                 return WERR_INVALID_NAME;
2636                         }
2637
2638                         fstrcpy(pjob->filename, output_file);
2639
2640                         DEBUG(3, ("print_job_spool_file:"
2641                                   "External spooling activated"));
2642
2643                         /* we do not open the file until spooling is done */
2644                         pjob->fd = -1;
2645                         pjob->status = PJOB_SMBD_SPOOLING;
2646
2647                         return WERR_OK;
2648                 }
2649         }
2650
2651         slprintf(pjob->filename, sizeof(pjob->filename)-1,
2652                  "%s/%s%.8u.XXXXXX", lp_pathname(snum),
2653                  PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2654         pjob->fd = mkstemp(pjob->filename);
2655
2656         if (pjob->fd == -1) {
2657                 werr = map_werror_from_unix(errno);
2658                 if (W_ERROR_EQUAL(werr, WERR_ACCESS_DENIED)) {
2659                         /* Common setup error, force a report. */
2660                         DEBUG(0, ("print_job_spool_file: "
2661                                   "insufficient permissions to open spool "
2662                                   "file %s.\n", pjob->filename));
2663                 } else {
2664                         /* Normal case, report at level 3 and above. */
2665                         DEBUG(3, ("print_job_spool_file: "
2666                                   "can't open spool file %s\n",
2667                                   pjob->filename));
2668                 }
2669                 return werr;
2670         }
2671
2672         return WERR_OK;
2673 }
2674
2675 /***************************************************************************
2676  Start spooling a job - return the jobid.
2677 ***************************************************************************/
2678
2679 WERROR print_job_start(struct auth_serversupplied_info *server_info,
2680                        struct messaging_context *msg_ctx,
2681                        int snum, const char *docname, const char *filename,
2682                        struct spoolss_DeviceMode *devmode, uint32_t *_jobid)
2683 {
2684         uint32_t jobid;
2685         char *path;
2686         struct printjob pjob;
2687         const char *sharename = lp_const_servicename(snum);
2688         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2689         int njobs;
2690         WERROR werr;
2691
2692         if (!pdb) {
2693                 return WERR_INTERNAL_DB_CORRUPTION;
2694         }
2695
2696         path = lp_pathname(snum);
2697
2698         werr = print_job_checks(server_info, msg_ctx, snum, &njobs);
2699         if (!W_ERROR_IS_OK(werr)) {
2700                 release_print_db(pdb);
2701                 return werr;
2702         }
2703
2704         DEBUG(10, ("print_job_start: "
2705                    "Queue %s number of jobs (%d), max printjobs = %d\n",
2706                    sharename, njobs, lp_maxprintjobs(snum)));
2707
2708         werr = allocate_print_jobid(pdb, snum, sharename, &jobid);
2709         if (!W_ERROR_IS_OK(werr)) {
2710                 goto fail;
2711         }
2712
2713         /* create the database entry */
2714
2715         ZERO_STRUCT(pjob);
2716
2717         pjob.pid = sys_getpid();
2718         pjob.sysjob = -1;
2719         pjob.fd = -1;
2720         pjob.starttime = time(NULL);
2721         pjob.status = LPQ_SPOOLING;
2722         pjob.size = 0;
2723         pjob.spooled = False;
2724         pjob.smbjob = True;
2725         pjob.devmode = devmode;
2726
2727         fstrcpy(pjob.jobname, docname);
2728
2729         fstrcpy(pjob.user, lp_printjob_username(snum));
2730         standard_sub_advanced(sharename, server_info->sanitized_username,
2731                               path, server_info->utok.gid,
2732                               server_info->sanitized_username,
2733                               server_info->info3->base.domain.string,
2734                               pjob.user, sizeof(pjob.user)-1);
2735         /* ensure NULL termination */
2736         pjob.user[sizeof(pjob.user)-1] = '\0';
2737
2738         fstrcpy(pjob.queuename, lp_const_servicename(snum));
2739
2740         /* we have a job entry - now create the spool file */
2741         werr = print_job_spool_file(snum, jobid, filename, &pjob);
2742         if (!W_ERROR_IS_OK(werr)) {
2743                 goto fail;
2744         }
2745
2746         pjob_store(server_event_context(), msg_ctx, sharename, jobid, &pjob);
2747
2748         /* Update the 'jobs changed' entry used by print_queue_status. */
2749         add_to_jobs_changed(pdb, jobid);
2750
2751         /* Ensure we keep a rough count of the number of total jobs... */
2752         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2753
2754         release_print_db(pdb);
2755
2756         *_jobid = jobid;
2757         return WERR_OK;
2758
2759 fail:
2760         if (jobid != -1) {
2761                 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
2762         }
2763
2764         release_print_db(pdb);
2765
2766         DEBUG(3, ("print_job_start: returning fail. "
2767                   "Error = %s\n", win_errstr(werr)));
2768         return werr;
2769 }
2770
2771 /****************************************************************************
2772  Update the number of pages spooled to jobid
2773 ****************************************************************************/
2774
2775 void print_job_endpage(int snum, uint32 jobid)
2776 {
2777         const char* sharename = lp_const_servicename(snum);
2778         struct printjob *pjob;
2779
2780         pjob = print_job_find(sharename, jobid);
2781         if (!pjob)
2782                 return;
2783         /* don't allow another process to get this info - it is meaningless */
2784         if (pjob->pid != sys_getpid())
2785                 return;
2786
2787         pjob->page_count++;
2788         pjob_store(server_event_context(), server_messaging_context(),
2789                    sharename, jobid, pjob);
2790 }
2791
2792 /****************************************************************************
2793  Print a file - called on closing the file. This spools the job.
2794  If normal close is false then we're tearing down the jobs - treat as an
2795  error.
2796 ****************************************************************************/
2797
2798 NTSTATUS print_job_end(struct messaging_context *msg_ctx, int snum,
2799                        uint32 jobid, enum file_close_type close_type)
2800 {
2801         const char* sharename = lp_const_servicename(snum);
2802         struct printjob *pjob;
2803         int ret;
2804         SMB_STRUCT_STAT sbuf;
2805         struct printif *current_printif = get_printer_fns( snum );
2806         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2807
2808         pjob = print_job_find(sharename, jobid);
2809
2810         if (!pjob) {
2811                 return NT_STATUS_PRINT_CANCELLED;
2812         }
2813
2814         if (pjob->spooled || pjob->pid != sys_getpid()) {
2815                 return NT_STATUS_ACCESS_DENIED;
2816         }
2817
2818         if (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) {
2819                 if (pjob->status == PJOB_SMBD_SPOOLING) {
2820                         /* take over the file now, smbd is done */
2821                         if (sys_stat(pjob->filename, &sbuf, false) != 0) {
2822                                 status = map_nt_error_from_unix(errno);
2823                                 DEBUG(3, ("print_job_end: "
2824                                           "stat file failed for jobid %d\n",
2825                                           jobid));
2826                                 goto fail;
2827                         }
2828
2829                         pjob->status = LPQ_SPOOLING;
2830
2831                 } else {
2832
2833                         if ((sys_fstat(pjob->fd, &sbuf, false) != 0)) {
2834                                 status = map_nt_error_from_unix(errno);
2835                                 close(pjob->fd);
2836                                 DEBUG(3, ("print_job_end: "
2837                                           "stat file failed for jobid %d\n",
2838                                           jobid));
2839                                 goto fail;
2840                         }
2841
2842                         close(pjob->fd);
2843                 }
2844
2845                 pjob->size = sbuf.st_ex_size;
2846         } else {
2847
2848                 /*
2849                  * Not a normal close, something has gone wrong. Cleanup.
2850                  */
2851                 if (pjob->fd != -1) {
2852                         close(pjob->fd);
2853                 }
2854                 goto fail;
2855         }
2856
2857         /* Technically, this is not quite right. If the printer has a separator
2858          * page turned on, the NT spooler prints the separator page even if the
2859          * print job is 0 bytes. 010215 JRR */
2860         if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2861                 /* don't bother spooling empty files or something being deleted. */
2862                 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2863                         pjob->filename, pjob->size ? "deleted" : "zero length" ));
2864                 unlink(pjob->filename);
2865                 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
2866                 return NT_STATUS_OK;
2867         }
2868
2869         ret = (*(current_printif->job_submit))(snum, pjob);
2870
2871         if (ret) {
2872                 status = NT_STATUS_PRINT_CANCELLED;
2873                 goto fail;
2874         }
2875
2876         /* The print job has been successfully handed over to the back-end */
2877
2878         pjob->spooled = True;
2879         pjob->status = LPQ_QUEUED;
2880         pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
2881
2882         /* make sure the database is up to date */
2883         if (print_cache_expired(lp_const_servicename(snum), True))
2884                 print_queue_update(msg_ctx, snum, False);
2885
2886         return NT_STATUS_OK;
2887
2888 fail:
2889
2890         /* The print job was not successfully started. Cleanup */
2891         /* Still need to add proper error return propagation! 010122:JRR */
2892         pjob->fd = -1;
2893         unlink(pjob->filename);
2894         pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
2895         return status;
2896 }
2897
2898 /****************************************************************************
2899  Get a snapshot of jobs in the system without traversing.
2900 ****************************************************************************/
2901
2902 static bool get_stored_queue_info(struct messaging_context *msg_ctx,
2903                                   struct tdb_print_db *pdb, int snum,
2904                                   int *pcount, print_queue_struct **ppqueue)
2905 {
2906         TDB_DATA data, cgdata;
2907         print_queue_struct *queue = NULL;
2908         uint32 qcount = 0;
2909         uint32 extra_count = 0;
2910         int total_count = 0;
2911         size_t len = 0;
2912         uint32 i;
2913         int max_reported_jobs = lp_max_reported_jobs(snum);
2914         bool ret = False;
2915         const char* sharename = lp_servicename(snum);
2916
2917         /* make sure the database is up to date */
2918         if (print_cache_expired(lp_const_servicename(snum), True))
2919                 print_queue_update(msg_ctx, snum, False);
2920
2921         *pcount = 0;
2922         *ppqueue = NULL;
2923
2924         ZERO_STRUCT(data);
2925         ZERO_STRUCT(cgdata);
2926
2927         /* Get the stored queue data. */
2928         data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
2929
2930         if (data.dptr && data.dsize >= sizeof(qcount))
2931                 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2932
2933         /* Get the changed jobs list. */
2934         cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
2935         if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2936                 extra_count = cgdata.dsize/4;
2937
2938         DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2939
2940         /* Allocate the queue size. */
2941         if (qcount == 0 && extra_count == 0)
2942                 goto out;
2943
2944         if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
2945                 goto out;
2946
2947         /* Retrieve the linearised queue data. */
2948
2949         for( i  = 0; i < qcount; i++) {
2950                 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2951                 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2952                                 &qjob,
2953                                 &qsize,
2954                                 &qpage_count,
2955                                 &qstatus,
2956                                 &qpriority,
2957                                 &qtime,
2958                                 queue[i].fs_user,
2959                                 queue[i].fs_file);
2960                 queue[i].job = qjob;
2961                 queue[i].size = qsize;
2962                 queue[i].page_count = qpage_count;
2963                 queue[i].status = qstatus;
2964                 queue[i].priority = qpriority;
2965                 queue[i].time = qtime;
2966         }
2967
2968         total_count = qcount;
2969
2970         /* Add in the changed jobids. */
2971         for( i  = 0; i < extra_count; i++) {
2972                 uint32 jobid;
2973                 struct printjob *pjob;
2974
2975                 jobid = IVAL(cgdata.dptr, i*4);
2976                 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2977                 pjob = print_job_find(lp_const_servicename(snum), jobid);
2978                 if (!pjob) {
2979                         DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2980                         remove_from_jobs_changed(sharename, jobid);
2981                         continue;
2982                 }
2983
2984                 queue[total_count].job = jobid;
2985                 queue[total_count].size = pjob->size;
2986                 queue[total_count].page_count = pjob->page_count;
2987                 queue[total_count].status = pjob->status;
2988                 queue[total_count].priority = 1;
2989                 queue[total_count].time = pjob->starttime;
2990                 fstrcpy(queue[total_count].fs_user, pjob->user);
2991                 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2992                 total_count++;
2993         }
2994
2995         /* Sort the queue by submission time otherwise they are displayed
2996            in hash order. */
2997
2998         TYPESAFE_QSORT(queue, total_count, printjob_comp);
2999
3000         DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
3001
3002         if (max_reported_jobs && total_count > max_reported_jobs)
3003                 total_count = max_reported_jobs;
3004
3005         *ppqueue = queue;
3006         *pcount = total_count;
3007
3008         ret = True;
3009
3010   out:
3011
3012         SAFE_FREE(data.dptr);
3013         SAFE_FREE(cgdata.dptr);
3014         return ret;
3015 }
3016
3017 /****************************************************************************
3018  Get a printer queue listing.
3019  set queue = NULL and status = NULL if you just want to update the cache
3020 ****************************************************************************/
3021
3022 int print_queue_status(struct messaging_context *msg_ctx, int snum,
3023                        print_queue_struct **ppqueue,
3024                        print_status_struct *status)
3025 {
3026         fstring keystr;
3027         TDB_DATA data, key;
3028         const char *sharename;
3029         struct tdb_print_db *pdb;
3030         int count = 0;
3031
3032         /* make sure the database is up to date */
3033
3034         if (print_cache_expired(lp_const_servicename(snum), True))
3035                 print_queue_update(msg_ctx, snum, False);
3036
3037         /* return if we are done */
3038         if ( !ppqueue || !status )
3039                 return 0;
3040
3041         *ppqueue = NULL;
3042         sharename = lp_const_servicename(snum);
3043         pdb = get_print_db_byname(sharename);
3044
3045         if (!pdb)
3046                 return 0;
3047
3048         /*
3049          * Fetch the queue status.  We must do this first, as there may
3050          * be no jobs in the queue.
3051          */
3052
3053         ZERO_STRUCTP(status);
3054         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
3055         key = string_tdb_data(keystr);
3056
3057         data = tdb_fetch(pdb->tdb, key);
3058         if (data.dptr) {
3059                 if (data.dsize == sizeof(*status)) {
3060                         /* this memcpy is ok since the status struct was
3061                            not packed before storing it in the tdb */
3062                         memcpy(status, data.dptr, sizeof(*status));
3063                 }
3064                 SAFE_FREE(data.dptr);
3065         }
3066
3067         /*
3068          * Now, fetch the print queue information.  We first count the number
3069          * of entries, and then only retrieve the queue if necessary.
3070          */
3071
3072         if (!get_stored_queue_info(msg_ctx, pdb, snum, &count, ppqueue)) {
3073                 release_print_db(pdb);
3074                 return 0;
3075         }
3076
3077         release_print_db(pdb);
3078         return count;
3079 }
3080
3081 /****************************************************************************
3082  Pause a queue.
3083 ****************************************************************************/
3084
3085 WERROR print_queue_pause(struct auth_serversupplied_info *server_info,
3086                          struct messaging_context *msg_ctx, int snum)
3087 {
3088         int ret;
3089         struct printif *current_printif = get_printer_fns( snum );
3090
3091         if (!print_access_check(server_info, msg_ctx, snum,
3092                                 PRINTER_ACCESS_ADMINISTER)) {
3093                 return WERR_ACCESS_DENIED;
3094         }
3095
3096
3097         become_root();
3098
3099         ret = (*(current_printif->queue_pause))(snum);
3100
3101         unbecome_root();
3102
3103         if (ret != 0) {
3104                 return WERR_INVALID_PARAM;
3105         }
3106
3107         /* force update the database */
3108         print_cache_flush(lp_const_servicename(snum));
3109
3110         /* Send a printer notify message */
3111
3112         notify_printer_status(server_event_context(), msg_ctx, snum,
3113                               PRINTER_STATUS_PAUSED);
3114
3115         return WERR_OK;
3116 }
3117
3118 /****************************************************************************
3119  Resume a queue.
3120 ****************************************************************************/
3121
3122 WERROR print_queue_resume(struct auth_serversupplied_info *server_info,
3123                           struct messaging_context *msg_ctx, int snum)
3124 {
3125         int ret;
3126         struct printif *current_printif = get_printer_fns( snum );
3127
3128         if (!print_access_check(server_info, msg_ctx, snum,
3129                                 PRINTER_ACCESS_ADMINISTER)) {
3130                 return WERR_ACCESS_DENIED;
3131         }
3132
3133         become_root();
3134
3135         ret = (*(current_printif->queue_resume))(snum);
3136
3137         unbecome_root();
3138
3139         if (ret != 0) {
3140                 return WERR_INVALID_PARAM;
3141         }
3142
3143         /* make sure the database is up to date */
3144         if (print_cache_expired(lp_const_servicename(snum), True))
3145                 print_queue_update(msg_ctx, snum, True);
3146
3147         /* Send a printer notify message */
3148
3149         notify_printer_status(server_event_context(), msg_ctx, snum,
3150                               PRINTER_STATUS_OK);
3151
3152         return WERR_OK;
3153 }
3154
3155 /****************************************************************************
3156  Purge a queue - implemented by deleting all jobs that we can delete.
3157 ****************************************************************************/
3158
3159 WERROR print_queue_purge(struct auth_serversupplied_info *server_info,
3160                          struct messaging_context *msg_ctx, int snum)
3161 {
3162         print_queue_struct *queue;
3163         print_status_struct status;
3164         int njobs, i;
3165         bool can_job_admin;
3166
3167         /* Force and update so the count is accurate (i.e. not a cached count) */
3168         print_queue_update(msg_ctx, snum, True);
3169
3170         can_job_admin = print_access_check(server_info,
3171                                            msg_ctx,
3172                                            snum,
3173                                            JOB_ACCESS_ADMINISTER);
3174         njobs = print_queue_status(msg_ctx, snum, &queue, &status);
3175
3176         if ( can_job_admin )
3177                 become_root();
3178
3179         for (i=0;i<njobs;i++) {
3180                 bool owner = is_owner(server_info, lp_const_servicename(snum),
3181                                       queue[i].job);
3182
3183                 if (owner || can_job_admin) {
3184                         print_job_delete1(snum, queue[i].job);
3185                 }
3186         }
3187
3188         if ( can_job_admin )
3189                 unbecome_root();
3190
3191         /* update the cache */
3192         print_queue_update(msg_ctx, snum, True);
3193
3194         SAFE_FREE(queue);
3195
3196         return WERR_OK;
3197 }