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