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