s3: Lift the server_messaging_context from pjob_store
[abartlet/samba.git/.git] / source3 / printing / printing.c
1 /*
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    printing backend routines
5    Copyright (C) Andrew Tridgell 1992-2000
6    Copyright (C) Jeremy Allison 2002
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "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 void pjob_delete(const char* sharename, uint32 jobid)
716 {
717         uint32_t tmp;
718         struct printjob *pjob;
719         uint32 job_status = 0;
720         struct tdb_print_db *pdb;
721
722         pdb = get_print_db_byname( sharename );
723
724         if (!pdb)
725                 return;
726
727         pjob = print_job_find( sharename, jobid );
728
729         if (!pjob) {
730                 DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
731                                         (unsigned int)jobid));
732                 release_print_db(pdb);
733                 return;
734         }
735
736         /* We must cycle through JOB_STATUS_DELETING and
737            JOB_STATUS_DELETED for the port monitor to delete the job
738            properly. */
739
740         job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
741         notify_job_status(server_event_context(),
742                           server_messaging_context(),
743                           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(ts->sharename, jobid);
834                         return 0;
835                 }
836
837                 /* need to continue the the bottom of the function to
838                    save the correct attributes */
839         }
840
841         /* maybe it hasn't been spooled yet */
842         if (!pjob.spooled) {
843                 /* if a job is not spooled and the process doesn't
844                    exist then kill it. This cleans up after smbd
845                    deaths */
846                 if (!process_exists_by_pid(pjob.pid)) {
847                         DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
848                                                 (unsigned int)jobid, (unsigned int)pjob.pid ));
849                         pjob_delete(ts->sharename, jobid);
850                 } else
851                         ts->total_jobs++;
852                 return 0;
853         }
854
855         /* this check only makes sense for jobs submitted from Windows clients */
856
857         if ( pjob.smbjob ) {
858                 for (i=0;i<ts->qcount;i++) {
859                         uint32 curr_jobid;
860
861                         if ( pjob.status == LPQ_DELETED )
862                                 continue;
863
864                         curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
865
866                         if (jobid == curr_jobid) {
867
868                                 /* try to clean up any jobs that need to be deleted */
869
870                                 if ( pjob.status == LPQ_DELETING ) {
871                                         int result;
872
873                                         result = (*(ts->print_if->job_delete))(
874                                                 ts->sharename, ts->lprm_command, &pjob );
875
876                                         if ( result != 0 ) {
877                                                 /* if we can't delete, then reset the job status */
878                                                 pjob.status = LPQ_QUEUED;
879                                                 pjob_store(server_event_context(),
880                                                            server_messaging_context(),
881                                                            ts->sharename, jobid, &pjob);
882                                         }
883                                         else {
884                                                 /* if we deleted the job, the remove the tdb record */
885                                                 pjob_delete(ts->sharename, jobid);
886                                                 pjob.status = LPQ_DELETED;
887                                         }
888
889                                 }
890
891                                 break;
892                         }
893                 }
894         }
895
896         /* The job isn't in the system queue - we have to assume it has
897            completed, so delete the database entry. */
898
899         if (i == ts->qcount) {
900
901                 /* A race can occur between the time a job is spooled and
902                    when it appears in the lpq output.  This happens when
903                    the job is added to printing.tdb when another smbd
904                    running print_queue_update() has completed a lpq and
905                    is currently traversing the printing tdb and deleting jobs.
906                    Don't delete the job if it was submitted after the lpq_time. */
907
908                 if (pjob.starttime < ts->lpq_time) {
909                         DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
910                                                 (unsigned int)jobid,
911                                                 (unsigned int)pjob.starttime,
912                                                 (unsigned int)ts->lpq_time ));
913                         pjob_delete(ts->sharename, jobid);
914                 } else
915                         ts->total_jobs++;
916                 return 0;
917         }
918
919         /* Save the pjob attributes we will store.
920            FIXME!!! This is the only place where queue->job
921            represents the SMB jobid      --jerry */
922
923         ts->queue[i].job = jobid;
924         ts->queue[i].size = pjob.size;
925         ts->queue[i].page_count = pjob.page_count;
926         ts->queue[i].status = pjob.status;
927         ts->queue[i].priority = 1;
928         ts->queue[i].time = pjob.starttime;
929         fstrcpy(ts->queue[i].fs_user, pjob.user);
930         fstrcpy(ts->queue[i].fs_file, pjob.jobname);
931
932         ts->total_jobs++;
933
934         return 0;
935 }
936
937 /****************************************************************************
938  Check if the print queue has been updated recently enough.
939 ****************************************************************************/
940
941 static void print_cache_flush(const char *sharename)
942 {
943         fstring key;
944         struct tdb_print_db *pdb = get_print_db_byname(sharename);
945
946         if (!pdb)
947                 return;
948         slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
949         tdb_store_int32(pdb->tdb, key, -1);
950         release_print_db(pdb);
951 }
952
953 /****************************************************************************
954  Check if someone already thinks they are doing the update.
955 ****************************************************************************/
956
957 static pid_t get_updating_pid(const char *sharename)
958 {
959         fstring keystr;
960         TDB_DATA data, key;
961         pid_t updating_pid;
962         struct tdb_print_db *pdb = get_print_db_byname(sharename);
963
964         if (!pdb)
965                 return (pid_t)-1;
966         slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
967         key = string_tdb_data(keystr);
968
969         data = tdb_fetch(pdb->tdb, key);
970         release_print_db(pdb);
971         if (!data.dptr || data.dsize != sizeof(pid_t)) {
972                 SAFE_FREE(data.dptr);
973                 return (pid_t)-1;
974         }
975
976         updating_pid = IVAL(data.dptr, 0);
977         SAFE_FREE(data.dptr);
978
979         if (process_exists_by_pid(updating_pid))
980                 return updating_pid;
981
982         return (pid_t)-1;
983 }
984
985 /****************************************************************************
986  Set the fact that we're doing the update, or have finished doing the update
987  in the tdb.
988 ****************************************************************************/
989
990 static void set_updating_pid(const fstring sharename, bool updating)
991 {
992         fstring keystr;
993         TDB_DATA key;
994         TDB_DATA data;
995         pid_t updating_pid = sys_getpid();
996         uint8 buffer[4];
997
998         struct tdb_print_db *pdb = get_print_db_byname(sharename);
999
1000         if (!pdb)
1001                 return;
1002
1003         slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
1004         key = string_tdb_data(keystr);
1005
1006         DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
1007                 updating ? "" : "not ",
1008                 sharename ));
1009
1010         if ( !updating ) {
1011                 tdb_delete(pdb->tdb, key);
1012                 release_print_db(pdb);
1013                 return;
1014         }
1015
1016         SIVAL( buffer, 0, updating_pid);
1017         data.dptr = buffer;
1018         data.dsize = 4;         /* we always assume this is a 4 byte value */
1019
1020         tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1021         release_print_db(pdb);
1022 }
1023
1024 /****************************************************************************
1025  Sort print jobs by submittal time.
1026 ****************************************************************************/
1027
1028 static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
1029 {
1030         /* Silly cases */
1031
1032         if (!j1 && !j2)
1033                 return 0;
1034         if (!j1)
1035                 return -1;
1036         if (!j2)
1037                 return 1;
1038
1039         /* Sort on job start time */
1040
1041         if (j1->time == j2->time)
1042                 return 0;
1043         return (j1->time > j2->time) ? 1 : -1;
1044 }
1045
1046 /****************************************************************************
1047  Store the sorted queue representation for later portmon retrieval.
1048  Skip deleted jobs
1049 ****************************************************************************/
1050
1051 static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
1052 {
1053         TDB_DATA data;
1054         int max_reported_jobs = lp_max_reported_jobs(pts->snum);
1055         print_queue_struct *queue = pts->queue;
1056         size_t len;
1057         size_t i;
1058         unsigned int qcount;
1059
1060         if (max_reported_jobs && (max_reported_jobs < pts->qcount))
1061                 pts->qcount = max_reported_jobs;
1062         qcount = 0;
1063
1064         /* Work out the size. */
1065         data.dsize = 0;
1066         data.dsize += tdb_pack(NULL, 0, "d", qcount);
1067
1068         for (i = 0; i < pts->qcount; i++) {
1069                 if ( queue[i].status == LPQ_DELETED )
1070                         continue;
1071
1072                 qcount++;
1073                 data.dsize += tdb_pack(NULL, 0, "ddddddff",
1074                                 (uint32)queue[i].job,
1075                                 (uint32)queue[i].size,
1076                                 (uint32)queue[i].page_count,
1077                                 (uint32)queue[i].status,
1078                                 (uint32)queue[i].priority,
1079                                 (uint32)queue[i].time,
1080                                 queue[i].fs_user,
1081                                 queue[i].fs_file);
1082         }
1083
1084         if ((data.dptr = (uint8 *)SMB_MALLOC(data.dsize)) == NULL)
1085                 return;
1086
1087         len = 0;
1088         len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
1089         for (i = 0; i < pts->qcount; i++) {
1090                 if ( queue[i].status == LPQ_DELETED )
1091                         continue;
1092
1093                 len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
1094                                 (uint32)queue[i].job,
1095                                 (uint32)queue[i].size,
1096                                 (uint32)queue[i].page_count,
1097                                 (uint32)queue[i].status,
1098                                 (uint32)queue[i].priority,
1099                                 (uint32)queue[i].time,
1100                                 queue[i].fs_user,
1101                                 queue[i].fs_file);
1102         }
1103
1104         tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
1105                   TDB_REPLACE);
1106         SAFE_FREE(data.dptr);
1107         return;
1108 }
1109
1110 static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
1111 {
1112         TDB_DATA data;
1113
1114         ZERO_STRUCT(data);
1115
1116         data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
1117         if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
1118                 SAFE_FREE(data.dptr);
1119                 ZERO_STRUCT(data);
1120         }
1121
1122         return data;
1123 }
1124
1125 static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid)
1126 {
1127         unsigned int i;
1128         unsigned int job_count = data.dsize / 4;
1129
1130         for (i = 0; i < job_count; i++) {
1131                 uint32 ch_jobid;
1132
1133                 ch_jobid = IVAL(data.dptr, i*4);
1134                 if (ch_jobid == jobid)
1135                         remove_from_jobs_changed(sharename, jobid);
1136         }
1137 }
1138
1139 /****************************************************************************
1140  Check if the print queue has been updated recently enough.
1141 ****************************************************************************/
1142
1143 static bool print_cache_expired(const char *sharename, bool check_pending)
1144 {
1145         fstring key;
1146         time_t last_qscan_time, time_now = time(NULL);
1147         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1148         bool result = False;
1149
1150         if (!pdb)
1151                 return False;
1152
1153         snprintf(key, sizeof(key), "CACHE/%s", sharename);
1154         last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
1155
1156         /*
1157          * Invalidate the queue for 3 reasons.
1158          * (1). last queue scan time == -1.
1159          * (2). Current time - last queue scan time > allowed cache time.
1160          * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
1161          * This last test picks up machines for which the clock has been moved
1162          * forward, an lpq scan done and then the clock moved back. Otherwise
1163          * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
1164          */
1165
1166         if (last_qscan_time == ((time_t)-1)
1167                 || (time_now - last_qscan_time) >= lp_lpqcachetime()
1168                 || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
1169         {
1170                 uint32 u;
1171                 time_t msg_pending_time;
1172
1173                 DEBUG(4, ("print_cache_expired: cache expired for queue %s "
1174                         "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
1175                         sharename, (int)last_qscan_time, (int)time_now,
1176                         (int)lp_lpqcachetime() ));
1177
1178                 /* check if another smbd has already sent a message to update the
1179                    queue.  Give the pending message one minute to clear and
1180                    then send another message anyways.  Make sure to check for
1181                    clocks that have been run forward and then back again. */
1182
1183                 snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1184
1185                 if ( check_pending
1186                         && tdb_fetch_uint32( pdb->tdb, key, &u )
1187                         && (msg_pending_time=u) > 0
1188                         && msg_pending_time <= time_now
1189                         && (time_now - msg_pending_time) < 60 )
1190                 {
1191                         DEBUG(4,("print_cache_expired: message already pending for %s.  Accepting cache\n",
1192                                 sharename));
1193                         goto done;
1194                 }
1195
1196                 result = True;
1197         }
1198
1199 done:
1200         release_print_db(pdb);
1201         return result;
1202 }
1203
1204 /****************************************************************************
1205  main work for updating the lpq cahe for a printer queue
1206 ****************************************************************************/
1207
1208 static void print_queue_update_internal( const char *sharename,
1209                                          struct printif *current_printif,
1210                                          char *lpq_command, char *lprm_command )
1211 {
1212         int i, qcount;
1213         print_queue_struct *queue = NULL;
1214         print_status_struct status;
1215         print_status_struct old_status;
1216         struct printjob *pjob;
1217         struct traverse_struct tstruct;
1218         TDB_DATA data, key;
1219         TDB_DATA jcdata;
1220         fstring keystr, cachestr;
1221         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1222
1223         if (!pdb) {
1224                 return;
1225         }
1226
1227         DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
1228                 sharename, current_printif->type, lpq_command));
1229
1230         /*
1231          * Update the cache time FIRST ! Stops others even
1232          * attempting to get the lock and doing this
1233          * if the lpq takes a long time.
1234          */
1235
1236         slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
1237         tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
1238
1239         /* get the current queue using the appropriate interface */
1240         ZERO_STRUCT(status);
1241
1242         qcount = (*(current_printif->queue_get))(sharename,
1243                 current_printif->type,
1244                 lpq_command, &queue, &status);
1245
1246         DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
1247                 qcount, (qcount != 1) ? "s" : "", sharename));
1248
1249         /* Sort the queue by submission time otherwise they are displayed
1250            in hash order. */
1251
1252         TYPESAFE_QSORT(queue, qcount, printjob_comp);
1253
1254         /*
1255           any job in the internal database that is marked as spooled
1256           and doesn't exist in the system queue is considered finished
1257           and removed from the database
1258
1259           any job in the system database but not in the internal database
1260           is added as a unix job
1261
1262           fill in any system job numbers as we go
1263         */
1264
1265         jcdata = get_jobs_changed_data(pdb);
1266
1267         for (i=0; i<qcount; i++) {
1268                 uint32 jobid = print_parse_jobid(queue[i].fs_file);
1269
1270                 if (jobid == (uint32)-1) {
1271                         /* assume its a unix print job */
1272                         print_unix_job(sharename, &queue[i], jobid);
1273                         continue;
1274                 }
1275
1276                 /* we have an active SMB print job - update its status */
1277                 pjob = print_job_find(sharename, jobid);
1278                 if (!pjob) {
1279                         /* err, somethings wrong. Probably smbd was restarted
1280                            with jobs in the queue. All we can do is treat them
1281                            like unix jobs. Pity. */
1282                         print_unix_job(sharename, &queue[i], jobid);
1283                         continue;
1284                 }
1285
1286                 pjob->sysjob = queue[i].job;
1287
1288                 /* don't reset the status on jobs to be deleted */
1289
1290                 if ( pjob->status != LPQ_DELETING )
1291                         pjob->status = queue[i].status;
1292
1293                 pjob_store(server_event_context(), server_messaging_context(),
1294                            sharename, jobid, pjob);
1295
1296                 check_job_changed(sharename, jcdata, jobid);
1297         }
1298
1299         SAFE_FREE(jcdata.dptr);
1300
1301         /* now delete any queued entries that don't appear in the
1302            system queue */
1303         tstruct.queue = queue;
1304         tstruct.qcount = qcount;
1305         tstruct.snum = -1;
1306         tstruct.total_jobs = 0;
1307         tstruct.lpq_time = time(NULL);
1308         tstruct.sharename = sharename;
1309         tstruct.lprm_command = lprm_command;
1310         tstruct.print_if = current_printif;
1311
1312         tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
1313
1314         /* Store the linearised queue, max jobs only. */
1315         store_queue_struct(pdb, &tstruct);
1316
1317         SAFE_FREE(tstruct.queue);
1318
1319         DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
1320                                 sharename, tstruct.total_jobs ));
1321
1322         tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
1323
1324         get_queue_status(sharename, &old_status);
1325         if (old_status.qcount != qcount)
1326                 DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
1327                                         old_status.qcount, qcount, sharename));
1328
1329         /* store the new queue status structure */
1330         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
1331         key = string_tdb_data(keystr);
1332
1333         status.qcount = qcount;
1334         data.dptr = (uint8 *)&status;
1335         data.dsize = sizeof(status);
1336         tdb_store(pdb->tdb, key, data, TDB_REPLACE);
1337
1338         /*
1339          * Update the cache time again. We want to do this call
1340          * as little as possible...
1341          */
1342
1343         slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
1344         tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
1345
1346         /* clear the msg pending record for this queue */
1347
1348         snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
1349
1350         if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
1351                 /* log a message but continue on */
1352
1353                 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1354                         sharename));
1355         }
1356
1357         release_print_db( pdb );
1358
1359         return;
1360 }
1361
1362 /****************************************************************************
1363  Update the internal database from the system print queue for a queue.
1364  obtain a lock on the print queue before proceeding (needed when mutiple
1365  smbd processes maytry to update the lpq cache concurrently).
1366 ****************************************************************************/
1367
1368 static void print_queue_update_with_lock( const char *sharename,
1369                                           struct printif *current_printif,
1370                                           char *lpq_command, char *lprm_command )
1371 {
1372         fstring keystr;
1373         struct tdb_print_db *pdb;
1374
1375         DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
1376         pdb = get_print_db_byname(sharename);
1377         if (!pdb)
1378                 return;
1379
1380         if ( !print_cache_expired(sharename, False) ) {
1381                 DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
1382                 release_print_db(pdb);
1383                 return;
1384         }
1385
1386         /*
1387          * Check to see if someone else is doing this update.
1388          * This is essentially a mutex on the update.
1389          */
1390
1391         if (get_updating_pid(sharename) != -1) {
1392                 release_print_db(pdb);
1393                 return;
1394         }
1395
1396         /* Lock the queue for the database update */
1397
1398         slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
1399         /* Only wait 10 seconds for this. */
1400         if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
1401                 DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
1402                 release_print_db(pdb);
1403                 return;
1404         }
1405
1406         /*
1407          * Ensure that no one else got in here.
1408          * If the updating pid is still -1 then we are
1409          * the winner.
1410          */
1411
1412         if (get_updating_pid(sharename) != -1) {
1413                 /*
1414                  * Someone else is doing the update, exit.
1415                  */
1416                 tdb_unlock_bystring(pdb->tdb, keystr);
1417                 release_print_db(pdb);
1418                 return;
1419         }
1420
1421         /*
1422          * We're going to do the update ourselves.
1423          */
1424
1425         /* Tell others we're doing the update. */
1426         set_updating_pid(sharename, True);
1427
1428         /*
1429          * Allow others to enter and notice we're doing
1430          * the update.
1431          */
1432
1433         tdb_unlock_bystring(pdb->tdb, keystr);
1434
1435         /* do the main work now */
1436
1437         print_queue_update_internal( sharename, current_printif,
1438                 lpq_command, lprm_command );
1439
1440         /* Delete our pid from the db. */
1441         set_updating_pid(sharename, False);
1442         release_print_db(pdb);
1443 }
1444
1445 /****************************************************************************
1446 this is the receive function of the background lpq updater
1447 ****************************************************************************/
1448 static void print_queue_receive(struct messaging_context *msg,
1449                                 void *private_data,
1450                                 uint32_t msg_type,
1451                                 struct server_id server_id,
1452                                 DATA_BLOB *data)
1453 {
1454         fstring sharename;
1455         char *lpqcommand = NULL, *lprmcommand = NULL;
1456         int printing_type;
1457         size_t len;
1458
1459         len = tdb_unpack( (uint8 *)data->data, data->length, "fdPP",
1460                 sharename,
1461                 &printing_type,
1462                 &lpqcommand,
1463                 &lprmcommand );
1464
1465         if ( len == -1 ) {
1466                 SAFE_FREE(lpqcommand);
1467                 SAFE_FREE(lprmcommand);
1468                 DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
1469                 return;
1470         }
1471
1472         print_queue_update_with_lock(sharename,
1473                 get_printer_fns_from_type((enum printing_types)printing_type),
1474                 lpqcommand, lprmcommand );
1475
1476         SAFE_FREE(lpqcommand);
1477         SAFE_FREE(lprmcommand);
1478         return;
1479 }
1480
1481 static void printing_pause_fd_handler(struct tevent_context *ev,
1482                                       struct tevent_fd *fde,
1483                                       uint16_t flags,
1484                                       void *private_data)
1485 {
1486         /*
1487          * If pause_pipe[1] is closed it means the parent smbd
1488          * and children exited or aborted.
1489          */
1490         exit_server_cleanly(NULL);
1491 }
1492
1493 extern struct child_pid *children;
1494 extern int num_children;
1495
1496 static void add_child_pid(pid_t pid)
1497 {
1498         struct child_pid *child;
1499
1500         child = SMB_MALLOC_P(struct child_pid);
1501         if (child == NULL) {
1502                 DEBUG(0, ("Could not add child struct -- malloc failed\n"));
1503                 return;
1504         }
1505         child->pid = pid;
1506         DLIST_ADD(children, child);
1507         num_children += 1;
1508 }
1509
1510 static pid_t background_lpq_updater_pid = -1;
1511
1512 /****************************************************************************
1513 main thread of the background lpq updater
1514 ****************************************************************************/
1515 void start_background_queue(struct tevent_context *ev,
1516                             struct messaging_context *msg_ctx)
1517 {
1518         /* Use local variables for this as we don't
1519          * need to save the parent side of this, just
1520          * ensure it closes when the process exits.
1521          */
1522         int pause_pipe[2];
1523
1524         DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
1525
1526         if (pipe(pause_pipe) == -1) {
1527                 DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno) ));
1528                 exit(1);
1529         }
1530
1531         background_lpq_updater_pid = sys_fork();
1532
1533         if (background_lpq_updater_pid == -1) {
1534                 DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
1535                 exit(1);
1536         }
1537
1538         /* Track the printing pid along with other smbd children */
1539         add_child_pid(background_lpq_updater_pid);
1540
1541         if(background_lpq_updater_pid == 0) {
1542                 struct tevent_fd *fde;
1543                 int ret;
1544                 NTSTATUS status;
1545
1546                 /* Child. */
1547                 DEBUG(5,("start_background_queue: background LPQ thread started\n"));
1548
1549                 close(pause_pipe[0]);
1550                 pause_pipe[0] = -1;
1551
1552                 status = reinit_after_fork(msg_ctx, ev, procid_self(), true);
1553
1554                 if (!NT_STATUS_IS_OK(status)) {
1555                         DEBUG(0,("reinit_after_fork() failed\n"));
1556                         smb_panic("reinit_after_fork() failed");
1557                 }
1558
1559                 smbd_setup_sig_term_handler();
1560                 smbd_setup_sig_hup_handler(ev, msg_ctx);
1561
1562                 if (!serverid_register(procid_self(),
1563                                        FLAG_MSG_GENERAL|FLAG_MSG_SMBD
1564                                        |FLAG_MSG_PRINT_GENERAL)) {
1565                         exit(1);
1566                 }
1567
1568                 if (!locking_init()) {
1569                         exit(1);
1570                 }
1571
1572                 messaging_register(msg_ctx, NULL, MSG_PRINTER_UPDATE,
1573                                    print_queue_receive);
1574
1575                 fde = tevent_add_fd(ev, ev, pause_pipe[1], TEVENT_FD_READ,
1576                                     printing_pause_fd_handler,
1577                                     NULL);
1578                 if (!fde) {
1579                         DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
1580                         smb_panic("tevent_add_fd() failed for pause_pipe");
1581                 }
1582
1583                 DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
1584                 ret = tevent_loop_wait(ev);
1585                 /* should not be reached */
1586                 DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
1587                          ret, (ret == 0) ? "out of events" : strerror(errno)));
1588                 exit(1);
1589         }
1590
1591         close(pause_pipe[1]);
1592 }
1593
1594 /****************************************************************************
1595 update the internal database from the system print queue for a queue
1596 ****************************************************************************/
1597
1598 static void print_queue_update(struct messaging_context *msg_ctx,
1599                                int snum, bool force)
1600 {
1601         fstring key;
1602         fstring sharename;
1603         char *lpqcommand = NULL;
1604         char *lprmcommand = NULL;
1605         uint8 *buffer = NULL;
1606         size_t len = 0;
1607         size_t newlen;
1608         struct tdb_print_db *pdb;
1609         int type;
1610         struct printif *current_printif;
1611         TALLOC_CTX *ctx = talloc_tos();
1612
1613         fstrcpy( sharename, lp_const_servicename(snum));
1614
1615         /* don't strip out characters like '$' from the printername */
1616
1617         lpqcommand = talloc_string_sub2(ctx,
1618                         lp_lpqcommand(snum),
1619                         "%p",
1620                         lp_printername(snum),
1621                         false, false, false);
1622         if (!lpqcommand) {
1623                 return;
1624         }
1625         lpqcommand = talloc_sub_advanced(ctx,
1626                         lp_servicename(snum),
1627                         current_user_info.unix_name,
1628                         "",
1629                         current_user.ut.gid,
1630                         get_current_username(),
1631                         current_user_info.domain,
1632                         lpqcommand);
1633         if (!lpqcommand) {
1634                 return;
1635         }
1636
1637         lprmcommand = talloc_string_sub2(ctx,
1638                         lp_lprmcommand(snum),
1639                         "%p",
1640                         lp_printername(snum),
1641                         false, false, false);
1642         if (!lprmcommand) {
1643                 return;
1644         }
1645         lprmcommand = talloc_sub_advanced(ctx,
1646                         lp_servicename(snum),
1647                         current_user_info.unix_name,
1648                         "",
1649                         current_user.ut.gid,
1650                         get_current_username(),
1651                         current_user_info.domain,
1652                         lprmcommand);
1653         if (!lprmcommand) {
1654                 return;
1655         }
1656
1657         /*
1658          * Make sure that the background queue process exists.
1659          * Otherwise just do the update ourselves
1660          */
1661
1662         if ( force || background_lpq_updater_pid == -1 ) {
1663                 DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
1664                 current_printif = get_printer_fns( snum );
1665                 print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand );
1666
1667                 return;
1668         }
1669
1670         type = lp_printing(snum);
1671
1672         /* get the length */
1673
1674         len = tdb_pack( NULL, 0, "fdPP",
1675                 sharename,
1676                 type,
1677                 lpqcommand,
1678                 lprmcommand );
1679
1680         buffer = SMB_XMALLOC_ARRAY( uint8, len );
1681
1682         /* now pack the buffer */
1683         newlen = tdb_pack( buffer, len, "fdPP",
1684                 sharename,
1685                 type,
1686                 lpqcommand,
1687                 lprmcommand );
1688
1689         SMB_ASSERT( newlen == len );
1690
1691         DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
1692                 "type = %d, lpq command = [%s] lprm command = [%s]\n",
1693                 sharename, type, lpqcommand, lprmcommand ));
1694
1695         /* here we set a msg pending record for other smbd processes
1696            to throttle the number of duplicate print_queue_update msgs
1697            sent.  */
1698
1699         pdb = get_print_db_byname(sharename);
1700         if (!pdb) {
1701                 SAFE_FREE(buffer);
1702                 return;
1703         }
1704
1705         snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
1706
1707         if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
1708                 /* log a message but continue on */
1709
1710                 DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
1711                         sharename));
1712         }
1713
1714         release_print_db( pdb );
1715
1716         /* finally send the message */
1717
1718         messaging_send_buf(msg_ctx, pid_to_procid(background_lpq_updater_pid),
1719                            MSG_PRINTER_UPDATE, (uint8 *)buffer, len);
1720
1721         SAFE_FREE( buffer );
1722
1723         return;
1724 }
1725
1726 /****************************************************************************
1727  Create/Update an entry in the print tdb that will allow us to send notify
1728  updates only to interested smbd's.
1729 ****************************************************************************/
1730
1731 bool print_notify_register_pid(int snum)
1732 {
1733         TDB_DATA data;
1734         struct tdb_print_db *pdb = NULL;
1735         TDB_CONTEXT *tdb = NULL;
1736         const char *printername;
1737         uint32 mypid = (uint32)sys_getpid();
1738         bool ret = False;
1739         size_t i;
1740
1741         /* if (snum == -1), then the change notify request was
1742            on a print server handle and we need to register on
1743            all print queus */
1744
1745         if (snum == -1)
1746         {
1747                 int num_services = lp_numservices();
1748                 int idx;
1749
1750                 for ( idx=0; idx<num_services; idx++ ) {
1751                         if (lp_snum_ok(idx) && lp_print_ok(idx) )
1752                                 print_notify_register_pid(idx);
1753                 }
1754
1755                 return True;
1756         }
1757         else /* register for a specific printer */
1758         {
1759                 printername = lp_const_servicename(snum);
1760                 pdb = get_print_db_byname(printername);
1761                 if (!pdb)
1762                         return False;
1763                 tdb = pdb->tdb;
1764         }
1765
1766         if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1767                 DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
1768                                         printername));
1769                 if (pdb)
1770                         release_print_db(pdb);
1771                 return False;
1772         }
1773
1774         data = get_printer_notify_pid_list( tdb, printername, True );
1775
1776         /* Add ourselves and increase the refcount. */
1777
1778         for (i = 0; i < data.dsize; i += 8) {
1779                 if (IVAL(data.dptr,i) == mypid) {
1780                         uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
1781                         SIVAL(data.dptr, i+4, new_refcount);
1782                         break;
1783                 }
1784         }
1785
1786         if (i == data.dsize) {
1787                 /* We weren't in the list. Realloc. */
1788                 data.dptr = (uint8 *)SMB_REALLOC(data.dptr, data.dsize + 8);
1789                 if (!data.dptr) {
1790                         DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
1791                                                 printername));
1792                         goto done;
1793                 }
1794                 data.dsize += 8;
1795                 SIVAL(data.dptr,data.dsize - 8,mypid);
1796                 SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
1797         }
1798
1799         /* Store back the record. */
1800         if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1801                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1802 list for printer %s\n", printername));
1803                 goto done;
1804         }
1805
1806         ret = True;
1807
1808  done:
1809
1810         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1811         if (pdb)
1812                 release_print_db(pdb);
1813         SAFE_FREE(data.dptr);
1814         return ret;
1815 }
1816
1817 /****************************************************************************
1818  Update an entry in the print tdb that will allow us to send notify
1819  updates only to interested smbd's.
1820 ****************************************************************************/
1821
1822 bool print_notify_deregister_pid(int snum)
1823 {
1824         TDB_DATA data;
1825         struct tdb_print_db *pdb = NULL;
1826         TDB_CONTEXT *tdb = NULL;
1827         const char *printername;
1828         uint32 mypid = (uint32)sys_getpid();
1829         size_t i;
1830         bool ret = False;
1831
1832         /* if ( snum == -1 ), we are deregister a print server handle
1833            which means to deregister on all print queues */
1834
1835         if (snum == -1)
1836         {
1837                 int num_services = lp_numservices();
1838                 int idx;
1839
1840                 for ( idx=0; idx<num_services; idx++ ) {
1841                         if ( lp_snum_ok(idx) && lp_print_ok(idx) )
1842                                 print_notify_deregister_pid(idx);
1843                 }
1844
1845                 return True;
1846         }
1847         else /* deregister a specific printer */
1848         {
1849                 printername = lp_const_servicename(snum);
1850                 pdb = get_print_db_byname(printername);
1851                 if (!pdb)
1852                         return False;
1853                 tdb = pdb->tdb;
1854         }
1855
1856         if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
1857                 DEBUG(0,("print_notify_register_pid: Failed to lock \
1858 printer %s database\n", printername));
1859                 if (pdb)
1860                         release_print_db(pdb);
1861                 return False;
1862         }
1863
1864         data = get_printer_notify_pid_list( tdb, printername, True );
1865
1866         /* Reduce refcount. Remove ourselves if zero. */
1867
1868         for (i = 0; i < data.dsize; ) {
1869                 if (IVAL(data.dptr,i) == mypid) {
1870                         uint32 refcount = IVAL(data.dptr, i+4);
1871
1872                         refcount--;
1873
1874                         if (refcount == 0) {
1875                                 if (data.dsize - i > 8)
1876                                         memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
1877                                 data.dsize -= 8;
1878                                 continue;
1879                         }
1880                         SIVAL(data.dptr, i+4, refcount);
1881                 }
1882
1883                 i += 8;
1884         }
1885
1886         if (data.dsize == 0)
1887                 SAFE_FREE(data.dptr);
1888
1889         /* Store back the record. */
1890         if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
1891                 DEBUG(0,("print_notify_register_pid: Failed to update pid \
1892 list for printer %s\n", printername));
1893                 goto done;
1894         }
1895
1896         ret = True;
1897
1898   done:
1899
1900         tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
1901         if (pdb)
1902                 release_print_db(pdb);
1903         SAFE_FREE(data.dptr);
1904         return ret;
1905 }
1906
1907 /****************************************************************************
1908  Check if a jobid is valid. It is valid if it exists in the database.
1909 ****************************************************************************/
1910
1911 bool print_job_exists(const char* sharename, uint32 jobid)
1912 {
1913         struct tdb_print_db *pdb = get_print_db_byname(sharename);
1914         bool ret;
1915         uint32_t tmp;
1916
1917         if (!pdb)
1918                 return False;
1919         ret = tdb_exists(pdb->tdb, print_key(jobid, &tmp));
1920         release_print_db(pdb);
1921         return ret;
1922 }
1923
1924 /****************************************************************************
1925  Give the filename used for a jobid.
1926  Only valid for the process doing the spooling and when the job
1927  has not been spooled.
1928 ****************************************************************************/
1929
1930 char *print_job_fname(const char* sharename, uint32 jobid)
1931 {
1932         struct printjob *pjob = print_job_find(sharename, jobid);
1933         if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
1934                 return NULL;
1935         return pjob->filename;
1936 }
1937
1938
1939 /****************************************************************************
1940  Give the filename used for a jobid.
1941  Only valid for the process doing the spooling and when the job
1942  has not been spooled.
1943 ****************************************************************************/
1944
1945 struct spoolss_DeviceMode *print_job_devmode(const char* sharename, uint32 jobid)
1946 {
1947         struct printjob *pjob = print_job_find(sharename, jobid);
1948
1949         if ( !pjob )
1950                 return NULL;
1951
1952         return pjob->devmode;
1953 }
1954
1955 /****************************************************************************
1956  Set the name of a job. Only possible for owner.
1957 ****************************************************************************/
1958
1959 bool print_job_set_name(const char *sharename, uint32 jobid, const char *name)
1960 {
1961         struct printjob *pjob;
1962
1963         pjob = print_job_find(sharename, jobid);
1964         if (!pjob || pjob->pid != sys_getpid())
1965                 return False;
1966
1967         fstrcpy(pjob->jobname, name);
1968         return pjob_store(server_event_context(), server_messaging_context(),
1969                           sharename, jobid, pjob);
1970 }
1971
1972 /****************************************************************************
1973  Get the name of a job. Only possible for owner.
1974 ****************************************************************************/
1975
1976 bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t jobid, char **name)
1977 {
1978         struct printjob *pjob;
1979
1980         pjob = print_job_find(sharename, jobid);
1981         if (!pjob || pjob->pid != sys_getpid()) {
1982                 return false;
1983         }
1984
1985         *name = talloc_strdup(mem_ctx, pjob->jobname);
1986         if (!*name) {
1987                 return false;
1988         }
1989
1990         return true;
1991 }
1992
1993
1994 /***************************************************************************
1995  Remove a jobid from the 'jobs changed' list.
1996 ***************************************************************************/
1997
1998 static bool remove_from_jobs_changed(const char* sharename, uint32 jobid)
1999 {
2000         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2001         TDB_DATA data, key;
2002         size_t job_count, i;
2003         bool ret = False;
2004         bool gotlock = False;
2005
2006         if (!pdb) {
2007                 return False;
2008         }
2009
2010         ZERO_STRUCT(data);
2011
2012         key = string_tdb_data("INFO/jobs_changed");
2013
2014         if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
2015                 goto out;
2016
2017         gotlock = True;
2018
2019         data = tdb_fetch(pdb->tdb, key);
2020
2021         if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
2022                 goto out;
2023
2024         job_count = data.dsize / 4;
2025         for (i = 0; i < job_count; i++) {
2026                 uint32 ch_jobid;
2027
2028                 ch_jobid = IVAL(data.dptr, i*4);
2029                 if (ch_jobid == jobid) {
2030                         if (i < job_count -1 )
2031                                 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
2032                         data.dsize -= 4;
2033                         if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
2034                                 goto out;
2035                         break;
2036                 }
2037         }
2038
2039         ret = True;
2040   out:
2041
2042         if (gotlock)
2043                 tdb_chainunlock(pdb->tdb, key);
2044         SAFE_FREE(data.dptr);
2045         release_print_db(pdb);
2046         if (ret)
2047                 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
2048         else
2049                 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
2050         return ret;
2051 }
2052
2053 /****************************************************************************
2054  Delete a print job - don't update queue.
2055 ****************************************************************************/
2056
2057 static bool print_job_delete1(int snum, uint32 jobid)
2058 {
2059         const char* sharename = lp_const_servicename(snum);
2060         struct printjob *pjob = print_job_find(sharename, jobid);
2061         int result = 0;
2062         struct printif *current_printif = get_printer_fns( snum );
2063
2064         if (!pjob)
2065                 return False;
2066
2067         /*
2068          * If already deleting just return.
2069          */
2070
2071         if (pjob->status == LPQ_DELETING)
2072                 return True;
2073
2074         /* Hrm - we need to be able to cope with deleting a job before it
2075            has reached the spooler.  Just mark it as LPQ_DELETING and
2076            let the print_queue_update() code rmeove the record */
2077
2078
2079         if (pjob->sysjob == -1) {
2080                 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
2081         }
2082
2083         /* Set the tdb entry to be deleting. */
2084
2085         pjob->status = LPQ_DELETING;
2086         pjob_store(server_event_context(), server_messaging_context(),
2087                    sharename, jobid, pjob);
2088
2089         if (pjob->spooled && pjob->sysjob != -1)
2090         {
2091                 result = (*(current_printif->job_delete))(
2092                         lp_printername(snum),
2093                         lp_lprmcommand(snum),
2094                         pjob);
2095
2096                 /* Delete the tdb entry if the delete succeeded or the job hasn't
2097                    been spooled. */
2098
2099                 if (result == 0) {
2100                         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2101                         int njobs = 1;
2102
2103                         if (!pdb)
2104                                 return False;
2105                         pjob_delete(sharename, jobid);
2106                         /* Ensure we keep a rough count of the number of total jobs... */
2107                         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
2108                         release_print_db(pdb);
2109                 }
2110         }
2111
2112         remove_from_jobs_changed( sharename, jobid );
2113
2114         return (result == 0);
2115 }
2116
2117 /****************************************************************************
2118  Return true if the current user owns the print job.
2119 ****************************************************************************/
2120
2121 static bool is_owner(struct auth_serversupplied_info *server_info,
2122                      const char *servicename,
2123                      uint32 jobid)
2124 {
2125         struct printjob *pjob = print_job_find(servicename, jobid);
2126
2127         if (!pjob || !server_info)
2128                 return False;
2129
2130         return strequal(pjob->user, server_info->sanitized_username);
2131 }
2132
2133 /****************************************************************************
2134  Delete a print job.
2135 ****************************************************************************/
2136
2137 WERROR print_job_delete(struct auth_serversupplied_info *server_info,
2138                         struct messaging_context *msg_ctx,
2139                         int snum, uint32_t jobid)
2140 {
2141         const char* sharename = lp_const_servicename(snum);
2142         struct printjob *pjob;
2143         bool    owner;
2144         char    *fname;
2145
2146         owner = is_owner(server_info, lp_const_servicename(snum), jobid);
2147
2148         /* Check access against security descriptor or whether the user
2149            owns their job. */
2150
2151         if (!owner &&
2152             !print_access_check(server_info, msg_ctx, snum,
2153                                 JOB_ACCESS_ADMINISTER)) {
2154                 DEBUG(3, ("delete denied by security descriptor\n"));
2155
2156                 /* BEGIN_ADMIN_LOG */
2157                 sys_adminlog( LOG_ERR,
2158                               "Permission denied-- user not allowed to delete, \
2159 pause, or resume print job. User name: %s. Printer name: %s.",
2160                               uidtoname(server_info->utok.uid),
2161                               lp_printername(snum) );
2162                 /* END_ADMIN_LOG */
2163
2164                 return WERR_ACCESS_DENIED;
2165         }
2166
2167         /*
2168          * get the spooled filename of the print job
2169          * if this works, then the file has not been spooled
2170          * to the underlying print system.  Just delete the
2171          * spool file & return.
2172          */
2173
2174         fname = print_job_fname(sharename, jobid);
2175         if (fname != NULL) {
2176                 /* remove the spool file */
2177                 DEBUG(10, ("print_job_delete: "
2178                            "Removing spool file [%s]\n", fname));
2179                 if (unlink(fname) == -1) {
2180                         return map_werror_from_unix(errno);
2181                 }
2182         }
2183
2184         if (!print_job_delete1(snum, jobid)) {
2185                 return WERR_ACCESS_DENIED;
2186         }
2187
2188         /* force update the database and say the delete failed if the
2189            job still exists */
2190
2191         print_queue_update(msg_ctx, snum, True);
2192
2193         pjob = print_job_find(sharename, jobid);
2194         if (pjob && (pjob->status != LPQ_DELETING)) {
2195                 return WERR_ACCESS_DENIED;
2196         }
2197
2198         return WERR_PRINTER_HAS_JOBS_QUEUED;
2199 }
2200
2201 /****************************************************************************
2202  Pause a job.
2203 ****************************************************************************/
2204
2205 bool print_job_pause(struct auth_serversupplied_info *server_info,
2206                      struct messaging_context *msg_ctx,
2207                      int snum, uint32 jobid, WERROR *errcode)
2208 {
2209         const char* sharename = lp_const_servicename(snum);
2210         struct printjob *pjob;
2211         int ret = -1;
2212         struct printif *current_printif = get_printer_fns( snum );
2213
2214         pjob = print_job_find(sharename, jobid);
2215
2216         if (!pjob || !server_info) {
2217                 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2218                         (unsigned int)jobid ));
2219                 return False;
2220         }
2221
2222         if (!pjob->spooled || pjob->sysjob == -1) {
2223                 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2224                         (int)pjob->sysjob, (unsigned int)jobid ));
2225                 return False;
2226         }
2227
2228         if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2229             !print_access_check(server_info, msg_ctx, snum,
2230                                 JOB_ACCESS_ADMINISTER)) {
2231                 DEBUG(3, ("pause denied by security descriptor\n"));
2232
2233                 /* BEGIN_ADMIN_LOG */
2234                 sys_adminlog( LOG_ERR,
2235                         "Permission denied-- user not allowed to delete, \
2236 pause, or resume print job. User name: %s. Printer name: %s.",
2237                               uidtoname(server_info->utok.uid),
2238                               lp_printername(snum) );
2239                 /* END_ADMIN_LOG */
2240
2241                 *errcode = WERR_ACCESS_DENIED;
2242                 return False;
2243         }
2244
2245         /* need to pause the spooled entry */
2246         ret = (*(current_printif->job_pause))(snum, pjob);
2247
2248         if (ret != 0) {
2249                 *errcode = WERR_INVALID_PARAM;
2250                 return False;
2251         }
2252
2253         /* force update the database */
2254         print_cache_flush(lp_const_servicename(snum));
2255
2256         /* Send a printer notify message */
2257
2258         notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2259                           JOB_STATUS_PAUSED);
2260
2261         /* how do we tell if this succeeded? */
2262
2263         return True;
2264 }
2265
2266 /****************************************************************************
2267  Resume a job.
2268 ****************************************************************************/
2269
2270 bool print_job_resume(struct auth_serversupplied_info *server_info,
2271                       struct messaging_context *msg_ctx,
2272                       int snum, uint32 jobid, WERROR *errcode)
2273 {
2274         const char *sharename = lp_const_servicename(snum);
2275         struct printjob *pjob;
2276         int ret;
2277         struct printif *current_printif = get_printer_fns( snum );
2278
2279         pjob = print_job_find(sharename, jobid);
2280
2281         if (!pjob || !server_info) {
2282                 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2283                         (unsigned int)jobid ));
2284                 return False;
2285         }
2286
2287         if (!pjob->spooled || pjob->sysjob == -1) {
2288                 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2289                         (int)pjob->sysjob, (unsigned int)jobid ));
2290                 return False;
2291         }
2292
2293         if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2294             !print_access_check(server_info, msg_ctx, snum,
2295                                 JOB_ACCESS_ADMINISTER)) {
2296                 DEBUG(3, ("resume denied by security descriptor\n"));
2297                 *errcode = WERR_ACCESS_DENIED;
2298
2299                 /* BEGIN_ADMIN_LOG */
2300                 sys_adminlog( LOG_ERR,
2301                          "Permission denied-- user not allowed to delete, \
2302 pause, or resume print job. User name: %s. Printer name: %s.",
2303                               uidtoname(server_info->utok.uid),
2304                               lp_printername(snum) );
2305                 /* END_ADMIN_LOG */
2306                 return False;
2307         }
2308
2309         ret = (*(current_printif->job_resume))(snum, pjob);
2310
2311         if (ret != 0) {
2312                 *errcode = WERR_INVALID_PARAM;
2313                 return False;
2314         }
2315
2316         /* force update the database */
2317         print_cache_flush(lp_const_servicename(snum));
2318
2319         /* Send a printer notify message */
2320
2321         notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2322                           JOB_STATUS_QUEUED);
2323
2324         return True;
2325 }
2326
2327 /****************************************************************************
2328  Write to a print file.
2329 ****************************************************************************/
2330
2331 ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size)
2332 {
2333         const char* sharename = lp_const_servicename(snum);
2334         ssize_t return_code;
2335         struct printjob *pjob;
2336
2337         pjob = print_job_find(sharename, jobid);
2338
2339         if (!pjob)
2340                 return -1;
2341         /* don't allow another process to get this info - it is meaningless */
2342         if (pjob->pid != sys_getpid())
2343                 return -1;
2344
2345         /* if SMBD is spooling this can't be allowed */
2346         if (pjob->status == PJOB_SMBD_SPOOLING) {
2347                 return -1;
2348         }
2349
2350         return_code = write_data_at_offset(pjob->fd, buf, size, pos);
2351
2352         if (return_code>0) {
2353                 pjob->size += size;
2354                 pjob_store(server_event_context(), server_messaging_context(),
2355                            sharename, jobid, pjob);
2356         }
2357         return return_code;
2358 }
2359
2360 /****************************************************************************
2361  Get the queue status - do not update if db is out of date.
2362 ****************************************************************************/
2363
2364 static int get_queue_status(const char* sharename, print_status_struct *status)
2365 {
2366         fstring keystr;
2367         TDB_DATA data;
2368         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2369         int len;
2370
2371         if (status) {
2372                 ZERO_STRUCTP(status);
2373         }
2374
2375         if (!pdb)
2376                 return 0;
2377
2378         if (status) {
2379                 fstr_sprintf(keystr, "STATUS/%s", sharename);
2380                 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2381                 if (data.dptr) {
2382                         if (data.dsize == sizeof(print_status_struct))
2383                                 /* this memcpy is ok since the status struct was
2384                                    not packed before storing it in the tdb */
2385                                 memcpy(status, data.dptr, sizeof(print_status_struct));
2386                         SAFE_FREE(data.dptr);
2387                 }
2388         }
2389         len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2390         release_print_db(pdb);
2391         return (len == -1 ? 0 : len);
2392 }
2393
2394 /****************************************************************************
2395  Determine the number of jobs in a queue.
2396 ****************************************************************************/
2397
2398 int print_queue_length(struct messaging_context *msg_ctx, int snum,
2399                        print_status_struct *pstatus)
2400 {
2401         const char* sharename = lp_const_servicename( snum );
2402         print_status_struct status;
2403         int len;
2404
2405         ZERO_STRUCT( status );
2406
2407         /* make sure the database is up to date */
2408         if (print_cache_expired(lp_const_servicename(snum), True))
2409                 print_queue_update(msg_ctx, snum, False);
2410
2411         /* also fetch the queue status */
2412         memset(&status, 0, sizeof(status));
2413         len = get_queue_status(sharename, &status);
2414
2415         if (pstatus)
2416                 *pstatus = status;
2417
2418         return len;
2419 }
2420
2421 /***************************************************************************
2422  Allocate a jobid. Hold the lock for as short a time as possible.
2423 ***************************************************************************/
2424
2425 static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum,
2426                                    const char *sharename, uint32 *pjobid)
2427 {
2428         int i;
2429         uint32 jobid;
2430         enum TDB_ERROR terr;
2431         int ret;
2432
2433         *pjobid = (uint32)-1;
2434
2435         for (i = 0; i < 3; i++) {
2436                 /* Lock the database - only wait 20 seconds. */
2437                 ret = tdb_lock_bystring_with_timeout(pdb->tdb,
2438                                                      "INFO/nextjob", 20);
2439                 if (ret == -1) {
2440                         DEBUG(0, ("allocate_print_jobid: "
2441                                   "Failed to lock printing database %s\n",
2442                                   sharename));
2443                         terr = tdb_error(pdb->tdb);
2444                         return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2445                 }
2446
2447                 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2448                         terr = tdb_error(pdb->tdb);
2449                         if (terr != TDB_ERR_NOEXIST) {
2450                                 DEBUG(0, ("allocate_print_jobid: "
2451                                           "Failed to fetch INFO/nextjob "
2452                                           "for print queue %s\n", sharename));
2453                                 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2454                                 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2455                         }
2456                         DEBUG(10, ("allocate_print_jobid: "
2457                                    "No existing jobid in %s\n", sharename));
2458                         jobid = 0;
2459                 }
2460
2461                 DEBUG(10, ("allocate_print_jobid: "
2462                            "Read jobid %u from %s\n", jobid, sharename));
2463
2464                 jobid = NEXT_JOBID(jobid);
2465
2466                 ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid);
2467                 if (ret == -1) {
2468                         terr = tdb_error(pdb->tdb);
2469                         DEBUG(3, ("allocate_print_jobid: "
2470                                   "Failed to store INFO/nextjob.\n"));
2471                         tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2472                         return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2473                 }
2474
2475                 /* We've finished with the INFO/nextjob lock. */
2476                 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2477
2478                 if (!print_job_exists(sharename, jobid)) {
2479                         break;
2480                 }
2481                 DEBUG(10, ("allocate_print_jobid: "
2482                            "Found jobid %u in %s\n", jobid, sharename));
2483         }
2484
2485         if (i > 2) {
2486                 DEBUG(0, ("allocate_print_jobid: "
2487                           "Failed to allocate a print job for queue %s\n",
2488                           sharename));
2489                 /* Probably full... */
2490                 return WERR_NO_SPOOL_SPACE;
2491         }
2492
2493         /* Store a dummy placeholder. */
2494         {
2495                 uint32_t tmp;
2496                 TDB_DATA dum;
2497                 dum.dptr = NULL;
2498                 dum.dsize = 0;
2499                 if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
2500                               TDB_INSERT) == -1) {
2501                         DEBUG(3, ("allocate_print_jobid: "
2502                                   "jobid (%d) failed to store placeholder.\n",
2503                                   jobid ));
2504                         terr = tdb_error(pdb->tdb);
2505                         return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2506                 }
2507         }
2508
2509         *pjobid = jobid;
2510         return WERR_OK;
2511 }
2512
2513 /***************************************************************************
2514  Append a jobid to the 'jobs changed' list.
2515 ***************************************************************************/
2516
2517 static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
2518 {
2519         TDB_DATA data;
2520         uint32 store_jobid;
2521
2522         SIVAL(&store_jobid, 0, jobid);
2523         data.dptr = (uint8 *)&store_jobid;
2524         data.dsize = 4;
2525
2526         DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
2527
2528         return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
2529                            data) == 0);
2530 }
2531
2532
2533 /***************************************************************************
2534  Do all checks needed to determine if we can start a job.
2535 ***************************************************************************/
2536
2537 static WERROR print_job_checks(struct auth_serversupplied_info *server_info,
2538                                struct messaging_context *msg_ctx,
2539                                int snum, int *njobs)
2540 {
2541         const char *sharename = lp_const_servicename(snum);
2542         uint64_t dspace, dsize;
2543         uint64_t minspace;
2544         int ret;
2545
2546         if (!print_access_check(server_info, msg_ctx, snum,
2547                                 PRINTER_ACCESS_USE)) {
2548                 DEBUG(3, ("print_job_checks: "
2549                           "job start denied by security descriptor\n"));
2550                 return WERR_ACCESS_DENIED;
2551         }
2552
2553         if (!print_time_access_check(server_info, msg_ctx, sharename)) {
2554                 DEBUG(3, ("print_job_checks: "
2555                           "job start denied by time check\n"));
2556                 return WERR_ACCESS_DENIED;
2557         }
2558
2559         /* see if we have sufficient disk space */
2560         if (lp_minprintspace(snum)) {
2561                 minspace = lp_minprintspace(snum);
2562                 ret = sys_fsusage(lp_pathname(snum), &dspace, &dsize);
2563                 if (ret == 0 && dspace < 2*minspace) {
2564                         DEBUG(3, ("print_job_checks: "
2565                                   "disk space check failed.\n"));
2566                         return WERR_NO_SPOOL_SPACE;
2567                 }
2568         }
2569
2570         /* for autoloaded printers, check that the printcap entry still exists */
2571         if (lp_autoloaded(snum) && !pcap_printername_ok(sharename)) {
2572                 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2573                           sharename));
2574                 return WERR_ACCESS_DENIED;
2575         }
2576
2577         /* Insure the maximum queue size is not violated */
2578         *njobs = print_queue_length(msg_ctx, snum, NULL);
2579         if (*njobs > lp_maxprintjobs(snum)) {
2580                 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2581                           "larger than max printjobs per queue (%d).\n",
2582                           sharename, *njobs, lp_maxprintjobs(snum)));
2583                 return WERR_NO_SPOOL_SPACE;
2584         }
2585
2586         return WERR_OK;
2587 }
2588
2589 /***************************************************************************
2590  Create a job file.
2591 ***************************************************************************/
2592
2593 static WERROR print_job_spool_file(int snum, uint32_t jobid,
2594                                    const char *output_file,
2595                                    struct printjob *pjob)
2596 {
2597         WERROR werr;
2598         SMB_STRUCT_STAT st;
2599         const char *path;
2600         int len;
2601
2602         /* if this file is within the printer path, it means that smbd
2603          * is spooling it and will pass us control when it is finished.
2604          * Verify that the file name is ok, within path, and it is
2605          * already already there */
2606         if (output_file) {
2607                 path = lp_pathname(snum);
2608                 len = strlen(path);
2609                 if (strncmp(output_file, path, len) == 0 &&
2610                     (output_file[len - 1] == '/' || output_file[len] == '/')) {
2611
2612                         /* verify path is not too long */
2613                         if (strlen(output_file) >= sizeof(pjob->filename)) {
2614                                 return WERR_INVALID_NAME;
2615                         }
2616
2617                         /* verify that the file exists */
2618                         if (sys_stat(output_file, &st, false) != 0) {
2619                                 return WERR_INVALID_NAME;
2620                         }
2621
2622                         fstrcpy(pjob->filename, output_file);
2623
2624                         DEBUG(3, ("print_job_spool_file:"
2625                                   "External spooling activated"));
2626
2627                         /* we do not open the file until spooling is done */
2628                         pjob->fd = -1;
2629                         pjob->status = PJOB_SMBD_SPOOLING;
2630
2631                         return WERR_OK;
2632                 }
2633         }
2634
2635         slprintf(pjob->filename, sizeof(pjob->filename)-1,
2636                  "%s/%s%.8u.XXXXXX", lp_pathname(snum),
2637                  PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2638         pjob->fd = mkstemp(pjob->filename);
2639
2640         if (pjob->fd == -1) {
2641                 werr = map_werror_from_unix(errno);
2642                 if (W_ERROR_EQUAL(werr, WERR_ACCESS_DENIED)) {
2643                         /* Common setup error, force a report. */
2644                         DEBUG(0, ("print_job_spool_file: "
2645                                   "insufficient permissions to open spool "
2646                                   "file %s.\n", pjob->filename));
2647                 } else {
2648                         /* Normal case, report at level 3 and above. */
2649                         DEBUG(3, ("print_job_spool_file: "
2650                                   "can't open spool file %s\n",
2651                                   pjob->filename));
2652                 }
2653                 return werr;
2654         }
2655
2656         return WERR_OK;
2657 }
2658
2659 /***************************************************************************
2660  Start spooling a job - return the jobid.
2661 ***************************************************************************/
2662
2663 WERROR print_job_start(struct auth_serversupplied_info *server_info,
2664                        struct messaging_context *msg_ctx,
2665                        int snum, const char *docname, const char *filename,
2666                        struct spoolss_DeviceMode *devmode, uint32_t *_jobid)
2667 {
2668         uint32_t jobid;
2669         char *path;
2670         struct printjob pjob;
2671         const char *sharename = lp_const_servicename(snum);
2672         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2673         int njobs;
2674         WERROR werr;
2675
2676         if (!pdb) {
2677                 return WERR_INTERNAL_DB_CORRUPTION;
2678         }
2679
2680         path = lp_pathname(snum);
2681
2682         werr = print_job_checks(server_info, msg_ctx, snum, &njobs);
2683         if (!W_ERROR_IS_OK(werr)) {
2684                 release_print_db(pdb);
2685                 return werr;
2686         }
2687
2688         DEBUG(10, ("print_job_start: "
2689                    "Queue %s number of jobs (%d), max printjobs = %d\n",
2690                    sharename, njobs, lp_maxprintjobs(snum)));
2691
2692         werr = allocate_print_jobid(pdb, snum, sharename, &jobid);
2693         if (!W_ERROR_IS_OK(werr)) {
2694                 goto fail;
2695         }
2696
2697         /* create the database entry */
2698
2699         ZERO_STRUCT(pjob);
2700
2701         pjob.pid = sys_getpid();
2702         pjob.sysjob = -1;
2703         pjob.fd = -1;
2704         pjob.starttime = time(NULL);
2705         pjob.status = LPQ_SPOOLING;
2706         pjob.size = 0;
2707         pjob.spooled = False;
2708         pjob.smbjob = True;
2709         pjob.devmode = devmode;
2710
2711         fstrcpy(pjob.jobname, docname);
2712
2713         fstrcpy(pjob.user, lp_printjob_username(snum));
2714         standard_sub_advanced(sharename, server_info->sanitized_username,
2715                               path, server_info->utok.gid,
2716                               server_info->sanitized_username,
2717                               server_info->info3->base.domain.string,
2718                               pjob.user, sizeof(pjob.user)-1);
2719         /* ensure NULL termination */
2720         pjob.user[sizeof(pjob.user)-1] = '\0';
2721
2722         fstrcpy(pjob.queuename, lp_const_servicename(snum));
2723
2724         /* we have a job entry - now create the spool file */
2725         werr = print_job_spool_file(snum, jobid, filename, &pjob);
2726         if (!W_ERROR_IS_OK(werr)) {
2727                 goto fail;
2728         }
2729
2730         pjob_store(server_event_context(), msg_ctx, sharename, jobid, &pjob);
2731
2732         /* Update the 'jobs changed' entry used by print_queue_status. */
2733         add_to_jobs_changed(pdb, jobid);
2734
2735         /* Ensure we keep a rough count of the number of total jobs... */
2736         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2737
2738         release_print_db(pdb);
2739
2740         *_jobid = jobid;
2741         return WERR_OK;
2742
2743 fail:
2744         if (jobid != -1) {
2745                 pjob_delete(sharename, jobid);
2746         }
2747
2748         release_print_db(pdb);
2749
2750         DEBUG(3, ("print_job_start: returning fail. "
2751                   "Error = %s\n", win_errstr(werr)));
2752         return werr;
2753 }
2754
2755 /****************************************************************************
2756  Update the number of pages spooled to jobid
2757 ****************************************************************************/
2758
2759 void print_job_endpage(int snum, uint32 jobid)
2760 {
2761         const char* sharename = lp_const_servicename(snum);
2762         struct printjob *pjob;
2763
2764         pjob = print_job_find(sharename, jobid);
2765         if (!pjob)
2766                 return;
2767         /* don't allow another process to get this info - it is meaningless */
2768         if (pjob->pid != sys_getpid())
2769                 return;
2770
2771         pjob->page_count++;
2772         pjob_store(server_event_context(), server_messaging_context(),
2773                    sharename, jobid, pjob);
2774 }
2775
2776 /****************************************************************************
2777  Print a file - called on closing the file. This spools the job.
2778  If normal close is false then we're tearing down the jobs - treat as an
2779  error.
2780 ****************************************************************************/
2781
2782 NTSTATUS print_job_end(struct messaging_context *msg_ctx, int snum,
2783                        uint32 jobid, enum file_close_type close_type)
2784 {
2785         const char* sharename = lp_const_servicename(snum);
2786         struct printjob *pjob;
2787         int ret;
2788         SMB_STRUCT_STAT sbuf;
2789         struct printif *current_printif = get_printer_fns( snum );
2790         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2791
2792         pjob = print_job_find(sharename, jobid);
2793
2794         if (!pjob) {
2795                 return NT_STATUS_PRINT_CANCELLED;
2796         }
2797
2798         if (pjob->spooled || pjob->pid != sys_getpid()) {
2799                 return NT_STATUS_ACCESS_DENIED;
2800         }
2801
2802         if (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) {
2803                 if (pjob->status == PJOB_SMBD_SPOOLING) {
2804                         /* take over the file now, smbd is done */
2805                         if (sys_stat(pjob->filename, &sbuf, false) != 0) {
2806                                 status = map_nt_error_from_unix(errno);
2807                                 DEBUG(3, ("print_job_end: "
2808                                           "stat file failed for jobid %d\n",
2809                                           jobid));
2810                                 goto fail;
2811                         }
2812
2813                         pjob->status = LPQ_SPOOLING;
2814
2815                 } else {
2816
2817                         if ((sys_fstat(pjob->fd, &sbuf, false) != 0)) {
2818                                 status = map_nt_error_from_unix(errno);
2819                                 close(pjob->fd);
2820                                 DEBUG(3, ("print_job_end: "
2821                                           "stat file failed for jobid %d\n",
2822                                           jobid));
2823                                 goto fail;
2824                         }
2825
2826                         close(pjob->fd);
2827                 }
2828
2829                 pjob->size = sbuf.st_ex_size;
2830         } else {
2831
2832                 /*
2833                  * Not a normal close, something has gone wrong. Cleanup.
2834                  */
2835                 if (pjob->fd != -1) {
2836                         close(pjob->fd);
2837                 }
2838                 goto fail;
2839         }
2840
2841         /* Technically, this is not quite right. If the printer has a separator
2842          * page turned on, the NT spooler prints the separator page even if the
2843          * print job is 0 bytes. 010215 JRR */
2844         if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2845                 /* don't bother spooling empty files or something being deleted. */
2846                 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2847                         pjob->filename, pjob->size ? "deleted" : "zero length" ));
2848                 unlink(pjob->filename);
2849                 pjob_delete(sharename, jobid);
2850                 return NT_STATUS_OK;
2851         }
2852
2853         ret = (*(current_printif->job_submit))(snum, pjob);
2854
2855         if (ret) {
2856                 status = NT_STATUS_PRINT_CANCELLED;
2857                 goto fail;
2858         }
2859
2860         /* The print job has been successfully handed over to the back-end */
2861
2862         pjob->spooled = True;
2863         pjob->status = LPQ_QUEUED;
2864         pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
2865
2866         /* make sure the database is up to date */
2867         if (print_cache_expired(lp_const_servicename(snum), True))
2868                 print_queue_update(msg_ctx, snum, False);
2869
2870         return NT_STATUS_OK;
2871
2872 fail:
2873
2874         /* The print job was not successfully started. Cleanup */
2875         /* Still need to add proper error return propagation! 010122:JRR */
2876         pjob->fd = -1;
2877         unlink(pjob->filename);
2878         pjob_delete(sharename, jobid);
2879         return status;
2880 }
2881
2882 /****************************************************************************
2883  Get a snapshot of jobs in the system without traversing.
2884 ****************************************************************************/
2885
2886 static bool get_stored_queue_info(struct messaging_context *msg_ctx,
2887                                   struct tdb_print_db *pdb, int snum,
2888                                   int *pcount, print_queue_struct **ppqueue)
2889 {
2890         TDB_DATA data, cgdata;
2891         print_queue_struct *queue = NULL;
2892         uint32 qcount = 0;
2893         uint32 extra_count = 0;
2894         int total_count = 0;
2895         size_t len = 0;
2896         uint32 i;
2897         int max_reported_jobs = lp_max_reported_jobs(snum);
2898         bool ret = False;
2899         const char* sharename = lp_servicename(snum);
2900
2901         /* make sure the database is up to date */
2902         if (print_cache_expired(lp_const_servicename(snum), True))
2903                 print_queue_update(msg_ctx, snum, False);
2904
2905         *pcount = 0;
2906         *ppqueue = NULL;
2907
2908         ZERO_STRUCT(data);
2909         ZERO_STRUCT(cgdata);
2910
2911         /* Get the stored queue data. */
2912         data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
2913
2914         if (data.dptr && data.dsize >= sizeof(qcount))
2915                 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2916
2917         /* Get the changed jobs list. */
2918         cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
2919         if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2920                 extra_count = cgdata.dsize/4;
2921
2922         DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2923
2924         /* Allocate the queue size. */
2925         if (qcount == 0 && extra_count == 0)
2926                 goto out;
2927
2928         if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
2929                 goto out;
2930
2931         /* Retrieve the linearised queue data. */
2932
2933         for( i  = 0; i < qcount; i++) {
2934                 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2935                 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2936                                 &qjob,
2937                                 &qsize,
2938                                 &qpage_count,
2939                                 &qstatus,
2940                                 &qpriority,
2941                                 &qtime,
2942                                 queue[i].fs_user,
2943                                 queue[i].fs_file);
2944                 queue[i].job = qjob;
2945                 queue[i].size = qsize;
2946                 queue[i].page_count = qpage_count;
2947                 queue[i].status = qstatus;
2948                 queue[i].priority = qpriority;
2949                 queue[i].time = qtime;
2950         }
2951
2952         total_count = qcount;
2953
2954         /* Add in the changed jobids. */
2955         for( i  = 0; i < extra_count; i++) {
2956                 uint32 jobid;
2957                 struct printjob *pjob;
2958
2959                 jobid = IVAL(cgdata.dptr, i*4);
2960                 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2961                 pjob = print_job_find(lp_const_servicename(snum), jobid);
2962                 if (!pjob) {
2963                         DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2964                         remove_from_jobs_changed(sharename, jobid);
2965                         continue;
2966                 }
2967
2968                 queue[total_count].job = jobid;
2969                 queue[total_count].size = pjob->size;
2970                 queue[total_count].page_count = pjob->page_count;
2971                 queue[total_count].status = pjob->status;
2972                 queue[total_count].priority = 1;
2973                 queue[total_count].time = pjob->starttime;
2974                 fstrcpy(queue[total_count].fs_user, pjob->user);
2975                 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2976                 total_count++;
2977         }
2978
2979         /* Sort the queue by submission time otherwise they are displayed
2980            in hash order. */
2981
2982         TYPESAFE_QSORT(queue, total_count, printjob_comp);
2983
2984         DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
2985
2986         if (max_reported_jobs && total_count > max_reported_jobs)
2987                 total_count = max_reported_jobs;
2988
2989         *ppqueue = queue;
2990         *pcount = total_count;
2991
2992         ret = True;
2993
2994   out:
2995
2996         SAFE_FREE(data.dptr);
2997         SAFE_FREE(cgdata.dptr);
2998         return ret;
2999 }
3000
3001 /****************************************************************************
3002  Get a printer queue listing.
3003  set queue = NULL and status = NULL if you just want to update the cache
3004 ****************************************************************************/
3005
3006 int print_queue_status(struct messaging_context *msg_ctx, int snum,
3007                        print_queue_struct **ppqueue,
3008                        print_status_struct *status)
3009 {
3010         fstring keystr;
3011         TDB_DATA data, key;
3012         const char *sharename;
3013         struct tdb_print_db *pdb;
3014         int count = 0;
3015
3016         /* make sure the database is up to date */
3017
3018         if (print_cache_expired(lp_const_servicename(snum), True))
3019                 print_queue_update(msg_ctx, snum, False);
3020
3021         /* return if we are done */
3022         if ( !ppqueue || !status )
3023                 return 0;
3024
3025         *ppqueue = NULL;
3026         sharename = lp_const_servicename(snum);
3027         pdb = get_print_db_byname(sharename);
3028
3029         if (!pdb)
3030                 return 0;
3031
3032         /*
3033          * Fetch the queue status.  We must do this first, as there may
3034          * be no jobs in the queue.
3035          */
3036
3037         ZERO_STRUCTP(status);
3038         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
3039         key = string_tdb_data(keystr);
3040
3041         data = tdb_fetch(pdb->tdb, key);
3042         if (data.dptr) {
3043                 if (data.dsize == sizeof(*status)) {
3044                         /* this memcpy is ok since the status struct was
3045                            not packed before storing it in the tdb */
3046                         memcpy(status, data.dptr, sizeof(*status));
3047                 }
3048                 SAFE_FREE(data.dptr);
3049         }
3050
3051         /*
3052          * Now, fetch the print queue information.  We first count the number
3053          * of entries, and then only retrieve the queue if necessary.
3054          */
3055
3056         if (!get_stored_queue_info(msg_ctx, pdb, snum, &count, ppqueue)) {
3057                 release_print_db(pdb);
3058                 return 0;
3059         }
3060
3061         release_print_db(pdb);
3062         return count;
3063 }
3064
3065 /****************************************************************************
3066  Pause a queue.
3067 ****************************************************************************/
3068
3069 WERROR print_queue_pause(struct auth_serversupplied_info *server_info,
3070                          struct messaging_context *msg_ctx, int snum)
3071 {
3072         int ret;
3073         struct printif *current_printif = get_printer_fns( snum );
3074
3075         if (!print_access_check(server_info, msg_ctx, snum,
3076                                 PRINTER_ACCESS_ADMINISTER)) {
3077                 return WERR_ACCESS_DENIED;
3078         }
3079
3080
3081         become_root();
3082
3083         ret = (*(current_printif->queue_pause))(snum);
3084
3085         unbecome_root();
3086
3087         if (ret != 0) {
3088                 return WERR_INVALID_PARAM;
3089         }
3090
3091         /* force update the database */
3092         print_cache_flush(lp_const_servicename(snum));
3093
3094         /* Send a printer notify message */
3095
3096         notify_printer_status(server_event_context(), msg_ctx, snum,
3097                               PRINTER_STATUS_PAUSED);
3098
3099         return WERR_OK;
3100 }
3101
3102 /****************************************************************************
3103  Resume a queue.
3104 ****************************************************************************/
3105
3106 WERROR print_queue_resume(struct auth_serversupplied_info *server_info,
3107                           struct messaging_context *msg_ctx, int snum)
3108 {
3109         int ret;
3110         struct printif *current_printif = get_printer_fns( snum );
3111
3112         if (!print_access_check(server_info, msg_ctx, snum,
3113                                 PRINTER_ACCESS_ADMINISTER)) {
3114                 return WERR_ACCESS_DENIED;
3115         }
3116
3117         become_root();
3118
3119         ret = (*(current_printif->queue_resume))(snum);
3120
3121         unbecome_root();
3122
3123         if (ret != 0) {
3124                 return WERR_INVALID_PARAM;
3125         }
3126
3127         /* make sure the database is up to date */
3128         if (print_cache_expired(lp_const_servicename(snum), True))
3129                 print_queue_update(msg_ctx, snum, True);
3130
3131         /* Send a printer notify message */
3132
3133         notify_printer_status(server_event_context(), msg_ctx, snum,
3134                               PRINTER_STATUS_OK);
3135
3136         return WERR_OK;
3137 }
3138
3139 /****************************************************************************
3140  Purge a queue - implemented by deleting all jobs that we can delete.
3141 ****************************************************************************/
3142
3143 WERROR print_queue_purge(struct auth_serversupplied_info *server_info,
3144                          struct messaging_context *msg_ctx, int snum)
3145 {
3146         print_queue_struct *queue;
3147         print_status_struct status;
3148         int njobs, i;
3149         bool can_job_admin;
3150
3151         /* Force and update so the count is accurate (i.e. not a cached count) */
3152         print_queue_update(msg_ctx, snum, True);
3153
3154         can_job_admin = print_access_check(server_info,
3155                                            msg_ctx,
3156                                            snum,
3157                                            JOB_ACCESS_ADMINISTER);
3158         njobs = print_queue_status(msg_ctx, snum, &queue, &status);
3159
3160         if ( can_job_admin )
3161                 become_root();
3162
3163         for (i=0;i<njobs;i++) {
3164                 bool owner = is_owner(server_info, lp_const_servicename(snum),
3165                                       queue[i].job);
3166
3167                 if (owner || can_job_admin) {
3168                         print_job_delete1(snum, queue[i].job);
3169                 }
3170         }
3171
3172         if ( can_job_admin )
3173                 unbecome_root();
3174
3175         /* update the cache */
3176         print_queue_update(msg_ctx, snum, True);
3177
3178         SAFE_FREE(queue);
3179
3180         return WERR_OK;
3181 }