d41c606b1c84410ab4ccf17bc5bfc154421719b9
[ddiss/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         release_print_db(pdb);
824 done:
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 bool print_job_pause(const struct auth_serversupplied_info *server_info,
2337                      struct messaging_context *msg_ctx,
2338                      int snum, uint32 jobid, WERROR *errcode)
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
2345         pjob = print_job_find(sharename, jobid);
2346
2347         if (!pjob || !server_info) {
2348                 DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
2349                         (unsigned int)jobid ));
2350                 return False;
2351         }
2352
2353         if (!pjob->spooled || pjob->sysjob == -1) {
2354                 DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
2355                         (int)pjob->sysjob, (unsigned int)jobid ));
2356                 return False;
2357         }
2358
2359         if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2360             !print_access_check(server_info, msg_ctx, snum,
2361                                 JOB_ACCESS_ADMINISTER)) {
2362                 DEBUG(3, ("pause denied by security descriptor\n"));
2363
2364                 /* BEGIN_ADMIN_LOG */
2365                 sys_adminlog( LOG_ERR,
2366                         "Permission denied-- user not allowed to delete, \
2367 pause, or resume print job. User name: %s. Printer name: %s.",
2368                               uidtoname(server_info->utok.uid),
2369                               lp_printername(snum) );
2370                 /* END_ADMIN_LOG */
2371
2372                 *errcode = WERR_ACCESS_DENIED;
2373                 return False;
2374         }
2375
2376         /* need to pause the spooled entry */
2377         ret = (*(current_printif->job_pause))(snum, pjob);
2378
2379         if (ret != 0) {
2380                 *errcode = WERR_INVALID_PARAM;
2381                 return False;
2382         }
2383
2384         /* force update the database */
2385         print_cache_flush(lp_const_servicename(snum));
2386
2387         /* Send a printer notify message */
2388
2389         notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2390                           JOB_STATUS_PAUSED);
2391
2392         /* how do we tell if this succeeded? */
2393
2394         return True;
2395 }
2396
2397 /****************************************************************************
2398  Resume a job.
2399 ****************************************************************************/
2400
2401 bool print_job_resume(const struct auth_serversupplied_info *server_info,
2402                       struct messaging_context *msg_ctx,
2403                       int snum, uint32 jobid, WERROR *errcode)
2404 {
2405         const char *sharename = lp_const_servicename(snum);
2406         struct printjob *pjob;
2407         int ret;
2408         struct printif *current_printif = get_printer_fns( snum );
2409
2410         pjob = print_job_find(sharename, jobid);
2411
2412         if (!pjob || !server_info) {
2413                 DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
2414                         (unsigned int)jobid ));
2415                 return False;
2416         }
2417
2418         if (!pjob->spooled || pjob->sysjob == -1) {
2419                 DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
2420                         (int)pjob->sysjob, (unsigned int)jobid ));
2421                 return False;
2422         }
2423
2424         if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
2425             !print_access_check(server_info, msg_ctx, snum,
2426                                 JOB_ACCESS_ADMINISTER)) {
2427                 DEBUG(3, ("resume denied by security descriptor\n"));
2428                 *errcode = WERR_ACCESS_DENIED;
2429
2430                 /* BEGIN_ADMIN_LOG */
2431                 sys_adminlog( LOG_ERR,
2432                          "Permission denied-- user not allowed to delete, \
2433 pause, or resume print job. User name: %s. Printer name: %s.",
2434                               uidtoname(server_info->utok.uid),
2435                               lp_printername(snum) );
2436                 /* END_ADMIN_LOG */
2437                 return False;
2438         }
2439
2440         ret = (*(current_printif->job_resume))(snum, pjob);
2441
2442         if (ret != 0) {
2443                 *errcode = WERR_INVALID_PARAM;
2444                 return False;
2445         }
2446
2447         /* force update the database */
2448         print_cache_flush(lp_const_servicename(snum));
2449
2450         /* Send a printer notify message */
2451
2452         notify_job_status(server_event_context(), msg_ctx, sharename, jobid,
2453                           JOB_STATUS_QUEUED);
2454
2455         return True;
2456 }
2457
2458 /****************************************************************************
2459  Write to a print file.
2460 ****************************************************************************/
2461
2462 ssize_t print_job_write(struct tevent_context *ev,
2463                         struct messaging_context *msg_ctx,
2464                         int snum, uint32 jobid, const char *buf, size_t size)
2465 {
2466         const char* sharename = lp_const_servicename(snum);
2467         ssize_t return_code;
2468         struct printjob *pjob;
2469
2470         pjob = print_job_find(sharename, jobid);
2471
2472         if (!pjob)
2473                 return -1;
2474         /* don't allow another process to get this info - it is meaningless */
2475         if (pjob->pid != sys_getpid())
2476                 return -1;
2477
2478         /* if SMBD is spooling this can't be allowed */
2479         if (pjob->status == PJOB_SMBD_SPOOLING) {
2480                 return -1;
2481         }
2482
2483         return_code = write_data(pjob->fd, buf, size);
2484
2485         if (return_code>0) {
2486                 pjob->size += size;
2487                 pjob_store(ev, msg_ctx, sharename, jobid, pjob);
2488         }
2489         return return_code;
2490 }
2491
2492 /****************************************************************************
2493  Get the queue status - do not update if db is out of date.
2494 ****************************************************************************/
2495
2496 static int get_queue_status(const char* sharename, print_status_struct *status)
2497 {
2498         fstring keystr;
2499         TDB_DATA data;
2500         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2501         int len;
2502
2503         if (status) {
2504                 ZERO_STRUCTP(status);
2505         }
2506
2507         if (!pdb)
2508                 return 0;
2509
2510         if (status) {
2511                 fstr_sprintf(keystr, "STATUS/%s", sharename);
2512                 data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
2513                 if (data.dptr) {
2514                         if (data.dsize == sizeof(print_status_struct))
2515                                 /* this memcpy is ok since the status struct was
2516                                    not packed before storing it in the tdb */
2517                                 memcpy(status, data.dptr, sizeof(print_status_struct));
2518                         SAFE_FREE(data.dptr);
2519                 }
2520         }
2521         len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
2522         release_print_db(pdb);
2523         return (len == -1 ? 0 : len);
2524 }
2525
2526 /****************************************************************************
2527  Determine the number of jobs in a queue.
2528 ****************************************************************************/
2529
2530 int print_queue_length(struct messaging_context *msg_ctx, int snum,
2531                        print_status_struct *pstatus)
2532 {
2533         const char* sharename = lp_const_servicename( snum );
2534         print_status_struct status;
2535         int len;
2536
2537         ZERO_STRUCT( status );
2538
2539         /* make sure the database is up to date */
2540         if (print_cache_expired(lp_const_servicename(snum), True))
2541                 print_queue_update(msg_ctx, snum, False);
2542
2543         /* also fetch the queue status */
2544         memset(&status, 0, sizeof(status));
2545         len = get_queue_status(sharename, &status);
2546
2547         if (pstatus)
2548                 *pstatus = status;
2549
2550         return len;
2551 }
2552
2553 /***************************************************************************
2554  Allocate a jobid. Hold the lock for as short a time as possible.
2555 ***************************************************************************/
2556
2557 static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum,
2558                                    const char *sharename, uint32 *pjobid)
2559 {
2560         int i;
2561         uint32 jobid;
2562         enum TDB_ERROR terr;
2563         int ret;
2564
2565         *pjobid = (uint32)-1;
2566
2567         for (i = 0; i < 3; i++) {
2568                 /* Lock the database - only wait 20 seconds. */
2569                 ret = tdb_lock_bystring_with_timeout(pdb->tdb,
2570                                                      "INFO/nextjob", 20);
2571                 if (ret == -1) {
2572                         DEBUG(0, ("allocate_print_jobid: "
2573                                   "Failed to lock printing database %s\n",
2574                                   sharename));
2575                         terr = tdb_error(pdb->tdb);
2576                         return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2577                 }
2578
2579                 if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
2580                         terr = tdb_error(pdb->tdb);
2581                         if (terr != TDB_ERR_NOEXIST) {
2582                                 DEBUG(0, ("allocate_print_jobid: "
2583                                           "Failed to fetch INFO/nextjob "
2584                                           "for print queue %s\n", sharename));
2585                                 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2586                                 return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2587                         }
2588                         DEBUG(10, ("allocate_print_jobid: "
2589                                    "No existing jobid in %s\n", sharename));
2590                         jobid = 0;
2591                 }
2592
2593                 DEBUG(10, ("allocate_print_jobid: "
2594                            "Read jobid %u from %s\n", jobid, sharename));
2595
2596                 jobid = NEXT_JOBID(jobid);
2597
2598                 ret = tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid);
2599                 if (ret == -1) {
2600                         terr = tdb_error(pdb->tdb);
2601                         DEBUG(3, ("allocate_print_jobid: "
2602                                   "Failed to store INFO/nextjob.\n"));
2603                         tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2604                         return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2605                 }
2606
2607                 /* We've finished with the INFO/nextjob lock. */
2608                 tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
2609
2610                 if (!print_job_exists(sharename, jobid)) {
2611                         break;
2612                 }
2613                 DEBUG(10, ("allocate_print_jobid: "
2614                            "Found jobid %u in %s\n", jobid, sharename));
2615         }
2616
2617         if (i > 2) {
2618                 DEBUG(0, ("allocate_print_jobid: "
2619                           "Failed to allocate a print job for queue %s\n",
2620                           sharename));
2621                 /* Probably full... */
2622                 return WERR_NO_SPOOL_SPACE;
2623         }
2624
2625         /* Store a dummy placeholder. */
2626         {
2627                 uint32_t tmp;
2628                 TDB_DATA dum;
2629                 dum.dptr = NULL;
2630                 dum.dsize = 0;
2631                 if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
2632                               TDB_INSERT) == -1) {
2633                         DEBUG(3, ("allocate_print_jobid: "
2634                                   "jobid (%d) failed to store placeholder.\n",
2635                                   jobid ));
2636                         terr = tdb_error(pdb->tdb);
2637                         return ntstatus_to_werror(map_nt_error_from_tdb(terr));
2638                 }
2639         }
2640
2641         *pjobid = jobid;
2642         return WERR_OK;
2643 }
2644
2645 /***************************************************************************
2646  Append a jobid to the 'jobs added' list.
2647 ***************************************************************************/
2648
2649 static bool add_to_jobs_added(struct tdb_print_db *pdb, uint32 jobid)
2650 {
2651         TDB_DATA data;
2652         uint32 store_jobid;
2653
2654         SIVAL(&store_jobid, 0, jobid);
2655         data.dptr = (uint8 *)&store_jobid;
2656         data.dsize = 4;
2657
2658         DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid ));
2659
2660         return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_added"),
2661                            data) == 0);
2662 }
2663
2664
2665 /***************************************************************************
2666  Do all checks needed to determine if we can start a job.
2667 ***************************************************************************/
2668
2669 static WERROR print_job_checks(const struct auth_serversupplied_info *server_info,
2670                                struct messaging_context *msg_ctx,
2671                                int snum, int *njobs)
2672 {
2673         const char *sharename = lp_const_servicename(snum);
2674         uint64_t dspace, dsize;
2675         uint64_t minspace;
2676         int ret;
2677
2678         if (!print_access_check(server_info, msg_ctx, snum,
2679                                 PRINTER_ACCESS_USE)) {
2680                 DEBUG(3, ("print_job_checks: "
2681                           "job start denied by security descriptor\n"));
2682                 return WERR_ACCESS_DENIED;
2683         }
2684
2685         if (!print_time_access_check(server_info, msg_ctx, sharename)) {
2686                 DEBUG(3, ("print_job_checks: "
2687                           "job start denied by time check\n"));
2688                 return WERR_ACCESS_DENIED;
2689         }
2690
2691         /* see if we have sufficient disk space */
2692         if (lp_minprintspace(snum)) {
2693                 minspace = lp_minprintspace(snum);
2694                 ret = sys_fsusage(lp_pathname(snum), &dspace, &dsize);
2695                 if (ret == 0 && dspace < 2*minspace) {
2696                         DEBUG(3, ("print_job_checks: "
2697                                   "disk space check failed.\n"));
2698                         return WERR_NO_SPOOL_SPACE;
2699                 }
2700         }
2701
2702         /* for autoloaded printers, check that the printcap entry still exists */
2703         if (lp_autoloaded(snum) && !pcap_printername_ok(sharename)) {
2704                 DEBUG(3, ("print_job_checks: printer name %s check failed.\n",
2705                           sharename));
2706                 return WERR_ACCESS_DENIED;
2707         }
2708
2709         /* Insure the maximum queue size is not violated */
2710         *njobs = print_queue_length(msg_ctx, snum, NULL);
2711         if (*njobs > lp_maxprintjobs(snum)) {
2712                 DEBUG(3, ("print_job_checks: Queue %s number of jobs (%d) "
2713                           "larger than max printjobs per queue (%d).\n",
2714                           sharename, *njobs, lp_maxprintjobs(snum)));
2715                 return WERR_NO_SPOOL_SPACE;
2716         }
2717
2718         return WERR_OK;
2719 }
2720
2721 /***************************************************************************
2722  Create a job file.
2723 ***************************************************************************/
2724
2725 static WERROR print_job_spool_file(int snum, uint32_t jobid,
2726                                    const char *output_file,
2727                                    struct printjob *pjob)
2728 {
2729         WERROR werr;
2730         SMB_STRUCT_STAT st;
2731         const char *path;
2732         int len;
2733
2734         /* if this file is within the printer path, it means that smbd
2735          * is spooling it and will pass us control when it is finished.
2736          * Verify that the file name is ok, within path, and it is
2737          * already already there */
2738         if (output_file) {
2739                 path = lp_pathname(snum);
2740                 len = strlen(path);
2741                 if (strncmp(output_file, path, len) == 0 &&
2742                     (output_file[len - 1] == '/' || output_file[len] == '/')) {
2743
2744                         /* verify path is not too long */
2745                         if (strlen(output_file) >= sizeof(pjob->filename)) {
2746                                 return WERR_INVALID_NAME;
2747                         }
2748
2749                         /* verify that the file exists */
2750                         if (sys_stat(output_file, &st, false) != 0) {
2751                                 return WERR_INVALID_NAME;
2752                         }
2753
2754                         fstrcpy(pjob->filename, output_file);
2755
2756                         DEBUG(3, ("print_job_spool_file:"
2757                                   "External spooling activated"));
2758
2759                         /* we do not open the file until spooling is done */
2760                         pjob->fd = -1;
2761                         pjob->status = PJOB_SMBD_SPOOLING;
2762
2763                         return WERR_OK;
2764                 }
2765         }
2766
2767         slprintf(pjob->filename, sizeof(pjob->filename)-1,
2768                  "%s/%s%.8u.XXXXXX", lp_pathname(snum),
2769                  PRINT_SPOOL_PREFIX, (unsigned int)jobid);
2770         pjob->fd = mkstemp(pjob->filename);
2771
2772         if (pjob->fd == -1) {
2773                 werr = map_werror_from_unix(errno);
2774                 if (W_ERROR_EQUAL(werr, WERR_ACCESS_DENIED)) {
2775                         /* Common setup error, force a report. */
2776                         DEBUG(0, ("print_job_spool_file: "
2777                                   "insufficient permissions to open spool "
2778                                   "file %s.\n", pjob->filename));
2779                 } else {
2780                         /* Normal case, report at level 3 and above. */
2781                         DEBUG(3, ("print_job_spool_file: "
2782                                   "can't open spool file %s\n",
2783                                   pjob->filename));
2784                 }
2785                 return werr;
2786         }
2787
2788         return WERR_OK;
2789 }
2790
2791 /***************************************************************************
2792  Start spooling a job - return the jobid.
2793 ***************************************************************************/
2794
2795 WERROR print_job_start(const struct auth_serversupplied_info *server_info,
2796                        struct messaging_context *msg_ctx,
2797                        const char *clientmachine,
2798                        int snum, const char *docname, const char *filename,
2799                        struct spoolss_DeviceMode *devmode, uint32_t *_jobid)
2800 {
2801         uint32_t jobid;
2802         char *path;
2803         struct printjob pjob;
2804         const char *sharename = lp_const_servicename(snum);
2805         struct tdb_print_db *pdb = get_print_db_byname(sharename);
2806         int njobs;
2807         WERROR werr;
2808
2809         if (!pdb) {
2810                 return WERR_INTERNAL_DB_CORRUPTION;
2811         }
2812
2813         path = lp_pathname(snum);
2814
2815         werr = print_job_checks(server_info, msg_ctx, snum, &njobs);
2816         if (!W_ERROR_IS_OK(werr)) {
2817                 release_print_db(pdb);
2818                 return werr;
2819         }
2820
2821         DEBUG(10, ("print_job_start: "
2822                    "Queue %s number of jobs (%d), max printjobs = %d\n",
2823                    sharename, njobs, lp_maxprintjobs(snum)));
2824
2825         werr = allocate_print_jobid(pdb, snum, sharename, &jobid);
2826         if (!W_ERROR_IS_OK(werr)) {
2827                 goto fail;
2828         }
2829
2830         /* create the database entry */
2831
2832         ZERO_STRUCT(pjob);
2833
2834         pjob.pid = sys_getpid();
2835         pjob.jobid = jobid;
2836         pjob.sysjob = -1;
2837         pjob.fd = -1;
2838         pjob.starttime = time(NULL);
2839         pjob.status = LPQ_SPOOLING;
2840         pjob.size = 0;
2841         pjob.spooled = False;
2842         pjob.smbjob = True;
2843         pjob.devmode = devmode;
2844
2845         fstrcpy(pjob.jobname, docname);
2846
2847         fstrcpy(pjob.clientmachine, clientmachine);
2848
2849         fstrcpy(pjob.user, lp_printjob_username(snum));
2850         standard_sub_advanced(sharename, server_info->sanitized_username,
2851                               path, server_info->utok.gid,
2852                               server_info->sanitized_username,
2853                               server_info->info3->base.domain.string,
2854                               pjob.user, sizeof(pjob.user)-1);
2855         /* ensure NULL termination */
2856         pjob.user[sizeof(pjob.user)-1] = '\0';
2857
2858         fstrcpy(pjob.queuename, lp_const_servicename(snum));
2859
2860         /* we have a job entry - now create the spool file */
2861         werr = print_job_spool_file(snum, jobid, filename, &pjob);
2862         if (!W_ERROR_IS_OK(werr)) {
2863                 goto fail;
2864         }
2865
2866         pjob_store(server_event_context(), msg_ctx, sharename, jobid, &pjob);
2867
2868         /* Update the 'jobs added' entry used by print_queue_status. */
2869         add_to_jobs_added(pdb, jobid);
2870
2871         /* Ensure we keep a rough count of the number of total jobs... */
2872         tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
2873
2874         release_print_db(pdb);
2875
2876         *_jobid = jobid;
2877         return WERR_OK;
2878
2879 fail:
2880         if (jobid != -1) {
2881                 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
2882         }
2883
2884         release_print_db(pdb);
2885
2886         DEBUG(3, ("print_job_start: returning fail. "
2887                   "Error = %s\n", win_errstr(werr)));
2888         return werr;
2889 }
2890
2891 /****************************************************************************
2892  Update the number of pages spooled to jobid
2893 ****************************************************************************/
2894
2895 void print_job_endpage(struct messaging_context *msg_ctx,
2896                        int snum, uint32 jobid)
2897 {
2898         const char* sharename = lp_const_servicename(snum);
2899         struct printjob *pjob;
2900
2901         pjob = print_job_find(sharename, jobid);
2902         if (!pjob)
2903                 return;
2904         /* don't allow another process to get this info - it is meaningless */
2905         if (pjob->pid != sys_getpid())
2906                 return;
2907
2908         pjob->page_count++;
2909         pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
2910 }
2911
2912 /****************************************************************************
2913  Print a file - called on closing the file. This spools the job.
2914  If normal close is false then we're tearing down the jobs - treat as an
2915  error.
2916 ****************************************************************************/
2917
2918 NTSTATUS print_job_end(struct messaging_context *msg_ctx, int snum,
2919                        uint32 jobid, enum file_close_type close_type)
2920 {
2921         const char* sharename = lp_const_servicename(snum);
2922         struct printjob *pjob;
2923         int ret;
2924         SMB_STRUCT_STAT sbuf;
2925         struct printif *current_printif = get_printer_fns( snum );
2926         NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
2927
2928         pjob = print_job_find(sharename, jobid);
2929
2930         if (!pjob) {
2931                 return NT_STATUS_PRINT_CANCELLED;
2932         }
2933
2934         if (pjob->spooled || pjob->pid != sys_getpid()) {
2935                 return NT_STATUS_ACCESS_DENIED;
2936         }
2937
2938         if (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) {
2939                 if (pjob->status == PJOB_SMBD_SPOOLING) {
2940                         /* take over the file now, smbd is done */
2941                         if (sys_stat(pjob->filename, &sbuf, false) != 0) {
2942                                 status = map_nt_error_from_unix(errno);
2943                                 DEBUG(3, ("print_job_end: "
2944                                           "stat file failed for jobid %d\n",
2945                                           jobid));
2946                                 goto fail;
2947                         }
2948
2949                         pjob->status = LPQ_SPOOLING;
2950
2951                 } else {
2952
2953                         if ((sys_fstat(pjob->fd, &sbuf, false) != 0)) {
2954                                 status = map_nt_error_from_unix(errno);
2955                                 close(pjob->fd);
2956                                 DEBUG(3, ("print_job_end: "
2957                                           "stat file failed for jobid %d\n",
2958                                           jobid));
2959                                 goto fail;
2960                         }
2961
2962                         close(pjob->fd);
2963                 }
2964
2965                 pjob->size = sbuf.st_ex_size;
2966         } else {
2967
2968                 /*
2969                  * Not a normal close, something has gone wrong. Cleanup.
2970                  */
2971                 if (pjob->fd != -1) {
2972                         close(pjob->fd);
2973                 }
2974                 goto fail;
2975         }
2976
2977         /* Technically, this is not quite right. If the printer has a separator
2978          * page turned on, the NT spooler prints the separator page even if the
2979          * print job is 0 bytes. 010215 JRR */
2980         if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
2981                 /* don't bother spooling empty files or something being deleted. */
2982                 DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
2983                         pjob->filename, pjob->size ? "deleted" : "zero length" ));
2984                 unlink(pjob->filename);
2985                 pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
2986                 return NT_STATUS_OK;
2987         }
2988
2989         ret = (*(current_printif->job_submit))(snum, pjob);
2990
2991         if (ret) {
2992                 status = NT_STATUS_PRINT_CANCELLED;
2993                 goto fail;
2994         }
2995
2996         /* The print job has been successfully handed over to the back-end */
2997
2998         pjob->spooled = True;
2999         pjob->status = LPQ_QUEUED;
3000         pjob_store(server_event_context(), msg_ctx, sharename, jobid, pjob);
3001
3002         /* make sure the database is up to date */
3003         if (print_cache_expired(lp_const_servicename(snum), True))
3004                 print_queue_update(msg_ctx, snum, False);
3005
3006         return NT_STATUS_OK;
3007
3008 fail:
3009
3010         /* The print job was not successfully started. Cleanup */
3011         /* Still need to add proper error return propagation! 010122:JRR */
3012         pjob->fd = -1;
3013         unlink(pjob->filename);
3014         pjob_delete(server_event_context(), msg_ctx, sharename, jobid);
3015         return status;
3016 }
3017
3018 /****************************************************************************
3019  Get a snapshot of jobs in the system without traversing.
3020 ****************************************************************************/
3021
3022 static bool get_stored_queue_info(struct messaging_context *msg_ctx,
3023                                   struct tdb_print_db *pdb, int snum,
3024                                   int *pcount, print_queue_struct **ppqueue)
3025 {
3026         TDB_DATA data, cgdata, jcdata;
3027         print_queue_struct *queue = NULL;
3028         uint32 qcount = 0;
3029         uint32 extra_count = 0;
3030         uint32_t changed_count = 0;
3031         int total_count = 0;
3032         size_t len = 0;
3033         uint32 i;
3034         int max_reported_jobs = lp_max_reported_jobs(snum);
3035         bool ret = False;
3036         const char* sharename = lp_servicename(snum);
3037
3038         /* make sure the database is up to date */
3039         if (print_cache_expired(lp_const_servicename(snum), True))
3040                 print_queue_update(msg_ctx, snum, False);
3041
3042         *pcount = 0;
3043         *ppqueue = NULL;
3044
3045         ZERO_STRUCT(data);
3046         ZERO_STRUCT(cgdata);
3047
3048         /* Get the stored queue data. */
3049         data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
3050
3051         if (data.dptr && data.dsize >= sizeof(qcount))
3052                 len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
3053
3054         /* Get the added jobs list. */
3055         cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added"));
3056         if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
3057                 extra_count = cgdata.dsize/4;
3058
3059         /* Get the changed jobs list. */
3060         jcdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
3061         if (jcdata.dptr != NULL && (jcdata.dsize % 4 == 0))
3062                 changed_count = jcdata.dsize / 4;
3063
3064         DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
3065
3066         /* Allocate the queue size. */
3067         if (qcount == 0 && extra_count == 0)
3068                 goto out;
3069
3070         if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
3071                 goto out;
3072
3073         /* Retrieve the linearised queue data. */
3074
3075         for( i  = 0; i < qcount; i++) {
3076                 uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
3077                 len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
3078                                 &qjob,
3079                                 &qsize,
3080                                 &qpage_count,
3081                                 &qstatus,
3082                                 &qpriority,
3083                                 &qtime,
3084                                 queue[i].fs_user,
3085                                 queue[i].fs_file);
3086                 queue[i].sysjob = qjob;
3087                 queue[i].size = qsize;
3088                 queue[i].page_count = qpage_count;
3089                 queue[i].status = qstatus;
3090                 queue[i].priority = qpriority;
3091                 queue[i].time = qtime;
3092         }
3093
3094         total_count = qcount;
3095
3096         /* Add new jobids to the queue. */
3097         for( i  = 0; i < extra_count; i++) {
3098                 uint32 jobid;
3099                 struct printjob *pjob;
3100
3101                 jobid = IVAL(cgdata.dptr, i*4);
3102                 DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)jobid));
3103                 pjob = print_job_find(lp_const_servicename(snum), jobid);
3104                 if (!pjob) {
3105                         DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid));
3106                         remove_from_jobs_added(sharename, jobid);
3107                         continue;
3108                 }
3109
3110                 queue[total_count].sysjob = jobid;
3111                 queue[total_count].size = pjob->size;
3112                 queue[total_count].page_count = pjob->page_count;
3113                 queue[total_count].status = pjob->status;
3114                 queue[total_count].priority = 1;
3115                 queue[total_count].time = pjob->starttime;
3116                 fstrcpy(queue[total_count].fs_user, pjob->user);
3117                 fstrcpy(queue[total_count].fs_file, pjob->jobname);
3118                 total_count++;
3119         }
3120
3121         /* Update the changed jobids. */
3122         for (i = 0; i < changed_count; i++) {
3123                 uint32_t jobid = IVAL(jcdata.dptr, i * 4);
3124                 uint32_t j;
3125                 bool found = false;
3126
3127                 for (j = 0; j < total_count; j++) {
3128                         if (queue[j].sysjob == jobid) {
3129                                 found = true;
3130                                 break;
3131                         }
3132                 }
3133
3134                 if (found) {
3135                         struct printjob *pjob;
3136
3137                         DEBUG(5,("get_stored_queue_info: changed job: %u\n",
3138                                  (unsigned int) jobid));
3139
3140                         pjob = print_job_find(sharename, jobid);
3141                         if (pjob == NULL) {
3142                                 DEBUG(5,("get_stored_queue_info: failed to find "
3143                                          "changed job = %u\n",
3144                                          (unsigned int) jobid));
3145                                 remove_from_jobs_changed(sharename, jobid);
3146                                 continue;
3147                         }
3148
3149                         queue[j].sysjob = jobid;
3150                         queue[j].size = pjob->size;
3151                         queue[j].page_count = pjob->page_count;
3152                         queue[j].status = pjob->status;
3153                         queue[j].priority = 1;
3154                         queue[j].time = pjob->starttime;
3155                         fstrcpy(queue[j].fs_user, pjob->user);
3156                         fstrcpy(queue[j].fs_file, pjob->jobname);
3157
3158                         DEBUG(5,("get_stored_queue_info: updated queue[%u], jobid: %u, jobname: %s\n",
3159                                  (unsigned int) j, (unsigned int) jobid, pjob->jobname));
3160                 }
3161
3162                 remove_from_jobs_changed(sharename, jobid);
3163         }
3164
3165         /* Sort the queue by submission time otherwise they are displayed
3166            in hash order. */
3167
3168         TYPESAFE_QSORT(queue, total_count, printjob_comp);
3169
3170         DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
3171
3172         if (max_reported_jobs && total_count > max_reported_jobs)
3173                 total_count = max_reported_jobs;
3174
3175         *ppqueue = queue;
3176         *pcount = total_count;
3177
3178         ret = True;
3179
3180   out:
3181
3182         SAFE_FREE(data.dptr);
3183         SAFE_FREE(cgdata.dptr);
3184         return ret;
3185 }
3186
3187 /****************************************************************************
3188  Get a printer queue listing.
3189  set queue = NULL and status = NULL if you just want to update the cache
3190 ****************************************************************************/
3191
3192 int print_queue_status(struct messaging_context *msg_ctx, int snum,
3193                        print_queue_struct **ppqueue,
3194                        print_status_struct *status)
3195 {
3196         fstring keystr;
3197         TDB_DATA data, key;
3198         const char *sharename;
3199         struct tdb_print_db *pdb;
3200         int count = 0;
3201
3202         /* make sure the database is up to date */
3203
3204         if (print_cache_expired(lp_const_servicename(snum), True))
3205                 print_queue_update(msg_ctx, snum, False);
3206
3207         /* return if we are done */
3208         if ( !ppqueue || !status )
3209                 return 0;
3210
3211         *ppqueue = NULL;
3212         sharename = lp_const_servicename(snum);
3213         pdb = get_print_db_byname(sharename);
3214
3215         if (!pdb)
3216                 return 0;
3217
3218         /*
3219          * Fetch the queue status.  We must do this first, as there may
3220          * be no jobs in the queue.
3221          */
3222
3223         ZERO_STRUCTP(status);
3224         slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
3225         key = string_tdb_data(keystr);
3226
3227         data = tdb_fetch(pdb->tdb, key);
3228         if (data.dptr) {
3229                 if (data.dsize == sizeof(*status)) {
3230                         /* this memcpy is ok since the status struct was
3231                            not packed before storing it in the tdb */
3232                         memcpy(status, data.dptr, sizeof(*status));
3233                 }
3234                 SAFE_FREE(data.dptr);
3235         }
3236
3237         /*
3238          * Now, fetch the print queue information.  We first count the number
3239          * of entries, and then only retrieve the queue if necessary.
3240          */
3241
3242         if (!get_stored_queue_info(msg_ctx, pdb, snum, &count, ppqueue)) {
3243                 release_print_db(pdb);
3244                 return 0;
3245         }
3246
3247         release_print_db(pdb);
3248         return count;
3249 }
3250
3251 /****************************************************************************
3252  Pause a queue.
3253 ****************************************************************************/
3254
3255 WERROR print_queue_pause(const struct auth_serversupplied_info *server_info,
3256                          struct messaging_context *msg_ctx, int snum)
3257 {
3258         int ret;
3259         struct printif *current_printif = get_printer_fns( snum );
3260
3261         if (!print_access_check(server_info, msg_ctx, snum,
3262                                 PRINTER_ACCESS_ADMINISTER)) {
3263                 return WERR_ACCESS_DENIED;
3264         }
3265
3266
3267         become_root();
3268
3269         ret = (*(current_printif->queue_pause))(snum);
3270
3271         unbecome_root();
3272
3273         if (ret != 0) {
3274                 return WERR_INVALID_PARAM;
3275         }
3276
3277         /* force update the database */
3278         print_cache_flush(lp_const_servicename(snum));
3279
3280         /* Send a printer notify message */
3281
3282         notify_printer_status(server_event_context(), msg_ctx, snum,
3283                               PRINTER_STATUS_PAUSED);
3284
3285         return WERR_OK;
3286 }
3287
3288 /****************************************************************************
3289  Resume a queue.
3290 ****************************************************************************/
3291
3292 WERROR print_queue_resume(const struct auth_serversupplied_info *server_info,
3293                           struct messaging_context *msg_ctx, int snum)
3294 {
3295         int ret;
3296         struct printif *current_printif = get_printer_fns( snum );
3297
3298         if (!print_access_check(server_info, msg_ctx, snum,
3299                                 PRINTER_ACCESS_ADMINISTER)) {
3300                 return WERR_ACCESS_DENIED;
3301         }
3302
3303         become_root();
3304
3305         ret = (*(current_printif->queue_resume))(snum);
3306
3307         unbecome_root();
3308
3309         if (ret != 0) {
3310                 return WERR_INVALID_PARAM;
3311         }
3312
3313         /* make sure the database is up to date */
3314         if (print_cache_expired(lp_const_servicename(snum), True))
3315                 print_queue_update(msg_ctx, snum, True);
3316
3317         /* Send a printer notify message */
3318
3319         notify_printer_status(server_event_context(), msg_ctx, snum,
3320                               PRINTER_STATUS_OK);
3321
3322         return WERR_OK;
3323 }
3324
3325 /****************************************************************************
3326  Purge a queue - implemented by deleting all jobs that we can delete.
3327 ****************************************************************************/
3328
3329 WERROR print_queue_purge(const struct auth_serversupplied_info *server_info,
3330                          struct messaging_context *msg_ctx, int snum)
3331 {
3332         print_queue_struct *queue;
3333         print_status_struct status;
3334         int njobs, i;
3335         bool can_job_admin;
3336
3337         /* Force and update so the count is accurate (i.e. not a cached count) */
3338         print_queue_update(msg_ctx, snum, True);
3339
3340         can_job_admin = print_access_check(server_info,
3341                                            msg_ctx,
3342                                            snum,
3343                                            JOB_ACCESS_ADMINISTER);
3344         njobs = print_queue_status(msg_ctx, snum, &queue, &status);
3345
3346         if ( can_job_admin )
3347                 become_root();
3348
3349         for (i=0;i<njobs;i++) {
3350                 bool owner = is_owner(server_info, lp_const_servicename(snum),
3351                                       queue[i].sysjob);
3352
3353                 if (owner || can_job_admin) {
3354                         print_job_delete1(server_event_context(), msg_ctx,
3355                                           snum, queue[i].sysjob);
3356                 }
3357         }
3358
3359         if ( can_job_admin )
3360                 unbecome_root();
3361
3362         /* update the cache */
3363         print_queue_update(msg_ctx, snum, True);
3364
3365         SAFE_FREE(queue);
3366
3367         return WERR_OK;
3368 }