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