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