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