ff1394f02827c4899a37749790e2441d06a61c9e
[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(struct tevent_context *ev,
1978                         struct messaging_context *msg_ctx,
1979                         const char *sharename, uint32 jobid, const char *name)
1980 {
1981         struct printjob *pjob;
1982
1983         pjob = print_job_find(sharename, jobid);
1984         if (!pjob || pjob->pid != sys_getpid())
1985                 return False;
1986
1987         fstrcpy(pjob->jobname, name);
1988         return pjob_store(ev, msg_ctx, sharename, jobid, pjob);
1989 }
1990
1991 /****************************************************************************
1992  Get the name of a job. Only possible for owner.
1993 ****************************************************************************/
1994
1995 bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t jobid, char **name)
1996 {
1997         struct printjob *pjob;
1998
1999         pjob = print_job_find(sharename, jobid);
2000         if (!pjob || pjob->pid != sys_getpid()) {
2001                 return false;
2002         }
2003
2004         *name = talloc_strdup(mem_ctx, pjob->jobname);
2005         if (!*name) {
2006                 return false;
2007         }
2008
2009         return true;
2010 }
2011
2012
2013 /***************************************************************************
2014  Remove a jobid from the 'jobs changed' list.
2015 ***************************************************************************/
2016
2017 static bool remove_from_jobs_changed(const char* sharename, uint32 jobid)
2018 {
2019         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2020         TDB_DATA data, key;
2021         size_t job_count, i;
2022         bool ret = False;
2023         bool gotlock = False;
2024
2025         if (!pdb) {
2026                 return False;
2027         }
2028
2029         ZERO_STRUCT(data);
2030
2031         key = string_tdb_data("INFO/jobs_changed");
2032
2033         if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
2034                 goto out;
2035
2036         gotlock = True;
2037
2038         data = tdb_fetch(pdb->tdb, key);
2039
2040         if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
2041                 goto out;
2042
2043         job_count = data.dsize / 4;
2044         for (i = 0; i < job_count; i++) {
2045                 uint32 ch_jobid;
2046
2047                 ch_jobid = IVAL(data.dptr, i*4);
2048                 if (ch_jobid == jobid) {
2049                         if (i < job_count -1 )
2050                                 memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
2051                         data.dsize -= 4;
2052                         if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
2053                                 goto out;
2054                         break;
2055                 }
2056         }
2057
2058         ret = True;
2059   out:
2060
2061         if (gotlock)
2062                 tdb_chainunlock(pdb->tdb, key);
2063         SAFE_FREE(data.dptr);
2064         release_print_db(pdb);
2065         if (ret)
2066                 DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
2067         else
2068                 DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
2069         return ret;
2070 }
2071
2072 /****************************************************************************
2073  Delete a print job - don't update queue.
2074 ****************************************************************************/
2075
2076 static bool print_job_delete1(int snum, uint32 jobid)
2077 {
2078         const char* sharename = lp_const_servicename(snum);
2079         struct printjob *pjob = print_job_find(sharename, jobid);
2080         int result = 0;
2081         struct printif *current_printif = get_printer_fns( snum );
2082
2083         if (!pjob)
2084                 return False;
2085
2086         /*
2087          * If already deleting just return.
2088          */
2089
2090         if (pjob->status == LPQ_DELETING)
2091                 return True;
2092
2093         /* Hrm - we need to be able to cope with deleting a job before it
2094            has reached the spooler.  Just mark it as LPQ_DELETING and
2095            let the print_queue_update() code rmeove the record */
2096
2097
2098         if (pjob->sysjob == -1) {
2099                 DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
2100         }
2101
2102         /* Set the tdb entry to be deleting. */
2103
2104         pjob->status = LPQ_DELETING;
2105         pjob_store(server_event_context(), server_messaging_context(),
2106                    sharename, jobid, pjob);
2107
2108         if (pjob->spooled && pjob->sysjob != -1)
2109         {
2110                 result = (*(current_printif->job_delete))(
2111                         lp_printername(snum),
2112                         lp_lprmcommand(snum),
2113                         pjob);
2114
2115                 /* Delete the tdb entry if the delete succeeded or the job hasn't
2116                    been spooled. */
2117
2118                 if (result == 0) {
2119                         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2120                         int njobs = 1;
2121
2122                         if (!pdb)
2123                                 return False;
2124                         pjob_delete(server_event_context(),
2125                                     server_messaging_context(),
2126                                     sharename, jobid);
2127                         /* Ensure we keep a rough count of the number of total jobs... */
2128                         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
2129                         release_print_db(pdb);
2130                 }
2131         }
2132
2133         remove_from_jobs_changed( sharename, jobid );
2134
2135         return (result == 0);
2136 }
2137
2138 /****************************************************************************
2139  Return true if the current user owns the print job.
2140 ****************************************************************************/
2141
2142 static bool is_owner(struct auth_serversupplied_info *server_info,
2143                      const char *servicename,
2144                      uint32 jobid)
2145 {
2146         struct printjob *pjob = print_job_find(servicename, jobid);
2147
2148         if (!pjob || !server_info)
2149                 return False;
2150
2151         return strequal(pjob->user, server_info->sanitized_username);
2152 }
2153
2154 /****************************************************************************
2155  Delete a print job.
2156 ****************************************************************************/
2157
2158 WERROR print_job_delete(struct auth_serversupplied_info *server_info,
2159                         struct messaging_context *msg_ctx,
2160                         int snum, uint32_t jobid)
2161 {
2162         const char* sharename = lp_const_servicename(snum);
2163         struct printjob *pjob;
2164         bool    owner;
2165         char    *fname;
2166
2167         owner = is_owner(server_info, lp_const_servicename(snum), jobid);
2168
2169         /* Check access against security descriptor or whether the user
2170            owns their job. */
2171
2172         if (!owner &&
2173             !print_access_check(server_info, msg_ctx, snum,
2174                                 JOB_ACCESS_ADMINISTER)) {
2175                 DEBUG(3, ("delete denied by security descriptor\n"));
2176
2177                 /* BEGIN_ADMIN_LOG */
2178                 sys_adminlog( LOG_ERR,
2179                               "Permission denied-- user not allowed to delete, \
2180 pause, or resume print job. User name: %s. Printer name: %s.",
2181                               uidtoname(server_info->utok.uid),
2182                               lp_printername(snum) );
2183                 /* END_ADMIN_LOG */
2184
2185                 return WERR_ACCESS_DENIED;
2186         }
2187
2188         /*
2189          * get the spooled filename of the print job
2190          * if this works, then the file has not been spooled
2191          * to the underlying print system.  Just delete the
2192          * spool file & return.
2193          */
2194
2195         fname = print_job_fname(sharename, jobid);
2196         if (fname != NULL) {
2197                 /* remove the spool file */
2198                 DEBUG(10, ("print_job_delete: "
2199                            "Removing spool file [%s]\n", fname));
2200                 if (unlink(fname) == -1) {
2201                         return map_werror_from_unix(errno);
2202                 }
2203         }
2204
2205         if (!print_job_delete1(snum, jobid)) {
2206                 return WERR_ACCESS_DENIED;
2207         }
2208
2209         /* force update the database and say the delete failed if the
2210            job still exists */
2211
2212         print_queue_update(msg_ctx, snum, True);
2213
2214         pjob = print_job_find(sharename, jobid);
2215         if (pjob && (pjob->status != LPQ_DELETING)) {
2216                 return WERR_ACCESS_DENIED;
2217         }
2218
2219         return WERR_PRINTER_HAS_JOBS_QUEUED;
2220 }
2221
2222 /****************************************************************************
2223  Pause a job.
2224 ****************************************************************************/
2225
2226 bool print_job_pause(struct auth_serversupplied_info *server_info,
2227                      struct messaging_context *msg_ctx,
2228                      int snum, uint32 jobid, WERROR *errcode)
2229 {
2230         const char* sharename = lp_const_servicename(snum);
2231         struct printjob *pjob;
2232         int ret = -1;
2233         struct printif *current_printif = get_printer_fns( snum );
2234
2235         pjob = print_job_find(sharename, jobid);
2236
2237         if (!pjob || !server_info) {
2238                 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2239                         (unsigned int)jobid ));
2240                 return False;
2241         }
2242
2243         if (!pjob->spooled || pjob->sysjob == -1) {
2244                 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2245                         (int)pjob->sysjob, (unsigned int)jobid ));
2246                 return False;
2247         }
2248
2249         if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2250             !print_access_check(server_info, msg_ctx, snum,
2251                                 JOB_ACCESS_ADMINISTER)) {
2252                 DEBUG(3, ("pause denied by security descriptor\n"));
2253
2254                 /* BEGIN_ADMIN_LOG */
2255                 sys_adminlog( LOG_ERR,
2256                         "Permission denied-- user not allowed to delete, \
2257 pause, or resume print job. User name: %s. Printer name: %s.",
2258                               uidtoname(server_info->utok.uid),
2259                               lp_printername(snum) );
2260                 /* END_ADMIN_LOG */
2261
2262                 *errcode = WERR_ACCESS_DENIED;
2263                 return False;
2264         }
2265
2266         /* need to pause the spooled entry */
2267         ret = (*(current_printif->job_pause))(snum, pjob);
2268
2269         if (ret != 0) {
2270                 *errcode = WERR_INVALID_PARAM;
2271                 return False;
2272         }
2273
2274         /* force update the database */
2275         print_cache_flush(lp_const_servicename(snum));
2276
2277         /* Send a printer notify message */
2278
2279         notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2280                           JOB_STATUS_PAUSED);
2281
2282         /* how do we tell if this succeeded? */
2283
2284         return True;
2285 }
2286
2287 /****************************************************************************
2288  Resume a job.
2289 ****************************************************************************/
2290
2291 bool print_job_resume(struct auth_serversupplied_info *server_info,
2292                       struct messaging_context *msg_ctx,
2293                       int snum, uint32 jobid, WERROR *errcode)
2294 {
2295         const char *sharename = lp_const_servicename(snum);
2296         struct printjob *pjob;
2297         int ret;
2298         struct printif *current_printif = get_printer_fns( snum );
2299
2300         pjob = print_job_find(sharename, jobid);
2301
2302         if (!pjob || !server_info) {
2303                 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2304                         (unsigned int)jobid ));
2305                 return False;
2306         }
2307
2308         if (!pjob->spooled || pjob->sysjob == -1) {
2309                 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2310                         (int)pjob->sysjob, (unsigned int)jobid ));
2311                 return False;
2312         }
2313
2314         if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2315             !print_access_check(server_info, msg_ctx, snum,
2316                                 JOB_ACCESS_ADMINISTER)) {
2317                 DEBUG(3, ("resume denied by security descriptor\n"));
2318                 *errcode = WERR_ACCESS_DENIED;
2319
2320                 /* BEGIN_ADMIN_LOG */
2321                 sys_adminlog( LOG_ERR,
2322                          "Permission denied-- user not allowed to delete, \
2323 pause, or resume print job. User name: %s. Printer name: %s.",
2324                               uidtoname(server_info->utok.uid),
2325                               lp_printername(snum) );
2326                 /* END_ADMIN_LOG */
2327                 return False;
2328         }
2329
2330         ret = (*(current_printif->job_resume))(snum, pjob);
2331
2332         if (ret != 0) {
2333                 *errcode = WERR_INVALID_PARAM;
2334                 return False;
2335         }
2336
2337         /* force update the database */
2338         print_cache_flush(lp_const_servicename(snum));
2339
2340         /* Send a printer notify message */
2341
2342         notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2343                           JOB_STATUS_QUEUED);
2344
2345         return True;
2346 }
2347
2348 /****************************************************************************
2349  Write to a print file.
2350 ****************************************************************************/
2351
2352 ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size)
2353 {
2354         const char* sharename = lp_const_servicename(snum);
2355         ssize_t return_code;
2356         struct printjob *pjob;
2357
2358         pjob = print_job_find(sharename, jobid);
2359
2360         if (!pjob)
2361                 return -1;
2362         /* don't allow another process to get this info - it is meaningless */
2363         if (pjob->pid != sys_getpid())
2364                 return -1;
2365
2366         /* if SMBD is spooling this can't be allowed */
2367         if (pjob->status == PJOB_SMBD_SPOOLING) {
2368                 return -1;
2369         }
2370
2371         return_code = write_data_at_offset(pjob->fd, buf, size, pos);
2372
2373         if (return_code>0) {
2374                 pjob->size += size;
2375                 pjob_store(server_event_context(), server_messaging_context(),
2376                            sharename, jobid, pjob);
2377         }
2378         return return_code;
2379 }
2380
2381 /****************************************************************************
2382  Get the queue status - do not update if db is out of date.
2383 ****************************************************************************/
2384
2385 static int get_queue_status(const char* sharename, print_status_struct *status)
2386 {
2387         fstring keystr;
2388         TDB_DATA data;
2389         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2390         int len;
2391
2392         if (status) {
2393                 ZERO_STRUCTP(status);
2394         }
2395
2396         if (!pdb)
2397                 return 0;
2398
2399         if (status) {
2400                 fstr_sprintf(keystr, "STATUS/%s", sharename);
2401                 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2402                 if (data.dptr) {
2403                         if (data.dsize == sizeof(print_status_struct))
2404                                 /* this memcpy is ok since the status struct was
2405                                    not packed before storing it in the tdb */
2406                                 memcpy(status, data.dptr, sizeof(print_status_struct));
2407                         SAFE_FREE(data.dptr);
2408                 }
2409         }
2410         len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2411         release_print_db(pdb);
2412         return (len == -1 ? 0 : len);
2413 }
2414
2415 /****************************************************************************
2416  Determine the number of jobs in a queue.
2417 ****************************************************************************/
2418
2419 int print_queue_length(struct messaging_context *msg_ctx, int snum,
2420                        print_status_struct *pstatus)
2421 {
2422         const char* sharename = lp_const_servicename( snum );
2423         print_status_struct status;
2424         int len;
2425
2426         ZERO_STRUCT( status );
2427
2428         /* make sure the database is up to date */
2429         if (print_cache_expired(lp_const_servicename(snum), True))
2430                 print_queue_update(msg_ctx, snum, False);
2431
2432         /* also fetch the queue status */
2433         memset(&status, 0, sizeof(status));
2434         len = get_queue_status(sharename, &status);
2435
2436         if (pstatus)
2437                 *pstatus = status;
2438
2439         return len;
2440 }
2441
2442 /***************************************************************************
2443  Allocate a jobid. Hold the lock for as short a time as possible.
2444 ***************************************************************************/
2445
2446 static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum,
2447                                    const char *sharename, uint32 *pjobid)
2448 {
2449         int i;
2450         uint32 jobid;
2451         enum TDB_ERROR terr;
2452         int ret;
2453
2454         *pjobid = (uint32)-1;
2455
2456         for (i = 0; i < 3; i++) {
2457                 /* Lock the database - only wait 20 seconds. */
2458                 ret = tdb_lock_bystring_with_timeout(pdb->tdb,
2459                                                      "INFO/nextjob", 20);
2460                 if (ret == -1) {
2461                         DEBUG(0, ("allocate_print_jobid: "
2462                                   "Failed to lock printing database %s\n",
2463                                   sharename));
2464                         terr = tdb_error(pdb->tdb);
2465                         return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2466                 }
2467
2468                 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2469                         terr = tdb_error(pdb->tdb);
2470                         if (terr != TDB_ERR_NOEXIST) {
2471                                 DEBUG(0, ("allocate_print_jobid: "
2472                                           "Failed to fetch INFO/nextjob "
2473                                           "for print queue %s\n", sharename));
2474                                 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2475                                 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2476                         }
2477                         DEBUG(10, ("allocate_print_jobid: "
2478                                    "No existing jobid in %s\n", sharename));
2479                         jobid = 0;
2480                 }
2481
2482                 DEBUG(10, ("allocate_print_jobid: "
2483                            "Read jobid %u from %s\n", jobid, sharename));
2484
2485                 jobid = NEXT_JOBID(jobid);
2486
2487                 ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid);
2488                 if (ret == -1) {
2489                         terr = tdb_error(pdb->tdb);
2490                         DEBUG(3, ("allocate_print_jobid: "
2491                                   "Failed to store INFO/nextjob.\n"));
2492                         tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2493                         return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2494                 }
2495
2496                 /* We've finished with the INFO/nextjob lock. */
2497                 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2498
2499                 if (!print_job_exists(sharename, jobid)) {
2500                         break;
2501                 }
2502                 DEBUG(10, ("allocate_print_jobid: "
2503                            "Found jobid %u in %s\n", jobid, sharename));
2504         }
2505
2506         if (i > 2) {
2507                 DEBUG(0, ("allocate_print_jobid: "
2508                           "Failed to allocate a print job for queue %s\n",
2509                           sharename));
2510                 /* Probably full... */
2511                 return WERR_NO_SPOOL_SPACE;
2512         }
2513
2514         /* Store a dummy placeholder. */
2515         {
2516                 uint32_t tmp;
2517                 TDB_DATA dum;
2518                 dum.dptr = NULL;
2519                 dum.dsize = 0;
2520                 if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
2521                               TDB_INSERT) == -1) {
2522                         DEBUG(3, ("allocate_print_jobid: "
2523                                   "jobid (%d) failed to store placeholder.\n",
2524                                   jobid ));
2525                         terr = tdb_error(pdb->tdb);
2526                         return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2527                 }
2528         }
2529
2530         *pjobid = jobid;
2531         return WERR_OK;
2532 }
2533
2534 /***************************************************************************
2535  Append a jobid to the 'jobs changed' list.
2536 ***************************************************************************/
2537
2538 static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
2539 {
2540         TDB_DATA data;
2541         uint32 store_jobid;
2542
2543         SIVAL(&store_jobid, 0, jobid);
2544         data.dptr = (uint8 *)&store_jobid;
2545         data.dsize = 4;
2546
2547         DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
2548
2549         return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
2550                            data) == 0);
2551 }
2552
2553
2554 /***************************************************************************
2555  Do all checks needed to determine if we can start a job.
2556 ***************************************************************************/
2557
2558 static WERROR print_job_checks(struct auth_serversupplied_info *server_info,
2559                                struct messaging_context *msg_ctx,
2560                                int snum, int *njobs)
2561 {
2562         const char *sharename = lp_const_servicename(snum);
2563         uint64_t dspace, dsize;
2564         uint64_t minspace;
2565         int ret;
2566
2567         if (!print_access_check(server_info, msg_ctx, snum,
2568                                 PRINTER_ACCESS_USE)) {
2569                 DEBUG(3, ("print_job_checks: "
2570                           "job start denied by security descriptor\n"));
2571                 return WERR_ACCESS_DENIED;
2572         }
2573
2574         if (!print_time_access_check(server_info, msg_ctx, sharename)) {
2575                 DEBUG(3, ("print_job_checks: "
2576                           "job start denied by time check\n"));
2577                 return WERR_ACCESS_DENIED;
2578         }
2579
2580         /* see if we have sufficient disk space */
2581         if (lp_minprintspace(snum)) {
2582                 minspace = lp_minprintspace(snum);
2583                 ret = sys_fsusage(lp_pathname(snum), &dspace, &dsize);
2584                 if (ret == 0 && dspace < 2*minspace) {
2585                         DEBUG(3, ("print_job_checks: "
2586                                   "disk space check failed.\n"));
2587                         return WERR_NO_SPOOL_SPACE;
2588                 }
2589         }
2590
2591         /* for autoloaded printers, check that the printcap entry still exists */
2592         if (lp_autoloaded(snum) && !pcap_printername_ok(sharename)) {
2593                 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2594                           sharename));
2595                 return WERR_ACCESS_DENIED;
2596         }
2597
2598         /* Insure the maximum queue size is not violated */
2599         *njobs = print_queue_length(msg_ctx, snum, NULL);
2600         if (*njobs > lp_maxprintjobs(snum)) {
2601                 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2602                           "larger than max printjobs per queue (%d).\n",
2603                           sharename, *njobs, lp_maxprintjobs(snum)));
2604                 return WERR_NO_SPOOL_SPACE;
2605         }
2606
2607         return WERR_OK;
2608 }
2609
2610 /***************************************************************************
2611  Create a job file.
2612 ***************************************************************************/
2613
2614 static WERROR print_job_spool_file(int snum, uint32_t jobid,
2615                                    const char *output_file,
2616                                    struct printjob *pjob)
2617 {
2618         WERROR werr;
2619         SMB_STRUCT_STAT st;
2620         const char *path;
2621         int len;
2622
2623         /* if this file is within the printer path, it means that smbd
2624          * is spooling it and will pass us control when it is finished.
2625          * Verify that the file name is ok, within path, and it is
2626          * already already there */
2627         if (output_file) {
2628                 path = lp_pathname(snum);
2629                 len = strlen(path);
2630                 if (strncmp(output_file, path, len) == 0 &&
2631                     (output_file[len - 1] == '/' || output_file[len] == '/')) {
2632
2633                         /* verify path is not too long */
2634                         if (strlen(output_file) >= sizeof(pjob->filename)) {
2635                                 return WERR_INVALID_NAME;
2636                         }
2637
2638                         /* verify that the file exists */
2639                         if (sys_stat(output_file, &st, false) != 0) {
2640                                 return WERR_INVALID_NAME;
2641                         }
2642
2643                         fstrcpy(pjob->filename, output_file);
2644
2645                         DEBUG(3, ("print_job_spool_file:"
2646                                   "External spooling activated"));
2647
2648                         /* we do not open the file until spooling is done */
2649                         pjob->fd = -1;
2650                         pjob->status = PJOB_SMBD_SPOOLING;
2651
2652                         return WERR_OK;
2653                 }
2654         }
2655
2656         slprintf(pjob->filename, sizeof(pjob->filename)-1,
2657                  "%s/%s%.8u.XXXXXX", lp_pathname(snum),
2658                  PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2659         pjob->fd = mkstemp(pjob->filename);
2660
2661         if (pjob->fd == -1) {
2662                 werr = map_werror_from_unix(errno);
2663                 if (W_ERROR_EQUAL(werr, WERR_ACCESS_DENIED)) {
2664                         /* Common setup error, force a report. */
2665                         DEBUG(0, ("print_job_spool_file: "
2666                                   "insufficient permissions to open spool "
2667                                   "file %s.\n", pjob->filename));
2668                 } else {
2669                         /* Normal case, report at level 3 and above. */
2670                         DEBUG(3, ("print_job_spool_file: "
2671                                   "can't open spool file %s\n",
2672                                   pjob->filename));
2673                 }
2674                 return werr;
2675         }
2676
2677         return WERR_OK;
2678 }
2679
2680 /***************************************************************************
2681  Start spooling a job - return the jobid.
2682 ***************************************************************************/
2683
2684 WERROR print_job_start(struct auth_serversupplied_info *server_info,
2685                        struct messaging_context *msg_ctx,
2686                        int snum, const char *docname, const char *filename,
2687                        struct spoolss_DeviceMode *devmode, uint32_t *_jobid)
2688 {
2689         uint32_t jobid;
2690         char *path;
2691         struct printjob pjob;
2692         const char *sharename = lp_const_servicename(snum);
2693         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2694         int njobs;
2695         WERROR werr;
2696
2697         if (!pdb) {
2698                 return WERR_INTERNAL_DB_CORRUPTION;
2699         }
2700
2701         path = lp_pathname(snum);
2702
2703         werr = print_job_checks(server_info, msg_ctx, snum, &njobs);
2704         if (!W_ERROR_IS_OK(werr)) {
2705                 release_print_db(pdb);
2706                 return werr;
2707         }
2708
2709         DEBUG(10, ("print_job_start: "
2710                    "Queue %s number of jobs (%d), max printjobs = %d\n",
2711                    sharename, njobs, lp_maxprintjobs(snum)));
2712
2713         werr = allocate_print_jobid(pdb, snum, sharename, &jobid);
2714         if (!W_ERROR_IS_OK(werr)) {
2715                 goto fail;
2716         }
2717
2718         /* create the database entry */
2719
2720         ZERO_STRUCT(pjob);
2721
2722         pjob.pid = sys_getpid();
2723         pjob.sysjob = -1;
2724         pjob.fd = -1;
2725         pjob.starttime = time(NULL);
2726         pjob.status = LPQ_SPOOLING;
2727         pjob.size = 0;
2728         pjob.spooled = False;
2729         pjob.smbjob = True;
2730         pjob.devmode = devmode;
2731
2732         fstrcpy(pjob.jobname, docname);
2733
2734         fstrcpy(pjob.user, lp_printjob_username(snum));
2735         standard_sub_advanced(sharename, server_info->sanitized_username,
2736                               path, server_info->utok.gid,
2737                               server_info->sanitized_username,
2738                               server_info->info3->base.domain.string,
2739                               pjob.user, sizeof(pjob.user)-1);
2740         /* ensure NULL termination */
2741         pjob.user[sizeof(pjob.user)-1] = '\0';
2742
2743         fstrcpy(pjob.queuename, lp_const_servicename(snum));
2744
2745         /* we have a job entry - now create the spool file */
2746         werr = print_job_spool_file(snum, jobid, filename, &pjob);
2747         if (!W_ERROR_IS_OK(werr)) {
2748                 goto fail;
2749         }
2750
2751         pjob_store(server_event_context(), msg_ctx, sharename, jobid, &pjob);
2752
2753         /* Update the 'jobs changed' entry used by print_queue_status. */
2754         add_to_jobs_changed(pdb, jobid);
2755
2756         /* Ensure we keep a rough count of the number of total jobs... */
2757         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2758
2759         release_print_db(pdb);
2760
2761         *_jobid = jobid;
2762         return WERR_OK;
2763
2764 fail:
2765         if (jobid != -1) {
2766                 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
2767         }
2768
2769         release_print_db(pdb);
2770
2771         DEBUG(3, ("print_job_start: returning fail. "
2772                   "Error = %s\n", win_errstr(werr)));
2773         return werr;
2774 }
2775
2776 /****************************************************************************
2777  Update the number of pages spooled to jobid
2778 ****************************************************************************/
2779
2780 void print_job_endpage(int snum, uint32 jobid)
2781 {
2782         const char* sharename = lp_const_servicename(snum);
2783         struct printjob *pjob;
2784
2785         pjob = print_job_find(sharename, jobid);
2786         if (!pjob)
2787                 return;
2788         /* don't allow another process to get this info - it is meaningless */
2789         if (pjob->pid != sys_getpid())
2790                 return;
2791
2792         pjob->page_count++;
2793         pjob_store(server_event_context(), server_messaging_context(),
2794                    sharename, jobid, pjob);
2795 }
2796
2797 /****************************************************************************
2798  Print a file - called on closing the file. This spools the job.
2799  If normal close is false then we're tearing down the jobs - treat as an
2800  error.
2801 ****************************************************************************/
2802
2803 NTSTATUS print_job_end(struct messaging_context *msg_ctx, int snum,
2804                        uint32 jobid, enum file_close_type close_type)
2805 {
2806         const char* sharename = lp_const_servicename(snum);
2807         struct printjob *pjob;
2808         int ret;
2809         SMB_STRUCT_STAT sbuf;
2810         struct printif *current_printif = get_printer_fns( snum );
2811         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2812
2813         pjob = print_job_find(sharename, jobid);
2814
2815         if (!pjob) {
2816                 return NT_STATUS_PRINT_CANCELLED;
2817         }
2818
2819         if (pjob->spooled || pjob->pid != sys_getpid()) {
2820                 return NT_STATUS_ACCESS_DENIED;
2821         }
2822
2823         if (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) {
2824                 if (pjob->status == PJOB_SMBD_SPOOLING) {
2825                         /* take over the file now, smbd is done */
2826                         if (sys_stat(pjob->filename, &sbuf, false) != 0) {
2827                                 status = map_nt_error_from_unix(errno);
2828                                 DEBUG(3, ("print_job_end: "
2829                                           "stat file failed for jobid %d\n",
2830                                           jobid));
2831                                 goto fail;
2832                         }
2833
2834                         pjob->status = LPQ_SPOOLING;
2835
2836                 } else {
2837
2838                         if ((sys_fstat(pjob->fd, &sbuf, false) != 0)) {
2839                                 status = map_nt_error_from_unix(errno);
2840                                 close(pjob->fd);
2841                                 DEBUG(3, ("print_job_end: "
2842                                           "stat file failed for jobid %d\n",
2843                                           jobid));
2844                                 goto fail;
2845                         }
2846
2847                         close(pjob->fd);
2848                 }
2849
2850                 pjob->size = sbuf.st_ex_size;
2851         } else {
2852
2853                 /*
2854                  * Not a normal close, something has gone wrong. Cleanup.
2855                  */
2856                 if (pjob->fd != -1) {
2857                         close(pjob->fd);
2858                 }
2859                 goto fail;
2860         }
2861
2862         /* Technically, this is not quite right. If the printer has a separator
2863          * page turned on, the NT spooler prints the separator page even if the
2864          * print job is 0 bytes. 010215 JRR */
2865         if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2866                 /* don't bother spooling empty files or something being deleted. */
2867                 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2868                         pjob->filename, pjob->size ? "deleted" : "zero length" ));
2869                 unlink(pjob->filename);
2870                 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
2871                 return NT_STATUS_OK;
2872         }
2873
2874         ret = (*(current_printif->job_submit))(snum, pjob);
2875
2876         if (ret) {
2877                 status = NT_STATUS_PRINT_CANCELLED;
2878                 goto fail;
2879         }
2880
2881         /* The print job has been successfully handed over to the back-end */
2882
2883         pjob->spooled = True;
2884         pjob->status = LPQ_QUEUED;
2885         pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
2886
2887         /* make sure the database is up to date */
2888         if (print_cache_expired(lp_const_servicename(snum), True))
2889                 print_queue_update(msg_ctx, snum, False);
2890
2891         return NT_STATUS_OK;
2892
2893 fail:
2894
2895         /* The print job was not successfully started. Cleanup */
2896         /* Still need to add proper error return propagation! 010122:JRR */
2897         pjob->fd = -1;
2898         unlink(pjob->filename);
2899         pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
2900         return status;
2901 }
2902
2903 /****************************************************************************
2904  Get a snapshot of jobs in the system without traversing.
2905 ****************************************************************************/
2906
2907 static bool get_stored_queue_info(struct messaging_context *msg_ctx,
2908                                   struct tdb_print_db *pdb, int snum,
2909                                   int *pcount, print_queue_struct **ppqueue)
2910 {
2911         TDB_DATA data, cgdata;
2912         print_queue_struct *queue = NULL;
2913         uint32 qcount = 0;
2914         uint32 extra_count = 0;
2915         int total_count = 0;
2916         size_t len = 0;
2917         uint32 i;
2918         int max_reported_jobs = lp_max_reported_jobs(snum);
2919         bool ret = False;
2920         const char* sharename = lp_servicename(snum);
2921
2922         /* make sure the database is up to date */
2923         if (print_cache_expired(lp_const_servicename(snum), True))
2924                 print_queue_update(msg_ctx, snum, False);
2925
2926         *pcount = 0;
2927         *ppqueue = NULL;
2928
2929         ZERO_STRUCT(data);
2930         ZERO_STRUCT(cgdata);
2931
2932         /* Get the stored queue data. */
2933         data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
2934
2935         if (data.dptr && data.dsize >= sizeof(qcount))
2936                 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
2937
2938         /* Get the changed jobs list. */
2939         cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
2940         if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
2941                 extra_count = cgdata.dsize/4;
2942
2943         DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
2944
2945         /* Allocate the queue size. */
2946         if (qcount == 0 && extra_count == 0)
2947                 goto out;
2948
2949         if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
2950                 goto out;
2951
2952         /* Retrieve the linearised queue data. */
2953
2954         for( i  = 0; i < qcount; i++) {
2955                 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
2956                 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
2957                                 &qjob,
2958                                 &qsize,
2959                                 &qpage_count,
2960                                 &qstatus,
2961                                 &qpriority,
2962                                 &qtime,
2963                                 queue[i].fs_user,
2964                                 queue[i].fs_file);
2965                 queue[i].job = qjob;
2966                 queue[i].size = qsize;
2967                 queue[i].page_count = qpage_count;
2968                 queue[i].status = qstatus;
2969                 queue[i].priority = qpriority;
2970                 queue[i].time = qtime;
2971         }
2972
2973         total_count = qcount;
2974
2975         /* Add in the changed jobids. */
2976         for( i  = 0; i < extra_count; i++) {
2977                 uint32 jobid;
2978                 struct printjob *pjob;
2979
2980                 jobid = IVAL(cgdata.dptr, i*4);
2981                 DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
2982                 pjob = print_job_find(lp_const_servicename(snum), jobid);
2983                 if (!pjob) {
2984                         DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
2985                         remove_from_jobs_changed(sharename, jobid);
2986                         continue;
2987                 }
2988
2989                 queue[total_count].job = jobid;
2990                 queue[total_count].size = pjob->size;
2991                 queue[total_count].page_count = pjob->page_count;
2992                 queue[total_count].status = pjob->status;
2993                 queue[total_count].priority = 1;
2994                 queue[total_count].time = pjob->starttime;
2995                 fstrcpy(queue[total_count].fs_user, pjob->user);
2996                 fstrcpy(queue[total_count].fs_file, pjob->jobname);
2997                 total_count++;
2998         }
2999
3000         /* Sort the queue by submission time otherwise they are displayed
3001            in hash order. */
3002
3003         TYPESAFE_QSORT(queue, total_count, printjob_comp);
3004
3005         DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
3006
3007         if (max_reported_jobs && total_count > max_reported_jobs)
3008                 total_count = max_reported_jobs;
3009
3010         *ppqueue = queue;
3011         *pcount = total_count;
3012
3013         ret = True;
3014
3015   out:
3016
3017         SAFE_FREE(data.dptr);
3018         SAFE_FREE(cgdata.dptr);
3019         return ret;
3020 }
3021
3022 /****************************************************************************
3023  Get a printer queue listing.
3024  set queue = NULL and status = NULL if you just want to update the cache
3025 ****************************************************************************/
3026
3027 int print_queue_status(struct messaging_context *msg_ctx, int snum,
3028                        print_queue_struct **ppqueue,
3029                        print_status_struct *status)
3030 {
3031         fstring keystr;
3032         TDB_DATA data, key;
3033         const char *sharename;
3034         struct tdb_print_db *pdb;
3035         int count = 0;
3036
3037         /* make sure the database is up to date */
3038
3039         if (print_cache_expired(lp_const_servicename(snum), True))
3040                 print_queue_update(msg_ctx, snum, False);
3041
3042         /* return if we are done */
3043         if ( !ppqueue || !status )
3044                 return 0;
3045
3046         *ppqueue = NULL;
3047         sharename = lp_const_servicename(snum);
3048         pdb = get_print_db_byname(sharename);
3049
3050         if (!pdb)
3051                 return 0;
3052
3053         /*
3054          * Fetch the queue status.  We must do this first, as there may
3055          * be no jobs in the queue.
3056          */
3057
3058         ZERO_STRUCTP(status);
3059         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
3060         key = string_tdb_data(keystr);
3061
3062         data = tdb_fetch(pdb->tdb, key);
3063         if (data.dptr) {
3064                 if (data.dsize == sizeof(*status)) {
3065                         /* this memcpy is ok since the status struct was
3066                            not packed before storing it in the tdb */
3067                         memcpy(status, data.dptr, sizeof(*status));
3068                 }
3069                 SAFE_FREE(data.dptr);
3070         }
3071
3072         /*
3073          * Now, fetch the print queue information.  We first count the number
3074          * of entries, and then only retrieve the queue if necessary.
3075          */
3076
3077         if (!get_stored_queue_info(msg_ctx, pdb, snum, &count, ppqueue)) {
3078                 release_print_db(pdb);
3079                 return 0;
3080         }
3081
3082         release_print_db(pdb);
3083         return count;
3084 }
3085
3086 /****************************************************************************
3087  Pause a queue.
3088 ****************************************************************************/
3089
3090 WERROR print_queue_pause(struct auth_serversupplied_info *server_info,
3091                          struct messaging_context *msg_ctx, int snum)
3092 {
3093         int ret;
3094         struct printif *current_printif = get_printer_fns( snum );
3095
3096         if (!print_access_check(server_info, msg_ctx, snum,
3097                                 PRINTER_ACCESS_ADMINISTER)) {
3098                 return WERR_ACCESS_DENIED;
3099         }
3100
3101
3102         become_root();
3103
3104         ret = (*(current_printif->queue_pause))(snum);
3105
3106         unbecome_root();
3107
3108         if (ret != 0) {
3109                 return WERR_INVALID_PARAM;
3110         }
3111
3112         /* force update the database */
3113         print_cache_flush(lp_const_servicename(snum));
3114
3115         /* Send a printer notify message */
3116
3117         notify_printer_status(server_event_context(), msg_ctx, snum,
3118                               PRINTER_STATUS_PAUSED);
3119
3120         return WERR_OK;
3121 }
3122
3123 /****************************************************************************
3124  Resume a queue.
3125 ****************************************************************************/
3126
3127 WERROR print_queue_resume(struct auth_serversupplied_info *server_info,
3128                           struct messaging_context *msg_ctx, int snum)
3129 {
3130         int ret;
3131         struct printif *current_printif = get_printer_fns( snum );
3132
3133         if (!print_access_check(server_info, msg_ctx, snum,
3134                                 PRINTER_ACCESS_ADMINISTER)) {
3135                 return WERR_ACCESS_DENIED;
3136         }
3137
3138         become_root();
3139
3140         ret = (*(current_printif->queue_resume))(snum);
3141
3142         unbecome_root();
3143
3144         if (ret != 0) {
3145                 return WERR_INVALID_PARAM;
3146         }
3147
3148         /* make sure the database is up to date */
3149         if (print_cache_expired(lp_const_servicename(snum), True))
3150                 print_queue_update(msg_ctx, snum, True);
3151
3152         /* Send a printer notify message */
3153
3154         notify_printer_status(server_event_context(), msg_ctx, snum,
3155                               PRINTER_STATUS_OK);
3156
3157         return WERR_OK;
3158 }
3159
3160 /****************************************************************************
3161  Purge a queue - implemented by deleting all jobs that we can delete.
3162 ****************************************************************************/
3163
3164 WERROR print_queue_purge(struct auth_serversupplied_info *server_info,
3165                          struct messaging_context *msg_ctx, int snum)
3166 {
3167         print_queue_struct *queue;
3168         print_status_struct status;
3169         int njobs, i;
3170         bool can_job_admin;
3171
3172         /* Force and update so the count is accurate (i.e. not a cached count) */
3173         print_queue_update(msg_ctx, snum, True);
3174
3175         can_job_admin = print_access_check(server_info,
3176                                            msg_ctx,
3177                                            snum,
3178                                            JOB_ACCESS_ADMINISTER);
3179         njobs = print_queue_status(msg_ctx, snum, &queue, &status);
3180
3181         if ( can_job_admin )
3182                 become_root();
3183
3184         for (i=0;i<njobs;i++) {
3185                 bool owner = is_owner(server_info, lp_const_servicename(snum),
3186                                       queue[i].job);
3187
3188                 if (owner || can_job_admin) {
3189                         print_job_delete1(snum, queue[i].job);
3190                 }
3191         }
3192
3193         if ( can_job_admin )
3194                 unbecome_root();
3195
3196         /* update the cache */
3197         print_queue_update(msg_ctx, snum, True);
3198
3199         SAFE_FREE(queue);
3200
3201         return WERR_OK;
3202 }