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