~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/printing/printing.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

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