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