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