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