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