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