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