~lefteris-nikoltsios/+junk/samba-lp1016895

« back to all changes in this revision

Viewing changes to source3/rpc_server/spoolss/srv_spoolss_nt.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Unix SMB/CIFS implementation.
 
3
 *  RPC Pipe client / server routines
 
4
 *  Copyright (C) Andrew Tridgell              1992-2000,
 
5
 *  Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
 
6
 *  Copyright (C) Jean François Micouleau      1998-2000,
 
7
 *  Copyright (C) Jeremy Allison               2001-2002,
 
8
 *  Copyright (C) Gerald Carter                2000-2004,
 
9
 *  Copyright (C) Tim Potter                   2001-2002.
 
10
 *  Copyright (C) Guenther Deschner            2009-2010.
 
11
 *  Copyright (C) Andreas Schneider            2010.
 
12
 *
 
13
 *  This program is free software; you can redistribute it and/or modify
 
14
 *  it under the terms of the GNU General Public License as published by
 
15
 *  the Free Software Foundation; either version 3 of the License, or
 
16
 *  (at your option) any later version.
 
17
 *
 
18
 *  This program is distributed in the hope that it will be useful,
 
19
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
20
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
21
 *  GNU General Public License for more details.
 
22
 *
 
23
 *  You should have received a copy of the GNU General Public License
 
24
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 
25
 */
 
26
 
 
27
/* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
 
28
   up, all the errors returned are DOS errors, not NT status codes. */
 
29
 
 
30
#include "includes.h"
 
31
#include "ntdomain.h"
 
32
#include "nt_printing.h"
 
33
#include "srv_spoolss_util.h"
 
34
#include "../librpc/gen_ndr/srv_spoolss.h"
 
35
#include "../librpc/gen_ndr/ndr_spoolss_c.h"
 
36
#include "rpc_client/init_spoolss.h"
 
37
#include "rpc_client/cli_pipe.h"
 
38
#include "../libcli/security/security.h"
 
39
#include "librpc/gen_ndr/ndr_security.h"
 
40
#include "registry.h"
 
41
#include "registry/reg_objects.h"
 
42
#include "include/printing.h"
 
43
#include "secrets.h"
 
44
#include "../librpc/gen_ndr/netlogon.h"
 
45
#include "rpc_misc.h"
 
46
#include "printing/notify.h"
 
47
#include "serverid.h"
 
48
#include "../libcli/registry/util_reg.h"
 
49
#include "smbd/smbd.h"
 
50
#include "auth.h"
 
51
#include "messages.h"
 
52
#include "rpc_server/spoolss/srv_spoolss_nt.h"
 
53
#include "util_tdb.h"
 
54
#include "libsmb/libsmb.h"
 
55
#include "printing/printer_list.h"
 
56
#include "rpc_client/cli_winreg_spoolss.h"
 
57
 
 
58
/* macros stolen from s4 spoolss server */
 
59
#define SPOOLSS_BUFFER_UNION(fn,info,level) \
 
60
        ((info)?ndr_size_##fn(info, level, 0):0)
 
61
 
 
62
#define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,info,level,count) \
 
63
        ((info)?ndr_size_##fn##_info(mem_ctx, level, count, info):0)
 
64
 
 
65
#define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,info,count) \
 
66
        ((info)?ndr_size_##fn##_info(mem_ctx, count, info):0)
 
67
 
 
68
#define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
 
69
 
 
70
#undef DBGC_CLASS
 
71
#define DBGC_CLASS DBGC_RPC_SRV
 
72
 
 
73
#ifndef MAX_OPEN_PRINTER_EXS
 
74
#define MAX_OPEN_PRINTER_EXS 50
 
75
#endif
 
76
 
 
77
struct notify_back_channel;
 
78
 
 
79
/* structure to store the printer handles */
 
80
/* and a reference to what it's pointing to */
 
81
/* and the notify info asked about */
 
82
/* that's the central struct */
 
83
struct printer_handle {
 
84
        struct printer_handle *prev, *next;
 
85
        bool document_started;
 
86
        bool page_started;
 
87
        uint32 jobid; /* jobid in printing backend */
 
88
        int printer_type;
 
89
        const char *servername;
 
90
        fstring sharename;
 
91
        uint32 type;
 
92
        uint32 access_granted;
 
93
        struct {
 
94
                uint32 flags;
 
95
                uint32 options;
 
96
                fstring localmachine;
 
97
                uint32 printerlocal;
 
98
                struct spoolss_NotifyOption *option;
 
99
                struct policy_handle cli_hnd;
 
100
                struct notify_back_channel *cli_chan;
 
101
                uint32 change;
 
102
                /* are we in a FindNextPrinterChangeNotify() call? */
 
103
                bool fnpcn;
 
104
                struct messaging_context *msg_ctx;
 
105
        } notify;
 
106
        struct {
 
107
                fstring machine;
 
108
                fstring user;
 
109
        } client;
 
110
 
 
111
        /* devmode sent in the OpenPrinter() call */
 
112
        struct spoolss_DeviceMode *devmode;
 
113
 
 
114
        /* TODO cache the printer info2 structure */
 
115
        struct spoolss_PrinterInfo2 *info2;
 
116
 
 
117
};
 
118
 
 
119
static struct printer_handle *printers_list;
 
120
 
 
121
struct printer_session_counter {
 
122
        struct printer_session_counter *next;
 
123
        struct printer_session_counter *prev;
 
124
 
 
125
        int snum;
 
126
        uint32_t counter;
 
127
};
 
128
 
 
129
static struct printer_session_counter *counter_list;
 
130
 
 
131
struct notify_back_channel {
 
132
        struct notify_back_channel *prev, *next;
 
133
 
 
134
        /* associated client */
 
135
        struct sockaddr_storage client_address;
 
136
 
 
137
        /* print notify back-channel pipe handle*/
 
138
        struct rpc_pipe_client *cli_pipe;
 
139
        struct dcerpc_binding_handle *binding_handle;
 
140
        uint32_t active_connections;
 
141
};
 
142
 
 
143
static struct notify_back_channel *back_channels;
 
144
 
 
145
/* Map generic permissions to printer object specific permissions */
 
146
 
 
147
const struct standard_mapping printer_std_mapping = {
 
148
        PRINTER_READ,
 
149
        PRINTER_WRITE,
 
150
        PRINTER_EXECUTE,
 
151
        PRINTER_ALL_ACCESS
 
152
};
 
153
 
 
154
/* Map generic permissions to print server object specific permissions */
 
155
 
 
156
const struct standard_mapping printserver_std_mapping = {
 
157
        SERVER_READ,
 
158
        SERVER_WRITE,
 
159
        SERVER_EXECUTE,
 
160
        SERVER_ALL_ACCESS
 
161
};
 
162
 
 
163
/* API table for Xcv Monitor functions */
 
164
 
 
165
struct xcv_api_table {
 
166
        const char *name;
 
167
        WERROR(*fn) (TALLOC_CTX *mem_ctx, struct security_token *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
 
168
};
 
169
 
 
170
static void prune_printername_cache(void);
 
171
 
 
172
/********************************************************************
 
173
 * Canonicalize servername.
 
174
 ********************************************************************/
 
175
 
 
176
static const char *canon_servername(const char *servername)
 
177
{
 
178
        const char *pservername = servername;
 
179
        while (*pservername == '\\') {
 
180
                pservername++;
 
181
        }
 
182
        return pservername;
 
183
}
 
184
 
 
185
/* translate between internal status numbers and NT status numbers */
 
186
static int nt_printj_status(int v)
 
187
{
 
188
        switch (v) {
 
189
        case LPQ_QUEUED:
 
190
                return 0;
 
191
        case LPQ_PAUSED:
 
192
                return JOB_STATUS_PAUSED;
 
193
        case LPQ_SPOOLING:
 
194
                return JOB_STATUS_SPOOLING;
 
195
        case LPQ_PRINTING:
 
196
                return JOB_STATUS_PRINTING;
 
197
        case LPQ_ERROR:
 
198
                return JOB_STATUS_ERROR;
 
199
        case LPQ_DELETING:
 
200
                return JOB_STATUS_DELETING;
 
201
        case LPQ_OFFLINE:
 
202
                return JOB_STATUS_OFFLINE;
 
203
        case LPQ_PAPEROUT:
 
204
                return JOB_STATUS_PAPEROUT;
 
205
        case LPQ_PRINTED:
 
206
                return JOB_STATUS_PRINTED;
 
207
        case LPQ_DELETED:
 
208
                return JOB_STATUS_DELETED;
 
209
        case LPQ_BLOCKED:
 
210
                return JOB_STATUS_BLOCKED_DEVQ;
 
211
        case LPQ_USER_INTERVENTION:
 
212
                return JOB_STATUS_USER_INTERVENTION;
 
213
        }
 
214
        return 0;
 
215
}
 
216
 
 
217
static int nt_printq_status(int v)
 
218
{
 
219
        switch (v) {
 
220
        case LPQ_PAUSED:
 
221
                return PRINTER_STATUS_PAUSED;
 
222
        case LPQ_QUEUED:
 
223
        case LPQ_SPOOLING:
 
224
        case LPQ_PRINTING:
 
225
                return 0;
 
226
        }
 
227
        return 0;
 
228
}
 
229
 
 
230
/***************************************************************************
 
231
 Disconnect from the client
 
232
****************************************************************************/
 
233
 
 
234
static void srv_spoolss_replycloseprinter(int snum,
 
235
                                          struct printer_handle *prn_hnd)
 
236
{
 
237
        WERROR result;
 
238
        NTSTATUS status;
 
239
 
 
240
        /*
 
241
         * Tell the specific printing tdb we no longer want messages for this printer
 
242
         * by deregistering our PID.
 
243
         */
 
244
 
 
245
        if (!print_notify_deregister_pid(snum)) {
 
246
                DEBUG(0, ("Failed to register our pid for printer %s\n",
 
247
                          lp_const_servicename(snum)));
 
248
        }
 
249
 
 
250
        /* weird if the test succeeds !!! */
 
251
        if (prn_hnd->notify.cli_chan == NULL ||
 
252
            prn_hnd->notify.cli_chan->active_connections == 0) {
 
253
                DEBUG(0, ("Trying to close unexisting backchannel!\n"));
 
254
                DLIST_REMOVE(back_channels, prn_hnd->notify.cli_chan);
 
255
                TALLOC_FREE(prn_hnd->notify.cli_chan);
 
256
                return;
 
257
        }
 
258
 
 
259
        status = dcerpc_spoolss_ReplyClosePrinter(
 
260
                                        prn_hnd->notify.cli_chan->binding_handle,
 
261
                                        talloc_tos(),
 
262
                                        &prn_hnd->notify.cli_hnd,
 
263
                                        &result);
 
264
        if (!NT_STATUS_IS_OK(status)) {
 
265
                DEBUG(0, ("dcerpc_spoolss_ReplyClosePrinter failed [%s].\n",
 
266
                          nt_errstr(status)));
 
267
                result = ntstatus_to_werror(status);
 
268
        } else if (!W_ERROR_IS_OK(result)) {
 
269
                DEBUG(0, ("reply_close_printer failed [%s].\n",
 
270
                          win_errstr(result)));
 
271
        }
 
272
 
 
273
        /* if it's the last connection, deconnect the IPC$ share */
 
274
        if (prn_hnd->notify.cli_chan->active_connections == 1) {
 
275
 
 
276
                prn_hnd->notify.cli_chan->binding_handle = NULL;
 
277
                cli_shutdown(rpc_pipe_np_smb_conn(prn_hnd->notify.cli_chan->cli_pipe));
 
278
                DLIST_REMOVE(back_channels, prn_hnd->notify.cli_chan);
 
279
                TALLOC_FREE(prn_hnd->notify.cli_chan);
 
280
 
 
281
                if (prn_hnd->notify.msg_ctx != NULL) {
 
282
                        messaging_deregister(prn_hnd->notify.msg_ctx,
 
283
                                             MSG_PRINTER_NOTIFY2, NULL);
 
284
 
 
285
                        /*
 
286
                         * Tell the serverid.tdb we're no longer
 
287
                         * interested in printer notify messages.
 
288
                         */
 
289
 
 
290
                        serverid_register_msg_flags(
 
291
                                messaging_server_id(prn_hnd->notify.msg_ctx),
 
292
                                false, FLAG_MSG_PRINT_NOTIFY);
 
293
                }
 
294
        }
 
295
 
 
296
        if (prn_hnd->notify.cli_chan) {
 
297
                prn_hnd->notify.cli_chan->active_connections--;
 
298
        }
 
299
}
 
300
 
 
301
/****************************************************************************
 
302
 Functions to free a printer entry datastruct.
 
303
****************************************************************************/
 
304
 
 
305
static int printer_entry_destructor(struct printer_handle *Printer)
 
306
{
 
307
        if (Printer->notify.cli_chan != NULL &&
 
308
            Printer->notify.cli_chan->active_connections > 0) {
 
309
                int snum = -1;
 
310
 
 
311
                switch(Printer->printer_type) {
 
312
                case SPLHND_SERVER:
 
313
                        srv_spoolss_replycloseprinter(snum, Printer);
 
314
                        break;
 
315
 
 
316
                case SPLHND_PRINTER:
 
317
                        snum = print_queue_snum(Printer->sharename);
 
318
                        if (snum != -1) {
 
319
                                srv_spoolss_replycloseprinter(snum, Printer);
 
320
                        }
 
321
                        break;
 
322
                default:
 
323
                        break;
 
324
                }
 
325
        }
 
326
 
 
327
        Printer->notify.flags=0;
 
328
        Printer->notify.options=0;
 
329
        Printer->notify.localmachine[0]='\0';
 
330
        Printer->notify.printerlocal=0;
 
331
        TALLOC_FREE(Printer->notify.option);
 
332
        TALLOC_FREE(Printer->devmode);
 
333
 
 
334
        /* Remove from the internal list. */
 
335
        DLIST_REMOVE(printers_list, Printer);
 
336
        return 0;
 
337
}
 
338
 
 
339
/****************************************************************************
 
340
  find printer index by handle
 
341
****************************************************************************/
 
342
 
 
343
static struct printer_handle *find_printer_index_by_hnd(struct pipes_struct *p,
 
344
                                                        struct policy_handle *hnd)
 
345
{
 
346
        struct printer_handle *find_printer = NULL;
 
347
 
 
348
        if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
 
349
                DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
 
350
                return NULL;
 
351
        }
 
352
 
 
353
        return find_printer;
 
354
}
 
355
 
 
356
/****************************************************************************
 
357
 Close printer index by handle.
 
358
****************************************************************************/
 
359
 
 
360
static bool close_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
 
361
{
 
362
        struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
 
363
 
 
364
        if (!Printer) {
 
365
                DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
 
366
                        OUR_HANDLE(hnd)));
 
367
                return false;
 
368
        }
 
369
 
 
370
        close_policy_hnd(p, hnd);
 
371
 
 
372
        return true;
 
373
}
 
374
 
 
375
/****************************************************************************
 
376
 Delete a printer given a handle.
 
377
****************************************************************************/
 
378
 
 
379
static WERROR delete_printer_hook(TALLOC_CTX *ctx, struct security_token *token,
 
380
                                  const char *sharename,
 
381
                                  struct messaging_context *msg_ctx)
 
382
{
 
383
        char *cmd = lp_deleteprinter_cmd();
 
384
        char *command = NULL;
 
385
        int ret;
 
386
        bool is_print_op = false;
 
387
 
 
388
        /* can't fail if we don't try */
 
389
 
 
390
        if ( !*cmd )
 
391
                return WERR_OK;
 
392
 
 
393
        command = talloc_asprintf(ctx,
 
394
                        "%s \"%s\"",
 
395
                        cmd, sharename);
 
396
        if (!command) {
 
397
                return WERR_NOMEM;
 
398
        }
 
399
        if ( token )
 
400
                is_print_op = security_token_has_privilege(token, SEC_PRIV_PRINT_OPERATOR);
 
401
 
 
402
        DEBUG(10,("Running [%s]\n", command));
 
403
 
 
404
        /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
 
405
 
 
406
        if ( is_print_op )
 
407
                become_root();
 
408
 
 
409
        if ( (ret = smbrun(command, NULL)) == 0 ) {
 
410
                /* Tell everyone we updated smb.conf. */
 
411
                message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
 
412
        }
 
413
 
 
414
        if ( is_print_op )
 
415
                unbecome_root();
 
416
 
 
417
        /********** END SePrintOperatorPrivlege BLOCK **********/
 
418
 
 
419
        DEBUGADD(10,("returned [%d]\n", ret));
 
420
 
 
421
        TALLOC_FREE(command);
 
422
 
 
423
        if (ret != 0)
 
424
                return WERR_BADFID; /* What to return here? */
 
425
 
 
426
        /* go ahead and re-read the services immediately */
 
427
        become_root();
 
428
        reload_services(msg_ctx, -1, false);
 
429
        unbecome_root();
 
430
 
 
431
        if ( lp_servicenumber( sharename ) >= 0 )
 
432
                return WERR_ACCESS_DENIED;
 
433
 
 
434
        return WERR_OK;
 
435
}
 
436
 
 
437
/****************************************************************************
 
438
 Delete a printer given a handle.
 
439
****************************************************************************/
 
440
 
 
441
static WERROR delete_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
 
442
{
 
443
        struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
 
444
        WERROR result;
 
445
 
 
446
        if (!Printer) {
 
447
                DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
 
448
                        OUR_HANDLE(hnd)));
 
449
                return WERR_BADFID;
 
450
        }
 
451
 
 
452
        /*
 
453
         * It turns out that Windows allows delete printer on a handle
 
454
         * opened by an admin user, then used on a pipe handle created
 
455
         * by an anonymous user..... but they're working on security.... riiight !
 
456
         * JRA.
 
457
         */
 
458
 
 
459
        if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
 
460
                DEBUG(3, ("delete_printer_handle: denied by handle\n"));
 
461
                return WERR_ACCESS_DENIED;
 
462
        }
 
463
 
 
464
        /* this does not need a become root since the access check has been
 
465
           done on the handle already */
 
466
 
 
467
        result = winreg_delete_printer_key_internal(p->mem_ctx,
 
468
                                           get_session_info_system(),
 
469
                                           p->msg_ctx,
 
470
                                           Printer->sharename,
 
471
                                           "");
 
472
        if (!W_ERROR_IS_OK(result)) {
 
473
                DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
 
474
                return WERR_BADFID;
 
475
        }
 
476
 
 
477
        result = delete_printer_hook(p->mem_ctx, p->session_info->security_token,
 
478
                                     Printer->sharename, p->msg_ctx);
 
479
        if (!W_ERROR_IS_OK(result)) {
 
480
                return result;
 
481
        }
 
482
        prune_printername_cache();
 
483
        return WERR_OK;
 
484
}
 
485
 
 
486
/****************************************************************************
 
487
 Return the snum of a printer corresponding to an handle.
 
488
****************************************************************************/
 
489
 
 
490
static bool get_printer_snum(struct pipes_struct *p, struct policy_handle *hnd,
 
491
                             int *number, struct share_params **params)
 
492
{
 
493
        struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
 
494
 
 
495
        if (!Printer) {
 
496
                DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
 
497
                        OUR_HANDLE(hnd)));
 
498
                return false;
 
499
        }
 
500
 
 
501
        switch (Printer->printer_type) {
 
502
                case SPLHND_PRINTER:
 
503
                        DEBUG(4,("short name:%s\n", Printer->sharename));
 
504
                        *number = print_queue_snum(Printer->sharename);
 
505
                        return (*number != -1);
 
506
                case SPLHND_SERVER:
 
507
                        return false;
 
508
                default:
 
509
                        return false;
 
510
        }
 
511
}
 
512
 
 
513
/****************************************************************************
 
514
 Set printer handle type.
 
515
 Check if it's \\server or \\server\printer
 
516
****************************************************************************/
 
517
 
 
518
static bool set_printer_hnd_printertype(struct printer_handle *Printer, const char *handlename)
 
519
{
 
520
        DEBUG(3,("Setting printer type=%s\n", handlename));
 
521
 
 
522
        /* it's a print server */
 
523
        if (handlename && *handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
 
524
                DEBUGADD(4,("Printer is a print server\n"));
 
525
                Printer->printer_type = SPLHND_SERVER;
 
526
        }
 
527
        /* it's a printer (set_printer_hnd_name() will handle port monitors */
 
528
        else {
 
529
                DEBUGADD(4,("Printer is a printer\n"));
 
530
                Printer->printer_type = SPLHND_PRINTER;
 
531
        }
 
532
 
 
533
        return true;
 
534
}
 
535
 
 
536
static void prune_printername_cache_fn(const char *key, const char *value,
 
537
                                       time_t timeout, void *private_data)
 
538
{
 
539
        gencache_del(key);
 
540
}
 
541
 
 
542
static void prune_printername_cache(void)
 
543
{
 
544
        gencache_iterate(prune_printername_cache_fn, NULL, "PRINTERNAME/*");
 
545
}
 
546
 
 
547
/****************************************************************************
 
548
 Set printer handle name..  Accept names like \\server, \\server\printer,
 
549
 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port"    See
 
550
 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
 
551
 XcvDataPort() interface.
 
552
****************************************************************************/
 
553
 
 
554
static WERROR set_printer_hnd_name(TALLOC_CTX *mem_ctx,
 
555
                                   const struct auth_serversupplied_info *session_info,
 
556
                                   struct messaging_context *msg_ctx,
 
557
                                   struct printer_handle *Printer,
 
558
                                   const char *handlename)
 
559
{
 
560
        int snum;
 
561
        int n_services=lp_numservices();
 
562
        char *aprinter;
 
563
        const char *printername;
 
564
        const char *servername = NULL;
 
565
        fstring sname;
 
566
        bool found = false;
 
567
        struct spoolss_PrinterInfo2 *info2 = NULL;
 
568
        WERROR result;
 
569
        char *p;
 
570
 
 
571
        /*
 
572
         * Hopefully nobody names his printers like this. Maybe \ or ,
 
573
         * are illegal in printer names even?
 
574
         */
 
575
        const char printer_not_found[] = "Printer \\, !@#$%^&*( not found";
 
576
        char *cache_key;
 
577
        char *tmp;
 
578
 
 
579
        DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
 
580
                (unsigned long)strlen(handlename)));
 
581
 
 
582
        aprinter = CONST_DISCARD(char *, handlename);
 
583
        if ( *handlename == '\\' ) {
 
584
                servername = canon_servername(handlename);
 
585
                if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
 
586
                        *aprinter = '\0';
 
587
                        aprinter++;
 
588
                }
 
589
                if (!is_myname_or_ipaddr(servername)) {
 
590
                        return WERR_INVALID_PRINTER_NAME;
 
591
                }
 
592
                Printer->servername = talloc_asprintf(Printer, "\\\\%s", servername);
 
593
                if (Printer->servername == NULL) {
 
594
                        return WERR_NOMEM;
 
595
                }
 
596
        }
 
597
 
 
598
        if (Printer->printer_type == SPLHND_SERVER) {
 
599
                return WERR_OK;
 
600
        }
 
601
 
 
602
        if (Printer->printer_type != SPLHND_PRINTER) {
 
603
                return WERR_INVALID_HANDLE;
 
604
        }
 
605
 
 
606
        DEBUGADD(5, ("searching for [%s]\n", aprinter));
 
607
 
 
608
        p = strchr(aprinter, ',');
 
609
        if (p != NULL) {
 
610
                char *p2 = p;
 
611
                p++;
 
612
                if (*p == ' ') {
 
613
                        p++;
 
614
                }
 
615
                if (strncmp(p, "DrvConvert", strlen("DrvConvert")) == 0) {
 
616
                        *p2 = '\0';
 
617
                } else if (strncmp(p, "LocalOnly", strlen("LocalOnly")) == 0) {
 
618
                        *p2 = '\0';
 
619
                }
 
620
        }
 
621
 
 
622
        if (p) {
 
623
                DEBUGADD(5, ("stripped handlename: [%s]\n", aprinter));
 
624
        }
 
625
 
 
626
        /* check for the Port Monitor Interface */
 
627
        if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
 
628
                Printer->printer_type = SPLHND_PORTMON_TCP;
 
629
                fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
 
630
                found = true;
 
631
        }
 
632
        else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
 
633
                Printer->printer_type = SPLHND_PORTMON_LOCAL;
 
634
                fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
 
635
                found = true;
 
636
        }
 
637
 
 
638
        /*
 
639
         * With hundreds of printers, the "for" loop iterating all
 
640
         * shares can be quite expensive, as it is done on every
 
641
         * OpenPrinter. The loop maps "aprinter" to "sname", the
 
642
         * result of which we cache in gencache.
 
643
         */
 
644
 
 
645
        cache_key = talloc_asprintf(talloc_tos(), "PRINTERNAME/%s",
 
646
                                    aprinter);
 
647
        if ((cache_key != NULL) && gencache_get(cache_key, &tmp, NULL)) {
 
648
 
 
649
                found = (strcmp(tmp, printer_not_found) != 0);
 
650
                if (!found) {
 
651
                        DEBUG(4, ("Printer %s not found\n", aprinter));
 
652
                        SAFE_FREE(tmp);
 
653
                        return WERR_INVALID_PRINTER_NAME;
 
654
                }
 
655
                fstrcpy(sname, tmp);
 
656
                SAFE_FREE(tmp);
 
657
        }
 
658
 
 
659
        /* Search all sharenames first as this is easier than pulling
 
660
           the printer_info_2 off of disk. Don't use find_service() since
 
661
           that calls out to map_username() */
 
662
 
 
663
        /* do another loop to look for printernames */
 
664
        for (snum = 0; !found && snum < n_services; snum++) {
 
665
                const char *printer = lp_const_servicename(snum);
 
666
 
 
667
                /* no point going on if this is not a printer */
 
668
                if (!(lp_snum_ok(snum) && lp_print_ok(snum))) {
 
669
                        continue;
 
670
                }
 
671
 
 
672
                /* ignore [printers] share */
 
673
                if (strequal(printer, "printers")) {
 
674
                        continue;
 
675
                }
 
676
 
 
677
                fstrcpy(sname, printer);
 
678
                if (strequal(aprinter, printer)) {
 
679
                        found = true;
 
680
                        break;
 
681
                }
 
682
 
 
683
                /* no point looking up the printer object if
 
684
                   we aren't allowing printername != sharename */
 
685
                if (lp_force_printername(snum)) {
 
686
                        continue;
 
687
                }
 
688
 
 
689
                result = winreg_get_printer_internal(mem_ctx,
 
690
                                            session_info,
 
691
                                            msg_ctx,
 
692
                                            sname,
 
693
                                            &info2);
 
694
                if ( !W_ERROR_IS_OK(result) ) {
 
695
                        DEBUG(2,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
 
696
                                 sname, win_errstr(result)));
 
697
                        continue;
 
698
                }
 
699
 
 
700
                printername = strrchr(info2->printername, '\\');
 
701
                if (printername == NULL) {
 
702
                        printername = info2->printername;
 
703
                } else {
 
704
                        printername++;
 
705
                }
 
706
 
 
707
                if (strequal(printername, aprinter)) {
 
708
                        found = true;
 
709
                        break;
 
710
                }
 
711
 
 
712
                DEBUGADD(10, ("printername: %s\n", printername));
 
713
 
 
714
                TALLOC_FREE(info2);
 
715
        }
 
716
 
 
717
        if ( !found ) {
 
718
                if (cache_key != NULL) {
 
719
                        gencache_set(cache_key, printer_not_found,
 
720
                                     time(NULL)+300);
 
721
                        TALLOC_FREE(cache_key);
 
722
                }
 
723
                DEBUGADD(4,("Printer not found\n"));
 
724
                return WERR_INVALID_PRINTER_NAME;
 
725
        }
 
726
 
 
727
        if (cache_key != NULL) {
 
728
                gencache_set(cache_key, sname, time(NULL)+300);
 
729
                TALLOC_FREE(cache_key);
 
730
        }
 
731
 
 
732
        DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
 
733
 
 
734
        fstrcpy(Printer->sharename, sname);
 
735
 
 
736
        return WERR_OK;
 
737
}
 
738
 
 
739
/****************************************************************************
 
740
 Find first available printer slot. creates a printer handle for you.
 
741
 ****************************************************************************/
 
742
 
 
743
static WERROR open_printer_hnd(struct pipes_struct *p,
 
744
                               struct policy_handle *hnd,
 
745
                               const char *name,
 
746
                               uint32_t access_granted)
 
747
{
 
748
        struct printer_handle *new_printer;
 
749
        WERROR result;
 
750
 
 
751
        DEBUG(10,("open_printer_hnd: name [%s]\n", name));
 
752
 
 
753
        new_printer = talloc_zero(p->mem_ctx, struct printer_handle);
 
754
        if (new_printer == NULL) {
 
755
                return WERR_NOMEM;
 
756
        }
 
757
        talloc_set_destructor(new_printer, printer_entry_destructor);
 
758
 
 
759
        /* This also steals the printer_handle on the policy_handle */
 
760
        if (!create_policy_hnd(p, hnd, new_printer)) {
 
761
                TALLOC_FREE(new_printer);
 
762
                return WERR_INVALID_HANDLE;
 
763
        }
 
764
 
 
765
        /* Add to the internal list. */
 
766
        DLIST_ADD(printers_list, new_printer);
 
767
 
 
768
        new_printer->notify.option=NULL;
 
769
 
 
770
        if (!set_printer_hnd_printertype(new_printer, name)) {
 
771
                close_printer_handle(p, hnd);
 
772
                return WERR_INVALID_HANDLE;
 
773
        }
 
774
 
 
775
        result = set_printer_hnd_name(p->mem_ctx,
 
776
                                      get_session_info_system(),
 
777
                                      p->msg_ctx,
 
778
                                      new_printer, name);
 
779
        if (!W_ERROR_IS_OK(result)) {
 
780
                close_printer_handle(p, hnd);
 
781
                return result;
 
782
        }
 
783
 
 
784
        new_printer->access_granted = access_granted;
 
785
 
 
786
        DEBUG(5, ("%d printer handles active\n",
 
787
                  (int)num_pipe_handles(p)));
 
788
 
 
789
        return WERR_OK;
 
790
}
 
791
 
 
792
/***************************************************************************
 
793
 check to see if the client motify handle is monitoring the notification
 
794
 given by (notify_type, notify_field).
 
795
 **************************************************************************/
 
796
 
 
797
static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
 
798
                                      uint16_t notify_field)
 
799
{
 
800
        return true;
 
801
}
 
802
 
 
803
static bool is_monitoring_event(struct printer_handle *p, uint16_t notify_type,
 
804
                                uint16_t notify_field)
 
805
{
 
806
        struct spoolss_NotifyOption *option = p->notify.option;
 
807
        uint32_t i, j;
 
808
 
 
809
        /*
 
810
         * Flags should always be zero when the change notify
 
811
         * is registered by the client's spooler.  A user Win32 app
 
812
         * might use the flags though instead of the NOTIFY_OPTION_INFO
 
813
         * --jerry
 
814
         */
 
815
 
 
816
        if (!option) {
 
817
                return false;
 
818
        }
 
819
 
 
820
        if (p->notify.flags)
 
821
                return is_monitoring_event_flags(
 
822
                        p->notify.flags, notify_type, notify_field);
 
823
 
 
824
        for (i = 0; i < option->count; i++) {
 
825
 
 
826
                /* Check match for notify_type */
 
827
 
 
828
                if (option->types[i].type != notify_type)
 
829
                        continue;
 
830
 
 
831
                /* Check match for field */
 
832
 
 
833
                for (j = 0; j < option->types[i].count; j++) {
 
834
                        if (option->types[i].fields[j].field == notify_field) {
 
835
                                return true;
 
836
                        }
 
837
                }
 
838
        }
 
839
 
 
840
        DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
 
841
                   p->servername, p->sharename, notify_type, notify_field));
 
842
 
 
843
        return false;
 
844
}
 
845
 
 
846
#define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
 
847
        _data->data.integer[0] = _integer; \
 
848
        _data->data.integer[1] = 0;
 
849
 
 
850
 
 
851
#define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
 
852
        _data->data.string.string = talloc_strdup(mem_ctx, _p); \
 
853
        if (!_data->data.string.string) {\
 
854
                _data->data.string.size = 0; \
 
855
        } \
 
856
        _data->data.string.size = strlen_m_term(_p) * 2;
 
857
 
 
858
#define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
 
859
        _data->data.devmode.devmode = _devmode;
 
860
 
 
861
#define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _sd) \
 
862
        _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
 
863
        if (!_data->data.sd.sd) { \
 
864
                _data->data.sd.sd_size = 0; \
 
865
        } \
 
866
        _data->data.sd.sd_size = \
 
867
                ndr_size_security_descriptor(_data->data.sd.sd, 0);
 
868
 
 
869
static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
 
870
                                   struct tm *t,
 
871
                                   const char **pp,
 
872
                                   uint32_t *plen)
 
873
{
 
874
        struct spoolss_Time st;
 
875
        uint32_t len = 16;
 
876
        char *p;
 
877
 
 
878
        if (!init_systemtime(&st, t)) {
 
879
                return;
 
880
        }
 
881
 
 
882
        p = talloc_array(mem_ctx, char, len);
 
883
        if (!p) {
 
884
                return;
 
885
        }
 
886
 
 
887
        /*
 
888
         * Systemtime must be linearized as a set of UINT16's.
 
889
         * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
 
890
         */
 
891
 
 
892
        SSVAL(p, 0, st.year);
 
893
        SSVAL(p, 2, st.month);
 
894
        SSVAL(p, 4, st.day_of_week);
 
895
        SSVAL(p, 6, st.day);
 
896
        SSVAL(p, 8, st.hour);
 
897
        SSVAL(p, 10, st.minute);
 
898
        SSVAL(p, 12, st.second);
 
899
        SSVAL(p, 14, st.millisecond);
 
900
 
 
901
        *pp = p;
 
902
        *plen = len;
 
903
}
 
904
 
 
905
/* Convert a notification message to a struct spoolss_Notify */
 
906
 
 
907
static void notify_one_value(struct spoolss_notify_msg *msg,
 
908
                             struct spoolss_Notify *data,
 
909
                             TALLOC_CTX *mem_ctx)
 
910
{
 
911
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
 
912
}
 
913
 
 
914
static void notify_string(struct spoolss_notify_msg *msg,
 
915
                          struct spoolss_Notify *data,
 
916
                          TALLOC_CTX *mem_ctx)
 
917
{
 
918
        /* The length of the message includes the trailing \0 */
 
919
 
 
920
        data->data.string.size = msg->len * 2;
 
921
        data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
 
922
        if (!data->data.string.string) {
 
923
                data->data.string.size = 0;
 
924
                return;
 
925
        }
 
926
}
 
927
 
 
928
static void notify_system_time(struct spoolss_notify_msg *msg,
 
929
                               struct spoolss_Notify *data,
 
930
                               TALLOC_CTX *mem_ctx)
 
931
{
 
932
        data->data.string.string = NULL;
 
933
        data->data.string.size = 0;
 
934
 
 
935
        if (msg->len != sizeof(time_t)) {
 
936
                DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
 
937
                          msg->len));
 
938
                return;
 
939
        }
 
940
 
 
941
        init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
 
942
                               &data->data.string.string,
 
943
                               &data->data.string.size);
 
944
}
 
945
 
 
946
struct notify2_message_table {
 
947
        const char *name;
 
948
        void (*fn)(struct spoolss_notify_msg *msg,
 
949
                   struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
 
950
};
 
951
 
 
952
static struct notify2_message_table printer_notify_table[] = {
 
953
        /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
 
954
        /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
 
955
        /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
 
956
        /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
 
957
        /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
 
958
        /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
 
959
        /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
 
960
        /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
 
961
        /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
 
962
        /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
 
963
        /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
 
964
        /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
 
965
        /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
 
966
        /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
 
967
        /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
 
968
        /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
 
969
        /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
 
970
        /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
 
971
        /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
 
972
};
 
973
 
 
974
static struct notify2_message_table job_notify_table[] = {
 
975
        /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
 
976
        /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
 
977
        /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
 
978
        /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
 
979
        /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
 
980
        /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
 
981
        /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
 
982
        /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
 
983
        /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
 
984
        /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
 
985
        /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
 
986
        /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
 
987
        /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
 
988
        /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
 
989
        /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
 
990
        /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
 
991
        /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
 
992
        /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
 
993
        /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
 
994
        /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
 
995
        /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
 
996
        /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
 
997
        /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
 
998
        /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
 
999
};
 
1000
 
 
1001
 
 
1002
/***********************************************************************
 
1003
 Allocate talloc context for container object
 
1004
 **********************************************************************/
 
1005
 
 
1006
static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
 
1007
{
 
1008
        if ( !ctr )
 
1009
                return;
 
1010
 
 
1011
        ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
 
1012
 
 
1013
        return;
 
1014
}
 
1015
 
 
1016
/***********************************************************************
 
1017
 release all allocated memory and zero out structure
 
1018
 **********************************************************************/
 
1019
 
 
1020
static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
 
1021
{
 
1022
        if ( !ctr )
 
1023
                return;
 
1024
 
 
1025
        if ( ctr->ctx )
 
1026
                talloc_destroy(ctr->ctx);
 
1027
 
 
1028
        ZERO_STRUCTP(ctr);
 
1029
 
 
1030
        return;
 
1031
}
 
1032
 
 
1033
/***********************************************************************
 
1034
 **********************************************************************/
 
1035
 
 
1036
static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
 
1037
{
 
1038
        if ( !ctr )
 
1039
                return NULL;
 
1040
 
 
1041
        return ctr->ctx;
 
1042
}
 
1043
 
 
1044
/***********************************************************************
 
1045
 **********************************************************************/
 
1046
 
 
1047
static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
 
1048
{
 
1049
        if ( !ctr || !ctr->msg_groups )
 
1050
                return NULL;
 
1051
 
 
1052
        if ( idx >= ctr->num_groups )
 
1053
                return NULL;
 
1054
 
 
1055
        return &ctr->msg_groups[idx];
 
1056
 
 
1057
}
 
1058
 
 
1059
/***********************************************************************
 
1060
 How many groups of change messages do we have ?
 
1061
 **********************************************************************/
 
1062
 
 
1063
static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
 
1064
{
 
1065
        if ( !ctr )
 
1066
                return 0;
 
1067
 
 
1068
        return ctr->num_groups;
 
1069
}
 
1070
 
 
1071
/***********************************************************************
 
1072
 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
 
1073
 **********************************************************************/
 
1074
 
 
1075
static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
 
1076
{
 
1077
        SPOOLSS_NOTIFY_MSG_GROUP        *groups = NULL;
 
1078
        SPOOLSS_NOTIFY_MSG_GROUP        *msg_grp = NULL;
 
1079
        SPOOLSS_NOTIFY_MSG              *msg_list = NULL;
 
1080
        int                             i, new_slot;
 
1081
 
 
1082
        if ( !ctr || !msg )
 
1083
                return 0;
 
1084
 
 
1085
        /* loop over all groups looking for a matching printer name */
 
1086
 
 
1087
        for ( i=0; i<ctr->num_groups; i++ ) {
 
1088
                if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
 
1089
                        break;
 
1090
        }
 
1091
 
 
1092
        /* add a new group? */
 
1093
 
 
1094
        if ( i == ctr->num_groups ) {
 
1095
                ctr->num_groups++;
 
1096
 
 
1097
                if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
 
1098
                        DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
 
1099
                        return 0;
 
1100
                }
 
1101
                ctr->msg_groups = groups;
 
1102
 
 
1103
                /* clear the new entry and set the printer name */
 
1104
 
 
1105
                ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
 
1106
                fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
 
1107
        }
 
1108
 
 
1109
        /* add the change messages; 'i' is the correct index now regardless */
 
1110
 
 
1111
        msg_grp = &ctr->msg_groups[i];
 
1112
 
 
1113
        msg_grp->num_msgs++;
 
1114
 
 
1115
        if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
 
1116
                DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
 
1117
                return 0;
 
1118
        }
 
1119
        msg_grp->msgs = msg_list;
 
1120
 
 
1121
        new_slot = msg_grp->num_msgs-1;
 
1122
        memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
 
1123
 
 
1124
        /* need to allocate own copy of data */
 
1125
 
 
1126
        if ( msg->len != 0 )
 
1127
                msg_grp->msgs[new_slot].notify.data = (char *)
 
1128
                        TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
 
1129
 
 
1130
        return ctr->num_groups;
 
1131
}
 
1132
 
 
1133
static void construct_info_data(struct spoolss_Notify *info_data,
 
1134
                                enum spoolss_NotifyType type,
 
1135
                                uint16_t field, int id);
 
1136
 
 
1137
/***********************************************************************
 
1138
 Send a change notication message on all handles which have a call
 
1139
 back registered
 
1140
 **********************************************************************/
 
1141
 
 
1142
static int build_notify2_messages(TALLOC_CTX *mem_ctx,
 
1143
                                  struct printer_handle *prn_hnd,
 
1144
                                  SPOOLSS_NOTIFY_MSG *messages,
 
1145
                                  uint32_t num_msgs,
 
1146
                                  struct spoolss_Notify **_notifies,
 
1147
                                  int *_count)
 
1148
{
 
1149
        struct spoolss_Notify *notifies;
 
1150
        SPOOLSS_NOTIFY_MSG *msg;
 
1151
        int count = 0;
 
1152
        uint32_t id;
 
1153
        int i;
 
1154
 
 
1155
        notifies = talloc_zero_array(mem_ctx,
 
1156
                                     struct spoolss_Notify, num_msgs);
 
1157
        if (!notifies) {
 
1158
                return ENOMEM;
 
1159
        }
 
1160
 
 
1161
        for (i = 0; i < num_msgs; i++) {
 
1162
 
 
1163
                msg = &messages[i];
 
1164
 
 
1165
                /* Are we monitoring this event? */
 
1166
 
 
1167
                if (!is_monitoring_event(prn_hnd, msg->type, msg->field)) {
 
1168
                        continue;
 
1169
                }
 
1170
 
 
1171
                DEBUG(10, ("Sending message type [0x%x] field [0x%2x] "
 
1172
                           "for printer [%s]\n",
 
1173
                           msg->type, msg->field, prn_hnd->sharename));
 
1174
 
 
1175
                /*
 
1176
                 * if the is a printer notification handle and not a job
 
1177
                 * notification type, then set the id to 0.
 
1178
                 * Otherwise just use what was specified in the message.
 
1179
                 *
 
1180
                 * When registering change notification on a print server
 
1181
                 * handle we always need to send back the id (snum) matching
 
1182
                 * the printer for which the change took place.
 
1183
                 * For change notify registered on a printer handle,
 
1184
                 * this does not matter and the id should be 0.
 
1185
                 *
 
1186
                 * --jerry
 
1187
                 */
 
1188
 
 
1189
                if ((msg->type == PRINTER_NOTIFY_TYPE) &&
 
1190
                    (prn_hnd->printer_type == SPLHND_PRINTER)) {
 
1191
                        id = 0;
 
1192
                } else {
 
1193
                        id = msg->id;
 
1194
                }
 
1195
 
 
1196
                /* Convert unix jobid to smb jobid */
 
1197
 
 
1198
                if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
 
1199
                        id = sysjob_to_jobid(msg->id);
 
1200
 
 
1201
                        if (id == -1) {
 
1202
                                DEBUG(3, ("no such unix jobid %d\n",
 
1203
                                          msg->id));
 
1204
                                continue;
 
1205
                        }
 
1206
                }
 
1207
 
 
1208
                construct_info_data(&notifies[count],
 
1209
                                    msg->type, msg->field, id);
 
1210
 
 
1211
                switch(msg->type) {
 
1212
                case PRINTER_NOTIFY_TYPE:
 
1213
                        if (printer_notify_table[msg->field].fn) {
 
1214
                                printer_notify_table[msg->field].fn(msg,
 
1215
                                                &notifies[count], mem_ctx);
 
1216
                        }
 
1217
                        break;
 
1218
 
 
1219
                case JOB_NOTIFY_TYPE:
 
1220
                        if (job_notify_table[msg->field].fn) {
 
1221
                                job_notify_table[msg->field].fn(msg,
 
1222
                                                &notifies[count], mem_ctx);
 
1223
                        }
 
1224
                        break;
 
1225
 
 
1226
                default:
 
1227
                        DEBUG(5, ("Unknown notification type %d\n",
 
1228
                                  msg->type));
 
1229
                        continue;
 
1230
                }
 
1231
 
 
1232
                count++;
 
1233
        }
 
1234
 
 
1235
        *_notifies = notifies;
 
1236
        *_count = count;
 
1237
 
 
1238
        return 0;
 
1239
}
 
1240
 
 
1241
static int send_notify2_printer(TALLOC_CTX *mem_ctx,
 
1242
                                struct printer_handle *prn_hnd,
 
1243
                                SPOOLSS_NOTIFY_MSG_GROUP *msg_group)
 
1244
{
 
1245
        struct spoolss_Notify *notifies;
 
1246
        int count = 0;
 
1247
        union spoolss_ReplyPrinterInfo info;
 
1248
        struct spoolss_NotifyInfo info0;
 
1249
        uint32_t reply_result;
 
1250
        NTSTATUS status;
 
1251
        WERROR werr;
 
1252
        int ret;
 
1253
 
 
1254
        /* Is there notification on this handle? */
 
1255
        if (prn_hnd->notify.cli_chan == NULL ||
 
1256
            prn_hnd->notify.cli_chan->active_connections == 0) {
 
1257
                return 0;
 
1258
        }
 
1259
 
 
1260
        DEBUG(10, ("Client connected! [\\\\%s\\%s]\n",
 
1261
                   prn_hnd->servername, prn_hnd->sharename));
 
1262
 
 
1263
        /* For this printer? Print servers always receive notifications. */
 
1264
        if ((prn_hnd->printer_type == SPLHND_PRINTER)  &&
 
1265
            (!strequal(msg_group->printername, prn_hnd->sharename))) {
 
1266
                return 0;
 
1267
        }
 
1268
 
 
1269
        DEBUG(10,("Our printer\n"));
 
1270
 
 
1271
        /* build the array of change notifications */
 
1272
        ret = build_notify2_messages(mem_ctx, prn_hnd,
 
1273
                                     msg_group->msgs,
 
1274
                                     msg_group->num_msgs,
 
1275
                                     &notifies, &count);
 
1276
        if (ret) {
 
1277
                return ret;
 
1278
        }
 
1279
 
 
1280
        info0.version   = 0x2;
 
1281
        info0.flags     = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
 
1282
        info0.count     = count;
 
1283
        info0.notifies  = notifies;
 
1284
 
 
1285
        info.info0 = &info0;
 
1286
 
 
1287
        status = dcerpc_spoolss_RouterReplyPrinterEx(
 
1288
                                prn_hnd->notify.cli_chan->binding_handle,
 
1289
                                mem_ctx,
 
1290
                                &prn_hnd->notify.cli_hnd,
 
1291
                                prn_hnd->notify.change, /* color */
 
1292
                                prn_hnd->notify.flags,
 
1293
                                &reply_result,
 
1294
                                0, /* reply_type, must be 0 */
 
1295
                                info, &werr);
 
1296
        if (!NT_STATUS_IS_OK(status)) {
 
1297
                DEBUG(1, ("dcerpc_spoolss_RouterReplyPrinterEx to client: %s "
 
1298
                          "failed: %s\n",
 
1299
                          prn_hnd->notify.cli_chan->cli_pipe->srv_name_slash,
 
1300
                          nt_errstr(status)));
 
1301
                werr = ntstatus_to_werror(status);
 
1302
        } else if (!W_ERROR_IS_OK(werr)) {
 
1303
                DEBUG(1, ("RouterReplyPrinterEx to client: %s "
 
1304
                          "failed: %s\n",
 
1305
                          prn_hnd->notify.cli_chan->cli_pipe->srv_name_slash,
 
1306
                          win_errstr(werr)));
 
1307
        }
 
1308
        switch (reply_result) {
 
1309
        case 0:
 
1310
                break;
 
1311
        case PRINTER_NOTIFY_INFO_DISCARDED:
 
1312
        case PRINTER_NOTIFY_INFO_DISCARDNOTED:
 
1313
        case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
 
1314
                break;
 
1315
        default:
 
1316
                break;
 
1317
        }
 
1318
 
 
1319
        return 0;
 
1320
}
 
1321
 
 
1322
static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
 
1323
{
 
1324
        struct printer_handle    *p;
 
1325
        TALLOC_CTX               *mem_ctx = notify_ctr_getctx( ctr );
 
1326
        SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
 
1327
        int ret;
 
1328
 
 
1329
        if ( !msg_group ) {
 
1330
                DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
 
1331
                return;
 
1332
        }
 
1333
 
 
1334
        if (!msg_group->msgs) {
 
1335
                DEBUG(5, ("send_notify2_changes() called with no messages!\n"));
 
1336
                return;
 
1337
        }
 
1338
 
 
1339
        DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
 
1340
 
 
1341
        /* loop over all printers */
 
1342
 
 
1343
        for (p = printers_list; p; p = p->next) {
 
1344
                ret = send_notify2_printer(mem_ctx, p, msg_group);
 
1345
                if (ret) {
 
1346
                        goto done;
 
1347
                }
 
1348
        }
 
1349
 
 
1350
done:
 
1351
        DEBUG(8,("send_notify2_changes: Exit...\n"));
 
1352
        return;
 
1353
}
 
1354
 
 
1355
/***********************************************************************
 
1356
 **********************************************************************/
 
1357
 
 
1358
static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
 
1359
{
 
1360
 
 
1361
        uint32_t tv_sec, tv_usec;
 
1362
        size_t offset = 0;
 
1363
 
 
1364
        /* Unpack message */
 
1365
 
 
1366
        offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
 
1367
                             msg->printer);
 
1368
 
 
1369
        offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
 
1370
                                &tv_sec, &tv_usec,
 
1371
                                &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
 
1372
 
 
1373
        if (msg->len == 0)
 
1374
                tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
 
1375
                           &msg->notify.value[0], &msg->notify.value[1]);
 
1376
        else
 
1377
                tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
 
1378
                           &msg->len, &msg->notify.data);
 
1379
 
 
1380
        DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
 
1381
                  msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
 
1382
 
 
1383
        tv->tv_sec = tv_sec;
 
1384
        tv->tv_usec = tv_usec;
 
1385
 
 
1386
        if (msg->len == 0)
 
1387
                DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
 
1388
                          msg->notify.value[1]));
 
1389
        else
 
1390
                dump_data(3, (uint8_t *)msg->notify.data, msg->len);
 
1391
 
 
1392
        return true;
 
1393
}
 
1394
 
 
1395
/********************************************************************
 
1396
 Receive a notify2 message list
 
1397
 ********************************************************************/
 
1398
 
 
1399
static void receive_notify2_message_list(struct messaging_context *msg,
 
1400
                                         void *private_data,
 
1401
                                         uint32_t msg_type,
 
1402
                                         struct server_id server_id,
 
1403
                                         DATA_BLOB *data)
 
1404
{
 
1405
        size_t                  msg_count, i;
 
1406
        char                    *buf = (char *)data->data;
 
1407
        char                    *msg_ptr;
 
1408
        size_t                  msg_len;
 
1409
        SPOOLSS_NOTIFY_MSG      notify;
 
1410
        SPOOLSS_NOTIFY_MSG_CTR  messages;
 
1411
        int                     num_groups;
 
1412
 
 
1413
        if (data->length < 4) {
 
1414
                DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
 
1415
                return;
 
1416
        }
 
1417
 
 
1418
        msg_count = IVAL(buf, 0);
 
1419
        msg_ptr = buf + 4;
 
1420
 
 
1421
        DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
 
1422
 
 
1423
        if (msg_count == 0) {
 
1424
                DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
 
1425
                return;
 
1426
        }
 
1427
 
 
1428
        /* initialize the container */
 
1429
 
 
1430
        ZERO_STRUCT( messages );
 
1431
        notify_msg_ctr_init( &messages );
 
1432
 
 
1433
        /*
 
1434
         * build message groups for each printer identified
 
1435
         * in a change_notify msg.  Remember that a PCN message
 
1436
         * includes the handle returned for the srv_spoolss_replyopenprinter()
 
1437
         * call.  Therefore messages are grouped according to printer handle.
 
1438
         */
 
1439
 
 
1440
        for ( i=0; i<msg_count; i++ ) {
 
1441
                struct timeval msg_tv;
 
1442
 
 
1443
                if (msg_ptr + 4 - buf > data->length) {
 
1444
                        DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
 
1445
                        return;
 
1446
                }
 
1447
 
 
1448
                msg_len = IVAL(msg_ptr,0);
 
1449
                msg_ptr += 4;
 
1450
 
 
1451
                if (msg_ptr + msg_len - buf > data->length) {
 
1452
                        DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
 
1453
                        return;
 
1454
                }
 
1455
 
 
1456
                /* unpack messages */
 
1457
 
 
1458
                ZERO_STRUCT( notify );
 
1459
                notify2_unpack_msg( &notify, &msg_tv, msg_ptr, msg_len );
 
1460
                msg_ptr += msg_len;
 
1461
 
 
1462
                /* add to correct list in container */
 
1463
 
 
1464
                notify_msg_ctr_addmsg( &messages, &notify );
 
1465
 
 
1466
                /* free memory that might have been allocated by notify2_unpack_msg() */
 
1467
 
 
1468
                if ( notify.len != 0 )
 
1469
                        SAFE_FREE( notify.notify.data );
 
1470
        }
 
1471
 
 
1472
        /* process each group of messages */
 
1473
 
 
1474
        num_groups = notify_msg_ctr_numgroups( &messages );
 
1475
        for ( i=0; i<num_groups; i++ )
 
1476
                send_notify2_changes( &messages, i );
 
1477
 
 
1478
 
 
1479
        /* cleanup */
 
1480
 
 
1481
        DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
 
1482
                (uint32_t)msg_count ));
 
1483
 
 
1484
        notify_msg_ctr_destroy( &messages );
 
1485
 
 
1486
        return;
 
1487
}
 
1488
 
 
1489
/********************************************************************
 
1490
 Send a message to ourself about new driver being installed
 
1491
 so we can upgrade the information for each printer bound to this
 
1492
 driver
 
1493
 ********************************************************************/
 
1494
 
 
1495
static bool srv_spoolss_drv_upgrade_printer(const char *drivername,
 
1496
                                            struct messaging_context *msg_ctx)
 
1497
{
 
1498
        int len = strlen(drivername);
 
1499
 
 
1500
        if (!len)
 
1501
                return false;
 
1502
 
 
1503
        DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
 
1504
                drivername));
 
1505
 
 
1506
        messaging_send_buf(msg_ctx, messaging_server_id(msg_ctx),
 
1507
                           MSG_PRINTER_DRVUPGRADE,
 
1508
                           (uint8_t *)drivername, len+1);
 
1509
 
 
1510
        return true;
 
1511
}
 
1512
 
 
1513
void srv_spoolss_cleanup(void)
 
1514
{
 
1515
        struct printer_session_counter *session_counter;
 
1516
 
 
1517
        for (session_counter = counter_list;
 
1518
             session_counter != NULL;
 
1519
             session_counter = counter_list) {
 
1520
                DLIST_REMOVE(counter_list, session_counter);
 
1521
                TALLOC_FREE(session_counter);
 
1522
        }
 
1523
}
 
1524
 
 
1525
/**********************************************************************
 
1526
 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
 
1527
 over all printers, upgrading ones as necessary
 
1528
 **********************************************************************/
 
1529
 
 
1530
void do_drv_upgrade_printer(struct messaging_context *msg,
 
1531
                            void *private_data,
 
1532
                            uint32_t msg_type,
 
1533
                            struct server_id server_id,
 
1534
                            DATA_BLOB *data)
 
1535
{
 
1536
        TALLOC_CTX *tmp_ctx;
 
1537
        struct auth_serversupplied_info *session_info = NULL;
 
1538
        struct spoolss_PrinterInfo2 *pinfo2;
 
1539
        NTSTATUS status;
 
1540
        WERROR result;
 
1541
        const char *drivername;
 
1542
        int snum;
 
1543
        int n_services = lp_numservices();
 
1544
        struct dcerpc_binding_handle *b = NULL;
 
1545
 
 
1546
        tmp_ctx = talloc_new(NULL);
 
1547
        if (!tmp_ctx) return;
 
1548
 
 
1549
        status = make_session_info_system(tmp_ctx, &session_info);
 
1550
        if (!NT_STATUS_IS_OK(status)) {
 
1551
                DEBUG(0, ("do_drv_upgrade_printer: "
 
1552
                          "Could not create system session_info\n"));
 
1553
                goto done;
 
1554
        }
 
1555
 
 
1556
        drivername = talloc_strndup(tmp_ctx, (const char *)data->data, data->length);
 
1557
        if (!drivername) {
 
1558
                DEBUG(0, ("do_drv_upgrade_printer: Out of memoery ?!\n"));
 
1559
                goto done;
 
1560
        }
 
1561
 
 
1562
        DEBUG(10, ("do_drv_upgrade_printer: "
 
1563
                   "Got message for new driver [%s]\n", drivername));
 
1564
 
 
1565
        /* Iterate the printer list */
 
1566
 
 
1567
        for (snum = 0; snum < n_services; snum++) {
 
1568
                if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
 
1569
                        continue;
 
1570
                }
 
1571
 
 
1572
                /* ignore [printers] share */
 
1573
                if (strequal(lp_const_servicename(snum), "printers")) {
 
1574
                        continue;
 
1575
                }
 
1576
 
 
1577
                if (b == NULL) {
 
1578
                        result = winreg_printer_binding_handle(tmp_ctx,
 
1579
                                                               session_info,
 
1580
                                                               msg,
 
1581
                                                               &b);
 
1582
                        if (!W_ERROR_IS_OK(result)) {
 
1583
                                break;
 
1584
                        }
 
1585
                }
 
1586
 
 
1587
                result = winreg_get_printer(tmp_ctx, b,
 
1588
                                            lp_const_servicename(snum),
 
1589
                                            &pinfo2);
 
1590
 
 
1591
                if (!W_ERROR_IS_OK(result)) {
 
1592
                        continue;
 
1593
                }
 
1594
 
 
1595
                if (!pinfo2->drivername) {
 
1596
                        continue;
 
1597
                }
 
1598
 
 
1599
                if (strcmp(drivername, pinfo2->drivername) != 0) {
 
1600
                        continue;
 
1601
                }
 
1602
 
 
1603
                DEBUG(6,("Updating printer [%s]\n", pinfo2->printername));
 
1604
 
 
1605
                /* all we care about currently is the change_id */
 
1606
                result = winreg_printer_update_changeid(tmp_ctx, b,
 
1607
                                                        pinfo2->printername);
 
1608
 
 
1609
                if (!W_ERROR_IS_OK(result)) {
 
1610
                        DEBUG(3, ("do_drv_upgrade_printer: "
 
1611
                                  "Failed to update changeid [%s]\n",
 
1612
                                  win_errstr(result)));
 
1613
                }
 
1614
        }
 
1615
 
 
1616
        /* all done */
 
1617
done:
 
1618
        talloc_free(tmp_ctx);
 
1619
}
 
1620
 
 
1621
/********************************************************************
 
1622
 Update the cache for all printq's with a registered client
 
1623
 connection
 
1624
 ********************************************************************/
 
1625
 
 
1626
void update_monitored_printq_cache(struct messaging_context *msg_ctx)
 
1627
{
 
1628
        struct printer_handle *printer = printers_list;
 
1629
        int snum;
 
1630
 
 
1631
        /* loop through all printers and update the cache where
 
1632
           a client is connected */
 
1633
        while (printer) {
 
1634
                if ((printer->printer_type == SPLHND_PRINTER) &&
 
1635
                    ((printer->notify.cli_chan != NULL) &&
 
1636
                     (printer->notify.cli_chan->active_connections > 0))) {
 
1637
                        snum = print_queue_snum(printer->sharename);
 
1638
                        print_queue_status(msg_ctx, snum, NULL, NULL);
 
1639
                }
 
1640
 
 
1641
                printer = printer->next;
 
1642
        }
 
1643
 
 
1644
        return;
 
1645
}
 
1646
 
 
1647
/****************************************************************
 
1648
 _spoolss_OpenPrinter
 
1649
****************************************************************/
 
1650
 
 
1651
WERROR _spoolss_OpenPrinter(struct pipes_struct *p,
 
1652
                            struct spoolss_OpenPrinter *r)
 
1653
{
 
1654
        struct spoolss_OpenPrinterEx e;
 
1655
        WERROR werr;
 
1656
 
 
1657
        ZERO_STRUCT(e.in.userlevel);
 
1658
 
 
1659
        e.in.printername        = r->in.printername;
 
1660
        e.in.datatype           = r->in.datatype;
 
1661
        e.in.devmode_ctr        = r->in.devmode_ctr;
 
1662
        e.in.access_mask        = r->in.access_mask;
 
1663
        e.in.level              = 0;
 
1664
 
 
1665
        e.out.handle            = r->out.handle;
 
1666
 
 
1667
        werr = _spoolss_OpenPrinterEx(p, &e);
 
1668
 
 
1669
        if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
 
1670
                /* OpenPrinterEx returns this for a bad
 
1671
                 * printer name. We must return WERR_INVALID_PRINTER_NAME
 
1672
                 * instead.
 
1673
                 */
 
1674
                werr = WERR_INVALID_PRINTER_NAME;
 
1675
        }
 
1676
 
 
1677
        return werr;
 
1678
}
 
1679
 
 
1680
static WERROR copy_devicemode(TALLOC_CTX *mem_ctx,
 
1681
                              struct spoolss_DeviceMode *orig,
 
1682
                              struct spoolss_DeviceMode **dest)
 
1683
{
 
1684
        struct spoolss_DeviceMode *dm;
 
1685
 
 
1686
        dm = talloc(mem_ctx, struct spoolss_DeviceMode);
 
1687
        if (!dm) {
 
1688
                return WERR_NOMEM;
 
1689
        }
 
1690
 
 
1691
        /* copy all values, then duplicate strings and structs */
 
1692
        *dm = *orig;
 
1693
 
 
1694
        dm->devicename = talloc_strdup(dm, orig->devicename);
 
1695
        if (!dm->devicename) {
 
1696
                return WERR_NOMEM;
 
1697
        }
 
1698
        dm->formname = talloc_strdup(dm, orig->formname);
 
1699
        if (!dm->formname) {
 
1700
                return WERR_NOMEM;
 
1701
        }
 
1702
        if (orig->driverextra_data.data) {
 
1703
                dm->driverextra_data.data =
 
1704
                        (uint8_t *) talloc_memdup(dm, orig->driverextra_data.data,
 
1705
                                        orig->driverextra_data.length);
 
1706
                if (!dm->driverextra_data.data) {
 
1707
                        return WERR_NOMEM;
 
1708
                }
 
1709
        }
 
1710
 
 
1711
        *dest = dm;
 
1712
        return WERR_OK;
 
1713
}
 
1714
 
 
1715
/****************************************************************
 
1716
 _spoolss_OpenPrinterEx
 
1717
****************************************************************/
 
1718
 
 
1719
WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
 
1720
                              struct spoolss_OpenPrinterEx *r)
 
1721
{
 
1722
        int snum;
 
1723
        struct printer_handle *Printer=NULL;
 
1724
        WERROR result;
 
1725
 
 
1726
        if (!r->in.printername) {
 
1727
                return WERR_INVALID_PARAM;
 
1728
        }
 
1729
 
 
1730
        if (r->in.level > 3) {
 
1731
                return WERR_INVALID_PARAM;
 
1732
        }
 
1733
        if ((r->in.level == 1 && !r->in.userlevel.level1) ||
 
1734
            (r->in.level == 2 && !r->in.userlevel.level2) ||
 
1735
            (r->in.level == 3 && !r->in.userlevel.level3)) {
 
1736
                return WERR_INVALID_PARAM;
 
1737
        }
 
1738
 
 
1739
        /* some sanity check because you can open a printer or a print server */
 
1740
        /* aka: \\server\printer or \\server */
 
1741
 
 
1742
        DEBUGADD(3,("checking name: %s\n", r->in.printername));
 
1743
 
 
1744
        result = open_printer_hnd(p, r->out.handle, r->in.printername, 0);
 
1745
        if (!W_ERROR_IS_OK(result)) {
 
1746
                DEBUG(0,("_spoolss_OpenPrinterEx: Cannot open a printer handle "
 
1747
                        "for printer %s\n", r->in.printername));
 
1748
                ZERO_STRUCTP(r->out.handle);
 
1749
                return result;
 
1750
        }
 
1751
 
 
1752
        Printer = find_printer_index_by_hnd(p, r->out.handle);
 
1753
        if ( !Printer ) {
 
1754
                DEBUG(0,("_spoolss_OpenPrinterEx: logic error.  Can't find printer "
 
1755
                        "handle we created for printer %s\n", r->in.printername));
 
1756
                close_printer_handle(p, r->out.handle);
 
1757
                ZERO_STRUCTP(r->out.handle);
 
1758
                return WERR_INVALID_PARAM;
 
1759
        }
 
1760
 
 
1761
        /*
 
1762
         * First case: the user is opening the print server:
 
1763
         *
 
1764
         * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
 
1765
         * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
 
1766
         *
 
1767
         * Then both Win2k and WinNT clients try an OpenPrinterEx with
 
1768
         * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
 
1769
         * or if the user is listed in the smb.conf printer admin parameter.
 
1770
         *
 
1771
         * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
 
1772
         * client view printer folder, but does not show the MSAPW.
 
1773
         *
 
1774
         * Note: this test needs code to check access rights here too. Jeremy
 
1775
         * could you look at this?
 
1776
         *
 
1777
         * Second case: the user is opening a printer:
 
1778
         * NT doesn't let us connect to a printer if the connecting user
 
1779
         * doesn't have print permission.
 
1780
         *
 
1781
         * Third case: user is opening a Port Monitor
 
1782
         * access checks same as opening a handle to the print server.
 
1783
         */
 
1784
 
 
1785
        switch (Printer->printer_type )
 
1786
        {
 
1787
        case SPLHND_SERVER:
 
1788
        case SPLHND_PORTMON_TCP:
 
1789
        case SPLHND_PORTMON_LOCAL:
 
1790
                /* Printserver handles use global struct... */
 
1791
 
 
1792
                snum = -1;
 
1793
 
 
1794
                /* Map standard access rights to object specific access rights */
 
1795
 
 
1796
                se_map_standard(&r->in.access_mask,
 
1797
                                &printserver_std_mapping);
 
1798
 
 
1799
                /* Deny any object specific bits that don't apply to print
 
1800
                   servers (i.e printer and job specific bits) */
 
1801
 
 
1802
                r->in.access_mask &= SEC_MASK_SPECIFIC;
 
1803
 
 
1804
                if (r->in.access_mask &
 
1805
                    ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
 
1806
                        DEBUG(3, ("access DENIED for non-printserver bits\n"));
 
1807
                        close_printer_handle(p, r->out.handle);
 
1808
                        ZERO_STRUCTP(r->out.handle);
 
1809
                        return WERR_ACCESS_DENIED;
 
1810
                }
 
1811
 
 
1812
                /* Allow admin access */
 
1813
 
 
1814
                if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
 
1815
                {
 
1816
                        if (!lp_ms_add_printer_wizard()) {
 
1817
                                close_printer_handle(p, r->out.handle);
 
1818
                                ZERO_STRUCTP(r->out.handle);
 
1819
                                return WERR_ACCESS_DENIED;
 
1820
                        }
 
1821
 
 
1822
                        /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
 
1823
                           and not a printer admin, then fail */
 
1824
 
 
1825
                        if ((p->session_info->utok.uid != sec_initial_uid()) &&
 
1826
                            !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_PRINT_OPERATOR) &&
 
1827
                            !nt_token_check_sid(&global_sid_Builtin_Print_Operators, p->session_info->security_token) &&
 
1828
                            !token_contains_name_in_list(
 
1829
                                    uidtoname(p->session_info->utok.uid),
 
1830
                                    p->session_info->info3->base.domain.string,
 
1831
                                    NULL,
 
1832
                                    p->session_info->security_token,
 
1833
                                    lp_printer_admin(snum))) {
 
1834
                                close_printer_handle(p, r->out.handle);
 
1835
                                ZERO_STRUCTP(r->out.handle);
 
1836
                                DEBUG(3,("access DENIED as user is not root, "
 
1837
                                        "has no printoperator privilege, "
 
1838
                                        "not a member of the printoperator builtin group and "
 
1839
                                        "is not in printer admin list"));
 
1840
                                return WERR_ACCESS_DENIED;
 
1841
                        }
 
1842
 
 
1843
                        r->in.access_mask = SERVER_ACCESS_ADMINISTER;
 
1844
                }
 
1845
                else
 
1846
                {
 
1847
                        r->in.access_mask = SERVER_ACCESS_ENUMERATE;
 
1848
                }
 
1849
 
 
1850
                DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
 
1851
                        ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
 
1852
 
 
1853
                /* We fall through to return WERR_OK */
 
1854
                break;
 
1855
 
 
1856
        case SPLHND_PRINTER:
 
1857
                /* NT doesn't let us connect to a printer if the connecting user
 
1858
                   doesn't have print permission.  */
 
1859
 
 
1860
                if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
 
1861
                        close_printer_handle(p, r->out.handle);
 
1862
                        ZERO_STRUCTP(r->out.handle);
 
1863
                        return WERR_BADFID;
 
1864
                }
 
1865
 
 
1866
                if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
 
1867
                        r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
 
1868
                }
 
1869
 
 
1870
                se_map_standard(&r->in.access_mask, &printer_std_mapping);
 
1871
 
 
1872
                /* map an empty access mask to the minimum access mask */
 
1873
                if (r->in.access_mask == 0x0)
 
1874
                        r->in.access_mask = PRINTER_ACCESS_USE;
 
1875
 
 
1876
                /*
 
1877
                 * If we are not serving the printer driver for this printer,
 
1878
                 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE.  This
 
1879
                 * will keep NT clients happy  --jerry
 
1880
                 */
 
1881
 
 
1882
                if (lp_use_client_driver(snum)
 
1883
                        && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
 
1884
                {
 
1885
                        r->in.access_mask = PRINTER_ACCESS_USE;
 
1886
                }
 
1887
 
 
1888
                /* check smb.conf parameters and the the sec_desc */
 
1889
 
 
1890
                if (!allow_access(lp_hostsdeny(snum), lp_hostsallow(snum),
 
1891
                                  p->client_id->name, p->client_id->addr)) {
 
1892
                        DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
 
1893
                        ZERO_STRUCTP(r->out.handle);
 
1894
                        return WERR_ACCESS_DENIED;
 
1895
                }
 
1896
 
 
1897
                if (!user_ok_token(uidtoname(p->session_info->utok.uid), NULL,
 
1898
                                   p->session_info->security_token, snum) ||
 
1899
                    !print_access_check(p->session_info,
 
1900
                                        p->msg_ctx,
 
1901
                                        snum,
 
1902
                                        r->in.access_mask)) {
 
1903
                        DEBUG(3, ("access DENIED for printer open\n"));
 
1904
                        close_printer_handle(p, r->out.handle);
 
1905
                        ZERO_STRUCTP(r->out.handle);
 
1906
                        return WERR_ACCESS_DENIED;
 
1907
                }
 
1908
 
 
1909
                if ((r->in.access_mask & SEC_MASK_SPECIFIC)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
 
1910
                        DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
 
1911
                        close_printer_handle(p, r->out.handle);
 
1912
                        ZERO_STRUCTP(r->out.handle);
 
1913
                        return WERR_ACCESS_DENIED;
 
1914
                }
 
1915
 
 
1916
                if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
 
1917
                        r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
 
1918
                else
 
1919
                        r->in.access_mask = PRINTER_ACCESS_USE;
 
1920
 
 
1921
                DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
 
1922
                        ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
 
1923
 
 
1924
                winreg_create_printer_internal(p->mem_ctx,
 
1925
                                      get_session_info_system(),
 
1926
                                      p->msg_ctx,
 
1927
                                      lp_const_servicename(snum));
 
1928
 
 
1929
                break;
 
1930
 
 
1931
        default:
 
1932
                /* sanity check to prevent programmer error */
 
1933
                ZERO_STRUCTP(r->out.handle);
 
1934
                return WERR_BADFID;
 
1935
        }
 
1936
 
 
1937
        Printer->access_granted = r->in.access_mask;
 
1938
 
 
1939
        /*
 
1940
         * If the client sent a devmode in the OpenPrinter() call, then
 
1941
         * save it here in case we get a job submission on this handle
 
1942
         */
 
1943
 
 
1944
         if ((Printer->printer_type != SPLHND_SERVER) &&
 
1945
             r->in.devmode_ctr.devmode) {
 
1946
                copy_devicemode(NULL, r->in.devmode_ctr.devmode,
 
1947
                                &Printer->devmode);
 
1948
         }
 
1949
 
 
1950
#if 0   /* JERRY -- I'm doubtful this is really effective */
 
1951
        /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
 
1952
           optimization in Windows 2000 clients  --jerry */
 
1953
 
 
1954
        if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
 
1955
                && (RA_WIN2K == get_remote_arch()) )
 
1956
        {
 
1957
                DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
 
1958
                sys_usleep( 500000 );
 
1959
        }
 
1960
#endif
 
1961
 
 
1962
        return WERR_OK;
 
1963
}
 
1964
 
 
1965
/****************************************************************
 
1966
 _spoolss_ClosePrinter
 
1967
****************************************************************/
 
1968
 
 
1969
WERROR _spoolss_ClosePrinter(struct pipes_struct *p,
 
1970
                             struct spoolss_ClosePrinter *r)
 
1971
{
 
1972
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
1973
 
 
1974
        if (Printer && Printer->document_started) {
 
1975
                struct spoolss_EndDocPrinter e;
 
1976
 
 
1977
                e.in.handle = r->in.handle;
 
1978
 
 
1979
                _spoolss_EndDocPrinter(p, &e);
 
1980
        }
 
1981
 
 
1982
        if (!close_printer_handle(p, r->in.handle))
 
1983
                return WERR_BADFID;
 
1984
 
 
1985
        /* clear the returned printer handle.  Observed behavior
 
1986
           from Win2k server.  Don't think this really matters.
 
1987
           Previous code just copied the value of the closed
 
1988
           handle.    --jerry */
 
1989
 
 
1990
        ZERO_STRUCTP(r->out.handle);
 
1991
 
 
1992
        return WERR_OK;
 
1993
}
 
1994
 
 
1995
/****************************************************************
 
1996
 _spoolss_DeletePrinter
 
1997
****************************************************************/
 
1998
 
 
1999
WERROR _spoolss_DeletePrinter(struct pipes_struct *p,
 
2000
                              struct spoolss_DeletePrinter *r)
 
2001
{
 
2002
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
2003
        WERROR result;
 
2004
        int snum;
 
2005
 
 
2006
        if (Printer && Printer->document_started) {
 
2007
                struct spoolss_EndDocPrinter e;
 
2008
 
 
2009
                e.in.handle = r->in.handle;
 
2010
 
 
2011
                _spoolss_EndDocPrinter(p, &e);
 
2012
        }
 
2013
 
 
2014
        if (get_printer_snum(p, r->in.handle, &snum, NULL)) {
 
2015
                winreg_delete_printer_key_internal(p->mem_ctx,
 
2016
                                          get_session_info_system(),
 
2017
                                          p->msg_ctx,
 
2018
                                          lp_const_servicename(snum),
 
2019
                                          "");
 
2020
        }
 
2021
 
 
2022
        result = delete_printer_handle(p, r->in.handle);
 
2023
 
 
2024
        return result;
 
2025
}
 
2026
 
 
2027
/*******************************************************************
 
2028
 * static function to lookup the version id corresponding to an
 
2029
 * long architecture string
 
2030
 ******************************************************************/
 
2031
 
 
2032
static const struct print_architecture_table_node archi_table[]= {
 
2033
 
 
2034
        {"Windows 4.0",          SPL_ARCH_WIN40,        0 },
 
2035
        {"Windows NT x86",       SPL_ARCH_W32X86,       2 },
 
2036
        {"Windows NT R4000",     SPL_ARCH_W32MIPS,      2 },
 
2037
        {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA,     2 },
 
2038
        {"Windows NT PowerPC",   SPL_ARCH_W32PPC,       2 },
 
2039
        {"Windows IA64",         SPL_ARCH_IA64,         3 },
 
2040
        {"Windows x64",          SPL_ARCH_X64,          3 },
 
2041
        {NULL,                   "",            -1 }
 
2042
};
 
2043
 
 
2044
static int get_version_id(const char *arch)
 
2045
{
 
2046
        int i;
 
2047
 
 
2048
        for (i=0; archi_table[i].long_archi != NULL; i++)
 
2049
        {
 
2050
                if (strcmp(arch, archi_table[i].long_archi) == 0)
 
2051
                        return (archi_table[i].version);
 
2052
        }
 
2053
 
 
2054
        return -1;
 
2055
}
 
2056
 
 
2057
/****************************************************************
 
2058
 _spoolss_DeletePrinterDriver
 
2059
****************************************************************/
 
2060
 
 
2061
WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
 
2062
                                    struct spoolss_DeletePrinterDriver *r)
 
2063
{
 
2064
 
 
2065
        struct spoolss_DriverInfo8 *info = NULL;
 
2066
        struct spoolss_DriverInfo8 *info_win2k = NULL;
 
2067
        int                             version;
 
2068
        WERROR                          status;
 
2069
        struct dcerpc_binding_handle *b;
 
2070
 
 
2071
        /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
 
2072
           and not a printer admin, then fail */
 
2073
 
 
2074
        if ( (p->session_info->utok.uid != sec_initial_uid())
 
2075
             && !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_PRINT_OPERATOR)
 
2076
                && !token_contains_name_in_list(
 
2077
                        uidtoname(p->session_info->utok.uid),
 
2078
                        p->session_info->info3->base.domain.string,
 
2079
                        NULL,
 
2080
                        p->session_info->security_token,
 
2081
                        lp_printer_admin(-1)) )
 
2082
        {
 
2083
                return WERR_ACCESS_DENIED;
 
2084
        }
 
2085
 
 
2086
        /* check that we have a valid driver name first */
 
2087
 
 
2088
        if ((version = get_version_id(r->in.architecture)) == -1)
 
2089
                return WERR_INVALID_ENVIRONMENT;
 
2090
 
 
2091
        status = winreg_printer_binding_handle(p->mem_ctx,
 
2092
                                               get_session_info_system(),
 
2093
                                               p->msg_ctx,
 
2094
                                               &b);
 
2095
        if (!W_ERROR_IS_OK(status)) {
 
2096
                return status;
 
2097
        }
 
2098
 
 
2099
        status = winreg_get_driver(p->mem_ctx, b,
 
2100
                                   r->in.architecture, r->in.driver,
 
2101
                                   version, &info);
 
2102
        if (!W_ERROR_IS_OK(status)) {
 
2103
                /* try for Win2k driver if "Windows NT x86" */
 
2104
 
 
2105
                if ( version == 2 ) {
 
2106
                        version = 3;
 
2107
 
 
2108
                        status = winreg_get_driver(p->mem_ctx, b,
 
2109
                                                   r->in.architecture,
 
2110
                                                   r->in.driver,
 
2111
                                                   version, &info);
 
2112
                        if (!W_ERROR_IS_OK(status)) {
 
2113
                                status = WERR_UNKNOWN_PRINTER_DRIVER;
 
2114
                                goto done;
 
2115
                        }
 
2116
                }
 
2117
                /* otherwise it was a failure */
 
2118
                else {
 
2119
                        status = WERR_UNKNOWN_PRINTER_DRIVER;
 
2120
                        goto done;
 
2121
                }
 
2122
 
 
2123
        }
 
2124
 
 
2125
        if (printer_driver_in_use(p->mem_ctx,
 
2126
                                  get_session_info_system(),
 
2127
                                  p->msg_ctx,
 
2128
                                  info)) {
 
2129
                status = WERR_PRINTER_DRIVER_IN_USE;
 
2130
                goto done;
 
2131
        }
 
2132
 
 
2133
        if (version == 2) {
 
2134
                status = winreg_get_driver(p->mem_ctx, b,
 
2135
                                           r->in.architecture,
 
2136
                                           r->in.driver, 3, &info_win2k);
 
2137
                if (W_ERROR_IS_OK(status)) {
 
2138
                        /* if we get to here, we now have 2 driver info structures to remove */
 
2139
                        /* remove the Win2k driver first*/
 
2140
 
 
2141
                        status = winreg_del_driver(p->mem_ctx, b,
 
2142
                                                   info_win2k, 3);
 
2143
                        talloc_free(info_win2k);
 
2144
 
 
2145
                        /* this should not have failed---if it did, report to client */
 
2146
                        if (!W_ERROR_IS_OK(status)) {
 
2147
                                goto done;
 
2148
                        }
 
2149
                }
 
2150
        }
 
2151
 
 
2152
        status = winreg_del_driver(p->mem_ctx, b,
 
2153
                                   info, version);
 
2154
 
 
2155
done:
 
2156
        talloc_free(info);
 
2157
 
 
2158
        return status;
 
2159
}
 
2160
 
 
2161
/****************************************************************
 
2162
 _spoolss_DeletePrinterDriverEx
 
2163
****************************************************************/
 
2164
 
 
2165
WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
 
2166
                                      struct spoolss_DeletePrinterDriverEx *r)
 
2167
{
 
2168
        struct spoolss_DriverInfo8      *info = NULL;
 
2169
        struct spoolss_DriverInfo8      *info_win2k = NULL;
 
2170
        int                             version;
 
2171
        bool                            delete_files;
 
2172
        WERROR                          status;
 
2173
        struct dcerpc_binding_handle *b;
 
2174
 
 
2175
        /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
 
2176
           and not a printer admin, then fail */
 
2177
 
 
2178
        if ( (p->session_info->utok.uid != sec_initial_uid())
 
2179
                && !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_PRINT_OPERATOR)
 
2180
                && !token_contains_name_in_list(
 
2181
                        uidtoname(p->session_info->utok.uid),
 
2182
                        p->session_info->info3->base.domain.string,
 
2183
                        NULL,
 
2184
                        p->session_info->security_token, lp_printer_admin(-1)) )
 
2185
        {
 
2186
                return WERR_ACCESS_DENIED;
 
2187
        }
 
2188
 
 
2189
        /* check that we have a valid driver name first */
 
2190
        if ((version = get_version_id(r->in.architecture)) == -1) {
 
2191
                /* this is what NT returns */
 
2192
                return WERR_INVALID_ENVIRONMENT;
 
2193
        }
 
2194
 
 
2195
        if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
 
2196
                version = r->in.version;
 
2197
 
 
2198
        status = winreg_printer_binding_handle(p->mem_ctx,
 
2199
                                               get_session_info_system(),
 
2200
                                               p->msg_ctx,
 
2201
                                               &b);
 
2202
        if (!W_ERROR_IS_OK(status)) {
 
2203
                return status;
 
2204
        }
 
2205
 
 
2206
        status = winreg_get_driver(p->mem_ctx, b,
 
2207
                                   r->in.architecture,
 
2208
                                   r->in.driver,
 
2209
                                   version,
 
2210
                                   &info);
 
2211
        if (!W_ERROR_IS_OK(status)) {
 
2212
                status = WERR_UNKNOWN_PRINTER_DRIVER;
 
2213
 
 
2214
                /*
 
2215
                 * if the client asked for a specific version,
 
2216
                 * or this is something other than Windows NT x86,
 
2217
                 * then we've failed
 
2218
                 */
 
2219
 
 
2220
                if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
 
2221
                        goto done;
 
2222
 
 
2223
                /* try for Win2k driver if "Windows NT x86" */
 
2224
 
 
2225
                version = 3;
 
2226
                status = winreg_get_driver(info, b,
 
2227
                                           r->in.architecture,
 
2228
                                           r->in.driver,
 
2229
                                           version, &info);
 
2230
                if (!W_ERROR_IS_OK(status)) {
 
2231
                        status = WERR_UNKNOWN_PRINTER_DRIVER;
 
2232
                        goto done;
 
2233
                }
 
2234
        }
 
2235
 
 
2236
        if (printer_driver_in_use(info,
 
2237
                                  get_session_info_system(),
 
2238
                                  p->msg_ctx,
 
2239
                                  info)) {
 
2240
                status = WERR_PRINTER_DRIVER_IN_USE;
 
2241
                goto done;
 
2242
        }
 
2243
 
 
2244
        /*
 
2245
         * we have a couple of cases to consider.
 
2246
         * (1) Are any files in use?  If so and DPD_DELTE_ALL_FILE is set,
 
2247
         *     then the delete should fail if **any** files overlap with
 
2248
         *     other drivers
 
2249
         * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
 
2250
         *     non-overlapping files
 
2251
         * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
 
2252
         *     is set, the do not delete any files
 
2253
         * Refer to MSDN docs on DeletePrinterDriverEx() for details.
 
2254
         */
 
2255
 
 
2256
        delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
 
2257
 
 
2258
        /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
 
2259
 
 
2260
        if (delete_files &&
 
2261
            (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
 
2262
            printer_driver_files_in_use(info,
 
2263
                                        get_session_info_system(),
 
2264
                                        p->msg_ctx,
 
2265
                                        info)) {
 
2266
                /* no idea of the correct error here */
 
2267
                status = WERR_ACCESS_DENIED;
 
2268
                goto done;
 
2269
        }
 
2270
 
 
2271
 
 
2272
        /* also check for W32X86/3 if necessary; maybe we already have? */
 
2273
 
 
2274
        if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION)  ) {
 
2275
                status = winreg_get_driver(info, b,
 
2276
                                           r->in.architecture,
 
2277
                                           r->in.driver, 3, &info_win2k);
 
2278
                if (W_ERROR_IS_OK(status)) {
 
2279
 
 
2280
                        if (delete_files &&
 
2281
                            (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
 
2282
                            printer_driver_files_in_use(info,
 
2283
                                                        get_session_info_system(),
 
2284
                                                        p->msg_ctx,
 
2285
                                                        info_win2k)) {
 
2286
                                /* no idea of the correct error here */
 
2287
                                talloc_free(info_win2k);
 
2288
                                status = WERR_ACCESS_DENIED;
 
2289
                                goto done;
 
2290
                        }
 
2291
 
 
2292
                        /* if we get to here, we now have 2 driver info structures to remove */
 
2293
                        /* remove the Win2k driver first*/
 
2294
 
 
2295
                        status = winreg_del_driver(info, b,
 
2296
                                                   info_win2k,
 
2297
                                                   3);
 
2298
 
 
2299
                        /* this should not have failed---if it did, report to client */
 
2300
 
 
2301
                        if (!W_ERROR_IS_OK(status)) {
 
2302
                                goto done;
 
2303
                        }
 
2304
 
 
2305
                        /*
 
2306
                         * now delete any associated files if delete_files is
 
2307
                         * true. Even if this part failes, we return succes
 
2308
                         * because the driver doesn not exist any more
 
2309
                         */
 
2310
                        if (delete_files) {
 
2311
                                delete_driver_files(get_session_info_system(),
 
2312
                                                    info_win2k);
 
2313
                        }
 
2314
                }
 
2315
        }
 
2316
 
 
2317
        status = winreg_del_driver(info, b,
 
2318
                                   info,
 
2319
                                   version);
 
2320
        if (!W_ERROR_IS_OK(status)) {
 
2321
                goto done;
 
2322
        }
 
2323
 
 
2324
        /*
 
2325
         * now delete any associated files if delete_files is
 
2326
         * true. Even if this part failes, we return succes
 
2327
         * because the driver doesn not exist any more
 
2328
         */
 
2329
        if (delete_files) {
 
2330
                delete_driver_files(get_session_info_system(), info);
 
2331
        }
 
2332
 
 
2333
done:
 
2334
        talloc_free(info);
 
2335
        return status;
 
2336
}
 
2337
 
 
2338
 
 
2339
/********************************************************************
 
2340
 GetPrinterData on a printer server Handle.
 
2341
********************************************************************/
 
2342
 
 
2343
static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
 
2344
                                            const char *value,
 
2345
                                            enum winreg_Type *type,
 
2346
                                            union spoolss_PrinterData *data)
 
2347
{
 
2348
        DEBUG(8,("getprinterdata_printer_server:%s\n", value));
 
2349
 
 
2350
        if (!StrCaseCmp(value, "W3SvcInstalled")) {
 
2351
                *type = REG_DWORD;
 
2352
                data->value = 0x00;
 
2353
                return WERR_OK;
 
2354
        }
 
2355
 
 
2356
        if (!StrCaseCmp(value, "BeepEnabled")) {
 
2357
                *type = REG_DWORD;
 
2358
                data->value = 0x00;
 
2359
                return WERR_OK;
 
2360
        }
 
2361
 
 
2362
        if (!StrCaseCmp(value, "EventLog")) {
 
2363
                *type = REG_DWORD;
 
2364
                /* formally was 0x1b */
 
2365
                data->value = 0x00;
 
2366
                return WERR_OK;
 
2367
        }
 
2368
 
 
2369
        if (!StrCaseCmp(value, "NetPopup")) {
 
2370
                *type = REG_DWORD;
 
2371
                data->value = 0x00;
 
2372
                return WERR_OK;
 
2373
        }
 
2374
 
 
2375
        if (!StrCaseCmp(value, "MajorVersion")) {
 
2376
                *type = REG_DWORD;
 
2377
 
 
2378
                /* Windows NT 4.0 seems to not allow uploading of drivers
 
2379
                   to a server that reports 0x3 as the MajorVersion.
 
2380
                   need to investigate more how Win2k gets around this .
 
2381
                   -- jerry */
 
2382
 
 
2383
                if (RA_WINNT == get_remote_arch()) {
 
2384
                        data->value = 0x02;
 
2385
                } else {
 
2386
                        data->value = 0x03;
 
2387
                }
 
2388
 
 
2389
                return WERR_OK;
 
2390
        }
 
2391
 
 
2392
        if (!StrCaseCmp(value, "MinorVersion")) {
 
2393
                *type = REG_DWORD;
 
2394
                data->value = 0x00;
 
2395
                return WERR_OK;
 
2396
        }
 
2397
 
 
2398
        /* REG_BINARY
 
2399
         *  uint32_t size        = 0x114
 
2400
         *  uint32_t major       = 5
 
2401
         *  uint32_t minor       = [0|1]
 
2402
         *  uint32_t build       = [2195|2600]
 
2403
         *  extra unicode string = e.g. "Service Pack 3"
 
2404
         */
 
2405
        if (!StrCaseCmp(value, "OSVersion")) {
 
2406
                DATA_BLOB blob;
 
2407
                enum ndr_err_code ndr_err;
 
2408
                struct spoolss_OSVersion os;
 
2409
 
 
2410
                os.major                = 5;    /* Windows 2000 == 5.0 */
 
2411
                os.minor                = 0;
 
2412
                os.build                = 2195; /* build */
 
2413
                os.extra_string         = "";   /* leave extra string empty */
 
2414
 
 
2415
                ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os,
 
2416
                        (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
 
2417
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 
2418
                        return WERR_GENERAL_FAILURE;
 
2419
                }
 
2420
 
 
2421
                *type = REG_BINARY;
 
2422
                data->binary = blob;
 
2423
 
 
2424
                return WERR_OK;
 
2425
        }
 
2426
 
 
2427
 
 
2428
        if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
 
2429
                *type = REG_SZ;
 
2430
 
 
2431
                data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
 
2432
                W_ERROR_HAVE_NO_MEMORY(data->string);
 
2433
 
 
2434
                return WERR_OK;
 
2435
        }
 
2436
 
 
2437
        if (!StrCaseCmp(value, "Architecture")) {
 
2438
                *type = REG_SZ;
 
2439
                data->string = talloc_strdup(mem_ctx,
 
2440
                        lp_parm_const_string(GLOBAL_SECTION_SNUM, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86));
 
2441
                W_ERROR_HAVE_NO_MEMORY(data->string);
 
2442
 
 
2443
                return WERR_OK;
 
2444
        }
 
2445
 
 
2446
        if (!StrCaseCmp(value, "DsPresent")) {
 
2447
                *type = REG_DWORD;
 
2448
 
 
2449
                /* only show the publish check box if we are a
 
2450
                   member of a AD domain */
 
2451
 
 
2452
                if (lp_security() == SEC_ADS) {
 
2453
                        data->value = 0x01;
 
2454
                } else {
 
2455
                        data->value = 0x00;
 
2456
                }
 
2457
                return WERR_OK;
 
2458
        }
 
2459
 
 
2460
        if (!StrCaseCmp(value, "DNSMachineName")) {
 
2461
                const char *hostname = get_mydnsfullname();
 
2462
 
 
2463
                if (!hostname) {
 
2464
                        return WERR_BADFILE;
 
2465
                }
 
2466
 
 
2467
                *type = REG_SZ;
 
2468
                data->string = talloc_strdup(mem_ctx, hostname);
 
2469
                W_ERROR_HAVE_NO_MEMORY(data->string);
 
2470
 
 
2471
                return WERR_OK;
 
2472
        }
 
2473
 
 
2474
        *type = REG_NONE;
 
2475
 
 
2476
        return WERR_INVALID_PARAM;
 
2477
}
 
2478
 
 
2479
/****************************************************************
 
2480
 _spoolss_GetPrinterData
 
2481
****************************************************************/
 
2482
 
 
2483
WERROR _spoolss_GetPrinterData(struct pipes_struct *p,
 
2484
                               struct spoolss_GetPrinterData *r)
 
2485
{
 
2486
        struct spoolss_GetPrinterDataEx r2;
 
2487
 
 
2488
        r2.in.handle            = r->in.handle;
 
2489
        r2.in.key_name          = "PrinterDriverData";
 
2490
        r2.in.value_name        = r->in.value_name;
 
2491
        r2.in.offered           = r->in.offered;
 
2492
        r2.out.type             = r->out.type;
 
2493
        r2.out.data             = r->out.data;
 
2494
        r2.out.needed           = r->out.needed;
 
2495
 
 
2496
        return _spoolss_GetPrinterDataEx(p, &r2);
 
2497
}
 
2498
 
 
2499
/*********************************************************
 
2500
 Connect to the client machine.
 
2501
**********************************************************/
 
2502
 
 
2503
static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
 
2504
                        struct sockaddr_storage *client_ss, const char *remote_machine)
 
2505
{
 
2506
        NTSTATUS ret;
 
2507
        struct cli_state *the_cli;
 
2508
        struct sockaddr_storage rm_addr;
 
2509
        char addr[INET6_ADDRSTRLEN];
 
2510
 
 
2511
        if ( is_zero_addr(client_ss) ) {
 
2512
                DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
 
2513
                        remote_machine));
 
2514
                if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
 
2515
                        DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
 
2516
                        return false;
 
2517
                }
 
2518
                print_sockaddr(addr, sizeof(addr), &rm_addr);
 
2519
        } else {
 
2520
                rm_addr = *client_ss;
 
2521
                print_sockaddr(addr, sizeof(addr), &rm_addr);
 
2522
                DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
 
2523
                        addr));
 
2524
        }
 
2525
 
 
2526
        if (ismyaddr((struct sockaddr *)(void *)&rm_addr)) {
 
2527
                DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
 
2528
                        addr));
 
2529
                return false;
 
2530
        }
 
2531
 
 
2532
        /* setup the connection */
 
2533
        ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
 
2534
                &rm_addr, 0, "IPC$", "IPC",
 
2535
                "", /* username */
 
2536
                "", /* domain */
 
2537
                "", /* password */
 
2538
                0, lp_client_signing());
 
2539
 
 
2540
        if ( !NT_STATUS_IS_OK( ret ) ) {
 
2541
                DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
 
2542
                        remote_machine ));
 
2543
                return false;
 
2544
        }
 
2545
 
 
2546
        if ( the_cli->protocol != PROTOCOL_NT1 ) {
 
2547
                DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
 
2548
                cli_shutdown(the_cli);
 
2549
                return false;
 
2550
        }
 
2551
 
 
2552
        /*
 
2553
         * Ok - we have an anonymous connection to the IPC$ share.
 
2554
         * Now start the NT Domain stuff :-).
 
2555
         */
 
2556
 
 
2557
        ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
 
2558
        if (!NT_STATUS_IS_OK(ret)) {
 
2559
                DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
 
2560
                        remote_machine, nt_errstr(ret)));
 
2561
                cli_shutdown(the_cli);
 
2562
                return false;
 
2563
        }
 
2564
 
 
2565
        return true;
 
2566
}
 
2567
 
 
2568
/***************************************************************************
 
2569
 Connect to the client.
 
2570
****************************************************************************/
 
2571
 
 
2572
static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
 
2573
                                        uint32_t localprinter,
 
2574
                                        enum winreg_Type type,
 
2575
                                        struct policy_handle *handle,
 
2576
                                        struct notify_back_channel **_chan,
 
2577
                                        struct sockaddr_storage *client_ss,
 
2578
                                        struct messaging_context *msg_ctx)
 
2579
{
 
2580
        WERROR result;
 
2581
        NTSTATUS status;
 
2582
        struct notify_back_channel *chan;
 
2583
 
 
2584
        for (chan = back_channels; chan; chan = chan->next) {
 
2585
                if (memcmp(&chan->client_address, client_ss,
 
2586
                           sizeof(struct sockaddr_storage)) == 0) {
 
2587
                        break;
 
2588
                }
 
2589
        }
 
2590
 
 
2591
        /*
 
2592
         * If it's the first connection, contact the client
 
2593
         * and connect to the IPC$ share anonymously
 
2594
         */
 
2595
        if (!chan) {
 
2596
                fstring unix_printer;
 
2597
 
 
2598
                /* the +2 is to strip the leading 2 backslashs */
 
2599
                fstrcpy(unix_printer, printer + 2);
 
2600
 
 
2601
                chan = talloc_zero(back_channels, struct notify_back_channel);
 
2602
                if (!chan) {
 
2603
                        return false;
 
2604
                }
 
2605
                chan->client_address = *client_ss;
 
2606
 
 
2607
                if (!spoolss_connect_to_client(&chan->cli_pipe, client_ss, unix_printer)) {
 
2608
                        TALLOC_FREE(chan);
 
2609
                        return false;
 
2610
                }
 
2611
                chan->binding_handle = chan->cli_pipe->binding_handle;
 
2612
 
 
2613
                DLIST_ADD(back_channels, chan);
 
2614
 
 
2615
                messaging_register(msg_ctx, NULL, MSG_PRINTER_NOTIFY2,
 
2616
                                   receive_notify2_message_list);
 
2617
                /* Tell the connections db we're now interested in printer
 
2618
                 * notify messages. */
 
2619
                serverid_register_msg_flags(messaging_server_id(msg_ctx),
 
2620
                                            true, FLAG_MSG_PRINT_NOTIFY);
 
2621
        }
 
2622
 
 
2623
        /*
 
2624
         * Tell the specific printing tdb we want messages for this printer
 
2625
         * by registering our PID.
 
2626
         */
 
2627
 
 
2628
        if (!print_notify_register_pid(snum)) {
 
2629
                DEBUG(0, ("Failed to register our pid for printer %s\n",
 
2630
                          printer));
 
2631
        }
 
2632
 
 
2633
        status = dcerpc_spoolss_ReplyOpenPrinter(chan->binding_handle,
 
2634
                                                 talloc_tos(),
 
2635
                                                 printer,
 
2636
                                                 localprinter,
 
2637
                                                 type,
 
2638
                                                 0,
 
2639
                                                 NULL,
 
2640
                                                 handle,
 
2641
                                                 &result);
 
2642
        if (!NT_STATUS_IS_OK(status)) {
 
2643
                DEBUG(5, ("dcerpc_spoolss_ReplyOpenPrinter returned [%s]\n", nt_errstr(status)));
 
2644
                result = ntstatus_to_werror(status);
 
2645
        } else if (!W_ERROR_IS_OK(result)) {
 
2646
                DEBUG(5, ("ReplyOpenPrinter returned [%s]\n", win_errstr(result)));
 
2647
        }
 
2648
 
 
2649
        chan->active_connections++;
 
2650
        *_chan = chan;
 
2651
 
 
2652
        return (W_ERROR_IS_OK(result));
 
2653
}
 
2654
 
 
2655
/****************************************************************
 
2656
 ****************************************************************/
 
2657
 
 
2658
static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
 
2659
                                                             const struct spoolss_NotifyOption *r)
 
2660
{
 
2661
        struct spoolss_NotifyOption *option;
 
2662
        uint32_t i,k;
 
2663
 
 
2664
        if (!r) {
 
2665
                return NULL;
 
2666
        }
 
2667
 
 
2668
        option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
 
2669
        if (!option) {
 
2670
                return NULL;
 
2671
        }
 
2672
 
 
2673
        *option = *r;
 
2674
 
 
2675
        if (!option->count) {
 
2676
                return option;
 
2677
        }
 
2678
 
 
2679
        option->types = talloc_zero_array(option,
 
2680
                struct spoolss_NotifyOptionType, option->count);
 
2681
        if (!option->types) {
 
2682
                talloc_free(option);
 
2683
                return NULL;
 
2684
        }
 
2685
 
 
2686
        for (i=0; i < option->count; i++) {
 
2687
                option->types[i] = r->types[i];
 
2688
 
 
2689
                if (option->types[i].count) {
 
2690
                        option->types[i].fields = talloc_zero_array(option,
 
2691
                                union spoolss_Field, option->types[i].count);
 
2692
                        if (!option->types[i].fields) {
 
2693
                                talloc_free(option);
 
2694
                                return NULL;
 
2695
                        }
 
2696
                        for (k=0; k<option->types[i].count; k++) {
 
2697
                                option->types[i].fields[k] =
 
2698
                                        r->types[i].fields[k];
 
2699
                        }
 
2700
                }
 
2701
        }
 
2702
 
 
2703
        return option;
 
2704
}
 
2705
 
 
2706
/****************************************************************
 
2707
 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
 
2708
 *
 
2709
 * before replying OK: status=0 a rpc call is made to the workstation
 
2710
 * asking ReplyOpenPrinter
 
2711
 *
 
2712
 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
 
2713
 * called from api_spoolss_rffpcnex
 
2714
****************************************************************/
 
2715
 
 
2716
WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct pipes_struct *p,
 
2717
                                                     struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
 
2718
{
 
2719
        int snum = -1;
 
2720
        struct spoolss_NotifyOption *option = r->in.notify_options;
 
2721
        struct sockaddr_storage client_ss;
 
2722
 
 
2723
        /* store the notify value in the printer struct */
 
2724
 
 
2725
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
2726
 
 
2727
        if (!Printer) {
 
2728
                DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
 
2729
                        "Invalid handle (%s:%u:%u).\n",
 
2730
                        OUR_HANDLE(r->in.handle)));
 
2731
                return WERR_BADFID;
 
2732
        }
 
2733
 
 
2734
        Printer->notify.flags           = r->in.flags;
 
2735
        Printer->notify.options         = r->in.options;
 
2736
        Printer->notify.printerlocal    = r->in.printer_local;
 
2737
        Printer->notify.msg_ctx         = p->msg_ctx;
 
2738
 
 
2739
        TALLOC_FREE(Printer->notify.option);
 
2740
        Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
 
2741
 
 
2742
        fstrcpy(Printer->notify.localmachine, r->in.local_machine);
 
2743
 
 
2744
        /* Connect to the client machine and send a ReplyOpenPrinter */
 
2745
 
 
2746
        if ( Printer->printer_type == SPLHND_SERVER)
 
2747
                snum = -1;
 
2748
        else if ( (Printer->printer_type == SPLHND_PRINTER) &&
 
2749
                        !get_printer_snum(p, r->in.handle, &snum, NULL) )
 
2750
                return WERR_BADFID;
 
2751
 
 
2752
        DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
 
2753
                "client_address is %s\n", p->client_id->addr));
 
2754
 
 
2755
        if (!lp_print_notify_backchannel(snum)) {
 
2756
                DEBUG(10, ("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
 
2757
                        "backchannel disabled\n"));
 
2758
                return WERR_SERVER_UNAVAILABLE;
 
2759
        }
 
2760
 
 
2761
        if (!interpret_string_addr(&client_ss, p->client_id->addr,
 
2762
                                   AI_NUMERICHOST)) {
 
2763
                return WERR_SERVER_UNAVAILABLE;
 
2764
        }
 
2765
 
 
2766
        if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
 
2767
                                        Printer->notify.printerlocal, REG_SZ,
 
2768
                                        &Printer->notify.cli_hnd,
 
2769
                                        &Printer->notify.cli_chan,
 
2770
                                        &client_ss, p->msg_ctx)) {
 
2771
                return WERR_SERVER_UNAVAILABLE;
 
2772
        }
 
2773
 
 
2774
        return WERR_OK;
 
2775
}
 
2776
 
 
2777
/*******************************************************************
 
2778
 * fill a notify_info_data with the servername
 
2779
 ********************************************************************/
 
2780
 
 
2781
static void spoolss_notify_server_name(struct messaging_context *msg_ctx,
 
2782
                                       int snum,
 
2783
                                       struct spoolss_Notify *data,
 
2784
                                       print_queue_struct *queue,
 
2785
                                       struct spoolss_PrinterInfo2 *pinfo2,
 
2786
                                       TALLOC_CTX *mem_ctx)
 
2787
{
 
2788
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->servername);
 
2789
}
 
2790
 
 
2791
/*******************************************************************
 
2792
 * fill a notify_info_data with the printername (not including the servername).
 
2793
 ********************************************************************/
 
2794
 
 
2795
static void spoolss_notify_printer_name(struct messaging_context *msg_ctx,
 
2796
                                        int snum,
 
2797
                                        struct spoolss_Notify *data,
 
2798
                                        print_queue_struct *queue,
 
2799
                                        struct spoolss_PrinterInfo2 *pinfo2,
 
2800
                                        TALLOC_CTX *mem_ctx)
 
2801
{
 
2802
        /* the notify name should not contain the \\server\ part */
 
2803
        const char *p = strrchr(pinfo2->printername, '\\');
 
2804
 
 
2805
        if (!p) {
 
2806
                p = pinfo2->printername;
 
2807
        } else {
 
2808
                p++;
 
2809
        }
 
2810
 
 
2811
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
 
2812
}
 
2813
 
 
2814
/*******************************************************************
 
2815
 * fill a notify_info_data with the servicename
 
2816
 ********************************************************************/
 
2817
 
 
2818
static void spoolss_notify_share_name(struct messaging_context *msg_ctx,
 
2819
                                      int snum,
 
2820
                                      struct spoolss_Notify *data,
 
2821
                                      print_queue_struct *queue,
 
2822
                                      struct spoolss_PrinterInfo2 *pinfo2,
 
2823
                                      TALLOC_CTX *mem_ctx)
 
2824
{
 
2825
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
 
2826
}
 
2827
 
 
2828
/*******************************************************************
 
2829
 * fill a notify_info_data with the port name
 
2830
 ********************************************************************/
 
2831
 
 
2832
static void spoolss_notify_port_name(struct messaging_context *msg_ctx,
 
2833
                                     int snum,
 
2834
                                     struct spoolss_Notify *data,
 
2835
                                     print_queue_struct *queue,
 
2836
                                     struct spoolss_PrinterInfo2 *pinfo2,
 
2837
                                     TALLOC_CTX *mem_ctx)
 
2838
{
 
2839
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->portname);
 
2840
}
 
2841
 
 
2842
/*******************************************************************
 
2843
 * fill a notify_info_data with the printername
 
2844
 * but it doesn't exist, have to see what to do
 
2845
 ********************************************************************/
 
2846
 
 
2847
static void spoolss_notify_driver_name(struct messaging_context *msg_ctx,
 
2848
                                       int snum,
 
2849
                                       struct spoolss_Notify *data,
 
2850
                                       print_queue_struct *queue,
 
2851
                                       struct spoolss_PrinterInfo2 *pinfo2,
 
2852
                                       TALLOC_CTX *mem_ctx)
 
2853
{
 
2854
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->drivername);
 
2855
}
 
2856
 
 
2857
/*******************************************************************
 
2858
 * fill a notify_info_data with the comment
 
2859
 ********************************************************************/
 
2860
 
 
2861
static void spoolss_notify_comment(struct messaging_context *msg_ctx,
 
2862
                                   int snum,
 
2863
                                   struct spoolss_Notify *data,
 
2864
                                   print_queue_struct *queue,
 
2865
                                   struct spoolss_PrinterInfo2 *pinfo2,
 
2866
                                   TALLOC_CTX *mem_ctx)
 
2867
{
 
2868
        const char *p;
 
2869
 
 
2870
        if (*pinfo2->comment == '\0') {
 
2871
                p = lp_comment(snum);
 
2872
        } else {
 
2873
                p = pinfo2->comment;
 
2874
        }
 
2875
 
 
2876
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
 
2877
}
 
2878
 
 
2879
/*******************************************************************
 
2880
 * fill a notify_info_data with the comment
 
2881
 * location = "Room 1, floor 2, building 3"
 
2882
 ********************************************************************/
 
2883
 
 
2884
static void spoolss_notify_location(struct messaging_context *msg_ctx,
 
2885
                                    int snum,
 
2886
                                    struct spoolss_Notify *data,
 
2887
                                    print_queue_struct *queue,
 
2888
                                    struct spoolss_PrinterInfo2 *pinfo2,
 
2889
                                    TALLOC_CTX *mem_ctx)
 
2890
{
 
2891
        const char *loc = pinfo2->location;
 
2892
        NTSTATUS status;
 
2893
 
 
2894
        status = printer_list_get_printer(mem_ctx,
 
2895
                                          pinfo2->sharename,
 
2896
                                          NULL,
 
2897
                                          &loc,
 
2898
                                          NULL);
 
2899
        if (NT_STATUS_IS_OK(status)) {
 
2900
                if (loc == NULL) {
 
2901
                        loc = pinfo2->location;
 
2902
                }
 
2903
        }
 
2904
 
 
2905
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, loc);
 
2906
}
 
2907
 
 
2908
/*******************************************************************
 
2909
 * fill a notify_info_data with the device mode
 
2910
 * jfm:xxxx don't to it for know but that's a real problem !!!
 
2911
 ********************************************************************/
 
2912
 
 
2913
static void spoolss_notify_devmode(struct messaging_context *msg_ctx,
 
2914
                                   int snum,
 
2915
                                   struct spoolss_Notify *data,
 
2916
                                   print_queue_struct *queue,
 
2917
                                   struct spoolss_PrinterInfo2 *pinfo2,
 
2918
                                   TALLOC_CTX *mem_ctx)
 
2919
{
 
2920
        /* for a dummy implementation we have to zero the fields */
 
2921
        SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
 
2922
}
 
2923
 
 
2924
/*******************************************************************
 
2925
 * fill a notify_info_data with the separator file name
 
2926
 ********************************************************************/
 
2927
 
 
2928
static void spoolss_notify_sepfile(struct messaging_context *msg_ctx,
 
2929
                                   int snum,
 
2930
                                   struct spoolss_Notify *data,
 
2931
                                   print_queue_struct *queue,
 
2932
                                   struct spoolss_PrinterInfo2 *pinfo2,
 
2933
                                   TALLOC_CTX *mem_ctx)
 
2934
{
 
2935
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->sepfile);
 
2936
}
 
2937
 
 
2938
/*******************************************************************
 
2939
 * fill a notify_info_data with the print processor
 
2940
 * jfm:xxxx return always winprint to indicate we don't do anything to it
 
2941
 ********************************************************************/
 
2942
 
 
2943
static void spoolss_notify_print_processor(struct messaging_context *msg_ctx,
 
2944
                                           int snum,
 
2945
                                           struct spoolss_Notify *data,
 
2946
                                           print_queue_struct *queue,
 
2947
                                           struct spoolss_PrinterInfo2 *pinfo2,
 
2948
                                           TALLOC_CTX *mem_ctx)
 
2949
{
 
2950
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->printprocessor);
 
2951
}
 
2952
 
 
2953
/*******************************************************************
 
2954
 * fill a notify_info_data with the print processor options
 
2955
 * jfm:xxxx send an empty string
 
2956
 ********************************************************************/
 
2957
 
 
2958
static void spoolss_notify_parameters(struct messaging_context *msg_ctx,
 
2959
                                      int snum,
 
2960
                                      struct spoolss_Notify *data,
 
2961
                                      print_queue_struct *queue,
 
2962
                                      struct spoolss_PrinterInfo2 *pinfo2,
 
2963
                                      TALLOC_CTX *mem_ctx)
 
2964
{
 
2965
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->parameters);
 
2966
}
 
2967
 
 
2968
/*******************************************************************
 
2969
 * fill a notify_info_data with the data type
 
2970
 * jfm:xxxx always send RAW as data type
 
2971
 ********************************************************************/
 
2972
 
 
2973
static void spoolss_notify_datatype(struct messaging_context *msg_ctx,
 
2974
                                    int snum,
 
2975
                                    struct spoolss_Notify *data,
 
2976
                                    print_queue_struct *queue,
 
2977
                                    struct spoolss_PrinterInfo2 *pinfo2,
 
2978
                                    TALLOC_CTX *mem_ctx)
 
2979
{
 
2980
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->datatype);
 
2981
}
 
2982
 
 
2983
/*******************************************************************
 
2984
 * fill a notify_info_data with the security descriptor
 
2985
 * jfm:xxxx send an null pointer to say no security desc
 
2986
 * have to implement security before !
 
2987
 ********************************************************************/
 
2988
 
 
2989
static void spoolss_notify_security_desc(struct messaging_context *msg_ctx,
 
2990
                                         int snum,
 
2991
                                         struct spoolss_Notify *data,
 
2992
                                         print_queue_struct *queue,
 
2993
                                         struct spoolss_PrinterInfo2 *pinfo2,
 
2994
                                         TALLOC_CTX *mem_ctx)
 
2995
{
 
2996
        SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data, pinfo2->secdesc);
 
2997
}
 
2998
 
 
2999
/*******************************************************************
 
3000
 * fill a notify_info_data with the attributes
 
3001
 * jfm:xxxx a samba printer is always shared
 
3002
 ********************************************************************/
 
3003
 
 
3004
static void spoolss_notify_attributes(struct messaging_context *msg_ctx,
 
3005
                                      int snum,
 
3006
                                      struct spoolss_Notify *data,
 
3007
                                      print_queue_struct *queue,
 
3008
                                      struct spoolss_PrinterInfo2 *pinfo2,
 
3009
                                      TALLOC_CTX *mem_ctx)
 
3010
{
 
3011
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->attributes);
 
3012
}
 
3013
 
 
3014
/*******************************************************************
 
3015
 * fill a notify_info_data with the priority
 
3016
 ********************************************************************/
 
3017
 
 
3018
static void spoolss_notify_priority(struct messaging_context *msg_ctx,
 
3019
                                    int snum,
 
3020
                                    struct spoolss_Notify *data,
 
3021
                                    print_queue_struct *queue,
 
3022
                                    struct spoolss_PrinterInfo2 *pinfo2,
 
3023
                                    TALLOC_CTX *mem_ctx)
 
3024
{
 
3025
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->priority);
 
3026
}
 
3027
 
 
3028
/*******************************************************************
 
3029
 * fill a notify_info_data with the default priority
 
3030
 ********************************************************************/
 
3031
 
 
3032
static void spoolss_notify_default_priority(struct messaging_context *msg_ctx,
 
3033
                                            int snum,
 
3034
                                            struct spoolss_Notify *data,
 
3035
                                            print_queue_struct *queue,
 
3036
                                            struct spoolss_PrinterInfo2 *pinfo2,
 
3037
                                            TALLOC_CTX *mem_ctx)
 
3038
{
 
3039
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->defaultpriority);
 
3040
}
 
3041
 
 
3042
/*******************************************************************
 
3043
 * fill a notify_info_data with the start time
 
3044
 ********************************************************************/
 
3045
 
 
3046
static void spoolss_notify_start_time(struct messaging_context *msg_ctx,
 
3047
                                      int snum,
 
3048
                                      struct spoolss_Notify *data,
 
3049
                                      print_queue_struct *queue,
 
3050
                                      struct spoolss_PrinterInfo2 *pinfo2,
 
3051
                                      TALLOC_CTX *mem_ctx)
 
3052
{
 
3053
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->starttime);
 
3054
}
 
3055
 
 
3056
/*******************************************************************
 
3057
 * fill a notify_info_data with the until time
 
3058
 ********************************************************************/
 
3059
 
 
3060
static void spoolss_notify_until_time(struct messaging_context *msg_ctx,
 
3061
                                      int snum,
 
3062
                                      struct spoolss_Notify *data,
 
3063
                                      print_queue_struct *queue,
 
3064
                                      struct spoolss_PrinterInfo2 *pinfo2,
 
3065
                                      TALLOC_CTX *mem_ctx)
 
3066
{
 
3067
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->untiltime);
 
3068
}
 
3069
 
 
3070
/*******************************************************************
 
3071
 * fill a notify_info_data with the status
 
3072
 ********************************************************************/
 
3073
 
 
3074
static void spoolss_notify_status(struct messaging_context *msg_ctx,
 
3075
                                  int snum,
 
3076
                                  struct spoolss_Notify *data,
 
3077
                                  print_queue_struct *queue,
 
3078
                                  struct spoolss_PrinterInfo2 *pinfo2,
 
3079
                                  TALLOC_CTX *mem_ctx)
 
3080
{
 
3081
        print_status_struct status;
 
3082
 
 
3083
        print_queue_length(msg_ctx, snum, &status);
 
3084
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
 
3085
}
 
3086
 
 
3087
/*******************************************************************
 
3088
 * fill a notify_info_data with the number of jobs queued
 
3089
 ********************************************************************/
 
3090
 
 
3091
static void spoolss_notify_cjobs(struct messaging_context *msg_ctx,
 
3092
                                 int snum,
 
3093
                                 struct spoolss_Notify *data,
 
3094
                                 print_queue_struct *queue,
 
3095
                                 struct spoolss_PrinterInfo2 *pinfo2,
 
3096
                                 TALLOC_CTX *mem_ctx)
 
3097
{
 
3098
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(
 
3099
                data, print_queue_length(msg_ctx, snum, NULL));
 
3100
}
 
3101
 
 
3102
/*******************************************************************
 
3103
 * fill a notify_info_data with the average ppm
 
3104
 ********************************************************************/
 
3105
 
 
3106
static void spoolss_notify_average_ppm(struct messaging_context *msg_ctx,
 
3107
                                       int snum,
 
3108
                                       struct spoolss_Notify *data,
 
3109
                                       print_queue_struct *queue,
 
3110
                                       struct spoolss_PrinterInfo2 *pinfo2,
 
3111
                                       TALLOC_CTX *mem_ctx)
 
3112
{
 
3113
        /* always respond 8 pages per minutes */
 
3114
        /* a little hard ! */
 
3115
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->averageppm);
 
3116
}
 
3117
 
 
3118
/*******************************************************************
 
3119
 * fill a notify_info_data with username
 
3120
 ********************************************************************/
 
3121
 
 
3122
static void spoolss_notify_username(struct messaging_context *msg_ctx,
 
3123
                                    int snum,
 
3124
                                    struct spoolss_Notify *data,
 
3125
                                    print_queue_struct *queue,
 
3126
                                    struct spoolss_PrinterInfo2 *pinfo2,
 
3127
                                    TALLOC_CTX *mem_ctx)
 
3128
{
 
3129
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
 
3130
}
 
3131
 
 
3132
/*******************************************************************
 
3133
 * fill a notify_info_data with job status
 
3134
 ********************************************************************/
 
3135
 
 
3136
static void spoolss_notify_job_status(struct messaging_context *msg_ctx,
 
3137
                                      int snum,
 
3138
                                      struct spoolss_Notify *data,
 
3139
                                      print_queue_struct *queue,
 
3140
                                      struct spoolss_PrinterInfo2 *pinfo2,
 
3141
                                      TALLOC_CTX *mem_ctx)
 
3142
{
 
3143
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
 
3144
}
 
3145
 
 
3146
/*******************************************************************
 
3147
 * fill a notify_info_data with job name
 
3148
 ********************************************************************/
 
3149
 
 
3150
static void spoolss_notify_job_name(struct messaging_context *msg_ctx,
 
3151
                                    int snum,
 
3152
                                    struct spoolss_Notify *data,
 
3153
                                    print_queue_struct *queue,
 
3154
                                    struct spoolss_PrinterInfo2 *pinfo2,
 
3155
                                    TALLOC_CTX *mem_ctx)
 
3156
{
 
3157
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
 
3158
}
 
3159
 
 
3160
/*******************************************************************
 
3161
 * fill a notify_info_data with job status
 
3162
 ********************************************************************/
 
3163
 
 
3164
static void spoolss_notify_job_status_string(struct messaging_context *msg_ctx,
 
3165
                                             int snum,
 
3166
                                             struct spoolss_Notify *data,
 
3167
                                             print_queue_struct *queue,
 
3168
                                             struct spoolss_PrinterInfo2 *pinfo2,
 
3169
                                             TALLOC_CTX *mem_ctx)
 
3170
{
 
3171
        /*
 
3172
         * Now we're returning job status codes we just return a "" here. JRA.
 
3173
         */
 
3174
 
 
3175
        const char *p = "";
 
3176
 
 
3177
#if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
 
3178
        p = "unknown";
 
3179
 
 
3180
        switch (queue->status) {
 
3181
        case LPQ_QUEUED:
 
3182
                p = "Queued";
 
3183
                break;
 
3184
        case LPQ_PAUSED:
 
3185
                p = "";    /* NT provides the paused string */
 
3186
                break;
 
3187
        case LPQ_SPOOLING:
 
3188
                p = "Spooling";
 
3189
                break;
 
3190
        case LPQ_PRINTING:
 
3191
                p = "Printing";
 
3192
                break;
 
3193
        }
 
3194
#endif /* NO LONGER NEEDED. */
 
3195
 
 
3196
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
 
3197
}
 
3198
 
 
3199
/*******************************************************************
 
3200
 * fill a notify_info_data with job time
 
3201
 ********************************************************************/
 
3202
 
 
3203
static void spoolss_notify_job_time(struct messaging_context *msg_ctx,
 
3204
                                    int snum,
 
3205
                                    struct spoolss_Notify *data,
 
3206
                                    print_queue_struct *queue,
 
3207
                                    struct spoolss_PrinterInfo2 *pinfo2,
 
3208
                                    TALLOC_CTX *mem_ctx)
 
3209
{
 
3210
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
 
3211
}
 
3212
 
 
3213
/*******************************************************************
 
3214
 * fill a notify_info_data with job size
 
3215
 ********************************************************************/
 
3216
 
 
3217
static void spoolss_notify_job_size(struct messaging_context *msg_ctx,
 
3218
                                    int snum,
 
3219
                                    struct spoolss_Notify *data,
 
3220
                                    print_queue_struct *queue,
 
3221
                                    struct spoolss_PrinterInfo2 *pinfo2,
 
3222
                                    TALLOC_CTX *mem_ctx)
 
3223
{
 
3224
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
 
3225
}
 
3226
 
 
3227
/*******************************************************************
 
3228
 * fill a notify_info_data with page info
 
3229
 ********************************************************************/
 
3230
static void spoolss_notify_total_pages(struct messaging_context *msg_ctx,
 
3231
                                       int snum,
 
3232
                                struct spoolss_Notify *data,
 
3233
                                print_queue_struct *queue,
 
3234
                                struct spoolss_PrinterInfo2 *pinfo2,
 
3235
                                TALLOC_CTX *mem_ctx)
 
3236
{
 
3237
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
 
3238
}
 
3239
 
 
3240
/*******************************************************************
 
3241
 * fill a notify_info_data with pages printed info.
 
3242
 ********************************************************************/
 
3243
static void spoolss_notify_pages_printed(struct messaging_context *msg_ctx,
 
3244
                                         int snum,
 
3245
                                struct spoolss_Notify *data,
 
3246
                                print_queue_struct *queue,
 
3247
                                struct spoolss_PrinterInfo2 *pinfo2,
 
3248
                                TALLOC_CTX *mem_ctx)
 
3249
{
 
3250
        /* Add code when back-end tracks this */
 
3251
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
 
3252
}
 
3253
 
 
3254
/*******************************************************************
 
3255
 Fill a notify_info_data with job position.
 
3256
 ********************************************************************/
 
3257
 
 
3258
static void spoolss_notify_job_position(struct messaging_context *msg_ctx,
 
3259
                                        int snum,
 
3260
                                        struct spoolss_Notify *data,
 
3261
                                        print_queue_struct *queue,
 
3262
                                        struct spoolss_PrinterInfo2 *pinfo2,
 
3263
                                        TALLOC_CTX *mem_ctx)
 
3264
{
 
3265
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
 
3266
}
 
3267
 
 
3268
/*******************************************************************
 
3269
 Fill a notify_info_data with submitted time.
 
3270
 ********************************************************************/
 
3271
 
 
3272
static void spoolss_notify_submitted_time(struct messaging_context *msg_ctx,
 
3273
                                          int snum,
 
3274
                                          struct spoolss_Notify *data,
 
3275
                                          print_queue_struct *queue,
 
3276
                                          struct spoolss_PrinterInfo2 *pinfo2,
 
3277
                                          TALLOC_CTX *mem_ctx)
 
3278
{
 
3279
        data->data.string.string = NULL;
 
3280
        data->data.string.size = 0;
 
3281
 
 
3282
        init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
 
3283
                               &data->data.string.string,
 
3284
                               &data->data.string.size);
 
3285
 
 
3286
}
 
3287
 
 
3288
struct s_notify_info_data_table
 
3289
{
 
3290
        enum spoolss_NotifyType type;
 
3291
        uint16_t field;
 
3292
        const char *name;
 
3293
        enum spoolss_NotifyTable variable_type;
 
3294
        void (*fn) (struct messaging_context *msg_ctx,
 
3295
                    int snum, struct spoolss_Notify *data,
 
3296
                    print_queue_struct *queue,
 
3297
                    struct spoolss_PrinterInfo2 *pinfo2,
 
3298
                    TALLOC_CTX *mem_ctx);
 
3299
};
 
3300
 
 
3301
/* A table describing the various print notification constants and
 
3302
   whether the notification data is a pointer to a variable sized
 
3303
   buffer, a one value uint32_t or a two value uint32_t. */
 
3304
 
 
3305
static const struct s_notify_info_data_table notify_info_data_table[] =
 
3306
{
 
3307
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME,         "PRINTER_NOTIFY_FIELD_SERVER_NAME",         NOTIFY_TABLE_STRING,   spoolss_notify_server_name },
 
3308
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME,        "PRINTER_NOTIFY_FIELD_PRINTER_NAME",        NOTIFY_TABLE_STRING,   spoolss_notify_printer_name },
 
3309
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME,          "PRINTER_NOTIFY_FIELD_SHARE_NAME",          NOTIFY_TABLE_STRING,   spoolss_notify_share_name },
 
3310
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME,           "PRINTER_NOTIFY_FIELD_PORT_NAME",           NOTIFY_TABLE_STRING,   spoolss_notify_port_name },
 
3311
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME,         "PRINTER_NOTIFY_FIELD_DRIVER_NAME",         NOTIFY_TABLE_STRING,   spoolss_notify_driver_name },
 
3312
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT,             "PRINTER_NOTIFY_FIELD_COMMENT",             NOTIFY_TABLE_STRING,   spoolss_notify_comment },
 
3313
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION,            "PRINTER_NOTIFY_FIELD_LOCATION",            NOTIFY_TABLE_STRING,   spoolss_notify_location },
 
3314
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE,             "PRINTER_NOTIFY_FIELD_DEVMODE",             NOTIFY_TABLE_DEVMODE,  spoolss_notify_devmode },
 
3315
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE,             "PRINTER_NOTIFY_FIELD_SEPFILE",             NOTIFY_TABLE_STRING,   spoolss_notify_sepfile },
 
3316
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR,     "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR",     NOTIFY_TABLE_STRING,   spoolss_notify_print_processor },
 
3317
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS,          "PRINTER_NOTIFY_FIELD_PARAMETERS",          NOTIFY_TABLE_STRING,   spoolss_notify_parameters },
 
3318
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE,            "PRINTER_NOTIFY_FIELD_DATATYPE",            NOTIFY_TABLE_STRING,   spoolss_notify_datatype },
 
3319
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR,   spoolss_notify_security_desc },
 
3320
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES,          "PRINTER_NOTIFY_FIELD_ATTRIBUTES",          NOTIFY_TABLE_DWORD,    spoolss_notify_attributes },
 
3321
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY,            "PRINTER_NOTIFY_FIELD_PRIORITY",            NOTIFY_TABLE_DWORD,    spoolss_notify_priority },
 
3322
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY,    "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY",    NOTIFY_TABLE_DWORD,    spoolss_notify_default_priority },
 
3323
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME,          "PRINTER_NOTIFY_FIELD_START_TIME",          NOTIFY_TABLE_DWORD,    spoolss_notify_start_time },
 
3324
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME,          "PRINTER_NOTIFY_FIELD_UNTIL_TIME",          NOTIFY_TABLE_DWORD,    spoolss_notify_until_time },
 
3325
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS,              "PRINTER_NOTIFY_FIELD_STATUS",              NOTIFY_TABLE_DWORD,    spoolss_notify_status },
 
3326
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING,       "PRINTER_NOTIFY_FIELD_STATUS_STRING",       NOTIFY_TABLE_STRING,   NULL },
 
3327
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS,               "PRINTER_NOTIFY_FIELD_CJOBS",               NOTIFY_TABLE_DWORD,    spoolss_notify_cjobs },
 
3328
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM,         "PRINTER_NOTIFY_FIELD_AVERAGE_PPM",         NOTIFY_TABLE_DWORD,    spoolss_notify_average_ppm },
 
3329
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES,         "PRINTER_NOTIFY_FIELD_TOTAL_PAGES",         NOTIFY_TABLE_DWORD,    NULL },
 
3330
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED,       "PRINTER_NOTIFY_FIELD_PAGES_PRINTED",       NOTIFY_TABLE_DWORD,    NULL },
 
3331
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES,         "PRINTER_NOTIFY_FIELD_TOTAL_BYTES",         NOTIFY_TABLE_DWORD,    NULL },
 
3332
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED,       "PRINTER_NOTIFY_FIELD_BYTES_PRINTED",       NOTIFY_TABLE_DWORD,    NULL },
 
3333
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PRINTER_NAME,            "JOB_NOTIFY_FIELD_PRINTER_NAME",            NOTIFY_TABLE_STRING,   spoolss_notify_printer_name },
 
3334
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_MACHINE_NAME,            "JOB_NOTIFY_FIELD_MACHINE_NAME",            NOTIFY_TABLE_STRING,   spoolss_notify_server_name },
 
3335
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PORT_NAME,               "JOB_NOTIFY_FIELD_PORT_NAME",               NOTIFY_TABLE_STRING,   spoolss_notify_port_name },
 
3336
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_USER_NAME,               "JOB_NOTIFY_FIELD_USER_NAME",               NOTIFY_TABLE_STRING,   spoolss_notify_username },
 
3337
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_NOTIFY_NAME,             "JOB_NOTIFY_FIELD_NOTIFY_NAME",             NOTIFY_TABLE_STRING,   spoolss_notify_username },
 
3338
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DATATYPE,                "JOB_NOTIFY_FIELD_DATATYPE",                NOTIFY_TABLE_STRING,   spoolss_notify_datatype },
 
3339
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PRINT_PROCESSOR,         "JOB_NOTIFY_FIELD_PRINT_PROCESSOR",         NOTIFY_TABLE_STRING,   spoolss_notify_print_processor },
 
3340
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PARAMETERS,              "JOB_NOTIFY_FIELD_PARAMETERS",              NOTIFY_TABLE_STRING,   spoolss_notify_parameters },
 
3341
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DRIVER_NAME,             "JOB_NOTIFY_FIELD_DRIVER_NAME",             NOTIFY_TABLE_STRING,   spoolss_notify_driver_name },
 
3342
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DEVMODE,                 "JOB_NOTIFY_FIELD_DEVMODE",                 NOTIFY_TABLE_DEVMODE,  spoolss_notify_devmode },
 
3343
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_STATUS,                  "JOB_NOTIFY_FIELD_STATUS",                  NOTIFY_TABLE_DWORD,    spoolss_notify_job_status },
 
3344
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_STATUS_STRING,           "JOB_NOTIFY_FIELD_STATUS_STRING",           NOTIFY_TABLE_STRING,   spoolss_notify_job_status_string },
 
3345
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR,     "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR",     NOTIFY_TABLE_SECURITYDESCRIPTOR,   NULL },
 
3346
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DOCUMENT,                "JOB_NOTIFY_FIELD_DOCUMENT",                NOTIFY_TABLE_STRING,   spoolss_notify_job_name },
 
3347
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PRIORITY,                "JOB_NOTIFY_FIELD_PRIORITY",                NOTIFY_TABLE_DWORD,    spoolss_notify_priority },
 
3348
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_POSITION,                "JOB_NOTIFY_FIELD_POSITION",                NOTIFY_TABLE_DWORD,    spoolss_notify_job_position },
 
3349
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_SUBMITTED,               "JOB_NOTIFY_FIELD_SUBMITTED",               NOTIFY_TABLE_TIME,     spoolss_notify_submitted_time },
 
3350
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_START_TIME,              "JOB_NOTIFY_FIELD_START_TIME",              NOTIFY_TABLE_DWORD,    spoolss_notify_start_time },
 
3351
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_UNTIL_TIME,              "JOB_NOTIFY_FIELD_UNTIL_TIME",              NOTIFY_TABLE_DWORD,    spoolss_notify_until_time },
 
3352
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_TIME,                    "JOB_NOTIFY_FIELD_TIME",                    NOTIFY_TABLE_DWORD,    spoolss_notify_job_time },
 
3353
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_TOTAL_PAGES,             "JOB_NOTIFY_FIELD_TOTAL_PAGES",             NOTIFY_TABLE_DWORD,    spoolss_notify_total_pages },
 
3354
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PAGES_PRINTED,           "JOB_NOTIFY_FIELD_PAGES_PRINTED",           NOTIFY_TABLE_DWORD,    spoolss_notify_pages_printed },
 
3355
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_TOTAL_BYTES,             "JOB_NOTIFY_FIELD_TOTAL_BYTES",             NOTIFY_TABLE_DWORD,    spoolss_notify_job_size },
 
3356
};
 
3357
 
 
3358
/*******************************************************************
 
3359
 Return the variable_type of info_data structure.
 
3360
********************************************************************/
 
3361
 
 
3362
static enum spoolss_NotifyTable variable_type_of_notify_info_data(enum spoolss_NotifyType type,
 
3363
                                                                  uint16_t field)
 
3364
{
 
3365
        int i=0;
 
3366
 
 
3367
        for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
 
3368
                if ( (notify_info_data_table[i].type == type) &&
 
3369
                     (notify_info_data_table[i].field == field) ) {
 
3370
                        return notify_info_data_table[i].variable_type;
 
3371
                }
 
3372
        }
 
3373
 
 
3374
        DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
 
3375
 
 
3376
        return (enum spoolss_NotifyTable) 0;
 
3377
}
 
3378
 
 
3379
/****************************************************************************
 
3380
****************************************************************************/
 
3381
 
 
3382
static bool search_notify(enum spoolss_NotifyType type,
 
3383
                          uint16_t field,
 
3384
                          int *value)
 
3385
{
 
3386
        int i;
 
3387
 
 
3388
        for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
 
3389
                if (notify_info_data_table[i].type == type &&
 
3390
                    notify_info_data_table[i].field == field &&
 
3391
                    notify_info_data_table[i].fn != NULL) {
 
3392
                        *value = i;
 
3393
                        return true;
 
3394
                }
 
3395
        }
 
3396
 
 
3397
        return false;
 
3398
}
 
3399
 
 
3400
/****************************************************************************
 
3401
****************************************************************************/
 
3402
 
 
3403
static void construct_info_data(struct spoolss_Notify *info_data,
 
3404
                                enum spoolss_NotifyType type,
 
3405
                                uint16_t field, int id)
 
3406
{
 
3407
        info_data->type                 = type;
 
3408
        info_data->field.field          = field;
 
3409
        info_data->variable_type        = variable_type_of_notify_info_data(type, field);
 
3410
        info_data->job_id               = id;
 
3411
}
 
3412
 
 
3413
/*******************************************************************
 
3414
 *
 
3415
 * fill a notify_info struct with info asked
 
3416
 *
 
3417
 ********************************************************************/
 
3418
 
 
3419
static bool construct_notify_printer_info(struct messaging_context *msg_ctx,
 
3420
                                          struct printer_handle *print_hnd,
 
3421
                                          struct spoolss_NotifyInfo *info,
 
3422
                                          struct spoolss_PrinterInfo2 *pinfo2,
 
3423
                                          int snum,
 
3424
                                          const struct spoolss_NotifyOptionType *option_type,
 
3425
                                          uint32_t id,
 
3426
                                          TALLOC_CTX *mem_ctx)
 
3427
{
 
3428
        int field_num,j;
 
3429
        enum spoolss_NotifyType type;
 
3430
        uint16_t field;
 
3431
 
 
3432
        struct spoolss_Notify *current_data;
 
3433
 
 
3434
        type = option_type->type;
 
3435
 
 
3436
        DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
 
3437
                (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
 
3438
                option_type->count, lp_servicename(snum)));
 
3439
 
 
3440
        for(field_num=0; field_num < option_type->count; field_num++) {
 
3441
                field = option_type->fields[field_num].field;
 
3442
 
 
3443
                DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
 
3444
 
 
3445
                if (!search_notify(type, field, &j) )
 
3446
                        continue;
 
3447
 
 
3448
                info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
 
3449
                                                      struct spoolss_Notify,
 
3450
                                                      info->count + 1);
 
3451
                if (info->notifies == NULL) {
 
3452
                        DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
 
3453
                        return false;
 
3454
                }
 
3455
 
 
3456
                current_data = &info->notifies[info->count];
 
3457
 
 
3458
                construct_info_data(current_data, type, field, id);
 
3459
 
 
3460
                DEBUG(10, ("construct_notify_printer_info: "
 
3461
                           "calling [%s]  snum=%d  printername=[%s])\n",
 
3462
                           notify_info_data_table[j].name, snum,
 
3463
                           pinfo2->printername));
 
3464
 
 
3465
                notify_info_data_table[j].fn(msg_ctx, snum, current_data,
 
3466
                                             NULL, pinfo2, mem_ctx);
 
3467
 
 
3468
                info->count++;
 
3469
        }
 
3470
 
 
3471
        return true;
 
3472
}
 
3473
 
 
3474
/*******************************************************************
 
3475
 *
 
3476
 * fill a notify_info struct with info asked
 
3477
 *
 
3478
 ********************************************************************/
 
3479
 
 
3480
static bool construct_notify_jobs_info(struct messaging_context *msg_ctx,
 
3481
                                       print_queue_struct *queue,
 
3482
                                       struct spoolss_NotifyInfo *info,
 
3483
                                       struct spoolss_PrinterInfo2 *pinfo2,
 
3484
                                       int snum,
 
3485
                                       const struct spoolss_NotifyOptionType *option_type,
 
3486
                                       uint32_t id,
 
3487
                                       TALLOC_CTX *mem_ctx)
 
3488
{
 
3489
        int field_num,j;
 
3490
        enum spoolss_NotifyType type;
 
3491
        uint16_t field;
 
3492
        struct spoolss_Notify *current_data;
 
3493
 
 
3494
        DEBUG(4,("construct_notify_jobs_info\n"));
 
3495
 
 
3496
        type = option_type->type;
 
3497
 
 
3498
        DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
 
3499
                (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
 
3500
                option_type->count));
 
3501
 
 
3502
        for(field_num=0; field_num<option_type->count; field_num++) {
 
3503
                field = option_type->fields[field_num].field;
 
3504
 
 
3505
                if (!search_notify(type, field, &j) )
 
3506
                        continue;
 
3507
 
 
3508
                info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
 
3509
                                                      struct spoolss_Notify,
 
3510
                                                      info->count + 1);
 
3511
                if (info->notifies == NULL) {
 
3512
                        DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
 
3513
                        return false;
 
3514
                }
 
3515
 
 
3516
                current_data=&(info->notifies[info->count]);
 
3517
 
 
3518
                construct_info_data(current_data, type, field, id);
 
3519
                notify_info_data_table[j].fn(msg_ctx, snum, current_data,
 
3520
                                             queue, pinfo2, mem_ctx);
 
3521
                info->count++;
 
3522
        }
 
3523
 
 
3524
        return true;
 
3525
}
 
3526
 
 
3527
/*
 
3528
 * JFM: The enumeration is not that simple, it's even non obvious.
 
3529
 *
 
3530
 * let's take an example: I want to monitor the PRINTER SERVER for
 
3531
 * the printer's name and the number of jobs currently queued.
 
3532
 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
 
3533
 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
 
3534
 *
 
3535
 * I have 3 printers on the back of my server.
 
3536
 *
 
3537
 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
 
3538
 * structures.
 
3539
 *   Number     Data                    Id
 
3540
 *      1       printer 1 name          1
 
3541
 *      2       printer 1 cjob          1
 
3542
 *      3       printer 2 name          2
 
3543
 *      4       printer 2 cjob          2
 
3544
 *      5       printer 3 name          3
 
3545
 *      6       printer 3 name          3
 
3546
 *
 
3547
 * that's the print server case, the printer case is even worse.
 
3548
 */
 
3549
 
 
3550
/*******************************************************************
 
3551
 *
 
3552
 * enumerate all printers on the printserver
 
3553
 * fill a notify_info struct with info asked
 
3554
 *
 
3555
 ********************************************************************/
 
3556
 
 
3557
static WERROR printserver_notify_info(struct pipes_struct *p,
 
3558
                                      struct policy_handle *hnd,
 
3559
                                      struct spoolss_NotifyInfo *info,
 
3560
                                      TALLOC_CTX *mem_ctx)
 
3561
{
 
3562
        int snum;
 
3563
        struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
 
3564
        int n_services=lp_numservices();
 
3565
        int i;
 
3566
        struct spoolss_NotifyOption *option;
 
3567
        struct spoolss_NotifyOptionType option_type;
 
3568
        struct spoolss_PrinterInfo2 *pinfo2 = NULL;
 
3569
        WERROR result;
 
3570
 
 
3571
        DEBUG(4,("printserver_notify_info\n"));
 
3572
 
 
3573
        if (!Printer)
 
3574
                return WERR_BADFID;
 
3575
 
 
3576
        option = Printer->notify.option;
 
3577
 
 
3578
        info->version   = 2;
 
3579
        info->notifies  = NULL;
 
3580
        info->count     = 0;
 
3581
 
 
3582
        /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
 
3583
           sending a ffpcn() request first */
 
3584
 
 
3585
        if ( !option )
 
3586
                return WERR_BADFID;
 
3587
 
 
3588
        for (i=0; i<option->count; i++) {
 
3589
                option_type = option->types[i];
 
3590
 
 
3591
                if (option_type.type != PRINTER_NOTIFY_TYPE)
 
3592
                        continue;
 
3593
 
 
3594
                for (snum = 0; snum < n_services; snum++) {
 
3595
                        if (!lp_browseable(snum) ||
 
3596
                            !lp_snum_ok(snum) ||
 
3597
                            !lp_print_ok(snum)) {
 
3598
                                continue; /* skip */
 
3599
                        }
 
3600
 
 
3601
                        /* Maybe we should use the SYSTEM session_info here... */
 
3602
                        result = winreg_get_printer_internal(mem_ctx,
 
3603
                                                    get_session_info_system(),
 
3604
                                                    p->msg_ctx,
 
3605
                                                    lp_servicename(snum),
 
3606
                                                    &pinfo2);
 
3607
                        if (!W_ERROR_IS_OK(result)) {
 
3608
                                DEBUG(4, ("printserver_notify_info: "
 
3609
                                          "Failed to get printer [%s]\n",
 
3610
                                          lp_servicename(snum)));
 
3611
                                continue;
 
3612
                        }
 
3613
 
 
3614
 
 
3615
                        construct_notify_printer_info(p->msg_ctx,
 
3616
                                                      Printer, info,
 
3617
                                                      pinfo2, snum,
 
3618
                                                      &option_type, snum,
 
3619
                                                      mem_ctx);
 
3620
 
 
3621
                        TALLOC_FREE(pinfo2);
 
3622
                }
 
3623
        }
 
3624
 
 
3625
#if 0
 
3626
        /*
 
3627
         * Debugging information, don't delete.
 
3628
         */
 
3629
 
 
3630
        DEBUG(1,("dumping the NOTIFY_INFO\n"));
 
3631
        DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
 
3632
        DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
 
3633
 
 
3634
        for (i=0; i<info->count; i++) {
 
3635
                DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
 
3636
                i, info->data[i].type, info->data[i].field, info->data[i].reserved,
 
3637
                info->data[i].id, info->data[i].size, info->data[i].enc_type));
 
3638
        }
 
3639
#endif
 
3640
 
 
3641
        return WERR_OK;
 
3642
}
 
3643
 
 
3644
/*******************************************************************
 
3645
 *
 
3646
 * fill a notify_info struct with info asked
 
3647
 *
 
3648
 ********************************************************************/
 
3649
 
 
3650
static WERROR printer_notify_info(struct pipes_struct *p,
 
3651
                                  struct policy_handle *hnd,
 
3652
                                  struct spoolss_NotifyInfo *info,
 
3653
                                  TALLOC_CTX *mem_ctx)
 
3654
{
 
3655
        int snum;
 
3656
        struct printer_handle *Printer = find_printer_index_by_hnd(p, hnd);
 
3657
        int i;
 
3658
        uint32_t id;
 
3659
        struct spoolss_NotifyOption *option;
 
3660
        struct spoolss_NotifyOptionType option_type;
 
3661
        int count,j;
 
3662
        print_queue_struct *queue=NULL;
 
3663
        print_status_struct status;
 
3664
        struct spoolss_PrinterInfo2 *pinfo2 = NULL;
 
3665
        WERROR result;
 
3666
 
 
3667
        DEBUG(4,("printer_notify_info\n"));
 
3668
 
 
3669
        if (!Printer)
 
3670
                return WERR_BADFID;
 
3671
 
 
3672
        option = Printer->notify.option;
 
3673
        id = 0x0;
 
3674
 
 
3675
        info->version   = 2;
 
3676
        info->notifies  = NULL;
 
3677
        info->count     = 0;
 
3678
 
 
3679
        /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
 
3680
           sending a ffpcn() request first */
 
3681
 
 
3682
        if ( !option )
 
3683
                return WERR_BADFID;
 
3684
 
 
3685
        if (!get_printer_snum(p, hnd, &snum, NULL)) {
 
3686
                return WERR_BADFID;
 
3687
        }
 
3688
 
 
3689
        /* Maybe we should use the SYSTEM session_info here... */
 
3690
        result = winreg_get_printer_internal(mem_ctx,
 
3691
                                    get_session_info_system(),
 
3692
                                    p->msg_ctx,
 
3693
                                    lp_servicename(snum), &pinfo2);
 
3694
        if (!W_ERROR_IS_OK(result)) {
 
3695
                return WERR_BADFID;
 
3696
        }
 
3697
 
 
3698
        /*
 
3699
         * When sending a PRINTER_NOTIFY_FIELD_SERVER_NAME we should send the
 
3700
         * correct servername.
 
3701
         */
 
3702
        pinfo2->servername = talloc_strdup(pinfo2, Printer->servername);
 
3703
        if (pinfo2->servername == NULL) {
 
3704
                return WERR_NOMEM;
 
3705
        }
 
3706
 
 
3707
        for (i=0; i<option->count; i++) {
 
3708
                option_type = option->types[i];
 
3709
 
 
3710
                switch (option_type.type) {
 
3711
                case PRINTER_NOTIFY_TYPE:
 
3712
                        if (construct_notify_printer_info(p->msg_ctx,
 
3713
                                                          Printer, info,
 
3714
                                                          pinfo2, snum,
 
3715
                                                          &option_type, id,
 
3716
                                                          mem_ctx)) {
 
3717
                                id--;
 
3718
                        }
 
3719
                        break;
 
3720
 
 
3721
                case JOB_NOTIFY_TYPE:
 
3722
 
 
3723
                        count = print_queue_status(p->msg_ctx, snum, &queue,
 
3724
                                                   &status);
 
3725
 
 
3726
                        for (j=0; j<count; j++) {
 
3727
                                construct_notify_jobs_info(p->msg_ctx,
 
3728
                                                           &queue[j], info,
 
3729
                                                           pinfo2, snum,
 
3730
                                                           &option_type,
 
3731
                                                           queue[j].job,
 
3732
                                                           mem_ctx);
 
3733
                        }
 
3734
 
 
3735
                        SAFE_FREE(queue);
 
3736
                        break;
 
3737
                }
 
3738
        }
 
3739
 
 
3740
        /*
 
3741
         * Debugging information, don't delete.
 
3742
         */
 
3743
        /*
 
3744
        DEBUG(1,("dumping the NOTIFY_INFO\n"));
 
3745
        DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
 
3746
        DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
 
3747
 
 
3748
        for (i=0; i<info->count; i++) {
 
3749
                DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
 
3750
                i, info->data[i].type, info->data[i].field, info->data[i].reserved,
 
3751
                info->data[i].id, info->data[i].size, info->data[i].enc_type));
 
3752
        }
 
3753
        */
 
3754
 
 
3755
        talloc_free(pinfo2);
 
3756
        return WERR_OK;
 
3757
}
 
3758
 
 
3759
/****************************************************************
 
3760
 _spoolss_RouterRefreshPrinterChangeNotify
 
3761
****************************************************************/
 
3762
 
 
3763
WERROR _spoolss_RouterRefreshPrinterChangeNotify(struct pipes_struct *p,
 
3764
                                                 struct spoolss_RouterRefreshPrinterChangeNotify *r)
 
3765
{
 
3766
        struct spoolss_NotifyInfo *info;
 
3767
 
 
3768
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
3769
        WERROR result = WERR_BADFID;
 
3770
 
 
3771
        /* we always have a spoolss_NotifyInfo struct */
 
3772
        info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
 
3773
        if (!info) {
 
3774
                result = WERR_NOMEM;
 
3775
                goto done;
 
3776
        }
 
3777
 
 
3778
        *r->out.info = info;
 
3779
 
 
3780
        if (!Printer) {
 
3781
                DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
 
3782
                        "Invalid handle (%s:%u:%u).\n",
 
3783
                        OUR_HANDLE(r->in.handle)));
 
3784
                goto done;
 
3785
        }
 
3786
 
 
3787
        DEBUG(4,("Printer type %x\n",Printer->printer_type));
 
3788
 
 
3789
        /*
 
3790
         *      We are now using the change value, and
 
3791
         *      I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
 
3792
         *      I don't have a global notification system, I'm sending back all the
 
3793
         *      information even when _NOTHING_ has changed.
 
3794
         */
 
3795
 
 
3796
        /* We need to keep track of the change value to send back in
 
3797
           RRPCN replies otherwise our updates are ignored. */
 
3798
 
 
3799
        Printer->notify.fnpcn = true;
 
3800
 
 
3801
        if (Printer->notify.cli_chan != NULL &&
 
3802
            Printer->notify.cli_chan->active_connections > 0) {
 
3803
                DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
 
3804
                        "Saving change value in request [%x]\n",
 
3805
                        r->in.change_low));
 
3806
                Printer->notify.change = r->in.change_low;
 
3807
        }
 
3808
 
 
3809
        /* just ignore the spoolss_NotifyOption */
 
3810
 
 
3811
        switch (Printer->printer_type) {
 
3812
                case SPLHND_SERVER:
 
3813
                        result = printserver_notify_info(p, r->in.handle,
 
3814
                                                         info, p->mem_ctx);
 
3815
                        break;
 
3816
 
 
3817
                case SPLHND_PRINTER:
 
3818
                        result = printer_notify_info(p, r->in.handle,
 
3819
                                                     info, p->mem_ctx);
 
3820
                        break;
 
3821
        }
 
3822
 
 
3823
        Printer->notify.fnpcn = false;
 
3824
 
 
3825
done:
 
3826
        return result;
 
3827
}
 
3828
 
 
3829
/********************************************************************
 
3830
 ********************************************************************/
 
3831
 
 
3832
static WERROR create_printername(TALLOC_CTX *mem_ctx,
 
3833
                                 const char *servername,
 
3834
                                 const char *printername,
 
3835
                                 const char **printername_p)
 
3836
{
 
3837
        /* FIXME: add lp_force_printername() */
 
3838
 
 
3839
        if (servername == NULL) {
 
3840
                *printername_p = talloc_strdup(mem_ctx, printername);
 
3841
                W_ERROR_HAVE_NO_MEMORY(*printername_p);
 
3842
                return WERR_OK;
 
3843
        }
 
3844
 
 
3845
        if (servername[0] == '\\' && servername[1] == '\\') {
 
3846
                servername += 2;
 
3847
        }
 
3848
 
 
3849
        *printername_p = talloc_asprintf(mem_ctx, "\\\\%s\\%s", servername, printername);
 
3850
        W_ERROR_HAVE_NO_MEMORY(*printername_p);
 
3851
 
 
3852
        return WERR_OK;
 
3853
}
 
3854
 
 
3855
/********************************************************************
 
3856
 ********************************************************************/
 
3857
 
 
3858
static void compose_devicemode_devicename(struct spoolss_DeviceMode *dm,
 
3859
                                          const char *printername)
 
3860
{
 
3861
        if (dm == NULL) {
 
3862
                return;
 
3863
        }
 
3864
 
 
3865
        dm->devicename = talloc_strndup(dm, printername,
 
3866
                                        MIN(strlen(printername), 31));
 
3867
}
 
3868
 
 
3869
/********************************************************************
 
3870
 * construct_printer_info_0
 
3871
 * fill a printer_info_0 struct
 
3872
 ********************************************************************/
 
3873
 
 
3874
static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
 
3875
                                      const struct auth_serversupplied_info *session_info,
 
3876
                                      struct messaging_context *msg_ctx,
 
3877
                                      struct spoolss_PrinterInfo2 *info2,
 
3878
                                      const char *servername,
 
3879
                                      struct spoolss_PrinterInfo0 *r,
 
3880
                                      int snum)
 
3881
{
 
3882
        int count;
 
3883
        struct printer_session_counter *session_counter;
 
3884
        struct timeval setuptime;
 
3885
        print_status_struct status;
 
3886
        WERROR result;
 
3887
 
 
3888
        result = create_printername(mem_ctx, servername, info2->printername, &r->printername);
 
3889
        if (!W_ERROR_IS_OK(result)) {
 
3890
                return result;
 
3891
        }
 
3892
 
 
3893
        if (servername) {
 
3894
                r->servername = talloc_strdup(mem_ctx, servername);
 
3895
                W_ERROR_HAVE_NO_MEMORY(r->servername);
 
3896
        } else {
 
3897
                r->servername = NULL;
 
3898
        }
 
3899
 
 
3900
        count = print_queue_length(msg_ctx, snum, &status);
 
3901
 
 
3902
        /* check if we already have a counter for this printer */
 
3903
        for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
 
3904
                if (session_counter->snum == snum)
 
3905
                        break;
 
3906
        }
 
3907
 
 
3908
        /* it's the first time, add it to the list */
 
3909
        if (session_counter == NULL) {
 
3910
                session_counter = talloc_zero(counter_list, struct printer_session_counter);
 
3911
                W_ERROR_HAVE_NO_MEMORY(session_counter);
 
3912
                session_counter->snum           = snum;
 
3913
                session_counter->counter        = 0;
 
3914
                DLIST_ADD(counter_list, session_counter);
 
3915
        }
 
3916
 
 
3917
        /* increment it */
 
3918
        session_counter->counter++;
 
3919
 
 
3920
        r->cjobs                        = count;
 
3921
        r->total_jobs                   = 0;
 
3922
        r->total_bytes                  = 0;
 
3923
 
 
3924
        get_startup_time(&setuptime);
 
3925
        init_systemtime(&r->time, gmtime(&setuptime.tv_sec));
 
3926
 
 
3927
        /* JFM:
 
3928
         * the global_counter should be stored in a TDB as it's common to all the clients
 
3929
         * and should be zeroed on samba startup
 
3930
         */
 
3931
        r->global_counter               = session_counter->counter;
 
3932
        r->total_pages                  = 0;
 
3933
        /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
 
3934
        SSVAL(&r->version, 0, 0x0005); /* NT 5 */
 
3935
        SSVAL(&r->version, 2, 0x0893); /* build 2195 */
 
3936
        r->free_build                   = SPOOLSS_RELEASE_BUILD;
 
3937
        r->spooling                     = 0;
 
3938
        r->max_spooling                 = 0;
 
3939
        r->session_counter              = session_counter->counter;
 
3940
        r->num_error_out_of_paper       = 0x0;
 
3941
        r->num_error_not_ready          = 0x0;          /* number of print failure */
 
3942
        r->job_error                    = 0x0;
 
3943
        r->number_of_processors         = 0x1;
 
3944
        r->processor_type               = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
 
3945
        r->high_part_total_bytes        = 0x0;
 
3946
 
 
3947
        /* ChangeID in milliseconds*/
 
3948
        winreg_printer_get_changeid_internal(mem_ctx, session_info, msg_ctx,
 
3949
                                    info2->sharename, &r->change_id);
 
3950
 
 
3951
        r->last_error                   = WERR_OK;
 
3952
        r->status                       = nt_printq_status(status.status);
 
3953
        r->enumerate_network_printers   = 0x0;
 
3954
        r->c_setprinter                 = 0x0;
 
3955
        r->processor_architecture       = PROCESSOR_ARCHITECTURE_INTEL;
 
3956
        r->processor_level              = 0x6;          /* 6  ???*/
 
3957
        r->ref_ic                       = 0;
 
3958
        r->reserved2                    = 0;
 
3959
        r->reserved3                    = 0;
 
3960
 
 
3961
        return WERR_OK;
 
3962
}
 
3963
 
 
3964
 
 
3965
/********************************************************************
 
3966
 * construct_printer_info1
 
3967
 * fill a spoolss_PrinterInfo1 struct
 
3968
********************************************************************/
 
3969
 
 
3970
static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
 
3971
                                      const struct spoolss_PrinterInfo2 *info2,
 
3972
                                      uint32_t flags,
 
3973
                                      const char *servername,
 
3974
                                      struct spoolss_PrinterInfo1 *r,
 
3975
                                      int snum)
 
3976
{
 
3977
        WERROR result;
 
3978
 
 
3979
        r->flags                = flags;
 
3980
 
 
3981
        if (info2->comment == NULL || info2->comment[0] == '\0') {
 
3982
                r->comment      = talloc_strdup(mem_ctx, lp_comment(snum));
 
3983
        } else {
 
3984
                r->comment      = talloc_strdup(mem_ctx, info2->comment); /* saved comment */
 
3985
        }
 
3986
        W_ERROR_HAVE_NO_MEMORY(r->comment);
 
3987
 
 
3988
        result = create_printername(mem_ctx, servername, info2->printername, &r->name);
 
3989
        if (!W_ERROR_IS_OK(result)) {
 
3990
                return result;
 
3991
        }
 
3992
 
 
3993
        r->description          = talloc_asprintf(mem_ctx, "%s,%s,%s",
 
3994
                                                  r->name,
 
3995
                                                  info2->drivername,
 
3996
                                                  r->comment);
 
3997
        W_ERROR_HAVE_NO_MEMORY(r->description);
 
3998
 
 
3999
        return WERR_OK;
 
4000
}
 
4001
 
 
4002
/********************************************************************
 
4003
 * construct_printer_info2
 
4004
 * fill a spoolss_PrinterInfo2 struct
 
4005
********************************************************************/
 
4006
 
 
4007
static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
 
4008
                                      struct messaging_context *msg_ctx,
 
4009
                                      const struct spoolss_PrinterInfo2 *info2,
 
4010
                                      const char *servername,
 
4011
                                      struct spoolss_PrinterInfo2 *r,
 
4012
                                      int snum)
 
4013
{
 
4014
        int count;
 
4015
        print_status_struct status;
 
4016
        WERROR result;
 
4017
 
 
4018
        count = print_queue_length(msg_ctx, snum, &status);
 
4019
 
 
4020
        if (servername) {
 
4021
                r->servername           = talloc_strdup(mem_ctx, servername);
 
4022
                W_ERROR_HAVE_NO_MEMORY(r->servername);
 
4023
        } else {
 
4024
                r->servername           = NULL;
 
4025
        }
 
4026
 
 
4027
        result = create_printername(mem_ctx, servername, info2->printername, &r->printername);
 
4028
        if (!W_ERROR_IS_OK(result)) {
 
4029
                return result;
 
4030
        }
 
4031
 
 
4032
        r->sharename            = talloc_strdup(mem_ctx, lp_servicename(snum));
 
4033
        W_ERROR_HAVE_NO_MEMORY(r->sharename);
 
4034
        r->portname             = talloc_strdup(mem_ctx, info2->portname);
 
4035
        W_ERROR_HAVE_NO_MEMORY(r->portname);
 
4036
        r->drivername           = talloc_strdup(mem_ctx, info2->drivername);
 
4037
        W_ERROR_HAVE_NO_MEMORY(r->drivername);
 
4038
 
 
4039
        if (info2->comment[0] == '\0') {
 
4040
                r->comment      = talloc_strdup(mem_ctx, lp_comment(snum));
 
4041
        } else {
 
4042
                r->comment      = talloc_strdup(mem_ctx, info2->comment);
 
4043
        }
 
4044
        W_ERROR_HAVE_NO_MEMORY(r->comment);
 
4045
 
 
4046
        r->location     = talloc_strdup(mem_ctx, info2->location);
 
4047
        if (info2->location[0] == '\0') {
 
4048
                const char *loc = NULL;
 
4049
                NTSTATUS nt_status;
 
4050
 
 
4051
                nt_status = printer_list_get_printer(mem_ctx,
 
4052
                                                     info2->sharename,
 
4053
                                                     NULL,
 
4054
                                                     &loc,
 
4055
                                                     NULL);
 
4056
                if (NT_STATUS_IS_OK(nt_status)) {
 
4057
                        if (loc != NULL) {
 
4058
                                r->location = talloc_strdup(mem_ctx, loc);
 
4059
                        }
 
4060
                }
 
4061
        }
 
4062
        W_ERROR_HAVE_NO_MEMORY(r->location);
 
4063
 
 
4064
        r->sepfile              = talloc_strdup(mem_ctx, info2->sepfile);
 
4065
        W_ERROR_HAVE_NO_MEMORY(r->sepfile);
 
4066
        r->printprocessor       = talloc_strdup(mem_ctx, info2->printprocessor);
 
4067
        W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
 
4068
        r->datatype             = talloc_strdup(mem_ctx, info2->datatype);
 
4069
        W_ERROR_HAVE_NO_MEMORY(r->datatype);
 
4070
        r->parameters           = talloc_strdup(mem_ctx, info2->parameters);
 
4071
        W_ERROR_HAVE_NO_MEMORY(r->parameters);
 
4072
 
 
4073
        r->attributes           = info2->attributes;
 
4074
 
 
4075
        r->priority             = info2->priority;
 
4076
        r->defaultpriority      = info2->defaultpriority;
 
4077
        r->starttime            = info2->starttime;
 
4078
        r->untiltime            = info2->untiltime;
 
4079
        r->status               = nt_printq_status(status.status);
 
4080
        r->cjobs                = count;
 
4081
        r->averageppm           = info2->averageppm;
 
4082
 
 
4083
        copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
 
4084
        if (!r->devmode) {
 
4085
                DEBUG(8,("Returning NULL Devicemode!\n"));
 
4086
        }
 
4087
 
 
4088
        compose_devicemode_devicename(r->devmode, r->printername);
 
4089
 
 
4090
        r->secdesc = NULL;
 
4091
 
 
4092
        if (info2->secdesc != NULL) {
 
4093
                /* don't use talloc_steal() here unless you do a deep steal of all
 
4094
                   the SEC_DESC members */
 
4095
 
 
4096
                r->secdesc      = dup_sec_desc(mem_ctx, info2->secdesc);
 
4097
        }
 
4098
 
 
4099
        return WERR_OK;
 
4100
}
 
4101
 
 
4102
/********************************************************************
 
4103
 * construct_printer_info3
 
4104
 * fill a spoolss_PrinterInfo3 struct
 
4105
 ********************************************************************/
 
4106
 
 
4107
static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
 
4108
                                      const struct spoolss_PrinterInfo2 *info2,
 
4109
                                      const char *servername,
 
4110
                                      struct spoolss_PrinterInfo3 *r,
 
4111
                                      int snum)
 
4112
{
 
4113
        /* These are the components of the SD we are returning. */
 
4114
 
 
4115
        if (info2->secdesc != NULL) {
 
4116
                /* don't use talloc_steal() here unless you do a deep steal of all
 
4117
                   the SEC_DESC members */
 
4118
 
 
4119
                r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
 
4120
                W_ERROR_HAVE_NO_MEMORY(r->secdesc);
 
4121
        }
 
4122
 
 
4123
        return WERR_OK;
 
4124
}
 
4125
 
 
4126
/********************************************************************
 
4127
 * construct_printer_info4
 
4128
 * fill a spoolss_PrinterInfo4 struct
 
4129
 ********************************************************************/
 
4130
 
 
4131
static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
 
4132
                                      const struct spoolss_PrinterInfo2 *info2,
 
4133
                                      const char *servername,
 
4134
                                      struct spoolss_PrinterInfo4 *r,
 
4135
                                      int snum)
 
4136
{
 
4137
        WERROR result;
 
4138
 
 
4139
        result = create_printername(mem_ctx, servername, info2->printername, &r->printername);
 
4140
        if (!W_ERROR_IS_OK(result)) {
 
4141
                return result;
 
4142
        }
 
4143
 
 
4144
        if (servername) {
 
4145
                r->servername   = talloc_strdup(mem_ctx, servername);
 
4146
                W_ERROR_HAVE_NO_MEMORY(r->servername);
 
4147
        } else {
 
4148
                r->servername = NULL;
 
4149
        }
 
4150
 
 
4151
        r->attributes   = info2->attributes;
 
4152
 
 
4153
        return WERR_OK;
 
4154
}
 
4155
 
 
4156
/********************************************************************
 
4157
 * construct_printer_info5
 
4158
 * fill a spoolss_PrinterInfo5 struct
 
4159
 ********************************************************************/
 
4160
 
 
4161
static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
 
4162
                                      const struct spoolss_PrinterInfo2 *info2,
 
4163
                                      const char *servername,
 
4164
                                      struct spoolss_PrinterInfo5 *r,
 
4165
                                      int snum)
 
4166
{
 
4167
        WERROR result;
 
4168
 
 
4169
        result = create_printername(mem_ctx, servername, info2->printername, &r->printername);
 
4170
        if (!W_ERROR_IS_OK(result)) {
 
4171
                return result;
 
4172
        }
 
4173
 
 
4174
        r->portname     = talloc_strdup(mem_ctx, info2->portname);
 
4175
        W_ERROR_HAVE_NO_MEMORY(r->portname);
 
4176
 
 
4177
        r->attributes   = info2->attributes;
 
4178
 
 
4179
        /* these two are not used by NT+ according to MSDN */
 
4180
        r->device_not_selected_timeout          = 0x0;  /* have seen 0x3a98 */
 
4181
        r->transmission_retry_timeout           = 0x0;  /* have seen 0xafc8 */
 
4182
 
 
4183
        return WERR_OK;
 
4184
}
 
4185
 
 
4186
/********************************************************************
 
4187
 * construct_printer_info_6
 
4188
 * fill a spoolss_PrinterInfo6 struct
 
4189
 ********************************************************************/
 
4190
 
 
4191
static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
 
4192
                                      struct messaging_context *msg_ctx,
 
4193
                                      const struct spoolss_PrinterInfo2 *info2,
 
4194
                                      const char *servername,
 
4195
                                      struct spoolss_PrinterInfo6 *r,
 
4196
                                      int snum)
 
4197
{
 
4198
        int count;
 
4199
        print_status_struct status;
 
4200
 
 
4201
        count = print_queue_length(msg_ctx, snum, &status);
 
4202
 
 
4203
        r->status = nt_printq_status(status.status);
 
4204
 
 
4205
        return WERR_OK;
 
4206
}
 
4207
 
 
4208
/********************************************************************
 
4209
 * construct_printer_info7
 
4210
 * fill a spoolss_PrinterInfo7 struct
 
4211
 ********************************************************************/
 
4212
 
 
4213
static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
 
4214
                                      struct messaging_context *msg_ctx,
 
4215
                                      const char *servername,
 
4216
                                      struct spoolss_PrinterInfo7 *r,
 
4217
                                      int snum)
 
4218
{
 
4219
        struct auth_serversupplied_info *session_info;
 
4220
        struct GUID guid;
 
4221
        NTSTATUS status;
 
4222
 
 
4223
        status = make_session_info_system(mem_ctx, &session_info);
 
4224
        if (!NT_STATUS_IS_OK(status)) {
 
4225
                DEBUG(0, ("construct_printer_info7: "
 
4226
                          "Could not create system session_info\n"));
 
4227
                return WERR_NOMEM;
 
4228
        }
 
4229
 
 
4230
        if (is_printer_published(mem_ctx, session_info, msg_ctx,
 
4231
                                 servername,
 
4232
                                 lp_servicename(snum), &guid, NULL)) {
 
4233
                r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
 
4234
                r->action = DSPRINT_PUBLISH;
 
4235
        } else {
 
4236
                r->guid = talloc_strdup(mem_ctx, "");
 
4237
                r->action = DSPRINT_UNPUBLISH;
 
4238
        }
 
4239
        W_ERROR_HAVE_NO_MEMORY(r->guid);
 
4240
 
 
4241
        TALLOC_FREE(session_info);
 
4242
        return WERR_OK;
 
4243
}
 
4244
 
 
4245
/********************************************************************
 
4246
 * construct_printer_info8
 
4247
 * fill a spoolss_PrinterInfo8 struct
 
4248
 ********************************************************************/
 
4249
 
 
4250
static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
 
4251
                                      const struct spoolss_PrinterInfo2 *info2,
 
4252
                                      const char *servername,
 
4253
                                      struct spoolss_DeviceModeInfo *r,
 
4254
                                      int snum)
 
4255
{
 
4256
        WERROR result;
 
4257
        const char *printername;
 
4258
 
 
4259
        result = create_printername(mem_ctx, servername, info2->printername, &printername);
 
4260
        if (!W_ERROR_IS_OK(result)) {
 
4261
                return result;
 
4262
        }
 
4263
 
 
4264
        copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
 
4265
        if (!r->devmode) {
 
4266
                DEBUG(8,("Returning NULL Devicemode!\n"));
 
4267
        }
 
4268
 
 
4269
        compose_devicemode_devicename(r->devmode, printername);
 
4270
 
 
4271
        return WERR_OK;
 
4272
}
 
4273
 
 
4274
 
 
4275
/********************************************************************
 
4276
********************************************************************/
 
4277
 
 
4278
static bool snum_is_shared_printer(int snum)
 
4279
{
 
4280
        return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
 
4281
}
 
4282
 
 
4283
/********************************************************************
 
4284
 Spoolss_enumprinters.
 
4285
********************************************************************/
 
4286
 
 
4287
static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
 
4288
                                           const struct auth_serversupplied_info *session_info,
 
4289
                                           struct messaging_context *msg_ctx,
 
4290
                                           const char *servername,
 
4291
                                           uint32_t level,
 
4292
                                           uint32_t flags,
 
4293
                                           union spoolss_PrinterInfo **info_p,
 
4294
                                           uint32_t *count_p)
 
4295
{
 
4296
        int snum;
 
4297
        int n_services = lp_numservices();
 
4298
        union spoolss_PrinterInfo *info = NULL;
 
4299
        uint32_t count = 0;
 
4300
        WERROR result = WERR_OK;
 
4301
        struct dcerpc_binding_handle *b = NULL;
 
4302
 
 
4303
        *count_p = 0;
 
4304
        *info_p = NULL;
 
4305
 
 
4306
        for (snum = 0; snum < n_services; snum++) {
 
4307
 
 
4308
                const char *printer;
 
4309
                struct spoolss_PrinterInfo2 *info2;
 
4310
 
 
4311
                if (!snum_is_shared_printer(snum)) {
 
4312
                        continue;
 
4313
                }
 
4314
 
 
4315
                printer = lp_const_servicename(snum);
 
4316
 
 
4317
                DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
 
4318
                        printer, snum));
 
4319
 
 
4320
                if (b == NULL) {
 
4321
                        result = winreg_printer_binding_handle(mem_ctx,
 
4322
                                                               session_info,
 
4323
                                                               msg_ctx,
 
4324
                                                               &b);
 
4325
                        if (!W_ERROR_IS_OK(result)) {
 
4326
                                goto out;
 
4327
                        }
 
4328
                }
 
4329
 
 
4330
                result = winreg_create_printer(mem_ctx, b,
 
4331
                                               printer);
 
4332
                if (!W_ERROR_IS_OK(result)) {
 
4333
                        goto out;
 
4334
                }
 
4335
 
 
4336
                info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
 
4337
                                            union spoolss_PrinterInfo,
 
4338
                                            count + 1);
 
4339
                if (!info) {
 
4340
                        result = WERR_NOMEM;
 
4341
                        goto out;
 
4342
                }
 
4343
 
 
4344
                result = winreg_get_printer(mem_ctx, b,
 
4345
                                            printer, &info2);
 
4346
                if (!W_ERROR_IS_OK(result)) {
 
4347
                        goto out;
 
4348
                }
 
4349
 
 
4350
                switch (level) {
 
4351
                case 0:
 
4352
                        result = construct_printer_info0(info, session_info,
 
4353
                                                         msg_ctx, info2,
 
4354
                                                         servername,
 
4355
                                                         &info[count].info0, snum);
 
4356
                        break;
 
4357
                case 1:
 
4358
                        result = construct_printer_info1(info, info2, flags,
 
4359
                                                         servername,
 
4360
                                                         &info[count].info1, snum);
 
4361
                        break;
 
4362
                case 2:
 
4363
                        result = construct_printer_info2(info, msg_ctx, info2,
 
4364
                                                         servername,
 
4365
                                                         &info[count].info2, snum);
 
4366
                        break;
 
4367
                case 4:
 
4368
                        result = construct_printer_info4(info, info2,
 
4369
                                                         servername,
 
4370
                                                         &info[count].info4, snum);
 
4371
                        break;
 
4372
                case 5:
 
4373
                        result = construct_printer_info5(info, info2,
 
4374
                                                         servername,
 
4375
                                                         &info[count].info5, snum);
 
4376
                        break;
 
4377
 
 
4378
                default:
 
4379
                        result = WERR_UNKNOWN_LEVEL;
 
4380
                        goto out;
 
4381
                }
 
4382
 
 
4383
                if (!W_ERROR_IS_OK(result)) {
 
4384
                        goto out;
 
4385
                }
 
4386
 
 
4387
                count++;
 
4388
        }
 
4389
 
 
4390
        *count_p = count;
 
4391
        *info_p = info;
 
4392
 
 
4393
 out:
 
4394
        if (!W_ERROR_IS_OK(result)) {
 
4395
                TALLOC_FREE(info);
 
4396
                return result;
 
4397
        }
 
4398
 
 
4399
        *info_p = info;
 
4400
 
 
4401
        return WERR_OK;
 
4402
}
 
4403
 
 
4404
/********************************************************************
 
4405
 * handle enumeration of printers at level 0
 
4406
 ********************************************************************/
 
4407
 
 
4408
static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
 
4409
                                  const struct auth_serversupplied_info *session_info,
 
4410
                                  struct messaging_context *msg_ctx,
 
4411
                                  uint32_t flags,
 
4412
                                  const char *servername,
 
4413
                                  union spoolss_PrinterInfo **info,
 
4414
                                  uint32_t *count)
 
4415
{
 
4416
        DEBUG(4,("enum_all_printers_info_0\n"));
 
4417
 
 
4418
        return enum_all_printers_info_level(mem_ctx, session_info, msg_ctx,
 
4419
                                            servername, 0, flags, info, count);
 
4420
}
 
4421
 
 
4422
 
 
4423
/********************************************************************
 
4424
********************************************************************/
 
4425
 
 
4426
static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
 
4427
                                       const struct auth_serversupplied_info *session_info,
 
4428
                                       struct messaging_context *msg_ctx,
 
4429
                                       const char *servername,
 
4430
                                       uint32_t flags,
 
4431
                                       union spoolss_PrinterInfo **info,
 
4432
                                       uint32_t *count)
 
4433
{
 
4434
        DEBUG(4,("enum_all_printers_info_1\n"));
 
4435
 
 
4436
        return enum_all_printers_info_level(mem_ctx, session_info, msg_ctx,
 
4437
                                            servername, 1, flags, info, count);
 
4438
}
 
4439
 
 
4440
/********************************************************************
 
4441
 enum_all_printers_info_1_local.
 
4442
*********************************************************************/
 
4443
 
 
4444
static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
 
4445
                                             const struct auth_serversupplied_info *session_info,
 
4446
                                             struct messaging_context *msg_ctx,
 
4447
                                             const char *servername,
 
4448
                                             union spoolss_PrinterInfo **info,
 
4449
                                             uint32_t *count)
 
4450
{
 
4451
        DEBUG(4,("enum_all_printers_info_1_local\n"));
 
4452
 
 
4453
        return enum_all_printers_info_1(mem_ctx, session_info, msg_ctx,
 
4454
                                        servername, PRINTER_ENUM_ICON8, info, count);
 
4455
}
 
4456
 
 
4457
/********************************************************************
 
4458
 enum_all_printers_info_1_name.
 
4459
*********************************************************************/
 
4460
 
 
4461
static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
 
4462
                                            const struct auth_serversupplied_info *session_info,
 
4463
                                            struct messaging_context *msg_ctx,
 
4464
                                            const char *servername,
 
4465
                                            union spoolss_PrinterInfo **info,
 
4466
                                            uint32_t *count)
 
4467
{
 
4468
        const char *s = servername;
 
4469
 
 
4470
        DEBUG(4,("enum_all_printers_info_1_name\n"));
 
4471
 
 
4472
        if ((servername[0] == '\\') && (servername[1] == '\\')) {
 
4473
                s = servername + 2;
 
4474
        }
 
4475
 
 
4476
        if (!is_myname_or_ipaddr(s)) {
 
4477
                return WERR_INVALID_NAME;
 
4478
        }
 
4479
 
 
4480
        return enum_all_printers_info_1(mem_ctx, session_info, msg_ctx,
 
4481
                                        servername, PRINTER_ENUM_ICON8, info, count);
 
4482
}
 
4483
 
 
4484
/********************************************************************
 
4485
 enum_all_printers_info_1_network.
 
4486
*********************************************************************/
 
4487
 
 
4488
static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
 
4489
                                               const struct auth_serversupplied_info *session_info,
 
4490
                                               struct messaging_context *msg_ctx,
 
4491
                                               const char *servername,
 
4492
                                               union spoolss_PrinterInfo **info,
 
4493
                                               uint32_t *count)
 
4494
{
 
4495
        const char *s = servername;
 
4496
 
 
4497
        DEBUG(4,("enum_all_printers_info_1_network\n"));
 
4498
 
 
4499
        /* If we respond to a enum_printers level 1 on our name with flags
 
4500
           set to PRINTER_ENUM_REMOTE with a list of printers then these
 
4501
           printers incorrectly appear in the APW browse list.
 
4502
           Specifically the printers for the server appear at the workgroup
 
4503
           level where all the other servers in the domain are
 
4504
           listed. Windows responds to this call with a
 
4505
           WERR_CAN_NOT_COMPLETE so we should do the same. */
 
4506
 
 
4507
        if (servername[0] == '\\' && servername[1] == '\\') {
 
4508
                 s = servername + 2;
 
4509
        }
 
4510
 
 
4511
        if (is_myname_or_ipaddr(s)) {
 
4512
                 return WERR_CAN_NOT_COMPLETE;
 
4513
        }
 
4514
 
 
4515
        return enum_all_printers_info_1(mem_ctx, session_info, msg_ctx,
 
4516
                                        servername, PRINTER_ENUM_NAME, info, count);
 
4517
}
 
4518
 
 
4519
/********************************************************************
 
4520
 * api_spoolss_enumprinters
 
4521
 *
 
4522
 * called from api_spoolss_enumprinters (see this to understand)
 
4523
 ********************************************************************/
 
4524
 
 
4525
static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
 
4526
                                       const struct auth_serversupplied_info *session_info,
 
4527
                                       struct messaging_context *msg_ctx,
 
4528
                                       const char *servername,
 
4529
                                       union spoolss_PrinterInfo **info,
 
4530
                                       uint32_t *count)
 
4531
{
 
4532
        DEBUG(4,("enum_all_printers_info_2\n"));
 
4533
 
 
4534
        return enum_all_printers_info_level(mem_ctx, session_info, msg_ctx,
 
4535
                                            servername, 2, 0, info, count);
 
4536
}
 
4537
 
 
4538
/********************************************************************
 
4539
 * handle enumeration of printers at level 1
 
4540
 ********************************************************************/
 
4541
 
 
4542
static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
 
4543
                                  const struct auth_serversupplied_info *session_info,
 
4544
                                  struct messaging_context *msg_ctx,
 
4545
                                  uint32_t flags,
 
4546
                                  const char *servername,
 
4547
                                  union spoolss_PrinterInfo **info,
 
4548
                                  uint32_t *count)
 
4549
{
 
4550
        /* Not all the flags are equals */
 
4551
 
 
4552
        if (flags & PRINTER_ENUM_LOCAL) {
 
4553
                return enum_all_printers_info_1_local(mem_ctx, session_info,
 
4554
                                                      msg_ctx, servername, info, count);
 
4555
        }
 
4556
 
 
4557
        if (flags & PRINTER_ENUM_NAME) {
 
4558
                return enum_all_printers_info_1_name(mem_ctx, session_info,
 
4559
                                                     msg_ctx, servername, info,
 
4560
                                                     count);
 
4561
        }
 
4562
 
 
4563
        if (flags & PRINTER_ENUM_NETWORK) {
 
4564
                return enum_all_printers_info_1_network(mem_ctx, session_info,
 
4565
                                                        msg_ctx, servername, info,
 
4566
                                                        count);
 
4567
        }
 
4568
 
 
4569
        return WERR_OK; /* NT4sp5 does that */
 
4570
}
 
4571
 
 
4572
/********************************************************************
 
4573
 * handle enumeration of printers at level 2
 
4574
 ********************************************************************/
 
4575
 
 
4576
static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
 
4577
                                  const struct auth_serversupplied_info *session_info,
 
4578
                                  struct messaging_context *msg_ctx,
 
4579
                                  uint32_t flags,
 
4580
                                  const char *servername,
 
4581
                                  union spoolss_PrinterInfo **info,
 
4582
                                  uint32_t *count)
 
4583
{
 
4584
        if (flags & PRINTER_ENUM_LOCAL) {
 
4585
 
 
4586
                return enum_all_printers_info_2(mem_ctx, session_info, msg_ctx,
 
4587
                                                servername,
 
4588
                                                info, count);
 
4589
        }
 
4590
 
 
4591
        if (flags & PRINTER_ENUM_NAME) {
 
4592
                if (servername && !is_myname_or_ipaddr(canon_servername(servername))) {
 
4593
                        return WERR_INVALID_NAME;
 
4594
                }
 
4595
 
 
4596
                return enum_all_printers_info_2(mem_ctx, session_info, msg_ctx,
 
4597
                                                servername,
 
4598
                                                info, count);
 
4599
        }
 
4600
 
 
4601
        if (flags & PRINTER_ENUM_REMOTE) {
 
4602
                return WERR_UNKNOWN_LEVEL;
 
4603
        }
 
4604
 
 
4605
        return WERR_OK;
 
4606
}
 
4607
 
 
4608
/********************************************************************
 
4609
 * handle enumeration of printers at level 4
 
4610
 ********************************************************************/
 
4611
 
 
4612
static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
 
4613
                                  const struct auth_serversupplied_info *session_info,
 
4614
                                  struct messaging_context *msg_ctx,
 
4615
                                  uint32_t flags,
 
4616
                                  const char *servername,
 
4617
                                  union spoolss_PrinterInfo **info,
 
4618
                                  uint32_t *count)
 
4619
{
 
4620
        DEBUG(4,("enum_all_printers_info_4\n"));
 
4621
 
 
4622
        return enum_all_printers_info_level(mem_ctx, session_info, msg_ctx,
 
4623
                                            servername, 4, flags, info, count);
 
4624
}
 
4625
 
 
4626
 
 
4627
/********************************************************************
 
4628
 * handle enumeration of printers at level 5
 
4629
 ********************************************************************/
 
4630
 
 
4631
static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
 
4632
                                  const struct auth_serversupplied_info *session_info,
 
4633
                                  struct messaging_context *msg_ctx,
 
4634
                                  uint32_t flags,
 
4635
                                  const char *servername,
 
4636
                                  union spoolss_PrinterInfo **info,
 
4637
                                  uint32_t *count)
 
4638
{
 
4639
        DEBUG(4,("enum_all_printers_info_5\n"));
 
4640
 
 
4641
        return enum_all_printers_info_level(mem_ctx, session_info, msg_ctx,
 
4642
                                            servername, 5, flags, info, count);
 
4643
}
 
4644
 
 
4645
/****************************************************************
 
4646
 _spoolss_EnumPrinters
 
4647
****************************************************************/
 
4648
 
 
4649
WERROR _spoolss_EnumPrinters(struct pipes_struct *p,
 
4650
                             struct spoolss_EnumPrinters *r)
 
4651
{
 
4652
        const struct auth_serversupplied_info *session_info = get_session_info_system();
 
4653
        WERROR result;
 
4654
 
 
4655
        /* that's an [in out] buffer */
 
4656
 
 
4657
        if (!r->in.buffer && (r->in.offered != 0)) {
 
4658
                return WERR_INVALID_PARAM;
 
4659
        }
 
4660
 
 
4661
        DEBUG(4,("_spoolss_EnumPrinters\n"));
 
4662
 
 
4663
        *r->out.needed = 0;
 
4664
        *r->out.count = 0;
 
4665
        *r->out.info = NULL;
 
4666
 
 
4667
        /*
 
4668
         * Level 1:
 
4669
         *          flags==PRINTER_ENUM_NAME
 
4670
         *           if name=="" then enumerates all printers
 
4671
         *           if name!="" then enumerate the printer
 
4672
         *          flags==PRINTER_ENUM_REMOTE
 
4673
         *          name is NULL, enumerate printers
 
4674
         * Level 2: name!="" enumerates printers, name can't be NULL
 
4675
         * Level 3: doesn't exist
 
4676
         * Level 4: does a local registry lookup
 
4677
         * Level 5: same as Level 2
 
4678
         */
 
4679
 
 
4680
        if (r->in.server && r->in.server[0] == '\0') {
 
4681
                r->in.server = NULL;
 
4682
        }
 
4683
 
 
4684
        switch (r->in.level) {
 
4685
        case 0:
 
4686
                result = enumprinters_level0(p->mem_ctx, session_info,
 
4687
                                             p->msg_ctx, r->in.flags,
 
4688
                                             r->in.server,
 
4689
                                             r->out.info, r->out.count);
 
4690
                break;
 
4691
        case 1:
 
4692
                result = enumprinters_level1(p->mem_ctx, session_info,
 
4693
                                             p->msg_ctx, r->in.flags,
 
4694
                                             r->in.server,
 
4695
                                             r->out.info, r->out.count);
 
4696
                break;
 
4697
        case 2:
 
4698
                result = enumprinters_level2(p->mem_ctx, session_info,
 
4699
                                             p->msg_ctx, r->in.flags,
 
4700
                                             r->in.server,
 
4701
                                             r->out.info, r->out.count);
 
4702
                break;
 
4703
        case 4:
 
4704
                result = enumprinters_level4(p->mem_ctx, session_info,
 
4705
                                             p->msg_ctx, r->in.flags,
 
4706
                                             r->in.server,
 
4707
                                             r->out.info, r->out.count);
 
4708
                break;
 
4709
        case 5:
 
4710
                result = enumprinters_level5(p->mem_ctx, session_info,
 
4711
                                             p->msg_ctx, r->in.flags,
 
4712
                                             r->in.server,
 
4713
                                             r->out.info, r->out.count);
 
4714
                break;
 
4715
        default:
 
4716
                return WERR_UNKNOWN_LEVEL;
 
4717
        }
 
4718
 
 
4719
        if (!W_ERROR_IS_OK(result)) {
 
4720
                return result;
 
4721
        }
 
4722
 
 
4723
        *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
 
4724
                                                     spoolss_EnumPrinters,
 
4725
                                                     *r->out.info, r->in.level,
 
4726
                                                     *r->out.count);
 
4727
        *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
 
4728
        *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
 
4729
 
 
4730
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 
4731
}
 
4732
 
 
4733
/****************************************************************
 
4734
 _spoolss_GetPrinter
 
4735
****************************************************************/
 
4736
 
 
4737
WERROR _spoolss_GetPrinter(struct pipes_struct *p,
 
4738
                           struct spoolss_GetPrinter *r)
 
4739
{
 
4740
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
4741
        struct spoolss_PrinterInfo2 *info2 = NULL;
 
4742
        WERROR result = WERR_OK;
 
4743
        int snum;
 
4744
 
 
4745
        /* that's an [in out] buffer */
 
4746
 
 
4747
        if (!r->in.buffer && (r->in.offered != 0)) {
 
4748
                return WERR_INVALID_PARAM;
 
4749
        }
 
4750
 
 
4751
        *r->out.needed = 0;
 
4752
 
 
4753
        if (Printer == NULL) {
 
4754
                return WERR_BADFID;
 
4755
        }
 
4756
 
 
4757
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
 
4758
                return WERR_BADFID;
 
4759
        }
 
4760
 
 
4761
        result = winreg_get_printer_internal(p->mem_ctx,
 
4762
                                    get_session_info_system(),
 
4763
                                    p->msg_ctx,
 
4764
                                    lp_const_servicename(snum),
 
4765
                                    &info2);
 
4766
        if (!W_ERROR_IS_OK(result)) {
 
4767
                goto out;
 
4768
        }
 
4769
 
 
4770
        switch (r->in.level) {
 
4771
        case 0:
 
4772
                result = construct_printer_info0(p->mem_ctx,
 
4773
                                                 get_session_info_system(),
 
4774
                                                 p->msg_ctx,
 
4775
                                                 info2,
 
4776
                                                 Printer->servername,
 
4777
                                                 &r->out.info->info0,
 
4778
                                                 snum);
 
4779
                break;
 
4780
        case 1:
 
4781
                result = construct_printer_info1(p->mem_ctx, info2,
 
4782
                                                 PRINTER_ENUM_ICON8,
 
4783
                                                 Printer->servername,
 
4784
                                                 &r->out.info->info1, snum);
 
4785
                break;
 
4786
        case 2:
 
4787
                result = construct_printer_info2(p->mem_ctx, p->msg_ctx, info2,
 
4788
                                                 Printer->servername,
 
4789
                                                 &r->out.info->info2, snum);
 
4790
                break;
 
4791
        case 3:
 
4792
                result = construct_printer_info3(p->mem_ctx, info2,
 
4793
                                                 Printer->servername,
 
4794
                                                 &r->out.info->info3, snum);
 
4795
                break;
 
4796
        case 4:
 
4797
                result = construct_printer_info4(p->mem_ctx, info2,
 
4798
                                                 Printer->servername,
 
4799
                                                 &r->out.info->info4, snum);
 
4800
                break;
 
4801
        case 5:
 
4802
                result = construct_printer_info5(p->mem_ctx, info2,
 
4803
                                                 Printer->servername,
 
4804
                                                 &r->out.info->info5, snum);
 
4805
                break;
 
4806
        case 6:
 
4807
                result = construct_printer_info6(p->mem_ctx, p->msg_ctx, info2,
 
4808
                                                 Printer->servername,
 
4809
                                                 &r->out.info->info6, snum);
 
4810
                break;
 
4811
        case 7:
 
4812
                result = construct_printer_info7(p->mem_ctx, p->msg_ctx,
 
4813
                                                 Printer->servername,
 
4814
                                                 &r->out.info->info7, snum);
 
4815
                break;
 
4816
        case 8:
 
4817
                result = construct_printer_info8(p->mem_ctx, info2,
 
4818
                                                 Printer->servername,
 
4819
                                                 &r->out.info->info8, snum);
 
4820
                break;
 
4821
        default:
 
4822
                result = WERR_UNKNOWN_LEVEL;
 
4823
                break;
 
4824
        }
 
4825
 
 
4826
 out:
 
4827
        if (!W_ERROR_IS_OK(result)) {
 
4828
                DEBUG(0, ("_spoolss_GetPrinter: failed to construct printer info level %d - %s\n",
 
4829
                          r->in.level, win_errstr(result)));
 
4830
                TALLOC_FREE(r->out.info);
 
4831
                return result;
 
4832
        }
 
4833
 
 
4834
        *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo,
 
4835
                                               r->out.info, r->in.level);
 
4836
        r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
 
4837
 
 
4838
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 
4839
}
 
4840
 
 
4841
/********************************************************************
 
4842
 ********************************************************************/
 
4843
 
 
4844
#define FILL_DRIVER_STRING(mem_ctx, in, out) \
 
4845
        do { \
 
4846
                if (in && strlen(in)) { \
 
4847
                        out = talloc_strdup(mem_ctx, in); \
 
4848
                } else { \
 
4849
                        out = talloc_strdup(mem_ctx, ""); \
 
4850
                } \
 
4851
                W_ERROR_HAVE_NO_MEMORY(out); \
 
4852
        } while (0);
 
4853
 
 
4854
#define FILL_DRIVER_UNC_STRING(mem_ctx, server, arch, ver, in, out) \
 
4855
        do { \
 
4856
                if (in && strlen(in)) { \
 
4857
                        out = talloc_asprintf(mem_ctx, "\\\\%s\\print$\\%s\\%d\\%s", server, get_short_archi(arch), ver, in); \
 
4858
                } else { \
 
4859
                        out = talloc_strdup(mem_ctx, ""); \
 
4860
                } \
 
4861
                W_ERROR_HAVE_NO_MEMORY(out); \
 
4862
        } while (0);
 
4863
 
 
4864
static WERROR string_array_from_driver_info(TALLOC_CTX *mem_ctx,
 
4865
                                                  const char **string_array,
 
4866
                                                  const char ***presult,
 
4867
                                                  const char *cservername,
 
4868
                                                  const char *arch,
 
4869
                                                  int version)
 
4870
{
 
4871
        int i, num_strings = 0;
 
4872
        const char **array = NULL;
 
4873
 
 
4874
        if (string_array == NULL) {
 
4875
                return WERR_INVALID_PARAMETER;
 
4876
        }
 
4877
 
 
4878
        for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
 
4879
                const char *str = NULL;
 
4880
 
 
4881
                if (cservername == NULL || arch == NULL) {
 
4882
                        FILL_DRIVER_STRING(mem_ctx, string_array[i], str);
 
4883
                } else {
 
4884
                        FILL_DRIVER_UNC_STRING(mem_ctx, cservername, arch, version, string_array[i], str);
 
4885
                }
 
4886
 
 
4887
                if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
 
4888
                        TALLOC_FREE(array);
 
4889
                        return WERR_NOMEM;
 
4890
                }
 
4891
        }
 
4892
 
 
4893
        if (i > 0) {
 
4894
                ADD_TO_ARRAY(mem_ctx, const char *, NULL,
 
4895
                             &array, &num_strings);
 
4896
        }
 
4897
 
 
4898
        if (presult) {
 
4899
                *presult = array;
 
4900
        }
 
4901
 
 
4902
        return WERR_OK;
 
4903
}
 
4904
 
 
4905
/********************************************************************
 
4906
 * fill a spoolss_DriverInfo1 struct
 
4907
 ********************************************************************/
 
4908
 
 
4909
static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
 
4910
                                        struct spoolss_DriverInfo1 *r,
 
4911
                                        const struct spoolss_DriverInfo8 *driver,
 
4912
                                        const char *servername)
 
4913
{
 
4914
        r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
 
4915
        W_ERROR_HAVE_NO_MEMORY(r->driver_name);
 
4916
 
 
4917
        return WERR_OK;
 
4918
}
 
4919
 
 
4920
/********************************************************************
 
4921
 * fill a spoolss_DriverInfo2 struct
 
4922
 ********************************************************************/
 
4923
 
 
4924
static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
 
4925
                                        struct spoolss_DriverInfo2 *r,
 
4926
                                        const struct spoolss_DriverInfo8 *driver,
 
4927
                                        const char *servername)
 
4928
 
 
4929
{
 
4930
        const char *cservername = canon_servername(servername);
 
4931
 
 
4932
        r->version              = driver->version;
 
4933
 
 
4934
        r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
 
4935
        W_ERROR_HAVE_NO_MEMORY(r->driver_name);
 
4936
        r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
 
4937
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
 
4938
 
 
4939
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
4940
                               driver->architecture,
 
4941
                               driver->version,
 
4942
                               driver->driver_path,
 
4943
                               r->driver_path);
 
4944
 
 
4945
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
4946
                               driver->architecture,
 
4947
                               driver->version,
 
4948
                               driver->data_file,
 
4949
                               r->data_file);
 
4950
 
 
4951
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
4952
                               driver->architecture,
 
4953
                               driver->version,
 
4954
                               driver->config_file,
 
4955
                               r->config_file);
 
4956
 
 
4957
        return WERR_OK;
 
4958
}
 
4959
 
 
4960
/********************************************************************
 
4961
 * fill a spoolss_DriverInfo3 struct
 
4962
 ********************************************************************/
 
4963
 
 
4964
static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
 
4965
                                        struct spoolss_DriverInfo3 *r,
 
4966
                                        const struct spoolss_DriverInfo8 *driver,
 
4967
                                        const char *servername)
 
4968
{
 
4969
        const char *cservername = canon_servername(servername);
 
4970
 
 
4971
        r->version              = driver->version;
 
4972
 
 
4973
        r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
 
4974
        W_ERROR_HAVE_NO_MEMORY(r->driver_name);
 
4975
        r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
 
4976
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
 
4977
 
 
4978
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
4979
                               driver->architecture,
 
4980
                               driver->version,
 
4981
                               driver->driver_path,
 
4982
                               r->driver_path);
 
4983
 
 
4984
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
4985
                               driver->architecture,
 
4986
                               driver->version,
 
4987
                               driver->data_file,
 
4988
                               r->data_file);
 
4989
 
 
4990
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
4991
                               driver->architecture,
 
4992
                               driver->version,
 
4993
                               driver->config_file,
 
4994
                               r->config_file);
 
4995
 
 
4996
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
4997
                               driver->architecture,
 
4998
                               driver->version,
 
4999
                               driver->help_file,
 
5000
                               r->help_file);
 
5001
 
 
5002
        FILL_DRIVER_STRING(mem_ctx,
 
5003
                           driver->monitor_name,
 
5004
                           r->monitor_name);
 
5005
 
 
5006
        FILL_DRIVER_STRING(mem_ctx,
 
5007
                           driver->default_datatype,
 
5008
                           r->default_datatype);
 
5009
 
 
5010
        return string_array_from_driver_info(mem_ctx,
 
5011
                                             driver->dependent_files,
 
5012
                                             &r->dependent_files,
 
5013
                                             cservername,
 
5014
                                             driver->architecture,
 
5015
                                             driver->version);
 
5016
}
 
5017
 
 
5018
/********************************************************************
 
5019
 * fill a spoolss_DriverInfo4 struct
 
5020
 ********************************************************************/
 
5021
 
 
5022
static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
 
5023
                                        struct spoolss_DriverInfo4 *r,
 
5024
                                        const struct spoolss_DriverInfo8 *driver,
 
5025
                                        const char *servername)
 
5026
{
 
5027
        const char *cservername = canon_servername(servername);
 
5028
        WERROR result;
 
5029
 
 
5030
        r->version              = driver->version;
 
5031
 
 
5032
        r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
 
5033
        W_ERROR_HAVE_NO_MEMORY(r->driver_name);
 
5034
        r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
 
5035
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
 
5036
 
 
5037
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
5038
                               driver->architecture,
 
5039
                               driver->version,
 
5040
                               driver->driver_path,
 
5041
                               r->driver_path);
 
5042
 
 
5043
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
5044
                               driver->architecture,
 
5045
                               driver->version,
 
5046
                               driver->data_file,
 
5047
                               r->data_file);
 
5048
 
 
5049
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
5050
                               driver->architecture,
 
5051
                               driver->version,
 
5052
                               driver->config_file,
 
5053
                               r->config_file);
 
5054
 
 
5055
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
5056
                               driver->architecture,
 
5057
                               driver->version,
 
5058
                               driver->help_file,
 
5059
                               r->help_file);
 
5060
 
 
5061
        result = string_array_from_driver_info(mem_ctx,
 
5062
                                               driver->dependent_files,
 
5063
                                               &r->dependent_files,
 
5064
                                               cservername,
 
5065
                                               driver->architecture,
 
5066
                                               driver->version);
 
5067
        if (!W_ERROR_IS_OK(result)) {
 
5068
                return result;
 
5069
        }
 
5070
 
 
5071
        FILL_DRIVER_STRING(mem_ctx,
 
5072
                           driver->monitor_name,
 
5073
                           r->monitor_name);
 
5074
 
 
5075
        FILL_DRIVER_STRING(mem_ctx,
 
5076
                           driver->default_datatype,
 
5077
                           r->default_datatype);
 
5078
 
 
5079
 
 
5080
        result = string_array_from_driver_info(mem_ctx,
 
5081
                                               driver->previous_names,
 
5082
                                               &r->previous_names,
 
5083
                                               NULL, NULL, 0);
 
5084
 
 
5085
        return result;
 
5086
}
 
5087
 
 
5088
/********************************************************************
 
5089
 * fill a spoolss_DriverInfo5 struct
 
5090
 ********************************************************************/
 
5091
 
 
5092
static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
 
5093
                                        struct spoolss_DriverInfo5 *r,
 
5094
                                        const struct spoolss_DriverInfo8 *driver,
 
5095
                                        const char *servername)
 
5096
{
 
5097
        const char *cservername = canon_servername(servername);
 
5098
 
 
5099
        r->version              = driver->version;
 
5100
 
 
5101
        r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
 
5102
        W_ERROR_HAVE_NO_MEMORY(r->driver_name);
 
5103
        r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
 
5104
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
 
5105
 
 
5106
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
5107
                               driver->architecture,
 
5108
                               driver->version,
 
5109
                               driver->driver_path,
 
5110
                               r->driver_path);
 
5111
 
 
5112
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
5113
                               driver->architecture,
 
5114
                               driver->version,
 
5115
                               driver->data_file,
 
5116
                               r->data_file);
 
5117
 
 
5118
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
5119
                               driver->architecture,
 
5120
                               driver->version,
 
5121
                               driver->config_file,
 
5122
                               r->config_file);
 
5123
 
 
5124
        r->driver_attributes    = 0;
 
5125
        r->config_version       = 0;
 
5126
        r->driver_version       = 0;
 
5127
 
 
5128
        return WERR_OK;
 
5129
}
 
5130
/********************************************************************
 
5131
 * fill a spoolss_DriverInfo6 struct
 
5132
 ********************************************************************/
 
5133
 
 
5134
static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
 
5135
                                        struct spoolss_DriverInfo6 *r,
 
5136
                                        const struct spoolss_DriverInfo8 *driver,
 
5137
                                        const char *servername)
 
5138
{
 
5139
        const char *cservername = canon_servername(servername);
 
5140
        WERROR result;
 
5141
 
 
5142
        r->version              = driver->version;
 
5143
 
 
5144
        r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
 
5145
        W_ERROR_HAVE_NO_MEMORY(r->driver_name);
 
5146
        r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
 
5147
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
 
5148
 
 
5149
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
5150
                               driver->architecture,
 
5151
                               driver->version,
 
5152
                               driver->driver_path,
 
5153
                               r->driver_path);
 
5154
 
 
5155
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
5156
                               driver->architecture,
 
5157
                               driver->version,
 
5158
                               driver->data_file,
 
5159
                               r->data_file);
 
5160
 
 
5161
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
5162
                               driver->architecture,
 
5163
                               driver->version,
 
5164
                               driver->config_file,
 
5165
                               r->config_file);
 
5166
 
 
5167
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
5168
                               driver->architecture,
 
5169
                               driver->version,
 
5170
                               driver->help_file,
 
5171
                               r->help_file);
 
5172
 
 
5173
        FILL_DRIVER_STRING(mem_ctx,
 
5174
                           driver->monitor_name,
 
5175
                           r->monitor_name);
 
5176
 
 
5177
        FILL_DRIVER_STRING(mem_ctx,
 
5178
                           driver->default_datatype,
 
5179
                           r->default_datatype);
 
5180
 
 
5181
        result = string_array_from_driver_info(mem_ctx,
 
5182
                                               driver->dependent_files,
 
5183
                                               &r->dependent_files,
 
5184
                                               cservername,
 
5185
                                               driver->architecture,
 
5186
                                               driver->version);
 
5187
        if (!W_ERROR_IS_OK(result)) {
 
5188
                return result;
 
5189
        }
 
5190
 
 
5191
        result = string_array_from_driver_info(mem_ctx,
 
5192
                                               driver->previous_names,
 
5193
                                               &r->previous_names,
 
5194
                                               NULL, NULL, 0);
 
5195
        if (!W_ERROR_IS_OK(result)) {
 
5196
                return result;
 
5197
        }
 
5198
 
 
5199
        r->driver_date          = driver->driver_date;
 
5200
        r->driver_version       = driver->driver_version;
 
5201
 
 
5202
        FILL_DRIVER_STRING(mem_ctx,
 
5203
                           driver->manufacturer_name,
 
5204
                           r->manufacturer_name);
 
5205
        FILL_DRIVER_STRING(mem_ctx,
 
5206
                           driver->manufacturer_url,
 
5207
                           r->manufacturer_url);
 
5208
        FILL_DRIVER_STRING(mem_ctx,
 
5209
                           driver->hardware_id,
 
5210
                           r->hardware_id);
 
5211
        FILL_DRIVER_STRING(mem_ctx,
 
5212
                           driver->provider,
 
5213
                           r->provider);
 
5214
 
 
5215
        return WERR_OK;
 
5216
}
 
5217
 
 
5218
/********************************************************************
 
5219
 * fill a spoolss_DriverInfo8 struct
 
5220
 ********************************************************************/
 
5221
 
 
5222
static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
 
5223
                                        struct spoolss_DriverInfo8 *r,
 
5224
                                        const struct spoolss_DriverInfo8 *driver,
 
5225
                                        const char *servername)
 
5226
{
 
5227
        const char *cservername = canon_servername(servername);
 
5228
        WERROR result;
 
5229
 
 
5230
        r->version              = driver->version;
 
5231
 
 
5232
        r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
 
5233
        W_ERROR_HAVE_NO_MEMORY(r->driver_name);
 
5234
        r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
 
5235
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
 
5236
 
 
5237
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
5238
                               driver->architecture,
 
5239
                               driver->version,
 
5240
                               driver->driver_path,
 
5241
                               r->driver_path);
 
5242
 
 
5243
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
5244
                               driver->architecture,
 
5245
                               driver->version,
 
5246
                               driver->data_file,
 
5247
                               r->data_file);
 
5248
 
 
5249
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
5250
                               driver->architecture,
 
5251
                               driver->version,
 
5252
                               driver->config_file,
 
5253
                               r->config_file);
 
5254
 
 
5255
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
 
5256
                               driver->architecture,
 
5257
                               driver->version,
 
5258
                               driver->help_file,
 
5259
                               r->help_file);
 
5260
 
 
5261
        FILL_DRIVER_STRING(mem_ctx,
 
5262
                           driver->monitor_name,
 
5263
                           r->monitor_name);
 
5264
 
 
5265
        FILL_DRIVER_STRING(mem_ctx,
 
5266
                           driver->default_datatype,
 
5267
                           r->default_datatype);
 
5268
 
 
5269
        result = string_array_from_driver_info(mem_ctx,
 
5270
                                               driver->dependent_files,
 
5271
                                               &r->dependent_files,
 
5272
                                               cservername,
 
5273
                                               driver->architecture,
 
5274
                                               driver->version);
 
5275
        if (!W_ERROR_IS_OK(result)) {
 
5276
                return result;
 
5277
        }
 
5278
 
 
5279
        result = string_array_from_driver_info(mem_ctx,
 
5280
                                               driver->previous_names,
 
5281
                                               &r->previous_names,
 
5282
                                               NULL, NULL, 0);
 
5283
        if (!W_ERROR_IS_OK(result)) {
 
5284
                return result;
 
5285
        }
 
5286
 
 
5287
        r->driver_date          = driver->driver_date;
 
5288
        r->driver_version       = driver->driver_version;
 
5289
 
 
5290
        FILL_DRIVER_STRING(mem_ctx,
 
5291
                           driver->manufacturer_name,
 
5292
                           r->manufacturer_name);
 
5293
        FILL_DRIVER_STRING(mem_ctx,
 
5294
                           driver->manufacturer_url,
 
5295
                           r->manufacturer_url);
 
5296
        FILL_DRIVER_STRING(mem_ctx,
 
5297
                           driver->hardware_id,
 
5298
                           r->hardware_id);
 
5299
        FILL_DRIVER_STRING(mem_ctx,
 
5300
                           driver->provider,
 
5301
                           r->provider);
 
5302
 
 
5303
        FILL_DRIVER_STRING(mem_ctx,
 
5304
                           driver->print_processor,
 
5305
                           r->print_processor);
 
5306
        FILL_DRIVER_STRING(mem_ctx,
 
5307
                           driver->vendor_setup,
 
5308
                           r->vendor_setup);
 
5309
 
 
5310
        result = string_array_from_driver_info(mem_ctx,
 
5311
                                               driver->color_profiles,
 
5312
                                               &r->color_profiles,
 
5313
                                               NULL, NULL, 0);
 
5314
        if (!W_ERROR_IS_OK(result)) {
 
5315
                return result;
 
5316
        }
 
5317
 
 
5318
        FILL_DRIVER_STRING(mem_ctx,
 
5319
                           driver->inf_path,
 
5320
                           r->inf_path);
 
5321
 
 
5322
        r->printer_driver_attributes    = driver->printer_driver_attributes;
 
5323
 
 
5324
        result = string_array_from_driver_info(mem_ctx,
 
5325
                                               driver->core_driver_dependencies,
 
5326
                                               &r->core_driver_dependencies,
 
5327
                                               NULL, NULL, 0);
 
5328
        if (!W_ERROR_IS_OK(result)) {
 
5329
                return result;
 
5330
        }
 
5331
 
 
5332
        r->min_inbox_driver_ver_date    = driver->min_inbox_driver_ver_date;
 
5333
        r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
 
5334
 
 
5335
        return WERR_OK;
 
5336
}
 
5337
 
 
5338
#if 0 /* disabled until marshalling issues are resolved - gd */
 
5339
/********************************************************************
 
5340
 ********************************************************************/
 
5341
 
 
5342
static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
 
5343
                                          struct spoolss_DriverFileInfo *r,
 
5344
                                          const char *cservername,
 
5345
                                          const char *file_name,
 
5346
                                          enum spoolss_DriverFileType file_type,
 
5347
                                          uint32_t file_version)
 
5348
{
 
5349
        r->file_name    = talloc_asprintf(mem_ctx, "\\\\%s%s",
 
5350
                                          cservername, file_name);
 
5351
        W_ERROR_HAVE_NO_MEMORY(r->file_name);
 
5352
        r->file_type    = file_type;
 
5353
        r->file_version = file_version;
 
5354
 
 
5355
        return WERR_OK;
 
5356
}
 
5357
 
 
5358
/********************************************************************
 
5359
 ********************************************************************/
 
5360
 
 
5361
static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
 
5362
                                                 const struct spoolss_DriverInfo8 *driver,
 
5363
                                                 const char *cservername,
 
5364
                                                 struct spoolss_DriverFileInfo **info_p,
 
5365
                                                 uint32_t *count_p)
 
5366
{
 
5367
        struct spoolss_DriverFileInfo *info = NULL;
 
5368
        uint32_t count = 0;
 
5369
        WERROR result;
 
5370
        uint32_t i;
 
5371
 
 
5372
        *info_p = NULL;
 
5373
        *count_p = 0;
 
5374
 
 
5375
        if (strlen(driver->driver_path)) {
 
5376
                info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
 
5377
                                            struct spoolss_DriverFileInfo,
 
5378
                                            count + 1);
 
5379
                W_ERROR_HAVE_NO_MEMORY(info);
 
5380
                result = fill_spoolss_DriverFileInfo(info,
 
5381
                                                     &info[count],
 
5382
                                                     cservername,
 
5383
                                                     driver->driver_path,
 
5384
                                                     SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
 
5385
                                                     0);
 
5386
                W_ERROR_NOT_OK_RETURN(result);
 
5387
                count++;
 
5388
        }
 
5389
 
 
5390
        if (strlen(driver->config_file)) {
 
5391
                info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
 
5392
                                            struct spoolss_DriverFileInfo,
 
5393
                                            count + 1);
 
5394
                W_ERROR_HAVE_NO_MEMORY(info);
 
5395
                result = fill_spoolss_DriverFileInfo(info,
 
5396
                                                     &info[count],
 
5397
                                                     cservername,
 
5398
                                                     driver->config_file,
 
5399
                                                     SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
 
5400
                                                     0);
 
5401
                W_ERROR_NOT_OK_RETURN(result);
 
5402
                count++;
 
5403
        }
 
5404
 
 
5405
        if (strlen(driver->data_file)) {
 
5406
                info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
 
5407
                                            struct spoolss_DriverFileInfo,
 
5408
                                            count + 1);
 
5409
                W_ERROR_HAVE_NO_MEMORY(info);
 
5410
                result = fill_spoolss_DriverFileInfo(info,
 
5411
                                                     &info[count],
 
5412
                                                     cservername,
 
5413
                                                     driver->data_file,
 
5414
                                                     SPOOLSS_DRIVER_FILE_TYPE_DATA,
 
5415
                                                     0);
 
5416
                W_ERROR_NOT_OK_RETURN(result);
 
5417
                count++;
 
5418
        }
 
5419
 
 
5420
        if (strlen(driver->help_file)) {
 
5421
                info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
 
5422
                                            struct spoolss_DriverFileInfo,
 
5423
                                            count + 1);
 
5424
                W_ERROR_HAVE_NO_MEMORY(info);
 
5425
                result = fill_spoolss_DriverFileInfo(info,
 
5426
                                                     &info[count],
 
5427
                                                     cservername,
 
5428
                                                     driver->help_file,
 
5429
                                                     SPOOLSS_DRIVER_FILE_TYPE_HELP,
 
5430
                                                     0);
 
5431
                W_ERROR_NOT_OK_RETURN(result);
 
5432
                count++;
 
5433
        }
 
5434
 
 
5435
        for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
 
5436
                info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
 
5437
                                            struct spoolss_DriverFileInfo,
 
5438
                                            count + 1);
 
5439
                W_ERROR_HAVE_NO_MEMORY(info);
 
5440
                result = fill_spoolss_DriverFileInfo(info,
 
5441
                                                     &info[count],
 
5442
                                                     cservername,
 
5443
                                                     driver->dependent_files[i],
 
5444
                                                     SPOOLSS_DRIVER_FILE_TYPE_OTHER,
 
5445
                                                     0);
 
5446
                W_ERROR_NOT_OK_RETURN(result);
 
5447
                count++;
 
5448
        }
 
5449
 
 
5450
        *info_p = info;
 
5451
        *count_p = count;
 
5452
 
 
5453
        return WERR_OK;
 
5454
}
 
5455
 
 
5456
/********************************************************************
 
5457
 * fill a spoolss_DriverInfo101 struct
 
5458
 ********************************************************************/
 
5459
 
 
5460
static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
 
5461
                                          struct spoolss_DriverInfo101 *r,
 
5462
                                          const struct spoolss_DriverInfo8 *driver,
 
5463
                                          const char *servername)
 
5464
{
 
5465
        const char *cservername = canon_servername(servername);
 
5466
        WERROR result;
 
5467
 
 
5468
        r->version              = driver->version;
 
5469
 
 
5470
        r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
 
5471
        W_ERROR_HAVE_NO_MEMORY(r->driver_name);
 
5472
        r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
 
5473
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
 
5474
 
 
5475
        result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
 
5476
                                                    cservername,
 
5477
                                                    &r->file_info,
 
5478
                                                    &r->file_count);
 
5479
        if (!W_ERROR_IS_OK(result)) {
 
5480
                return result;
 
5481
        }
 
5482
 
 
5483
        FILL_DRIVER_STRING(mem_ctx,
 
5484
                           driver->monitor_name,
 
5485
                           r->monitor_name);
 
5486
 
 
5487
        FILL_DRIVER_STRING(mem_ctx,
 
5488
                           driver->default_datatype,
 
5489
                           r->default_datatype);
 
5490
 
 
5491
        result = string_array_from_driver_info(mem_ctx,
 
5492
                                               driver->previous_names,
 
5493
                                               &r->previous_names,
 
5494
                                               NULL, NULL, 0);
 
5495
        if (!W_ERROR_IS_OK(result)) {
 
5496
                return result;
 
5497
        }
 
5498
 
 
5499
        r->driver_date          = driver->driver_date;
 
5500
        r->driver_version       = driver->driver_version;
 
5501
 
 
5502
        FILL_DRIVER_STRING(mem_ctx,
 
5503
                           driver->manufacturer_name,
 
5504
                           r->manufacturer_name);
 
5505
        FILL_DRIVER_STRING(mem_ctx,
 
5506
                           driver->manufacturer_url,
 
5507
                           r->manufacturer_url);
 
5508
        FILL_DRIVER_STRING(mem_ctx,
 
5509
                           driver->hardware_id,
 
5510
                           r->hardware_id);
 
5511
        FILL_DRIVER_STRING(mem_ctx,
 
5512
                           driver->provider,
 
5513
                           r->provider);
 
5514
 
 
5515
        return WERR_OK;
 
5516
}
 
5517
#endif
 
5518
/********************************************************************
 
5519
 ********************************************************************/
 
5520
 
 
5521
static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
 
5522
                                                  const struct auth_serversupplied_info *session_info,
 
5523
                                                  struct messaging_context *msg_ctx,
 
5524
                                                  uint32_t level,
 
5525
                                                  union spoolss_DriverInfo *r,
 
5526
                                                  int snum,
 
5527
                                                  const char *servername,
 
5528
                                                  const char *architecture,
 
5529
                                                  uint32_t version)
 
5530
{
 
5531
        struct spoolss_PrinterInfo2 *pinfo2 = NULL;
 
5532
        struct spoolss_DriverInfo8 *driver;
 
5533
        WERROR result;
 
5534
        struct dcerpc_binding_handle *b;
 
5535
 
 
5536
        if (level == 101) {
 
5537
                return WERR_UNKNOWN_LEVEL;
 
5538
        }
 
5539
 
 
5540
        result = winreg_printer_binding_handle(mem_ctx,
 
5541
                                               session_info,
 
5542
                                               msg_ctx,
 
5543
                                               &b);
 
5544
        if (!W_ERROR_IS_OK(result)) {
 
5545
                return result;
 
5546
        }
 
5547
 
 
5548
        result = winreg_get_printer(mem_ctx, b,
 
5549
                                    lp_const_servicename(snum),
 
5550
                                    &pinfo2);
 
5551
 
 
5552
        DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
 
5553
                win_errstr(result)));
 
5554
 
 
5555
        if (!W_ERROR_IS_OK(result)) {
 
5556
                return WERR_INVALID_PRINTER_NAME;
 
5557
        }
 
5558
 
 
5559
        result = winreg_get_driver(mem_ctx, b,
 
5560
                                   architecture,
 
5561
                                   pinfo2->drivername, version, &driver);
 
5562
 
 
5563
        DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
 
5564
                win_errstr(result)));
 
5565
 
 
5566
        if (!W_ERROR_IS_OK(result)) {
 
5567
                /*
 
5568
                 * Is this a W2k client ?
 
5569
                 */
 
5570
 
 
5571
                if (version < 3) {
 
5572
                        talloc_free(pinfo2);
 
5573
                        return WERR_UNKNOWN_PRINTER_DRIVER;
 
5574
                }
 
5575
 
 
5576
                /* Yes - try again with a WinNT driver. */
 
5577
                version = 2;
 
5578
                result = winreg_get_driver(mem_ctx, b,
 
5579
                                           architecture,
 
5580
                                           pinfo2->drivername,
 
5581
                                           version, &driver);
 
5582
                DEBUG(8,("construct_printer_driver_level: status: %s\n",
 
5583
                        win_errstr(result)));
 
5584
                if (!W_ERROR_IS_OK(result)) {
 
5585
                        talloc_free(pinfo2);
 
5586
                        return WERR_UNKNOWN_PRINTER_DRIVER;
 
5587
                }
 
5588
        }
 
5589
 
 
5590
        switch (level) {
 
5591
        case 1:
 
5592
                result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
 
5593
                break;
 
5594
        case 2:
 
5595
                result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
 
5596
                break;
 
5597
        case 3:
 
5598
                result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
 
5599
                break;
 
5600
        case 4:
 
5601
                result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
 
5602
                break;
 
5603
        case 5:
 
5604
                result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
 
5605
                break;
 
5606
        case 6:
 
5607
                result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
 
5608
                break;
 
5609
        case 8:
 
5610
                result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
 
5611
                break;
 
5612
#if 0 /* disabled until marshalling issues are resolved - gd */
 
5613
        case 101:
 
5614
                result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
 
5615
                break;
 
5616
#endif
 
5617
        default:
 
5618
                result = WERR_UNKNOWN_LEVEL;
 
5619
                break;
 
5620
        }
 
5621
 
 
5622
        talloc_free(pinfo2);
 
5623
        talloc_free(driver);
 
5624
 
 
5625
        return result;
 
5626
}
 
5627
 
 
5628
/****************************************************************
 
5629
 _spoolss_GetPrinterDriver2
 
5630
****************************************************************/
 
5631
 
 
5632
WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p,
 
5633
                                  struct spoolss_GetPrinterDriver2 *r)
 
5634
{
 
5635
        struct printer_handle *printer;
 
5636
        WERROR result;
 
5637
 
 
5638
        int snum;
 
5639
 
 
5640
        /* that's an [in out] buffer */
 
5641
 
 
5642
        if (!r->in.buffer && (r->in.offered != 0)) {
 
5643
                return WERR_INVALID_PARAM;
 
5644
        }
 
5645
 
 
5646
        DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
 
5647
 
 
5648
        if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
 
5649
                DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
 
5650
                return WERR_INVALID_PRINTER_NAME;
 
5651
        }
 
5652
 
 
5653
        *r->out.needed = 0;
 
5654
        *r->out.server_major_version = 0;
 
5655
        *r->out.server_minor_version = 0;
 
5656
 
 
5657
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
 
5658
                return WERR_BADFID;
 
5659
        }
 
5660
 
 
5661
        result = construct_printer_driver_info_level(p->mem_ctx,
 
5662
                                                     get_session_info_system(),
 
5663
                                                     p->msg_ctx,
 
5664
                                                     r->in.level, r->out.info,
 
5665
                                                     snum, printer->servername,
 
5666
                                                     r->in.architecture,
 
5667
                                                     r->in.client_major_version);
 
5668
        if (!W_ERROR_IS_OK(result)) {
 
5669
                TALLOC_FREE(r->out.info);
 
5670
                return result;
 
5671
        }
 
5672
 
 
5673
        *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo,
 
5674
                                               r->out.info, r->in.level);
 
5675
        r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
 
5676
 
 
5677
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 
5678
}
 
5679
 
 
5680
 
 
5681
/****************************************************************
 
5682
 _spoolss_StartPagePrinter
 
5683
****************************************************************/
 
5684
 
 
5685
WERROR _spoolss_StartPagePrinter(struct pipes_struct *p,
 
5686
                                 struct spoolss_StartPagePrinter *r)
 
5687
{
 
5688
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
5689
 
 
5690
        if (!Printer) {
 
5691
                DEBUG(3,("_spoolss_StartPagePrinter: "
 
5692
                        "Error in startpageprinter printer handle\n"));
 
5693
                return WERR_BADFID;
 
5694
        }
 
5695
 
 
5696
        Printer->page_started = true;
 
5697
        return WERR_OK;
 
5698
}
 
5699
 
 
5700
/****************************************************************
 
5701
 _spoolss_EndPagePrinter
 
5702
****************************************************************/
 
5703
 
 
5704
WERROR _spoolss_EndPagePrinter(struct pipes_struct *p,
 
5705
                               struct spoolss_EndPagePrinter *r)
 
5706
{
 
5707
        int snum;
 
5708
 
 
5709
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
5710
 
 
5711
        if (!Printer) {
 
5712
                DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
 
5713
                        OUR_HANDLE(r->in.handle)));
 
5714
                return WERR_BADFID;
 
5715
        }
 
5716
 
 
5717
        if (!get_printer_snum(p, r->in.handle, &snum, NULL))
 
5718
                return WERR_BADFID;
 
5719
 
 
5720
        Printer->page_started = false;
 
5721
        print_job_endpage(p->msg_ctx, snum, Printer->jobid);
 
5722
 
 
5723
        return WERR_OK;
 
5724
}
 
5725
 
 
5726
/****************************************************************
 
5727
 _spoolss_StartDocPrinter
 
5728
****************************************************************/
 
5729
 
 
5730
WERROR _spoolss_StartDocPrinter(struct pipes_struct *p,
 
5731
                                struct spoolss_StartDocPrinter *r)
 
5732
{
 
5733
        struct spoolss_DocumentInfo1 *info_1;
 
5734
        int snum;
 
5735
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
5736
        WERROR werr;
 
5737
 
 
5738
        if (!Printer) {
 
5739
                DEBUG(2,("_spoolss_StartDocPrinter: "
 
5740
                        "Invalid handle (%s:%u:%u)\n",
 
5741
                        OUR_HANDLE(r->in.handle)));
 
5742
                return WERR_BADFID;
 
5743
        }
 
5744
 
 
5745
        if (Printer->jobid) {
 
5746
                DEBUG(2, ("_spoolss_StartDocPrinter: "
 
5747
                          "StartDocPrinter called twice! "
 
5748
                          "(existing jobid = %d)\n", Printer->jobid));
 
5749
                return WERR_INVALID_HANDLE;
 
5750
        }
 
5751
 
 
5752
        if (r->in.level != 1) {
 
5753
                return WERR_UNKNOWN_LEVEL;
 
5754
        }
 
5755
 
 
5756
        info_1 = r->in.info.info1;
 
5757
 
 
5758
        /*
 
5759
         * a nice thing with NT is it doesn't listen to what you tell it.
 
5760
         * when asked to send _only_ RAW datas, it tries to send datas
 
5761
         * in EMF format.
 
5762
         *
 
5763
         * So I add checks like in NT Server ...
 
5764
         */
 
5765
 
 
5766
        if (info_1->datatype) {
 
5767
                if (strcmp(info_1->datatype, "RAW") != 0) {
 
5768
                        *r->out.job_id = 0;
 
5769
                        return WERR_INVALID_DATATYPE;
 
5770
                }
 
5771
        }
 
5772
 
 
5773
        /* get the share number of the printer */
 
5774
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
 
5775
                return WERR_BADFID;
 
5776
        }
 
5777
 
 
5778
        werr = print_job_start(p->session_info,
 
5779
                               p->msg_ctx,
 
5780
                               p->client_id->name,
 
5781
                               snum,
 
5782
                               info_1->document_name,
 
5783
                               info_1->output_file,
 
5784
                               Printer->devmode,
 
5785
                               &Printer->jobid);
 
5786
 
 
5787
        /* An error occured in print_job_start() so return an appropriate
 
5788
           NT error code. */
 
5789
 
 
5790
        if (!W_ERROR_IS_OK(werr)) {
 
5791
                return werr;
 
5792
        }
 
5793
 
 
5794
        Printer->document_started = true;
 
5795
        *r->out.job_id = Printer->jobid;
 
5796
 
 
5797
        return WERR_OK;
 
5798
}
 
5799
 
 
5800
/****************************************************************
 
5801
 _spoolss_EndDocPrinter
 
5802
****************************************************************/
 
5803
 
 
5804
WERROR _spoolss_EndDocPrinter(struct pipes_struct *p,
 
5805
                              struct spoolss_EndDocPrinter *r)
 
5806
{
 
5807
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
5808
        NTSTATUS status;
 
5809
        int snum;
 
5810
 
 
5811
        if (!Printer) {
 
5812
                DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
 
5813
                        OUR_HANDLE(r->in.handle)));
 
5814
                return WERR_BADFID;
 
5815
        }
 
5816
 
 
5817
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
 
5818
                return WERR_BADFID;
 
5819
        }
 
5820
 
 
5821
        Printer->document_started = false;
 
5822
        status = print_job_end(p->msg_ctx, snum, Printer->jobid, NORMAL_CLOSE);
 
5823
        if (!NT_STATUS_IS_OK(status)) {
 
5824
                DEBUG(2, ("_spoolss_EndDocPrinter: "
 
5825
                          "print_job_end failed [%s]\n",
 
5826
                          nt_errstr(status)));
 
5827
        }
 
5828
 
 
5829
        Printer->jobid = 0;
 
5830
        return ntstatus_to_werror(status);
 
5831
}
 
5832
 
 
5833
/****************************************************************
 
5834
 _spoolss_WritePrinter
 
5835
****************************************************************/
 
5836
 
 
5837
WERROR _spoolss_WritePrinter(struct pipes_struct *p,
 
5838
                             struct spoolss_WritePrinter *r)
 
5839
{
 
5840
        ssize_t buffer_written;
 
5841
        int snum;
 
5842
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
5843
 
 
5844
        if (!Printer) {
 
5845
                DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
 
5846
                        OUR_HANDLE(r->in.handle)));
 
5847
                *r->out.num_written = r->in._data_size;
 
5848
                return WERR_BADFID;
 
5849
        }
 
5850
 
 
5851
        if (!get_printer_snum(p, r->in.handle, &snum, NULL))
 
5852
                return WERR_BADFID;
 
5853
 
 
5854
        /* print_job_write takes care of checking for PJOB_SMBD_SPOOLING */
 
5855
        buffer_written = print_job_write(server_event_context(),p->msg_ctx,
 
5856
                                                   snum, Printer->jobid,
 
5857
                                                   (const char *)r->in.data.data,
 
5858
                                                   (size_t)r->in._data_size);
 
5859
        if (buffer_written == (ssize_t)-1) {
 
5860
                *r->out.num_written = 0;
 
5861
                if (errno == ENOSPC)
 
5862
                        return WERR_NO_SPOOL_SPACE;
 
5863
                else
 
5864
                        return WERR_ACCESS_DENIED;
 
5865
        }
 
5866
 
 
5867
        *r->out.num_written = r->in._data_size;
 
5868
 
 
5869
        return WERR_OK;
 
5870
}
 
5871
 
 
5872
/********************************************************************
 
5873
 * api_spoolss_getprinter
 
5874
 * called from the spoolss dispatcher
 
5875
 *
 
5876
 ********************************************************************/
 
5877
 
 
5878
static WERROR control_printer(struct policy_handle *handle, uint32_t command,
 
5879
                              struct pipes_struct *p)
 
5880
{
 
5881
        const struct auth_serversupplied_info *session_info = p->session_info;
 
5882
        int snum;
 
5883
        WERROR errcode = WERR_BADFUNC;
 
5884
        struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
 
5885
 
 
5886
        if (!Printer) {
 
5887
                DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
 
5888
                        OUR_HANDLE(handle)));
 
5889
                return WERR_BADFID;
 
5890
        }
 
5891
 
 
5892
        if (!get_printer_snum(p, handle, &snum, NULL))
 
5893
                return WERR_BADFID;
 
5894
 
 
5895
        switch (command) {
 
5896
        case SPOOLSS_PRINTER_CONTROL_PAUSE:
 
5897
                errcode = print_queue_pause(session_info, p->msg_ctx, snum);
 
5898
                break;
 
5899
        case SPOOLSS_PRINTER_CONTROL_RESUME:
 
5900
        case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
 
5901
                errcode = print_queue_resume(session_info, p->msg_ctx, snum);
 
5902
                break;
 
5903
        case SPOOLSS_PRINTER_CONTROL_PURGE:
 
5904
                errcode = print_queue_purge(session_info, p->msg_ctx, snum);
 
5905
                break;
 
5906
        default:
 
5907
                return WERR_UNKNOWN_LEVEL;
 
5908
        }
 
5909
 
 
5910
        return errcode;
 
5911
}
 
5912
 
 
5913
 
 
5914
/****************************************************************
 
5915
 _spoolss_AbortPrinter
 
5916
 * From MSDN: "Deletes printer's spool file if printer is configured
 
5917
 * for spooling"
 
5918
****************************************************************/
 
5919
 
 
5920
WERROR _spoolss_AbortPrinter(struct pipes_struct *p,
 
5921
                             struct spoolss_AbortPrinter *r)
 
5922
{
 
5923
        struct printer_handle   *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
5924
        int             snum;
 
5925
        WERROR          errcode = WERR_OK;
 
5926
 
 
5927
        if (!Printer) {
 
5928
                DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
 
5929
                        OUR_HANDLE(r->in.handle)));
 
5930
                return WERR_BADFID;
 
5931
        }
 
5932
 
 
5933
        if (!get_printer_snum(p, r->in.handle, &snum, NULL))
 
5934
                return WERR_BADFID;
 
5935
 
 
5936
        if (!Printer->document_started) {
 
5937
                return WERR_SPL_NO_STARTDOC;
 
5938
        }
 
5939
 
 
5940
        errcode = print_job_delete(p->session_info,
 
5941
                                   p->msg_ctx,
 
5942
                                   snum,
 
5943
                                   Printer->jobid);
 
5944
 
 
5945
        return errcode;
 
5946
}
 
5947
 
 
5948
/********************************************************************
 
5949
 * called by spoolss_api_setprinter
 
5950
 * when updating a printer description
 
5951
 ********************************************************************/
 
5952
 
 
5953
static WERROR update_printer_sec(struct policy_handle *handle,
 
5954
                                 struct pipes_struct *p,
 
5955
                                 struct sec_desc_buf *secdesc_ctr)
 
5956
{
 
5957
        struct spoolss_security_descriptor *new_secdesc = NULL;
 
5958
        struct spoolss_security_descriptor *old_secdesc = NULL;
 
5959
        const char *printer;
 
5960
        WERROR result;
 
5961
        int snum;
 
5962
        struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
 
5963
        struct dcerpc_binding_handle *b;
 
5964
 
 
5965
        if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
 
5966
                DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
 
5967
                         OUR_HANDLE(handle)));
 
5968
 
 
5969
                result = WERR_BADFID;
 
5970
                goto done;
 
5971
        }
 
5972
 
 
5973
        if (secdesc_ctr == NULL) {
 
5974
                DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
 
5975
                result = WERR_INVALID_PARAM;
 
5976
                goto done;
 
5977
        }
 
5978
        printer = lp_const_servicename(snum);
 
5979
 
 
5980
        /* Check the user has permissions to change the security
 
5981
           descriptor.  By experimentation with two NT machines, the user
 
5982
           requires Full Access to the printer to change security
 
5983
           information. */
 
5984
 
 
5985
        if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
 
5986
                DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
 
5987
                result = WERR_ACCESS_DENIED;
 
5988
                goto done;
 
5989
        }
 
5990
 
 
5991
        result = winreg_printer_binding_handle(p->mem_ctx,
 
5992
                                               get_session_info_system(),
 
5993
                                               p->msg_ctx,
 
5994
                                               &b);
 
5995
        if (!W_ERROR_IS_OK(result)) {
 
5996
                goto done;
 
5997
        }
 
5998
 
 
5999
        /* NT seems to like setting the security descriptor even though
 
6000
           nothing may have actually changed. */
 
6001
        result = winreg_get_printer_secdesc(p->mem_ctx, b,
 
6002
                                            printer,
 
6003
                                            &old_secdesc);
 
6004
        if (!W_ERROR_IS_OK(result)) {
 
6005
                DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc_internal() failed\n"));
 
6006
                result = WERR_BADFID;
 
6007
                goto done;
 
6008
        }
 
6009
 
 
6010
        if (DEBUGLEVEL >= 10) {
 
6011
                struct security_acl *the_acl;
 
6012
                int i;
 
6013
 
 
6014
                the_acl = old_secdesc->dacl;
 
6015
                DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
 
6016
                           printer, the_acl->num_aces));
 
6017
 
 
6018
                for (i = 0; i < the_acl->num_aces; i++) {
 
6019
                        DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
 
6020
                                           &the_acl->aces[i].trustee),
 
6021
                                  the_acl->aces[i].access_mask));
 
6022
                }
 
6023
 
 
6024
                the_acl = secdesc_ctr->sd->dacl;
 
6025
 
 
6026
                if (the_acl) {
 
6027
                        DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
 
6028
                                   printer, the_acl->num_aces));
 
6029
 
 
6030
                        for (i = 0; i < the_acl->num_aces; i++) {
 
6031
                                DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
 
6032
                                                   &the_acl->aces[i].trustee),
 
6033
                                           the_acl->aces[i].access_mask));
 
6034
                        }
 
6035
                } else {
 
6036
                        DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
 
6037
                }
 
6038
        }
 
6039
 
 
6040
        new_secdesc = sec_desc_merge(p->mem_ctx, secdesc_ctr->sd, old_secdesc);
 
6041
        if (new_secdesc == NULL) {
 
6042
                result = WERR_NOMEM;
 
6043
                goto done;
 
6044
        }
 
6045
 
 
6046
        if (security_descriptor_equal(new_secdesc, old_secdesc)) {
 
6047
                result = WERR_OK;
 
6048
                goto done;
 
6049
        }
 
6050
 
 
6051
        result = winreg_set_printer_secdesc(p->mem_ctx, b,
 
6052
                                            printer,
 
6053
                                            new_secdesc);
 
6054
 
 
6055
 done:
 
6056
        return result;
 
6057
}
 
6058
 
 
6059
/********************************************************************
 
6060
 Canonicalize printer info from a client
 
6061
 ********************************************************************/
 
6062
 
 
6063
static bool check_printer_ok(TALLOC_CTX *mem_ctx,
 
6064
                             struct spoolss_SetPrinterInfo2 *info2,
 
6065
                             int snum)
 
6066
{
 
6067
        fstring printername;
 
6068
        const char *p;
 
6069
 
 
6070
        DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
 
6071
                "portname=%s drivername=%s comment=%s location=%s\n",
 
6072
                info2->servername, info2->printername, info2->sharename,
 
6073
                info2->portname, info2->drivername, info2->comment,
 
6074
                info2->location));
 
6075
 
 
6076
        /* we force some elements to "correct" values */
 
6077
        info2->servername = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
 
6078
        if (info2->servername == NULL) {
 
6079
                return false;
 
6080
        }
 
6081
        info2->sharename = talloc_strdup(mem_ctx, lp_const_servicename(snum));
 
6082
        if (info2->sharename == NULL) {
 
6083
                return false;
 
6084
        }
 
6085
 
 
6086
        /* check to see if we allow printername != sharename */
 
6087
        if (lp_force_printername(snum)) {
 
6088
                info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
 
6089
                                        global_myname(), info2->sharename);
 
6090
        } else {
 
6091
                /* make sure printername is in \\server\printername format */
 
6092
                fstrcpy(printername, info2->printername);
 
6093
                p = printername;
 
6094
                if ( printername[0] == '\\' && printername[1] == '\\' ) {
 
6095
                        if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
 
6096
                                p++;
 
6097
                }
 
6098
 
 
6099
                info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
 
6100
                                        global_myname(), p);
 
6101
        }
 
6102
        if (info2->printername == NULL) {
 
6103
                return false;
 
6104
        }
 
6105
 
 
6106
        info2->attributes |= PRINTER_ATTRIBUTE_SAMBA;
 
6107
        info2->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
 
6108
 
 
6109
        return true;
 
6110
}
 
6111
 
 
6112
/****************************************************************************
 
6113
****************************************************************************/
 
6114
 
 
6115
static WERROR add_port_hook(TALLOC_CTX *ctx, struct security_token *token, const char *portname, const char *uri)
 
6116
{
 
6117
        char *cmd = lp_addport_cmd();
 
6118
        char *command = NULL;
 
6119
        int ret;
 
6120
        bool is_print_op = false;
 
6121
 
 
6122
        if ( !*cmd ) {
 
6123
                return WERR_ACCESS_DENIED;
 
6124
        }
 
6125
 
 
6126
        command = talloc_asprintf(ctx,
 
6127
                        "%s \"%s\" \"%s\"", cmd, portname, uri );
 
6128
        if (!command) {
 
6129
                return WERR_NOMEM;
 
6130
        }
 
6131
 
 
6132
        if ( token )
 
6133
                is_print_op = security_token_has_privilege(token, SEC_PRIV_PRINT_OPERATOR);
 
6134
 
 
6135
        DEBUG(10,("Running [%s]\n", command));
 
6136
 
 
6137
        /********* BEGIN SePrintOperatorPrivilege **********/
 
6138
 
 
6139
        if ( is_print_op )
 
6140
                become_root();
 
6141
 
 
6142
        ret = smbrun(command, NULL);
 
6143
 
 
6144
        if ( is_print_op )
 
6145
                unbecome_root();
 
6146
 
 
6147
        /********* END SePrintOperatorPrivilege **********/
 
6148
 
 
6149
        DEBUGADD(10,("returned [%d]\n", ret));
 
6150
 
 
6151
        TALLOC_FREE(command);
 
6152
 
 
6153
        if ( ret != 0 ) {
 
6154
                return WERR_ACCESS_DENIED;
 
6155
        }
 
6156
 
 
6157
        return WERR_OK;
 
6158
}
 
6159
 
 
6160
/****************************************************************************
 
6161
****************************************************************************/
 
6162
 
 
6163
static bool add_printer_hook(TALLOC_CTX *ctx, struct security_token *token,
 
6164
                             struct spoolss_SetPrinterInfo2 *info2,
 
6165
                             const char *remote_machine,
 
6166
                             struct messaging_context *msg_ctx)
 
6167
{
 
6168
        char *cmd = lp_addprinter_cmd();
 
6169
        char **qlines;
 
6170
        char *command = NULL;
 
6171
        int numlines;
 
6172
        int ret;
 
6173
        int fd;
 
6174
        bool is_print_op = false;
 
6175
 
 
6176
        if (!remote_machine) {
 
6177
                return false;
 
6178
        }
 
6179
 
 
6180
        command = talloc_asprintf(ctx,
 
6181
                        "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
 
6182
                        cmd, info2->printername, info2->sharename,
 
6183
                        info2->portname, info2->drivername,
 
6184
                        info2->location, info2->comment, remote_machine);
 
6185
        if (!command) {
 
6186
                return false;
 
6187
        }
 
6188
 
 
6189
        if ( token )
 
6190
                is_print_op = security_token_has_privilege(token, SEC_PRIV_PRINT_OPERATOR);
 
6191
 
 
6192
        DEBUG(10,("Running [%s]\n", command));
 
6193
 
 
6194
        /********* BEGIN SePrintOperatorPrivilege **********/
 
6195
 
 
6196
        if ( is_print_op )
 
6197
                become_root();
 
6198
 
 
6199
        if ( (ret = smbrun(command, &fd)) == 0 ) {
 
6200
                /* Tell everyone we updated smb.conf. */
 
6201
                message_send_all(msg_ctx, MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
 
6202
        }
 
6203
 
 
6204
        if ( is_print_op )
 
6205
                unbecome_root();
 
6206
 
 
6207
        /********* END SePrintOperatorPrivilege **********/
 
6208
 
 
6209
        DEBUGADD(10,("returned [%d]\n", ret));
 
6210
 
 
6211
        TALLOC_FREE(command);
 
6212
 
 
6213
        if ( ret != 0 ) {
 
6214
                if (fd != -1)
 
6215
                        close(fd);
 
6216
                return false;
 
6217
        }
 
6218
 
 
6219
        /* reload our services immediately */
 
6220
        become_root();
 
6221
        reload_services(msg_ctx, -1, false);
 
6222
        unbecome_root();
 
6223
 
 
6224
        numlines = 0;
 
6225
        /* Get lines and convert them back to dos-codepage */
 
6226
        qlines = fd_lines_load(fd, &numlines, 0, NULL);
 
6227
        DEBUGADD(10,("Lines returned = [%d]\n", numlines));
 
6228
        close(fd);
 
6229
 
 
6230
        /* Set the portname to what the script says the portname should be. */
 
6231
        /* but don't require anything to be return from the script exit a good error code */
 
6232
 
 
6233
        if (numlines) {
 
6234
                /* Set the portname to what the script says the portname should be. */
 
6235
                info2->portname = talloc_strdup(ctx, qlines[0]);
 
6236
                DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
 
6237
        }
 
6238
 
 
6239
        TALLOC_FREE(qlines);
 
6240
        return true;
 
6241
}
 
6242
 
 
6243
static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
 
6244
                               const struct auth_serversupplied_info *session_info,
 
6245
                               struct messaging_context *msg_ctx,
 
6246
                               int snum,
 
6247
                               struct spoolss_SetPrinterInfo2 *printer,
 
6248
                               struct spoolss_PrinterInfo2 *old_printer)
 
6249
{
 
6250
        bool force_update = (old_printer == NULL);
 
6251
        const char *dnsdomname;
 
6252
        const char *longname;
 
6253
        const char *uncname;
 
6254
        const char *spooling;
 
6255
        DATA_BLOB buffer;
 
6256
        WERROR result = WERR_OK;
 
6257
        struct dcerpc_binding_handle *b;
 
6258
 
 
6259
        result = winreg_printer_binding_handle(mem_ctx,
 
6260
                                               session_info,
 
6261
                                               msg_ctx,
 
6262
                                               &b);
 
6263
        if (!W_ERROR_IS_OK(result)) {
 
6264
                return result;
 
6265
        }
 
6266
 
 
6267
        if (force_update || !strequal(printer->drivername, old_printer->drivername)) {
 
6268
                push_reg_sz(mem_ctx, &buffer, printer->drivername);
 
6269
                winreg_set_printer_dataex(mem_ctx, b,
 
6270
                                          printer->sharename,
 
6271
                                          SPOOL_DSSPOOLER_KEY,
 
6272
                                          SPOOL_REG_DRIVERNAME,
 
6273
                                          REG_SZ,
 
6274
                                          buffer.data,
 
6275
                                          buffer.length);
 
6276
 
 
6277
                if (!force_update) {
 
6278
                        DEBUG(10,("update_printer: changing driver [%s]!  Sending event!\n",
 
6279
                                printer->drivername));
 
6280
 
 
6281
                        notify_printer_driver(server_event_context(), msg_ctx,
 
6282
                                              snum, printer->drivername ?
 
6283
                                              printer->drivername : "");
 
6284
                }
 
6285
        }
 
6286
 
 
6287
        if (force_update || !strequal(printer->comment, old_printer->comment)) {
 
6288
                push_reg_sz(mem_ctx, &buffer, printer->comment);
 
6289
                winreg_set_printer_dataex(mem_ctx, b,
 
6290
                                          printer->sharename,
 
6291
                                          SPOOL_DSSPOOLER_KEY,
 
6292
                                          SPOOL_REG_DESCRIPTION,
 
6293
                                          REG_SZ,
 
6294
                                          buffer.data,
 
6295
                                          buffer.length);
 
6296
 
 
6297
                if (!force_update) {
 
6298
                        notify_printer_comment(server_event_context(), msg_ctx,
 
6299
                                               snum, printer->comment ?
 
6300
                                               printer->comment : "");
 
6301
                }
 
6302
        }
 
6303
 
 
6304
        if (force_update || !strequal(printer->sharename, old_printer->sharename)) {
 
6305
                push_reg_sz(mem_ctx, &buffer, printer->sharename);
 
6306
                winreg_set_printer_dataex(mem_ctx, b,
 
6307
                                          printer->sharename,
 
6308
                                          SPOOL_DSSPOOLER_KEY,
 
6309
                                          SPOOL_REG_PRINTSHARENAME,
 
6310
                                          REG_SZ,
 
6311
                                          buffer.data,
 
6312
                                          buffer.length);
 
6313
 
 
6314
                if (!force_update) {
 
6315
                        notify_printer_sharename(server_event_context(),
 
6316
                                                 msg_ctx,
 
6317
                                                 snum, printer->sharename ?
 
6318
                                                 printer->sharename : "");
 
6319
                }
 
6320
        }
 
6321
 
 
6322
        if (force_update || !strequal(printer->printername, old_printer->printername)) {
 
6323
                const char *p;
 
6324
 
 
6325
                p = strrchr(printer->printername, '\\' );
 
6326
                if (p != NULL) {
 
6327
                        p++;
 
6328
                } else {
 
6329
                        p = printer->printername;
 
6330
                }
 
6331
 
 
6332
                push_reg_sz(mem_ctx, &buffer, p);
 
6333
                winreg_set_printer_dataex(mem_ctx, b,
 
6334
                                          printer->sharename,
 
6335
                                          SPOOL_DSSPOOLER_KEY,
 
6336
                                          SPOOL_REG_PRINTERNAME,
 
6337
                                          REG_SZ,
 
6338
                                          buffer.data,
 
6339
                                          buffer.length);
 
6340
 
 
6341
                if (!force_update) {
 
6342
                        notify_printer_printername(server_event_context(),
 
6343
                                                   msg_ctx, snum, p ? p : "");
 
6344
                }
 
6345
        }
 
6346
 
 
6347
        if (force_update || !strequal(printer->portname, old_printer->portname)) {
 
6348
                push_reg_sz(mem_ctx, &buffer, printer->portname);
 
6349
                winreg_set_printer_dataex(mem_ctx, b,
 
6350
                                          printer->sharename,
 
6351
                                          SPOOL_DSSPOOLER_KEY,
 
6352
                                          SPOOL_REG_PORTNAME,
 
6353
                                          REG_SZ,
 
6354
                                          buffer.data,
 
6355
                                          buffer.length);
 
6356
 
 
6357
                if (!force_update) {
 
6358
                        notify_printer_port(server_event_context(),
 
6359
                                            msg_ctx, snum, printer->portname ?
 
6360
                                            printer->portname : "");
 
6361
                }
 
6362
        }
 
6363
 
 
6364
        if (force_update || !strequal(printer->location, old_printer->location)) {
 
6365
                push_reg_sz(mem_ctx, &buffer, printer->location);
 
6366
                winreg_set_printer_dataex(mem_ctx, b,
 
6367
                                          printer->sharename,
 
6368
                                          SPOOL_DSSPOOLER_KEY,
 
6369
                                          SPOOL_REG_LOCATION,
 
6370
                                          REG_SZ,
 
6371
                                          buffer.data,
 
6372
                                          buffer.length);
 
6373
 
 
6374
                if (!force_update) {
 
6375
                        notify_printer_location(server_event_context(),
 
6376
                                                msg_ctx, snum,
 
6377
                                                printer->location ?
 
6378
                                                printer->location : "");
 
6379
                }
 
6380
        }
 
6381
 
 
6382
        if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) {
 
6383
                push_reg_sz(mem_ctx, &buffer, printer->sepfile);
 
6384
                winreg_set_printer_dataex(mem_ctx, b,
 
6385
                                          printer->sharename,
 
6386
                                          SPOOL_DSSPOOLER_KEY,
 
6387
                                          SPOOL_REG_PRINTSEPARATORFILE,
 
6388
                                          REG_SZ,
 
6389
                                          buffer.data,
 
6390
                                          buffer.length);
 
6391
 
 
6392
                if (!force_update) {
 
6393
                        notify_printer_sepfile(server_event_context(),
 
6394
                                               msg_ctx, snum,
 
6395
                                               printer->sepfile ?
 
6396
                                               printer->sepfile : "");
 
6397
                }
 
6398
        }
 
6399
 
 
6400
        if (force_update || printer->starttime != old_printer->starttime) {
 
6401
                buffer = data_blob_talloc(mem_ctx, NULL, 4);
 
6402
                SIVAL(buffer.data, 0, printer->starttime);
 
6403
                winreg_set_printer_dataex(mem_ctx, b,
 
6404
                                          printer->sharename,
 
6405
                                          SPOOL_DSSPOOLER_KEY,
 
6406
                                          SPOOL_REG_PRINTSTARTTIME,
 
6407
                                          REG_DWORD,
 
6408
                                          buffer.data,
 
6409
                                          buffer.length);
 
6410
        }
 
6411
 
 
6412
        if (force_update || printer->untiltime != old_printer->untiltime) {
 
6413
                buffer = data_blob_talloc(mem_ctx, NULL, 4);
 
6414
                SIVAL(buffer.data, 0, printer->untiltime);
 
6415
                winreg_set_printer_dataex(mem_ctx, b,
 
6416
                                          printer->sharename,
 
6417
                                          SPOOL_DSSPOOLER_KEY,
 
6418
                                          SPOOL_REG_PRINTENDTIME,
 
6419
                                          REG_DWORD,
 
6420
                                          buffer.data,
 
6421
                                          buffer.length);
 
6422
        }
 
6423
 
 
6424
        if (force_update || printer->priority != old_printer->priority) {
 
6425
                buffer = data_blob_talloc(mem_ctx, NULL, 4);
 
6426
                SIVAL(buffer.data, 0, printer->priority);
 
6427
                winreg_set_printer_dataex(mem_ctx, b,
 
6428
                                          printer->sharename,
 
6429
                                          SPOOL_DSSPOOLER_KEY,
 
6430
                                          SPOOL_REG_PRIORITY,
 
6431
                                          REG_DWORD,
 
6432
                                          buffer.data,
 
6433
                                          buffer.length);
 
6434
        }
 
6435
 
 
6436
        if (force_update || printer->attributes != old_printer->attributes) {
 
6437
                buffer = data_blob_talloc(mem_ctx, NULL, 4);
 
6438
                SIVAL(buffer.data, 0, (printer->attributes &
 
6439
                                       PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
 
6440
                winreg_set_printer_dataex(mem_ctx, b,
 
6441
                                          printer->sharename,
 
6442
                                          SPOOL_DSSPOOLER_KEY,
 
6443
                                          SPOOL_REG_PRINTKEEPPRINTEDJOBS,
 
6444
                                          REG_DWORD,
 
6445
                                          buffer.data,
 
6446
                                          buffer.length);
 
6447
 
 
6448
                switch (printer->attributes & 0x3) {
 
6449
                        case 0:
 
6450
                                spooling = SPOOL_REGVAL_PRINTWHILESPOOLING;
 
6451
                                break;
 
6452
                        case 1:
 
6453
                                spooling = SPOOL_REGVAL_PRINTAFTERSPOOLED;
 
6454
                                break;
 
6455
                        case 2:
 
6456
                                spooling = SPOOL_REGVAL_PRINTDIRECT;
 
6457
                                break;
 
6458
                        default:
 
6459
                                spooling = "unknown";
 
6460
                }
 
6461
                push_reg_sz(mem_ctx, &buffer, spooling);
 
6462
                winreg_set_printer_dataex(mem_ctx, b,
 
6463
                                          printer->sharename,
 
6464
                                          SPOOL_DSSPOOLER_KEY,
 
6465
                                          SPOOL_REG_PRINTSPOOLING,
 
6466
                                          REG_SZ,
 
6467
                                          buffer.data,
 
6468
                                          buffer.length);
 
6469
        }
 
6470
 
 
6471
        push_reg_sz(mem_ctx, &buffer, global_myname());
 
6472
        winreg_set_printer_dataex(mem_ctx, b,
 
6473
                                  printer->sharename,
 
6474
                                  SPOOL_DSSPOOLER_KEY,
 
6475
                                  SPOOL_REG_SHORTSERVERNAME,
 
6476
                                  REG_SZ,
 
6477
                                  buffer.data,
 
6478
                                  buffer.length);
 
6479
 
 
6480
        dnsdomname = get_mydnsfullname();
 
6481
        if (dnsdomname != NULL && dnsdomname[0] != '\0') {
 
6482
                longname = talloc_strdup(mem_ctx, dnsdomname);
 
6483
        } else {
 
6484
                longname = talloc_strdup(mem_ctx, global_myname());
 
6485
        }
 
6486
        if (longname == NULL) {
 
6487
                result = WERR_NOMEM;
 
6488
                goto done;
 
6489
        }
 
6490
 
 
6491
        push_reg_sz(mem_ctx, &buffer, longname);
 
6492
        winreg_set_printer_dataex(mem_ctx, b,
 
6493
                                  printer->sharename,
 
6494
                                  SPOOL_DSSPOOLER_KEY,
 
6495
                                  SPOOL_REG_SERVERNAME,
 
6496
                                  REG_SZ,
 
6497
                                  buffer.data,
 
6498
                                  buffer.length);
 
6499
 
 
6500
        uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
 
6501
                                  global_myname(), printer->sharename);
 
6502
        push_reg_sz(mem_ctx, &buffer, uncname);
 
6503
        winreg_set_printer_dataex(mem_ctx, b,
 
6504
                                  printer->sharename,
 
6505
                                  SPOOL_DSSPOOLER_KEY,
 
6506
                                  SPOOL_REG_UNCNAME,
 
6507
                                  REG_SZ,
 
6508
                                  buffer.data,
 
6509
                                  buffer.length);
 
6510
 
 
6511
done:
 
6512
        return result;
 
6513
}
 
6514
 
 
6515
/********************************************************************
 
6516
 * Called by spoolss_api_setprinter
 
6517
 * when updating a printer description.
 
6518
 ********************************************************************/
 
6519
 
 
6520
static WERROR update_printer(struct pipes_struct *p,
 
6521
                             struct policy_handle *handle,
 
6522
                             struct spoolss_SetPrinterInfoCtr *info_ctr,
 
6523
                             struct spoolss_DeviceMode *devmode)
 
6524
{
 
6525
        uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
 
6526
        struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
 
6527
        struct spoolss_PrinterInfo2 *old_printer;
 
6528
        struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
 
6529
        int snum;
 
6530
        WERROR result = WERR_OK;
 
6531
        TALLOC_CTX *tmp_ctx;
 
6532
        struct dcerpc_binding_handle *b;
 
6533
 
 
6534
        DEBUG(8,("update_printer\n"));
 
6535
 
 
6536
        tmp_ctx = talloc_new(p->mem_ctx);
 
6537
        if (tmp_ctx == NULL) {
 
6538
                return WERR_NOMEM;
 
6539
        }
 
6540
 
 
6541
        if (!Printer) {
 
6542
                result = WERR_BADFID;
 
6543
                goto done;
 
6544
        }
 
6545
 
 
6546
        if (!get_printer_snum(p, handle, &snum, NULL)) {
 
6547
                result = WERR_BADFID;
 
6548
                goto done;
 
6549
        }
 
6550
 
 
6551
        result = winreg_printer_binding_handle(tmp_ctx,
 
6552
                                               get_session_info_system(),
 
6553
                                               p->msg_ctx,
 
6554
                                               &b);
 
6555
        if (!W_ERROR_IS_OK(result)) {
 
6556
                goto done;
 
6557
        }
 
6558
 
 
6559
        result = winreg_get_printer(tmp_ctx, b,
 
6560
                                    lp_const_servicename(snum),
 
6561
                                    &old_printer);
 
6562
        if (!W_ERROR_IS_OK(result)) {
 
6563
                result = WERR_BADFID;
 
6564
                goto done;
 
6565
        }
 
6566
 
 
6567
        /* Do sanity check on the requested changes for Samba */
 
6568
        if (!check_printer_ok(tmp_ctx, printer, snum)) {
 
6569
                result = WERR_INVALID_PARAM;
 
6570
                goto done;
 
6571
        }
 
6572
 
 
6573
        /* FIXME!!! If the driver has changed we really should verify that
 
6574
           it is installed before doing much else   --jerry */
 
6575
 
 
6576
        /* Check calling user has permission to update printer description */
 
6577
        if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
 
6578
                DEBUG(3, ("update_printer: printer property change denied by handle\n"));
 
6579
                result = WERR_ACCESS_DENIED;
 
6580
                goto done;
 
6581
        }
 
6582
 
 
6583
        /* Call addprinter hook */
 
6584
        /* Check changes to see if this is really needed */
 
6585
 
 
6586
        if (*lp_addprinter_cmd() &&
 
6587
                        (!strequal(printer->drivername, old_printer->drivername) ||
 
6588
                         !strequal(printer->comment, old_printer->comment) ||
 
6589
                         !strequal(printer->portname, old_printer->portname) ||
 
6590
                         !strequal(printer->location, old_printer->location)) )
 
6591
        {
 
6592
                /* add_printer_hook() will call reload_services() */
 
6593
                if (!add_printer_hook(tmp_ctx, p->session_info->security_token,
 
6594
                                      printer, p->client_id->addr,
 
6595
                                      p->msg_ctx)) {
 
6596
                        result = WERR_ACCESS_DENIED;
 
6597
                        goto done;
 
6598
                }
 
6599
        }
 
6600
 
 
6601
        update_dsspooler(tmp_ctx,
 
6602
                         get_session_info_system(),
 
6603
                         p->msg_ctx,
 
6604
                         snum,
 
6605
                         printer,
 
6606
                         old_printer);
 
6607
 
 
6608
        printer_mask &= ~SPOOLSS_PRINTER_INFO_SECDESC;
 
6609
 
 
6610
        if (devmode == NULL) {
 
6611
                printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
 
6612
        }
 
6613
        result = winreg_update_printer(tmp_ctx, b,
 
6614
                                       printer->sharename,
 
6615
                                       printer_mask,
 
6616
                                       printer,
 
6617
                                       devmode,
 
6618
                                       NULL);
 
6619
 
 
6620
done:
 
6621
        talloc_free(tmp_ctx);
 
6622
 
 
6623
        return result;
 
6624
}
 
6625
 
 
6626
/****************************************************************************
 
6627
****************************************************************************/
 
6628
static WERROR publish_or_unpublish_printer(struct pipes_struct *p,
 
6629
                                           struct policy_handle *handle,
 
6630
                                           struct spoolss_SetPrinterInfo7 *info7)
 
6631
{
 
6632
#ifdef HAVE_ADS
 
6633
        struct spoolss_PrinterInfo2 *pinfo2 = NULL;
 
6634
        WERROR result;
 
6635
        int snum;
 
6636
        struct printer_handle *Printer;
 
6637
 
 
6638
        if ( lp_security() != SEC_ADS ) {
 
6639
                return WERR_UNKNOWN_LEVEL;
 
6640
        }
 
6641
 
 
6642
        Printer = find_printer_index_by_hnd(p, handle);
 
6643
 
 
6644
        DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
 
6645
 
 
6646
        if (!Printer)
 
6647
                return WERR_BADFID;
 
6648
 
 
6649
        if (!get_printer_snum(p, handle, &snum, NULL))
 
6650
                return WERR_BADFID;
 
6651
 
 
6652
        result = winreg_get_printer_internal(p->mem_ctx,
 
6653
                                    get_session_info_system(),
 
6654
                                    p->msg_ctx,
 
6655
                                    lp_servicename(snum),
 
6656
                                    &pinfo2);
 
6657
        if (!W_ERROR_IS_OK(result)) {
 
6658
                return WERR_BADFID;
 
6659
        }
 
6660
 
 
6661
        nt_printer_publish(pinfo2,
 
6662
                           get_session_info_system(),
 
6663
                           p->msg_ctx,
 
6664
                           pinfo2,
 
6665
                           info7->action);
 
6666
 
 
6667
        TALLOC_FREE(pinfo2);
 
6668
        return WERR_OK;
 
6669
#else
 
6670
        return WERR_UNKNOWN_LEVEL;
 
6671
#endif
 
6672
}
 
6673
 
 
6674
/********************************************************************
 
6675
 ********************************************************************/
 
6676
 
 
6677
static WERROR update_printer_devmode(struct pipes_struct *p,
 
6678
                                     struct policy_handle *handle,
 
6679
                                     struct spoolss_DeviceMode *devmode)
 
6680
{
 
6681
        int snum;
 
6682
        struct printer_handle *Printer = find_printer_index_by_hnd(p, handle);
 
6683
        uint32_t info2_mask = SPOOLSS_PRINTER_INFO_DEVMODE;
 
6684
 
 
6685
        DEBUG(8,("update_printer_devmode\n"));
 
6686
 
 
6687
        if (!Printer) {
 
6688
                return WERR_BADFID;
 
6689
        }
 
6690
 
 
6691
        if (!get_printer_snum(p, handle, &snum, NULL)) {
 
6692
                return WERR_BADFID;
 
6693
        }
 
6694
 
 
6695
        /* Check calling user has permission to update printer description */
 
6696
        if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
 
6697
                DEBUG(3, ("update_printer: printer property change denied by handle\n"));
 
6698
                return WERR_ACCESS_DENIED;
 
6699
        }
 
6700
 
 
6701
        return winreg_update_printer_internal(p->mem_ctx,
 
6702
                                     get_session_info_system(),
 
6703
                                     p->msg_ctx,
 
6704
                                     lp_const_servicename(snum),
 
6705
                                     info2_mask,
 
6706
                                     NULL,
 
6707
                                     devmode,
 
6708
                                     NULL);
 
6709
}
 
6710
 
 
6711
 
 
6712
/****************************************************************
 
6713
 _spoolss_SetPrinter
 
6714
****************************************************************/
 
6715
 
 
6716
WERROR _spoolss_SetPrinter(struct pipes_struct *p,
 
6717
                           struct spoolss_SetPrinter *r)
 
6718
{
 
6719
        WERROR result;
 
6720
 
 
6721
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
6722
 
 
6723
        if (!Printer) {
 
6724
                DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
 
6725
                        OUR_HANDLE(r->in.handle)));
 
6726
                return WERR_BADFID;
 
6727
        }
 
6728
 
 
6729
        /* check the level */
 
6730
        switch (r->in.info_ctr->level) {
 
6731
                case 0:
 
6732
                        return control_printer(r->in.handle, r->in.command, p);
 
6733
                case 2:
 
6734
                        result = update_printer(p, r->in.handle,
 
6735
                                                r->in.info_ctr,
 
6736
                                                r->in.devmode_ctr->devmode);
 
6737
                        if (!W_ERROR_IS_OK(result))
 
6738
                                return result;
 
6739
                        if (r->in.secdesc_ctr->sd)
 
6740
                                result = update_printer_sec(r->in.handle, p,
 
6741
                                                            r->in.secdesc_ctr);
 
6742
                        return result;
 
6743
                case 3:
 
6744
                        return update_printer_sec(r->in.handle, p,
 
6745
                                                  r->in.secdesc_ctr);
 
6746
                case 7:
 
6747
                        return publish_or_unpublish_printer(p, r->in.handle,
 
6748
                                                            r->in.info_ctr->info.info7);
 
6749
                case 8:
 
6750
                        return update_printer_devmode(p, r->in.handle,
 
6751
                                                      r->in.devmode_ctr->devmode);
 
6752
                default:
 
6753
                        return WERR_UNKNOWN_LEVEL;
 
6754
        }
 
6755
}
 
6756
 
 
6757
/****************************************************************
 
6758
 _spoolss_FindClosePrinterNotify
 
6759
****************************************************************/
 
6760
 
 
6761
WERROR _spoolss_FindClosePrinterNotify(struct pipes_struct *p,
 
6762
                                       struct spoolss_FindClosePrinterNotify *r)
 
6763
{
 
6764
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
6765
 
 
6766
        if (!Printer) {
 
6767
                DEBUG(2,("_spoolss_FindClosePrinterNotify: "
 
6768
                        "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
 
6769
                return WERR_BADFID;
 
6770
        }
 
6771
 
 
6772
        if (Printer->notify.cli_chan != NULL &&
 
6773
            Printer->notify.cli_chan->active_connections > 0) {
 
6774
                int snum = -1;
 
6775
 
 
6776
                if (Printer->printer_type == SPLHND_PRINTER) {
 
6777
                        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
 
6778
                                return WERR_BADFID;
 
6779
                        }
 
6780
                }
 
6781
 
 
6782
                srv_spoolss_replycloseprinter(snum, Printer);
 
6783
        }
 
6784
 
 
6785
        Printer->notify.flags=0;
 
6786
        Printer->notify.options=0;
 
6787
        Printer->notify.localmachine[0]='\0';
 
6788
        Printer->notify.printerlocal=0;
 
6789
        TALLOC_FREE(Printer->notify.option);
 
6790
 
 
6791
        return WERR_OK;
 
6792
}
 
6793
 
 
6794
/****************************************************************
 
6795
 _spoolss_AddJob
 
6796
****************************************************************/
 
6797
 
 
6798
WERROR _spoolss_AddJob(struct pipes_struct *p,
 
6799
                       struct spoolss_AddJob *r)
 
6800
{
 
6801
        if (!r->in.buffer && (r->in.offered != 0)) {
 
6802
                return WERR_INVALID_PARAM;
 
6803
        }
 
6804
 
 
6805
        /* this is what a NT server returns for AddJob. AddJob must fail on
 
6806
         * non-local printers */
 
6807
 
 
6808
        if (r->in.level != 1) {
 
6809
                return WERR_UNKNOWN_LEVEL;
 
6810
        }
 
6811
 
 
6812
        return WERR_INVALID_PARAM;
 
6813
}
 
6814
 
 
6815
/****************************************************************************
 
6816
fill_job_info1
 
6817
****************************************************************************/
 
6818
 
 
6819
static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
 
6820
                             struct spoolss_JobInfo1 *r,
 
6821
                             const print_queue_struct *queue,
 
6822
                             int position, int snum,
 
6823
                             struct spoolss_PrinterInfo2 *pinfo2)
 
6824
{
 
6825
        struct tm *t;
 
6826
 
 
6827
        t = gmtime(&queue->time);
 
6828
 
 
6829
        r->job_id               = queue->job;
 
6830
 
 
6831
        r->printer_name         = talloc_strdup(mem_ctx, lp_servicename(snum));
 
6832
        W_ERROR_HAVE_NO_MEMORY(r->printer_name);
 
6833
        r->server_name          = talloc_strdup(mem_ctx, pinfo2->servername);
 
6834
        W_ERROR_HAVE_NO_MEMORY(r->server_name);
 
6835
        r->user_name            = talloc_strdup(mem_ctx, queue->fs_user);
 
6836
        W_ERROR_HAVE_NO_MEMORY(r->user_name);
 
6837
        r->document_name        = talloc_strdup(mem_ctx, queue->fs_file);
 
6838
        W_ERROR_HAVE_NO_MEMORY(r->document_name);
 
6839
        r->data_type            = talloc_strdup(mem_ctx, "RAW");
 
6840
        W_ERROR_HAVE_NO_MEMORY(r->data_type);
 
6841
        r->text_status          = talloc_strdup(mem_ctx, "");
 
6842
        W_ERROR_HAVE_NO_MEMORY(r->text_status);
 
6843
 
 
6844
        r->status               = nt_printj_status(queue->status);
 
6845
        r->priority             = queue->priority;
 
6846
        r->position             = position;
 
6847
        r->total_pages          = queue->page_count;
 
6848
        r->pages_printed        = 0; /* ??? */
 
6849
 
 
6850
        init_systemtime(&r->submitted, t);
 
6851
 
 
6852
        return WERR_OK;
 
6853
}
 
6854
 
 
6855
/****************************************************************************
 
6856
fill_job_info2
 
6857
****************************************************************************/
 
6858
 
 
6859
static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
 
6860
                             struct spoolss_JobInfo2 *r,
 
6861
                             const print_queue_struct *queue,
 
6862
                             int position, int snum,
 
6863
                             struct spoolss_PrinterInfo2 *pinfo2,
 
6864
                             struct spoolss_DeviceMode *devmode)
 
6865
{
 
6866
        struct tm *t;
 
6867
 
 
6868
        t = gmtime(&queue->time);
 
6869
 
 
6870
        r->job_id               = queue->job;
 
6871
 
 
6872
        r->printer_name         = talloc_strdup(mem_ctx, lp_servicename(snum));
 
6873
        W_ERROR_HAVE_NO_MEMORY(r->printer_name);
 
6874
        r->server_name          = talloc_strdup(mem_ctx, pinfo2->servername);
 
6875
        W_ERROR_HAVE_NO_MEMORY(r->server_name);
 
6876
        r->user_name            = talloc_strdup(mem_ctx, queue->fs_user);
 
6877
        W_ERROR_HAVE_NO_MEMORY(r->user_name);
 
6878
        r->document_name        = talloc_strdup(mem_ctx, queue->fs_file);
 
6879
        W_ERROR_HAVE_NO_MEMORY(r->document_name);
 
6880
        r->notify_name          = talloc_strdup(mem_ctx, queue->fs_user);
 
6881
        W_ERROR_HAVE_NO_MEMORY(r->notify_name);
 
6882
        r->data_type            = talloc_strdup(mem_ctx, "RAW");
 
6883
        W_ERROR_HAVE_NO_MEMORY(r->data_type);
 
6884
        r->print_processor      = talloc_strdup(mem_ctx, "winprint");
 
6885
        W_ERROR_HAVE_NO_MEMORY(r->print_processor);
 
6886
        r->parameters           = talloc_strdup(mem_ctx, "");
 
6887
        W_ERROR_HAVE_NO_MEMORY(r->parameters);
 
6888
        r->driver_name          = talloc_strdup(mem_ctx, pinfo2->drivername);
 
6889
        W_ERROR_HAVE_NO_MEMORY(r->driver_name);
 
6890
 
 
6891
        r->devmode              = devmode;
 
6892
 
 
6893
        r->text_status          = talloc_strdup(mem_ctx, "");
 
6894
        W_ERROR_HAVE_NO_MEMORY(r->text_status);
 
6895
 
 
6896
        r->secdesc              = NULL;
 
6897
 
 
6898
        r->status               = nt_printj_status(queue->status);
 
6899
        r->priority             = queue->priority;
 
6900
        r->position             = position;
 
6901
        r->start_time           = 0;
 
6902
        r->until_time           = 0;
 
6903
        r->total_pages          = queue->page_count;
 
6904
        r->size                 = queue->size;
 
6905
        init_systemtime(&r->submitted, t);
 
6906
        r->time                 = 0;
 
6907
        r->pages_printed        = 0; /* ??? */
 
6908
 
 
6909
        return WERR_OK;
 
6910
}
 
6911
 
 
6912
/****************************************************************************
 
6913
fill_job_info3
 
6914
****************************************************************************/
 
6915
 
 
6916
static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
 
6917
                             struct spoolss_JobInfo3 *r,
 
6918
                             const print_queue_struct *queue,
 
6919
                             const print_queue_struct *next_queue,
 
6920
                             int position, int snum,
 
6921
                             struct spoolss_PrinterInfo2 *pinfo2)
 
6922
{
 
6923
        r->job_id               = queue->job;
 
6924
        r->next_job_id          = 0;
 
6925
        if (next_queue) {
 
6926
                r->next_job_id  = next_queue->job;
 
6927
        }
 
6928
        r->reserved             = 0;
 
6929
 
 
6930
        return WERR_OK;
 
6931
}
 
6932
 
 
6933
/****************************************************************************
 
6934
 Enumjobs at level 1.
 
6935
****************************************************************************/
 
6936
 
 
6937
static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
 
6938
                              const print_queue_struct *queue,
 
6939
                              uint32_t num_queues, int snum,
 
6940
                              struct spoolss_PrinterInfo2 *pinfo2,
 
6941
                              union spoolss_JobInfo **info_p,
 
6942
                              uint32_t *count)
 
6943
{
 
6944
        union spoolss_JobInfo *info;
 
6945
        int i;
 
6946
        WERROR result = WERR_OK;
 
6947
 
 
6948
        info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
 
6949
        W_ERROR_HAVE_NO_MEMORY(info);
 
6950
 
 
6951
        *count = num_queues;
 
6952
 
 
6953
        for (i=0; i<*count; i++) {
 
6954
                result = fill_job_info1(info,
 
6955
                                        &info[i].info1,
 
6956
                                        &queue[i],
 
6957
                                        i,
 
6958
                                        snum,
 
6959
                                        pinfo2);
 
6960
                if (!W_ERROR_IS_OK(result)) {
 
6961
                        goto out;
 
6962
                }
 
6963
        }
 
6964
 
 
6965
 out:
 
6966
        if (!W_ERROR_IS_OK(result)) {
 
6967
                TALLOC_FREE(info);
 
6968
                *count = 0;
 
6969
                return result;
 
6970
        }
 
6971
 
 
6972
        *info_p = info;
 
6973
 
 
6974
        return WERR_OK;
 
6975
}
 
6976
 
 
6977
/****************************************************************************
 
6978
 Enumjobs at level 2.
 
6979
****************************************************************************/
 
6980
 
 
6981
static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
 
6982
                              const print_queue_struct *queue,
 
6983
                              uint32_t num_queues, int snum,
 
6984
                              struct spoolss_PrinterInfo2 *pinfo2,
 
6985
                              union spoolss_JobInfo **info_p,
 
6986
                              uint32_t *count)
 
6987
{
 
6988
        union spoolss_JobInfo *info;
 
6989
        int i;
 
6990
        WERROR result = WERR_OK;
 
6991
 
 
6992
        info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
 
6993
        W_ERROR_HAVE_NO_MEMORY(info);
 
6994
 
 
6995
        *count = num_queues;
 
6996
 
 
6997
        for (i=0; i<*count; i++) {
 
6998
                struct spoolss_DeviceMode *devmode;
 
6999
 
 
7000
                result = spoolss_create_default_devmode(info,
 
7001
                                                        pinfo2->printername,
 
7002
                                                        &devmode);
 
7003
                if (!W_ERROR_IS_OK(result)) {
 
7004
                        DEBUG(3, ("Can't proceed w/o a devmode!"));
 
7005
                        goto out;
 
7006
                }
 
7007
 
 
7008
                result = fill_job_info2(info,
 
7009
                                        &info[i].info2,
 
7010
                                        &queue[i],
 
7011
                                        i,
 
7012
                                        snum,
 
7013
                                        pinfo2,
 
7014
                                        devmode);
 
7015
                if (!W_ERROR_IS_OK(result)) {
 
7016
                        goto out;
 
7017
                }
 
7018
        }
 
7019
 
 
7020
 out:
 
7021
        if (!W_ERROR_IS_OK(result)) {
 
7022
                TALLOC_FREE(info);
 
7023
                *count = 0;
 
7024
                return result;
 
7025
        }
 
7026
 
 
7027
        *info_p = info;
 
7028
 
 
7029
        return WERR_OK;
 
7030
}
 
7031
 
 
7032
/****************************************************************************
 
7033
 Enumjobs at level 3.
 
7034
****************************************************************************/
 
7035
 
 
7036
static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
 
7037
                              const print_queue_struct *queue,
 
7038
                              uint32_t num_queues, int snum,
 
7039
                              struct spoolss_PrinterInfo2 *pinfo2,
 
7040
                              union spoolss_JobInfo **info_p,
 
7041
                              uint32_t *count)
 
7042
{
 
7043
        union spoolss_JobInfo *info;
 
7044
        int i;
 
7045
        WERROR result = WERR_OK;
 
7046
 
 
7047
        info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
 
7048
        W_ERROR_HAVE_NO_MEMORY(info);
 
7049
 
 
7050
        *count = num_queues;
 
7051
 
 
7052
        for (i=0; i<*count; i++) {
 
7053
                const print_queue_struct *next_queue = NULL;
 
7054
 
 
7055
                if (i+1 < *count) {
 
7056
                        next_queue = &queue[i+1];
 
7057
                }
 
7058
 
 
7059
                result = fill_job_info3(info,
 
7060
                                        &info[i].info3,
 
7061
                                        &queue[i],
 
7062
                                        next_queue,
 
7063
                                        i,
 
7064
                                        snum,
 
7065
                                        pinfo2);
 
7066
                if (!W_ERROR_IS_OK(result)) {
 
7067
                        goto out;
 
7068
                }
 
7069
        }
 
7070
 
 
7071
 out:
 
7072
        if (!W_ERROR_IS_OK(result)) {
 
7073
                TALLOC_FREE(info);
 
7074
                *count = 0;
 
7075
                return result;
 
7076
        }
 
7077
 
 
7078
        *info_p = info;
 
7079
 
 
7080
        return WERR_OK;
 
7081
}
 
7082
 
 
7083
/****************************************************************
 
7084
 _spoolss_EnumJobs
 
7085
****************************************************************/
 
7086
 
 
7087
WERROR _spoolss_EnumJobs(struct pipes_struct *p,
 
7088
                         struct spoolss_EnumJobs *r)
 
7089
{
 
7090
        WERROR result;
 
7091
        struct spoolss_PrinterInfo2 *pinfo2 = NULL;
 
7092
        int snum;
 
7093
        print_status_struct prt_status;
 
7094
        print_queue_struct *queue = NULL;
 
7095
        uint32_t count;
 
7096
 
 
7097
        /* that's an [in out] buffer */
 
7098
 
 
7099
        if (!r->in.buffer && (r->in.offered != 0)) {
 
7100
                return WERR_INVALID_PARAM;
 
7101
        }
 
7102
 
 
7103
        DEBUG(4,("_spoolss_EnumJobs\n"));
 
7104
 
 
7105
        *r->out.needed = 0;
 
7106
        *r->out.count = 0;
 
7107
        *r->out.info = NULL;
 
7108
 
 
7109
        /* lookup the printer snum and tdb entry */
 
7110
 
 
7111
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
 
7112
                return WERR_BADFID;
 
7113
        }
 
7114
 
 
7115
        result = winreg_get_printer_internal(p->mem_ctx,
 
7116
                                    get_session_info_system(),
 
7117
                                    p->msg_ctx,
 
7118
                                    lp_const_servicename(snum),
 
7119
                                    &pinfo2);
 
7120
        if (!W_ERROR_IS_OK(result)) {
 
7121
                return result;
 
7122
        }
 
7123
 
 
7124
        count = print_queue_status(p->msg_ctx, snum, &queue, &prt_status);
 
7125
        DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
 
7126
                count, prt_status.status, prt_status.message));
 
7127
 
 
7128
        if (count == 0) {
 
7129
                SAFE_FREE(queue);
 
7130
                TALLOC_FREE(pinfo2);
 
7131
                return WERR_OK;
 
7132
        }
 
7133
 
 
7134
        switch (r->in.level) {
 
7135
        case 1:
 
7136
                result = enumjobs_level1(p->mem_ctx, queue, count, snum,
 
7137
                                         pinfo2, r->out.info, r->out.count);
 
7138
                break;
 
7139
        case 2:
 
7140
                result = enumjobs_level2(p->mem_ctx, queue, count, snum,
 
7141
                                         pinfo2, r->out.info, r->out.count);
 
7142
                break;
 
7143
        case 3:
 
7144
                result = enumjobs_level3(p->mem_ctx, queue, count, snum,
 
7145
                                         pinfo2, r->out.info, r->out.count);
 
7146
                break;
 
7147
        default:
 
7148
                result = WERR_UNKNOWN_LEVEL;
 
7149
                break;
 
7150
        }
 
7151
 
 
7152
        SAFE_FREE(queue);
 
7153
        TALLOC_FREE(pinfo2);
 
7154
 
 
7155
        if (!W_ERROR_IS_OK(result)) {
 
7156
                return result;
 
7157
        }
 
7158
 
 
7159
        *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
 
7160
                                                     spoolss_EnumJobs,
 
7161
                                                     *r->out.info, r->in.level,
 
7162
                                                     *r->out.count);
 
7163
        *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
 
7164
        *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
 
7165
 
 
7166
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 
7167
}
 
7168
 
 
7169
/****************************************************************
 
7170
 _spoolss_ScheduleJob
 
7171
****************************************************************/
 
7172
 
 
7173
WERROR _spoolss_ScheduleJob(struct pipes_struct *p,
 
7174
                            struct spoolss_ScheduleJob *r)
 
7175
{
 
7176
        return WERR_OK;
 
7177
}
 
7178
 
 
7179
/****************************************************************
 
7180
****************************************************************/
 
7181
 
 
7182
static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
 
7183
                               struct messaging_context *msg_ctx,
 
7184
                               const char *printer_name,
 
7185
                               uint32_t job_id,
 
7186
                               struct spoolss_SetJobInfo1 *r)
 
7187
{
 
7188
        char *old_doc_name;
 
7189
 
 
7190
        if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
 
7191
                return WERR_BADFID;
 
7192
        }
 
7193
 
 
7194
        if (strequal(old_doc_name, r->document_name)) {
 
7195
                return WERR_OK;
 
7196
        }
 
7197
 
 
7198
        if (!print_job_set_name(server_event_context(), msg_ctx,
 
7199
                                printer_name, job_id, r->document_name)) {
 
7200
                return WERR_BADFID;
 
7201
        }
 
7202
 
 
7203
        return WERR_OK;
 
7204
}
 
7205
 
 
7206
/****************************************************************
 
7207
 _spoolss_SetJob
 
7208
****************************************************************/
 
7209
 
 
7210
WERROR _spoolss_SetJob(struct pipes_struct *p,
 
7211
                       struct spoolss_SetJob *r)
 
7212
{
 
7213
        const struct auth_serversupplied_info *session_info = p->session_info;
 
7214
        int snum;
 
7215
        WERROR errcode = WERR_BADFUNC;
 
7216
 
 
7217
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
 
7218
                return WERR_BADFID;
 
7219
        }
 
7220
 
 
7221
        if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
 
7222
                return WERR_INVALID_PRINTER_NAME;
 
7223
        }
 
7224
 
 
7225
        switch (r->in.command) {
 
7226
        case SPOOLSS_JOB_CONTROL_CANCEL:
 
7227
        case SPOOLSS_JOB_CONTROL_DELETE:
 
7228
                errcode = print_job_delete(session_info, p->msg_ctx,
 
7229
                                           snum, r->in.job_id);
 
7230
                if (W_ERROR_EQUAL(errcode, WERR_PRINTER_HAS_JOBS_QUEUED)) {
 
7231
                        errcode = WERR_OK;
 
7232
                }
 
7233
                break;
 
7234
        case SPOOLSS_JOB_CONTROL_PAUSE:
 
7235
                if (print_job_pause(session_info, p->msg_ctx,
 
7236
                                    snum, r->in.job_id, &errcode)) {
 
7237
                        errcode = WERR_OK;
 
7238
                }
 
7239
                break;
 
7240
        case SPOOLSS_JOB_CONTROL_RESTART:
 
7241
        case SPOOLSS_JOB_CONTROL_RESUME:
 
7242
                if (print_job_resume(session_info, p->msg_ctx,
 
7243
                                     snum, r->in.job_id, &errcode)) {
 
7244
                        errcode = WERR_OK;
 
7245
                }
 
7246
                break;
 
7247
        case 0:
 
7248
                errcode = WERR_OK;
 
7249
                break;
 
7250
        default:
 
7251
                return WERR_UNKNOWN_LEVEL;
 
7252
        }
 
7253
 
 
7254
        if (!W_ERROR_IS_OK(errcode)) {
 
7255
                return errcode;
 
7256
        }
 
7257
 
 
7258
        if (r->in.ctr == NULL) {
 
7259
                return errcode;
 
7260
        }
 
7261
 
 
7262
        switch (r->in.ctr->level) {
 
7263
        case 1:
 
7264
                errcode = spoolss_setjob_1(p->mem_ctx, p->msg_ctx,
 
7265
                                           lp_const_servicename(snum),
 
7266
                                           r->in.job_id,
 
7267
                                           r->in.ctr->info.info1);
 
7268
                break;
 
7269
        case 2:
 
7270
        case 3:
 
7271
        case 4:
 
7272
        default:
 
7273
                return WERR_UNKNOWN_LEVEL;
 
7274
        }
 
7275
 
 
7276
        return errcode;
 
7277
}
 
7278
 
 
7279
/****************************************************************************
 
7280
 Enumerates all printer drivers by level and architecture.
 
7281
****************************************************************************/
 
7282
 
 
7283
static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
 
7284
                                                       const struct auth_serversupplied_info *session_info,
 
7285
                                                       struct messaging_context *msg_ctx,
 
7286
                                                       const char *servername,
 
7287
                                                       const char *architecture,
 
7288
                                                       uint32_t level,
 
7289
                                                       union spoolss_DriverInfo **info_p,
 
7290
                                                       uint32_t *count_p)
 
7291
{
 
7292
        int i;
 
7293
        uint32_t version;
 
7294
        struct spoolss_DriverInfo8 *driver;
 
7295
        union spoolss_DriverInfo *info = NULL;
 
7296
        uint32_t count = 0;
 
7297
        WERROR result = WERR_OK;
 
7298
        uint32_t num_drivers;
 
7299
        const char **drivers;
 
7300
        struct dcerpc_binding_handle *b;
 
7301
 
 
7302
        *count_p = 0;
 
7303
        *info_p = NULL;
 
7304
 
 
7305
        result = winreg_printer_binding_handle(mem_ctx,
 
7306
                                               session_info,
 
7307
                                               msg_ctx,
 
7308
                                               &b);
 
7309
        if (!W_ERROR_IS_OK(result)) {
 
7310
                goto out;
 
7311
        }
 
7312
 
 
7313
        for (version=0; version<DRIVER_MAX_VERSION; version++) {
 
7314
                result = winreg_get_driver_list(mem_ctx, b,
 
7315
                                                architecture, version,
 
7316
                                                &num_drivers, &drivers);
 
7317
                if (!W_ERROR_IS_OK(result)) {
 
7318
                        goto out;
 
7319
                }
 
7320
                DEBUG(4, ("we have:[%d] drivers in environment"
 
7321
                          " [%s] and version [%d]\n",
 
7322
                          num_drivers, architecture, version));
 
7323
 
 
7324
                if (num_drivers != 0) {
 
7325
                        info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
 
7326
                                                    union spoolss_DriverInfo,
 
7327
                                                    count + num_drivers);
 
7328
                        if (!info) {
 
7329
                                DEBUG(0,("enumprinterdrivers_level_by_architecture: "
 
7330
                                        "failed to enlarge driver info buffer!\n"));
 
7331
                                result = WERR_NOMEM;
 
7332
                                goto out;
 
7333
                        }
 
7334
                }
 
7335
 
 
7336
                for (i = 0; i < num_drivers; i++) {
 
7337
                        DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
 
7338
 
 
7339
                        result = winreg_get_driver(mem_ctx, b,
 
7340
                                                   architecture, drivers[i],
 
7341
                                                   version, &driver);
 
7342
                        if (!W_ERROR_IS_OK(result)) {
 
7343
                                goto out;
 
7344
                        }
 
7345
 
 
7346
                        switch (level) {
 
7347
                        case 1:
 
7348
                                result = fill_printer_driver_info1(info, &info[count+i].info1,
 
7349
                                                                   driver, servername);
 
7350
                                break;
 
7351
                        case 2:
 
7352
                                result = fill_printer_driver_info2(info, &info[count+i].info2,
 
7353
                                                                   driver, servername);
 
7354
                                break;
 
7355
                        case 3:
 
7356
                                result = fill_printer_driver_info3(info, &info[count+i].info3,
 
7357
                                                                   driver, servername);
 
7358
                                break;
 
7359
                        case 4:
 
7360
                                result = fill_printer_driver_info4(info, &info[count+i].info4,
 
7361
                                                                   driver, servername);
 
7362
                                break;
 
7363
                        case 5:
 
7364
                                result = fill_printer_driver_info5(info, &info[count+i].info5,
 
7365
                                                                   driver, servername);
 
7366
                                break;
 
7367
                        case 6:
 
7368
                                result = fill_printer_driver_info6(info, &info[count+i].info6,
 
7369
                                                                   driver, servername);
 
7370
                                break;
 
7371
                        case 8:
 
7372
                                result = fill_printer_driver_info8(info, &info[count+i].info8,
 
7373
                                                                   driver, servername);
 
7374
                                break;
 
7375
                        default:
 
7376
                                result = WERR_UNKNOWN_LEVEL;
 
7377
                                break;
 
7378
                        }
 
7379
 
 
7380
                        TALLOC_FREE(driver);
 
7381
 
 
7382
                        if (!W_ERROR_IS_OK(result)) {
 
7383
                                goto out;
 
7384
                        }
 
7385
                }
 
7386
 
 
7387
                count += num_drivers;
 
7388
                TALLOC_FREE(drivers);
 
7389
        }
 
7390
 
 
7391
 out:
 
7392
        TALLOC_FREE(drivers);
 
7393
 
 
7394
        if (!W_ERROR_IS_OK(result)) {
 
7395
                TALLOC_FREE(info);
 
7396
                return result;
 
7397
        }
 
7398
 
 
7399
        *info_p = info;
 
7400
        *count_p = count;
 
7401
 
 
7402
        return WERR_OK;
 
7403
}
 
7404
 
 
7405
/****************************************************************************
 
7406
 Enumerates all printer drivers by level.
 
7407
****************************************************************************/
 
7408
 
 
7409
static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
 
7410
                                       const struct auth_serversupplied_info *session_info,
 
7411
                                       struct messaging_context *msg_ctx,
 
7412
                                       const char *servername,
 
7413
                                       const char *architecture,
 
7414
                                       uint32_t level,
 
7415
                                       union spoolss_DriverInfo **info_p,
 
7416
                                       uint32_t *count_p)
 
7417
{
 
7418
        uint32_t a,i;
 
7419
        WERROR result = WERR_OK;
 
7420
 
 
7421
        if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
 
7422
 
 
7423
                for (a=0; archi_table[a].long_archi != NULL; a++) {
 
7424
 
 
7425
                        union spoolss_DriverInfo *info = NULL;
 
7426
                        uint32_t count = 0;
 
7427
 
 
7428
                        result = enumprinterdrivers_level_by_architecture(mem_ctx,
 
7429
                                                                          session_info,
 
7430
                                                                          msg_ctx,
 
7431
                                                                          servername,
 
7432
                                                                          archi_table[a].long_archi,
 
7433
                                                                          level,
 
7434
                                                                          &info,
 
7435
                                                                          &count);
 
7436
                        if (!W_ERROR_IS_OK(result)) {
 
7437
                                continue;
 
7438
                        }
 
7439
 
 
7440
                        for (i=0; i < count; i++) {
 
7441
                                ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
 
7442
                                             info[i], info_p, count_p);
 
7443
                        }
 
7444
                }
 
7445
 
 
7446
                return result;
 
7447
        }
 
7448
 
 
7449
        return enumprinterdrivers_level_by_architecture(mem_ctx,
 
7450
                                                        session_info,
 
7451
                                                        msg_ctx,
 
7452
                                                        servername,
 
7453
                                                        architecture,
 
7454
                                                        level,
 
7455
                                                        info_p,
 
7456
                                                        count_p);
 
7457
}
 
7458
 
 
7459
/****************************************************************
 
7460
 _spoolss_EnumPrinterDrivers
 
7461
****************************************************************/
 
7462
 
 
7463
WERROR _spoolss_EnumPrinterDrivers(struct pipes_struct *p,
 
7464
                                   struct spoolss_EnumPrinterDrivers *r)
 
7465
{
 
7466
        const char *cservername;
 
7467
        WERROR result;
 
7468
 
 
7469
        /* that's an [in out] buffer */
 
7470
 
 
7471
        if (!r->in.buffer && (r->in.offered != 0)) {
 
7472
                return WERR_INVALID_PARAM;
 
7473
        }
 
7474
 
 
7475
        DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
 
7476
 
 
7477
        *r->out.needed = 0;
 
7478
        *r->out.count = 0;
 
7479
        *r->out.info = NULL;
 
7480
 
 
7481
        cservername = canon_servername(r->in.server);
 
7482
 
 
7483
        if (!is_myname_or_ipaddr(cservername)) {
 
7484
                return WERR_UNKNOWN_PRINTER_DRIVER;
 
7485
        }
 
7486
 
 
7487
        result = enumprinterdrivers_level(p->mem_ctx,
 
7488
                                          get_session_info_system(),
 
7489
                                          p->msg_ctx,
 
7490
                                          cservername,
 
7491
                                          r->in.environment,
 
7492
                                          r->in.level,
 
7493
                                          r->out.info,
 
7494
                                          r->out.count);
 
7495
        if (!W_ERROR_IS_OK(result)) {
 
7496
                return result;
 
7497
        }
 
7498
 
 
7499
        *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
 
7500
                                                     spoolss_EnumPrinterDrivers,
 
7501
                                                     *r->out.info, r->in.level,
 
7502
                                                     *r->out.count);
 
7503
        *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
 
7504
        *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
 
7505
 
 
7506
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 
7507
}
 
7508
 
 
7509
/****************************************************************
 
7510
 _spoolss_EnumForms
 
7511
****************************************************************/
 
7512
 
 
7513
WERROR _spoolss_EnumForms(struct pipes_struct *p,
 
7514
                          struct spoolss_EnumForms *r)
 
7515
{
 
7516
        WERROR result;
 
7517
 
 
7518
        *r->out.count = 0;
 
7519
        *r->out.needed = 0;
 
7520
        *r->out.info = NULL;
 
7521
 
 
7522
        /* that's an [in out] buffer */
 
7523
 
 
7524
        if (!r->in.buffer && (r->in.offered != 0) ) {
 
7525
                return WERR_INVALID_PARAM;
 
7526
        }
 
7527
 
 
7528
        DEBUG(4,("_spoolss_EnumForms\n"));
 
7529
        DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
 
7530
        DEBUGADD(5,("Info level [%d]\n",          r->in.level));
 
7531
 
 
7532
        switch (r->in.level) {
 
7533
        case 1:
 
7534
                result = winreg_printer_enumforms1_internal(p->mem_ctx,
 
7535
                                                   get_session_info_system(),
 
7536
                                                   p->msg_ctx,
 
7537
                                                   r->out.count,
 
7538
                                                   r->out.info);
 
7539
                break;
 
7540
        default:
 
7541
                result = WERR_UNKNOWN_LEVEL;
 
7542
                break;
 
7543
        }
 
7544
 
 
7545
        if (!W_ERROR_IS_OK(result)) {
 
7546
                return result;
 
7547
        }
 
7548
 
 
7549
        if (*r->out.count == 0) {
 
7550
                return WERR_NO_MORE_ITEMS;
 
7551
        }
 
7552
 
 
7553
        *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
 
7554
                                                     spoolss_EnumForms,
 
7555
                                                     *r->out.info, r->in.level,
 
7556
                                                     *r->out.count);
 
7557
        *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
 
7558
        *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
 
7559
 
 
7560
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 
7561
}
 
7562
 
 
7563
/****************************************************************
 
7564
 _spoolss_GetForm
 
7565
****************************************************************/
 
7566
 
 
7567
WERROR _spoolss_GetForm(struct pipes_struct *p,
 
7568
                        struct spoolss_GetForm *r)
 
7569
{
 
7570
        WERROR result;
 
7571
 
 
7572
        /* that's an [in out] buffer */
 
7573
 
 
7574
        if (!r->in.buffer && (r->in.offered != 0)) {
 
7575
                return WERR_INVALID_PARAM;
 
7576
        }
 
7577
 
 
7578
        DEBUG(4,("_spoolss_GetForm\n"));
 
7579
        DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
 
7580
        DEBUGADD(5,("Info level [%d]\n",          r->in.level));
 
7581
 
 
7582
        switch (r->in.level) {
 
7583
        case 1:
 
7584
                result = winreg_printer_getform1_internal(p->mem_ctx,
 
7585
                                                 get_session_info_system(),
 
7586
                                                 p->msg_ctx,
 
7587
                                                 r->in.form_name,
 
7588
                                                 &r->out.info->info1);
 
7589
                break;
 
7590
        default:
 
7591
                result = WERR_UNKNOWN_LEVEL;
 
7592
                break;
 
7593
        }
 
7594
 
 
7595
        if (!W_ERROR_IS_OK(result)) {
 
7596
                TALLOC_FREE(r->out.info);
 
7597
                return result;
 
7598
        }
 
7599
 
 
7600
        *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_FormInfo,
 
7601
                                               r->out.info, r->in.level);
 
7602
        r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
 
7603
 
 
7604
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 
7605
}
 
7606
 
 
7607
/****************************************************************************
 
7608
****************************************************************************/
 
7609
 
 
7610
static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
 
7611
                          struct spoolss_PortInfo1 *r,
 
7612
                          const char *name)
 
7613
{
 
7614
        r->port_name = talloc_strdup(mem_ctx, name);
 
7615
        W_ERROR_HAVE_NO_MEMORY(r->port_name);
 
7616
 
 
7617
        return WERR_OK;
 
7618
}
 
7619
 
 
7620
/****************************************************************************
 
7621
 TODO: This probably needs distinguish between TCP/IP and Local ports
 
7622
 somehow.
 
7623
****************************************************************************/
 
7624
 
 
7625
static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
 
7626
                          struct spoolss_PortInfo2 *r,
 
7627
                          const char *name)
 
7628
{
 
7629
        r->port_name = talloc_strdup(mem_ctx, name);
 
7630
        W_ERROR_HAVE_NO_MEMORY(r->port_name);
 
7631
 
 
7632
        r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
 
7633
        W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
 
7634
 
 
7635
        r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
 
7636
        W_ERROR_HAVE_NO_MEMORY(r->description);
 
7637
 
 
7638
        r->port_type = SPOOLSS_PORT_TYPE_WRITE;
 
7639
        r->reserved = 0;
 
7640
 
 
7641
        return WERR_OK;
 
7642
}
 
7643
 
 
7644
 
 
7645
/****************************************************************************
 
7646
 wrapper around the enumer ports command
 
7647
****************************************************************************/
 
7648
 
 
7649
static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
 
7650
{
 
7651
        char *cmd = lp_enumports_cmd();
 
7652
        char **qlines = NULL;
 
7653
        char *command = NULL;
 
7654
        int numlines;
 
7655
        int ret;
 
7656
        int fd;
 
7657
 
 
7658
        *count = 0;
 
7659
        *lines = NULL;
 
7660
 
 
7661
        /* if no hook then just fill in the default port */
 
7662
 
 
7663
        if ( !*cmd ) {
 
7664
                if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
 
7665
                        return WERR_NOMEM;
 
7666
                }
 
7667
                if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
 
7668
                        TALLOC_FREE(qlines);
 
7669
                        return WERR_NOMEM;
 
7670
                }
 
7671
                qlines[1] = NULL;
 
7672
                numlines = 1;
 
7673
        }
 
7674
        else {
 
7675
                /* we have a valid enumport command */
 
7676
 
 
7677
                command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
 
7678
                if (!command) {
 
7679
                        return WERR_NOMEM;
 
7680
                }
 
7681
 
 
7682
                DEBUG(10,("Running [%s]\n", command));
 
7683
                ret = smbrun(command, &fd);
 
7684
                DEBUG(10,("Returned [%d]\n", ret));
 
7685
                TALLOC_FREE(command);
 
7686
                if (ret != 0) {
 
7687
                        if (fd != -1) {
 
7688
                                close(fd);
 
7689
                        }
 
7690
                        return WERR_ACCESS_DENIED;
 
7691
                }
 
7692
 
 
7693
                numlines = 0;
 
7694
                qlines = fd_lines_load(fd, &numlines, 0, NULL);
 
7695
                DEBUGADD(10,("Lines returned = [%d]\n", numlines));
 
7696
                close(fd);
 
7697
        }
 
7698
 
 
7699
        *count = numlines;
 
7700
        *lines = qlines;
 
7701
 
 
7702
        return WERR_OK;
 
7703
}
 
7704
 
 
7705
/****************************************************************************
 
7706
 enumports level 1.
 
7707
****************************************************************************/
 
7708
 
 
7709
static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
 
7710
                                union spoolss_PortInfo **info_p,
 
7711
                                uint32_t *count)
 
7712
{
 
7713
        union spoolss_PortInfo *info = NULL;
 
7714
        int i=0;
 
7715
        WERROR result = WERR_OK;
 
7716
        char **qlines = NULL;
 
7717
        int numlines = 0;
 
7718
 
 
7719
        result = enumports_hook(talloc_tos(), &numlines, &qlines );
 
7720
        if (!W_ERROR_IS_OK(result)) {
 
7721
                goto out;
 
7722
        }
 
7723
 
 
7724
        if (numlines) {
 
7725
                info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
 
7726
                if (!info) {
 
7727
                        DEBUG(10,("Returning WERR_NOMEM\n"));
 
7728
                        result = WERR_NOMEM;
 
7729
                        goto out;
 
7730
                }
 
7731
 
 
7732
                for (i=0; i<numlines; i++) {
 
7733
                        DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
 
7734
                        result = fill_port_1(info, &info[i].info1, qlines[i]);
 
7735
                        if (!W_ERROR_IS_OK(result)) {
 
7736
                                goto out;
 
7737
                        }
 
7738
                }
 
7739
        }
 
7740
        TALLOC_FREE(qlines);
 
7741
 
 
7742
out:
 
7743
        if (!W_ERROR_IS_OK(result)) {
 
7744
                TALLOC_FREE(info);
 
7745
                TALLOC_FREE(qlines);
 
7746
                *count = 0;
 
7747
                *info_p = NULL;
 
7748
                return result;
 
7749
        }
 
7750
 
 
7751
        *info_p = info;
 
7752
        *count = numlines;
 
7753
 
 
7754
        return WERR_OK;
 
7755
}
 
7756
 
 
7757
/****************************************************************************
 
7758
 enumports level 2.
 
7759
****************************************************************************/
 
7760
 
 
7761
static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
 
7762
                                union spoolss_PortInfo **info_p,
 
7763
                                uint32_t *count)
 
7764
{
 
7765
        union spoolss_PortInfo *info = NULL;
 
7766
        int i=0;
 
7767
        WERROR result = WERR_OK;
 
7768
        char **qlines = NULL;
 
7769
        int numlines = 0;
 
7770
 
 
7771
        result = enumports_hook(talloc_tos(), &numlines, &qlines );
 
7772
        if (!W_ERROR_IS_OK(result)) {
 
7773
                goto out;
 
7774
        }
 
7775
 
 
7776
        if (numlines) {
 
7777
                info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
 
7778
                if (!info) {
 
7779
                        DEBUG(10,("Returning WERR_NOMEM\n"));
 
7780
                        result = WERR_NOMEM;
 
7781
                        goto out;
 
7782
                }
 
7783
 
 
7784
                for (i=0; i<numlines; i++) {
 
7785
                        DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
 
7786
                        result = fill_port_2(info, &info[i].info2, qlines[i]);
 
7787
                        if (!W_ERROR_IS_OK(result)) {
 
7788
                                goto out;
 
7789
                        }
 
7790
                }
 
7791
        }
 
7792
        TALLOC_FREE(qlines);
 
7793
 
 
7794
out:
 
7795
        if (!W_ERROR_IS_OK(result)) {
 
7796
                TALLOC_FREE(info);
 
7797
                TALLOC_FREE(qlines);
 
7798
                *count = 0;
 
7799
                *info_p = NULL;
 
7800
                return result;
 
7801
        }
 
7802
 
 
7803
        *info_p = info;
 
7804
        *count = numlines;
 
7805
 
 
7806
        return WERR_OK;
 
7807
}
 
7808
 
 
7809
/****************************************************************
 
7810
 _spoolss_EnumPorts
 
7811
****************************************************************/
 
7812
 
 
7813
WERROR _spoolss_EnumPorts(struct pipes_struct *p,
 
7814
                          struct spoolss_EnumPorts *r)
 
7815
{
 
7816
        WERROR result;
 
7817
 
 
7818
        /* that's an [in out] buffer */
 
7819
 
 
7820
        if (!r->in.buffer && (r->in.offered != 0)) {
 
7821
                return WERR_INVALID_PARAM;
 
7822
        }
 
7823
 
 
7824
        DEBUG(4,("_spoolss_EnumPorts\n"));
 
7825
 
 
7826
        *r->out.count = 0;
 
7827
        *r->out.needed = 0;
 
7828
        *r->out.info = NULL;
 
7829
 
 
7830
        switch (r->in.level) {
 
7831
        case 1:
 
7832
                result = enumports_level_1(p->mem_ctx, r->out.info,
 
7833
                                           r->out.count);
 
7834
                break;
 
7835
        case 2:
 
7836
                result = enumports_level_2(p->mem_ctx, r->out.info,
 
7837
                                           r->out.count);
 
7838
                break;
 
7839
        default:
 
7840
                return WERR_UNKNOWN_LEVEL;
 
7841
        }
 
7842
 
 
7843
        if (!W_ERROR_IS_OK(result)) {
 
7844
                return result;
 
7845
        }
 
7846
 
 
7847
        *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
 
7848
                                                     spoolss_EnumPorts,
 
7849
                                                     *r->out.info, r->in.level,
 
7850
                                                     *r->out.count);
 
7851
        *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
 
7852
        *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
 
7853
 
 
7854
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 
7855
}
 
7856
 
 
7857
/****************************************************************************
 
7858
****************************************************************************/
 
7859
 
 
7860
static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p,
 
7861
                                           const char *server,
 
7862
                                           struct spoolss_SetPrinterInfoCtr *info_ctr,
 
7863
                                           struct spoolss_DeviceMode *devmode,
 
7864
                                           struct security_descriptor *secdesc,
 
7865
                                           struct spoolss_UserLevelCtr *user_ctr,
 
7866
                                           struct policy_handle *handle)
 
7867
{
 
7868
        struct spoolss_SetPrinterInfo2 *info2 = info_ctr->info.info2;
 
7869
        uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ALL;
 
7870
        int     snum;
 
7871
        WERROR err = WERR_OK;
 
7872
 
 
7873
        /* samba does not have a concept of local, non-shared printers yet, so
 
7874
         * make sure we always setup sharename - gd */
 
7875
        if ((info2->sharename == NULL || info2->sharename[0] == '\0') &&
 
7876
            (info2->printername != NULL && info2->printername[0] != '\0')) {
 
7877
                DEBUG(5, ("spoolss_addprinterex_level_2: "
 
7878
                        "no sharename has been set, setting printername %s as sharename\n",
 
7879
                        info2->printername));
 
7880
                info2->sharename = info2->printername;
 
7881
        }
 
7882
 
 
7883
        /* check to see if the printer already exists */
 
7884
        if ((snum = print_queue_snum(info2->sharename)) != -1) {
 
7885
                DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
 
7886
                        info2->sharename));
 
7887
                return WERR_PRINTER_ALREADY_EXISTS;
 
7888
        }
 
7889
 
 
7890
        if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
 
7891
                if ((snum = print_queue_snum(info2->printername)) != -1) {
 
7892
                        DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
 
7893
                                info2->printername));
 
7894
                        return WERR_PRINTER_ALREADY_EXISTS;
 
7895
                }
 
7896
        }
 
7897
 
 
7898
        /* validate printer info struct */
 
7899
        if (!info2->printername || strlen(info2->printername) == 0) {
 
7900
                return WERR_INVALID_PRINTER_NAME;
 
7901
        }
 
7902
        if (!info2->portname || strlen(info2->portname) == 0) {
 
7903
                return WERR_UNKNOWN_PORT;
 
7904
        }
 
7905
        if (!info2->drivername || strlen(info2->drivername) == 0) {
 
7906
                return WERR_UNKNOWN_PRINTER_DRIVER;
 
7907
        }
 
7908
        if (!info2->printprocessor || strlen(info2->printprocessor) == 0) {
 
7909
                return WERR_UNKNOWN_PRINTPROCESSOR;
 
7910
        }
 
7911
 
 
7912
        /* FIXME!!!  smbd should check to see if the driver is installed before
 
7913
           trying to add a printer like this  --jerry */
 
7914
 
 
7915
        if (*lp_addprinter_cmd() ) {
 
7916
                if ( !add_printer_hook(p->mem_ctx, p->session_info->security_token,
 
7917
                                       info2, p->client_id->addr,
 
7918
                                       p->msg_ctx) ) {
 
7919
                        return WERR_ACCESS_DENIED;
 
7920
                }
 
7921
        } else {
 
7922
                DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no "
 
7923
                        "smb.conf parameter \"addprinter command\" is defined. This "
 
7924
                        "parameter must exist for this call to succeed\n",
 
7925
                        info2->sharename ));
 
7926
        }
 
7927
 
 
7928
        if ((snum = print_queue_snum(info2->sharename)) == -1) {
 
7929
                return WERR_ACCESS_DENIED;
 
7930
        }
 
7931
 
 
7932
        /* you must be a printer admin to add a new printer */
 
7933
        if (!print_access_check(p->session_info,
 
7934
                                p->msg_ctx,
 
7935
                                snum,
 
7936
                                PRINTER_ACCESS_ADMINISTER)) {
 
7937
                return WERR_ACCESS_DENIED;
 
7938
        }
 
7939
 
 
7940
        /*
 
7941
         * Do sanity check on the requested changes for Samba.
 
7942
         */
 
7943
 
 
7944
        if (!check_printer_ok(p->mem_ctx, info2, snum)) {
 
7945
                return WERR_INVALID_PARAM;
 
7946
        }
 
7947
 
 
7948
        if (devmode == NULL) {
 
7949
                info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
 
7950
        }
 
7951
 
 
7952
        update_dsspooler(p->mem_ctx,
 
7953
                         get_session_info_system(),
 
7954
                         p->msg_ctx,
 
7955
                         0,
 
7956
                         info2,
 
7957
                         NULL);
 
7958
 
 
7959
        err = winreg_update_printer_internal(p->mem_ctx,
 
7960
                                    get_session_info_system(),
 
7961
                                    p->msg_ctx,
 
7962
                                    info2->sharename,
 
7963
                                    info2_mask,
 
7964
                                    info2,
 
7965
                                    devmode,
 
7966
                                    secdesc);
 
7967
        if (!W_ERROR_IS_OK(err)) {
 
7968
                return err;
 
7969
        }
 
7970
 
 
7971
        err = open_printer_hnd(p, handle, info2->printername, PRINTER_ACCESS_ADMINISTER);
 
7972
        if (!W_ERROR_IS_OK(err)) {
 
7973
                /* Handle open failed - remove addition. */
 
7974
                ZERO_STRUCTP(handle);
 
7975
                return err;
 
7976
        }
 
7977
 
 
7978
        return WERR_OK;
 
7979
}
 
7980
 
 
7981
/****************************************************************
 
7982
 _spoolss_AddPrinterEx
 
7983
****************************************************************/
 
7984
 
 
7985
WERROR _spoolss_AddPrinterEx(struct pipes_struct *p,
 
7986
                             struct spoolss_AddPrinterEx *r)
 
7987
{
 
7988
        switch (r->in.info_ctr->level) {
 
7989
        case 1:
 
7990
                /* we don't handle yet */
 
7991
                /* but I know what to do ... */
 
7992
                return WERR_UNKNOWN_LEVEL;
 
7993
        case 2:
 
7994
                return spoolss_addprinterex_level_2(p, r->in.server,
 
7995
                                                    r->in.info_ctr,
 
7996
                                                    r->in.devmode_ctr->devmode,
 
7997
                                                    r->in.secdesc_ctr->sd,
 
7998
                                                    r->in.userlevel_ctr,
 
7999
                                                    r->out.handle);
 
8000
        default:
 
8001
                return WERR_UNKNOWN_LEVEL;
 
8002
        }
 
8003
}
 
8004
 
 
8005
/****************************************************************
 
8006
 _spoolss_AddPrinter
 
8007
****************************************************************/
 
8008
 
 
8009
WERROR _spoolss_AddPrinter(struct pipes_struct *p,
 
8010
                           struct spoolss_AddPrinter *r)
 
8011
{
 
8012
        struct spoolss_AddPrinterEx a;
 
8013
        struct spoolss_UserLevelCtr userlevel_ctr;
 
8014
 
 
8015
        ZERO_STRUCT(userlevel_ctr);
 
8016
 
 
8017
        userlevel_ctr.level = 1;
 
8018
 
 
8019
        a.in.server             = r->in.server;
 
8020
        a.in.info_ctr           = r->in.info_ctr;
 
8021
        a.in.devmode_ctr        = r->in.devmode_ctr;
 
8022
        a.in.secdesc_ctr        = r->in.secdesc_ctr;
 
8023
        a.in.userlevel_ctr      = &userlevel_ctr;
 
8024
        a.out.handle            = r->out.handle;
 
8025
 
 
8026
        return _spoolss_AddPrinterEx(p, &a);
 
8027
}
 
8028
 
 
8029
/****************************************************************
 
8030
 _spoolss_AddPrinterDriverEx
 
8031
****************************************************************/
 
8032
 
 
8033
WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
 
8034
                                   struct spoolss_AddPrinterDriverEx *r)
 
8035
{
 
8036
        WERROR err = WERR_OK;
 
8037
        const char *driver_name = NULL;
 
8038
        uint32_t version;
 
8039
        const char *fn;
 
8040
 
 
8041
        switch (p->opnum) {
 
8042
                case NDR_SPOOLSS_ADDPRINTERDRIVER:
 
8043
                        fn = "_spoolss_AddPrinterDriver";
 
8044
                        break;
 
8045
                case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
 
8046
                        fn = "_spoolss_AddPrinterDriverEx";
 
8047
                        break;
 
8048
                default:
 
8049
                        return WERR_INVALID_PARAM;
 
8050
        }
 
8051
 
 
8052
        /*
 
8053
         * we only support the semantics of AddPrinterDriver()
 
8054
         * i.e. only copy files that are newer than existing ones
 
8055
         */
 
8056
 
 
8057
        if (r->in.flags == 0) {
 
8058
                return WERR_INVALID_PARAM;
 
8059
        }
 
8060
 
 
8061
        if (r->in.flags != APD_COPY_NEW_FILES) {
 
8062
                return WERR_ACCESS_DENIED;
 
8063
        }
 
8064
 
 
8065
        /* FIXME */
 
8066
        if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
 
8067
                /* Clever hack from Martin Zielinski <mz@seh.de>
 
8068
                 * to allow downgrade from level 8 (Vista).
 
8069
                 */
 
8070
                DEBUG(0,("%s: level %d not yet implemented\n", fn,
 
8071
                        r->in.info_ctr->level));
 
8072
                return WERR_UNKNOWN_LEVEL;
 
8073
        }
 
8074
 
 
8075
        DEBUG(5,("Cleaning driver's information\n"));
 
8076
        err = clean_up_driver_struct(p->mem_ctx, p->session_info, r->in.info_ctr);
 
8077
        if (!W_ERROR_IS_OK(err))
 
8078
                goto done;
 
8079
 
 
8080
        DEBUG(5,("Moving driver to final destination\n"));
 
8081
        err = move_driver_to_download_area(p->session_info, r->in.info_ctr);
 
8082
        if (!W_ERROR_IS_OK(err)) {
 
8083
                goto done;
 
8084
        }
 
8085
 
 
8086
        err = winreg_add_driver_internal(p->mem_ctx,
 
8087
                                get_session_info_system(),
 
8088
                                p->msg_ctx,
 
8089
                                r->in.info_ctr,
 
8090
                                &driver_name,
 
8091
                                &version);
 
8092
        if (!W_ERROR_IS_OK(err)) {
 
8093
                goto done;
 
8094
        }
 
8095
 
 
8096
        /*
 
8097
         * I think this is where he DrvUpgradePrinter() hook would be
 
8098
         * be called in a driver's interface DLL on a Windows NT 4.0/2k
 
8099
         * server.  Right now, we just need to send ourselves a message
 
8100
         * to update each printer bound to this driver.   --jerry
 
8101
         */
 
8102
 
 
8103
        if (!srv_spoolss_drv_upgrade_printer(driver_name, p->msg_ctx)) {
 
8104
                DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
 
8105
                        fn, driver_name));
 
8106
        }
 
8107
 
 
8108
done:
 
8109
        return err;
 
8110
}
 
8111
 
 
8112
/****************************************************************
 
8113
 _spoolss_AddPrinterDriver
 
8114
****************************************************************/
 
8115
 
 
8116
WERROR _spoolss_AddPrinterDriver(struct pipes_struct *p,
 
8117
                                 struct spoolss_AddPrinterDriver *r)
 
8118
{
 
8119
        struct spoolss_AddPrinterDriverEx a;
 
8120
 
 
8121
        switch (r->in.info_ctr->level) {
 
8122
        case 2:
 
8123
        case 3:
 
8124
        case 4:
 
8125
        case 5:
 
8126
                break;
 
8127
        default:
 
8128
                return WERR_UNKNOWN_LEVEL;
 
8129
        }
 
8130
 
 
8131
        a.in.servername         = r->in.servername;
 
8132
        a.in.info_ctr           = r->in.info_ctr;
 
8133
        a.in.flags              = APD_COPY_NEW_FILES;
 
8134
 
 
8135
        return _spoolss_AddPrinterDriverEx(p, &a);
 
8136
}
 
8137
 
 
8138
/****************************************************************************
 
8139
****************************************************************************/
 
8140
 
 
8141
struct _spoolss_paths {
 
8142
        int type;
 
8143
        const char *share;
 
8144
        const char *dir;
 
8145
};
 
8146
 
 
8147
enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
 
8148
 
 
8149
static const struct _spoolss_paths spoolss_paths[]= {
 
8150
        { SPOOLSS_DRIVER_PATH,          "print$",       "DRIVERS" },
 
8151
        { SPOOLSS_PRTPROCS_PATH,        "prnproc$",     "PRTPROCS" }
 
8152
};
 
8153
 
 
8154
static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
 
8155
                                          const char *servername,
 
8156
                                          const char *environment,
 
8157
                                          int component,
 
8158
                                          char **path)
 
8159
{
 
8160
        const char *pservername = NULL;
 
8161
        const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
 
8162
        const char *short_archi;
 
8163
 
 
8164
        *path = NULL;
 
8165
 
 
8166
        /* environment may be empty */
 
8167
        if (environment && strlen(environment)) {
 
8168
                long_archi = environment;
 
8169
        }
 
8170
 
 
8171
        /* servername may be empty */
 
8172
        if (servername && strlen(servername)) {
 
8173
                pservername = canon_servername(servername);
 
8174
 
 
8175
                if (!is_myname_or_ipaddr(pservername)) {
 
8176
                        return WERR_INVALID_PARAM;
 
8177
                }
 
8178
        }
 
8179
 
 
8180
        if (!(short_archi = get_short_archi(long_archi))) {
 
8181
                return WERR_INVALID_ENVIRONMENT;
 
8182
        }
 
8183
 
 
8184
        switch (component) {
 
8185
        case SPOOLSS_PRTPROCS_PATH:
 
8186
        case SPOOLSS_DRIVER_PATH:
 
8187
                if (pservername) {
 
8188
                        *path = talloc_asprintf(mem_ctx,
 
8189
                                        "\\\\%s\\%s\\%s",
 
8190
                                        pservername,
 
8191
                                        spoolss_paths[component].share,
 
8192
                                        short_archi);
 
8193
                } else {
 
8194
                        *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
 
8195
                                        SPOOLSS_DEFAULT_SERVER_PATH,
 
8196
                                        spoolss_paths[component].dir,
 
8197
                                        short_archi);
 
8198
                }
 
8199
                break;
 
8200
        default:
 
8201
                return WERR_INVALID_PARAM;
 
8202
        }
 
8203
 
 
8204
        if (!*path) {
 
8205
                return WERR_NOMEM;
 
8206
        }
 
8207
 
 
8208
        return WERR_OK;
 
8209
}
 
8210
 
 
8211
/****************************************************************************
 
8212
****************************************************************************/
 
8213
 
 
8214
static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
 
8215
                                          const char *servername,
 
8216
                                          const char *environment,
 
8217
                                          struct spoolss_DriverDirectoryInfo1 *r)
 
8218
{
 
8219
        WERROR werr;
 
8220
        char *path = NULL;
 
8221
 
 
8222
        werr = compose_spoolss_server_path(mem_ctx,
 
8223
                                           servername,
 
8224
                                           environment,
 
8225
                                           SPOOLSS_DRIVER_PATH,
 
8226
                                           &path);
 
8227
        if (!W_ERROR_IS_OK(werr)) {
 
8228
                return werr;
 
8229
        }
 
8230
 
 
8231
        DEBUG(4,("printer driver directory: [%s]\n", path));
 
8232
 
 
8233
        r->directory_name = path;
 
8234
 
 
8235
        return WERR_OK;
 
8236
}
 
8237
 
 
8238
/****************************************************************
 
8239
 _spoolss_GetPrinterDriverDirectory
 
8240
****************************************************************/
 
8241
 
 
8242
WERROR _spoolss_GetPrinterDriverDirectory(struct pipes_struct *p,
 
8243
                                          struct spoolss_GetPrinterDriverDirectory *r)
 
8244
{
 
8245
        WERROR werror;
 
8246
 
 
8247
        /* that's an [in out] buffer */
 
8248
 
 
8249
        if (!r->in.buffer && (r->in.offered != 0)) {
 
8250
                return WERR_INVALID_PARAM;
 
8251
        }
 
8252
 
 
8253
        DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
 
8254
                r->in.level));
 
8255
 
 
8256
        *r->out.needed = 0;
 
8257
 
 
8258
        /* r->in.level is ignored */
 
8259
 
 
8260
        werror = getprinterdriverdir_level_1(p->mem_ctx,
 
8261
                                             r->in.server,
 
8262
                                             r->in.environment,
 
8263
                                             &r->out.info->info1);
 
8264
        if (!W_ERROR_IS_OK(werror)) {
 
8265
                TALLOC_FREE(r->out.info);
 
8266
                return werror;
 
8267
        }
 
8268
 
 
8269
        *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo,
 
8270
                                               r->out.info, r->in.level);
 
8271
        r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
 
8272
 
 
8273
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 
8274
}
 
8275
 
 
8276
/****************************************************************
 
8277
 _spoolss_EnumPrinterData
 
8278
****************************************************************/
 
8279
 
 
8280
WERROR _spoolss_EnumPrinterData(struct pipes_struct *p,
 
8281
                                struct spoolss_EnumPrinterData *r)
 
8282
{
 
8283
        WERROR result;
 
8284
        struct spoolss_EnumPrinterDataEx r2;
 
8285
        uint32_t count;
 
8286
        struct spoolss_PrinterEnumValues *info, *val = NULL;
 
8287
        uint32_t needed;
 
8288
 
 
8289
        r2.in.handle    = r->in.handle;
 
8290
        r2.in.key_name  = "PrinterDriverData";
 
8291
        r2.in.offered   = 0;
 
8292
        r2.out.count    = &count;
 
8293
        r2.out.info     = &info;
 
8294
        r2.out.needed   = &needed;
 
8295
 
 
8296
        result = _spoolss_EnumPrinterDataEx(p, &r2);
 
8297
        if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
 
8298
                r2.in.offered = needed;
 
8299
                result = _spoolss_EnumPrinterDataEx(p, &r2);
 
8300
        }
 
8301
        if (!W_ERROR_IS_OK(result)) {
 
8302
                return result;
 
8303
        }
 
8304
 
 
8305
        /*
 
8306
         * The NT machine wants to know the biggest size of value and data
 
8307
         *
 
8308
         * cf: MSDN EnumPrinterData remark section
 
8309
         */
 
8310
 
 
8311
        if (!r->in.value_offered && !r->in.data_offered) {
 
8312
                uint32_t biggest_valuesize = 0;
 
8313
                uint32_t biggest_datasize = 0;
 
8314
                int i, name_length;
 
8315
 
 
8316
                DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
 
8317
 
 
8318
                for (i=0; i<count; i++) {
 
8319
 
 
8320
                        name_length = strlen(info[i].value_name);
 
8321
                        if (strlen(info[i].value_name) > biggest_valuesize) {
 
8322
                                biggest_valuesize = name_length;
 
8323
                        }
 
8324
 
 
8325
                        if (info[i].data_length > biggest_datasize) {
 
8326
                                biggest_datasize = info[i].data_length;
 
8327
                        }
 
8328
 
 
8329
                        DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
 
8330
                                biggest_datasize));
 
8331
                }
 
8332
 
 
8333
                /* the value is an UNICODE string but real_value_size is the length
 
8334
                   in bytes including the trailing 0 */
 
8335
 
 
8336
                *r->out.value_needed = 2 * (1 + biggest_valuesize);
 
8337
                *r->out.data_needed  = biggest_datasize;
 
8338
 
 
8339
                DEBUG(6,("final values: [%d], [%d]\n",
 
8340
                        *r->out.value_needed, *r->out.data_needed));
 
8341
 
 
8342
                return WERR_OK;
 
8343
        }
 
8344
 
 
8345
        if (r->in.enum_index < count) {
 
8346
                val = &info[r->in.enum_index];
 
8347
        }
 
8348
 
 
8349
        if (val == NULL) {
 
8350
                /* out_value should default to "" or else NT4 has
 
8351
                   problems unmarshalling the response */
 
8352
 
 
8353
                if (r->in.value_offered) {
 
8354
                        *r->out.value_needed = 1;
 
8355
                        r->out.value_name = talloc_strdup(r, "");
 
8356
                        if (!r->out.value_name) {
 
8357
                                return WERR_NOMEM;
 
8358
                        }
 
8359
                } else {
 
8360
                        r->out.value_name = NULL;
 
8361
                        *r->out.value_needed = 0;
 
8362
                }
 
8363
 
 
8364
                /* the data is counted in bytes */
 
8365
 
 
8366
                *r->out.data_needed = r->in.data_offered;
 
8367
 
 
8368
                result = WERR_NO_MORE_ITEMS;
 
8369
        } else {
 
8370
                /*
 
8371
                 * the value is:
 
8372
                 * - counted in bytes in the request
 
8373
                 * - counted in UNICODE chars in the max reply
 
8374
                 * - counted in bytes in the real size
 
8375
                 *
 
8376
                 * take a pause *before* coding not *during* coding
 
8377
                 */
 
8378
 
 
8379
                /* name */
 
8380
                if (r->in.value_offered) {
 
8381
                        r->out.value_name = talloc_strdup(r, val->value_name);
 
8382
                        if (!r->out.value_name) {
 
8383
                                return WERR_NOMEM;
 
8384
                        }
 
8385
                        *r->out.value_needed = val->value_name_len;
 
8386
                } else {
 
8387
                        r->out.value_name = NULL;
 
8388
                        *r->out.value_needed = 0;
 
8389
                }
 
8390
 
 
8391
                /* type */
 
8392
 
 
8393
                *r->out.type = val->type;
 
8394
 
 
8395
                /* data - counted in bytes */
 
8396
 
 
8397
                /*
 
8398
                 * See the section "Dynamically Typed Query Parameters"
 
8399
                 * in MS-RPRN.
 
8400
                 */
 
8401
 
 
8402
                if (r->out.data && val->data && val->data->data &&
 
8403
                                val->data_length && r->in.data_offered) {
 
8404
                        memcpy(r->out.data, val->data->data,
 
8405
                                MIN(val->data_length,r->in.data_offered));
 
8406
                }
 
8407
 
 
8408
                *r->out.data_needed = val->data_length;
 
8409
 
 
8410
                result = WERR_OK;
 
8411
        }
 
8412
 
 
8413
        return result;
 
8414
}
 
8415
 
 
8416
/****************************************************************
 
8417
 _spoolss_SetPrinterData
 
8418
****************************************************************/
 
8419
 
 
8420
WERROR _spoolss_SetPrinterData(struct pipes_struct *p,
 
8421
                               struct spoolss_SetPrinterData *r)
 
8422
{
 
8423
        struct spoolss_SetPrinterDataEx r2;
 
8424
 
 
8425
        r2.in.handle            = r->in.handle;
 
8426
        r2.in.key_name          = "PrinterDriverData";
 
8427
        r2.in.value_name        = r->in.value_name;
 
8428
        r2.in.type              = r->in.type;
 
8429
        r2.in.data              = r->in.data;
 
8430
        r2.in.offered           = r->in.offered;
 
8431
 
 
8432
        return _spoolss_SetPrinterDataEx(p, &r2);
 
8433
}
 
8434
 
 
8435
/****************************************************************
 
8436
 _spoolss_ResetPrinter
 
8437
****************************************************************/
 
8438
 
 
8439
WERROR _spoolss_ResetPrinter(struct pipes_struct *p,
 
8440
                             struct spoolss_ResetPrinter *r)
 
8441
{
 
8442
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
8443
        int             snum;
 
8444
 
 
8445
        DEBUG(5,("_spoolss_ResetPrinter\n"));
 
8446
 
 
8447
        /*
 
8448
         * All we do is to check to see if the handle and queue is valid.
 
8449
         * This call really doesn't mean anything to us because we only
 
8450
         * support RAW printing.   --jerry
 
8451
         */
 
8452
 
 
8453
        if (!Printer) {
 
8454
                DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
 
8455
                        OUR_HANDLE(r->in.handle)));
 
8456
                return WERR_BADFID;
 
8457
        }
 
8458
 
 
8459
        if (!get_printer_snum(p, r->in.handle, &snum, NULL))
 
8460
                return WERR_BADFID;
 
8461
 
 
8462
 
 
8463
        /* blindly return success */
 
8464
        return WERR_OK;
 
8465
}
 
8466
 
 
8467
/****************************************************************
 
8468
 _spoolss_DeletePrinterData
 
8469
****************************************************************/
 
8470
 
 
8471
WERROR _spoolss_DeletePrinterData(struct pipes_struct *p,
 
8472
                                  struct spoolss_DeletePrinterData *r)
 
8473
{
 
8474
        struct spoolss_DeletePrinterDataEx r2;
 
8475
 
 
8476
        r2.in.handle            = r->in.handle;
 
8477
        r2.in.key_name          = "PrinterDriverData";
 
8478
        r2.in.value_name        = r->in.value_name;
 
8479
 
 
8480
        return _spoolss_DeletePrinterDataEx(p, &r2);
 
8481
}
 
8482
 
 
8483
/****************************************************************
 
8484
 _spoolss_AddForm
 
8485
****************************************************************/
 
8486
 
 
8487
WERROR _spoolss_AddForm(struct pipes_struct *p,
 
8488
                        struct spoolss_AddForm *r)
 
8489
{
 
8490
        struct spoolss_AddFormInfo1 *form = r->in.info.info1;
 
8491
        int snum = -1;
 
8492
        WERROR status = WERR_OK;
 
8493
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
8494
        struct dcerpc_binding_handle *b;
 
8495
 
 
8496
        DEBUG(5,("_spoolss_AddForm\n"));
 
8497
 
 
8498
        if (!Printer) {
 
8499
                DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
 
8500
                        OUR_HANDLE(r->in.handle)));
 
8501
                return WERR_BADFID;
 
8502
        }
 
8503
 
 
8504
        /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
 
8505
           and not a printer admin, then fail */
 
8506
 
 
8507
        if ((p->session_info->utok.uid != sec_initial_uid()) &&
 
8508
            !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_PRINT_OPERATOR) &&
 
8509
            !token_contains_name_in_list(uidtoname(p->session_info->utok.uid),
 
8510
                                          p->session_info->info3->base.domain.string,
 
8511
                                          NULL,
 
8512
                                          p->session_info->security_token,
 
8513
                                          lp_printer_admin(snum))) {
 
8514
                DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
 
8515
                return WERR_ACCESS_DENIED;
 
8516
        }
 
8517
 
 
8518
        switch (form->flags) {
 
8519
        case SPOOLSS_FORM_USER:
 
8520
        case SPOOLSS_FORM_BUILTIN:
 
8521
        case SPOOLSS_FORM_PRINTER:
 
8522
                break;
 
8523
        default:
 
8524
                return WERR_INVALID_PARAM;
 
8525
        }
 
8526
 
 
8527
        status = winreg_printer_binding_handle(p->mem_ctx,
 
8528
                                               get_session_info_system(),
 
8529
                                               p->msg_ctx,
 
8530
                                               &b);
 
8531
        if (!W_ERROR_IS_OK(status)) {
 
8532
                return status;
 
8533
        }
 
8534
 
 
8535
        status = winreg_printer_addform1(p->mem_ctx, b,
 
8536
                                         form);
 
8537
        if (!W_ERROR_IS_OK(status)) {
 
8538
                return status;
 
8539
        }
 
8540
 
 
8541
        /*
 
8542
         * ChangeID must always be set if this is a printer
 
8543
         */
 
8544
        if (Printer->printer_type == SPLHND_PRINTER) {
 
8545
                if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
 
8546
                        return WERR_BADFID;
 
8547
                }
 
8548
 
 
8549
                status = winreg_printer_update_changeid(p->mem_ctx, b,
 
8550
                                                        lp_const_servicename(snum));
 
8551
                if (!W_ERROR_IS_OK(status)) {
 
8552
                        return status;
 
8553
                }
 
8554
        }
 
8555
 
 
8556
        return status;
 
8557
}
 
8558
 
 
8559
/****************************************************************
 
8560
 _spoolss_DeleteForm
 
8561
****************************************************************/
 
8562
 
 
8563
WERROR _spoolss_DeleteForm(struct pipes_struct *p,
 
8564
                           struct spoolss_DeleteForm *r)
 
8565
{
 
8566
        const char *form_name = r->in.form_name;
 
8567
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
8568
        int snum = -1;
 
8569
        WERROR status = WERR_OK;
 
8570
        struct dcerpc_binding_handle *b;
 
8571
 
 
8572
        DEBUG(5,("_spoolss_DeleteForm\n"));
 
8573
 
 
8574
        if (!Printer) {
 
8575
                DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
 
8576
                        OUR_HANDLE(r->in.handle)));
 
8577
                return WERR_BADFID;
 
8578
        }
 
8579
 
 
8580
        if ((p->session_info->utok.uid != sec_initial_uid()) &&
 
8581
            !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_PRINT_OPERATOR) &&
 
8582
            !token_contains_name_in_list(uidtoname(p->session_info->utok.uid),
 
8583
                                          p->session_info->info3->base.domain.string,
 
8584
                                          NULL,
 
8585
                                          p->session_info->security_token,
 
8586
                                          lp_printer_admin(snum))) {
 
8587
                DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
 
8588
                return WERR_ACCESS_DENIED;
 
8589
        }
 
8590
 
 
8591
        status = winreg_printer_binding_handle(p->mem_ctx,
 
8592
                                               get_session_info_system(),
 
8593
                                               p->msg_ctx,
 
8594
                                               &b);
 
8595
        if (!W_ERROR_IS_OK(status)) {
 
8596
                return status;
 
8597
        }
 
8598
 
 
8599
        status = winreg_printer_deleteform1(p->mem_ctx, b,
 
8600
                                            form_name);
 
8601
        if (!W_ERROR_IS_OK(status)) {
 
8602
                return status;
 
8603
        }
 
8604
 
 
8605
        /*
 
8606
         * ChangeID must always be set if this is a printer
 
8607
         */
 
8608
        if (Printer->printer_type == SPLHND_PRINTER) {
 
8609
                if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
 
8610
                        return WERR_BADFID;
 
8611
                }
 
8612
 
 
8613
                status = winreg_printer_update_changeid(p->mem_ctx, b,
 
8614
                                                        lp_const_servicename(snum));
 
8615
                if (!W_ERROR_IS_OK(status)) {
 
8616
                        return status;
 
8617
                }
 
8618
        }
 
8619
 
 
8620
        return status;
 
8621
}
 
8622
 
 
8623
/****************************************************************
 
8624
 _spoolss_SetForm
 
8625
****************************************************************/
 
8626
 
 
8627
WERROR _spoolss_SetForm(struct pipes_struct *p,
 
8628
                        struct spoolss_SetForm *r)
 
8629
{
 
8630
        struct spoolss_AddFormInfo1 *form = r->in.info.info1;
 
8631
        const char *form_name = r->in.form_name;
 
8632
        int snum = -1;
 
8633
        WERROR status = WERR_OK;
 
8634
        struct dcerpc_binding_handle *b;
 
8635
 
 
8636
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
8637
 
 
8638
        DEBUG(5,("_spoolss_SetForm\n"));
 
8639
 
 
8640
        if (!Printer) {
 
8641
                DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
 
8642
                        OUR_HANDLE(r->in.handle)));
 
8643
                return WERR_BADFID;
 
8644
        }
 
8645
 
 
8646
        /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
 
8647
           and not a printer admin, then fail */
 
8648
 
 
8649
        if ((p->session_info->utok.uid != sec_initial_uid()) &&
 
8650
             !security_token_has_privilege(p->session_info->security_token, SEC_PRIV_PRINT_OPERATOR) &&
 
8651
             !token_contains_name_in_list(uidtoname(p->session_info->utok.uid),
 
8652
                                          p->session_info->info3->base.domain.string,
 
8653
                                          NULL,
 
8654
                                          p->session_info->security_token,
 
8655
                                          lp_printer_admin(snum))) {
 
8656
                DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
 
8657
                return WERR_ACCESS_DENIED;
 
8658
        }
 
8659
 
 
8660
        status = winreg_printer_binding_handle(p->mem_ctx,
 
8661
                                               get_session_info_system(),
 
8662
                                               p->msg_ctx,
 
8663
                                               &b);
 
8664
        if (!W_ERROR_IS_OK(status)) {
 
8665
                return status;
 
8666
        }
 
8667
 
 
8668
        status = winreg_printer_setform1(p->mem_ctx, b,
 
8669
                                         form_name,
 
8670
                                         form);
 
8671
        if (!W_ERROR_IS_OK(status)) {
 
8672
                return status;
 
8673
        }
 
8674
 
 
8675
        /*
 
8676
         * ChangeID must always be set if this is a printer
 
8677
         */
 
8678
        if (Printer->printer_type == SPLHND_PRINTER) {
 
8679
                if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
 
8680
                        return WERR_BADFID;
 
8681
                }
 
8682
 
 
8683
                status = winreg_printer_update_changeid(p->mem_ctx, b,
 
8684
                                                        lp_const_servicename(snum));
 
8685
                if (!W_ERROR_IS_OK(status)) {
 
8686
                        return status;
 
8687
                }
 
8688
        }
 
8689
 
 
8690
        return status;
 
8691
}
 
8692
 
 
8693
/****************************************************************************
 
8694
 fill_print_processor1
 
8695
****************************************************************************/
 
8696
 
 
8697
static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
 
8698
                                    struct spoolss_PrintProcessorInfo1 *r,
 
8699
                                    const char *print_processor_name)
 
8700
{
 
8701
        r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
 
8702
        W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
 
8703
 
 
8704
        return WERR_OK;
 
8705
}
 
8706
 
 
8707
/****************************************************************************
 
8708
 enumprintprocessors level 1.
 
8709
****************************************************************************/
 
8710
 
 
8711
static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
 
8712
                                          union spoolss_PrintProcessorInfo **info_p,
 
8713
                                          uint32_t *count)
 
8714
{
 
8715
        union spoolss_PrintProcessorInfo *info;
 
8716
        WERROR result;
 
8717
 
 
8718
        info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
 
8719
        W_ERROR_HAVE_NO_MEMORY(info);
 
8720
 
 
8721
        *count = 1;
 
8722
 
 
8723
        result = fill_print_processor1(info, &info[0].info1, "winprint");
 
8724
        if (!W_ERROR_IS_OK(result)) {
 
8725
                goto out;
 
8726
        }
 
8727
 
 
8728
 out:
 
8729
        if (!W_ERROR_IS_OK(result)) {
 
8730
                TALLOC_FREE(info);
 
8731
                *count = 0;
 
8732
                return result;
 
8733
        }
 
8734
 
 
8735
        *info_p = info;
 
8736
 
 
8737
        return WERR_OK;
 
8738
}
 
8739
 
 
8740
/****************************************************************
 
8741
 _spoolss_EnumPrintProcessors
 
8742
****************************************************************/
 
8743
 
 
8744
WERROR _spoolss_EnumPrintProcessors(struct pipes_struct *p,
 
8745
                                    struct spoolss_EnumPrintProcessors *r)
 
8746
{
 
8747
        WERROR result;
 
8748
 
 
8749
        /* that's an [in out] buffer */
 
8750
 
 
8751
        if (!r->in.buffer && (r->in.offered != 0)) {
 
8752
                return WERR_INVALID_PARAM;
 
8753
        }
 
8754
 
 
8755
        DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
 
8756
 
 
8757
        /*
 
8758
         * Enumerate the print processors ...
 
8759
         *
 
8760
         * Just reply with "winprint", to keep NT happy
 
8761
         * and I can use my nice printer checker.
 
8762
         */
 
8763
 
 
8764
        *r->out.count = 0;
 
8765
        *r->out.needed = 0;
 
8766
        *r->out.info = NULL;
 
8767
 
 
8768
        if (!get_short_archi(r->in.environment)) {
 
8769
                return WERR_INVALID_ENVIRONMENT;
 
8770
        }
 
8771
 
 
8772
        switch (r->in.level) {
 
8773
        case 1:
 
8774
                result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
 
8775
                                                     r->out.count);
 
8776
                break;
 
8777
        default:
 
8778
                return WERR_UNKNOWN_LEVEL;
 
8779
        }
 
8780
 
 
8781
        if (!W_ERROR_IS_OK(result)) {
 
8782
                return result;
 
8783
        }
 
8784
 
 
8785
        *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
 
8786
                                                     spoolss_EnumPrintProcessors,
 
8787
                                                     *r->out.info, r->in.level,
 
8788
                                                     *r->out.count);
 
8789
        *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
 
8790
        *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
 
8791
 
 
8792
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 
8793
}
 
8794
 
 
8795
/****************************************************************************
 
8796
 fill_printprocdatatype1
 
8797
****************************************************************************/
 
8798
 
 
8799
static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
 
8800
                                      struct spoolss_PrintProcDataTypesInfo1 *r,
 
8801
                                      const char *name_array)
 
8802
{
 
8803
        r->name_array = talloc_strdup(mem_ctx, name_array);
 
8804
        W_ERROR_HAVE_NO_MEMORY(r->name_array);
 
8805
 
 
8806
        return WERR_OK;
 
8807
}
 
8808
 
 
8809
/****************************************************************************
 
8810
 enumprintprocdatatypes level 1.
 
8811
****************************************************************************/
 
8812
 
 
8813
static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
 
8814
                                             union spoolss_PrintProcDataTypesInfo **info_p,
 
8815
                                             uint32_t *count)
 
8816
{
 
8817
        WERROR result;
 
8818
        union spoolss_PrintProcDataTypesInfo *info;
 
8819
 
 
8820
        info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
 
8821
        W_ERROR_HAVE_NO_MEMORY(info);
 
8822
 
 
8823
        *count = 1;
 
8824
 
 
8825
        result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
 
8826
        if (!W_ERROR_IS_OK(result)) {
 
8827
                goto out;
 
8828
        }
 
8829
 
 
8830
 out:
 
8831
        if (!W_ERROR_IS_OK(result)) {
 
8832
                TALLOC_FREE(info);
 
8833
                *count = 0;
 
8834
                return result;
 
8835
        }
 
8836
 
 
8837
        *info_p = info;
 
8838
 
 
8839
        return WERR_OK;
 
8840
}
 
8841
 
 
8842
/****************************************************************
 
8843
 _spoolss_EnumPrintProcDataTypes
 
8844
****************************************************************/
 
8845
 
 
8846
WERROR _spoolss_EnumPrintProcDataTypes(struct pipes_struct *p,
 
8847
                                       struct spoolss_EnumPrintProcDataTypes *r)
 
8848
{
 
8849
        WERROR result;
 
8850
 
 
8851
        /* that's an [in out] buffer */
 
8852
 
 
8853
        if (!r->in.buffer && (r->in.offered != 0)) {
 
8854
                return WERR_INVALID_PARAM;
 
8855
        }
 
8856
 
 
8857
        DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
 
8858
 
 
8859
        *r->out.count = 0;
 
8860
        *r->out.needed = 0;
 
8861
        *r->out.info = NULL;
 
8862
 
 
8863
        if (r->in.print_processor_name == NULL ||
 
8864
            !strequal(r->in.print_processor_name, "winprint")) {
 
8865
                return WERR_UNKNOWN_PRINTPROCESSOR;
 
8866
        }
 
8867
 
 
8868
        switch (r->in.level) {
 
8869
        case 1:
 
8870
                result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
 
8871
                                                        r->out.count);
 
8872
                break;
 
8873
        default:
 
8874
                return WERR_UNKNOWN_LEVEL;
 
8875
        }
 
8876
 
 
8877
        *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
 
8878
                                                     spoolss_EnumPrintProcDataTypes,
 
8879
                                                     *r->out.info, r->in.level,
 
8880
                                                     *r->out.count);
 
8881
        *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
 
8882
        *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
 
8883
 
 
8884
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 
8885
}
 
8886
 
 
8887
/****************************************************************************
 
8888
 fill_monitor_1
 
8889
****************************************************************************/
 
8890
 
 
8891
static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
 
8892
                             struct spoolss_MonitorInfo1 *r,
 
8893
                             const char *monitor_name)
 
8894
{
 
8895
        r->monitor_name                 = talloc_strdup(mem_ctx, monitor_name);
 
8896
        W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
 
8897
 
 
8898
        return WERR_OK;
 
8899
}
 
8900
 
 
8901
/****************************************************************************
 
8902
 fill_monitor_2
 
8903
****************************************************************************/
 
8904
 
 
8905
static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
 
8906
                             struct spoolss_MonitorInfo2 *r,
 
8907
                             const char *monitor_name,
 
8908
                             const char *environment,
 
8909
                             const char *dll_name)
 
8910
{
 
8911
        r->monitor_name                 = talloc_strdup(mem_ctx, monitor_name);
 
8912
        W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
 
8913
        r->environment                  = talloc_strdup(mem_ctx, environment);
 
8914
        W_ERROR_HAVE_NO_MEMORY(r->environment);
 
8915
        r->dll_name                     = talloc_strdup(mem_ctx, dll_name);
 
8916
        W_ERROR_HAVE_NO_MEMORY(r->dll_name);
 
8917
 
 
8918
        return WERR_OK;
 
8919
}
 
8920
 
 
8921
/****************************************************************************
 
8922
 enumprintmonitors level 1.
 
8923
****************************************************************************/
 
8924
 
 
8925
static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
 
8926
                                        union spoolss_MonitorInfo **info_p,
 
8927
                                        uint32_t *count)
 
8928
{
 
8929
        union spoolss_MonitorInfo *info;
 
8930
        WERROR result = WERR_OK;
 
8931
 
 
8932
        info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
 
8933
        W_ERROR_HAVE_NO_MEMORY(info);
 
8934
 
 
8935
        *count = 2;
 
8936
 
 
8937
        result = fill_monitor_1(info, &info[0].info1,
 
8938
                                SPL_LOCAL_PORT);
 
8939
        if (!W_ERROR_IS_OK(result)) {
 
8940
                goto out;
 
8941
        }
 
8942
 
 
8943
        result = fill_monitor_1(info, &info[1].info1,
 
8944
                                SPL_TCPIP_PORT);
 
8945
        if (!W_ERROR_IS_OK(result)) {
 
8946
                goto out;
 
8947
        }
 
8948
 
 
8949
out:
 
8950
        if (!W_ERROR_IS_OK(result)) {
 
8951
                TALLOC_FREE(info);
 
8952
                *count = 0;
 
8953
                return result;
 
8954
        }
 
8955
 
 
8956
        *info_p = info;
 
8957
 
 
8958
        return WERR_OK;
 
8959
}
 
8960
 
 
8961
/****************************************************************************
 
8962
 enumprintmonitors level 2.
 
8963
****************************************************************************/
 
8964
 
 
8965
static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
 
8966
                                        union spoolss_MonitorInfo **info_p,
 
8967
                                        uint32_t *count)
 
8968
{
 
8969
        union spoolss_MonitorInfo *info;
 
8970
        WERROR result = WERR_OK;
 
8971
 
 
8972
        info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
 
8973
        W_ERROR_HAVE_NO_MEMORY(info);
 
8974
 
 
8975
        *count = 2;
 
8976
 
 
8977
        result = fill_monitor_2(info, &info[0].info2,
 
8978
                                SPL_LOCAL_PORT,
 
8979
                                "Windows NT X86", /* FIXME */
 
8980
                                "localmon.dll");
 
8981
        if (!W_ERROR_IS_OK(result)) {
 
8982
                goto out;
 
8983
        }
 
8984
 
 
8985
        result = fill_monitor_2(info, &info[1].info2,
 
8986
                                SPL_TCPIP_PORT,
 
8987
                                "Windows NT X86", /* FIXME */
 
8988
                                "tcpmon.dll");
 
8989
        if (!W_ERROR_IS_OK(result)) {
 
8990
                goto out;
 
8991
        }
 
8992
 
 
8993
out:
 
8994
        if (!W_ERROR_IS_OK(result)) {
 
8995
                TALLOC_FREE(info);
 
8996
                *count = 0;
 
8997
                return result;
 
8998
        }
 
8999
 
 
9000
        *info_p = info;
 
9001
 
 
9002
        return WERR_OK;
 
9003
}
 
9004
 
 
9005
/****************************************************************
 
9006
 _spoolss_EnumMonitors
 
9007
****************************************************************/
 
9008
 
 
9009
WERROR _spoolss_EnumMonitors(struct pipes_struct *p,
 
9010
                             struct spoolss_EnumMonitors *r)
 
9011
{
 
9012
        WERROR result;
 
9013
 
 
9014
        /* that's an [in out] buffer */
 
9015
 
 
9016
        if (!r->in.buffer && (r->in.offered != 0)) {
 
9017
                return WERR_INVALID_PARAM;
 
9018
        }
 
9019
 
 
9020
        DEBUG(5,("_spoolss_EnumMonitors\n"));
 
9021
 
 
9022
        /*
 
9023
         * Enumerate the print monitors ...
 
9024
         *
 
9025
         * Just reply with "Local Port", to keep NT happy
 
9026
         * and I can use my nice printer checker.
 
9027
         */
 
9028
 
 
9029
        *r->out.count = 0;
 
9030
        *r->out.needed = 0;
 
9031
        *r->out.info = NULL;
 
9032
 
 
9033
        switch (r->in.level) {
 
9034
        case 1:
 
9035
                result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
 
9036
                                                   r->out.count);
 
9037
                break;
 
9038
        case 2:
 
9039
                result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
 
9040
                                                   r->out.count);
 
9041
                break;
 
9042
        default:
 
9043
                return WERR_UNKNOWN_LEVEL;
 
9044
        }
 
9045
 
 
9046
        if (!W_ERROR_IS_OK(result)) {
 
9047
                return result;
 
9048
        }
 
9049
 
 
9050
        *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
 
9051
                                                     spoolss_EnumMonitors,
 
9052
                                                     *r->out.info, r->in.level,
 
9053
                                                     *r->out.count);
 
9054
        *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
 
9055
        *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
 
9056
 
 
9057
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 
9058
}
 
9059
 
 
9060
/****************************************************************************
 
9061
****************************************************************************/
 
9062
 
 
9063
static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
 
9064
                             const print_queue_struct *queue,
 
9065
                             int count, int snum,
 
9066
                             struct spoolss_PrinterInfo2 *pinfo2,
 
9067
                             uint32_t jobid,
 
9068
                             struct spoolss_JobInfo1 *r)
 
9069
{
 
9070
        int i = 0;
 
9071
        bool found = false;
 
9072
 
 
9073
        for (i=0; i<count; i++) {
 
9074
                if (queue[i].job == (int)jobid) {
 
9075
                        found = true;
 
9076
                        break;
 
9077
                }
 
9078
        }
 
9079
 
 
9080
        if (found == false) {
 
9081
                /* NT treats not found as bad param... yet another bad choice */
 
9082
                return WERR_INVALID_PARAM;
 
9083
        }
 
9084
 
 
9085
        return fill_job_info1(mem_ctx,
 
9086
                              r,
 
9087
                              &queue[i],
 
9088
                              i,
 
9089
                              snum,
 
9090
                              pinfo2);
 
9091
}
 
9092
 
 
9093
/****************************************************************************
 
9094
****************************************************************************/
 
9095
 
 
9096
static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
 
9097
                             const print_queue_struct *queue,
 
9098
                             int count, int snum,
 
9099
                             struct spoolss_PrinterInfo2 *pinfo2,
 
9100
                             uint32_t jobid,
 
9101
                             struct spoolss_JobInfo2 *r)
 
9102
{
 
9103
        int i = 0;
 
9104
        bool found = false;
 
9105
        struct spoolss_DeviceMode *devmode;
 
9106
        WERROR result;
 
9107
 
 
9108
        for (i=0; i<count; i++) {
 
9109
                if (queue[i].job == (int)jobid) {
 
9110
                        found = true;
 
9111
                        break;
 
9112
                }
 
9113
        }
 
9114
 
 
9115
        if (found == false) {
 
9116
                /* NT treats not found as bad param... yet another bad
 
9117
                   choice */
 
9118
                return WERR_INVALID_PARAM;
 
9119
        }
 
9120
 
 
9121
        /*
 
9122
         * if the print job does not have a DEVMODE associated with it,
 
9123
         * just use the one for the printer. A NULL devicemode is not
 
9124
         *  a failure condition
 
9125
         */
 
9126
 
 
9127
        devmode = print_job_devmode(lp_const_servicename(snum), jobid);
 
9128
        if (!devmode) {
 
9129
                result = spoolss_create_default_devmode(mem_ctx,
 
9130
                                                pinfo2->printername,
 
9131
                                                &devmode);
 
9132
                if (!W_ERROR_IS_OK(result)) {
 
9133
                        DEBUG(3, ("Can't proceed w/o a devmode!"));
 
9134
                        return result;
 
9135
                }
 
9136
        }
 
9137
 
 
9138
        return fill_job_info2(mem_ctx,
 
9139
                              r,
 
9140
                              &queue[i],
 
9141
                              i,
 
9142
                              snum,
 
9143
                              pinfo2,
 
9144
                              devmode);
 
9145
}
 
9146
 
 
9147
/****************************************************************
 
9148
 _spoolss_GetJob
 
9149
****************************************************************/
 
9150
 
 
9151
WERROR _spoolss_GetJob(struct pipes_struct *p,
 
9152
                       struct spoolss_GetJob *r)
 
9153
{
 
9154
        WERROR result = WERR_OK;
 
9155
        struct spoolss_PrinterInfo2 *pinfo2 = NULL;
 
9156
        int snum;
 
9157
        int count;
 
9158
        print_queue_struct      *queue = NULL;
 
9159
        print_status_struct prt_status;
 
9160
 
 
9161
        /* that's an [in out] buffer */
 
9162
 
 
9163
        if (!r->in.buffer && (r->in.offered != 0)) {
 
9164
                return WERR_INVALID_PARAM;
 
9165
        }
 
9166
 
 
9167
        DEBUG(5,("_spoolss_GetJob\n"));
 
9168
 
 
9169
        *r->out.needed = 0;
 
9170
 
 
9171
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
 
9172
                return WERR_BADFID;
 
9173
        }
 
9174
 
 
9175
        result = winreg_get_printer_internal(p->mem_ctx,
 
9176
                                    get_session_info_system(),
 
9177
                                    p->msg_ctx,
 
9178
                                    lp_const_servicename(snum),
 
9179
                                    &pinfo2);
 
9180
        if (!W_ERROR_IS_OK(result)) {
 
9181
                return result;
 
9182
        }
 
9183
 
 
9184
        count = print_queue_status(p->msg_ctx, snum, &queue, &prt_status);
 
9185
 
 
9186
        DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
 
9187
                     count, prt_status.status, prt_status.message));
 
9188
 
 
9189
        switch (r->in.level) {
 
9190
        case 1:
 
9191
                result = getjob_level_1(p->mem_ctx,
 
9192
                                        queue, count, snum, pinfo2,
 
9193
                                        r->in.job_id, &r->out.info->info1);
 
9194
                break;
 
9195
        case 2:
 
9196
                result = getjob_level_2(p->mem_ctx,
 
9197
                                        queue, count, snum, pinfo2,
 
9198
                                        r->in.job_id, &r->out.info->info2);
 
9199
                break;
 
9200
        default:
 
9201
                result = WERR_UNKNOWN_LEVEL;
 
9202
                break;
 
9203
        }
 
9204
 
 
9205
        SAFE_FREE(queue);
 
9206
        TALLOC_FREE(pinfo2);
 
9207
 
 
9208
        if (!W_ERROR_IS_OK(result)) {
 
9209
                TALLOC_FREE(r->out.info);
 
9210
                return result;
 
9211
        }
 
9212
 
 
9213
        *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
 
9214
                                                                                   r->in.level);
 
9215
        r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
 
9216
 
 
9217
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 
9218
}
 
9219
 
 
9220
/****************************************************************
 
9221
 _spoolss_GetPrinterDataEx
 
9222
****************************************************************/
 
9223
 
 
9224
WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
 
9225
                                 struct spoolss_GetPrinterDataEx *r)
 
9226
{
 
9227
 
 
9228
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
9229
        const char *printer;
 
9230
        int                     snum = 0;
 
9231
        WERROR result = WERR_OK;
 
9232
        DATA_BLOB blob;
 
9233
        enum winreg_Type val_type = REG_NONE;
 
9234
        uint8_t *val_data = NULL;
 
9235
        uint32_t val_size = 0;
 
9236
        struct dcerpc_binding_handle *b;
 
9237
 
 
9238
        DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
 
9239
 
 
9240
        DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
 
9241
                r->in.key_name, r->in.value_name));
 
9242
 
 
9243
        /* in case of problem, return some default values */
 
9244
 
 
9245
        *r->out.needed  = 0;
 
9246
        *r->out.type    = REG_NONE;
 
9247
 
 
9248
        if (!Printer) {
 
9249
                DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
 
9250
                        OUR_HANDLE(r->in.handle)));
 
9251
                result = WERR_BADFID;
 
9252
                goto done;
 
9253
        }
 
9254
 
 
9255
        /* Is the handle to a printer or to the server? */
 
9256
 
 
9257
        if (Printer->printer_type == SPLHND_SERVER) {
 
9258
 
 
9259
                union spoolss_PrinterData data;
 
9260
 
 
9261
                result = getprinterdata_printer_server(p->mem_ctx,
 
9262
                                                       r->in.value_name,
 
9263
                                                       r->out.type,
 
9264
                                                       &data);
 
9265
                if (!W_ERROR_IS_OK(result)) {
 
9266
                        return result;
 
9267
                }
 
9268
 
 
9269
                result = push_spoolss_PrinterData(p->mem_ctx, &blob,
 
9270
                                                  *r->out.type, &data);
 
9271
                if (!W_ERROR_IS_OK(result)) {
 
9272
                        return result;
 
9273
                }
 
9274
 
 
9275
                *r->out.needed = blob.length;
 
9276
 
 
9277
                if (r->in.offered >= *r->out.needed) {
 
9278
                        memcpy(r->out.data, blob.data, blob.length);
 
9279
                }
 
9280
 
 
9281
                return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
 
9282
        }
 
9283
 
 
9284
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
 
9285
                return WERR_BADFID;
 
9286
        }
 
9287
        printer = lp_const_servicename(snum);
 
9288
 
 
9289
        /* check to see if the keyname is valid */
 
9290
        if (!strlen(r->in.key_name)) {
 
9291
                return WERR_INVALID_PARAM;
 
9292
        }
 
9293
 
 
9294
        result = winreg_printer_binding_handle(p->mem_ctx,
 
9295
                                               get_session_info_system(),
 
9296
                                               p->msg_ctx,
 
9297
                                               &b);
 
9298
        if (!W_ERROR_IS_OK(result)) {
 
9299
                return result;
 
9300
        }
 
9301
 
 
9302
        /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
 
9303
        if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
 
9304
            strequal(r->in.value_name, "ChangeId")) {
 
9305
                *r->out.type = REG_DWORD;
 
9306
                *r->out.needed = 4;
 
9307
                if (r->in.offered >= *r->out.needed) {
 
9308
                        uint32_t changeid = 0;
 
9309
 
 
9310
                        result = winreg_printer_get_changeid(p->mem_ctx, b,
 
9311
                                                             printer,
 
9312
                                                             &changeid);
 
9313
                        if (!W_ERROR_IS_OK(result)) {
 
9314
                                return result;
 
9315
                        }
 
9316
 
 
9317
                        SIVAL(r->out.data, 0, changeid);
 
9318
                        result = WERR_OK;
 
9319
                }
 
9320
                goto done;
 
9321
        }
 
9322
 
 
9323
        result = winreg_get_printer_dataex(p->mem_ctx, b,
 
9324
                                           printer,
 
9325
                                           r->in.key_name,
 
9326
                                           r->in.value_name,
 
9327
                                           &val_type,
 
9328
                                           &val_data,
 
9329
                                           &val_size);
 
9330
        if (!W_ERROR_IS_OK(result)) {
 
9331
                return result;
 
9332
        }
 
9333
 
 
9334
        *r->out.needed = val_size;
 
9335
        *r->out.type = val_type;
 
9336
 
 
9337
        if (r->in.offered >= *r->out.needed) {
 
9338
                memcpy(r->out.data, val_data, val_size);
 
9339
        }
 
9340
 
 
9341
 done:
 
9342
        /* retain type when returning WERR_MORE_DATA */
 
9343
        r->out.data     = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
 
9344
 
 
9345
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
 
9346
}
 
9347
 
 
9348
/****************************************************************
 
9349
 _spoolss_SetPrinterDataEx
 
9350
****************************************************************/
 
9351
 
 
9352
WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
 
9353
                                 struct spoolss_SetPrinterDataEx *r)
 
9354
{
 
9355
        struct spoolss_PrinterInfo2 *pinfo2 = NULL;
 
9356
        int                     snum = 0;
 
9357
        WERROR                  result = WERR_OK;
 
9358
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
9359
        char                    *oid_string;
 
9360
        struct dcerpc_binding_handle *b;
 
9361
 
 
9362
        DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
 
9363
 
 
9364
        /* From MSDN documentation of SetPrinterDataEx: pass request to
 
9365
           SetPrinterData if key is "PrinterDriverData" */
 
9366
 
 
9367
        if (!Printer) {
 
9368
                DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
 
9369
                        OUR_HANDLE(r->in.handle)));
 
9370
                return WERR_BADFID;
 
9371
        }
 
9372
 
 
9373
        if (Printer->printer_type == SPLHND_SERVER) {
 
9374
                DEBUG(10,("_spoolss_SetPrinterDataEx: "
 
9375
                        "Not implemented for server handles yet\n"));
 
9376
                return WERR_INVALID_PARAM;
 
9377
        }
 
9378
 
 
9379
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
 
9380
                return WERR_BADFID;
 
9381
        }
 
9382
 
 
9383
        /*
 
9384
         * Access check : NT returns "access denied" if you make a
 
9385
         * SetPrinterData call without the necessary privildge.
 
9386
         * we were originally returning OK if nothing changed
 
9387
         * which made Win2k issue **a lot** of SetPrinterData
 
9388
         * when connecting to a printer  --jerry
 
9389
         */
 
9390
 
 
9391
        if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
 
9392
                DEBUG(3, ("_spoolss_SetPrinterDataEx: "
 
9393
                        "change denied by handle access permissions\n"));
 
9394
                return WERR_ACCESS_DENIED;
 
9395
        }
 
9396
 
 
9397
        result = winreg_printer_binding_handle(p->mem_ctx,
 
9398
                                               get_session_info_system(),
 
9399
                                               p->msg_ctx,
 
9400
                                               &b);
 
9401
        if (!W_ERROR_IS_OK(result)) {
 
9402
                return result;
 
9403
        }
 
9404
 
 
9405
        result = winreg_get_printer(Printer, b,
 
9406
                                    lp_servicename(snum),
 
9407
                                    &pinfo2);
 
9408
        if (!W_ERROR_IS_OK(result)) {
 
9409
                return result;
 
9410
        }
 
9411
 
 
9412
        /* check for OID in valuename */
 
9413
 
 
9414
        oid_string = strchr(r->in.value_name, ',');
 
9415
        if (oid_string) {
 
9416
                *oid_string = '\0';
 
9417
                oid_string++;
 
9418
        }
 
9419
 
 
9420
        /* save the registry data */
 
9421
 
 
9422
        result = winreg_set_printer_dataex(p->mem_ctx, b,
 
9423
                                           pinfo2->sharename,
 
9424
                                           r->in.key_name,
 
9425
                                           r->in.value_name,
 
9426
                                           r->in.type,
 
9427
                                           r->in.data,
 
9428
                                           r->in.offered);
 
9429
 
 
9430
        if (W_ERROR_IS_OK(result)) {
 
9431
                /* save the OID if one was specified */
 
9432
                if (oid_string) {
 
9433
                        char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
 
9434
                                r->in.key_name, SPOOL_OID_KEY);
 
9435
                        if (!str) {
 
9436
                                result = WERR_NOMEM;
 
9437
                                goto done;
 
9438
                        }
 
9439
 
 
9440
                        /*
 
9441
                         * I'm not checking the status here on purpose.  Don't know
 
9442
                         * if this is right, but I'm returning the status from the
 
9443
                         * previous set_printer_dataex() call.  I have no idea if
 
9444
                         * this is right.    --jerry
 
9445
                         */
 
9446
                        winreg_set_printer_dataex(p->mem_ctx, b,
 
9447
                                                  pinfo2->sharename,
 
9448
                                                  str,
 
9449
                                                  r->in.value_name,
 
9450
                                                  REG_SZ,
 
9451
                                                  (uint8_t *) oid_string,
 
9452
                                                  strlen(oid_string) + 1);
 
9453
                }
 
9454
 
 
9455
                result = winreg_printer_update_changeid(p->mem_ctx, b,
 
9456
                                                        lp_const_servicename(snum));
 
9457
 
 
9458
        }
 
9459
 
 
9460
done:
 
9461
        talloc_free(pinfo2);
 
9462
        return result;
 
9463
}
 
9464
 
 
9465
/****************************************************************
 
9466
 _spoolss_DeletePrinterDataEx
 
9467
****************************************************************/
 
9468
 
 
9469
WERROR _spoolss_DeletePrinterDataEx(struct pipes_struct *p,
 
9470
                                    struct spoolss_DeletePrinterDataEx *r)
 
9471
{
 
9472
        const char *printer;
 
9473
        int             snum=0;
 
9474
        WERROR          status = WERR_OK;
 
9475
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
9476
 
 
9477
        DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
 
9478
 
 
9479
        if (!Printer) {
 
9480
                DEBUG(2,("_spoolss_DeletePrinterDataEx: "
 
9481
                        "Invalid handle (%s:%u:%u).\n",
 
9482
                        OUR_HANDLE(r->in.handle)));
 
9483
                return WERR_BADFID;
 
9484
        }
 
9485
 
 
9486
        if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
 
9487
                DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
 
9488
                        "printer properties change denied by handle\n"));
 
9489
                return WERR_ACCESS_DENIED;
 
9490
        }
 
9491
 
 
9492
        if (!r->in.value_name || !r->in.key_name) {
 
9493
                return WERR_NOMEM;
 
9494
        }
 
9495
 
 
9496
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
 
9497
                return WERR_BADFID;
 
9498
        }
 
9499
        printer = lp_const_servicename(snum);
 
9500
 
 
9501
        status = winreg_delete_printer_dataex_internal(p->mem_ctx,
 
9502
                                              get_session_info_system(),
 
9503
                                              p->msg_ctx,
 
9504
                                              printer,
 
9505
                                              r->in.key_name,
 
9506
                                              r->in.value_name);
 
9507
        if (W_ERROR_IS_OK(status)) {
 
9508
                status = winreg_printer_update_changeid_internal(p->mem_ctx,
 
9509
                                                        get_session_info_system(),
 
9510
                                                        p->msg_ctx,
 
9511
                                                        printer);
 
9512
        }
 
9513
 
 
9514
        return status;
 
9515
}
 
9516
 
 
9517
/****************************************************************
 
9518
 _spoolss_EnumPrinterKey
 
9519
****************************************************************/
 
9520
 
 
9521
WERROR _spoolss_EnumPrinterKey(struct pipes_struct *p,
 
9522
                               struct spoolss_EnumPrinterKey *r)
 
9523
{
 
9524
        uint32_t        num_keys;
 
9525
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
9526
        int             snum = 0;
 
9527
        WERROR          result = WERR_BADFILE;
 
9528
        const char **array = NULL;
 
9529
        DATA_BLOB blob;
 
9530
 
 
9531
        DEBUG(4,("_spoolss_EnumPrinterKey\n"));
 
9532
 
 
9533
        if (!Printer) {
 
9534
                DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
 
9535
                        OUR_HANDLE(r->in.handle)));
 
9536
                return WERR_BADFID;
 
9537
        }
 
9538
 
 
9539
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
 
9540
                return WERR_BADFID;
 
9541
        }
 
9542
 
 
9543
        result = winreg_enum_printer_key_internal(p->mem_ctx,
 
9544
                                         get_session_info_system(),
 
9545
                                         p->msg_ctx,
 
9546
                                         lp_const_servicename(snum),
 
9547
                                         r->in.key_name,
 
9548
                                         &num_keys,
 
9549
                                         &array);
 
9550
        if (!W_ERROR_IS_OK(result)) {
 
9551
                goto done;
 
9552
        }
 
9553
 
 
9554
        if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
 
9555
                result = WERR_NOMEM;
 
9556
                goto done;
 
9557
        }
 
9558
 
 
9559
        *r->out._ndr_size = r->in.offered / 2;
 
9560
        *r->out.needed = blob.length;
 
9561
 
 
9562
        if (r->in.offered < *r->out.needed) {
 
9563
                result = WERR_MORE_DATA;
 
9564
        } else {
 
9565
                result = WERR_OK;
 
9566
                r->out.key_buffer->string_array = array;
 
9567
        }
 
9568
 
 
9569
 done:
 
9570
        if (!W_ERROR_IS_OK(result)) {
 
9571
                TALLOC_FREE(array);
 
9572
                if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
 
9573
                        *r->out.needed = 0;
 
9574
                }
 
9575
        }
 
9576
 
 
9577
        return result;
 
9578
}
 
9579
 
 
9580
/****************************************************************
 
9581
 _spoolss_DeletePrinterKey
 
9582
****************************************************************/
 
9583
 
 
9584
WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
 
9585
                                 struct spoolss_DeletePrinterKey *r)
 
9586
{
 
9587
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
9588
        int                     snum=0;
 
9589
        WERROR                  status;
 
9590
        const char *printer;
 
9591
        struct dcerpc_binding_handle *b;
 
9592
 
 
9593
        DEBUG(5,("_spoolss_DeletePrinterKey\n"));
 
9594
 
 
9595
        if (!Printer) {
 
9596
                DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
 
9597
                        OUR_HANDLE(r->in.handle)));
 
9598
                return WERR_BADFID;
 
9599
        }
 
9600
 
 
9601
        /* if keyname == NULL, return error */
 
9602
        if ( !r->in.key_name )
 
9603
                return WERR_INVALID_PARAM;
 
9604
 
 
9605
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
 
9606
                return WERR_BADFID;
 
9607
        }
 
9608
 
 
9609
        if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
 
9610
                DEBUG(3, ("_spoolss_DeletePrinterKey: "
 
9611
                        "printer properties change denied by handle\n"));
 
9612
                return WERR_ACCESS_DENIED;
 
9613
        }
 
9614
 
 
9615
        printer = lp_const_servicename(snum);
 
9616
 
 
9617
        status = winreg_printer_binding_handle(p->mem_ctx,
 
9618
                                               get_session_info_system(),
 
9619
                                               p->msg_ctx,
 
9620
                                               &b);
 
9621
        if (!W_ERROR_IS_OK(status)) {
 
9622
                return status;
 
9623
        }
 
9624
 
 
9625
        /* delete the key and all subkeys */
 
9626
        status = winreg_delete_printer_key(p->mem_ctx, b,
 
9627
                                           printer,
 
9628
                                           r->in.key_name);
 
9629
        if (W_ERROR_IS_OK(status)) {
 
9630
                status = winreg_printer_update_changeid(p->mem_ctx, b,
 
9631
                                                        printer);
 
9632
        }
 
9633
 
 
9634
        return status;
 
9635
}
 
9636
 
 
9637
/****************************************************************
 
9638
 _spoolss_EnumPrinterDataEx
 
9639
****************************************************************/
 
9640
 
 
9641
WERROR _spoolss_EnumPrinterDataEx(struct pipes_struct *p,
 
9642
                                  struct spoolss_EnumPrinterDataEx *r)
 
9643
{
 
9644
        uint32_t        count = 0;
 
9645
        struct spoolss_PrinterEnumValues *info = NULL;
 
9646
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
9647
        int             snum;
 
9648
        WERROR          result;
 
9649
 
 
9650
        DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
 
9651
 
 
9652
        *r->out.count = 0;
 
9653
        *r->out.needed = 0;
 
9654
        *r->out.info = NULL;
 
9655
 
 
9656
        if (!Printer) {
 
9657
                DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
 
9658
                        OUR_HANDLE(r->in.handle)));
 
9659
                return WERR_BADFID;
 
9660
        }
 
9661
 
 
9662
        /*
 
9663
         * first check for a keyname of NULL or "".  Win2k seems to send
 
9664
         * this a lot and we should send back WERR_INVALID_PARAM
 
9665
         * no need to spend time looking up the printer in this case.
 
9666
         * --jerry
 
9667
         */
 
9668
 
 
9669
        if (!strlen(r->in.key_name)) {
 
9670
                result = WERR_INVALID_PARAM;
 
9671
                goto done;
 
9672
        }
 
9673
 
 
9674
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
 
9675
                return WERR_BADFID;
 
9676
        }
 
9677
 
 
9678
        /* now look for a match on the key name */
 
9679
        result = winreg_enum_printer_dataex_internal(p->mem_ctx,
 
9680
                                            get_session_info_system(),
 
9681
                                            p->msg_ctx,
 
9682
                                            lp_const_servicename(snum),
 
9683
                                            r->in.key_name,
 
9684
                                            &count,
 
9685
                                            &info);
 
9686
        if (!W_ERROR_IS_OK(result)) {
 
9687
                goto done;
 
9688
        }
 
9689
 
 
9690
#if 0 /* FIXME - gd */
 
9691
        /* housekeeping information in the reply */
 
9692
 
 
9693
        /* Fix from Martin Zielinski <mz@seh.de> - ensure
 
9694
         * the hand marshalled container size is a multiple
 
9695
         * of 4 bytes for RPC alignment.
 
9696
         */
 
9697
 
 
9698
        if (needed % 4) {
 
9699
                needed += 4-(needed % 4);
 
9700
        }
 
9701
#endif
 
9702
        *r->out.count   = count;
 
9703
        *r->out.info    = info;
 
9704
 
 
9705
 done:
 
9706
        if (!W_ERROR_IS_OK(result)) {
 
9707
                return result;
 
9708
        }
 
9709
 
 
9710
        *r->out.needed  = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
 
9711
                                               spoolss_EnumPrinterDataEx,
 
9712
                                               *r->out.info,
 
9713
                                               *r->out.count);
 
9714
        *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
 
9715
        *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
 
9716
 
 
9717
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
 
9718
}
 
9719
 
 
9720
/****************************************************************************
 
9721
****************************************************************************/
 
9722
 
 
9723
static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
 
9724
                                                 const char *servername,
 
9725
                                                 const char *environment,
 
9726
                                                 struct spoolss_PrintProcessorDirectoryInfo1 *r)
 
9727
{
 
9728
        WERROR werr;
 
9729
        char *path = NULL;
 
9730
 
 
9731
        werr = compose_spoolss_server_path(mem_ctx,
 
9732
                                           servername,
 
9733
                                           environment,
 
9734
                                           SPOOLSS_PRTPROCS_PATH,
 
9735
                                           &path);
 
9736
        if (!W_ERROR_IS_OK(werr)) {
 
9737
                return werr;
 
9738
        }
 
9739
 
 
9740
        DEBUG(4,("print processor directory: [%s]\n", path));
 
9741
 
 
9742
        r->directory_name = path;
 
9743
 
 
9744
        return WERR_OK;
 
9745
}
 
9746
 
 
9747
/****************************************************************
 
9748
 _spoolss_GetPrintProcessorDirectory
 
9749
****************************************************************/
 
9750
 
 
9751
WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p,
 
9752
                                           struct spoolss_GetPrintProcessorDirectory *r)
 
9753
{
 
9754
        WERROR result;
 
9755
        char *prnproc_share = NULL;
 
9756
        bool prnproc_share_exists = false;
 
9757
        int snum;
 
9758
 
 
9759
        /* that's an [in out] buffer */
 
9760
 
 
9761
        if (!r->in.buffer && (r->in.offered != 0)) {
 
9762
                return WERR_INVALID_PARAM;
 
9763
        }
 
9764
 
 
9765
        DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
 
9766
                r->in.level));
 
9767
 
 
9768
        *r->out.needed = 0;
 
9769
 
 
9770
        /* r->in.level is ignored */
 
9771
 
 
9772
        /* We always should reply with a local print processor directory so that
 
9773
         * users are not forced to have a [prnproc$] share on the Samba spoolss
 
9774
         * server, if users decide to do so, lets announce it though - Guenther */
 
9775
 
 
9776
        snum = find_service(talloc_tos(), "prnproc$", &prnproc_share);
 
9777
        if (!prnproc_share) {
 
9778
                return WERR_NOMEM;
 
9779
        }
 
9780
        if (snum != -1) {
 
9781
                prnproc_share_exists = true;
 
9782
        }
 
9783
 
 
9784
        result = getprintprocessordirectory_level_1(p->mem_ctx,
 
9785
                                                    prnproc_share_exists ? r->in.server : NULL,
 
9786
                                                    r->in.environment,
 
9787
                                                    &r->out.info->info1);
 
9788
        if (!W_ERROR_IS_OK(result)) {
 
9789
                TALLOC_FREE(r->out.info);
 
9790
                return result;
 
9791
        }
 
9792
 
 
9793
        *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
 
9794
                                                                                   r->out.info, r->in.level);
 
9795
        r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
 
9796
 
 
9797
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
 
9798
}
 
9799
 
 
9800
/*******************************************************************
 
9801
 ********************************************************************/
 
9802
 
 
9803
static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
 
9804
                               const char *dllname)
 
9805
{
 
9806
        enum ndr_err_code ndr_err;
 
9807
        struct spoolss_MonitorUi ui;
 
9808
 
 
9809
        ui.dll_name = dllname;
 
9810
 
 
9811
        ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ui,
 
9812
                       (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
 
9813
        if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
 
9814
                NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
 
9815
        }
 
9816
        return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
 
9817
}
 
9818
 
 
9819
/*******************************************************************
 
9820
 Streams the monitor UI DLL name in UNICODE
 
9821
*******************************************************************/
 
9822
 
 
9823
static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
 
9824
                               struct security_token *token, DATA_BLOB *in,
 
9825
                               DATA_BLOB *out, uint32_t *needed)
 
9826
{
 
9827
        const char *dllname = "tcpmonui.dll";
 
9828
 
 
9829
        *needed = (strlen(dllname)+1) * 2;
 
9830
 
 
9831
        if (out->length < *needed) {
 
9832
                return WERR_INSUFFICIENT_BUFFER;
 
9833
        }
 
9834
 
 
9835
        if (!push_monitorui_buf(mem_ctx, out, dllname)) {
 
9836
                return WERR_NOMEM;
 
9837
        }
 
9838
 
 
9839
        return WERR_OK;
 
9840
}
 
9841
 
 
9842
/*******************************************************************
 
9843
 ********************************************************************/
 
9844
 
 
9845
static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
 
9846
                             struct spoolss_PortData1 *port1,
 
9847
                             const DATA_BLOB *buf)
 
9848
{
 
9849
        enum ndr_err_code ndr_err;
 
9850
        ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port1,
 
9851
                       (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
 
9852
        if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
 
9853
                NDR_PRINT_DEBUG(spoolss_PortData1, port1);
 
9854
        }
 
9855
        return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
 
9856
}
 
9857
 
 
9858
/*******************************************************************
 
9859
 ********************************************************************/
 
9860
 
 
9861
static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
 
9862
                             struct spoolss_PortData2 *port2,
 
9863
                             const DATA_BLOB *buf)
 
9864
{
 
9865
        enum ndr_err_code ndr_err;
 
9866
        ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port2,
 
9867
                       (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
 
9868
        if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
 
9869
                NDR_PRINT_DEBUG(spoolss_PortData2, port2);
 
9870
        }
 
9871
        return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
 
9872
}
 
9873
 
 
9874
/*******************************************************************
 
9875
 Create a new TCP/IP port
 
9876
*******************************************************************/
 
9877
 
 
9878
static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
 
9879
                             struct security_token *token, DATA_BLOB *in,
 
9880
                             DATA_BLOB *out, uint32_t *needed)
 
9881
{
 
9882
        struct spoolss_PortData1 port1;
 
9883
        struct spoolss_PortData2 port2;
 
9884
        char *device_uri = NULL;
 
9885
        uint32_t version;
 
9886
 
 
9887
        const char *portname;
 
9888
        const char *hostaddress;
 
9889
        const char *queue;
 
9890
        uint32_t port_number;
 
9891
        uint32_t protocol;
 
9892
 
 
9893
        /* peek for spoolss_PortData version */
 
9894
 
 
9895
        if (!in || (in->length < (128 + 4))) {
 
9896
                return WERR_GENERAL_FAILURE;
 
9897
        }
 
9898
 
 
9899
        version = IVAL(in->data, 128);
 
9900
 
 
9901
        switch (version) {
 
9902
                case 1:
 
9903
                        ZERO_STRUCT(port1);
 
9904
 
 
9905
                        if (!pull_port_data_1(mem_ctx, &port1, in)) {
 
9906
                                return WERR_NOMEM;
 
9907
                        }
 
9908
 
 
9909
                        portname        = port1.portname;
 
9910
                        hostaddress     = port1.hostaddress;
 
9911
                        queue           = port1.queue;
 
9912
                        protocol        = port1.protocol;
 
9913
                        port_number     = port1.port_number;
 
9914
 
 
9915
                        break;
 
9916
                case 2:
 
9917
                        ZERO_STRUCT(port2);
 
9918
 
 
9919
                        if (!pull_port_data_2(mem_ctx, &port2, in)) {
 
9920
                                return WERR_NOMEM;
 
9921
                        }
 
9922
 
 
9923
                        portname        = port2.portname;
 
9924
                        hostaddress     = port2.hostaddress;
 
9925
                        queue           = port2.queue;
 
9926
                        protocol        = port2.protocol;
 
9927
                        port_number     = port2.port_number;
 
9928
 
 
9929
                        break;
 
9930
                default:
 
9931
                        DEBUG(1,("xcvtcp_addport: "
 
9932
                                "unknown version of port_data: %d\n", version));
 
9933
                        return WERR_UNKNOWN_PORT;
 
9934
        }
 
9935
 
 
9936
        /* create the device URI and call the add_port_hook() */
 
9937
 
 
9938
        switch (protocol) {
 
9939
        case PROTOCOL_RAWTCP_TYPE:
 
9940
                device_uri = talloc_asprintf(mem_ctx,
 
9941
                                "socket://%s:%d/", hostaddress,
 
9942
                                port_number);
 
9943
                break;
 
9944
 
 
9945
        case PROTOCOL_LPR_TYPE:
 
9946
                device_uri = talloc_asprintf(mem_ctx,
 
9947
                        "lpr://%s/%s", hostaddress, queue );
 
9948
                break;
 
9949
 
 
9950
        default:
 
9951
                return WERR_UNKNOWN_PORT;
 
9952
        }
 
9953
 
 
9954
        if (!device_uri) {
 
9955
                return WERR_NOMEM;
 
9956
        }
 
9957
 
 
9958
        return add_port_hook(mem_ctx, token, portname, device_uri);
 
9959
}
 
9960
 
 
9961
/*******************************************************************
 
9962
*******************************************************************/
 
9963
 
 
9964
struct xcv_api_table xcvtcp_cmds[] = {
 
9965
        { "MonitorUI",  xcvtcp_monitorui },
 
9966
        { "AddPort",    xcvtcp_addport},
 
9967
        { NULL,         NULL }
 
9968
};
 
9969
 
 
9970
static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
 
9971
                                     struct security_token *token, const char *command,
 
9972
                                     DATA_BLOB *inbuf,
 
9973
                                     DATA_BLOB *outbuf,
 
9974
                                     uint32_t *needed )
 
9975
{
 
9976
        int i;
 
9977
 
 
9978
        DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
 
9979
 
 
9980
        for ( i=0; xcvtcp_cmds[i].name; i++ ) {
 
9981
                if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
 
9982
                        return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
 
9983
        }
 
9984
 
 
9985
        return WERR_BADFUNC;
 
9986
}
 
9987
 
 
9988
/*******************************************************************
 
9989
*******************************************************************/
 
9990
#if 0   /* don't support management using the "Local Port" monitor */
 
9991
 
 
9992
static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
 
9993
                                 struct security_token *token, DATA_BLOB *in,
 
9994
                                 DATA_BLOB *out, uint32_t *needed)
 
9995
{
 
9996
        const char *dllname = "localui.dll";
 
9997
 
 
9998
        *needed = (strlen(dllname)+1) * 2;
 
9999
 
 
10000
        if (out->length < *needed) {
 
10001
                return WERR_INSUFFICIENT_BUFFER;
 
10002
        }
 
10003
 
 
10004
        if (!push_monitorui_buf(mem_ctx, out, dllname)) {
 
10005
                return WERR_NOMEM;
 
10006
        }
 
10007
 
 
10008
        return WERR_OK;
 
10009
}
 
10010
 
 
10011
/*******************************************************************
 
10012
*******************************************************************/
 
10013
 
 
10014
struct xcv_api_table xcvlocal_cmds[] = {
 
10015
        { "MonitorUI",  xcvlocal_monitorui },
 
10016
        { NULL,         NULL }
 
10017
};
 
10018
#else
 
10019
struct xcv_api_table xcvlocal_cmds[] = {
 
10020
        { NULL,         NULL }
 
10021
};
 
10022
#endif
 
10023
 
 
10024
 
 
10025
 
 
10026
/*******************************************************************
 
10027
*******************************************************************/
 
10028
 
 
10029
static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
 
10030
                                       struct security_token *token, const char *command,
 
10031
                                       DATA_BLOB *inbuf, DATA_BLOB *outbuf,
 
10032
                                       uint32_t *needed)
 
10033
{
 
10034
        int i;
 
10035
 
 
10036
        DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
 
10037
 
 
10038
        for ( i=0; xcvlocal_cmds[i].name; i++ ) {
 
10039
                if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
 
10040
                        return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
 
10041
        }
 
10042
        return WERR_BADFUNC;
 
10043
}
 
10044
 
 
10045
/****************************************************************
 
10046
 _spoolss_XcvData
 
10047
****************************************************************/
 
10048
 
 
10049
WERROR _spoolss_XcvData(struct pipes_struct *p,
 
10050
                        struct spoolss_XcvData *r)
 
10051
{
 
10052
        struct printer_handle *Printer = find_printer_index_by_hnd(p, r->in.handle);
 
10053
        DATA_BLOB out_data = data_blob_null;
 
10054
        WERROR werror;
 
10055
 
 
10056
        if (!Printer) {
 
10057
                DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
 
10058
                        OUR_HANDLE(r->in.handle)));
 
10059
                return WERR_BADFID;
 
10060
        }
 
10061
 
 
10062
        /* Has to be a handle to the TCP/IP port monitor */
 
10063
 
 
10064
        if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
 
10065
                DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
 
10066
                return WERR_BADFID;
 
10067
        }
 
10068
 
 
10069
        /* requires administrative access to the server */
 
10070
 
 
10071
        if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
 
10072
                DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
 
10073
                return WERR_ACCESS_DENIED;
 
10074
        }
 
10075
 
 
10076
        /* Allocate the outgoing buffer */
 
10077
 
 
10078
        if (r->in.out_data_size) {
 
10079
                out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
 
10080
                if (out_data.data == NULL) {
 
10081
                        return WERR_NOMEM;
 
10082
                }
 
10083
        }
 
10084
 
 
10085
        switch ( Printer->printer_type ) {
 
10086
        case SPLHND_PORTMON_TCP:
 
10087
                werror = process_xcvtcp_command(p->mem_ctx,
 
10088
                                                p->session_info->security_token,
 
10089
                                                r->in.function_name,
 
10090
                                                &r->in.in_data, &out_data,
 
10091
                                                r->out.needed);
 
10092
                break;
 
10093
        case SPLHND_PORTMON_LOCAL:
 
10094
                werror = process_xcvlocal_command(p->mem_ctx,
 
10095
                                                  p->session_info->security_token,
 
10096
                                                  r->in.function_name,
 
10097
                                                  &r->in.in_data, &out_data,
 
10098
                                                  r->out.needed);
 
10099
                break;
 
10100
        default:
 
10101
                werror = WERR_INVALID_PRINT_MONITOR;
 
10102
        }
 
10103
 
 
10104
        if (!W_ERROR_IS_OK(werror)) {
 
10105
                return werror;
 
10106
        }
 
10107
 
 
10108
        *r->out.status_code = 0;
 
10109
 
 
10110
        if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
 
10111
                memcpy(r->out.out_data, out_data.data,
 
10112
                        MIN(r->in.out_data_size, out_data.length));
 
10113
        }
 
10114
 
 
10115
        return WERR_OK;
 
10116
}
 
10117
 
 
10118
/****************************************************************
 
10119
 _spoolss_AddPrintProcessor
 
10120
****************************************************************/
 
10121
 
 
10122
WERROR _spoolss_AddPrintProcessor(struct pipes_struct *p,
 
10123
                                  struct spoolss_AddPrintProcessor *r)
 
10124
{
 
10125
        /* for now, just indicate success and ignore the add.  We'll
 
10126
           automatically set the winprint processor for printer
 
10127
           entries later.  Used to debug the LexMark Optra S 1855 PCL
 
10128
           driver --jerry */
 
10129
 
 
10130
        return WERR_OK;
 
10131
}
 
10132
 
 
10133
/****************************************************************
 
10134
 _spoolss_AddPort
 
10135
****************************************************************/
 
10136
 
 
10137
WERROR _spoolss_AddPort(struct pipes_struct *p,
 
10138
                        struct spoolss_AddPort *r)
 
10139
{
 
10140
        /* do what w2k3 does */
 
10141
 
 
10142
        return WERR_NOT_SUPPORTED;
 
10143
}
 
10144
 
 
10145
/****************************************************************
 
10146
 _spoolss_GetPrinterDriver
 
10147
****************************************************************/
 
10148
 
 
10149
WERROR _spoolss_GetPrinterDriver(struct pipes_struct *p,
 
10150
                                 struct spoolss_GetPrinterDriver *r)
 
10151
{
 
10152
        p->rng_fault_state = true;
 
10153
        return WERR_NOT_SUPPORTED;
 
10154
}
 
10155
 
 
10156
/****************************************************************
 
10157
 _spoolss_ReadPrinter
 
10158
****************************************************************/
 
10159
 
 
10160
WERROR _spoolss_ReadPrinter(struct pipes_struct *p,
 
10161
                            struct spoolss_ReadPrinter *r)
 
10162
{
 
10163
        p->rng_fault_state = true;
 
10164
        return WERR_NOT_SUPPORTED;
 
10165
}
 
10166
 
 
10167
/****************************************************************
 
10168
 _spoolss_WaitForPrinterChange
 
10169
****************************************************************/
 
10170
 
 
10171
WERROR _spoolss_WaitForPrinterChange(struct pipes_struct *p,
 
10172
                                     struct spoolss_WaitForPrinterChange *r)
 
10173
{
 
10174
        p->rng_fault_state = true;
 
10175
        return WERR_NOT_SUPPORTED;
 
10176
}
 
10177
 
 
10178
/****************************************************************
 
10179
 _spoolss_ConfigurePort
 
10180
****************************************************************/
 
10181
 
 
10182
WERROR _spoolss_ConfigurePort(struct pipes_struct *p,
 
10183
                              struct spoolss_ConfigurePort *r)
 
10184
{
 
10185
        p->rng_fault_state = true;
 
10186
        return WERR_NOT_SUPPORTED;
 
10187
}
 
10188
 
 
10189
/****************************************************************
 
10190
 _spoolss_DeletePort
 
10191
****************************************************************/
 
10192
 
 
10193
WERROR _spoolss_DeletePort(struct pipes_struct *p,
 
10194
                           struct spoolss_DeletePort *r)
 
10195
{
 
10196
        p->rng_fault_state = true;
 
10197
        return WERR_NOT_SUPPORTED;
 
10198
}
 
10199
 
 
10200
/****************************************************************
 
10201
 _spoolss_CreatePrinterIC
 
10202
****************************************************************/
 
10203
 
 
10204
WERROR _spoolss_CreatePrinterIC(struct pipes_struct *p,
 
10205
                                struct spoolss_CreatePrinterIC *r)
 
10206
{
 
10207
        p->rng_fault_state = true;
 
10208
        return WERR_NOT_SUPPORTED;
 
10209
}
 
10210
 
 
10211
/****************************************************************
 
10212
 _spoolss_PlayGDIScriptOnPrinterIC
 
10213
****************************************************************/
 
10214
 
 
10215
WERROR _spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct *p,
 
10216
                                         struct spoolss_PlayGDIScriptOnPrinterIC *r)
 
10217
{
 
10218
        p->rng_fault_state = true;
 
10219
        return WERR_NOT_SUPPORTED;
 
10220
}
 
10221
 
 
10222
/****************************************************************
 
10223
 _spoolss_DeletePrinterIC
 
10224
****************************************************************/
 
10225
 
 
10226
WERROR _spoolss_DeletePrinterIC(struct pipes_struct *p,
 
10227
                                struct spoolss_DeletePrinterIC *r)
 
10228
{
 
10229
        p->rng_fault_state = true;
 
10230
        return WERR_NOT_SUPPORTED;
 
10231
}
 
10232
 
 
10233
/****************************************************************
 
10234
 _spoolss_AddPrinterConnection
 
10235
****************************************************************/
 
10236
 
 
10237
WERROR _spoolss_AddPrinterConnection(struct pipes_struct *p,
 
10238
                                     struct spoolss_AddPrinterConnection *r)
 
10239
{
 
10240
        p->rng_fault_state = true;
 
10241
        return WERR_NOT_SUPPORTED;
 
10242
}
 
10243
 
 
10244
/****************************************************************
 
10245
 _spoolss_DeletePrinterConnection
 
10246
****************************************************************/
 
10247
 
 
10248
WERROR _spoolss_DeletePrinterConnection(struct pipes_struct *p,
 
10249
                                        struct spoolss_DeletePrinterConnection *r)
 
10250
{
 
10251
        p->rng_fault_state = true;
 
10252
        return WERR_NOT_SUPPORTED;
 
10253
}
 
10254
 
 
10255
/****************************************************************
 
10256
 _spoolss_PrinterMessageBox
 
10257
****************************************************************/
 
10258
 
 
10259
WERROR _spoolss_PrinterMessageBox(struct pipes_struct *p,
 
10260
                                  struct spoolss_PrinterMessageBox *r)
 
10261
{
 
10262
        p->rng_fault_state = true;
 
10263
        return WERR_NOT_SUPPORTED;
 
10264
}
 
10265
 
 
10266
/****************************************************************
 
10267
 _spoolss_AddMonitor
 
10268
****************************************************************/
 
10269
 
 
10270
WERROR _spoolss_AddMonitor(struct pipes_struct *p,
 
10271
                           struct spoolss_AddMonitor *r)
 
10272
{
 
10273
        p->rng_fault_state = true;
 
10274
        return WERR_NOT_SUPPORTED;
 
10275
}
 
10276
 
 
10277
/****************************************************************
 
10278
 _spoolss_DeleteMonitor
 
10279
****************************************************************/
 
10280
 
 
10281
WERROR _spoolss_DeleteMonitor(struct pipes_struct *p,
 
10282
                              struct spoolss_DeleteMonitor *r)
 
10283
{
 
10284
        p->rng_fault_state = true;
 
10285
        return WERR_NOT_SUPPORTED;
 
10286
}
 
10287
 
 
10288
/****************************************************************
 
10289
 _spoolss_DeletePrintProcessor
 
10290
****************************************************************/
 
10291
 
 
10292
WERROR _spoolss_DeletePrintProcessor(struct pipes_struct *p,
 
10293
                                     struct spoolss_DeletePrintProcessor *r)
 
10294
{
 
10295
        p->rng_fault_state = true;
 
10296
        return WERR_NOT_SUPPORTED;
 
10297
}
 
10298
 
 
10299
/****************************************************************
 
10300
 _spoolss_AddPrintProvidor
 
10301
****************************************************************/
 
10302
 
 
10303
WERROR _spoolss_AddPrintProvidor(struct pipes_struct *p,
 
10304
                                 struct spoolss_AddPrintProvidor *r)
 
10305
{
 
10306
        p->rng_fault_state = true;
 
10307
        return WERR_NOT_SUPPORTED;
 
10308
}
 
10309
 
 
10310
/****************************************************************
 
10311
 _spoolss_DeletePrintProvidor
 
10312
****************************************************************/
 
10313
 
 
10314
WERROR _spoolss_DeletePrintProvidor(struct pipes_struct *p,
 
10315
                                    struct spoolss_DeletePrintProvidor *r)
 
10316
{
 
10317
        p->rng_fault_state = true;
 
10318
        return WERR_NOT_SUPPORTED;
 
10319
}
 
10320
 
 
10321
/****************************************************************
 
10322
 _spoolss_FindFirstPrinterChangeNotification
 
10323
****************************************************************/
 
10324
 
 
10325
WERROR _spoolss_FindFirstPrinterChangeNotification(struct pipes_struct *p,
 
10326
                                                   struct spoolss_FindFirstPrinterChangeNotification *r)
 
10327
{
 
10328
        p->rng_fault_state = true;
 
10329
        return WERR_NOT_SUPPORTED;
 
10330
}
 
10331
 
 
10332
/****************************************************************
 
10333
 _spoolss_FindNextPrinterChangeNotification
 
10334
****************************************************************/
 
10335
 
 
10336
WERROR _spoolss_FindNextPrinterChangeNotification(struct pipes_struct *p,
 
10337
                                                  struct spoolss_FindNextPrinterChangeNotification *r)
 
10338
{
 
10339
        p->rng_fault_state = true;
 
10340
        return WERR_NOT_SUPPORTED;
 
10341
}
 
10342
 
 
10343
/****************************************************************
 
10344
 _spoolss_RouterFindFirstPrinterChangeNotificationOld
 
10345
****************************************************************/
 
10346
 
 
10347
WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct *p,
 
10348
                                                            struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
 
10349
{
 
10350
        p->rng_fault_state = true;
 
10351
        return WERR_NOT_SUPPORTED;
 
10352
}
 
10353
 
 
10354
/****************************************************************
 
10355
 _spoolss_ReplyOpenPrinter
 
10356
****************************************************************/
 
10357
 
 
10358
WERROR _spoolss_ReplyOpenPrinter(struct pipes_struct *p,
 
10359
                                 struct spoolss_ReplyOpenPrinter *r)
 
10360
{
 
10361
        p->rng_fault_state = true;
 
10362
        return WERR_NOT_SUPPORTED;
 
10363
}
 
10364
 
 
10365
/****************************************************************
 
10366
 _spoolss_RouterReplyPrinter
 
10367
****************************************************************/
 
10368
 
 
10369
WERROR _spoolss_RouterReplyPrinter(struct pipes_struct *p,
 
10370
                                   struct spoolss_RouterReplyPrinter *r)
 
10371
{
 
10372
        p->rng_fault_state = true;
 
10373
        return WERR_NOT_SUPPORTED;
 
10374
}
 
10375
 
 
10376
/****************************************************************
 
10377
 _spoolss_ReplyClosePrinter
 
10378
****************************************************************/
 
10379
 
 
10380
WERROR _spoolss_ReplyClosePrinter(struct pipes_struct *p,
 
10381
                                  struct spoolss_ReplyClosePrinter *r)
 
10382
{
 
10383
        p->rng_fault_state = true;
 
10384
        return WERR_NOT_SUPPORTED;
 
10385
}
 
10386
 
 
10387
/****************************************************************
 
10388
 _spoolss_AddPortEx
 
10389
****************************************************************/
 
10390
 
 
10391
WERROR _spoolss_AddPortEx(struct pipes_struct *p,
 
10392
                          struct spoolss_AddPortEx *r)
 
10393
{
 
10394
        p->rng_fault_state = true;
 
10395
        return WERR_NOT_SUPPORTED;
 
10396
}
 
10397
 
 
10398
/****************************************************************
 
10399
 _spoolss_RouterFindFirstPrinterChangeNotification
 
10400
****************************************************************/
 
10401
 
 
10402
WERROR _spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct *p,
 
10403
                                                         struct spoolss_RouterFindFirstPrinterChangeNotification *r)
 
10404
{
 
10405
        p->rng_fault_state = true;
 
10406
        return WERR_NOT_SUPPORTED;
 
10407
}
 
10408
 
 
10409
/****************************************************************
 
10410
 _spoolss_SpoolerInit
 
10411
****************************************************************/
 
10412
 
 
10413
WERROR _spoolss_SpoolerInit(struct pipes_struct *p,
 
10414
                            struct spoolss_SpoolerInit *r)
 
10415
{
 
10416
        p->rng_fault_state = true;
 
10417
        return WERR_NOT_SUPPORTED;
 
10418
}
 
10419
 
 
10420
/****************************************************************
 
10421
 _spoolss_ResetPrinterEx
 
10422
****************************************************************/
 
10423
 
 
10424
WERROR _spoolss_ResetPrinterEx(struct pipes_struct *p,
 
10425
                               struct spoolss_ResetPrinterEx *r)
 
10426
{
 
10427
        p->rng_fault_state = true;
 
10428
        return WERR_NOT_SUPPORTED;
 
10429
}
 
10430
 
 
10431
/****************************************************************
 
10432
 _spoolss_RouterReplyPrinterEx
 
10433
****************************************************************/
 
10434
 
 
10435
WERROR _spoolss_RouterReplyPrinterEx(struct pipes_struct *p,
 
10436
                                     struct spoolss_RouterReplyPrinterEx *r)
 
10437
{
 
10438
        p->rng_fault_state = true;
 
10439
        return WERR_NOT_SUPPORTED;
 
10440
}
 
10441
 
 
10442
/****************************************************************
 
10443
 _spoolss_44
 
10444
****************************************************************/
 
10445
 
 
10446
WERROR _spoolss_44(struct pipes_struct *p,
 
10447
                   struct spoolss_44 *r)
 
10448
{
 
10449
        p->rng_fault_state = true;
 
10450
        return WERR_NOT_SUPPORTED;
 
10451
}
 
10452
 
 
10453
/****************************************************************
 
10454
 _spoolss_SetPort
 
10455
****************************************************************/
 
10456
 
 
10457
WERROR _spoolss_SetPort(struct pipes_struct *p,
 
10458
                        struct spoolss_SetPort *r)
 
10459
{
 
10460
        p->rng_fault_state = true;
 
10461
        return WERR_NOT_SUPPORTED;
 
10462
}
 
10463
 
 
10464
/****************************************************************
 
10465
 _spoolss_4a
 
10466
****************************************************************/
 
10467
 
 
10468
WERROR _spoolss_4a(struct pipes_struct *p,
 
10469
                   struct spoolss_4a *r)
 
10470
{
 
10471
        p->rng_fault_state = true;
 
10472
        return WERR_NOT_SUPPORTED;
 
10473
}
 
10474
 
 
10475
/****************************************************************
 
10476
 _spoolss_4b
 
10477
****************************************************************/
 
10478
 
 
10479
WERROR _spoolss_4b(struct pipes_struct *p,
 
10480
                   struct spoolss_4b *r)
 
10481
{
 
10482
        p->rng_fault_state = true;
 
10483
        return WERR_NOT_SUPPORTED;
 
10484
}
 
10485
 
 
10486
/****************************************************************
 
10487
 _spoolss_4c
 
10488
****************************************************************/
 
10489
 
 
10490
WERROR _spoolss_4c(struct pipes_struct *p,
 
10491
                   struct spoolss_4c *r)
 
10492
{
 
10493
        p->rng_fault_state = true;
 
10494
        return WERR_NOT_SUPPORTED;
 
10495
}
 
10496
 
 
10497
/****************************************************************
 
10498
 _spoolss_53
 
10499
****************************************************************/
 
10500
 
 
10501
WERROR _spoolss_53(struct pipes_struct *p,
 
10502
                   struct spoolss_53 *r)
 
10503
{
 
10504
        p->rng_fault_state = true;
 
10505
        return WERR_NOT_SUPPORTED;
 
10506
}
 
10507
 
 
10508
/****************************************************************
 
10509
 _spoolss_AddPerMachineConnection
 
10510
****************************************************************/
 
10511
 
 
10512
WERROR _spoolss_AddPerMachineConnection(struct pipes_struct *p,
 
10513
                                        struct spoolss_AddPerMachineConnection *r)
 
10514
{
 
10515
        p->rng_fault_state = true;
 
10516
        return WERR_NOT_SUPPORTED;
 
10517
}
 
10518
 
 
10519
/****************************************************************
 
10520
 _spoolss_DeletePerMachineConnection
 
10521
****************************************************************/
 
10522
 
 
10523
WERROR _spoolss_DeletePerMachineConnection(struct pipes_struct *p,
 
10524
                                           struct spoolss_DeletePerMachineConnection *r)
 
10525
{
 
10526
        p->rng_fault_state = true;
 
10527
        return WERR_NOT_SUPPORTED;
 
10528
}
 
10529
 
 
10530
/****************************************************************
 
10531
 _spoolss_EnumPerMachineConnections
 
10532
****************************************************************/
 
10533
 
 
10534
WERROR _spoolss_EnumPerMachineConnections(struct pipes_struct *p,
 
10535
                                          struct spoolss_EnumPerMachineConnections *r)
 
10536
{
 
10537
        p->rng_fault_state = true;
 
10538
        return WERR_NOT_SUPPORTED;
 
10539
}
 
10540
 
 
10541
/****************************************************************
 
10542
 _spoolss_5a
 
10543
****************************************************************/
 
10544
 
 
10545
WERROR _spoolss_5a(struct pipes_struct *p,
 
10546
                   struct spoolss_5a *r)
 
10547
{
 
10548
        p->rng_fault_state = true;
 
10549
        return WERR_NOT_SUPPORTED;
 
10550
}
 
10551
 
 
10552
/****************************************************************
 
10553
 _spoolss_5b
 
10554
****************************************************************/
 
10555
 
 
10556
WERROR _spoolss_5b(struct pipes_struct *p,
 
10557
                   struct spoolss_5b *r)
 
10558
{
 
10559
        p->rng_fault_state = true;
 
10560
        return WERR_NOT_SUPPORTED;
 
10561
}
 
10562
 
 
10563
/****************************************************************
 
10564
 _spoolss_5c
 
10565
****************************************************************/
 
10566
 
 
10567
WERROR _spoolss_5c(struct pipes_struct *p,
 
10568
                   struct spoolss_5c *r)
 
10569
{
 
10570
        p->rng_fault_state = true;
 
10571
        return WERR_NOT_SUPPORTED;
 
10572
}
 
10573
 
 
10574
/****************************************************************
 
10575
 _spoolss_5d
 
10576
****************************************************************/
 
10577
 
 
10578
WERROR _spoolss_5d(struct pipes_struct *p,
 
10579
                   struct spoolss_5d *r)
 
10580
{
 
10581
        p->rng_fault_state = true;
 
10582
        return WERR_NOT_SUPPORTED;
 
10583
}
 
10584
 
 
10585
/****************************************************************
 
10586
 _spoolss_5e
 
10587
****************************************************************/
 
10588
 
 
10589
WERROR _spoolss_5e(struct pipes_struct *p,
 
10590
                   struct spoolss_5e *r)
 
10591
{
 
10592
        p->rng_fault_state = true;
 
10593
        return WERR_NOT_SUPPORTED;
 
10594
}
 
10595
 
 
10596
/****************************************************************
 
10597
 _spoolss_5f
 
10598
****************************************************************/
 
10599
 
 
10600
WERROR _spoolss_5f(struct pipes_struct *p,
 
10601
                   struct spoolss_5f *r)
 
10602
{
 
10603
        p->rng_fault_state = true;
 
10604
        return WERR_NOT_SUPPORTED;
 
10605
}
 
10606
 
 
10607
/****************************************************************
 
10608
 _spoolss_60
 
10609
****************************************************************/
 
10610
 
 
10611
WERROR _spoolss_60(struct pipes_struct *p,
 
10612
                   struct spoolss_60 *r)
 
10613
{
 
10614
        p->rng_fault_state = true;
 
10615
        return WERR_NOT_SUPPORTED;
 
10616
}
 
10617
 
 
10618
/****************************************************************
 
10619
 _spoolss_61
 
10620
****************************************************************/
 
10621
 
 
10622
WERROR _spoolss_61(struct pipes_struct *p,
 
10623
                   struct spoolss_61 *r)
 
10624
{
 
10625
        p->rng_fault_state = true;
 
10626
        return WERR_NOT_SUPPORTED;
 
10627
}
 
10628
 
 
10629
/****************************************************************
 
10630
 _spoolss_62
 
10631
****************************************************************/
 
10632
 
 
10633
WERROR _spoolss_62(struct pipes_struct *p,
 
10634
                   struct spoolss_62 *r)
 
10635
{
 
10636
        p->rng_fault_state = true;
 
10637
        return WERR_NOT_SUPPORTED;
 
10638
}
 
10639
 
 
10640
/****************************************************************
 
10641
 _spoolss_63
 
10642
****************************************************************/
 
10643
 
 
10644
WERROR _spoolss_63(struct pipes_struct *p,
 
10645
                   struct spoolss_63 *r)
 
10646
{
 
10647
        p->rng_fault_state = true;
 
10648
        return WERR_NOT_SUPPORTED;
 
10649
}
 
10650
 
 
10651
/****************************************************************
 
10652
 _spoolss_64
 
10653
****************************************************************/
 
10654
 
 
10655
WERROR _spoolss_64(struct pipes_struct *p,
 
10656
                   struct spoolss_64 *r)
 
10657
{
 
10658
        p->rng_fault_state = true;
 
10659
        return WERR_NOT_SUPPORTED;
 
10660
}
 
10661
 
 
10662
/****************************************************************
 
10663
 _spoolss_65
 
10664
****************************************************************/
 
10665
 
 
10666
WERROR _spoolss_65(struct pipes_struct *p,
 
10667
                   struct spoolss_65 *r)
 
10668
{
 
10669
        p->rng_fault_state = true;
 
10670
        return WERR_NOT_SUPPORTED;
 
10671
}
 
10672
 
 
10673
/****************************************************************
 
10674
 _spoolss_GetCorePrinterDrivers
 
10675
****************************************************************/
 
10676
 
 
10677
WERROR _spoolss_GetCorePrinterDrivers(struct pipes_struct *p,
 
10678
                                      struct spoolss_GetCorePrinterDrivers *r)
 
10679
{
 
10680
        p->rng_fault_state = true;
 
10681
        return WERR_NOT_SUPPORTED;
 
10682
}
 
10683
 
 
10684
/****************************************************************
 
10685
 _spoolss_67
 
10686
****************************************************************/
 
10687
 
 
10688
WERROR _spoolss_67(struct pipes_struct *p,
 
10689
                   struct spoolss_67 *r)
 
10690
{
 
10691
        p->rng_fault_state = true;
 
10692
        return WERR_NOT_SUPPORTED;
 
10693
}
 
10694
 
 
10695
/****************************************************************
 
10696
 _spoolss_GetPrinterDriverPackagePath
 
10697
****************************************************************/
 
10698
 
 
10699
WERROR _spoolss_GetPrinterDriverPackagePath(struct pipes_struct *p,
 
10700
                                            struct spoolss_GetPrinterDriverPackagePath *r)
 
10701
{
 
10702
        p->rng_fault_state = true;
 
10703
        return WERR_NOT_SUPPORTED;
 
10704
}
 
10705
 
 
10706
/****************************************************************
 
10707
 _spoolss_69
 
10708
****************************************************************/
 
10709
 
 
10710
WERROR _spoolss_69(struct pipes_struct *p,
 
10711
                   struct spoolss_69 *r)
 
10712
{
 
10713
        p->rng_fault_state = true;
 
10714
        return WERR_NOT_SUPPORTED;
 
10715
}
 
10716
 
 
10717
/****************************************************************
 
10718
 _spoolss_6a
 
10719
****************************************************************/
 
10720
 
 
10721
WERROR _spoolss_6a(struct pipes_struct *p,
 
10722
                   struct spoolss_6a *r)
 
10723
{
 
10724
        p->rng_fault_state = true;
 
10725
        return WERR_NOT_SUPPORTED;
 
10726
}
 
10727
 
 
10728
/****************************************************************
 
10729
 _spoolss_6b
 
10730
****************************************************************/
 
10731
 
 
10732
WERROR _spoolss_6b(struct pipes_struct *p,
 
10733
                   struct spoolss_6b *r)
 
10734
{
 
10735
        p->rng_fault_state = true;
 
10736
        return WERR_NOT_SUPPORTED;
 
10737
}
 
10738
 
 
10739
/****************************************************************
 
10740
 _spoolss_6c
 
10741
****************************************************************/
 
10742
 
 
10743
WERROR _spoolss_6c(struct pipes_struct *p,
 
10744
                   struct spoolss_6c *r)
 
10745
{
 
10746
        p->rng_fault_state = true;
 
10747
        return WERR_NOT_SUPPORTED;
 
10748
}
 
10749
 
 
10750
/****************************************************************
 
10751
 _spoolss_6d
 
10752
****************************************************************/
 
10753
 
 
10754
WERROR _spoolss_6d(struct pipes_struct *p,
 
10755
                   struct spoolss_6d *r)
 
10756
{
 
10757
        p->rng_fault_state = true;
 
10758
        return WERR_NOT_SUPPORTED;
 
10759
}