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