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