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