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