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