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