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