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