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