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