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