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