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