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