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