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