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