~ubuntu-branches/ubuntu/vivid/samba/vivid

« back to all changes in this revision

Viewing changes to source3/rpc_server/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.
11
 
 *
12
 
 *  This program is free software; you can redistribute it and/or modify
13
 
 *  it under the terms of the GNU General Public License as published by
14
 
 *  the Free Software Foundation; either version 3 of the License, or
15
 
 *  (at your option) any later version.
16
 
 *
17
 
 *  This program is distributed in the hope that it will be useful,
18
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 
 *  GNU General Public License for more details.
21
 
 *
22
 
 *  You should have received a copy of the GNU General Public License
23
 
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
24
 
 */
25
 
 
26
 
/* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
27
 
   up, all the errors returned are DOS errors, not NT status codes. */
28
 
 
29
 
#include "includes.h"
30
 
#include "../librpc/gen_ndr/srv_spoolss.h"
31
 
#include "../librpc/gen_ndr/cli_spoolss.h"
32
 
 
33
 
/* macros stolen from s4 spoolss server */
34
 
#define SPOOLSS_BUFFER_UNION(fn,ic,info,level) \
35
 
        ((info)?ndr_size_##fn(info, level, ic, 0):0)
36
 
 
37
 
#define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,ic,info,level,count) \
38
 
        ((info)?ndr_size_##fn##_info(mem_ctx, ic, level, count, info):0)
39
 
 
40
 
#define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,ic,info,count) \
41
 
        ((info)?ndr_size_##fn##_info(mem_ctx, ic, count, info):0)
42
 
 
43
 
#define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
44
 
 
45
 
 
46
 
extern userdom_struct current_user_info;
47
 
 
48
 
#undef DBGC_CLASS
49
 
#define DBGC_CLASS DBGC_RPC_SRV
50
 
 
51
 
#ifndef MAX_OPEN_PRINTER_EXS
52
 
#define MAX_OPEN_PRINTER_EXS 50
53
 
#endif
54
 
 
55
 
#define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
56
 
#define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
57
 
 
58
 
static Printer_entry *printers_list;
59
 
 
60
 
typedef struct _counter_printer_0 {
61
 
        struct _counter_printer_0 *next;
62
 
        struct _counter_printer_0 *prev;
63
 
 
64
 
        int snum;
65
 
        uint32_t counter;
66
 
} counter_printer_0;
67
 
 
68
 
static counter_printer_0 *counter_list;
69
 
 
70
 
static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
71
 
static uint32_t smb_connections = 0;
72
 
 
73
 
 
74
 
/* in printing/nt_printing.c */
75
 
 
76
 
extern struct standard_mapping printer_std_mapping, printserver_std_mapping;
77
 
 
78
 
/* API table for Xcv Monitor functions */
79
 
 
80
 
struct xcv_api_table {
81
 
        const char *name;
82
 
        WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
83
 
};
84
 
 
85
 
/********************************************************************
86
 
 * Canonicalize servername.
87
 
 ********************************************************************/
88
 
 
89
 
static const char *canon_servername(const char *servername)
90
 
{
91
 
        const char *pservername = servername;
92
 
        while (*pservername == '\\') {
93
 
                pservername++;
94
 
        }
95
 
        return pservername;
96
 
}
97
 
 
98
 
/* translate between internal status numbers and NT status numbers */
99
 
static int nt_printj_status(int v)
100
 
{
101
 
        switch (v) {
102
 
        case LPQ_QUEUED:
103
 
                return 0;
104
 
        case LPQ_PAUSED:
105
 
                return JOB_STATUS_PAUSED;
106
 
        case LPQ_SPOOLING:
107
 
                return JOB_STATUS_SPOOLING;
108
 
        case LPQ_PRINTING:
109
 
                return JOB_STATUS_PRINTING;
110
 
        case LPQ_ERROR:
111
 
                return JOB_STATUS_ERROR;
112
 
        case LPQ_DELETING:
113
 
                return JOB_STATUS_DELETING;
114
 
        case LPQ_OFFLINE:
115
 
                return JOB_STATUS_OFFLINE;
116
 
        case LPQ_PAPEROUT:
117
 
                return JOB_STATUS_PAPEROUT;
118
 
        case LPQ_PRINTED:
119
 
                return JOB_STATUS_PRINTED;
120
 
        case LPQ_DELETED:
121
 
                return JOB_STATUS_DELETED;
122
 
        case LPQ_BLOCKED:
123
 
                return JOB_STATUS_BLOCKED_DEVQ;
124
 
        case LPQ_USER_INTERVENTION:
125
 
                return JOB_STATUS_USER_INTERVENTION;
126
 
        }
127
 
        return 0;
128
 
}
129
 
 
130
 
static int nt_printq_status(int v)
131
 
{
132
 
        switch (v) {
133
 
        case LPQ_PAUSED:
134
 
                return PRINTER_STATUS_PAUSED;
135
 
        case LPQ_QUEUED:
136
 
        case LPQ_SPOOLING:
137
 
        case LPQ_PRINTING:
138
 
                return 0;
139
 
        }
140
 
        return 0;
141
 
}
142
 
 
143
 
static void prune_printername_cache(void);
144
 
 
145
 
/***************************************************************************
146
 
 Disconnect from the client
147
 
****************************************************************************/
148
 
 
149
 
static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle)
150
 
{
151
 
        WERROR result;
152
 
        NTSTATUS status;
153
 
 
154
 
        /*
155
 
         * Tell the specific printing tdb we no longer want messages for this printer
156
 
         * by deregistering our PID.
157
 
         */
158
 
 
159
 
        if (!print_notify_deregister_pid(snum))
160
 
                DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
161
 
 
162
 
        /* weird if the test succeds !!! */
163
 
        if (smb_connections==0) {
164
 
                DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
165
 
                return;
166
 
        }
167
 
 
168
 
        status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
169
 
                                                  handle,
170
 
                                                  &result);
171
 
        if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
172
 
                DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
173
 
                        win_errstr(result)));
174
 
 
175
 
        /* if it's the last connection, deconnect the IPC$ share */
176
 
        if (smb_connections==1) {
177
 
 
178
 
                cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
179
 
                notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */
180
 
 
181
 
                messaging_deregister(smbd_messaging_context(),
182
 
                                     MSG_PRINTER_NOTIFY2, NULL);
183
 
 
184
 
                /* Tell the connections db we're no longer interested in
185
 
                 * printer notify messages. */
186
 
 
187
 
                register_message_flags(false, FLAG_MSG_PRINT_NOTIFY);
188
 
        }
189
 
 
190
 
        smb_connections--;
191
 
}
192
 
 
193
 
/****************************************************************************
194
 
 Functions to free a printer entry datastruct.
195
 
****************************************************************************/
196
 
 
197
 
static int printer_entry_destructor(Printer_entry *Printer)
198
 
{
199
 
        if (Printer->notify.client_connected == true) {
200
 
                int snum = -1;
201
 
 
202
 
                if ( Printer->printer_type == SPLHND_SERVER) {
203
 
                        snum = -1;
204
 
                        srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
205
 
                } else if (Printer->printer_type == SPLHND_PRINTER) {
206
 
                        snum = print_queue_snum(Printer->sharename);
207
 
                        if (snum != -1)
208
 
                                srv_spoolss_replycloseprinter(snum,
209
 
                                                &Printer->notify.client_hnd);
210
 
                }
211
 
        }
212
 
 
213
 
        Printer->notify.flags=0;
214
 
        Printer->notify.options=0;
215
 
        Printer->notify.localmachine[0]='\0';
216
 
        Printer->notify.printerlocal=0;
217
 
        TALLOC_FREE(Printer->notify.option);
218
 
        Printer->notify.client_connected = false;
219
 
 
220
 
        free_nt_devicemode( &Printer->nt_devmode );
221
 
        free_a_printer( &Printer->printer_info, 2 );
222
 
 
223
 
        /* Remove from the internal list. */
224
 
        DLIST_REMOVE(printers_list, Printer);
225
 
        return 0;
226
 
}
227
 
 
228
 
/****************************************************************************
229
 
  find printer index by handle
230
 
****************************************************************************/
231
 
 
232
 
static Printer_entry *find_printer_index_by_hnd(pipes_struct *p,
233
 
                                                struct policy_handle *hnd)
234
 
{
235
 
        Printer_entry *find_printer = NULL;
236
 
 
237
 
        if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
238
 
                DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
239
 
                return NULL;
240
 
        }
241
 
 
242
 
        return find_printer;
243
 
}
244
 
 
245
 
/****************************************************************************
246
 
 Close printer index by handle.
247
 
****************************************************************************/
248
 
 
249
 
static bool close_printer_handle(pipes_struct *p, struct policy_handle *hnd)
250
 
{
251
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
252
 
 
253
 
        if (!Printer) {
254
 
                DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
255
 
                        OUR_HANDLE(hnd)));
256
 
                return false;
257
 
        }
258
 
 
259
 
        close_policy_hnd(p, hnd);
260
 
 
261
 
        return true;
262
 
}
263
 
 
264
 
/****************************************************************************
265
 
 Delete a printer given a handle.
266
 
****************************************************************************/
267
 
 
268
 
static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename)
269
 
{
270
 
        char *cmd = lp_deleteprinter_cmd();
271
 
        char *command = NULL;
272
 
        int ret;
273
 
        SE_PRIV se_printop = SE_PRINT_OPERATOR;
274
 
        bool is_print_op = false;
275
 
 
276
 
        /* can't fail if we don't try */
277
 
 
278
 
        if ( !*cmd )
279
 
                return WERR_OK;
280
 
 
281
 
        command = talloc_asprintf(ctx,
282
 
                        "%s \"%s\"",
283
 
                        cmd, sharename);
284
 
        if (!command) {
285
 
                return WERR_NOMEM;
286
 
        }
287
 
        if ( token )
288
 
                is_print_op = user_has_privileges( token, &se_printop );
289
 
 
290
 
        DEBUG(10,("Running [%s]\n", command));
291
 
 
292
 
        /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
293
 
 
294
 
        if ( is_print_op )
295
 
                become_root();
296
 
 
297
 
        if ( (ret = smbrun(command, NULL)) == 0 ) {
298
 
                /* Tell everyone we updated smb.conf. */
299
 
                message_send_all(smbd_messaging_context(),
300
 
                                 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
301
 
        }
302
 
 
303
 
        if ( is_print_op )
304
 
                unbecome_root();
305
 
 
306
 
        /********** END SePrintOperatorPrivlege BLOCK **********/
307
 
 
308
 
        DEBUGADD(10,("returned [%d]\n", ret));
309
 
 
310
 
        TALLOC_FREE(command);
311
 
 
312
 
        if (ret != 0)
313
 
                return WERR_BADFID; /* What to return here? */
314
 
 
315
 
        /* go ahead and re-read the services immediately */
316
 
        become_root();
317
 
        reload_services(false);
318
 
        unbecome_root();
319
 
 
320
 
        if ( lp_servicenumber( sharename )  < 0 )
321
 
                return WERR_ACCESS_DENIED;
322
 
 
323
 
        return WERR_OK;
324
 
}
325
 
 
326
 
/****************************************************************************
327
 
 Delete a printer given a handle.
328
 
****************************************************************************/
329
 
 
330
 
static WERROR delete_printer_handle(pipes_struct *p, struct policy_handle *hnd)
331
 
{
332
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
333
 
        WERROR result;
334
 
 
335
 
        if (!Printer) {
336
 
                DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
337
 
                        OUR_HANDLE(hnd)));
338
 
                return WERR_BADFID;
339
 
        }
340
 
 
341
 
        /*
342
 
         * It turns out that Windows allows delete printer on a handle
343
 
         * opened by an admin user, then used on a pipe handle created
344
 
         * by an anonymous user..... but they're working on security.... riiight !
345
 
         * JRA.
346
 
         */
347
 
 
348
 
        if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
349
 
                DEBUG(3, ("delete_printer_handle: denied by handle\n"));
350
 
                return WERR_ACCESS_DENIED;
351
 
        }
352
 
 
353
 
        /* this does not need a become root since the access check has been
354
 
           done on the handle already */
355
 
 
356
 
        if (del_a_printer( Printer->sharename ) != 0) {
357
 
                DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
358
 
                return WERR_BADFID;
359
 
        }
360
 
 
361
 
        result = delete_printer_hook(p->mem_ctx, p->server_info->ptok,
362
 
                                     Printer->sharename);
363
 
        if (!W_ERROR_IS_OK(result)) {
364
 
                return result;
365
 
        }
366
 
        prune_printername_cache();
367
 
        return WERR_OK;
368
 
}
369
 
 
370
 
/****************************************************************************
371
 
 Return the snum of a printer corresponding to an handle.
372
 
****************************************************************************/
373
 
 
374
 
static bool get_printer_snum(pipes_struct *p, struct policy_handle *hnd,
375
 
                             int *number, struct share_params **params)
376
 
{
377
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
378
 
 
379
 
        if (!Printer) {
380
 
                DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
381
 
                        OUR_HANDLE(hnd)));
382
 
                return false;
383
 
        }
384
 
 
385
 
        switch (Printer->printer_type) {
386
 
                case SPLHND_PRINTER:
387
 
                        DEBUG(4,("short name:%s\n", Printer->sharename));
388
 
                        *number = print_queue_snum(Printer->sharename);
389
 
                        return (*number != -1);
390
 
                case SPLHND_SERVER:
391
 
                        return false;
392
 
                default:
393
 
                        return false;
394
 
        }
395
 
}
396
 
 
397
 
/****************************************************************************
398
 
 Set printer handle type.
399
 
 Check if it's \\server or \\server\printer
400
 
****************************************************************************/
401
 
 
402
 
static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename)
403
 
{
404
 
        DEBUG(3,("Setting printer type=%s\n", handlename));
405
 
 
406
 
        if ( strlen(handlename) < 3 ) {
407
 
                DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
408
 
                return false;
409
 
        }
410
 
 
411
 
        /* it's a print server */
412
 
        if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
413
 
                DEBUGADD(4,("Printer is a print server\n"));
414
 
                Printer->printer_type = SPLHND_SERVER;
415
 
        }
416
 
        /* it's a printer (set_printer_hnd_name() will handle port monitors */
417
 
        else {
418
 
                DEBUGADD(4,("Printer is a printer\n"));
419
 
                Printer->printer_type = SPLHND_PRINTER;
420
 
        }
421
 
 
422
 
        return true;
423
 
}
424
 
 
425
 
static void prune_printername_cache_fn(const char *key, const char *value,
426
 
                                       time_t timeout, void *private_data)
427
 
{
428
 
        gencache_del(key);
429
 
}
430
 
 
431
 
static void prune_printername_cache(void)
432
 
{
433
 
        gencache_iterate(prune_printername_cache_fn, NULL, "PRINTERNAME/*");
434
 
}
435
 
 
436
 
/****************************************************************************
437
 
 Set printer handle name..  Accept names like \\server, \\server\printer,
438
 
 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port"    See
439
 
 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
440
 
 XcvDataPort() interface.
441
 
****************************************************************************/
442
 
 
443
 
static bool set_printer_hnd_name(Printer_entry *Printer, const char *handlename)
444
 
{
445
 
        int snum;
446
 
        int n_services=lp_numservices();
447
 
        char *aprinter, *printername;
448
 
        const char *servername;
449
 
        fstring sname;
450
 
        bool found = false;
451
 
        NT_PRINTER_INFO_LEVEL *printer = NULL;
452
 
        WERROR result;
453
 
 
454
 
        /*
455
 
         * Hopefully nobody names his printers like this. Maybe \ or ,
456
 
         * are illegal in printer names even?
457
 
         */
458
 
        const char printer_not_found[] = "Printer \\, !@#$%^&*( not found";
459
 
        char *cache_key;
460
 
        char *tmp;
461
 
 
462
 
        DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
463
 
                (unsigned long)strlen(handlename)));
464
 
 
465
 
        aprinter = CONST_DISCARD(char *, handlename);
466
 
        if ( *handlename == '\\' ) {
467
 
                servername = canon_servername(handlename);
468
 
                if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
469
 
                        *aprinter = '\0';
470
 
                        aprinter++;
471
 
                }
472
 
        } else {
473
 
                servername = global_myname();
474
 
        }
475
 
 
476
 
        /* save the servername to fill in replies on this handle */
477
 
 
478
 
        if ( !is_myname_or_ipaddr( servername ) )
479
 
                return false;
480
 
 
481
 
        fstrcpy( Printer->servername, servername );
482
 
 
483
 
        if ( Printer->printer_type == SPLHND_SERVER )
484
 
                return true;
485
 
 
486
 
        if ( Printer->printer_type != SPLHND_PRINTER )
487
 
                return false;
488
 
 
489
 
        DEBUGADD(5, ("searching for [%s]\n", aprinter ));
490
 
 
491
 
        /* check for the Port Monitor Interface */
492
 
 
493
 
        if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
494
 
                Printer->printer_type = SPLHND_PORTMON_TCP;
495
 
                fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
496
 
                found = true;
497
 
        }
498
 
        else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
499
 
                Printer->printer_type = SPLHND_PORTMON_LOCAL;
500
 
                fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
501
 
                found = true;
502
 
        }
503
 
 
504
 
        /*
505
 
         * With hundreds of printers, the "for" loop iterating all
506
 
         * shares can be quite expensive, as it is done on every
507
 
         * OpenPrinter. The loop maps "aprinter" to "sname", the
508
 
         * result of which we cache in gencache.
509
 
         */
510
 
 
511
 
        cache_key = talloc_asprintf(talloc_tos(), "PRINTERNAME/%s",
512
 
                                    aprinter);
513
 
        if ((cache_key != NULL) && gencache_get(cache_key, &tmp, NULL)) {
514
 
 
515
 
                found = (strcmp(tmp, printer_not_found) != 0);
516
 
                if (!found) {
517
 
                        DEBUG(4, ("Printer %s not found\n", aprinter));
518
 
                        SAFE_FREE(tmp);
519
 
                        return false;
520
 
                }
521
 
                fstrcpy(sname, tmp);
522
 
                SAFE_FREE(tmp);
523
 
        }
524
 
 
525
 
        /* Search all sharenames first as this is easier than pulling
526
 
           the printer_info_2 off of disk. Don't use find_service() since
527
 
           that calls out to map_username() */
528
 
 
529
 
        /* do another loop to look for printernames */
530
 
 
531
 
        for (snum=0; !found && snum<n_services; snum++) {
532
 
 
533
 
                /* no point going on if this is not a printer */
534
 
 
535
 
                if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
536
 
                        continue;
537
 
 
538
 
                fstrcpy(sname, lp_servicename(snum));
539
 
                if ( strequal( aprinter, sname ) ) {
540
 
                        found = true;
541
 
                        break;
542
 
                }
543
 
 
544
 
                /* no point looking up the printer object if
545
 
                   we aren't allowing printername != sharename */
546
 
 
547
 
                if ( lp_force_printername(snum) )
548
 
                        continue;
549
 
 
550
 
                fstrcpy(sname, lp_servicename(snum));
551
 
 
552
 
                printer = NULL;
553
 
 
554
 
                /* This call doesn't fill in the location or comment from
555
 
                 * a CUPS server for efficiency with large numbers of printers.
556
 
                 * JRA.
557
 
                 */
558
 
 
559
 
                result = get_a_printer_search( NULL, &printer, 2, sname );
560
 
                if ( !W_ERROR_IS_OK(result) ) {
561
 
                        DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
562
 
                                sname, win_errstr(result)));
563
 
                        continue;
564
 
                }
565
 
 
566
 
                /* printername is always returned as \\server\printername */
567
 
                if ( !(printername = strchr_m(&printer->info_2->printername[2], '\\')) ) {
568
 
                        DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
569
 
                                printer->info_2->printername));
570
 
                        free_a_printer( &printer, 2);
571
 
                        continue;
572
 
                }
573
 
 
574
 
                printername++;
575
 
 
576
 
                if ( strequal(printername, aprinter) ) {
577
 
                        free_a_printer( &printer, 2);
578
 
                        found = true;
579
 
                        break;
580
 
                }
581
 
 
582
 
                DEBUGADD(10, ("printername: %s\n", printername));
583
 
 
584
 
                free_a_printer( &printer, 2);
585
 
        }
586
 
 
587
 
        free_a_printer( &printer, 2);
588
 
 
589
 
        if ( !found ) {
590
 
                if (cache_key != NULL) {
591
 
                        gencache_set(cache_key, printer_not_found,
592
 
                                     time(NULL)+300);
593
 
                        TALLOC_FREE(cache_key);
594
 
                }
595
 
                DEBUGADD(4,("Printer not found\n"));
596
 
                return false;
597
 
        }
598
 
 
599
 
        if (cache_key != NULL) {
600
 
                gencache_set(cache_key, sname, time(NULL)+300);
601
 
                TALLOC_FREE(cache_key);
602
 
        }
603
 
 
604
 
        DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
605
 
 
606
 
        fstrcpy(Printer->sharename, sname);
607
 
 
608
 
        return true;
609
 
}
610
 
 
611
 
/****************************************************************************
612
 
 Find first available printer slot. creates a printer handle for you.
613
 
 ****************************************************************************/
614
 
 
615
 
static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd,
616
 
                             const char *name, uint32_t access_granted)
617
 
{
618
 
        Printer_entry *new_printer;
619
 
 
620
 
        DEBUG(10,("open_printer_hnd: name [%s]\n", name));
621
 
 
622
 
        new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
623
 
        if (new_printer == NULL) {
624
 
                return false;
625
 
        }
626
 
        talloc_set_destructor(new_printer, printer_entry_destructor);
627
 
 
628
 
        if (!create_policy_hnd(p, hnd, new_printer)) {
629
 
                TALLOC_FREE(new_printer);
630
 
                return false;
631
 
        }
632
 
 
633
 
        /* Add to the internal list. */
634
 
        DLIST_ADD(printers_list, new_printer);
635
 
 
636
 
        new_printer->notify.option=NULL;
637
 
 
638
 
        if (!set_printer_hnd_printertype(new_printer, name)) {
639
 
                close_printer_handle(p, hnd);
640
 
                return false;
641
 
        }
642
 
 
643
 
        if (!set_printer_hnd_name(new_printer, name)) {
644
 
                close_printer_handle(p, hnd);
645
 
                return false;
646
 
        }
647
 
 
648
 
        new_printer->access_granted = access_granted;
649
 
 
650
 
        DEBUG(5, ("%d printer handles active\n",
651
 
                  (int)num_pipe_handles(p->pipe_handles)));
652
 
 
653
 
        return true;
654
 
}
655
 
 
656
 
/***************************************************************************
657
 
 check to see if the client motify handle is monitoring the notification
658
 
 given by (notify_type, notify_field).
659
 
 **************************************************************************/
660
 
 
661
 
static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
662
 
                                      uint16_t notify_field)
663
 
{
664
 
        return true;
665
 
}
666
 
 
667
 
static bool is_monitoring_event(Printer_entry *p, uint16_t notify_type,
668
 
                                uint16_t notify_field)
669
 
{
670
 
        struct spoolss_NotifyOption *option = p->notify.option;
671
 
        uint32_t i, j;
672
 
 
673
 
        /*
674
 
         * Flags should always be zero when the change notify
675
 
         * is registered by the client's spooler.  A user Win32 app
676
 
         * might use the flags though instead of the NOTIFY_OPTION_INFO
677
 
         * --jerry
678
 
         */
679
 
 
680
 
        if (!option) {
681
 
                return false;
682
 
        }
683
 
 
684
 
        if (p->notify.flags)
685
 
                return is_monitoring_event_flags(
686
 
                        p->notify.flags, notify_type, notify_field);
687
 
 
688
 
        for (i = 0; i < option->count; i++) {
689
 
 
690
 
                /* Check match for notify_type */
691
 
 
692
 
                if (option->types[i].type != notify_type)
693
 
                        continue;
694
 
 
695
 
                /* Check match for field */
696
 
 
697
 
                for (j = 0; j < option->types[i].count; j++) {
698
 
                        if (option->types[i].fields[j].field == notify_field) {
699
 
                                return true;
700
 
                        }
701
 
                }
702
 
        }
703
 
 
704
 
        DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
705
 
                   p->servername, p->sharename, notify_type, notify_field));
706
 
 
707
 
        return false;
708
 
}
709
 
 
710
 
#define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
711
 
        _data->data.integer[0] = _integer; \
712
 
        _data->data.integer[1] = 0;
713
 
 
714
 
 
715
 
#define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
716
 
        _data->data.string.string = talloc_strdup(mem_ctx, _p); \
717
 
        if (!_data->data.string.string) {\
718
 
                _data->data.string.size = 0; \
719
 
        } \
720
 
        _data->data.string.size = strlen_m_term(_p) * 2;
721
 
 
722
 
#define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
723
 
        _data->data.devmode.devmode = _devmode;
724
 
 
725
 
#define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _size, _sd) \
726
 
        _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
727
 
        if (!_data->data.sd.sd) { \
728
 
                _data->data.sd.sd_size = 0; \
729
 
        } \
730
 
        _data->data.sd.sd_size = _size;
731
 
 
732
 
static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
733
 
                                   struct tm *t,
734
 
                                   const char **pp,
735
 
                                   uint32_t *plen)
736
 
{
737
 
        struct spoolss_Time st;
738
 
        uint32_t len = 16;
739
 
        char *p;
740
 
 
741
 
        if (!init_systemtime(&st, t)) {
742
 
                return;
743
 
        }
744
 
 
745
 
        p = talloc_array(mem_ctx, char, len);
746
 
        if (!p) {
747
 
                return;
748
 
        }
749
 
 
750
 
        /*
751
 
         * Systemtime must be linearized as a set of UINT16's.
752
 
         * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
753
 
         */
754
 
 
755
 
        SSVAL(p, 0, st.year);
756
 
        SSVAL(p, 2, st.month);
757
 
        SSVAL(p, 4, st.day_of_week);
758
 
        SSVAL(p, 6, st.day);
759
 
        SSVAL(p, 8, st.hour);
760
 
        SSVAL(p, 10, st.minute);
761
 
        SSVAL(p, 12, st.second);
762
 
        SSVAL(p, 14, st.millisecond);
763
 
 
764
 
        *pp = p;
765
 
        *plen = len;
766
 
}
767
 
 
768
 
/* Convert a notification message to a struct spoolss_Notify */
769
 
 
770
 
static void notify_one_value(struct spoolss_notify_msg *msg,
771
 
                             struct spoolss_Notify *data,
772
 
                             TALLOC_CTX *mem_ctx)
773
 
{
774
 
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
775
 
}
776
 
 
777
 
static void notify_string(struct spoolss_notify_msg *msg,
778
 
                          struct spoolss_Notify *data,
779
 
                          TALLOC_CTX *mem_ctx)
780
 
{
781
 
        /* The length of the message includes the trailing \0 */
782
 
 
783
 
        data->data.string.size = msg->len * 2;
784
 
        data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
785
 
        if (!data->data.string.string) {
786
 
                data->data.string.size = 0;
787
 
                return;
788
 
        }
789
 
}
790
 
 
791
 
static void notify_system_time(struct spoolss_notify_msg *msg,
792
 
                               struct spoolss_Notify *data,
793
 
                               TALLOC_CTX *mem_ctx)
794
 
{
795
 
        data->data.string.string = NULL;
796
 
        data->data.string.size = 0;
797
 
 
798
 
        if (msg->len != sizeof(time_t)) {
799
 
                DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
800
 
                          msg->len));
801
 
                return;
802
 
        }
803
 
 
804
 
        init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
805
 
                               &data->data.string.string,
806
 
                               &data->data.string.size);
807
 
}
808
 
 
809
 
struct notify2_message_table {
810
 
        const char *name;
811
 
        void (*fn)(struct spoolss_notify_msg *msg,
812
 
                   struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
813
 
};
814
 
 
815
 
static struct notify2_message_table printer_notify_table[] = {
816
 
        /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
817
 
        /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
818
 
        /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
819
 
        /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
820
 
        /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
821
 
        /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
822
 
        /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
823
 
        /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
824
 
        /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
825
 
        /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
826
 
        /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
827
 
        /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
828
 
        /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
829
 
        /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
830
 
        /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
831
 
        /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
832
 
        /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
833
 
        /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
834
 
        /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
835
 
};
836
 
 
837
 
static struct notify2_message_table job_notify_table[] = {
838
 
        /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
839
 
        /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
840
 
        /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
841
 
        /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
842
 
        /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
843
 
        /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
844
 
        /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
845
 
        /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
846
 
        /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
847
 
        /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
848
 
        /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
849
 
        /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
850
 
        /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
851
 
        /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
852
 
        /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
853
 
        /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
854
 
        /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
855
 
        /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
856
 
        /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
857
 
        /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
858
 
        /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
859
 
        /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
860
 
        /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
861
 
        /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
862
 
};
863
 
 
864
 
 
865
 
/***********************************************************************
866
 
 Allocate talloc context for container object
867
 
 **********************************************************************/
868
 
 
869
 
static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
870
 
{
871
 
        if ( !ctr )
872
 
                return;
873
 
 
874
 
        ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
875
 
 
876
 
        return;
877
 
}
878
 
 
879
 
/***********************************************************************
880
 
 release all allocated memory and zero out structure
881
 
 **********************************************************************/
882
 
 
883
 
static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
884
 
{
885
 
        if ( !ctr )
886
 
                return;
887
 
 
888
 
        if ( ctr->ctx )
889
 
                talloc_destroy(ctr->ctx);
890
 
 
891
 
        ZERO_STRUCTP(ctr);
892
 
 
893
 
        return;
894
 
}
895
 
 
896
 
/***********************************************************************
897
 
 **********************************************************************/
898
 
 
899
 
static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
900
 
{
901
 
        if ( !ctr )
902
 
                return NULL;
903
 
 
904
 
        return ctr->ctx;
905
 
}
906
 
 
907
 
/***********************************************************************
908
 
 **********************************************************************/
909
 
 
910
 
static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
911
 
{
912
 
        if ( !ctr || !ctr->msg_groups )
913
 
                return NULL;
914
 
 
915
 
        if ( idx >= ctr->num_groups )
916
 
                return NULL;
917
 
 
918
 
        return &ctr->msg_groups[idx];
919
 
 
920
 
}
921
 
 
922
 
/***********************************************************************
923
 
 How many groups of change messages do we have ?
924
 
 **********************************************************************/
925
 
 
926
 
static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
927
 
{
928
 
        if ( !ctr )
929
 
                return 0;
930
 
 
931
 
        return ctr->num_groups;
932
 
}
933
 
 
934
 
/***********************************************************************
935
 
 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
936
 
 **********************************************************************/
937
 
 
938
 
static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
939
 
{
940
 
        SPOOLSS_NOTIFY_MSG_GROUP        *groups = NULL;
941
 
        SPOOLSS_NOTIFY_MSG_GROUP        *msg_grp = NULL;
942
 
        SPOOLSS_NOTIFY_MSG              *msg_list = NULL;
943
 
        int                             i, new_slot;
944
 
 
945
 
        if ( !ctr || !msg )
946
 
                return 0;
947
 
 
948
 
        /* loop over all groups looking for a matching printer name */
949
 
 
950
 
        for ( i=0; i<ctr->num_groups; i++ ) {
951
 
                if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
952
 
                        break;
953
 
        }
954
 
 
955
 
        /* add a new group? */
956
 
 
957
 
        if ( i == ctr->num_groups ) {
958
 
                ctr->num_groups++;
959
 
 
960
 
                if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
961
 
                        DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
962
 
                        return 0;
963
 
                }
964
 
                ctr->msg_groups = groups;
965
 
 
966
 
                /* clear the new entry and set the printer name */
967
 
 
968
 
                ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
969
 
                fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
970
 
        }
971
 
 
972
 
        /* add the change messages; 'i' is the correct index now regardless */
973
 
 
974
 
        msg_grp = &ctr->msg_groups[i];
975
 
 
976
 
        msg_grp->num_msgs++;
977
 
 
978
 
        if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
979
 
                DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
980
 
                return 0;
981
 
        }
982
 
        msg_grp->msgs = msg_list;
983
 
 
984
 
        new_slot = msg_grp->num_msgs-1;
985
 
        memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
986
 
 
987
 
        /* need to allocate own copy of data */
988
 
 
989
 
        if ( msg->len != 0 )
990
 
                msg_grp->msgs[new_slot].notify.data = (char *)
991
 
                        TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
992
 
 
993
 
        return ctr->num_groups;
994
 
}
995
 
 
996
 
/***********************************************************************
997
 
 Send a change notication message on all handles which have a call
998
 
 back registered
999
 
 **********************************************************************/
1000
 
 
1001
 
static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
1002
 
{
1003
 
        Printer_entry            *p;
1004
 
        TALLOC_CTX               *mem_ctx = notify_ctr_getctx( ctr );
1005
 
        SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
1006
 
        SPOOLSS_NOTIFY_MSG       *messages;
1007
 
        int                      sending_msg_count;
1008
 
 
1009
 
        if ( !msg_group ) {
1010
 
                DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
1011
 
                return;
1012
 
        }
1013
 
 
1014
 
        messages = msg_group->msgs;
1015
 
 
1016
 
        if ( !messages ) {
1017
 
                DEBUG(5,("send_notify2_changes() called with no messages!\n"));
1018
 
                return;
1019
 
        }
1020
 
 
1021
 
        DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
1022
 
 
1023
 
        /* loop over all printers */
1024
 
 
1025
 
        for (p = printers_list; p; p = p->next) {
1026
 
                struct spoolss_Notify *notifies;
1027
 
                uint32_t count = 0;
1028
 
                uint32_t id;
1029
 
                int     i;
1030
 
 
1031
 
                /* Is there notification on this handle? */
1032
 
 
1033
 
                if ( !p->notify.client_connected )
1034
 
                        continue;
1035
 
 
1036
 
                DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
1037
 
 
1038
 
                /* For this printer?  Print servers always receive
1039
 
                   notifications. */
1040
 
 
1041
 
                if ( ( p->printer_type == SPLHND_PRINTER )  &&
1042
 
                    ( !strequal(msg_group->printername, p->sharename) ) )
1043
 
                        continue;
1044
 
 
1045
 
                DEBUG(10,("Our printer\n"));
1046
 
 
1047
 
                /* allocate the max entries possible */
1048
 
 
1049
 
                notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
1050
 
                if (!notifies) {
1051
 
                        return;
1052
 
                }
1053
 
 
1054
 
                /* build the array of change notifications */
1055
 
 
1056
 
                sending_msg_count = 0;
1057
 
 
1058
 
                for ( i=0; i<msg_group->num_msgs; i++ ) {
1059
 
                        SPOOLSS_NOTIFY_MSG      *msg = &messages[i];
1060
 
 
1061
 
                        /* Are we monitoring this event? */
1062
 
 
1063
 
                        if (!is_monitoring_event(p, msg->type, msg->field))
1064
 
                                continue;
1065
 
 
1066
 
                        sending_msg_count++;
1067
 
 
1068
 
 
1069
 
                        DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1070
 
                                msg->type, msg->field, p->sharename));
1071
 
 
1072
 
                        /*
1073
 
                         * if the is a printer notification handle and not a job notification
1074
 
                         * type, then set the id to 0.  Other wise just use what was specified
1075
 
                         * in the message.
1076
 
                         *
1077
 
                         * When registering change notification on a print server handle
1078
 
                         * we always need to send back the id (snum) matching the printer
1079
 
                         * for which the change took place.  For change notify registered
1080
 
                         * on a printer handle, this does not matter and the id should be 0.
1081
 
                         *
1082
 
                         * --jerry
1083
 
                         */
1084
 
 
1085
 
                        if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1086
 
                                id = 0;
1087
 
                        else
1088
 
                                id = msg->id;
1089
 
 
1090
 
 
1091
 
                        /* Convert unix jobid to smb jobid */
1092
 
 
1093
 
                        if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1094
 
                                id = sysjob_to_jobid(msg->id);
1095
 
 
1096
 
                                if (id == -1) {
1097
 
                                        DEBUG(3, ("no such unix jobid %d\n", msg->id));
1098
 
                                        goto done;
1099
 
                                }
1100
 
                        }
1101
 
 
1102
 
                        construct_info_data( &notifies[count], msg->type, msg->field, id );
1103
 
 
1104
 
                        switch(msg->type) {
1105
 
                        case PRINTER_NOTIFY_TYPE:
1106
 
                                if ( printer_notify_table[msg->field].fn )
1107
 
                                        printer_notify_table[msg->field].fn(msg, &notifies[count], mem_ctx);
1108
 
                                break;
1109
 
 
1110
 
                        case JOB_NOTIFY_TYPE:
1111
 
                                if ( job_notify_table[msg->field].fn )
1112
 
                                        job_notify_table[msg->field].fn(msg, &notifies[count], mem_ctx);
1113
 
                                break;
1114
 
 
1115
 
                        default:
1116
 
                                DEBUG(5, ("Unknown notification type %d\n", msg->type));
1117
 
                                goto done;
1118
 
                        }
1119
 
 
1120
 
                        count++;
1121
 
                }
1122
 
 
1123
 
                if ( sending_msg_count ) {
1124
 
                        NTSTATUS status;
1125
 
                        WERROR werr;
1126
 
                        union spoolss_ReplyPrinterInfo info;
1127
 
                        struct spoolss_NotifyInfo info0;
1128
 
                        uint32_t reply_result;
1129
 
 
1130
 
                        info0.version   = 0x2;
1131
 
                        info0.flags     = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1132
 
                        info0.count     = count;
1133
 
                        info0.notifies  = notifies;
1134
 
 
1135
 
                        info.info0 = &info0;
1136
 
 
1137
 
                        status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
1138
 
                                                                     &p->notify.client_hnd,
1139
 
                                                                     p->notify.change, /* color */
1140
 
                                                                     p->notify.flags,
1141
 
                                                                     &reply_result,
1142
 
                                                                     0, /* reply_type, must be 0 */
1143
 
                                                                     info,
1144
 
                                                                     &werr);
1145
 
                        if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1146
 
                                DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1147
 
                                        notify_cli_pipe->srv_name_slash,
1148
 
                                        win_errstr(werr)));
1149
 
                        }
1150
 
                        switch (reply_result) {
1151
 
                                case 0:
1152
 
                                        break;
1153
 
                                case PRINTER_NOTIFY_INFO_DISCARDED:
1154
 
                                case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1155
 
                                case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1156
 
                                        break;
1157
 
                                default:
1158
 
                                        break;
1159
 
                        }
1160
 
                }
1161
 
        }
1162
 
 
1163
 
done:
1164
 
        DEBUG(8,("send_notify2_changes: Exit...\n"));
1165
 
        return;
1166
 
}
1167
 
 
1168
 
/***********************************************************************
1169
 
 **********************************************************************/
1170
 
 
1171
 
static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1172
 
{
1173
 
 
1174
 
        uint32_t tv_sec, tv_usec;
1175
 
        size_t offset = 0;
1176
 
 
1177
 
        /* Unpack message */
1178
 
 
1179
 
        offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
1180
 
                             msg->printer);
1181
 
 
1182
 
        offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
1183
 
                                &tv_sec, &tv_usec,
1184
 
                                &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1185
 
 
1186
 
        if (msg->len == 0)
1187
 
                tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
1188
 
                           &msg->notify.value[0], &msg->notify.value[1]);
1189
 
        else
1190
 
                tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
1191
 
                           &msg->len, &msg->notify.data);
1192
 
 
1193
 
        DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1194
 
                  msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1195
 
 
1196
 
        tv->tv_sec = tv_sec;
1197
 
        tv->tv_usec = tv_usec;
1198
 
 
1199
 
        if (msg->len == 0)
1200
 
                DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1201
 
                          msg->notify.value[1]));
1202
 
        else
1203
 
                dump_data(3, (uint8_t *)msg->notify.data, msg->len);
1204
 
 
1205
 
        return true;
1206
 
}
1207
 
 
1208
 
/********************************************************************
1209
 
 Receive a notify2 message list
1210
 
 ********************************************************************/
1211
 
 
1212
 
static void receive_notify2_message_list(struct messaging_context *msg,
1213
 
                                         void *private_data,
1214
 
                                         uint32_t msg_type,
1215
 
                                         struct server_id server_id,
1216
 
                                         DATA_BLOB *data)
1217
 
{
1218
 
        size_t                  msg_count, i;
1219
 
        char                    *buf = (char *)data->data;
1220
 
        char                    *msg_ptr;
1221
 
        size_t                  msg_len;
1222
 
        SPOOLSS_NOTIFY_MSG      notify;
1223
 
        SPOOLSS_NOTIFY_MSG_CTR  messages;
1224
 
        int                     num_groups;
1225
 
 
1226
 
        if (data->length < 4) {
1227
 
                DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1228
 
                return;
1229
 
        }
1230
 
 
1231
 
        msg_count = IVAL(buf, 0);
1232
 
        msg_ptr = buf + 4;
1233
 
 
1234
 
        DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1235
 
 
1236
 
        if (msg_count == 0) {
1237
 
                DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1238
 
                return;
1239
 
        }
1240
 
 
1241
 
        /* initialize the container */
1242
 
 
1243
 
        ZERO_STRUCT( messages );
1244
 
        notify_msg_ctr_init( &messages );
1245
 
 
1246
 
        /*
1247
 
         * build message groups for each printer identified
1248
 
         * in a change_notify msg.  Remember that a PCN message
1249
 
         * includes the handle returned for the srv_spoolss_replyopenprinter()
1250
 
         * call.  Therefore messages are grouped according to printer handle.
1251
 
         */
1252
 
 
1253
 
        for ( i=0; i<msg_count; i++ ) {
1254
 
                struct timeval msg_tv;
1255
 
 
1256
 
                if (msg_ptr + 4 - buf > data->length) {
1257
 
                        DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1258
 
                        return;
1259
 
                }
1260
 
 
1261
 
                msg_len = IVAL(msg_ptr,0);
1262
 
                msg_ptr += 4;
1263
 
 
1264
 
                if (msg_ptr + msg_len - buf > data->length) {
1265
 
                        DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1266
 
                        return;
1267
 
                }
1268
 
 
1269
 
                /* unpack messages */
1270
 
 
1271
 
                ZERO_STRUCT( notify );
1272
 
                notify2_unpack_msg( &notify, &msg_tv, msg_ptr, msg_len );
1273
 
                msg_ptr += msg_len;
1274
 
 
1275
 
                /* add to correct list in container */
1276
 
 
1277
 
                notify_msg_ctr_addmsg( &messages, &notify );
1278
 
 
1279
 
                /* free memory that might have been allocated by notify2_unpack_msg() */
1280
 
 
1281
 
                if ( notify.len != 0 )
1282
 
                        SAFE_FREE( notify.notify.data );
1283
 
        }
1284
 
 
1285
 
        /* process each group of messages */
1286
 
 
1287
 
        num_groups = notify_msg_ctr_numgroups( &messages );
1288
 
        for ( i=0; i<num_groups; i++ )
1289
 
                send_notify2_changes( &messages, i );
1290
 
 
1291
 
 
1292
 
        /* cleanup */
1293
 
 
1294
 
        DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1295
 
                (uint32_t)msg_count ));
1296
 
 
1297
 
        notify_msg_ctr_destroy( &messages );
1298
 
 
1299
 
        return;
1300
 
}
1301
 
 
1302
 
/********************************************************************
1303
 
 Send a message to ourself about new driver being installed
1304
 
 so we can upgrade the information for each printer bound to this
1305
 
 driver
1306
 
 ********************************************************************/
1307
 
 
1308
 
static bool srv_spoolss_drv_upgrade_printer(const char *drivername)
1309
 
{
1310
 
        int len = strlen(drivername);
1311
 
 
1312
 
        if (!len)
1313
 
                return false;
1314
 
 
1315
 
        DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1316
 
                drivername));
1317
 
 
1318
 
        messaging_send_buf(smbd_messaging_context(), procid_self(),
1319
 
                           MSG_PRINTER_DRVUPGRADE,
1320
 
                           (uint8_t *)drivername, len+1);
1321
 
 
1322
 
        return true;
1323
 
}
1324
 
 
1325
 
/**********************************************************************
1326
 
 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1327
 
 over all printers, upgrading ones as necessary
1328
 
 **********************************************************************/
1329
 
 
1330
 
void do_drv_upgrade_printer(struct messaging_context *msg,
1331
 
                            void *private_data,
1332
 
                            uint32_t msg_type,
1333
 
                            struct server_id server_id,
1334
 
                            DATA_BLOB *data)
1335
 
{
1336
 
        fstring drivername;
1337
 
        int snum;
1338
 
        int n_services = lp_numservices();
1339
 
        size_t len;
1340
 
 
1341
 
        len = MIN(data->length,sizeof(drivername)-1);
1342
 
        strncpy(drivername, (const char *)data->data, len);
1343
 
 
1344
 
        DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername ));
1345
 
 
1346
 
        /* Iterate the printer list */
1347
 
 
1348
 
        for (snum=0; snum<n_services; snum++)
1349
 
        {
1350
 
                if (lp_snum_ok(snum) && lp_print_ok(snum) )
1351
 
                {
1352
 
                        WERROR result;
1353
 
                        NT_PRINTER_INFO_LEVEL *printer = NULL;
1354
 
 
1355
 
                        result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
1356
 
                        if (!W_ERROR_IS_OK(result))
1357
 
                                continue;
1358
 
 
1359
 
                        if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername))
1360
 
                        {
1361
 
                                DEBUG(6,("Updating printer [%s]\n", printer->info_2->printername));
1362
 
 
1363
 
                                /* all we care about currently is the change_id */
1364
 
 
1365
 
                                result = mod_a_printer(printer, 2);
1366
 
                                if (!W_ERROR_IS_OK(result)) {
1367
 
                                        DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1368
 
                                                win_errstr(result)));
1369
 
                                }
1370
 
                        }
1371
 
 
1372
 
                        free_a_printer(&printer, 2);
1373
 
                }
1374
 
        }
1375
 
 
1376
 
        /* all done */
1377
 
}
1378
 
 
1379
 
/********************************************************************
1380
 
 Update the cache for all printq's with a registered client
1381
 
 connection
1382
 
 ********************************************************************/
1383
 
 
1384
 
void update_monitored_printq_cache( void )
1385
 
{
1386
 
        Printer_entry *printer = printers_list;
1387
 
        int snum;
1388
 
 
1389
 
        /* loop through all printers and update the cache where
1390
 
           client_connected == true */
1391
 
        while ( printer )
1392
 
        {
1393
 
                if ( (printer->printer_type == SPLHND_PRINTER)
1394
 
                        && printer->notify.client_connected )
1395
 
                {
1396
 
                        snum = print_queue_snum(printer->sharename);
1397
 
                        print_queue_status( snum, NULL, NULL );
1398
 
                }
1399
 
 
1400
 
                printer = printer->next;
1401
 
        }
1402
 
 
1403
 
        return;
1404
 
}
1405
 
/********************************************************************
1406
 
 Send a message to ourself about new driver being installed
1407
 
 so we can upgrade the information for each printer bound to this
1408
 
 driver
1409
 
 ********************************************************************/
1410
 
 
1411
 
static bool srv_spoolss_reset_printerdata(char* drivername)
1412
 
{
1413
 
        int len = strlen(drivername);
1414
 
 
1415
 
        if (!len)
1416
 
                return false;
1417
 
 
1418
 
        DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1419
 
                drivername));
1420
 
 
1421
 
        messaging_send_buf(smbd_messaging_context(), procid_self(),
1422
 
                           MSG_PRINTERDATA_INIT_RESET,
1423
 
                           (uint8_t *)drivername, len+1);
1424
 
 
1425
 
        return true;
1426
 
}
1427
 
 
1428
 
/**********************************************************************
1429
 
 callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1430
 
 over all printers, resetting printer data as neessary
1431
 
 **********************************************************************/
1432
 
 
1433
 
void reset_all_printerdata(struct messaging_context *msg,
1434
 
                           void *private_data,
1435
 
                           uint32_t msg_type,
1436
 
                           struct server_id server_id,
1437
 
                           DATA_BLOB *data)
1438
 
{
1439
 
        fstring drivername;
1440
 
        int snum;
1441
 
        int n_services = lp_numservices();
1442
 
        size_t len;
1443
 
 
1444
 
        len = MIN( data->length, sizeof(drivername)-1 );
1445
 
        strncpy( drivername, (const char *)data->data, len );
1446
 
 
1447
 
        DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername ));
1448
 
 
1449
 
        /* Iterate the printer list */
1450
 
 
1451
 
        for ( snum=0; snum<n_services; snum++ )
1452
 
        {
1453
 
                if ( lp_snum_ok(snum) && lp_print_ok(snum) )
1454
 
                {
1455
 
                        WERROR result;
1456
 
                        NT_PRINTER_INFO_LEVEL *printer = NULL;
1457
 
 
1458
 
                        result = get_a_printer( NULL, &printer, 2, lp_const_servicename(snum) );
1459
 
                        if ( !W_ERROR_IS_OK(result) )
1460
 
                                continue;
1461
 
 
1462
 
                        /*
1463
 
                         * if the printer is bound to the driver,
1464
 
                         * then reset to the new driver initdata
1465
 
                         */
1466
 
 
1467
 
                        if ( printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername) )
1468
 
                        {
1469
 
                                DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer->info_2->printername));
1470
 
 
1471
 
                                if ( !set_driver_init(printer, 2) ) {
1472
 
                                        DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1473
 
                                                printer->info_2->printername, printer->info_2->drivername));
1474
 
                                }
1475
 
 
1476
 
                                result = mod_a_printer( printer, 2 );
1477
 
                                if ( !W_ERROR_IS_OK(result) ) {
1478
 
                                        DEBUG(3,("reset_all_printerdata: mod_a_printer() failed!  (%s)\n",
1479
 
                                                get_dos_error_msg(result)));
1480
 
                                }
1481
 
                        }
1482
 
 
1483
 
                        free_a_printer( &printer, 2 );
1484
 
                }
1485
 
        }
1486
 
 
1487
 
        /* all done */
1488
 
 
1489
 
        return;
1490
 
}
1491
 
 
1492
 
/****************************************************************
1493
 
 _spoolss_OpenPrinter
1494
 
****************************************************************/
1495
 
 
1496
 
WERROR _spoolss_OpenPrinter(pipes_struct *p,
1497
 
                            struct spoolss_OpenPrinter *r)
1498
 
{
1499
 
        struct spoolss_OpenPrinterEx e;
1500
 
        WERROR werr;
1501
 
 
1502
 
        ZERO_STRUCT(e.in.userlevel);
1503
 
 
1504
 
        e.in.printername        = r->in.printername;
1505
 
        e.in.datatype           = r->in.datatype;
1506
 
        e.in.devmode_ctr        = r->in.devmode_ctr;
1507
 
        e.in.access_mask        = r->in.access_mask;
1508
 
        e.in.level              = 0;
1509
 
 
1510
 
        e.out.handle            = r->out.handle;
1511
 
 
1512
 
        werr = _spoolss_OpenPrinterEx(p, &e);
1513
 
 
1514
 
        if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1515
 
                /* OpenPrinterEx returns this for a bad
1516
 
                 * printer name. We must return WERR_INVALID_PRINTER_NAME
1517
 
                 * instead.
1518
 
                 */
1519
 
                werr = WERR_INVALID_PRINTER_NAME;
1520
 
        }
1521
 
 
1522
 
        return werr;
1523
 
}
1524
 
 
1525
 
/********************************************************************
1526
 
 ********************************************************************/
1527
 
 
1528
 
bool convert_devicemode(const char *printername,
1529
 
                        const struct spoolss_DeviceMode *devmode,
1530
 
                        NT_DEVICEMODE **pp_nt_devmode)
1531
 
{
1532
 
        NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
1533
 
 
1534
 
        /*
1535
 
         * Ensure nt_devmode is a valid pointer
1536
 
         * as we will be overwriting it.
1537
 
         */
1538
 
 
1539
 
        if (nt_devmode == NULL) {
1540
 
                DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1541
 
                if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
1542
 
                        return false;
1543
 
        }
1544
 
 
1545
 
        fstrcpy(nt_devmode->devicename, devmode->devicename);
1546
 
        fstrcpy(nt_devmode->formname, devmode->formname);
1547
 
 
1548
 
        nt_devmode->devicename[31] = '\0';
1549
 
        nt_devmode->formname[31] = '\0';
1550
 
 
1551
 
        nt_devmode->specversion         = devmode->specversion;
1552
 
        nt_devmode->driverversion       = devmode->driverversion;
1553
 
        nt_devmode->size                = devmode->size;
1554
 
        nt_devmode->fields              = devmode->fields;
1555
 
        nt_devmode->orientation         = devmode->orientation;
1556
 
        nt_devmode->papersize           = devmode->papersize;
1557
 
        nt_devmode->paperlength         = devmode->paperlength;
1558
 
        nt_devmode->paperwidth          = devmode->paperwidth;
1559
 
        nt_devmode->scale               = devmode->scale;
1560
 
        nt_devmode->copies              = devmode->copies;
1561
 
        nt_devmode->defaultsource       = devmode->defaultsource;
1562
 
        nt_devmode->printquality        = devmode->printquality;
1563
 
        nt_devmode->color               = devmode->color;
1564
 
        nt_devmode->duplex              = devmode->duplex;
1565
 
        nt_devmode->yresolution         = devmode->yresolution;
1566
 
        nt_devmode->ttoption            = devmode->ttoption;
1567
 
        nt_devmode->collate             = devmode->collate;
1568
 
 
1569
 
        nt_devmode->logpixels           = devmode->logpixels;
1570
 
        nt_devmode->bitsperpel          = devmode->bitsperpel;
1571
 
        nt_devmode->pelswidth           = devmode->pelswidth;
1572
 
        nt_devmode->pelsheight          = devmode->pelsheight;
1573
 
        nt_devmode->displayflags        = devmode->displayflags;
1574
 
        nt_devmode->displayfrequency    = devmode->displayfrequency;
1575
 
        nt_devmode->icmmethod           = devmode->icmmethod;
1576
 
        nt_devmode->icmintent           = devmode->icmintent;
1577
 
        nt_devmode->mediatype           = devmode->mediatype;
1578
 
        nt_devmode->dithertype          = devmode->dithertype;
1579
 
        nt_devmode->reserved1           = devmode->reserved1;
1580
 
        nt_devmode->reserved2           = devmode->reserved2;
1581
 
        nt_devmode->panningwidth        = devmode->panningwidth;
1582
 
        nt_devmode->panningheight       = devmode->panningheight;
1583
 
 
1584
 
        /*
1585
 
         * Only change private and driverextra if the incoming devmode
1586
 
         * has a new one. JRA.
1587
 
         */
1588
 
 
1589
 
        if ((devmode->__driverextra_length != 0) && (devmode->driverextra_data.data != NULL)) {
1590
 
                SAFE_FREE(nt_devmode->nt_dev_private);
1591
 
                nt_devmode->driverextra = devmode->__driverextra_length;
1592
 
                if((nt_devmode->nt_dev_private = SMB_MALLOC_ARRAY(uint8_t, nt_devmode->driverextra)) == NULL)
1593
 
                        return false;
1594
 
                memcpy(nt_devmode->nt_dev_private, devmode->driverextra_data.data, nt_devmode->driverextra);
1595
 
        }
1596
 
 
1597
 
        *pp_nt_devmode = nt_devmode;
1598
 
 
1599
 
        return true;
1600
 
}
1601
 
 
1602
 
/****************************************************************
1603
 
 _spoolss_OpenPrinterEx
1604
 
****************************************************************/
1605
 
 
1606
 
WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
1607
 
                              struct spoolss_OpenPrinterEx *r)
1608
 
{
1609
 
        int snum;
1610
 
        Printer_entry *Printer=NULL;
1611
 
 
1612
 
        if (!r->in.printername) {
1613
 
                return WERR_INVALID_PARAM;
1614
 
        }
1615
 
 
1616
 
        /* some sanity check because you can open a printer or a print server */
1617
 
        /* aka: \\server\printer or \\server */
1618
 
 
1619
 
        DEBUGADD(3,("checking name: %s\n", r->in.printername));
1620
 
 
1621
 
        if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
1622
 
                ZERO_STRUCTP(r->out.handle);
1623
 
                return WERR_INVALID_PARAM;
1624
 
        }
1625
 
 
1626
 
        Printer = find_printer_index_by_hnd(p, r->out.handle);
1627
 
        if ( !Printer ) {
1628
 
                DEBUG(0,("_spoolss_OpenPrinterEx: logic error.  Can't find printer "
1629
 
                        "handle we created for printer %s\n", r->in.printername));
1630
 
                close_printer_handle(p, r->out.handle);
1631
 
                ZERO_STRUCTP(r->out.handle);
1632
 
                return WERR_INVALID_PARAM;
1633
 
        }
1634
 
 
1635
 
        /*
1636
 
         * First case: the user is opening the print server:
1637
 
         *
1638
 
         * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1639
 
         * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1640
 
         *
1641
 
         * Then both Win2k and WinNT clients try an OpenPrinterEx with
1642
 
         * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1643
 
         * or if the user is listed in the smb.conf printer admin parameter.
1644
 
         *
1645
 
         * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1646
 
         * client view printer folder, but does not show the MSAPW.
1647
 
         *
1648
 
         * Note: this test needs code to check access rights here too. Jeremy
1649
 
         * could you look at this?
1650
 
         *
1651
 
         * Second case: the user is opening a printer:
1652
 
         * NT doesn't let us connect to a printer if the connecting user
1653
 
         * doesn't have print permission.
1654
 
         *
1655
 
         * Third case: user is opening a Port Monitor
1656
 
         * access checks same as opening a handle to the print server.
1657
 
         */
1658
 
 
1659
 
        switch (Printer->printer_type )
1660
 
        {
1661
 
        case SPLHND_SERVER:
1662
 
        case SPLHND_PORTMON_TCP:
1663
 
        case SPLHND_PORTMON_LOCAL:
1664
 
                /* Printserver handles use global struct... */
1665
 
 
1666
 
                snum = -1;
1667
 
 
1668
 
                /* Map standard access rights to object specific access rights */
1669
 
 
1670
 
                se_map_standard(&r->in.access_mask,
1671
 
                                &printserver_std_mapping);
1672
 
 
1673
 
                /* Deny any object specific bits that don't apply to print
1674
 
                   servers (i.e printer and job specific bits) */
1675
 
 
1676
 
                r->in.access_mask &= SPECIFIC_RIGHTS_MASK;
1677
 
 
1678
 
                if (r->in.access_mask &
1679
 
                    ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1680
 
                        DEBUG(3, ("access DENIED for non-printserver bits\n"));
1681
 
                        close_printer_handle(p, r->out.handle);
1682
 
                        ZERO_STRUCTP(r->out.handle);
1683
 
                        return WERR_ACCESS_DENIED;
1684
 
                }
1685
 
 
1686
 
                /* Allow admin access */
1687
 
 
1688
 
                if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1689
 
                {
1690
 
                        SE_PRIV se_printop = SE_PRINT_OPERATOR;
1691
 
 
1692
 
                        if (!lp_ms_add_printer_wizard()) {
1693
 
                                close_printer_handle(p, r->out.handle);
1694
 
                                ZERO_STRUCTP(r->out.handle);
1695
 
                                return WERR_ACCESS_DENIED;
1696
 
                        }
1697
 
 
1698
 
                        /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1699
 
                           and not a printer admin, then fail */
1700
 
 
1701
 
                        if ((p->server_info->utok.uid != sec_initial_uid()) &&
1702
 
                            !user_has_privileges(p->server_info->ptok,
1703
 
                                                 &se_printop ) &&
1704
 
                            !token_contains_name_in_list(
1705
 
                                    uidtoname(p->server_info->utok.uid),
1706
 
                                    pdb_get_domain(p->server_info->sam_account),
1707
 
                                    NULL,
1708
 
                                    p->server_info->ptok,
1709
 
                                    lp_printer_admin(snum))) {
1710
 
                                close_printer_handle(p, r->out.handle);
1711
 
                                ZERO_STRUCTP(r->out.handle);
1712
 
                                return WERR_ACCESS_DENIED;
1713
 
                        }
1714
 
 
1715
 
                        r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1716
 
                }
1717
 
                else
1718
 
                {
1719
 
                        r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1720
 
                }
1721
 
 
1722
 
                DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1723
 
                        ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1724
 
 
1725
 
                /* We fall through to return WERR_OK */
1726
 
                break;
1727
 
 
1728
 
        case SPLHND_PRINTER:
1729
 
                /* NT doesn't let us connect to a printer if the connecting user
1730
 
                   doesn't have print permission.  */
1731
 
 
1732
 
                if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1733
 
                        close_printer_handle(p, r->out.handle);
1734
 
                        ZERO_STRUCTP(r->out.handle);
1735
 
                        return WERR_BADFID;
1736
 
                }
1737
 
 
1738
 
                if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
1739
 
                        r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1740
 
                }
1741
 
 
1742
 
                se_map_standard(&r->in.access_mask, &printer_std_mapping);
1743
 
 
1744
 
                /* map an empty access mask to the minimum access mask */
1745
 
                if (r->in.access_mask == 0x0)
1746
 
                        r->in.access_mask = PRINTER_ACCESS_USE;
1747
 
 
1748
 
                /*
1749
 
                 * If we are not serving the printer driver for this printer,
1750
 
                 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE.  This
1751
 
                 * will keep NT clients happy  --jerry
1752
 
                 */
1753
 
 
1754
 
                if (lp_use_client_driver(snum)
1755
 
                        && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1756
 
                {
1757
 
                        r->in.access_mask = PRINTER_ACCESS_USE;
1758
 
                }
1759
 
 
1760
 
                /* check smb.conf parameters and the the sec_desc */
1761
 
 
1762
 
                if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1763
 
                        DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1764
 
                        ZERO_STRUCTP(r->out.handle);
1765
 
                        return WERR_ACCESS_DENIED;
1766
 
                }
1767
 
 
1768
 
                if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1769
 
                                   p->server_info->ptok, snum) ||
1770
 
                    !print_access_check(p->server_info, snum,
1771
 
                                        r->in.access_mask)) {
1772
 
                        DEBUG(3, ("access DENIED for printer open\n"));
1773
 
                        close_printer_handle(p, r->out.handle);
1774
 
                        ZERO_STRUCTP(r->out.handle);
1775
 
                        return WERR_ACCESS_DENIED;
1776
 
                }
1777
 
 
1778
 
                if ((r->in.access_mask & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1779
 
                        DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1780
 
                        close_printer_handle(p, r->out.handle);
1781
 
                        ZERO_STRUCTP(r->out.handle);
1782
 
                        return WERR_ACCESS_DENIED;
1783
 
                }
1784
 
 
1785
 
                if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1786
 
                        r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1787
 
                else
1788
 
                        r->in.access_mask = PRINTER_ACCESS_USE;
1789
 
 
1790
 
                DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1791
 
                        ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1792
 
 
1793
 
                break;
1794
 
 
1795
 
        default:
1796
 
                /* sanity check to prevent programmer error */
1797
 
                ZERO_STRUCTP(r->out.handle);
1798
 
                return WERR_BADFID;
1799
 
        }
1800
 
 
1801
 
        Printer->access_granted = r->in.access_mask;
1802
 
 
1803
 
        /*
1804
 
         * If the client sent a devmode in the OpenPrinter() call, then
1805
 
         * save it here in case we get a job submission on this handle
1806
 
         */
1807
 
 
1808
 
         if ((Printer->printer_type != SPLHND_SERVER) &&
1809
 
             r->in.devmode_ctr.devmode) {
1810
 
                convert_devicemode(Printer->sharename,
1811
 
                                   r->in.devmode_ctr.devmode,
1812
 
                                   &Printer->nt_devmode);
1813
 
         }
1814
 
 
1815
 
#if 0   /* JERRY -- I'm doubtful this is really effective */
1816
 
        /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1817
 
           optimization in Windows 2000 clients  --jerry */
1818
 
 
1819
 
        if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1820
 
                && (RA_WIN2K == get_remote_arch()) )
1821
 
        {
1822
 
                DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1823
 
                sys_usleep( 500000 );
1824
 
        }
1825
 
#endif
1826
 
 
1827
 
        return WERR_OK;
1828
 
}
1829
 
 
1830
 
/****************************************************************************
1831
 
****************************************************************************/
1832
 
 
1833
 
static bool printer_info2_to_nt_printer_info2(struct spoolss_SetPrinterInfo2 *r,
1834
 
                                              NT_PRINTER_INFO_LEVEL_2 *d)
1835
 
{
1836
 
        DEBUG(7,("printer_info2_to_nt_printer_info2\n"));
1837
 
 
1838
 
        if (!r || !d) {
1839
 
                return false;
1840
 
        }
1841
 
 
1842
 
        d->attributes           = r->attributes;
1843
 
        d->priority             = r->priority;
1844
 
        d->default_priority     = r->defaultpriority;
1845
 
        d->starttime            = r->starttime;
1846
 
        d->untiltime            = r->untiltime;
1847
 
        d->status               = r->status;
1848
 
        d->cjobs                = r->cjobs;
1849
 
 
1850
 
        fstrcpy(d->servername,  r->servername);
1851
 
        fstrcpy(d->printername, r->printername);
1852
 
        fstrcpy(d->sharename,   r->sharename);
1853
 
        fstrcpy(d->portname,    r->portname);
1854
 
        fstrcpy(d->drivername,  r->drivername);
1855
 
        slprintf(d->comment, sizeof(d->comment)-1, "%s", r->comment);
1856
 
        fstrcpy(d->location,    r->location);
1857
 
        fstrcpy(d->sepfile,     r->sepfile);
1858
 
        fstrcpy(d->printprocessor, r->printprocessor);
1859
 
        fstrcpy(d->datatype,    r->datatype);
1860
 
        fstrcpy(d->parameters,  r->parameters);
1861
 
 
1862
 
        return true;
1863
 
}
1864
 
 
1865
 
/****************************************************************************
1866
 
****************************************************************************/
1867
 
 
1868
 
static bool convert_printer_info(struct spoolss_SetPrinterInfoCtr *info_ctr,
1869
 
                                 NT_PRINTER_INFO_LEVEL *printer)
1870
 
{
1871
 
        bool ret;
1872
 
 
1873
 
        switch (info_ctr->level) {
1874
 
        case 2:
1875
 
                /* allocate memory if needed.  Messy because
1876
 
                   convert_printer_info is used to update an existing
1877
 
                   printer or build a new one */
1878
 
 
1879
 
                if (!printer->info_2) {
1880
 
                        printer->info_2 = TALLOC_ZERO_P(printer, NT_PRINTER_INFO_LEVEL_2);
1881
 
                        if (!printer->info_2) {
1882
 
                                DEBUG(0,("convert_printer_info: "
1883
 
                                        "talloc() failed!\n"));
1884
 
                                return false;
1885
 
                        }
1886
 
                }
1887
 
 
1888
 
                ret = printer_info2_to_nt_printer_info2(info_ctr->info.info2,
1889
 
                                                        printer->info_2);
1890
 
                printer->info_2->setuptime = time(NULL);
1891
 
                return ret;
1892
 
        }
1893
 
 
1894
 
        return false;
1895
 
}
1896
 
 
1897
 
/****************************************************************
1898
 
 _spoolss_ClosePrinter
1899
 
****************************************************************/
1900
 
 
1901
 
WERROR _spoolss_ClosePrinter(pipes_struct *p,
1902
 
                             struct spoolss_ClosePrinter *r)
1903
 
{
1904
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1905
 
 
1906
 
        if (Printer && Printer->document_started) {
1907
 
                struct spoolss_EndDocPrinter e;
1908
 
 
1909
 
                e.in.handle = r->in.handle;
1910
 
 
1911
 
                _spoolss_EndDocPrinter(p, &e);
1912
 
        }
1913
 
 
1914
 
        if (!close_printer_handle(p, r->in.handle))
1915
 
                return WERR_BADFID;
1916
 
 
1917
 
        /* clear the returned printer handle.  Observed behavior
1918
 
           from Win2k server.  Don't think this really matters.
1919
 
           Previous code just copied the value of the closed
1920
 
           handle.    --jerry */
1921
 
 
1922
 
        ZERO_STRUCTP(r->out.handle);
1923
 
 
1924
 
        return WERR_OK;
1925
 
}
1926
 
 
1927
 
/****************************************************************
1928
 
 _spoolss_DeletePrinter
1929
 
****************************************************************/
1930
 
 
1931
 
WERROR _spoolss_DeletePrinter(pipes_struct *p,
1932
 
                              struct spoolss_DeletePrinter *r)
1933
 
{
1934
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1935
 
        WERROR result;
1936
 
 
1937
 
        if (Printer && Printer->document_started) {
1938
 
                struct spoolss_EndDocPrinter e;
1939
 
 
1940
 
                e.in.handle = r->in.handle;
1941
 
 
1942
 
                _spoolss_EndDocPrinter(p, &e);
1943
 
        }
1944
 
 
1945
 
        result = delete_printer_handle(p, r->in.handle);
1946
 
 
1947
 
        update_c_setprinter(false);
1948
 
 
1949
 
        return result;
1950
 
}
1951
 
 
1952
 
/*******************************************************************
1953
 
 * static function to lookup the version id corresponding to an
1954
 
 * long architecture string
1955
 
 ******************************************************************/
1956
 
 
1957
 
static const struct print_architecture_table_node archi_table[]= {
1958
 
 
1959
 
        {"Windows 4.0",          SPL_ARCH_WIN40,        0 },
1960
 
        {"Windows NT x86",       SPL_ARCH_W32X86,       2 },
1961
 
        {"Windows NT R4000",     SPL_ARCH_W32MIPS,      2 },
1962
 
        {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA,     2 },
1963
 
        {"Windows NT PowerPC",   SPL_ARCH_W32PPC,       2 },
1964
 
        {"Windows IA64",         SPL_ARCH_IA64,         3 },
1965
 
        {"Windows x64",          SPL_ARCH_X64,          3 },
1966
 
        {NULL,                   "",            -1 }
1967
 
};
1968
 
 
1969
 
static int get_version_id(const char *arch)
1970
 
{
1971
 
        int i;
1972
 
 
1973
 
        for (i=0; archi_table[i].long_archi != NULL; i++)
1974
 
        {
1975
 
                if (strcmp(arch, archi_table[i].long_archi) == 0)
1976
 
                        return (archi_table[i].version);
1977
 
        }
1978
 
 
1979
 
        return -1;
1980
 
}
1981
 
 
1982
 
/****************************************************************
1983
 
 _spoolss_DeletePrinterDriver
1984
 
****************************************************************/
1985
 
 
1986
 
WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
1987
 
                                    struct spoolss_DeletePrinterDriver *r)
1988
 
{
1989
 
 
1990
 
        struct spoolss_DriverInfo8 *info = NULL;
1991
 
        struct spoolss_DriverInfo8 *info_win2k = NULL;
1992
 
        int                             version;
1993
 
        WERROR                          status;
1994
 
        WERROR                          status_win2k = WERR_ACCESS_DENIED;
1995
 
        SE_PRIV                         se_printop = SE_PRINT_OPERATOR;
1996
 
 
1997
 
        /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1998
 
           and not a printer admin, then fail */
1999
 
 
2000
 
        if ( (p->server_info->utok.uid != sec_initial_uid())
2001
 
                && !user_has_privileges(p->server_info->ptok, &se_printop )
2002
 
                && !token_contains_name_in_list(
2003
 
                        uidtoname(p->server_info->utok.uid),
2004
 
                        pdb_get_domain(p->server_info->sam_account),
2005
 
                        NULL,
2006
 
                        p->server_info->ptok,
2007
 
                        lp_printer_admin(-1)) )
2008
 
        {
2009
 
                return WERR_ACCESS_DENIED;
2010
 
        }
2011
 
 
2012
 
        /* check that we have a valid driver name first */
2013
 
 
2014
 
        if ((version = get_version_id(r->in.architecture)) == -1)
2015
 
                return WERR_INVALID_ENVIRONMENT;
2016
 
 
2017
 
        if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &info, r->in.driver,
2018
 
                                                r->in.architecture,
2019
 
                                                version)))
2020
 
        {
2021
 
                /* try for Win2k driver if "Windows NT x86" */
2022
 
 
2023
 
                if ( version == 2 ) {
2024
 
                        version = 3;
2025
 
                        if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx,
2026
 
                                                                &info,
2027
 
                                                                r->in.driver,
2028
 
                                                                r->in.architecture,
2029
 
                                                                version))) {
2030
 
                                status = WERR_UNKNOWN_PRINTER_DRIVER;
2031
 
                                goto done;
2032
 
                        }
2033
 
                }
2034
 
                /* otherwise it was a failure */
2035
 
                else {
2036
 
                        status = WERR_UNKNOWN_PRINTER_DRIVER;
2037
 
                        goto done;
2038
 
                }
2039
 
 
2040
 
        }
2041
 
 
2042
 
        if (printer_driver_in_use(info)) {
2043
 
                status = WERR_PRINTER_DRIVER_IN_USE;
2044
 
                goto done;
2045
 
        }
2046
 
 
2047
 
        if ( version == 2 )
2048
 
        {
2049
 
                if (W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx,
2050
 
                                                       &info_win2k,
2051
 
                                                       r->in.driver,
2052
 
                                                       r->in.architecture, 3)))
2053
 
                {
2054
 
                        /* if we get to here, we now have 2 driver info structures to remove */
2055
 
                        /* remove the Win2k driver first*/
2056
 
 
2057
 
                        status_win2k = delete_printer_driver(
2058
 
                                p, info_win2k, 3, false);
2059
 
                        free_a_printer_driver(info_win2k);
2060
 
 
2061
 
                        /* this should not have failed---if it did, report to client */
2062
 
                        if ( !W_ERROR_IS_OK(status_win2k) )
2063
 
                        {
2064
 
                                status = status_win2k;
2065
 
                                goto done;
2066
 
                        }
2067
 
                }
2068
 
        }
2069
 
 
2070
 
        status = delete_printer_driver(p, info, version, false);
2071
 
 
2072
 
        /* if at least one of the deletes succeeded return OK */
2073
 
 
2074
 
        if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2075
 
                status = WERR_OK;
2076
 
 
2077
 
done:
2078
 
        free_a_printer_driver(info);
2079
 
 
2080
 
        return status;
2081
 
}
2082
 
 
2083
 
/****************************************************************
2084
 
 _spoolss_DeletePrinterDriverEx
2085
 
****************************************************************/
2086
 
 
2087
 
WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
2088
 
                                      struct spoolss_DeletePrinterDriverEx *r)
2089
 
{
2090
 
        struct spoolss_DriverInfo8      *info = NULL;
2091
 
        struct spoolss_DriverInfo8      *info_win2k = NULL;
2092
 
        int                             version;
2093
 
        bool                            delete_files;
2094
 
        WERROR                          status;
2095
 
        WERROR                          status_win2k = WERR_ACCESS_DENIED;
2096
 
        SE_PRIV                         se_printop = SE_PRINT_OPERATOR;
2097
 
 
2098
 
        /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2099
 
           and not a printer admin, then fail */
2100
 
 
2101
 
        if ( (p->server_info->utok.uid != sec_initial_uid())
2102
 
                && !user_has_privileges(p->server_info->ptok, &se_printop )
2103
 
                && !token_contains_name_in_list(
2104
 
                        uidtoname(p->server_info->utok.uid),
2105
 
                        pdb_get_domain(p->server_info->sam_account),
2106
 
                        NULL,
2107
 
                        p->server_info->ptok, lp_printer_admin(-1)) )
2108
 
        {
2109
 
                return WERR_ACCESS_DENIED;
2110
 
        }
2111
 
 
2112
 
        /* check that we have a valid driver name first */
2113
 
        if ((version = get_version_id(r->in.architecture)) == -1) {
2114
 
                /* this is what NT returns */
2115
 
                return WERR_INVALID_ENVIRONMENT;
2116
 
        }
2117
 
 
2118
 
        if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
2119
 
                version = r->in.version;
2120
 
 
2121
 
        status = get_a_printer_driver(p->mem_ctx, &info, r->in.driver,
2122
 
                                      r->in.architecture, version);
2123
 
 
2124
 
        if ( !W_ERROR_IS_OK(status) )
2125
 
        {
2126
 
                /*
2127
 
                 * if the client asked for a specific version,
2128
 
                 * or this is something other than Windows NT x86,
2129
 
                 * then we've failed
2130
 
                 */
2131
 
 
2132
 
                if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
2133
 
                        goto done;
2134
 
 
2135
 
                /* try for Win2k driver if "Windows NT x86" */
2136
 
 
2137
 
                version = 3;
2138
 
                if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &info, r->in.driver,
2139
 
                                                        r->in.architecture,
2140
 
                                                        version))) {
2141
 
                        status = WERR_UNKNOWN_PRINTER_DRIVER;
2142
 
                        goto done;
2143
 
                }
2144
 
        }
2145
 
 
2146
 
        if (printer_driver_in_use(info)) {
2147
 
                status = WERR_PRINTER_DRIVER_IN_USE;
2148
 
                goto done;
2149
 
        }
2150
 
 
2151
 
        /*
2152
 
         * we have a couple of cases to consider.
2153
 
         * (1) Are any files in use?  If so and DPD_DELTE_ALL_FILE is set,
2154
 
         *     then the delete should fail if **any** files overlap with
2155
 
         *     other drivers
2156
 
         * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2157
 
         *     non-overlapping files
2158
 
         * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2159
 
         *     is set, the do not delete any files
2160
 
         * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2161
 
         */
2162
 
 
2163
 
        delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
2164
 
 
2165
 
        /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2166
 
 
2167
 
        if (delete_files && printer_driver_files_in_use(info, info) & (r->in.delete_flags & DPD_DELETE_ALL_FILES)) {
2168
 
                /* no idea of the correct error here */
2169
 
                status = WERR_ACCESS_DENIED;
2170
 
                goto done;
2171
 
        }
2172
 
 
2173
 
 
2174
 
        /* also check for W32X86/3 if necessary; maybe we already have? */
2175
 
 
2176
 
        if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION)  ) {
2177
 
                if (W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &info_win2k,
2178
 
                                                       r->in.driver,
2179
 
                                                       r->in.architecture, 3)))
2180
 
                {
2181
 
 
2182
 
                        if (delete_files && printer_driver_files_in_use(info, info_win2k) & (r->in.delete_flags & DPD_DELETE_ALL_FILES) ) {
2183
 
                                /* no idea of the correct error here */
2184
 
                                free_a_printer_driver(info_win2k);
2185
 
                                status = WERR_ACCESS_DENIED;
2186
 
                                goto done;
2187
 
                        }
2188
 
 
2189
 
                        /* if we get to here, we now have 2 driver info structures to remove */
2190
 
                        /* remove the Win2k driver first*/
2191
 
 
2192
 
                        status_win2k = delete_printer_driver(
2193
 
                                p, info_win2k, 3, delete_files);
2194
 
                        free_a_printer_driver(info_win2k);
2195
 
 
2196
 
                        /* this should not have failed---if it did, report to client */
2197
 
 
2198
 
                        if ( !W_ERROR_IS_OK(status_win2k) )
2199
 
                                goto done;
2200
 
                }
2201
 
        }
2202
 
 
2203
 
        status = delete_printer_driver(p, info, version, delete_files);
2204
 
 
2205
 
        if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2206
 
                status = WERR_OK;
2207
 
done:
2208
 
        free_a_printer_driver(info);
2209
 
 
2210
 
        return status;
2211
 
}
2212
 
 
2213
 
 
2214
 
/****************************************************************************
2215
 
 Internal routine for removing printerdata
2216
 
 ***************************************************************************/
2217
 
 
2218
 
static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value )
2219
 
{
2220
 
        return delete_printer_data( printer->info_2, key, value );
2221
 
}
2222
 
 
2223
 
/****************************************************************************
2224
 
 Internal routine for storing printerdata
2225
 
 ***************************************************************************/
2226
 
 
2227
 
WERROR set_printer_dataex(NT_PRINTER_INFO_LEVEL *printer,
2228
 
                          const char *key, const char *value,
2229
 
                          uint32_t type, uint8_t *data, int real_len)
2230
 
{
2231
 
        /* the registry objects enforce uniqueness based on value name */
2232
 
 
2233
 
        return add_printer_data( printer->info_2, key, value, type, data, real_len );
2234
 
}
2235
 
 
2236
 
/********************************************************************
2237
 
 GetPrinterData on a printer server Handle.
2238
 
********************************************************************/
2239
 
 
2240
 
static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2241
 
                                            const char *value,
2242
 
                                            enum winreg_Type *type,
2243
 
                                            union spoolss_PrinterData *data)
2244
 
{
2245
 
        DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2246
 
 
2247
 
        if (!StrCaseCmp(value, "W3SvcInstalled")) {
2248
 
                *type = REG_DWORD;
2249
 
                data->value = 0x00;
2250
 
                return WERR_OK;
2251
 
        }
2252
 
 
2253
 
        if (!StrCaseCmp(value, "BeepEnabled")) {
2254
 
                *type = REG_DWORD;
2255
 
                data->value = 0x00;
2256
 
                return WERR_OK;
2257
 
        }
2258
 
 
2259
 
        if (!StrCaseCmp(value, "EventLog")) {
2260
 
                *type = REG_DWORD;
2261
 
                /* formally was 0x1b */
2262
 
                data->value = 0x00;
2263
 
                return WERR_OK;
2264
 
        }
2265
 
 
2266
 
        if (!StrCaseCmp(value, "NetPopup")) {
2267
 
                *type = REG_DWORD;
2268
 
                data->value = 0x00;
2269
 
                return WERR_OK;
2270
 
        }
2271
 
 
2272
 
        if (!StrCaseCmp(value, "MajorVersion")) {
2273
 
                *type = REG_DWORD;
2274
 
 
2275
 
                /* Windows NT 4.0 seems to not allow uploading of drivers
2276
 
                   to a server that reports 0x3 as the MajorVersion.
2277
 
                   need to investigate more how Win2k gets around this .
2278
 
                   -- jerry */
2279
 
 
2280
 
                if (RA_WINNT == get_remote_arch()) {
2281
 
                        data->value = 0x02;
2282
 
                } else {
2283
 
                        data->value = 0x03;
2284
 
                }
2285
 
 
2286
 
                return WERR_OK;
2287
 
        }
2288
 
 
2289
 
        if (!StrCaseCmp(value, "MinorVersion")) {
2290
 
                *type = REG_DWORD;
2291
 
                data->value = 0x00;
2292
 
                return WERR_OK;
2293
 
        }
2294
 
 
2295
 
        /* REG_BINARY
2296
 
         *  uint32_t size        = 0x114
2297
 
         *  uint32_t major       = 5
2298
 
         *  uint32_t minor       = [0|1]
2299
 
         *  uint32_t build       = [2195|2600]
2300
 
         *  extra unicode string = e.g. "Service Pack 3"
2301
 
         */
2302
 
        if (!StrCaseCmp(value, "OSVersion")) {
2303
 
                DATA_BLOB blob;
2304
 
                enum ndr_err_code ndr_err;
2305
 
                struct spoolss_OSVersion os;
2306
 
 
2307
 
                os.major                = 5;    /* Windows 2000 == 5.0 */
2308
 
                os.minor                = 0;
2309
 
                os.build                = 2195; /* build */
2310
 
                os.extra_string         = "";   /* leave extra string empty */
2311
 
 
2312
 
                ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, &os,
2313
 
                        (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2314
 
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2315
 
                        return WERR_GENERAL_FAILURE;
2316
 
                }
2317
 
 
2318
 
                *type = REG_BINARY;
2319
 
                data->binary = blob;
2320
 
 
2321
 
                return WERR_OK;
2322
 
        }
2323
 
 
2324
 
 
2325
 
        if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2326
 
                *type = REG_SZ;
2327
 
 
2328
 
                data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
2329
 
                W_ERROR_HAVE_NO_MEMORY(data->string);
2330
 
 
2331
 
                return WERR_OK;
2332
 
        }
2333
 
 
2334
 
        if (!StrCaseCmp(value, "Architecture")) {
2335
 
                *type = REG_SZ;
2336
 
 
2337
 
                data->string = talloc_strdup(mem_ctx, "Windows NT x86");
2338
 
                W_ERROR_HAVE_NO_MEMORY(data->string);
2339
 
 
2340
 
                return WERR_OK;
2341
 
        }
2342
 
 
2343
 
        if (!StrCaseCmp(value, "DsPresent")) {
2344
 
                *type = REG_DWORD;
2345
 
 
2346
 
                /* only show the publish check box if we are a
2347
 
                   member of a AD domain */
2348
 
 
2349
 
                if (lp_security() == SEC_ADS) {
2350
 
                        data->value = 0x01;
2351
 
                } else {
2352
 
                        data->value = 0x00;
2353
 
                }
2354
 
                return WERR_OK;
2355
 
        }
2356
 
 
2357
 
        if (!StrCaseCmp(value, "DNSMachineName")) {
2358
 
                const char *hostname = get_mydnsfullname();
2359
 
 
2360
 
                if (!hostname) {
2361
 
                        return WERR_BADFILE;
2362
 
                }
2363
 
 
2364
 
                *type = REG_SZ;
2365
 
                data->string = talloc_strdup(mem_ctx, hostname);
2366
 
                W_ERROR_HAVE_NO_MEMORY(data->string);
2367
 
 
2368
 
                return WERR_OK;
2369
 
        }
2370
 
 
2371
 
        *type = REG_NONE;
2372
 
 
2373
 
        return WERR_INVALID_PARAM;
2374
 
}
2375
 
 
2376
 
/****************************************************************
2377
 
 _spoolss_GetPrinterData
2378
 
****************************************************************/
2379
 
 
2380
 
WERROR _spoolss_GetPrinterData(pipes_struct *p,
2381
 
                               struct spoolss_GetPrinterData *r)
2382
 
{
2383
 
        struct spoolss_GetPrinterDataEx r2;
2384
 
 
2385
 
        r2.in.handle            = r->in.handle;
2386
 
        r2.in.key_name          = "PrinterDriverData";
2387
 
        r2.in.value_name        = r->in.value_name;
2388
 
        r2.in.offered           = r->in.offered;
2389
 
        r2.out.type             = r->out.type;
2390
 
        r2.out.data             = r->out.data;
2391
 
        r2.out.needed           = r->out.needed;
2392
 
 
2393
 
        return _spoolss_GetPrinterDataEx(p, &r2);
2394
 
}
2395
 
 
2396
 
/*********************************************************
2397
 
 Connect to the client machine.
2398
 
**********************************************************/
2399
 
 
2400
 
static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2401
 
                        struct sockaddr_storage *client_ss, const char *remote_machine)
2402
 
{
2403
 
        NTSTATUS ret;
2404
 
        struct cli_state *the_cli;
2405
 
        struct sockaddr_storage rm_addr;
2406
 
 
2407
 
        if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2408
 
                if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2409
 
                        DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2410
 
                        return false;
2411
 
                }
2412
 
 
2413
 
                if (ismyaddr((struct sockaddr *)&rm_addr)) {
2414
 
                        DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
2415
 
                        return false;
2416
 
                }
2417
 
        } else {
2418
 
                char addr[INET6_ADDRSTRLEN];
2419
 
                rm_addr = *client_ss;
2420
 
                print_sockaddr(addr, sizeof(addr), &rm_addr);
2421
 
                DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2422
 
                        addr));
2423
 
        }
2424
 
 
2425
 
        /* setup the connection */
2426
 
 
2427
 
        ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2428
 
                &rm_addr, 0, "IPC$", "IPC",
2429
 
                "", /* username */
2430
 
                "", /* domain */
2431
 
                "", /* password */
2432
 
                0, lp_client_signing(), NULL );
2433
 
 
2434
 
        if ( !NT_STATUS_IS_OK( ret ) ) {
2435
 
                DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2436
 
                        remote_machine ));
2437
 
                return false;
2438
 
        }
2439
 
 
2440
 
        if ( the_cli->protocol != PROTOCOL_NT1 ) {
2441
 
                DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2442
 
                cli_shutdown(the_cli);
2443
 
                return false;
2444
 
        }
2445
 
 
2446
 
        /*
2447
 
         * Ok - we have an anonymous connection to the IPC$ share.
2448
 
         * Now start the NT Domain stuff :-).
2449
 
         */
2450
 
 
2451
 
        ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
2452
 
        if (!NT_STATUS_IS_OK(ret)) {
2453
 
                DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2454
 
                        remote_machine, nt_errstr(ret)));
2455
 
                cli_shutdown(the_cli);
2456
 
                return false;
2457
 
        }
2458
 
 
2459
 
        return true;
2460
 
}
2461
 
 
2462
 
/***************************************************************************
2463
 
 Connect to the client.
2464
 
****************************************************************************/
2465
 
 
2466
 
static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2467
 
                                        uint32_t localprinter, uint32_t type,
2468
 
                                        struct policy_handle *handle,
2469
 
                                        struct sockaddr_storage *client_ss)
2470
 
{
2471
 
        WERROR result;
2472
 
        NTSTATUS status;
2473
 
 
2474
 
        /*
2475
 
         * If it's the first connection, contact the client
2476
 
         * and connect to the IPC$ share anonymously
2477
 
         */
2478
 
        if (smb_connections==0) {
2479
 
                fstring unix_printer;
2480
 
 
2481
 
                fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2482
 
 
2483
 
                if ( !spoolss_connect_to_client( &notify_cli_pipe, client_ss, unix_printer ))
2484
 
                        return false;
2485
 
 
2486
 
                messaging_register(smbd_messaging_context(), NULL,
2487
 
                                   MSG_PRINTER_NOTIFY2,
2488
 
                                   receive_notify2_message_list);
2489
 
                /* Tell the connections db we're now interested in printer
2490
 
                 * notify messages. */
2491
 
                register_message_flags(true, FLAG_MSG_PRINT_NOTIFY);
2492
 
        }
2493
 
 
2494
 
        /*
2495
 
         * Tell the specific printing tdb we want messages for this printer
2496
 
         * by registering our PID.
2497
 
         */
2498
 
 
2499
 
        if (!print_notify_register_pid(snum))
2500
 
                DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2501
 
 
2502
 
        smb_connections++;
2503
 
 
2504
 
        status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2505
 
                                                 printer,
2506
 
                                                 localprinter,
2507
 
                                                 type,
2508
 
                                                 0,
2509
 
                                                 NULL,
2510
 
                                                 handle,
2511
 
                                                 &result);
2512
 
        if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2513
 
                DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2514
 
                        win_errstr(result)));
2515
 
 
2516
 
        return (W_ERROR_IS_OK(result));
2517
 
}
2518
 
 
2519
 
/****************************************************************
2520
 
 ****************************************************************/
2521
 
 
2522
 
static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2523
 
                                                             const struct spoolss_NotifyOption *r)
2524
 
{
2525
 
        struct spoolss_NotifyOption *option;
2526
 
        uint32_t i,k;
2527
 
 
2528
 
        if (!r) {
2529
 
                return NULL;
2530
 
        }
2531
 
 
2532
 
        option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2533
 
        if (!option) {
2534
 
                return NULL;
2535
 
        }
2536
 
 
2537
 
        *option = *r;
2538
 
 
2539
 
        if (!option->count) {
2540
 
                return option;
2541
 
        }
2542
 
 
2543
 
        option->types = talloc_zero_array(option,
2544
 
                struct spoolss_NotifyOptionType, option->count);
2545
 
        if (!option->types) {
2546
 
                talloc_free(option);
2547
 
                return NULL;
2548
 
        }
2549
 
 
2550
 
        for (i=0; i < option->count; i++) {
2551
 
                option->types[i] = r->types[i];
2552
 
 
2553
 
                if (option->types[i].count) {
2554
 
                        option->types[i].fields = talloc_zero_array(option,
2555
 
                                union spoolss_Field, option->types[i].count);
2556
 
                        if (!option->types[i].fields) {
2557
 
                                talloc_free(option);
2558
 
                                return NULL;
2559
 
                        }
2560
 
                        for (k=0; k<option->types[i].count; k++) {
2561
 
                                option->types[i].fields[k] =
2562
 
                                        r->types[i].fields[k];
2563
 
                        }
2564
 
                }
2565
 
        }
2566
 
 
2567
 
        return option;
2568
 
}
2569
 
 
2570
 
/****************************************************************
2571
 
 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2572
 
 *
2573
 
 * before replying OK: status=0 a rpc call is made to the workstation
2574
 
 * asking ReplyOpenPrinter
2575
 
 *
2576
 
 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2577
 
 * called from api_spoolss_rffpcnex
2578
 
****************************************************************/
2579
 
 
2580
 
WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
2581
 
                                                     struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2582
 
{
2583
 
        int snum = -1;
2584
 
        struct spoolss_NotifyOption *option = r->in.notify_options;
2585
 
        struct sockaddr_storage client_ss;
2586
 
 
2587
 
        /* store the notify value in the printer struct */
2588
 
 
2589
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
2590
 
 
2591
 
        if (!Printer) {
2592
 
                DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2593
 
                        "Invalid handle (%s:%u:%u).\n",
2594
 
                        OUR_HANDLE(r->in.handle)));
2595
 
                return WERR_BADFID;
2596
 
        }
2597
 
 
2598
 
        Printer->notify.flags           = r->in.flags;
2599
 
        Printer->notify.options         = r->in.options;
2600
 
        Printer->notify.printerlocal    = r->in.printer_local;
2601
 
 
2602
 
        TALLOC_FREE(Printer->notify.option);
2603
 
        Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2604
 
 
2605
 
        fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2606
 
 
2607
 
        /* Connect to the client machine and send a ReplyOpenPrinter */
2608
 
 
2609
 
        if ( Printer->printer_type == SPLHND_SERVER)
2610
 
                snum = -1;
2611
 
        else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2612
 
                        !get_printer_snum(p, r->in.handle, &snum, NULL) )
2613
 
                return WERR_BADFID;
2614
 
 
2615
 
        if (!interpret_string_addr(&client_ss, p->client_address,
2616
 
                                   AI_NUMERICHOST)) {
2617
 
                return WERR_SERVER_UNAVAILABLE;
2618
 
        }
2619
 
 
2620
 
        if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2621
 
                                        Printer->notify.printerlocal, 1,
2622
 
                                        &Printer->notify.client_hnd, &client_ss))
2623
 
                return WERR_SERVER_UNAVAILABLE;
2624
 
 
2625
 
        Printer->notify.client_connected = true;
2626
 
 
2627
 
        return WERR_OK;
2628
 
}
2629
 
 
2630
 
/*******************************************************************
2631
 
 * fill a notify_info_data with the servername
2632
 
 ********************************************************************/
2633
 
 
2634
 
void spoolss_notify_server_name(int snum,
2635
 
                                       struct spoolss_Notify *data,
2636
 
                                       print_queue_struct *queue,
2637
 
                                       NT_PRINTER_INFO_LEVEL *printer,
2638
 
                                       TALLOC_CTX *mem_ctx)
2639
 
{
2640
 
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->servername);
2641
 
}
2642
 
 
2643
 
/*******************************************************************
2644
 
 * fill a notify_info_data with the printername (not including the servername).
2645
 
 ********************************************************************/
2646
 
 
2647
 
void spoolss_notify_printer_name(int snum,
2648
 
                                        struct spoolss_Notify *data,
2649
 
                                        print_queue_struct *queue,
2650
 
                                        NT_PRINTER_INFO_LEVEL *printer,
2651
 
                                        TALLOC_CTX *mem_ctx)
2652
 
{
2653
 
        /* the notify name should not contain the \\server\ part */
2654
 
        char *p = strrchr(printer->info_2->printername, '\\');
2655
 
 
2656
 
        if (!p) {
2657
 
                p = printer->info_2->printername;
2658
 
        } else {
2659
 
                p++;
2660
 
        }
2661
 
 
2662
 
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2663
 
}
2664
 
 
2665
 
/*******************************************************************
2666
 
 * fill a notify_info_data with the servicename
2667
 
 ********************************************************************/
2668
 
 
2669
 
void spoolss_notify_share_name(int snum,
2670
 
                                      struct spoolss_Notify *data,
2671
 
                                      print_queue_struct *queue,
2672
 
                                      NT_PRINTER_INFO_LEVEL *printer,
2673
 
                                      TALLOC_CTX *mem_ctx)
2674
 
{
2675
 
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2676
 
}
2677
 
 
2678
 
/*******************************************************************
2679
 
 * fill a notify_info_data with the port name
2680
 
 ********************************************************************/
2681
 
 
2682
 
void spoolss_notify_port_name(int snum,
2683
 
                                     struct spoolss_Notify *data,
2684
 
                                     print_queue_struct *queue,
2685
 
                                     NT_PRINTER_INFO_LEVEL *printer,
2686
 
                                     TALLOC_CTX *mem_ctx)
2687
 
{
2688
 
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->portname);
2689
 
}
2690
 
 
2691
 
/*******************************************************************
2692
 
 * fill a notify_info_data with the printername
2693
 
 * but it doesn't exist, have to see what to do
2694
 
 ********************************************************************/
2695
 
 
2696
 
void spoolss_notify_driver_name(int snum,
2697
 
                                       struct spoolss_Notify *data,
2698
 
                                       print_queue_struct *queue,
2699
 
                                       NT_PRINTER_INFO_LEVEL *printer,
2700
 
                                       TALLOC_CTX *mem_ctx)
2701
 
{
2702
 
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->drivername);
2703
 
}
2704
 
 
2705
 
/*******************************************************************
2706
 
 * fill a notify_info_data with the comment
2707
 
 ********************************************************************/
2708
 
 
2709
 
void spoolss_notify_comment(int snum,
2710
 
                                   struct spoolss_Notify *data,
2711
 
                                   print_queue_struct *queue,
2712
 
                                   NT_PRINTER_INFO_LEVEL *printer,
2713
 
                                   TALLOC_CTX *mem_ctx)
2714
 
{
2715
 
        char *p;
2716
 
 
2717
 
        if (*printer->info_2->comment == '\0') {
2718
 
                p = lp_comment(snum);
2719
 
        } else {
2720
 
                p = printer->info_2->comment;
2721
 
        }
2722
 
 
2723
 
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->comment);
2724
 
}
2725
 
 
2726
 
/*******************************************************************
2727
 
 * fill a notify_info_data with the comment
2728
 
 * location = "Room 1, floor 2, building 3"
2729
 
 ********************************************************************/
2730
 
 
2731
 
void spoolss_notify_location(int snum,
2732
 
                                    struct spoolss_Notify *data,
2733
 
                                    print_queue_struct *queue,
2734
 
                                    NT_PRINTER_INFO_LEVEL *printer,
2735
 
                                    TALLOC_CTX *mem_ctx)
2736
 
{
2737
 
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->location);
2738
 
}
2739
 
 
2740
 
/*******************************************************************
2741
 
 * fill a notify_info_data with the device mode
2742
 
 * jfm:xxxx don't to it for know but that's a real problem !!!
2743
 
 ********************************************************************/
2744
 
 
2745
 
static void spoolss_notify_devmode(int snum,
2746
 
                                   struct spoolss_Notify *data,
2747
 
                                   print_queue_struct *queue,
2748
 
                                   NT_PRINTER_INFO_LEVEL *printer,
2749
 
                                   TALLOC_CTX *mem_ctx)
2750
 
{
2751
 
        /* for a dummy implementation we have to zero the fields */
2752
 
        SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2753
 
}
2754
 
 
2755
 
/*******************************************************************
2756
 
 * fill a notify_info_data with the separator file name
2757
 
 ********************************************************************/
2758
 
 
2759
 
void spoolss_notify_sepfile(int snum,
2760
 
                                   struct spoolss_Notify *data,
2761
 
                                   print_queue_struct *queue,
2762
 
                                   NT_PRINTER_INFO_LEVEL *printer,
2763
 
                                   TALLOC_CTX *mem_ctx)
2764
 
{
2765
 
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->sepfile);
2766
 
}
2767
 
 
2768
 
/*******************************************************************
2769
 
 * fill a notify_info_data with the print processor
2770
 
 * jfm:xxxx return always winprint to indicate we don't do anything to it
2771
 
 ********************************************************************/
2772
 
 
2773
 
void spoolss_notify_print_processor(int snum,
2774
 
                                           struct spoolss_Notify *data,
2775
 
                                           print_queue_struct *queue,
2776
 
                                           NT_PRINTER_INFO_LEVEL *printer,
2777
 
                                           TALLOC_CTX *mem_ctx)
2778
 
{
2779
 
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->printprocessor);
2780
 
}
2781
 
 
2782
 
/*******************************************************************
2783
 
 * fill a notify_info_data with the print processor options
2784
 
 * jfm:xxxx send an empty string
2785
 
 ********************************************************************/
2786
 
 
2787
 
void spoolss_notify_parameters(int snum,
2788
 
                                      struct spoolss_Notify *data,
2789
 
                                      print_queue_struct *queue,
2790
 
                                      NT_PRINTER_INFO_LEVEL *printer,
2791
 
                                      TALLOC_CTX *mem_ctx)
2792
 
{
2793
 
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->parameters);
2794
 
}
2795
 
 
2796
 
/*******************************************************************
2797
 
 * fill a notify_info_data with the data type
2798
 
 * jfm:xxxx always send RAW as data type
2799
 
 ********************************************************************/
2800
 
 
2801
 
void spoolss_notify_datatype(int snum,
2802
 
                                    struct spoolss_Notify *data,
2803
 
                                    print_queue_struct *queue,
2804
 
                                    NT_PRINTER_INFO_LEVEL *printer,
2805
 
                                    TALLOC_CTX *mem_ctx)
2806
 
{
2807
 
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->datatype);
2808
 
}
2809
 
 
2810
 
/*******************************************************************
2811
 
 * fill a notify_info_data with the security descriptor
2812
 
 * jfm:xxxx send an null pointer to say no security desc
2813
 
 * have to implement security before !
2814
 
 ********************************************************************/
2815
 
 
2816
 
static void spoolss_notify_security_desc(int snum,
2817
 
                                         struct spoolss_Notify *data,
2818
 
                                         print_queue_struct *queue,
2819
 
                                         NT_PRINTER_INFO_LEVEL *printer,
2820
 
                                         TALLOC_CTX *mem_ctx)
2821
 
{
2822
 
        SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data,
2823
 
                                          printer->info_2->secdesc_buf->sd_size,
2824
 
                                          printer->info_2->secdesc_buf->sd);
2825
 
}
2826
 
 
2827
 
/*******************************************************************
2828
 
 * fill a notify_info_data with the attributes
2829
 
 * jfm:xxxx a samba printer is always shared
2830
 
 ********************************************************************/
2831
 
 
2832
 
void spoolss_notify_attributes(int snum,
2833
 
                                      struct spoolss_Notify *data,
2834
 
                                      print_queue_struct *queue,
2835
 
                                      NT_PRINTER_INFO_LEVEL *printer,
2836
 
                                      TALLOC_CTX *mem_ctx)
2837
 
{
2838
 
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->attributes);
2839
 
}
2840
 
 
2841
 
/*******************************************************************
2842
 
 * fill a notify_info_data with the priority
2843
 
 ********************************************************************/
2844
 
 
2845
 
static void spoolss_notify_priority(int snum,
2846
 
                                    struct spoolss_Notify *data,
2847
 
                                    print_queue_struct *queue,
2848
 
                                    NT_PRINTER_INFO_LEVEL *printer,
2849
 
                                    TALLOC_CTX *mem_ctx)
2850
 
{
2851
 
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->priority);
2852
 
}
2853
 
 
2854
 
/*******************************************************************
2855
 
 * fill a notify_info_data with the default priority
2856
 
 ********************************************************************/
2857
 
 
2858
 
static void spoolss_notify_default_priority(int snum,
2859
 
                                            struct spoolss_Notify *data,
2860
 
                                            print_queue_struct *queue,
2861
 
                                            NT_PRINTER_INFO_LEVEL *printer,
2862
 
                                            TALLOC_CTX *mem_ctx)
2863
 
{
2864
 
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->default_priority);
2865
 
}
2866
 
 
2867
 
/*******************************************************************
2868
 
 * fill a notify_info_data with the start time
2869
 
 ********************************************************************/
2870
 
 
2871
 
static void spoolss_notify_start_time(int snum,
2872
 
                                      struct spoolss_Notify *data,
2873
 
                                      print_queue_struct *queue,
2874
 
                                      NT_PRINTER_INFO_LEVEL *printer,
2875
 
                                      TALLOC_CTX *mem_ctx)
2876
 
{
2877
 
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->starttime);
2878
 
}
2879
 
 
2880
 
/*******************************************************************
2881
 
 * fill a notify_info_data with the until time
2882
 
 ********************************************************************/
2883
 
 
2884
 
static void spoolss_notify_until_time(int snum,
2885
 
                                      struct spoolss_Notify *data,
2886
 
                                      print_queue_struct *queue,
2887
 
                                      NT_PRINTER_INFO_LEVEL *printer,
2888
 
                                      TALLOC_CTX *mem_ctx)
2889
 
{
2890
 
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->untiltime);
2891
 
}
2892
 
 
2893
 
/*******************************************************************
2894
 
 * fill a notify_info_data with the status
2895
 
 ********************************************************************/
2896
 
 
2897
 
static void spoolss_notify_status(int snum,
2898
 
                                  struct spoolss_Notify *data,
2899
 
                                  print_queue_struct *queue,
2900
 
                                  NT_PRINTER_INFO_LEVEL *printer,
2901
 
                                  TALLOC_CTX *mem_ctx)
2902
 
{
2903
 
        print_status_struct status;
2904
 
 
2905
 
        print_queue_length(snum, &status);
2906
 
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
2907
 
}
2908
 
 
2909
 
/*******************************************************************
2910
 
 * fill a notify_info_data with the number of jobs queued
2911
 
 ********************************************************************/
2912
 
 
2913
 
void spoolss_notify_cjobs(int snum,
2914
 
                                 struct spoolss_Notify *data,
2915
 
                                 print_queue_struct *queue,
2916
 
                                 NT_PRINTER_INFO_LEVEL *printer,
2917
 
                                 TALLOC_CTX *mem_ctx)
2918
 
{
2919
 
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
2920
 
}
2921
 
 
2922
 
/*******************************************************************
2923
 
 * fill a notify_info_data with the average ppm
2924
 
 ********************************************************************/
2925
 
 
2926
 
static void spoolss_notify_average_ppm(int snum,
2927
 
                                       struct spoolss_Notify *data,
2928
 
                                       print_queue_struct *queue,
2929
 
                                       NT_PRINTER_INFO_LEVEL *printer,
2930
 
                                       TALLOC_CTX *mem_ctx)
2931
 
{
2932
 
        /* always respond 8 pages per minutes */
2933
 
        /* a little hard ! */
2934
 
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->averageppm);
2935
 
}
2936
 
 
2937
 
/*******************************************************************
2938
 
 * fill a notify_info_data with username
2939
 
 ********************************************************************/
2940
 
 
2941
 
static void spoolss_notify_username(int snum,
2942
 
                                    struct spoolss_Notify *data,
2943
 
                                    print_queue_struct *queue,
2944
 
                                    NT_PRINTER_INFO_LEVEL *printer,
2945
 
                                    TALLOC_CTX *mem_ctx)
2946
 
{
2947
 
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
2948
 
}
2949
 
 
2950
 
/*******************************************************************
2951
 
 * fill a notify_info_data with job status
2952
 
 ********************************************************************/
2953
 
 
2954
 
static void spoolss_notify_job_status(int snum,
2955
 
                                      struct spoolss_Notify *data,
2956
 
                                      print_queue_struct *queue,
2957
 
                                      NT_PRINTER_INFO_LEVEL *printer,
2958
 
                                      TALLOC_CTX *mem_ctx)
2959
 
{
2960
 
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
2961
 
}
2962
 
 
2963
 
/*******************************************************************
2964
 
 * fill a notify_info_data with job name
2965
 
 ********************************************************************/
2966
 
 
2967
 
static void spoolss_notify_job_name(int snum,
2968
 
                                    struct spoolss_Notify *data,
2969
 
                                    print_queue_struct *queue,
2970
 
                                    NT_PRINTER_INFO_LEVEL *printer,
2971
 
                                    TALLOC_CTX *mem_ctx)
2972
 
{
2973
 
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
2974
 
}
2975
 
 
2976
 
/*******************************************************************
2977
 
 * fill a notify_info_data with job status
2978
 
 ********************************************************************/
2979
 
 
2980
 
static void spoolss_notify_job_status_string(int snum,
2981
 
                                             struct spoolss_Notify *data,
2982
 
                                             print_queue_struct *queue,
2983
 
                                             NT_PRINTER_INFO_LEVEL *printer,
2984
 
                                             TALLOC_CTX *mem_ctx)
2985
 
{
2986
 
        /*
2987
 
         * Now we're returning job status codes we just return a "" here. JRA.
2988
 
         */
2989
 
 
2990
 
        const char *p = "";
2991
 
 
2992
 
#if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2993
 
        p = "unknown";
2994
 
 
2995
 
        switch (queue->status) {
2996
 
        case LPQ_QUEUED:
2997
 
                p = "Queued";
2998
 
                break;
2999
 
        case LPQ_PAUSED:
3000
 
                p = "";    /* NT provides the paused string */
3001
 
                break;
3002
 
        case LPQ_SPOOLING:
3003
 
                p = "Spooling";
3004
 
                break;
3005
 
        case LPQ_PRINTING:
3006
 
                p = "Printing";
3007
 
                break;
3008
 
        }
3009
 
#endif /* NO LONGER NEEDED. */
3010
 
 
3011
 
        SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
3012
 
}
3013
 
 
3014
 
/*******************************************************************
3015
 
 * fill a notify_info_data with job time
3016
 
 ********************************************************************/
3017
 
 
3018
 
static void spoolss_notify_job_time(int snum,
3019
 
                                    struct spoolss_Notify *data,
3020
 
                                    print_queue_struct *queue,
3021
 
                                    NT_PRINTER_INFO_LEVEL *printer,
3022
 
                                    TALLOC_CTX *mem_ctx)
3023
 
{
3024
 
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3025
 
}
3026
 
 
3027
 
/*******************************************************************
3028
 
 * fill a notify_info_data with job size
3029
 
 ********************************************************************/
3030
 
 
3031
 
static void spoolss_notify_job_size(int snum,
3032
 
                                    struct spoolss_Notify *data,
3033
 
                                    print_queue_struct *queue,
3034
 
                                    NT_PRINTER_INFO_LEVEL *printer,
3035
 
                                    TALLOC_CTX *mem_ctx)
3036
 
{
3037
 
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
3038
 
}
3039
 
 
3040
 
/*******************************************************************
3041
 
 * fill a notify_info_data with page info
3042
 
 ********************************************************************/
3043
 
static void spoolss_notify_total_pages(int snum,
3044
 
                                struct spoolss_Notify *data,
3045
 
                                print_queue_struct *queue,
3046
 
                                NT_PRINTER_INFO_LEVEL *printer,
3047
 
                                TALLOC_CTX *mem_ctx)
3048
 
{
3049
 
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
3050
 
}
3051
 
 
3052
 
/*******************************************************************
3053
 
 * fill a notify_info_data with pages printed info.
3054
 
 ********************************************************************/
3055
 
static void spoolss_notify_pages_printed(int snum,
3056
 
                                struct spoolss_Notify *data,
3057
 
                                print_queue_struct *queue,
3058
 
                                NT_PRINTER_INFO_LEVEL *printer,
3059
 
                                TALLOC_CTX *mem_ctx)
3060
 
{
3061
 
        /* Add code when back-end tracks this */
3062
 
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3063
 
}
3064
 
 
3065
 
/*******************************************************************
3066
 
 Fill a notify_info_data with job position.
3067
 
 ********************************************************************/
3068
 
 
3069
 
static void spoolss_notify_job_position(int snum,
3070
 
                                        struct spoolss_Notify *data,
3071
 
                                        print_queue_struct *queue,
3072
 
                                        NT_PRINTER_INFO_LEVEL *printer,
3073
 
                                        TALLOC_CTX *mem_ctx)
3074
 
{
3075
 
        SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
3076
 
}
3077
 
 
3078
 
/*******************************************************************
3079
 
 Fill a notify_info_data with submitted time.
3080
 
 ********************************************************************/
3081
 
 
3082
 
static void spoolss_notify_submitted_time(int snum,
3083
 
                                          struct spoolss_Notify *data,
3084
 
                                          print_queue_struct *queue,
3085
 
                                          NT_PRINTER_INFO_LEVEL *printer,
3086
 
                                          TALLOC_CTX *mem_ctx)
3087
 
{
3088
 
        data->data.string.string = NULL;
3089
 
        data->data.string.size = 0;
3090
 
 
3091
 
        init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
3092
 
                               &data->data.string.string,
3093
 
                               &data->data.string.size);
3094
 
 
3095
 
}
3096
 
 
3097
 
struct s_notify_info_data_table
3098
 
{
3099
 
        enum spoolss_NotifyType type;
3100
 
        uint16_t field;
3101
 
        const char *name;
3102
 
        enum spoolss_NotifyTable variable_type;
3103
 
        void (*fn) (int snum, struct spoolss_Notify *data,
3104
 
                    print_queue_struct *queue,
3105
 
                    NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
3106
 
};
3107
 
 
3108
 
/* A table describing the various print notification constants and
3109
 
   whether the notification data is a pointer to a variable sized
3110
 
   buffer, a one value uint32_t or a two value uint32_t. */
3111
 
 
3112
 
static const struct s_notify_info_data_table notify_info_data_table[] =
3113
 
{
3114
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME,         "PRINTER_NOTIFY_FIELD_SERVER_NAME",         NOTIFY_TABLE_STRING,   spoolss_notify_server_name },
3115
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME,        "PRINTER_NOTIFY_FIELD_PRINTER_NAME",        NOTIFY_TABLE_STRING,   spoolss_notify_printer_name },
3116
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME,          "PRINTER_NOTIFY_FIELD_SHARE_NAME",          NOTIFY_TABLE_STRING,   spoolss_notify_share_name },
3117
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME,           "PRINTER_NOTIFY_FIELD_PORT_NAME",           NOTIFY_TABLE_STRING,   spoolss_notify_port_name },
3118
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME,         "PRINTER_NOTIFY_FIELD_DRIVER_NAME",         NOTIFY_TABLE_STRING,   spoolss_notify_driver_name },
3119
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT,             "PRINTER_NOTIFY_FIELD_COMMENT",             NOTIFY_TABLE_STRING,   spoolss_notify_comment },
3120
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION,            "PRINTER_NOTIFY_FIELD_LOCATION",            NOTIFY_TABLE_STRING,   spoolss_notify_location },
3121
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE,             "PRINTER_NOTIFY_FIELD_DEVMODE",             NOTIFY_TABLE_DEVMODE,  spoolss_notify_devmode },
3122
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE,             "PRINTER_NOTIFY_FIELD_SEPFILE",             NOTIFY_TABLE_STRING,   spoolss_notify_sepfile },
3123
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR,     "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR",     NOTIFY_TABLE_STRING,   spoolss_notify_print_processor },
3124
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS,          "PRINTER_NOTIFY_FIELD_PARAMETERS",          NOTIFY_TABLE_STRING,   spoolss_notify_parameters },
3125
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE,            "PRINTER_NOTIFY_FIELD_DATATYPE",            NOTIFY_TABLE_STRING,   spoolss_notify_datatype },
3126
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR,   spoolss_notify_security_desc },
3127
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES,          "PRINTER_NOTIFY_FIELD_ATTRIBUTES",          NOTIFY_TABLE_DWORD,    spoolss_notify_attributes },
3128
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY,            "PRINTER_NOTIFY_FIELD_PRIORITY",            NOTIFY_TABLE_DWORD,    spoolss_notify_priority },
3129
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY,    "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY",    NOTIFY_TABLE_DWORD,    spoolss_notify_default_priority },
3130
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME,          "PRINTER_NOTIFY_FIELD_START_TIME",          NOTIFY_TABLE_DWORD,    spoolss_notify_start_time },
3131
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME,          "PRINTER_NOTIFY_FIELD_UNTIL_TIME",          NOTIFY_TABLE_DWORD,    spoolss_notify_until_time },
3132
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS,              "PRINTER_NOTIFY_FIELD_STATUS",              NOTIFY_TABLE_DWORD,    spoolss_notify_status },
3133
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING,       "PRINTER_NOTIFY_FIELD_STATUS_STRING",       NOTIFY_TABLE_STRING,   NULL },
3134
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS,               "PRINTER_NOTIFY_FIELD_CJOBS",               NOTIFY_TABLE_DWORD,    spoolss_notify_cjobs },
3135
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM,         "PRINTER_NOTIFY_FIELD_AVERAGE_PPM",         NOTIFY_TABLE_DWORD,    spoolss_notify_average_ppm },
3136
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES,         "PRINTER_NOTIFY_FIELD_TOTAL_PAGES",         NOTIFY_TABLE_DWORD,    NULL },
3137
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED,       "PRINTER_NOTIFY_FIELD_PAGES_PRINTED",       NOTIFY_TABLE_DWORD,    NULL },
3138
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES,         "PRINTER_NOTIFY_FIELD_TOTAL_BYTES",         NOTIFY_TABLE_DWORD,    NULL },
3139
 
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED,       "PRINTER_NOTIFY_FIELD_BYTES_PRINTED",       NOTIFY_TABLE_DWORD,    NULL },
3140
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PRINTER_NAME,            "JOB_NOTIFY_FIELD_PRINTER_NAME",            NOTIFY_TABLE_STRING,   spoolss_notify_printer_name },
3141
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_MACHINE_NAME,            "JOB_NOTIFY_FIELD_MACHINE_NAME",            NOTIFY_TABLE_STRING,   spoolss_notify_server_name },
3142
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PORT_NAME,               "JOB_NOTIFY_FIELD_PORT_NAME",               NOTIFY_TABLE_STRING,   spoolss_notify_port_name },
3143
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_USER_NAME,               "JOB_NOTIFY_FIELD_USER_NAME",               NOTIFY_TABLE_STRING,   spoolss_notify_username },
3144
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_NOTIFY_NAME,             "JOB_NOTIFY_FIELD_NOTIFY_NAME",             NOTIFY_TABLE_STRING,   spoolss_notify_username },
3145
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DATATYPE,                "JOB_NOTIFY_FIELD_DATATYPE",                NOTIFY_TABLE_STRING,   spoolss_notify_datatype },
3146
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PRINT_PROCESSOR,         "JOB_NOTIFY_FIELD_PRINT_PROCESSOR",         NOTIFY_TABLE_STRING,   spoolss_notify_print_processor },
3147
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PARAMETERS,              "JOB_NOTIFY_FIELD_PARAMETERS",              NOTIFY_TABLE_STRING,   spoolss_notify_parameters },
3148
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DRIVER_NAME,             "JOB_NOTIFY_FIELD_DRIVER_NAME",             NOTIFY_TABLE_STRING,   spoolss_notify_driver_name },
3149
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DEVMODE,                 "JOB_NOTIFY_FIELD_DEVMODE",                 NOTIFY_TABLE_DEVMODE,  spoolss_notify_devmode },
3150
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_STATUS,                  "JOB_NOTIFY_FIELD_STATUS",                  NOTIFY_TABLE_DWORD,    spoolss_notify_job_status },
3151
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_STATUS_STRING,           "JOB_NOTIFY_FIELD_STATUS_STRING",           NOTIFY_TABLE_STRING,   spoolss_notify_job_status_string },
3152
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR,     "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR",     NOTIFY_TABLE_SECURITYDESCRIPTOR,   NULL },
3153
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_DOCUMENT,                "JOB_NOTIFY_FIELD_DOCUMENT",                NOTIFY_TABLE_STRING,   spoolss_notify_job_name },
3154
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PRIORITY,                "JOB_NOTIFY_FIELD_PRIORITY",                NOTIFY_TABLE_DWORD,    spoolss_notify_priority },
3155
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_POSITION,                "JOB_NOTIFY_FIELD_POSITION",                NOTIFY_TABLE_DWORD,    spoolss_notify_job_position },
3156
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_SUBMITTED,               "JOB_NOTIFY_FIELD_SUBMITTED",               NOTIFY_TABLE_TIME,     spoolss_notify_submitted_time },
3157
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_START_TIME,              "JOB_NOTIFY_FIELD_START_TIME",              NOTIFY_TABLE_DWORD,    spoolss_notify_start_time },
3158
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_UNTIL_TIME,              "JOB_NOTIFY_FIELD_UNTIL_TIME",              NOTIFY_TABLE_DWORD,    spoolss_notify_until_time },
3159
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_TIME,                    "JOB_NOTIFY_FIELD_TIME",                    NOTIFY_TABLE_DWORD,    spoolss_notify_job_time },
3160
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_TOTAL_PAGES,             "JOB_NOTIFY_FIELD_TOTAL_PAGES",             NOTIFY_TABLE_DWORD,    spoolss_notify_total_pages },
3161
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_PAGES_PRINTED,           "JOB_NOTIFY_FIELD_PAGES_PRINTED",           NOTIFY_TABLE_DWORD,    spoolss_notify_pages_printed },
3162
 
{ JOB_NOTIFY_TYPE,     JOB_NOTIFY_FIELD_TOTAL_BYTES,             "JOB_NOTIFY_FIELD_TOTAL_BYTES",             NOTIFY_TABLE_DWORD,    spoolss_notify_job_size },
3163
 
};
3164
 
 
3165
 
/*******************************************************************
3166
 
 Return the variable_type of info_data structure.
3167
 
********************************************************************/
3168
 
 
3169
 
static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
3170
 
                                                  uint16_t field)
3171
 
{
3172
 
        int i=0;
3173
 
 
3174
 
        for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3175
 
                if ( (notify_info_data_table[i].type == type) &&
3176
 
                     (notify_info_data_table[i].field == field) ) {
3177
 
                        return notify_info_data_table[i].variable_type;
3178
 
                }
3179
 
        }
3180
 
 
3181
 
        DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3182
 
 
3183
 
        return 0;
3184
 
}
3185
 
 
3186
 
/****************************************************************************
3187
 
****************************************************************************/
3188
 
 
3189
 
static bool search_notify(enum spoolss_NotifyType type,
3190
 
                          uint16_t field,
3191
 
                          int *value)
3192
 
{
3193
 
        int i;
3194
 
 
3195
 
        for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3196
 
                if (notify_info_data_table[i].type == type &&
3197
 
                    notify_info_data_table[i].field == field &&
3198
 
                    notify_info_data_table[i].fn != NULL) {
3199
 
                        *value = i;
3200
 
                        return true;
3201
 
                }
3202
 
        }
3203
 
 
3204
 
        return false;
3205
 
}
3206
 
 
3207
 
/****************************************************************************
3208
 
****************************************************************************/
3209
 
 
3210
 
void construct_info_data(struct spoolss_Notify *info_data,
3211
 
                         enum spoolss_NotifyType type,
3212
 
                         uint16_t field,
3213
 
                         int id)
3214
 
{
3215
 
        info_data->type                 = type;
3216
 
        info_data->field.field          = field;
3217
 
        info_data->variable_type        = variable_type_of_notify_info_data(type, field);
3218
 
        info_data->job_id               = id;
3219
 
}
3220
 
 
3221
 
/*******************************************************************
3222
 
 *
3223
 
 * fill a notify_info struct with info asked
3224
 
 *
3225
 
 ********************************************************************/
3226
 
 
3227
 
static bool construct_notify_printer_info(Printer_entry *print_hnd,
3228
 
                                          struct spoolss_NotifyInfo *info,
3229
 
                                          int snum,
3230
 
                                          const struct spoolss_NotifyOptionType *option_type,
3231
 
                                          uint32_t id,
3232
 
                                          TALLOC_CTX *mem_ctx)
3233
 
{
3234
 
        int field_num,j;
3235
 
        enum spoolss_NotifyType type;
3236
 
        uint16_t field;
3237
 
 
3238
 
        struct spoolss_Notify *current_data;
3239
 
        NT_PRINTER_INFO_LEVEL *printer = NULL;
3240
 
        print_queue_struct *queue=NULL;
3241
 
 
3242
 
        type = option_type->type;
3243
 
 
3244
 
        DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3245
 
                (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3246
 
                option_type->count, lp_servicename(snum)));
3247
 
 
3248
 
        if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
3249
 
                return false;
3250
 
 
3251
 
        for(field_num=0; field_num < option_type->count; field_num++) {
3252
 
                field = option_type->fields[field_num].field;
3253
 
 
3254
 
                DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3255
 
 
3256
 
                if (!search_notify(type, field, &j) )
3257
 
                        continue;
3258
 
 
3259
 
                info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3260
 
                                                      struct spoolss_Notify,
3261
 
                                                      info->count + 1);
3262
 
                if (info->notifies == NULL) {
3263
 
                        DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3264
 
                        free_a_printer(&printer, 2);
3265
 
                        return false;
3266
 
                }
3267
 
 
3268
 
                current_data = &info->notifies[info->count];
3269
 
 
3270
 
                construct_info_data(current_data, type, field, id);
3271
 
 
3272
 
                DEBUG(10,("construct_notify_printer_info: calling [%s]  snum=%d  printername=[%s])\n",
3273
 
                                notify_info_data_table[j].name, snum, printer->info_2->printername ));
3274
 
 
3275
 
                notify_info_data_table[j].fn(snum, current_data, queue,
3276
 
                                             printer, mem_ctx);
3277
 
 
3278
 
                info->count++;
3279
 
        }
3280
 
 
3281
 
        free_a_printer(&printer, 2);
3282
 
        return true;
3283
 
}
3284
 
 
3285
 
/*******************************************************************
3286
 
 *
3287
 
 * fill a notify_info struct with info asked
3288
 
 *
3289
 
 ********************************************************************/
3290
 
 
3291
 
static bool construct_notify_jobs_info(print_queue_struct *queue,
3292
 
                                       struct spoolss_NotifyInfo *info,
3293
 
                                       NT_PRINTER_INFO_LEVEL *printer,
3294
 
                                       int snum,
3295
 
                                       const struct spoolss_NotifyOptionType *option_type,
3296
 
                                       uint32_t id,
3297
 
                                       TALLOC_CTX *mem_ctx)
3298
 
{
3299
 
        int field_num,j;
3300
 
        enum spoolss_NotifyType type;
3301
 
        uint16_t field;
3302
 
        struct spoolss_Notify *current_data;
3303
 
 
3304
 
        DEBUG(4,("construct_notify_jobs_info\n"));
3305
 
 
3306
 
        type = option_type->type;
3307
 
 
3308
 
        DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3309
 
                (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3310
 
                option_type->count));
3311
 
 
3312
 
        for(field_num=0; field_num<option_type->count; field_num++) {
3313
 
                field = option_type->fields[field_num].field;
3314
 
 
3315
 
                if (!search_notify(type, field, &j) )
3316
 
                        continue;
3317
 
 
3318
 
                info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3319
 
                                                      struct spoolss_Notify,
3320
 
                                                      info->count + 1);
3321
 
                if (info->notifies == NULL) {
3322
 
                        DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3323
 
                        return false;
3324
 
                }
3325
 
 
3326
 
                current_data=&(info->notifies[info->count]);
3327
 
 
3328
 
                construct_info_data(current_data, type, field, id);
3329
 
                notify_info_data_table[j].fn(snum, current_data, queue,
3330
 
                                             printer, mem_ctx);
3331
 
                info->count++;
3332
 
        }
3333
 
 
3334
 
        return true;
3335
 
}
3336
 
 
3337
 
/*
3338
 
 * JFM: The enumeration is not that simple, it's even non obvious.
3339
 
 *
3340
 
 * let's take an example: I want to monitor the PRINTER SERVER for
3341
 
 * the printer's name and the number of jobs currently queued.
3342
 
 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3343
 
 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3344
 
 *
3345
 
 * I have 3 printers on the back of my server.
3346
 
 *
3347
 
 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3348
 
 * structures.
3349
 
 *   Number     Data                    Id
3350
 
 *      1       printer 1 name          1
3351
 
 *      2       printer 1 cjob          1
3352
 
 *      3       printer 2 name          2
3353
 
 *      4       printer 2 cjob          2
3354
 
 *      5       printer 3 name          3
3355
 
 *      6       printer 3 name          3
3356
 
 *
3357
 
 * that's the print server case, the printer case is even worse.
3358
 
 */
3359
 
 
3360
 
/*******************************************************************
3361
 
 *
3362
 
 * enumerate all printers on the printserver
3363
 
 * fill a notify_info struct with info asked
3364
 
 *
3365
 
 ********************************************************************/
3366
 
 
3367
 
static WERROR printserver_notify_info(pipes_struct *p,
3368
 
                                      struct policy_handle *hnd,
3369
 
                                      struct spoolss_NotifyInfo *info,
3370
 
                                      TALLOC_CTX *mem_ctx)
3371
 
{
3372
 
        int snum;
3373
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3374
 
        int n_services=lp_numservices();
3375
 
        int i;
3376
 
        struct spoolss_NotifyOption *option;
3377
 
        struct spoolss_NotifyOptionType option_type;
3378
 
 
3379
 
        DEBUG(4,("printserver_notify_info\n"));
3380
 
 
3381
 
        if (!Printer)
3382
 
                return WERR_BADFID;
3383
 
 
3384
 
        option = Printer->notify.option;
3385
 
 
3386
 
        info->version   = 2;
3387
 
        info->notifies  = NULL;
3388
 
        info->count     = 0;
3389
 
 
3390
 
        /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3391
 
           sending a ffpcn() request first */
3392
 
 
3393
 
        if ( !option )
3394
 
                return WERR_BADFID;
3395
 
 
3396
 
        for (i=0; i<option->count; i++) {
3397
 
                option_type = option->types[i];
3398
 
 
3399
 
                if (option_type.type != PRINTER_NOTIFY_TYPE)
3400
 
                        continue;
3401
 
 
3402
 
                for (snum=0; snum<n_services; snum++)
3403
 
                {
3404
 
                        if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3405
 
                                construct_notify_printer_info ( Printer, info, snum, &option_type, snum, mem_ctx );
3406
 
                }
3407
 
        }
3408
 
 
3409
 
#if 0
3410
 
        /*
3411
 
         * Debugging information, don't delete.
3412
 
         */
3413
 
 
3414
 
        DEBUG(1,("dumping the NOTIFY_INFO\n"));
3415
 
        DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3416
 
        DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3417
 
 
3418
 
        for (i=0; i<info->count; i++) {
3419
 
                DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3420
 
                i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3421
 
                info->data[i].id, info->data[i].size, info->data[i].enc_type));
3422
 
        }
3423
 
#endif
3424
 
 
3425
 
        return WERR_OK;
3426
 
}
3427
 
 
3428
 
/*******************************************************************
3429
 
 *
3430
 
 * fill a notify_info struct with info asked
3431
 
 *
3432
 
 ********************************************************************/
3433
 
 
3434
 
static WERROR printer_notify_info(pipes_struct *p, struct policy_handle *hnd,
3435
 
                                  struct spoolss_NotifyInfo *info,
3436
 
                                  TALLOC_CTX *mem_ctx)
3437
 
{
3438
 
        int snum;
3439
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3440
 
        int i;
3441
 
        uint32_t id;
3442
 
        struct spoolss_NotifyOption *option;
3443
 
        struct spoolss_NotifyOptionType option_type;
3444
 
        int count,j;
3445
 
        print_queue_struct *queue=NULL;
3446
 
        print_status_struct status;
3447
 
 
3448
 
        DEBUG(4,("printer_notify_info\n"));
3449
 
 
3450
 
        if (!Printer)
3451
 
                return WERR_BADFID;
3452
 
 
3453
 
        option = Printer->notify.option;
3454
 
        id = 0x0;
3455
 
 
3456
 
        info->version   = 2;
3457
 
        info->notifies  = NULL;
3458
 
        info->count     = 0;
3459
 
 
3460
 
        /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3461
 
           sending a ffpcn() request first */
3462
 
 
3463
 
        if ( !option )
3464
 
                return WERR_BADFID;
3465
 
 
3466
 
        get_printer_snum(p, hnd, &snum, NULL);
3467
 
 
3468
 
        for (i=0; i<option->count; i++) {
3469
 
                option_type = option->types[i];
3470
 
 
3471
 
                switch (option_type.type) {
3472
 
                case PRINTER_NOTIFY_TYPE:
3473
 
                        if(construct_notify_printer_info(Printer, info, snum,
3474
 
                                                         &option_type, id,
3475
 
                                                         mem_ctx))
3476
 
                                id--;
3477
 
                        break;
3478
 
 
3479
 
                case JOB_NOTIFY_TYPE: {
3480
 
                        NT_PRINTER_INFO_LEVEL *printer = NULL;
3481
 
 
3482
 
                        count = print_queue_status(snum, &queue, &status);
3483
 
 
3484
 
                        if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))))
3485
 
                                goto done;
3486
 
 
3487
 
                        for (j=0; j<count; j++) {
3488
 
                                construct_notify_jobs_info(&queue[j], info,
3489
 
                                                           printer, snum,
3490
 
                                                           &option_type,
3491
 
                                                           queue[j].job,
3492
 
                                                           mem_ctx);
3493
 
                        }
3494
 
 
3495
 
                        free_a_printer(&printer, 2);
3496
 
 
3497
 
                done:
3498
 
                        SAFE_FREE(queue);
3499
 
                        break;
3500
 
                }
3501
 
                }
3502
 
        }
3503
 
 
3504
 
        /*
3505
 
         * Debugging information, don't delete.
3506
 
         */
3507
 
        /*
3508
 
        DEBUG(1,("dumping the NOTIFY_INFO\n"));
3509
 
        DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3510
 
        DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3511
 
 
3512
 
        for (i=0; i<info->count; i++) {
3513
 
                DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3514
 
                i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3515
 
                info->data[i].id, info->data[i].size, info->data[i].enc_type));
3516
 
        }
3517
 
        */
3518
 
        return WERR_OK;
3519
 
}
3520
 
 
3521
 
/****************************************************************
3522
 
 _spoolss_RouterRefreshPrinterChangeNotify
3523
 
****************************************************************/
3524
 
 
3525
 
WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
3526
 
                                                 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3527
 
{
3528
 
        struct spoolss_NotifyInfo *info;
3529
 
 
3530
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
3531
 
        WERROR result = WERR_BADFID;
3532
 
 
3533
 
        /* we always have a spoolss_NotifyInfo struct */
3534
 
        info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3535
 
        if (!info) {
3536
 
                result = WERR_NOMEM;
3537
 
                goto done;
3538
 
        }
3539
 
 
3540
 
        *r->out.info = info;
3541
 
 
3542
 
        if (!Printer) {
3543
 
                DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3544
 
                        "Invalid handle (%s:%u:%u).\n",
3545
 
                        OUR_HANDLE(r->in.handle)));
3546
 
                goto done;
3547
 
        }
3548
 
 
3549
 
        DEBUG(4,("Printer type %x\n",Printer->printer_type));
3550
 
 
3551
 
        /*
3552
 
         *      We are now using the change value, and
3553
 
         *      I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3554
 
         *      I don't have a global notification system, I'm sending back all the
3555
 
         *      informations even when _NOTHING_ has changed.
3556
 
         */
3557
 
 
3558
 
        /* We need to keep track of the change value to send back in
3559
 
           RRPCN replies otherwise our updates are ignored. */
3560
 
 
3561
 
        Printer->notify.fnpcn = true;
3562
 
 
3563
 
        if (Printer->notify.client_connected) {
3564
 
                DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3565
 
                        "Saving change value in request [%x]\n",
3566
 
                        r->in.change_low));
3567
 
                Printer->notify.change = r->in.change_low;
3568
 
        }
3569
 
 
3570
 
        /* just ignore the spoolss_NotifyOption */
3571
 
 
3572
 
        switch (Printer->printer_type) {
3573
 
                case SPLHND_SERVER:
3574
 
                        result = printserver_notify_info(p, r->in.handle,
3575
 
                                                         info, p->mem_ctx);
3576
 
                        break;
3577
 
 
3578
 
                case SPLHND_PRINTER:
3579
 
                        result = printer_notify_info(p, r->in.handle,
3580
 
                                                     info, p->mem_ctx);
3581
 
                        break;
3582
 
        }
3583
 
 
3584
 
        Printer->notify.fnpcn = false;
3585
 
 
3586
 
done:
3587
 
        return result;
3588
 
}
3589
 
 
3590
 
/********************************************************************
3591
 
 * construct_printer_info_0
3592
 
 * fill a printer_info_0 struct
3593
 
 ********************************************************************/
3594
 
 
3595
 
static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
3596
 
                                      const NT_PRINTER_INFO_LEVEL *ntprinter,
3597
 
                                      struct spoolss_PrinterInfo0 *r,
3598
 
                                      int snum)
3599
 
{
3600
 
        int count;
3601
 
        counter_printer_0 *session_counter;
3602
 
        time_t setuptime;
3603
 
        print_status_struct status;
3604
 
 
3605
 
        r->printername          = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3606
 
        W_ERROR_HAVE_NO_MEMORY(r->printername);
3607
 
 
3608
 
        r->servername           = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
3609
 
        W_ERROR_HAVE_NO_MEMORY(r->servername);
3610
 
 
3611
 
        count = print_queue_length(snum, &status);
3612
 
 
3613
 
        /* check if we already have a counter for this printer */
3614
 
        for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3615
 
                if (session_counter->snum == snum)
3616
 
                        break;
3617
 
        }
3618
 
 
3619
 
        /* it's the first time, add it to the list */
3620
 
        if (session_counter == NULL) {
3621
 
                session_counter = SMB_MALLOC_P(counter_printer_0);
3622
 
                W_ERROR_HAVE_NO_MEMORY(session_counter);
3623
 
                ZERO_STRUCTP(session_counter);
3624
 
                session_counter->snum           = snum;
3625
 
                session_counter->counter        = 0;
3626
 
                DLIST_ADD(counter_list, session_counter);
3627
 
        }
3628
 
 
3629
 
        /* increment it */
3630
 
        session_counter->counter++;
3631
 
 
3632
 
        r->cjobs                        = count;
3633
 
        r->total_jobs                   = 0;
3634
 
        r->total_bytes                  = 0;
3635
 
 
3636
 
        setuptime = (time_t)ntprinter->info_2->setuptime;
3637
 
 
3638
 
        init_systemtime(&r->time, gmtime(&setuptime));
3639
 
 
3640
 
        /* JFM:
3641
 
         * the global_counter should be stored in a TDB as it's common to all the clients
3642
 
         * and should be zeroed on samba startup
3643
 
         */
3644
 
        r->global_counter               = session_counter->counter;
3645
 
        r->total_pages                  = 0;
3646
 
        /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3647
 
        r->version                      = 0x0005;       /* NT 5 */
3648
 
        r->free_build                   = 0x0893;       /* build 2195 */
3649
 
        r->spooling                     = 0;
3650
 
        r->max_spooling                 = 0;
3651
 
        r->session_counter              = session_counter->counter;
3652
 
        r->num_error_out_of_paper       = 0x0;
3653
 
        r->num_error_not_ready          = 0x0;          /* number of print failure */
3654
 
        r->job_error                    = 0x0;
3655
 
        r->number_of_processors         = 0x1;
3656
 
        r->processor_type               = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
3657
 
        r->high_part_total_bytes        = 0x0;
3658
 
        r->change_id                    = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
3659
 
        r->last_error                   = WERR_OK;
3660
 
        r->status                       = nt_printq_status(status.status);
3661
 
        r->enumerate_network_printers   = 0x0;
3662
 
        r->c_setprinter                 = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
3663
 
        r->processor_architecture       = 0x0;
3664
 
        r->processor_level              = 0x6;          /* 6  ???*/
3665
 
        r->ref_ic                       = 0;
3666
 
        r->reserved2                    = 0;
3667
 
        r->reserved3                    = 0;
3668
 
 
3669
 
        return WERR_OK;
3670
 
}
3671
 
 
3672
 
/****************************************************************************
3673
 
 Convert an NT_DEVICEMODE to a spoolss_DeviceMode structure.  Both pointers
3674
 
 should be valid upon entry
3675
 
****************************************************************************/
3676
 
 
3677
 
static WERROR convert_nt_devicemode(TALLOC_CTX *mem_ctx,
3678
 
                                    struct spoolss_DeviceMode *r,
3679
 
                                    const NT_DEVICEMODE *ntdevmode)
3680
 
{
3681
 
        if (!r || !ntdevmode) {
3682
 
                return WERR_INVALID_PARAM;
3683
 
        }
3684
 
 
3685
 
        r->devicename           = talloc_strdup(mem_ctx, ntdevmode->devicename);
3686
 
        W_ERROR_HAVE_NO_MEMORY(r->devicename);
3687
 
 
3688
 
        r->specversion          = ntdevmode->specversion;
3689
 
        r->driverversion        = ntdevmode->driverversion;
3690
 
        r->size                 = ntdevmode->size;
3691
 
        r->__driverextra_length = ntdevmode->driverextra;
3692
 
        r->fields               = ntdevmode->fields;
3693
 
 
3694
 
        r->orientation          = ntdevmode->orientation;
3695
 
        r->papersize            = ntdevmode->papersize;
3696
 
        r->paperlength          = ntdevmode->paperlength;
3697
 
        r->paperwidth           = ntdevmode->paperwidth;
3698
 
        r->scale                = ntdevmode->scale;
3699
 
        r->copies               = ntdevmode->copies;
3700
 
        r->defaultsource        = ntdevmode->defaultsource;
3701
 
        r->printquality         = ntdevmode->printquality;
3702
 
        r->color                = ntdevmode->color;
3703
 
        r->duplex               = ntdevmode->duplex;
3704
 
        r->yresolution          = ntdevmode->yresolution;
3705
 
        r->ttoption             = ntdevmode->ttoption;
3706
 
        r->collate              = ntdevmode->collate;
3707
 
 
3708
 
        r->formname             = talloc_strdup(mem_ctx, ntdevmode->formname);
3709
 
        W_ERROR_HAVE_NO_MEMORY(r->formname);
3710
 
 
3711
 
        /* all 0 below are values that have not been set in the old parsing/copy
3712
 
         * function, maybe they should... - gd */
3713
 
 
3714
 
        r->logpixels            = 0;
3715
 
        r->bitsperpel           = 0;
3716
 
        r->pelswidth            = 0;
3717
 
        r->pelsheight           = 0;
3718
 
        r->displayflags         = 0;
3719
 
        r->displayfrequency     = 0;
3720
 
        r->icmmethod            = ntdevmode->icmmethod;
3721
 
        r->icmintent            = ntdevmode->icmintent;
3722
 
        r->mediatype            = ntdevmode->mediatype;
3723
 
        r->dithertype           = ntdevmode->dithertype;
3724
 
        r->reserved1            = 0;
3725
 
        r->reserved2            = 0;
3726
 
        r->panningwidth         = 0;
3727
 
        r->panningheight        = 0;
3728
 
 
3729
 
        if (ntdevmode->nt_dev_private != NULL) {
3730
 
                r->driverextra_data = data_blob_talloc(mem_ctx,
3731
 
                        ntdevmode->nt_dev_private,
3732
 
                        ntdevmode->driverextra);
3733
 
                W_ERROR_HAVE_NO_MEMORY(r->driverextra_data.data);
3734
 
        }
3735
 
 
3736
 
        return WERR_OK;
3737
 
}
3738
 
 
3739
 
 
3740
 
/****************************************************************************
3741
 
 Create a spoolss_DeviceMode struct. Returns talloced memory.
3742
 
****************************************************************************/
3743
 
 
3744
 
struct spoolss_DeviceMode *construct_dev_mode(TALLOC_CTX *mem_ctx,
3745
 
                                              const char *servicename)
3746
 
{
3747
 
        WERROR result;
3748
 
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
3749
 
        struct spoolss_DeviceMode *devmode = NULL;
3750
 
 
3751
 
        DEBUG(7,("construct_dev_mode\n"));
3752
 
 
3753
 
        DEBUGADD(8,("getting printer characteristics\n"));
3754
 
 
3755
 
        if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
3756
 
                return NULL;
3757
 
 
3758
 
        if (!printer->info_2->devmode) {
3759
 
                DEBUG(5, ("BONG! There was no device mode!\n"));
3760
 
                goto done;
3761
 
        }
3762
 
 
3763
 
        devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode);
3764
 
        if (!devmode) {
3765
 
                DEBUG(2,("construct_dev_mode: talloc fail.\n"));
3766
 
                goto done;
3767
 
        }
3768
 
 
3769
 
        DEBUGADD(8,("loading DEVICEMODE\n"));
3770
 
 
3771
 
        result = convert_nt_devicemode(mem_ctx, devmode, printer->info_2->devmode);
3772
 
        if (!W_ERROR_IS_OK(result)) {
3773
 
                TALLOC_FREE(devmode);
3774
 
        }
3775
 
 
3776
 
done:
3777
 
        free_a_printer(&printer,2);
3778
 
 
3779
 
        return devmode;
3780
 
}
3781
 
 
3782
 
/********************************************************************
3783
 
 * construct_printer_info1
3784
 
 * fill a spoolss_PrinterInfo1 struct
3785
 
********************************************************************/
3786
 
 
3787
 
static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
3788
 
                                      const NT_PRINTER_INFO_LEVEL *ntprinter,
3789
 
                                      uint32_t flags,
3790
 
                                      struct spoolss_PrinterInfo1 *r,
3791
 
                                      int snum)
3792
 
{
3793
 
        r->flags                = flags;
3794
 
 
3795
 
        r->description          = talloc_asprintf(mem_ctx, "%s,%s,%s",
3796
 
                                                  ntprinter->info_2->printername,
3797
 
                                                  ntprinter->info_2->drivername,
3798
 
                                                  ntprinter->info_2->location);
3799
 
        W_ERROR_HAVE_NO_MEMORY(r->description);
3800
 
 
3801
 
        if (*ntprinter->info_2->comment == '\0') {
3802
 
                r->comment      = talloc_strdup(mem_ctx, lp_comment(snum));
3803
 
        } else {
3804
 
                r->comment      = talloc_strdup(mem_ctx, ntprinter->info_2->comment); /* saved comment */
3805
 
        }
3806
 
        W_ERROR_HAVE_NO_MEMORY(r->comment);
3807
 
 
3808
 
        r->name                 = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3809
 
        W_ERROR_HAVE_NO_MEMORY(r->name);
3810
 
 
3811
 
        return WERR_OK;
3812
 
}
3813
 
 
3814
 
/********************************************************************
3815
 
 * construct_printer_info2
3816
 
 * fill a spoolss_PrinterInfo2 struct
3817
 
********************************************************************/
3818
 
 
3819
 
static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
3820
 
                                      const NT_PRINTER_INFO_LEVEL *ntprinter,
3821
 
                                      struct spoolss_PrinterInfo2 *r,
3822
 
                                      int snum)
3823
 
{
3824
 
        int count;
3825
 
 
3826
 
        print_status_struct status;
3827
 
 
3828
 
        count = print_queue_length(snum, &status);
3829
 
 
3830
 
        r->servername           = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
3831
 
        W_ERROR_HAVE_NO_MEMORY(r->servername);
3832
 
        r->printername          = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3833
 
        W_ERROR_HAVE_NO_MEMORY(r->printername);
3834
 
        r->sharename            = talloc_strdup(mem_ctx, lp_servicename(snum));
3835
 
        W_ERROR_HAVE_NO_MEMORY(r->sharename);
3836
 
        r->portname             = talloc_strdup(mem_ctx, ntprinter->info_2->portname);
3837
 
        W_ERROR_HAVE_NO_MEMORY(r->portname);
3838
 
        r->drivername           = talloc_strdup(mem_ctx, ntprinter->info_2->drivername);
3839
 
        W_ERROR_HAVE_NO_MEMORY(r->drivername);
3840
 
 
3841
 
        if (*ntprinter->info_2->comment == '\0') {
3842
 
                r->comment      = talloc_strdup(mem_ctx, lp_comment(snum));
3843
 
        } else {
3844
 
                r->comment      = talloc_strdup(mem_ctx, ntprinter->info_2->comment);
3845
 
        }
3846
 
        W_ERROR_HAVE_NO_MEMORY(r->comment);
3847
 
 
3848
 
        r->location             = talloc_strdup(mem_ctx, ntprinter->info_2->location);
3849
 
        W_ERROR_HAVE_NO_MEMORY(r->location);
3850
 
        r->sepfile              = talloc_strdup(mem_ctx, ntprinter->info_2->sepfile);
3851
 
        W_ERROR_HAVE_NO_MEMORY(r->sepfile);
3852
 
        r->printprocessor       = talloc_strdup(mem_ctx, ntprinter->info_2->printprocessor);
3853
 
        W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
3854
 
        r->datatype             = talloc_strdup(mem_ctx, ntprinter->info_2->datatype);
3855
 
        W_ERROR_HAVE_NO_MEMORY(r->datatype);
3856
 
        r->parameters           = talloc_strdup(mem_ctx, ntprinter->info_2->parameters);
3857
 
        W_ERROR_HAVE_NO_MEMORY(r->parameters);
3858
 
 
3859
 
        r->attributes           = ntprinter->info_2->attributes;
3860
 
 
3861
 
        r->priority             = ntprinter->info_2->priority;
3862
 
        r->defaultpriority      = ntprinter->info_2->default_priority;
3863
 
        r->starttime            = ntprinter->info_2->starttime;
3864
 
        r->untiltime            = ntprinter->info_2->untiltime;
3865
 
        r->status               = nt_printq_status(status.status);
3866
 
        r->cjobs                = count;
3867
 
        r->averageppm           = ntprinter->info_2->averageppm;
3868
 
 
3869
 
        r->devmode = construct_dev_mode(mem_ctx, lp_const_servicename(snum));
3870
 
        if (!r->devmode) {
3871
 
                DEBUG(8,("Returning NULL Devicemode!\n"));
3872
 
        }
3873
 
 
3874
 
        r->secdesc              = NULL;
3875
 
 
3876
 
        if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
3877
 
                /* don't use talloc_steal() here unless you do a deep steal of all
3878
 
                   the SEC_DESC members */
3879
 
 
3880
 
                r->secdesc      = dup_sec_desc(mem_ctx, ntprinter->info_2->secdesc_buf->sd);
3881
 
        }
3882
 
 
3883
 
        return WERR_OK;
3884
 
}
3885
 
 
3886
 
/********************************************************************
3887
 
 * construct_printer_info3
3888
 
 * fill a spoolss_PrinterInfo3 struct
3889
 
 ********************************************************************/
3890
 
 
3891
 
static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
3892
 
                                      const NT_PRINTER_INFO_LEVEL *ntprinter,
3893
 
                                      struct spoolss_PrinterInfo3 *r,
3894
 
                                      int snum)
3895
 
{
3896
 
        /* These are the components of the SD we are returning. */
3897
 
 
3898
 
        if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
3899
 
                /* don't use talloc_steal() here unless you do a deep steal of all
3900
 
                   the SEC_DESC members */
3901
 
 
3902
 
                r->secdesc = dup_sec_desc(mem_ctx,
3903
 
                                          ntprinter->info_2->secdesc_buf->sd);
3904
 
                W_ERROR_HAVE_NO_MEMORY(r->secdesc);
3905
 
        }
3906
 
 
3907
 
        return WERR_OK;
3908
 
}
3909
 
 
3910
 
/********************************************************************
3911
 
 * construct_printer_info4
3912
 
 * fill a spoolss_PrinterInfo4 struct
3913
 
 ********************************************************************/
3914
 
 
3915
 
static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
3916
 
                                      const NT_PRINTER_INFO_LEVEL *ntprinter,
3917
 
                                      struct spoolss_PrinterInfo4 *r,
3918
 
                                      int snum)
3919
 
{
3920
 
        r->printername  = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3921
 
        W_ERROR_HAVE_NO_MEMORY(r->printername);
3922
 
        r->servername   = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
3923
 
        W_ERROR_HAVE_NO_MEMORY(r->servername);
3924
 
 
3925
 
        r->attributes   = ntprinter->info_2->attributes;
3926
 
 
3927
 
        return WERR_OK;
3928
 
}
3929
 
 
3930
 
/********************************************************************
3931
 
 * construct_printer_info5
3932
 
 * fill a spoolss_PrinterInfo5 struct
3933
 
 ********************************************************************/
3934
 
 
3935
 
static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
3936
 
                                      const NT_PRINTER_INFO_LEVEL *ntprinter,
3937
 
                                      struct spoolss_PrinterInfo5 *r,
3938
 
                                      int snum)
3939
 
{
3940
 
        r->printername  = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3941
 
        W_ERROR_HAVE_NO_MEMORY(r->printername);
3942
 
        r->portname     = talloc_strdup(mem_ctx, ntprinter->info_2->portname);
3943
 
        W_ERROR_HAVE_NO_MEMORY(r->portname);
3944
 
 
3945
 
        r->attributes   = ntprinter->info_2->attributes;
3946
 
 
3947
 
        /* these two are not used by NT+ according to MSDN */
3948
 
 
3949
 
        r->device_not_selected_timeout          = 0x0;  /* have seen 0x3a98 */
3950
 
        r->transmission_retry_timeout           = 0x0;  /* have seen 0xafc8 */
3951
 
 
3952
 
        return WERR_OK;
3953
 
}
3954
 
 
3955
 
/********************************************************************
3956
 
 * construct_printer_info_6
3957
 
 * fill a spoolss_PrinterInfo6 struct
3958
 
 ********************************************************************/
3959
 
 
3960
 
static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
3961
 
                                      const NT_PRINTER_INFO_LEVEL *ntprinter,
3962
 
                                      struct spoolss_PrinterInfo6 *r,
3963
 
                                      int snum)
3964
 
{
3965
 
        int count;
3966
 
        print_status_struct status;
3967
 
 
3968
 
        count = print_queue_length(snum, &status);
3969
 
 
3970
 
        r->status = nt_printq_status(status.status);
3971
 
 
3972
 
        return WERR_OK;
3973
 
}
3974
 
 
3975
 
/********************************************************************
3976
 
 * construct_printer_info7
3977
 
 * fill a spoolss_PrinterInfo7 struct
3978
 
 ********************************************************************/
3979
 
 
3980
 
static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
3981
 
                                      Printer_entry *print_hnd,
3982
 
                                      struct spoolss_PrinterInfo7 *r,
3983
 
                                      int snum)
3984
 
{
3985
 
        struct GUID guid;
3986
 
 
3987
 
        if (is_printer_published(print_hnd, snum, &guid)) {
3988
 
                r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
3989
 
                r->action = DSPRINT_PUBLISH;
3990
 
        } else {
3991
 
                r->guid = talloc_strdup(mem_ctx, "");
3992
 
                r->action = DSPRINT_UNPUBLISH;
3993
 
        }
3994
 
        W_ERROR_HAVE_NO_MEMORY(r->guid);
3995
 
 
3996
 
        return WERR_OK;
3997
 
}
3998
 
 
3999
 
/********************************************************************
4000
 
 * construct_printer_info8
4001
 
 * fill a spoolss_PrinterInfo8 struct
4002
 
 ********************************************************************/
4003
 
 
4004
 
static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
4005
 
                                      const NT_PRINTER_INFO_LEVEL *ntprinter,
4006
 
                                      struct spoolss_DeviceModeInfo *r,
4007
 
                                      int snum)
4008
 
{
4009
 
        struct spoolss_DeviceMode *devmode;
4010
 
        WERROR result;
4011
 
 
4012
 
        if (!ntprinter->info_2->devmode) {
4013
 
                r->devmode = NULL;
4014
 
                return WERR_OK;
4015
 
        }
4016
 
 
4017
 
        devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode);
4018
 
        W_ERROR_HAVE_NO_MEMORY(devmode);
4019
 
 
4020
 
        result = convert_nt_devicemode(mem_ctx, devmode, ntprinter->info_2->devmode);
4021
 
        if (!W_ERROR_IS_OK(result)) {
4022
 
                TALLOC_FREE(devmode);
4023
 
                return result;
4024
 
        }
4025
 
 
4026
 
        r->devmode      = devmode;
4027
 
 
4028
 
        return WERR_OK;
4029
 
}
4030
 
 
4031
 
 
4032
 
/********************************************************************
4033
 
********************************************************************/
4034
 
 
4035
 
static bool snum_is_shared_printer(int snum)
4036
 
{
4037
 
        return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
4038
 
}
4039
 
 
4040
 
/********************************************************************
4041
 
 Spoolss_enumprinters.
4042
 
********************************************************************/
4043
 
 
4044
 
static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
4045
 
                                           uint32_t level,
4046
 
                                           uint32_t flags,
4047
 
                                           union spoolss_PrinterInfo **info_p,
4048
 
                                           uint32_t *count_p)
4049
 
{
4050
 
        int snum;
4051
 
        int n_services = lp_numservices();
4052
 
        union spoolss_PrinterInfo *info = NULL;
4053
 
        uint32_t count = 0;
4054
 
        WERROR result = WERR_OK;
4055
 
 
4056
 
        *count_p = 0;
4057
 
        *info_p = NULL;
4058
 
 
4059
 
        for (snum = 0; snum < n_services; snum++) {
4060
 
 
4061
 
                NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4062
 
 
4063
 
                if (!snum_is_shared_printer(snum)) {
4064
 
                        continue;
4065
 
                }
4066
 
 
4067
 
                DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
4068
 
                        lp_servicename(snum), snum));
4069
 
 
4070
 
                info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4071
 
                                            union spoolss_PrinterInfo,
4072
 
                                            count + 1);
4073
 
                if (!info) {
4074
 
                        result = WERR_NOMEM;
4075
 
                        goto out;
4076
 
                }
4077
 
 
4078
 
                result = get_a_printer(NULL, &ntprinter, 2,
4079
 
                                       lp_const_servicename(snum));
4080
 
                if (!W_ERROR_IS_OK(result)) {
4081
 
                        goto out;
4082
 
                }
4083
 
 
4084
 
                switch (level) {
4085
 
                case 0:
4086
 
                        result = construct_printer_info0(info, ntprinter,
4087
 
                                                         &info[count].info0, snum);
4088
 
                        break;
4089
 
                case 1:
4090
 
                        result = construct_printer_info1(info, ntprinter, flags,
4091
 
                                                         &info[count].info1, snum);
4092
 
                        break;
4093
 
                case 2:
4094
 
                        result = construct_printer_info2(info, ntprinter,
4095
 
                                                         &info[count].info2, snum);
4096
 
                        break;
4097
 
                case 4:
4098
 
                        result = construct_printer_info4(info, ntprinter,
4099
 
                                                         &info[count].info4, snum);
4100
 
                        break;
4101
 
                case 5:
4102
 
                        result = construct_printer_info5(info, ntprinter,
4103
 
                                                         &info[count].info5, snum);
4104
 
                        break;
4105
 
 
4106
 
                default:
4107
 
                        result = WERR_UNKNOWN_LEVEL;
4108
 
                        free_a_printer(&ntprinter, 2);
4109
 
                        goto out;
4110
 
                }
4111
 
 
4112
 
                free_a_printer(&ntprinter, 2);
4113
 
                if (!W_ERROR_IS_OK(result)) {
4114
 
                        goto out;
4115
 
                }
4116
 
 
4117
 
                count++;
4118
 
        }
4119
 
 
4120
 
        *count_p = count;
4121
 
        *info_p = info;
4122
 
 
4123
 
 out:
4124
 
        if (!W_ERROR_IS_OK(result)) {
4125
 
                TALLOC_FREE(info);
4126
 
                return result;
4127
 
        }
4128
 
 
4129
 
        *info_p = info;
4130
 
 
4131
 
        return WERR_OK;
4132
 
}
4133
 
 
4134
 
/********************************************************************
4135
 
 * handle enumeration of printers at level 0
4136
 
 ********************************************************************/
4137
 
 
4138
 
static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
4139
 
                                  uint32_t flags,
4140
 
                                  const char *servername,
4141
 
                                  union spoolss_PrinterInfo **info,
4142
 
                                  uint32_t *count)
4143
 
{
4144
 
        DEBUG(4,("enum_all_printers_info_0\n"));
4145
 
 
4146
 
        return enum_all_printers_info_level(mem_ctx, 0, flags, info, count);
4147
 
}
4148
 
 
4149
 
 
4150
 
/********************************************************************
4151
 
********************************************************************/
4152
 
 
4153
 
static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
4154
 
                                       uint32_t flags,
4155
 
                                       union spoolss_PrinterInfo **info,
4156
 
                                       uint32_t *count)
4157
 
{
4158
 
        DEBUG(4,("enum_all_printers_info_1\n"));
4159
 
 
4160
 
        return enum_all_printers_info_level(mem_ctx, 1, flags, info, count);
4161
 
}
4162
 
 
4163
 
/********************************************************************
4164
 
 enum_all_printers_info_1_local.
4165
 
*********************************************************************/
4166
 
 
4167
 
static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
4168
 
                                             union spoolss_PrinterInfo **info,
4169
 
                                             uint32_t *count)
4170
 
{
4171
 
        DEBUG(4,("enum_all_printers_info_1_local\n"));
4172
 
 
4173
 
        return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count);
4174
 
}
4175
 
 
4176
 
/********************************************************************
4177
 
 enum_all_printers_info_1_name.
4178
 
*********************************************************************/
4179
 
 
4180
 
static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
4181
 
                                            const char *name,
4182
 
                                            union spoolss_PrinterInfo **info,
4183
 
                                            uint32_t *count)
4184
 
{
4185
 
        const char *s = name;
4186
 
 
4187
 
        DEBUG(4,("enum_all_printers_info_1_name\n"));
4188
 
 
4189
 
        if ((name[0] == '\\') && (name[1] == '\\')) {
4190
 
                s = name + 2;
4191
 
        }
4192
 
 
4193
 
        if (!is_myname_or_ipaddr(s)) {
4194
 
                return WERR_INVALID_NAME;
4195
 
        }
4196
 
 
4197
 
        return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count);
4198
 
}
4199
 
 
4200
 
/********************************************************************
4201
 
 enum_all_printers_info_1_network.
4202
 
*********************************************************************/
4203
 
 
4204
 
static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
4205
 
                                               const char *name,
4206
 
                                               union spoolss_PrinterInfo **info,
4207
 
                                               uint32_t *count)
4208
 
{
4209
 
        const char *s = name;
4210
 
 
4211
 
        DEBUG(4,("enum_all_printers_info_1_network\n"));
4212
 
 
4213
 
        /* If we respond to a enum_printers level 1 on our name with flags
4214
 
           set to PRINTER_ENUM_REMOTE with a list of printers then these
4215
 
           printers incorrectly appear in the APW browse list.
4216
 
           Specifically the printers for the server appear at the workgroup
4217
 
           level where all the other servers in the domain are
4218
 
           listed. Windows responds to this call with a
4219
 
           WERR_CAN_NOT_COMPLETE so we should do the same. */
4220
 
 
4221
 
        if (name[0] == '\\' && name[1] == '\\') {
4222
 
                 s = name + 2;
4223
 
        }
4224
 
 
4225
 
        if (is_myname_or_ipaddr(s)) {
4226
 
                 return WERR_CAN_NOT_COMPLETE;
4227
 
        }
4228
 
 
4229
 
        return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_NAME, info, count);
4230
 
}
4231
 
 
4232
 
/********************************************************************
4233
 
 * api_spoolss_enumprinters
4234
 
 *
4235
 
 * called from api_spoolss_enumprinters (see this to understand)
4236
 
 ********************************************************************/
4237
 
 
4238
 
static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
4239
 
                                       union spoolss_PrinterInfo **info,
4240
 
                                       uint32_t *count)
4241
 
{
4242
 
        DEBUG(4,("enum_all_printers_info_2\n"));
4243
 
 
4244
 
        return enum_all_printers_info_level(mem_ctx, 2, 0, info, count);
4245
 
}
4246
 
 
4247
 
/********************************************************************
4248
 
 * handle enumeration of printers at level 1
4249
 
 ********************************************************************/
4250
 
 
4251
 
static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
4252
 
                                  uint32_t flags,
4253
 
                                  const char *name,
4254
 
                                  union spoolss_PrinterInfo **info,
4255
 
                                  uint32_t *count)
4256
 
{
4257
 
        /* Not all the flags are equals */
4258
 
 
4259
 
        if (flags & PRINTER_ENUM_LOCAL) {
4260
 
                return enum_all_printers_info_1_local(mem_ctx, info, count);
4261
 
        }
4262
 
 
4263
 
        if (flags & PRINTER_ENUM_NAME) {
4264
 
                return enum_all_printers_info_1_name(mem_ctx, name, info, count);
4265
 
        }
4266
 
 
4267
 
        if (flags & PRINTER_ENUM_NETWORK) {
4268
 
                return enum_all_printers_info_1_network(mem_ctx, name, info, count);
4269
 
        }
4270
 
 
4271
 
        return WERR_OK; /* NT4sp5 does that */
4272
 
}
4273
 
 
4274
 
/********************************************************************
4275
 
 * handle enumeration of printers at level 2
4276
 
 ********************************************************************/
4277
 
 
4278
 
static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
4279
 
                                  uint32_t flags,
4280
 
                                  const char *servername,
4281
 
                                  union spoolss_PrinterInfo **info,
4282
 
                                  uint32_t *count)
4283
 
{
4284
 
        if (flags & PRINTER_ENUM_LOCAL) {
4285
 
                return enum_all_printers_info_2(mem_ctx, info, count);
4286
 
        }
4287
 
 
4288
 
        if (flags & PRINTER_ENUM_NAME) {
4289
 
                if (!is_myname_or_ipaddr(canon_servername(servername))) {
4290
 
                        return WERR_INVALID_NAME;
4291
 
                }
4292
 
 
4293
 
                return enum_all_printers_info_2(mem_ctx, info, count);
4294
 
        }
4295
 
 
4296
 
        if (flags & PRINTER_ENUM_REMOTE) {
4297
 
                return WERR_UNKNOWN_LEVEL;
4298
 
        }
4299
 
 
4300
 
        return WERR_OK;
4301
 
}
4302
 
 
4303
 
/********************************************************************
4304
 
 * handle enumeration of printers at level 4
4305
 
 ********************************************************************/
4306
 
 
4307
 
static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
4308
 
                                  uint32_t flags,
4309
 
                                  const char *servername,
4310
 
                                  union spoolss_PrinterInfo **info,
4311
 
                                  uint32_t *count)
4312
 
{
4313
 
        DEBUG(4,("enum_all_printers_info_4\n"));
4314
 
 
4315
 
        return enum_all_printers_info_level(mem_ctx, 4, flags, info, count);
4316
 
}
4317
 
 
4318
 
 
4319
 
/********************************************************************
4320
 
 * handle enumeration of printers at level 5
4321
 
 ********************************************************************/
4322
 
 
4323
 
static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
4324
 
                                  uint32_t flags,
4325
 
                                  const char *servername,
4326
 
                                  union spoolss_PrinterInfo **info,
4327
 
                                  uint32_t *count)
4328
 
{
4329
 
        DEBUG(4,("enum_all_printers_info_5\n"));
4330
 
 
4331
 
        return enum_all_printers_info_level(mem_ctx, 5, flags, info, count);
4332
 
}
4333
 
 
4334
 
/****************************************************************
4335
 
 _spoolss_EnumPrinters
4336
 
****************************************************************/
4337
 
 
4338
 
WERROR _spoolss_EnumPrinters(pipes_struct *p,
4339
 
                             struct spoolss_EnumPrinters *r)
4340
 
{
4341
 
        const char *name = NULL;
4342
 
        WERROR result;
4343
 
 
4344
 
        /* that's an [in out] buffer */
4345
 
 
4346
 
        if (!r->in.buffer && (r->in.offered != 0)) {
4347
 
                return WERR_INVALID_PARAM;
4348
 
        }
4349
 
 
4350
 
        DEBUG(4,("_spoolss_EnumPrinters\n"));
4351
 
 
4352
 
        *r->out.needed = 0;
4353
 
        *r->out.count = 0;
4354
 
        *r->out.info = NULL;
4355
 
 
4356
 
        /*
4357
 
         * Level 1:
4358
 
         *          flags==PRINTER_ENUM_NAME
4359
 
         *           if name=="" then enumerates all printers
4360
 
         *           if name!="" then enumerate the printer
4361
 
         *          flags==PRINTER_ENUM_REMOTE
4362
 
         *          name is NULL, enumerate printers
4363
 
         * Level 2: name!="" enumerates printers, name can't be NULL
4364
 
         * Level 3: doesn't exist
4365
 
         * Level 4: does a local registry lookup
4366
 
         * Level 5: same as Level 2
4367
 
         */
4368
 
 
4369
 
        if (r->in.server) {
4370
 
                name = talloc_strdup_upper(p->mem_ctx, r->in.server);
4371
 
                W_ERROR_HAVE_NO_MEMORY(name);
4372
 
        }
4373
 
 
4374
 
        switch (r->in.level) {
4375
 
        case 0:
4376
 
                result = enumprinters_level0(p->mem_ctx, r->in.flags, name,
4377
 
                                             r->out.info, r->out.count);
4378
 
                break;
4379
 
        case 1:
4380
 
                result = enumprinters_level1(p->mem_ctx, r->in.flags, name,
4381
 
                                             r->out.info, r->out.count);
4382
 
                break;
4383
 
        case 2:
4384
 
                result = enumprinters_level2(p->mem_ctx, r->in.flags, name,
4385
 
                                             r->out.info, r->out.count);
4386
 
                break;
4387
 
        case 4:
4388
 
                result = enumprinters_level4(p->mem_ctx, r->in.flags, name,
4389
 
                                             r->out.info, r->out.count);
4390
 
                break;
4391
 
        case 5:
4392
 
                result = enumprinters_level5(p->mem_ctx, r->in.flags, name,
4393
 
                                             r->out.info, r->out.count);
4394
 
                break;
4395
 
        default:
4396
 
                return WERR_UNKNOWN_LEVEL;
4397
 
        }
4398
 
 
4399
 
        if (!W_ERROR_IS_OK(result)) {
4400
 
                return result;
4401
 
        }
4402
 
 
4403
 
        *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
4404
 
                                                     spoolss_EnumPrinters, NULL,
4405
 
                                                     *r->out.info, r->in.level,
4406
 
                                                     *r->out.count);
4407
 
        *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
4408
 
        *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
4409
 
 
4410
 
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4411
 
}
4412
 
 
4413
 
/****************************************************************
4414
 
 _spoolss_GetPrinter
4415
 
****************************************************************/
4416
 
 
4417
 
WERROR _spoolss_GetPrinter(pipes_struct *p,
4418
 
                           struct spoolss_GetPrinter *r)
4419
 
{
4420
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
4421
 
        NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4422
 
        WERROR result = WERR_OK;
4423
 
 
4424
 
        int snum;
4425
 
 
4426
 
        /* that's an [in out] buffer */
4427
 
 
4428
 
        if (!r->in.buffer && (r->in.offered != 0)) {
4429
 
                return WERR_INVALID_PARAM;
4430
 
        }
4431
 
 
4432
 
        *r->out.needed = 0;
4433
 
 
4434
 
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
4435
 
                return WERR_BADFID;
4436
 
        }
4437
 
 
4438
 
        result = get_a_printer(Printer, &ntprinter, 2,
4439
 
                               lp_const_servicename(snum));
4440
 
        if (!W_ERROR_IS_OK(result)) {
4441
 
                return result;
4442
 
        }
4443
 
 
4444
 
        switch (r->in.level) {
4445
 
        case 0:
4446
 
                result = construct_printer_info0(p->mem_ctx, ntprinter,
4447
 
                                                 &r->out.info->info0, snum);
4448
 
                break;
4449
 
        case 1:
4450
 
                result = construct_printer_info1(p->mem_ctx, ntprinter,
4451
 
                                                 PRINTER_ENUM_ICON8,
4452
 
                                                 &r->out.info->info1, snum);
4453
 
                break;
4454
 
        case 2:
4455
 
                result = construct_printer_info2(p->mem_ctx, ntprinter,
4456
 
                                                 &r->out.info->info2, snum);
4457
 
                break;
4458
 
        case 3:
4459
 
                result = construct_printer_info3(p->mem_ctx, ntprinter,
4460
 
                                                 &r->out.info->info3, snum);
4461
 
                break;
4462
 
        case 4:
4463
 
                result = construct_printer_info4(p->mem_ctx, ntprinter,
4464
 
                                                 &r->out.info->info4, snum);
4465
 
                break;
4466
 
        case 5:
4467
 
                result = construct_printer_info5(p->mem_ctx, ntprinter,
4468
 
                                                 &r->out.info->info5, snum);
4469
 
                break;
4470
 
        case 6:
4471
 
                result = construct_printer_info6(p->mem_ctx, ntprinter,
4472
 
                                                 &r->out.info->info6, snum);
4473
 
                break;
4474
 
        case 7:
4475
 
                result = construct_printer_info7(p->mem_ctx, Printer,
4476
 
                                                 &r->out.info->info7, snum);
4477
 
                break;
4478
 
        case 8:
4479
 
                result = construct_printer_info8(p->mem_ctx, ntprinter,
4480
 
                                                 &r->out.info->info8, snum);
4481
 
                break;
4482
 
        default:
4483
 
                result = WERR_UNKNOWN_LEVEL;
4484
 
                break;
4485
 
        }
4486
 
 
4487
 
        free_a_printer(&ntprinter, 2);
4488
 
 
4489
 
        if (!W_ERROR_IS_OK(result)) {
4490
 
                TALLOC_FREE(r->out.info);
4491
 
                return result;
4492
 
        }
4493
 
 
4494
 
        *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo, NULL,
4495
 
                                               r->out.info, r->in.level);
4496
 
        r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
4497
 
 
4498
 
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4499
 
}
4500
 
 
4501
 
/********************************************************************
4502
 
 ********************************************************************/
4503
 
 
4504
 
static const char **string_array_from_driver_info(TALLOC_CTX *mem_ctx,
4505
 
                                                  const char **string_array,
4506
 
                                                  const char *cservername)
4507
 
{
4508
 
        int i, num_strings = 0;
4509
 
        const char **array = NULL;
4510
 
 
4511
 
        if (!string_array) {
4512
 
                return NULL;
4513
 
        }
4514
 
 
4515
 
        for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
4516
 
 
4517
 
                const char *str = talloc_asprintf(mem_ctx, "\\\\%s%s",
4518
 
                                                  cservername, string_array[i]);
4519
 
                if (!str) {
4520
 
                        TALLOC_FREE(array);
4521
 
                        return NULL;
4522
 
                }
4523
 
 
4524
 
 
4525
 
                if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
4526
 
                        TALLOC_FREE(array);
4527
 
                        return NULL;
4528
 
                }
4529
 
        }
4530
 
 
4531
 
        if (i > 0) {
4532
 
                ADD_TO_ARRAY(mem_ctx, const char *, NULL,
4533
 
                             &array, &num_strings);
4534
 
        }
4535
 
 
4536
 
        return array;
4537
 
}
4538
 
 
4539
 
#define FILL_DRIVER_STRING(mem_ctx, in, out) \
4540
 
        do { \
4541
 
                if (in && strlen(in)) { \
4542
 
                        out = talloc_strdup(mem_ctx, in); \
4543
 
                        W_ERROR_HAVE_NO_MEMORY(out); \
4544
 
                } else { \
4545
 
                        out = NULL; \
4546
 
                } \
4547
 
        } while (0);
4548
 
 
4549
 
#define FILL_DRIVER_UNC_STRING(mem_ctx, server, in, out) \
4550
 
        do { \
4551
 
                if (in && strlen(in)) { \
4552
 
                        out = talloc_asprintf(mem_ctx, "\\\\%s%s", server, in); \
4553
 
                } else { \
4554
 
                        out = talloc_strdup(mem_ctx, ""); \
4555
 
                } \
4556
 
                W_ERROR_HAVE_NO_MEMORY(out); \
4557
 
        } while (0);
4558
 
 
4559
 
/********************************************************************
4560
 
 * fill a spoolss_DriverInfo1 struct
4561
 
 ********************************************************************/
4562
 
 
4563
 
static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
4564
 
                                        struct spoolss_DriverInfo1 *r,
4565
 
                                        const struct spoolss_DriverInfo8 *driver,
4566
 
                                        const char *servername)
4567
 
{
4568
 
        r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4569
 
        W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4570
 
 
4571
 
        return WERR_OK;
4572
 
}
4573
 
 
4574
 
/********************************************************************
4575
 
 * fill a spoolss_DriverInfo2 struct
4576
 
 ********************************************************************/
4577
 
 
4578
 
static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
4579
 
                                        struct spoolss_DriverInfo2 *r,
4580
 
                                        const struct spoolss_DriverInfo8 *driver,
4581
 
                                        const char *servername)
4582
 
 
4583
 
{
4584
 
        const char *cservername = canon_servername(servername);
4585
 
 
4586
 
        r->version              = driver->version;
4587
 
 
4588
 
        r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4589
 
        W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4590
 
        r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
4591
 
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
4592
 
 
4593
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4594
 
                               driver->driver_path,
4595
 
                               r->driver_path);
4596
 
 
4597
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4598
 
                               driver->data_file,
4599
 
                               r->data_file);
4600
 
 
4601
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4602
 
                               driver->config_file,
4603
 
                               r->config_file);
4604
 
 
4605
 
        return WERR_OK;
4606
 
}
4607
 
 
4608
 
/********************************************************************
4609
 
 * fill a spoolss_DriverInfo3 struct
4610
 
 ********************************************************************/
4611
 
 
4612
 
static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
4613
 
                                        struct spoolss_DriverInfo3 *r,
4614
 
                                        const struct spoolss_DriverInfo8 *driver,
4615
 
                                        const char *servername)
4616
 
{
4617
 
        const char *cservername = canon_servername(servername);
4618
 
 
4619
 
        r->version              = driver->version;
4620
 
 
4621
 
        r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4622
 
        W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4623
 
        r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
4624
 
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
4625
 
 
4626
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4627
 
                               driver->driver_path,
4628
 
                               r->driver_path);
4629
 
 
4630
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4631
 
                               driver->data_file,
4632
 
                               r->data_file);
4633
 
 
4634
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4635
 
                               driver->config_file,
4636
 
                               r->config_file);
4637
 
 
4638
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4639
 
                               driver->help_file,
4640
 
                               r->help_file);
4641
 
 
4642
 
        FILL_DRIVER_STRING(mem_ctx,
4643
 
                           driver->monitor_name,
4644
 
                           r->monitor_name);
4645
 
 
4646
 
        FILL_DRIVER_STRING(mem_ctx,
4647
 
                           driver->default_datatype,
4648
 
                           r->default_datatype);
4649
 
 
4650
 
        r->dependent_files = string_array_from_driver_info(mem_ctx,
4651
 
                                                           driver->dependent_files,
4652
 
                                                           cservername);
4653
 
        return WERR_OK;
4654
 
}
4655
 
 
4656
 
/********************************************************************
4657
 
 * fill a spoolss_DriverInfo4 struct
4658
 
 ********************************************************************/
4659
 
 
4660
 
static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
4661
 
                                        struct spoolss_DriverInfo4 *r,
4662
 
                                        const struct spoolss_DriverInfo8 *driver,
4663
 
                                        const char *servername)
4664
 
{
4665
 
        const char *cservername = canon_servername(servername);
4666
 
 
4667
 
        r->version              = driver->version;
4668
 
 
4669
 
        r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4670
 
        W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4671
 
        r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
4672
 
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
4673
 
 
4674
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4675
 
                               driver->driver_path,
4676
 
                               r->driver_path);
4677
 
 
4678
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4679
 
                               driver->data_file,
4680
 
                               r->data_file);
4681
 
 
4682
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4683
 
                               driver->config_file,
4684
 
                               r->config_file);
4685
 
 
4686
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4687
 
                               driver->help_file,
4688
 
                               r->help_file);
4689
 
 
4690
 
        r->dependent_files = string_array_from_driver_info(mem_ctx,
4691
 
                                                           driver->dependent_files,
4692
 
                                                           cservername);
4693
 
 
4694
 
        FILL_DRIVER_STRING(mem_ctx,
4695
 
                           driver->monitor_name,
4696
 
                           r->monitor_name);
4697
 
 
4698
 
        FILL_DRIVER_STRING(mem_ctx,
4699
 
                           driver->default_datatype,
4700
 
                           r->default_datatype);
4701
 
 
4702
 
        r->previous_names = string_array_from_driver_info(mem_ctx,
4703
 
                                                          driver->previous_names,
4704
 
                                                          cservername);
4705
 
 
4706
 
        return WERR_OK;
4707
 
}
4708
 
 
4709
 
/********************************************************************
4710
 
 * fill a spoolss_DriverInfo5 struct
4711
 
 ********************************************************************/
4712
 
 
4713
 
static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
4714
 
                                        struct spoolss_DriverInfo5 *r,
4715
 
                                        const struct spoolss_DriverInfo8 *driver,
4716
 
                                        const char *servername)
4717
 
{
4718
 
        const char *cservername = canon_servername(servername);
4719
 
 
4720
 
        r->version              = driver->version;
4721
 
 
4722
 
        r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4723
 
        W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4724
 
        r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
4725
 
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
4726
 
 
4727
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4728
 
                               driver->driver_path,
4729
 
                               r->driver_path);
4730
 
 
4731
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4732
 
                               driver->data_file,
4733
 
                               r->data_file);
4734
 
 
4735
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4736
 
                               driver->config_file,
4737
 
                               r->config_file);
4738
 
 
4739
 
        r->driver_attributes    = 0;
4740
 
        r->config_version       = 0;
4741
 
        r->driver_version       = 0;
4742
 
 
4743
 
        return WERR_OK;
4744
 
}
4745
 
/********************************************************************
4746
 
 * fill a spoolss_DriverInfo6 struct
4747
 
 ********************************************************************/
4748
 
 
4749
 
static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
4750
 
                                        struct spoolss_DriverInfo6 *r,
4751
 
                                        const struct spoolss_DriverInfo8 *driver,
4752
 
                                        const char *servername)
4753
 
{
4754
 
        const char *cservername = canon_servername(servername);
4755
 
 
4756
 
        r->version              = driver->version;
4757
 
 
4758
 
        r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4759
 
        W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4760
 
        r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
4761
 
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
4762
 
 
4763
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4764
 
                               driver->driver_path,
4765
 
                               r->driver_path);
4766
 
 
4767
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4768
 
                               driver->data_file,
4769
 
                               r->data_file);
4770
 
 
4771
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4772
 
                               driver->config_file,
4773
 
                               r->config_file);
4774
 
 
4775
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4776
 
                               driver->help_file,
4777
 
                               r->help_file);
4778
 
 
4779
 
        FILL_DRIVER_STRING(mem_ctx,
4780
 
                           driver->monitor_name,
4781
 
                           r->monitor_name);
4782
 
 
4783
 
        FILL_DRIVER_STRING(mem_ctx,
4784
 
                           driver->default_datatype,
4785
 
                           r->default_datatype);
4786
 
 
4787
 
        r->dependent_files = string_array_from_driver_info(mem_ctx,
4788
 
                                                           driver->dependent_files,
4789
 
                                                           cservername);
4790
 
        r->previous_names = string_array_from_driver_info(mem_ctx,
4791
 
                                                          driver->previous_names,
4792
 
                                                          cservername);
4793
 
 
4794
 
        r->driver_date          = driver->driver_date;
4795
 
        r->driver_version       = driver->driver_version;
4796
 
 
4797
 
        FILL_DRIVER_STRING(mem_ctx,
4798
 
                           driver->manufacturer_name,
4799
 
                           r->manufacturer_name);
4800
 
        FILL_DRIVER_STRING(mem_ctx,
4801
 
                           driver->manufacturer_url,
4802
 
                           r->manufacturer_url);
4803
 
        FILL_DRIVER_STRING(mem_ctx,
4804
 
                           driver->hardware_id,
4805
 
                           r->hardware_id);
4806
 
        FILL_DRIVER_STRING(mem_ctx,
4807
 
                           driver->provider,
4808
 
                           r->provider);
4809
 
 
4810
 
        return WERR_OK;
4811
 
}
4812
 
 
4813
 
/********************************************************************
4814
 
 * fill a spoolss_DriverInfo8 struct
4815
 
 ********************************************************************/
4816
 
 
4817
 
static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
4818
 
                                        struct spoolss_DriverInfo8 *r,
4819
 
                                        const struct spoolss_DriverInfo8 *driver,
4820
 
                                        const char *servername)
4821
 
{
4822
 
        const char *cservername = canon_servername(servername);
4823
 
 
4824
 
        r->version              = driver->version;
4825
 
 
4826
 
        r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
4827
 
        W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4828
 
        r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
4829
 
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
4830
 
 
4831
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4832
 
                               driver->driver_path,
4833
 
                               r->driver_path);
4834
 
 
4835
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4836
 
                               driver->data_file,
4837
 
                               r->data_file);
4838
 
 
4839
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4840
 
                               driver->config_file,
4841
 
                               r->config_file);
4842
 
 
4843
 
        FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4844
 
                               driver->help_file,
4845
 
                               r->help_file);
4846
 
 
4847
 
        FILL_DRIVER_STRING(mem_ctx,
4848
 
                           driver->monitor_name,
4849
 
                           r->monitor_name);
4850
 
 
4851
 
        FILL_DRIVER_STRING(mem_ctx,
4852
 
                           driver->default_datatype,
4853
 
                           r->default_datatype);
4854
 
 
4855
 
        r->dependent_files = string_array_from_driver_info(mem_ctx,
4856
 
                                                           driver->dependent_files,
4857
 
                                                           cservername);
4858
 
        r->previous_names = string_array_from_driver_info(mem_ctx,
4859
 
                                                          driver->previous_names,
4860
 
                                                          cservername);
4861
 
 
4862
 
        r->driver_date          = driver->driver_date;
4863
 
        r->driver_version       = driver->driver_version;
4864
 
 
4865
 
        FILL_DRIVER_STRING(mem_ctx,
4866
 
                           driver->manufacturer_name,
4867
 
                           r->manufacturer_name);
4868
 
        FILL_DRIVER_STRING(mem_ctx,
4869
 
                           driver->manufacturer_url,
4870
 
                           r->manufacturer_url);
4871
 
        FILL_DRIVER_STRING(mem_ctx,
4872
 
                           driver->hardware_id,
4873
 
                           r->hardware_id);
4874
 
        FILL_DRIVER_STRING(mem_ctx,
4875
 
                           driver->provider,
4876
 
                           r->provider);
4877
 
 
4878
 
        FILL_DRIVER_STRING(mem_ctx,
4879
 
                           driver->print_processor,
4880
 
                           r->print_processor);
4881
 
        FILL_DRIVER_STRING(mem_ctx,
4882
 
                           driver->vendor_setup,
4883
 
                           r->vendor_setup);
4884
 
 
4885
 
        r->color_profiles = string_array_from_driver_info(mem_ctx,
4886
 
                                                          driver->color_profiles,
4887
 
                                                          cservername);
4888
 
 
4889
 
        FILL_DRIVER_STRING(mem_ctx,
4890
 
                           driver->inf_path,
4891
 
                           r->inf_path);
4892
 
 
4893
 
        r->printer_driver_attributes    = driver->printer_driver_attributes;
4894
 
 
4895
 
        r->core_driver_dependencies = string_array_from_driver_info(mem_ctx,
4896
 
                                                                    driver->core_driver_dependencies,
4897
 
                                                                    cservername);
4898
 
 
4899
 
        r->min_inbox_driver_ver_date    = driver->min_inbox_driver_ver_date;
4900
 
        r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
4901
 
 
4902
 
        return WERR_OK;
4903
 
}
4904
 
 
4905
 
#if 0 /* disabled until marshalling issues are resolved - gd */
4906
 
/********************************************************************
4907
 
 ********************************************************************/
4908
 
 
4909
 
static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
4910
 
                                          struct spoolss_DriverFileInfo *r,
4911
 
                                          const char *cservername,
4912
 
                                          const char *file_name,
4913
 
                                          enum spoolss_DriverFileType file_type,
4914
 
                                          uint32_t file_version)
4915
 
{
4916
 
        r->file_name    = talloc_asprintf(mem_ctx, "\\\\%s%s",
4917
 
                                          cservername, file_name);
4918
 
        W_ERROR_HAVE_NO_MEMORY(r->file_name);
4919
 
        r->file_type    = file_type;
4920
 
        r->file_version = file_version;
4921
 
 
4922
 
        return WERR_OK;
4923
 
}
4924
 
 
4925
 
/********************************************************************
4926
 
 ********************************************************************/
4927
 
 
4928
 
static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
4929
 
                                                 const struct spoolss_DriverInfo8 *driver,
4930
 
                                                 const char *cservername,
4931
 
                                                 struct spoolss_DriverFileInfo **info_p,
4932
 
                                                 uint32_t *count_p)
4933
 
{
4934
 
        struct spoolss_DriverFileInfo *info = NULL;
4935
 
        uint32_t count = 0;
4936
 
        WERROR result;
4937
 
        uint32_t i;
4938
 
 
4939
 
        *info_p = NULL;
4940
 
        *count_p = 0;
4941
 
 
4942
 
        if (strlen(driver->driver_path)) {
4943
 
                info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4944
 
                                            struct spoolss_DriverFileInfo,
4945
 
                                            count + 1);
4946
 
                W_ERROR_HAVE_NO_MEMORY(info);
4947
 
                result = fill_spoolss_DriverFileInfo(info,
4948
 
                                                     &info[count],
4949
 
                                                     cservername,
4950
 
                                                     driver->driver_path,
4951
 
                                                     SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
4952
 
                                                     0);
4953
 
                W_ERROR_NOT_OK_RETURN(result);
4954
 
                count++;
4955
 
        }
4956
 
 
4957
 
        if (strlen(driver->config_file)) {
4958
 
                info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4959
 
                                            struct spoolss_DriverFileInfo,
4960
 
                                            count + 1);
4961
 
                W_ERROR_HAVE_NO_MEMORY(info);
4962
 
                result = fill_spoolss_DriverFileInfo(info,
4963
 
                                                     &info[count],
4964
 
                                                     cservername,
4965
 
                                                     driver->config_file,
4966
 
                                                     SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
4967
 
                                                     0);
4968
 
                W_ERROR_NOT_OK_RETURN(result);
4969
 
                count++;
4970
 
        }
4971
 
 
4972
 
        if (strlen(driver->data_file)) {
4973
 
                info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4974
 
                                            struct spoolss_DriverFileInfo,
4975
 
                                            count + 1);
4976
 
                W_ERROR_HAVE_NO_MEMORY(info);
4977
 
                result = fill_spoolss_DriverFileInfo(info,
4978
 
                                                     &info[count],
4979
 
                                                     cservername,
4980
 
                                                     driver->data_file,
4981
 
                                                     SPOOLSS_DRIVER_FILE_TYPE_DATA,
4982
 
                                                     0);
4983
 
                W_ERROR_NOT_OK_RETURN(result);
4984
 
                count++;
4985
 
        }
4986
 
 
4987
 
        if (strlen(driver->help_file)) {
4988
 
                info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4989
 
                                            struct spoolss_DriverFileInfo,
4990
 
                                            count + 1);
4991
 
                W_ERROR_HAVE_NO_MEMORY(info);
4992
 
                result = fill_spoolss_DriverFileInfo(info,
4993
 
                                                     &info[count],
4994
 
                                                     cservername,
4995
 
                                                     driver->help_file,
4996
 
                                                     SPOOLSS_DRIVER_FILE_TYPE_HELP,
4997
 
                                                     0);
4998
 
                W_ERROR_NOT_OK_RETURN(result);
4999
 
                count++;
5000
 
        }
5001
 
 
5002
 
        for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
5003
 
                info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
5004
 
                                            struct spoolss_DriverFileInfo,
5005
 
                                            count + 1);
5006
 
                W_ERROR_HAVE_NO_MEMORY(info);
5007
 
                result = fill_spoolss_DriverFileInfo(info,
5008
 
                                                     &info[count],
5009
 
                                                     cservername,
5010
 
                                                     driver->dependent_files[i],
5011
 
                                                     SPOOLSS_DRIVER_FILE_TYPE_OTHER,
5012
 
                                                     0);
5013
 
                W_ERROR_NOT_OK_RETURN(result);
5014
 
                count++;
5015
 
        }
5016
 
 
5017
 
        *info_p = info;
5018
 
        *count_p = count;
5019
 
 
5020
 
        return WERR_OK;
5021
 
}
5022
 
 
5023
 
/********************************************************************
5024
 
 * fill a spoolss_DriverInfo101 struct
5025
 
 ********************************************************************/
5026
 
 
5027
 
static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
5028
 
                                          struct spoolss_DriverInfo101 *r,
5029
 
                                          const struct spoolss_DriverInfo8 *driver,
5030
 
                                          const char *servername)
5031
 
{
5032
 
        const char *cservername = canon_servername(servername);
5033
 
        WERROR result;
5034
 
 
5035
 
        r->version              = driver->version;
5036
 
 
5037
 
        r->driver_name          = talloc_strdup(mem_ctx, driver->driver_name);
5038
 
        W_ERROR_HAVE_NO_MEMORY(r->driver_name);
5039
 
        r->architecture         = talloc_strdup(mem_ctx, driver->architecture);
5040
 
        W_ERROR_HAVE_NO_MEMORY(r->architecture);
5041
 
 
5042
 
        result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
5043
 
                                                    cservername,
5044
 
                                                    &r->file_info,
5045
 
                                                    &r->file_count);
5046
 
        if (!W_ERROR_IS_OK(result)) {
5047
 
                return result;
5048
 
        }
5049
 
 
5050
 
        FILL_DRIVER_STRING(mem_ctx,
5051
 
                           driver->monitor_name,
5052
 
                           r->monitor_name);
5053
 
 
5054
 
        FILL_DRIVER_STRING(mem_ctx,
5055
 
                           driver->default_datatype,
5056
 
                           r->default_datatype);
5057
 
 
5058
 
        r->previous_names = string_array_from_driver_info(mem_ctx,
5059
 
                                                          driver->previous_names,
5060
 
                                                          cservername);
5061
 
        r->driver_date          = driver->driver_date;
5062
 
        r->driver_version       = driver->driver_version;
5063
 
 
5064
 
        FILL_DRIVER_STRING(mem_ctx,
5065
 
                           driver->manufacturer_name,
5066
 
                           r->manufacturer_name);
5067
 
        FILL_DRIVER_STRING(mem_ctx,
5068
 
                           driver->manufacturer_url,
5069
 
                           r->manufacturer_url);
5070
 
        FILL_DRIVER_STRING(mem_ctx,
5071
 
                           driver->hardware_id,
5072
 
                           r->hardware_id);
5073
 
        FILL_DRIVER_STRING(mem_ctx,
5074
 
                           driver->provider,
5075
 
                           r->provider);
5076
 
 
5077
 
        return WERR_OK;
5078
 
}
5079
 
#endif
5080
 
/********************************************************************
5081
 
 ********************************************************************/
5082
 
 
5083
 
static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
5084
 
                                                  uint32_t level,
5085
 
                                                  union spoolss_DriverInfo *r,
5086
 
                                                  int snum,
5087
 
                                                  const char *servername,
5088
 
                                                  const char *architecture,
5089
 
                                                  uint32_t version)
5090
 
{
5091
 
        NT_PRINTER_INFO_LEVEL *printer = NULL;
5092
 
        struct spoolss_DriverInfo8 *driver;
5093
 
        WERROR result;
5094
 
 
5095
 
        result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
5096
 
 
5097
 
        DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5098
 
                win_errstr(result)));
5099
 
 
5100
 
        if (!W_ERROR_IS_OK(result)) {
5101
 
                return WERR_INVALID_PRINTER_NAME;
5102
 
        }
5103
 
 
5104
 
        result = get_a_printer_driver(mem_ctx, &driver, printer->info_2->drivername,
5105
 
                                      architecture, version);
5106
 
 
5107
 
        DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5108
 
                win_errstr(result)));
5109
 
 
5110
 
        if (!W_ERROR_IS_OK(result)) {
5111
 
                /*
5112
 
                 * Is this a W2k client ?
5113
 
                 */
5114
 
 
5115
 
                if (version < 3) {
5116
 
                        free_a_printer(&printer, 2);
5117
 
                        return WERR_UNKNOWN_PRINTER_DRIVER;
5118
 
                }
5119
 
 
5120
 
                /* Yes - try again with a WinNT driver. */
5121
 
                version = 2;
5122
 
                result = get_a_printer_driver(mem_ctx, &driver, printer->info_2->drivername,
5123
 
                                              architecture, version);
5124
 
                DEBUG(8,("construct_printer_driver_level: status: %s\n",
5125
 
                        win_errstr(result)));
5126
 
                if (!W_ERROR_IS_OK(result)) {
5127
 
                        free_a_printer(&printer, 2);
5128
 
                        return WERR_UNKNOWN_PRINTER_DRIVER;
5129
 
                }
5130
 
        }
5131
 
 
5132
 
        switch (level) {
5133
 
        case 1:
5134
 
                result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
5135
 
                break;
5136
 
        case 2:
5137
 
                result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
5138
 
                break;
5139
 
        case 3:
5140
 
                result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
5141
 
                break;
5142
 
        case 4:
5143
 
                result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
5144
 
                break;
5145
 
        case 5:
5146
 
                result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
5147
 
                break;
5148
 
        case 6:
5149
 
                result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
5150
 
                break;
5151
 
        case 8:
5152
 
                result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
5153
 
                break;
5154
 
#if 0 /* disabled until marshalling issues are resolved - gd */
5155
 
        case 101:
5156
 
                result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
5157
 
                break;
5158
 
#endif
5159
 
        default:
5160
 
                result = WERR_UNKNOWN_LEVEL;
5161
 
                break;
5162
 
        }
5163
 
 
5164
 
        free_a_printer(&printer, 2);
5165
 
        free_a_printer_driver(driver);
5166
 
 
5167
 
        return result;
5168
 
}
5169
 
 
5170
 
/****************************************************************
5171
 
 _spoolss_GetPrinterDriver2
5172
 
****************************************************************/
5173
 
 
5174
 
WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
5175
 
                                  struct spoolss_GetPrinterDriver2 *r)
5176
 
{
5177
 
        Printer_entry *printer;
5178
 
        WERROR result;
5179
 
 
5180
 
        const char *servername;
5181
 
        int snum;
5182
 
 
5183
 
        /* that's an [in out] buffer */
5184
 
 
5185
 
        if (!r->in.buffer && (r->in.offered != 0)) {
5186
 
                return WERR_INVALID_PARAM;
5187
 
        }
5188
 
 
5189
 
        DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5190
 
 
5191
 
        if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
5192
 
                DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5193
 
                return WERR_INVALID_PRINTER_NAME;
5194
 
        }
5195
 
 
5196
 
        *r->out.needed = 0;
5197
 
        *r->out.server_major_version = 0;
5198
 
        *r->out.server_minor_version = 0;
5199
 
 
5200
 
        servername = get_server_name(printer);
5201
 
 
5202
 
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5203
 
                return WERR_BADFID;
5204
 
        }
5205
 
 
5206
 
        result = construct_printer_driver_info_level(p->mem_ctx, r->in.level,
5207
 
                                                     r->out.info, snum,
5208
 
                                                     servername,
5209
 
                                                     r->in.architecture,
5210
 
                                                     r->in.client_major_version);
5211
 
        if (!W_ERROR_IS_OK(result)) {
5212
 
                TALLOC_FREE(r->out.info);
5213
 
                return result;
5214
 
        }
5215
 
 
5216
 
        *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo, NULL,
5217
 
                                               r->out.info, r->in.level);
5218
 
        r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
5219
 
 
5220
 
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
5221
 
}
5222
 
 
5223
 
 
5224
 
/****************************************************************
5225
 
 _spoolss_StartPagePrinter
5226
 
****************************************************************/
5227
 
 
5228
 
WERROR _spoolss_StartPagePrinter(pipes_struct *p,
5229
 
                                 struct spoolss_StartPagePrinter *r)
5230
 
{
5231
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5232
 
 
5233
 
        if (!Printer) {
5234
 
                DEBUG(3,("_spoolss_StartPagePrinter: "
5235
 
                        "Error in startpageprinter printer handle\n"));
5236
 
                return WERR_BADFID;
5237
 
        }
5238
 
 
5239
 
        Printer->page_started = true;
5240
 
        return WERR_OK;
5241
 
}
5242
 
 
5243
 
/****************************************************************
5244
 
 _spoolss_EndPagePrinter
5245
 
****************************************************************/
5246
 
 
5247
 
WERROR _spoolss_EndPagePrinter(pipes_struct *p,
5248
 
                               struct spoolss_EndPagePrinter *r)
5249
 
{
5250
 
        int snum;
5251
 
 
5252
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5253
 
 
5254
 
        if (!Printer) {
5255
 
                DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5256
 
                        OUR_HANDLE(r->in.handle)));
5257
 
                return WERR_BADFID;
5258
 
        }
5259
 
 
5260
 
        if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5261
 
                return WERR_BADFID;
5262
 
 
5263
 
        Printer->page_started = false;
5264
 
        print_job_endpage(snum, Printer->jobid);
5265
 
 
5266
 
        return WERR_OK;
5267
 
}
5268
 
 
5269
 
/****************************************************************
5270
 
 _spoolss_StartDocPrinter
5271
 
****************************************************************/
5272
 
 
5273
 
WERROR _spoolss_StartDocPrinter(pipes_struct *p,
5274
 
                                struct spoolss_StartDocPrinter *r)
5275
 
{
5276
 
        struct spoolss_DocumentInfo1 *info_1;
5277
 
        int snum;
5278
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5279
 
 
5280
 
        if (!Printer) {
5281
 
                DEBUG(2,("_spoolss_StartDocPrinter: "
5282
 
                        "Invalid handle (%s:%u:%u)\n",
5283
 
                        OUR_HANDLE(r->in.handle)));
5284
 
                return WERR_BADFID;
5285
 
        }
5286
 
 
5287
 
        if (r->in.level != 1) {
5288
 
                return WERR_UNKNOWN_LEVEL;
5289
 
        }
5290
 
 
5291
 
        info_1 = r->in.info.info1;
5292
 
 
5293
 
        /*
5294
 
         * a nice thing with NT is it doesn't listen to what you tell it.
5295
 
         * when asked to send _only_ RAW datas, it tries to send datas
5296
 
         * in EMF format.
5297
 
         *
5298
 
         * So I add checks like in NT Server ...
5299
 
         */
5300
 
 
5301
 
        if (info_1->datatype) {
5302
 
                if (strcmp(info_1->datatype, "RAW") != 0) {
5303
 
                        *r->out.job_id = 0;
5304
 
                        return WERR_INVALID_DATATYPE;
5305
 
                }
5306
 
        }
5307
 
 
5308
 
        /* get the share number of the printer */
5309
 
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5310
 
                return WERR_BADFID;
5311
 
        }
5312
 
 
5313
 
        Printer->jobid = print_job_start(p->server_info, snum,
5314
 
                                         info_1->document_name,
5315
 
                                         Printer->nt_devmode);
5316
 
 
5317
 
        /* An error occured in print_job_start() so return an appropriate
5318
 
           NT error code. */
5319
 
 
5320
 
        if (Printer->jobid == -1) {
5321
 
                return map_werror_from_unix(errno);
5322
 
        }
5323
 
 
5324
 
        Printer->document_started = true;
5325
 
        *r->out.job_id = Printer->jobid;
5326
 
 
5327
 
        return WERR_OK;
5328
 
}
5329
 
 
5330
 
/****************************************************************
5331
 
 _spoolss_EndDocPrinter
5332
 
****************************************************************/
5333
 
 
5334
 
WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5335
 
                              struct spoolss_EndDocPrinter *r)
5336
 
{
5337
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5338
 
        int snum;
5339
 
 
5340
 
        if (!Printer) {
5341
 
                DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5342
 
                        OUR_HANDLE(r->in.handle)));
5343
 
                return WERR_BADFID;
5344
 
        }
5345
 
 
5346
 
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5347
 
                return WERR_BADFID;
5348
 
        }
5349
 
 
5350
 
        Printer->document_started = false;
5351
 
        print_job_end(snum, Printer->jobid, NORMAL_CLOSE);
5352
 
        /* error codes unhandled so far ... */
5353
 
 
5354
 
        return WERR_OK;
5355
 
}
5356
 
 
5357
 
/****************************************************************
5358
 
 _spoolss_WritePrinter
5359
 
****************************************************************/
5360
 
 
5361
 
WERROR _spoolss_WritePrinter(pipes_struct *p,
5362
 
                             struct spoolss_WritePrinter *r)
5363
 
{
5364
 
        uint32_t buffer_written;
5365
 
        int snum;
5366
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5367
 
 
5368
 
        if (!Printer) {
5369
 
                DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5370
 
                        OUR_HANDLE(r->in.handle)));
5371
 
                *r->out.num_written = r->in._data_size;
5372
 
                return WERR_BADFID;
5373
 
        }
5374
 
 
5375
 
        if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5376
 
                return WERR_BADFID;
5377
 
 
5378
 
        buffer_written = (uint32_t)print_job_write(snum, Printer->jobid,
5379
 
                                                   (const char *)r->in.data.data,
5380
 
                                                   (SMB_OFF_T)-1,
5381
 
                                                   (size_t)r->in._data_size);
5382
 
        if (buffer_written == (uint32_t)-1) {
5383
 
                *r->out.num_written = 0;
5384
 
                if (errno == ENOSPC)
5385
 
                        return WERR_NO_SPOOL_SPACE;
5386
 
                else
5387
 
                        return WERR_ACCESS_DENIED;
5388
 
        }
5389
 
 
5390
 
        *r->out.num_written = r->in._data_size;
5391
 
 
5392
 
        return WERR_OK;
5393
 
}
5394
 
 
5395
 
/********************************************************************
5396
 
 * api_spoolss_getprinter
5397
 
 * called from the spoolss dispatcher
5398
 
 *
5399
 
 ********************************************************************/
5400
 
 
5401
 
static WERROR control_printer(struct policy_handle *handle, uint32_t command,
5402
 
                              pipes_struct *p)
5403
 
{
5404
 
        int snum;
5405
 
        WERROR errcode = WERR_BADFUNC;
5406
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5407
 
 
5408
 
        if (!Printer) {
5409
 
                DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5410
 
                        OUR_HANDLE(handle)));
5411
 
                return WERR_BADFID;
5412
 
        }
5413
 
 
5414
 
        if (!get_printer_snum(p, handle, &snum, NULL))
5415
 
                return WERR_BADFID;
5416
 
 
5417
 
        switch (command) {
5418
 
        case SPOOLSS_PRINTER_CONTROL_PAUSE:
5419
 
                errcode = print_queue_pause(p->server_info, snum);
5420
 
                break;
5421
 
        case SPOOLSS_PRINTER_CONTROL_RESUME:
5422
 
        case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5423
 
                errcode = print_queue_resume(p->server_info, snum);
5424
 
                break;
5425
 
        case SPOOLSS_PRINTER_CONTROL_PURGE:
5426
 
                errcode = print_queue_purge(p->server_info, snum);
5427
 
                break;
5428
 
        default:
5429
 
                return WERR_UNKNOWN_LEVEL;
5430
 
        }
5431
 
 
5432
 
        return errcode;
5433
 
}
5434
 
 
5435
 
 
5436
 
/****************************************************************
5437
 
 _spoolss_AbortPrinter
5438
 
 * From MSDN: "Deletes printer's spool file if printer is configured
5439
 
 * for spooling"
5440
 
****************************************************************/
5441
 
 
5442
 
WERROR _spoolss_AbortPrinter(pipes_struct *p,
5443
 
                             struct spoolss_AbortPrinter *r)
5444
 
{
5445
 
        Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
5446
 
        int             snum;
5447
 
        WERROR          errcode = WERR_OK;
5448
 
 
5449
 
        if (!Printer) {
5450
 
                DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5451
 
                        OUR_HANDLE(r->in.handle)));
5452
 
                return WERR_BADFID;
5453
 
        }
5454
 
 
5455
 
        if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5456
 
                return WERR_BADFID;
5457
 
 
5458
 
        print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
5459
 
 
5460
 
        return errcode;
5461
 
}
5462
 
 
5463
 
/********************************************************************
5464
 
 * called by spoolss_api_setprinter
5465
 
 * when updating a printer description
5466
 
 ********************************************************************/
5467
 
 
5468
 
static WERROR update_printer_sec(struct policy_handle *handle,
5469
 
                                 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
5470
 
{
5471
 
        SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
5472
 
        WERROR result;
5473
 
        int snum;
5474
 
 
5475
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5476
 
 
5477
 
        if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5478
 
                DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5479
 
                         OUR_HANDLE(handle)));
5480
 
 
5481
 
                result = WERR_BADFID;
5482
 
                goto done;
5483
 
        }
5484
 
 
5485
 
        if (!secdesc_ctr) {
5486
 
                DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5487
 
                result = WERR_INVALID_PARAM;
5488
 
                goto done;
5489
 
        }
5490
 
 
5491
 
        /* Check the user has permissions to change the security
5492
 
           descriptor.  By experimentation with two NT machines, the user
5493
 
           requires Full Access to the printer to change security
5494
 
           information. */
5495
 
 
5496
 
        if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5497
 
                DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5498
 
                result = WERR_ACCESS_DENIED;
5499
 
                goto done;
5500
 
        }
5501
 
 
5502
 
        /* NT seems to like setting the security descriptor even though
5503
 
           nothing may have actually changed. */
5504
 
 
5505
 
        if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) {
5506
 
                DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
5507
 
                result = WERR_BADFID;
5508
 
                goto done;
5509
 
        }
5510
 
 
5511
 
        if (DEBUGLEVEL >= 10) {
5512
 
                SEC_ACL *the_acl;
5513
 
                int i;
5514
 
 
5515
 
                the_acl = old_secdesc_ctr->sd->dacl;
5516
 
                DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5517
 
                           PRINTERNAME(snum), the_acl->num_aces));
5518
 
 
5519
 
                for (i = 0; i < the_acl->num_aces; i++) {
5520
 
                        DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5521
 
                                           &the_acl->aces[i].trustee),
5522
 
                                  the_acl->aces[i].access_mask));
5523
 
                }
5524
 
 
5525
 
                the_acl = secdesc_ctr->sd->dacl;
5526
 
 
5527
 
                if (the_acl) {
5528
 
                        DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5529
 
                                   PRINTERNAME(snum), the_acl->num_aces));
5530
 
 
5531
 
                        for (i = 0; i < the_acl->num_aces; i++) {
5532
 
                                DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5533
 
                                                   &the_acl->aces[i].trustee),
5534
 
                                           the_acl->aces[i].access_mask));
5535
 
                        }
5536
 
                } else {
5537
 
                        DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5538
 
                }
5539
 
        }
5540
 
 
5541
 
        new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
5542
 
        if (!new_secdesc_ctr) {
5543
 
                result = WERR_NOMEM;
5544
 
                goto done;
5545
 
        }
5546
 
 
5547
 
        if (security_descriptor_equal(new_secdesc_ctr->sd, old_secdesc_ctr->sd)) {
5548
 
                result = WERR_OK;
5549
 
                goto done;
5550
 
        }
5551
 
 
5552
 
        result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
5553
 
 
5554
 
 done:
5555
 
 
5556
 
        return result;
5557
 
}
5558
 
 
5559
 
/********************************************************************
5560
 
 Canonicalize printer info from a client
5561
 
 
5562
 
 ATTN: It does not matter what we set the servername to hear
5563
 
 since we do the necessary work in get_a_printer() to set it to
5564
 
 the correct value based on what the client sent in the
5565
 
 _spoolss_open_printer_ex().
5566
 
 ********************************************************************/
5567
 
 
5568
 
static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
5569
 
{
5570
 
        fstring printername;
5571
 
        const char *p;
5572
 
 
5573
 
        DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5574
 
                "portname=%s drivername=%s comment=%s location=%s\n",
5575
 
                info->servername, info->printername, info->sharename,
5576
 
                info->portname, info->drivername, info->comment, info->location));
5577
 
 
5578
 
        /* we force some elements to "correct" values */
5579
 
        slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
5580
 
        fstrcpy(info->sharename, lp_servicename(snum));
5581
 
 
5582
 
        /* check to see if we allow printername != sharename */
5583
 
 
5584
 
        if ( lp_force_printername(snum) ) {
5585
 
                slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
5586
 
                        global_myname(), info->sharename );
5587
 
        } else {
5588
 
 
5589
 
                /* make sure printername is in \\server\printername format */
5590
 
 
5591
 
                fstrcpy( printername, info->printername );
5592
 
                p = printername;
5593
 
                if ( printername[0] == '\\' && printername[1] == '\\' ) {
5594
 
                        if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
5595
 
                                p++;
5596
 
                }
5597
 
 
5598
 
                slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
5599
 
                         global_myname(), p );
5600
 
        }
5601
 
 
5602
 
        info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
5603
 
        info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
5604
 
 
5605
 
 
5606
 
 
5607
 
        return true;
5608
 
}
5609
 
 
5610
 
/****************************************************************************
5611
 
****************************************************************************/
5612
 
 
5613
 
static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
5614
 
{
5615
 
        char *cmd = lp_addport_cmd();
5616
 
        char *command = NULL;
5617
 
        int ret;
5618
 
        SE_PRIV se_printop = SE_PRINT_OPERATOR;
5619
 
        bool is_print_op = false;
5620
 
 
5621
 
        if ( !*cmd ) {
5622
 
                return WERR_ACCESS_DENIED;
5623
 
        }
5624
 
 
5625
 
        command = talloc_asprintf(ctx,
5626
 
                        "%s \"%s\" \"%s\"", cmd, portname, uri );
5627
 
        if (!command) {
5628
 
                return WERR_NOMEM;
5629
 
        }
5630
 
 
5631
 
        if ( token )
5632
 
                is_print_op = user_has_privileges( token, &se_printop );
5633
 
 
5634
 
        DEBUG(10,("Running [%s]\n", command));
5635
 
 
5636
 
        /********* BEGIN SePrintOperatorPrivilege **********/
5637
 
 
5638
 
        if ( is_print_op )
5639
 
                become_root();
5640
 
 
5641
 
        ret = smbrun(command, NULL);
5642
 
 
5643
 
        if ( is_print_op )
5644
 
                unbecome_root();
5645
 
 
5646
 
        /********* END SePrintOperatorPrivilege **********/
5647
 
 
5648
 
        DEBUGADD(10,("returned [%d]\n", ret));
5649
 
 
5650
 
        TALLOC_FREE(command);
5651
 
 
5652
 
        if ( ret != 0 ) {
5653
 
                return WERR_ACCESS_DENIED;
5654
 
        }
5655
 
 
5656
 
        return WERR_OK;
5657
 
}
5658
 
 
5659
 
/****************************************************************************
5660
 
****************************************************************************/
5661
 
 
5662
 
bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
5663
 
{
5664
 
        char *cmd = lp_addprinter_cmd();
5665
 
        char **qlines;
5666
 
        char *command = NULL;
5667
 
        int numlines;
5668
 
        int ret;
5669
 
        int fd;
5670
 
        SE_PRIV se_printop = SE_PRINT_OPERATOR;
5671
 
        bool is_print_op = false;
5672
 
        char *remote_machine = talloc_strdup(ctx, "%m");
5673
 
 
5674
 
        if (!remote_machine) {
5675
 
                return false;
5676
 
        }
5677
 
        remote_machine = talloc_sub_basic(ctx,
5678
 
                                current_user_info.smb_name,
5679
 
                                current_user_info.domain,
5680
 
                                remote_machine);
5681
 
        if (!remote_machine) {
5682
 
                return false;
5683
 
        }
5684
 
 
5685
 
        command = talloc_asprintf(ctx,
5686
 
                        "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5687
 
                        cmd, printer->info_2->printername, printer->info_2->sharename,
5688
 
                        printer->info_2->portname, printer->info_2->drivername,
5689
 
                        printer->info_2->location, printer->info_2->comment, remote_machine);
5690
 
        if (!command) {
5691
 
                return false;
5692
 
        }
5693
 
 
5694
 
        if ( token )
5695
 
                is_print_op = user_has_privileges( token, &se_printop );
5696
 
 
5697
 
        DEBUG(10,("Running [%s]\n", command));
5698
 
 
5699
 
        /********* BEGIN SePrintOperatorPrivilege **********/
5700
 
 
5701
 
        if ( is_print_op )
5702
 
                become_root();
5703
 
 
5704
 
        if ( (ret = smbrun(command, &fd)) == 0 ) {
5705
 
                /* Tell everyone we updated smb.conf. */
5706
 
                message_send_all(smbd_messaging_context(),
5707
 
                                 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
5708
 
        }
5709
 
 
5710
 
        if ( is_print_op )
5711
 
                unbecome_root();
5712
 
 
5713
 
        /********* END SePrintOperatorPrivilege **********/
5714
 
 
5715
 
        DEBUGADD(10,("returned [%d]\n", ret));
5716
 
 
5717
 
        TALLOC_FREE(command);
5718
 
        TALLOC_FREE(remote_machine);
5719
 
 
5720
 
        if ( ret != 0 ) {
5721
 
                if (fd != -1)
5722
 
                        close(fd);
5723
 
                return false;
5724
 
        }
5725
 
 
5726
 
        /* reload our services immediately */
5727
 
        become_root();
5728
 
        reload_services(false);
5729
 
        unbecome_root();
5730
 
 
5731
 
        numlines = 0;
5732
 
        /* Get lines and convert them back to dos-codepage */
5733
 
        qlines = fd_lines_load(fd, &numlines, 0, NULL);
5734
 
        DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5735
 
        close(fd);
5736
 
 
5737
 
        /* Set the portname to what the script says the portname should be. */
5738
 
        /* but don't require anything to be return from the script exit a good error code */
5739
 
 
5740
 
        if (numlines) {
5741
 
                /* Set the portname to what the script says the portname should be. */
5742
 
                strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
5743
 
                DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
5744
 
        }
5745
 
 
5746
 
        TALLOC_FREE(qlines);
5747
 
        return true;
5748
 
}
5749
 
 
5750
 
 
5751
 
/********************************************************************
5752
 
 * Called by spoolss_api_setprinter
5753
 
 * when updating a printer description.
5754
 
 ********************************************************************/
5755
 
 
5756
 
static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
5757
 
                             struct spoolss_SetPrinterInfoCtr *info_ctr,
5758
 
                             struct spoolss_DeviceMode *devmode)
5759
 
{
5760
 
        int snum;
5761
 
        NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
5762
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5763
 
        WERROR result;
5764
 
        DATA_BLOB buffer;
5765
 
        fstring asc_buffer;
5766
 
 
5767
 
        DEBUG(8,("update_printer\n"));
5768
 
 
5769
 
        result = WERR_OK;
5770
 
 
5771
 
        if (!Printer) {
5772
 
                result = WERR_BADFID;
5773
 
                goto done;
5774
 
        }
5775
 
 
5776
 
        if (!get_printer_snum(p, handle, &snum, NULL)) {
5777
 
                result = WERR_BADFID;
5778
 
                goto done;
5779
 
        }
5780
 
 
5781
 
        if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
5782
 
            (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
5783
 
                result = WERR_BADFID;
5784
 
                goto done;
5785
 
        }
5786
 
 
5787
 
        DEBUGADD(8,("Converting info_2 struct\n"));
5788
 
 
5789
 
        /*
5790
 
         * convert_printer_info converts the incoming
5791
 
         * info from the client and overwrites the info
5792
 
         * just read from the tdb in the pointer 'printer'.
5793
 
         */
5794
 
 
5795
 
        if (!convert_printer_info(info_ctr, printer)) {
5796
 
                result =  WERR_NOMEM;
5797
 
                goto done;
5798
 
        }
5799
 
 
5800
 
        if (devmode) {
5801
 
                /* we have a valid devmode
5802
 
                   convert it and link it*/
5803
 
 
5804
 
                DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
5805
 
                if (!convert_devicemode(printer->info_2->printername, devmode,
5806
 
                                        &printer->info_2->devmode)) {
5807
 
                        result =  WERR_NOMEM;
5808
 
                        goto done;
5809
 
                }
5810
 
        }
5811
 
 
5812
 
        /* Do sanity check on the requested changes for Samba */
5813
 
 
5814
 
        if (!check_printer_ok(printer->info_2, snum)) {
5815
 
                result = WERR_INVALID_PARAM;
5816
 
                goto done;
5817
 
        }
5818
 
 
5819
 
        /* FIXME!!! If the driver has changed we really should verify that
5820
 
           it is installed before doing much else   --jerry */
5821
 
 
5822
 
        /* Check calling user has permission to update printer description */
5823
 
 
5824
 
        if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
5825
 
                DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5826
 
                result = WERR_ACCESS_DENIED;
5827
 
                goto done;
5828
 
        }
5829
 
 
5830
 
        /* Call addprinter hook */
5831
 
        /* Check changes to see if this is really needed */
5832
 
 
5833
 
        if ( *lp_addprinter_cmd()
5834
 
                && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
5835
 
                        || !strequal(printer->info_2->comment, old_printer->info_2->comment)
5836
 
                        || !strequal(printer->info_2->portname, old_printer->info_2->portname)
5837
 
                        || !strequal(printer->info_2->location, old_printer->info_2->location)) )
5838
 
        {
5839
 
                /* add_printer_hook() will call reload_services() */
5840
 
 
5841
 
                if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
5842
 
                                       printer) ) {
5843
 
                        result = WERR_ACCESS_DENIED;
5844
 
                        goto done;
5845
 
                }
5846
 
        }
5847
 
 
5848
 
        /*
5849
 
         * When a *new* driver is bound to a printer, the drivername is used to
5850
 
         * lookup previously saved driver initialization info, which is then
5851
 
         * bound to the printer, simulating what happens in the Windows arch.
5852
 
         */
5853
 
        if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
5854
 
        {
5855
 
                if (!set_driver_init(printer, 2))
5856
 
                {
5857
 
                        DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
5858
 
                                printer->info_2->drivername));
5859
 
                }
5860
 
 
5861
 
                DEBUG(10,("update_printer: changing driver [%s]!  Sending event!\n",
5862
 
                        printer->info_2->drivername));
5863
 
 
5864
 
                notify_printer_driver(snum, printer->info_2->drivername);
5865
 
        }
5866
 
 
5867
 
        /*
5868
 
         * flag which changes actually occured.  This is a small subset of
5869
 
         * all the possible changes.  We also have to update things in the
5870
 
         * DsSpooler key.
5871
 
         */
5872
 
 
5873
 
        if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
5874
 
                push_reg_sz(talloc_tos(), &buffer, printer->info_2->comment);
5875
 
                set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
5876
 
                        REG_SZ, buffer.data, buffer.length);
5877
 
 
5878
 
                notify_printer_comment(snum, printer->info_2->comment);
5879
 
        }
5880
 
 
5881
 
        if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
5882
 
                push_reg_sz(talloc_tos(), &buffer, printer->info_2->sharename);
5883
 
                set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
5884
 
                        REG_SZ, buffer.data, buffer.length);
5885
 
 
5886
 
                notify_printer_sharename(snum, printer->info_2->sharename);
5887
 
        }
5888
 
 
5889
 
        if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
5890
 
                char *pname;
5891
 
 
5892
 
                if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
5893
 
                        pname++;
5894
 
                else
5895
 
                        pname = printer->info_2->printername;
5896
 
 
5897
 
 
5898
 
                push_reg_sz(talloc_tos(), &buffer, pname);
5899
 
                set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
5900
 
                        REG_SZ, buffer.data, buffer.length);
5901
 
 
5902
 
                notify_printer_printername( snum, pname );
5903
 
        }
5904
 
 
5905
 
        if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
5906
 
                push_reg_sz(talloc_tos(), &buffer, printer->info_2->portname);
5907
 
                set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
5908
 
                        REG_SZ, buffer.data, buffer.length);
5909
 
 
5910
 
                notify_printer_port(snum, printer->info_2->portname);
5911
 
        }
5912
 
 
5913
 
        if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
5914
 
                push_reg_sz(talloc_tos(), &buffer, printer->info_2->location);
5915
 
                set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
5916
 
                        REG_SZ, buffer.data, buffer.length);
5917
 
 
5918
 
                notify_printer_location(snum, printer->info_2->location);
5919
 
        }
5920
 
 
5921
 
        /* here we need to update some more DsSpooler keys */
5922
 
        /* uNCName, serverName, shortServerName */
5923
 
 
5924
 
        push_reg_sz(talloc_tos(), &buffer, global_myname());
5925
 
        set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
5926
 
                REG_SZ, buffer.data, buffer.length);
5927
 
        set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
5928
 
                REG_SZ, buffer.data, buffer.length);
5929
 
 
5930
 
        slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
5931
 
                 global_myname(), printer->info_2->sharename );
5932
 
        push_reg_sz(talloc_tos(), &buffer, asc_buffer);
5933
 
        set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
5934
 
                REG_SZ, buffer.data, buffer.length);
5935
 
 
5936
 
        /* Update printer info */
5937
 
        result = mod_a_printer(printer, 2);
5938
 
 
5939
 
done:
5940
 
        free_a_printer(&printer, 2);
5941
 
        free_a_printer(&old_printer, 2);
5942
 
 
5943
 
 
5944
 
        return result;
5945
 
}
5946
 
 
5947
 
/****************************************************************************
5948
 
****************************************************************************/
5949
 
static WERROR publish_or_unpublish_printer(pipes_struct *p,
5950
 
                                           struct policy_handle *handle,
5951
 
                                           struct spoolss_SetPrinterInfo7 *info7)
5952
 
{
5953
 
#ifdef HAVE_ADS
5954
 
        int snum;
5955
 
        Printer_entry *Printer;
5956
 
 
5957
 
        if ( lp_security() != SEC_ADS ) {
5958
 
                return WERR_UNKNOWN_LEVEL;
5959
 
        }
5960
 
 
5961
 
        Printer = find_printer_index_by_hnd(p, handle);
5962
 
 
5963
 
        DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
5964
 
 
5965
 
        if (!Printer)
5966
 
                return WERR_BADFID;
5967
 
 
5968
 
        if (!get_printer_snum(p, handle, &snum, NULL))
5969
 
                return WERR_BADFID;
5970
 
 
5971
 
        nt_printer_publish(Printer, snum, info7->action);
5972
 
 
5973
 
        return WERR_OK;
5974
 
#else
5975
 
        return WERR_UNKNOWN_LEVEL;
5976
 
#endif
5977
 
}
5978
 
 
5979
 
/****************************************************************
5980
 
 _spoolss_SetPrinter
5981
 
****************************************************************/
5982
 
 
5983
 
WERROR _spoolss_SetPrinter(pipes_struct *p,
5984
 
                           struct spoolss_SetPrinter *r)
5985
 
{
5986
 
        WERROR result;
5987
 
 
5988
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5989
 
 
5990
 
        if (!Printer) {
5991
 
                DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
5992
 
                        OUR_HANDLE(r->in.handle)));
5993
 
                return WERR_BADFID;
5994
 
        }
5995
 
 
5996
 
        /* check the level */
5997
 
        switch (r->in.info_ctr->level) {
5998
 
                case 0:
5999
 
                        return control_printer(r->in.handle, r->in.command, p);
6000
 
                case 2:
6001
 
                        result = update_printer(p, r->in.handle,
6002
 
                                                r->in.info_ctr,
6003
 
                                                r->in.devmode_ctr->devmode);
6004
 
                        if (!W_ERROR_IS_OK(result))
6005
 
                                return result;
6006
 
                        if (r->in.secdesc_ctr->sd)
6007
 
                                result = update_printer_sec(r->in.handle, p,
6008
 
                                                            r->in.secdesc_ctr);
6009
 
                        return result;
6010
 
                case 3:
6011
 
                        return update_printer_sec(r->in.handle, p,
6012
 
                                                  r->in.secdesc_ctr);
6013
 
                case 7:
6014
 
                        return publish_or_unpublish_printer(p, r->in.handle,
6015
 
                                                            r->in.info_ctr->info.info7);
6016
 
                default:
6017
 
                        return WERR_UNKNOWN_LEVEL;
6018
 
        }
6019
 
}
6020
 
 
6021
 
/****************************************************************
6022
 
 _spoolss_FindClosePrinterNotify
6023
 
****************************************************************/
6024
 
 
6025
 
WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
6026
 
                                       struct spoolss_FindClosePrinterNotify *r)
6027
 
{
6028
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6029
 
 
6030
 
        if (!Printer) {
6031
 
                DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6032
 
                        "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6033
 
                return WERR_BADFID;
6034
 
        }
6035
 
 
6036
 
        if (Printer->notify.client_connected == true) {
6037
 
                int snum = -1;
6038
 
 
6039
 
                if ( Printer->printer_type == SPLHND_SERVER)
6040
 
                        snum = -1;
6041
 
                else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6042
 
                                !get_printer_snum(p, r->in.handle, &snum, NULL) )
6043
 
                        return WERR_BADFID;
6044
 
 
6045
 
                srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6046
 
        }
6047
 
 
6048
 
        Printer->notify.flags=0;
6049
 
        Printer->notify.options=0;
6050
 
        Printer->notify.localmachine[0]='\0';
6051
 
        Printer->notify.printerlocal=0;
6052
 
        TALLOC_FREE(Printer->notify.option);
6053
 
        Printer->notify.client_connected = false;
6054
 
 
6055
 
        return WERR_OK;
6056
 
}
6057
 
 
6058
 
/****************************************************************
6059
 
 _spoolss_AddJob
6060
 
****************************************************************/
6061
 
 
6062
 
WERROR _spoolss_AddJob(pipes_struct *p,
6063
 
                       struct spoolss_AddJob *r)
6064
 
{
6065
 
        if (!r->in.buffer && (r->in.offered != 0)) {
6066
 
                return WERR_INVALID_PARAM;
6067
 
        }
6068
 
 
6069
 
        /* this is what a NT server returns for AddJob. AddJob must fail on
6070
 
         * non-local printers */
6071
 
 
6072
 
        if (r->in.level != 1) {
6073
 
                return WERR_UNKNOWN_LEVEL;
6074
 
        }
6075
 
 
6076
 
        return WERR_INVALID_PARAM;
6077
 
}
6078
 
 
6079
 
/****************************************************************************
6080
 
fill_job_info1
6081
 
****************************************************************************/
6082
 
 
6083
 
static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6084
 
                             struct spoolss_JobInfo1 *r,
6085
 
                             const print_queue_struct *queue,
6086
 
                             int position, int snum,
6087
 
                             const NT_PRINTER_INFO_LEVEL *ntprinter)
6088
 
{
6089
 
        struct tm *t;
6090
 
 
6091
 
        t = gmtime(&queue->time);
6092
 
 
6093
 
        r->job_id               = queue->job;
6094
 
 
6095
 
        r->printer_name         = talloc_strdup(mem_ctx, lp_servicename(snum));
6096
 
        W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6097
 
        r->server_name          = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
6098
 
        W_ERROR_HAVE_NO_MEMORY(r->server_name);
6099
 
        r->user_name            = talloc_strdup(mem_ctx, queue->fs_user);
6100
 
        W_ERROR_HAVE_NO_MEMORY(r->user_name);
6101
 
        r->document_name        = talloc_strdup(mem_ctx, queue->fs_file);
6102
 
        W_ERROR_HAVE_NO_MEMORY(r->document_name);
6103
 
        r->data_type            = talloc_strdup(mem_ctx, "RAW");
6104
 
        W_ERROR_HAVE_NO_MEMORY(r->data_type);
6105
 
        r->text_status          = talloc_strdup(mem_ctx, "");
6106
 
        W_ERROR_HAVE_NO_MEMORY(r->text_status);
6107
 
 
6108
 
        r->status               = nt_printj_status(queue->status);
6109
 
        r->priority             = queue->priority;
6110
 
        r->position             = position;
6111
 
        r->total_pages          = queue->page_count;
6112
 
        r->pages_printed        = 0; /* ??? */
6113
 
 
6114
 
        init_systemtime(&r->submitted, t);
6115
 
 
6116
 
        return WERR_OK;
6117
 
}
6118
 
 
6119
 
/****************************************************************************
6120
 
fill_job_info2
6121
 
****************************************************************************/
6122
 
 
6123
 
static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6124
 
                             struct spoolss_JobInfo2 *r,
6125
 
                             const print_queue_struct *queue,
6126
 
                             int position, int snum,
6127
 
                             const NT_PRINTER_INFO_LEVEL *ntprinter,
6128
 
                             struct spoolss_DeviceMode *devmode)
6129
 
{
6130
 
        struct tm *t;
6131
 
 
6132
 
        t = gmtime(&queue->time);
6133
 
 
6134
 
        r->job_id               = queue->job;
6135
 
 
6136
 
        r->printer_name         = talloc_strdup(mem_ctx, lp_servicename(snum));
6137
 
        W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6138
 
        r->server_name          = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
6139
 
        W_ERROR_HAVE_NO_MEMORY(r->server_name);
6140
 
        r->user_name            = talloc_strdup(mem_ctx, queue->fs_user);
6141
 
        W_ERROR_HAVE_NO_MEMORY(r->user_name);
6142
 
        r->document_name        = talloc_strdup(mem_ctx, queue->fs_file);
6143
 
        W_ERROR_HAVE_NO_MEMORY(r->document_name);
6144
 
        r->notify_name          = talloc_strdup(mem_ctx, queue->fs_user);
6145
 
        W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6146
 
        r->data_type            = talloc_strdup(mem_ctx, "RAW");
6147
 
        W_ERROR_HAVE_NO_MEMORY(r->data_type);
6148
 
        r->print_processor      = talloc_strdup(mem_ctx, "winprint");
6149
 
        W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6150
 
        r->parameters           = talloc_strdup(mem_ctx, "");
6151
 
        W_ERROR_HAVE_NO_MEMORY(r->parameters);
6152
 
        r->driver_name          = talloc_strdup(mem_ctx, ntprinter->info_2->drivername);
6153
 
        W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6154
 
 
6155
 
        r->devmode              = devmode;
6156
 
 
6157
 
        r->text_status          = talloc_strdup(mem_ctx, "");
6158
 
        W_ERROR_HAVE_NO_MEMORY(r->text_status);
6159
 
 
6160
 
        r->secdesc              = NULL;
6161
 
 
6162
 
        r->status               = nt_printj_status(queue->status);
6163
 
        r->priority             = queue->priority;
6164
 
        r->position             = position;
6165
 
        r->start_time           = 0;
6166
 
        r->until_time           = 0;
6167
 
        r->total_pages          = queue->page_count;
6168
 
        r->size                 = queue->size;
6169
 
        init_systemtime(&r->submitted, t);
6170
 
        r->time                 = 0;
6171
 
        r->pages_printed        = 0; /* ??? */
6172
 
 
6173
 
        return WERR_OK;
6174
 
}
6175
 
 
6176
 
/****************************************************************************
6177
 
fill_job_info3
6178
 
****************************************************************************/
6179
 
 
6180
 
static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6181
 
                             struct spoolss_JobInfo3 *r,
6182
 
                             const print_queue_struct *queue,
6183
 
                             const print_queue_struct *next_queue,
6184
 
                             int position, int snum,
6185
 
                             const NT_PRINTER_INFO_LEVEL *ntprinter)
6186
 
{
6187
 
        r->job_id               = queue->job;
6188
 
        r->next_job_id          = 0;
6189
 
        if (next_queue) {
6190
 
                r->next_job_id  = next_queue->job;
6191
 
        }
6192
 
        r->reserved             = 0;
6193
 
 
6194
 
        return WERR_OK;
6195
 
}
6196
 
 
6197
 
/****************************************************************************
6198
 
 Enumjobs at level 1.
6199
 
****************************************************************************/
6200
 
 
6201
 
static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6202
 
                              const print_queue_struct *queue,
6203
 
                              uint32_t num_queues, int snum,
6204
 
                              const NT_PRINTER_INFO_LEVEL *ntprinter,
6205
 
                              union spoolss_JobInfo **info_p,
6206
 
                              uint32_t *count)
6207
 
{
6208
 
        union spoolss_JobInfo *info;
6209
 
        int i;
6210
 
        WERROR result = WERR_OK;
6211
 
 
6212
 
        info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6213
 
        W_ERROR_HAVE_NO_MEMORY(info);
6214
 
 
6215
 
        *count = num_queues;
6216
 
 
6217
 
        for (i=0; i<*count; i++) {
6218
 
                result = fill_job_info1(info,
6219
 
                                        &info[i].info1,
6220
 
                                        &queue[i],
6221
 
                                        i,
6222
 
                                        snum,
6223
 
                                        ntprinter);
6224
 
                if (!W_ERROR_IS_OK(result)) {
6225
 
                        goto out;
6226
 
                }
6227
 
        }
6228
 
 
6229
 
 out:
6230
 
        if (!W_ERROR_IS_OK(result)) {
6231
 
                TALLOC_FREE(info);
6232
 
                *count = 0;
6233
 
                return result;
6234
 
        }
6235
 
 
6236
 
        *info_p = info;
6237
 
 
6238
 
        return WERR_OK;
6239
 
}
6240
 
 
6241
 
/****************************************************************************
6242
 
 Enumjobs at level 2.
6243
 
****************************************************************************/
6244
 
 
6245
 
static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6246
 
                              const print_queue_struct *queue,
6247
 
                              uint32_t num_queues, int snum,
6248
 
                              const NT_PRINTER_INFO_LEVEL *ntprinter,
6249
 
                              union spoolss_JobInfo **info_p,
6250
 
                              uint32_t *count)
6251
 
{
6252
 
        union spoolss_JobInfo *info;
6253
 
        int i;
6254
 
        WERROR result = WERR_OK;
6255
 
 
6256
 
        info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6257
 
        W_ERROR_HAVE_NO_MEMORY(info);
6258
 
 
6259
 
        *count = num_queues;
6260
 
 
6261
 
        for (i=0; i<*count; i++) {
6262
 
 
6263
 
                struct spoolss_DeviceMode *devmode;
6264
 
 
6265
 
                devmode = construct_dev_mode(info, lp_const_servicename(snum));
6266
 
                if (!devmode) {
6267
 
                        result = WERR_NOMEM;
6268
 
                        goto out;
6269
 
                }
6270
 
 
6271
 
                result = fill_job_info2(info,
6272
 
                                        &info[i].info2,
6273
 
                                        &queue[i],
6274
 
                                        i,
6275
 
                                        snum,
6276
 
                                        ntprinter,
6277
 
                                        devmode);
6278
 
                if (!W_ERROR_IS_OK(result)) {
6279
 
                        goto out;
6280
 
                }
6281
 
        }
6282
 
 
6283
 
 out:
6284
 
        if (!W_ERROR_IS_OK(result)) {
6285
 
                TALLOC_FREE(info);
6286
 
                *count = 0;
6287
 
                return result;
6288
 
        }
6289
 
 
6290
 
        *info_p = info;
6291
 
 
6292
 
        return WERR_OK;
6293
 
}
6294
 
 
6295
 
/****************************************************************************
6296
 
 Enumjobs at level 3.
6297
 
****************************************************************************/
6298
 
 
6299
 
static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6300
 
                              const print_queue_struct *queue,
6301
 
                              uint32_t num_queues, int snum,
6302
 
                              const NT_PRINTER_INFO_LEVEL *ntprinter,
6303
 
                              union spoolss_JobInfo **info_p,
6304
 
                              uint32_t *count)
6305
 
{
6306
 
        union spoolss_JobInfo *info;
6307
 
        int i;
6308
 
        WERROR result = WERR_OK;
6309
 
 
6310
 
        info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6311
 
        W_ERROR_HAVE_NO_MEMORY(info);
6312
 
 
6313
 
        *count = num_queues;
6314
 
 
6315
 
        for (i=0; i<*count; i++) {
6316
 
                const print_queue_struct *next_queue = NULL;
6317
 
 
6318
 
                if (i+1 < *count) {
6319
 
                        next_queue = &queue[i+1];
6320
 
                }
6321
 
 
6322
 
                result = fill_job_info3(info,
6323
 
                                        &info[i].info3,
6324
 
                                        &queue[i],
6325
 
                                        next_queue,
6326
 
                                        i,
6327
 
                                        snum,
6328
 
                                        ntprinter);
6329
 
                if (!W_ERROR_IS_OK(result)) {
6330
 
                        goto out;
6331
 
                }
6332
 
        }
6333
 
 
6334
 
 out:
6335
 
        if (!W_ERROR_IS_OK(result)) {
6336
 
                TALLOC_FREE(info);
6337
 
                *count = 0;
6338
 
                return result;
6339
 
        }
6340
 
 
6341
 
        *info_p = info;
6342
 
 
6343
 
        return WERR_OK;
6344
 
}
6345
 
 
6346
 
/****************************************************************
6347
 
 _spoolss_EnumJobs
6348
 
****************************************************************/
6349
 
 
6350
 
WERROR _spoolss_EnumJobs(pipes_struct *p,
6351
 
                         struct spoolss_EnumJobs *r)
6352
 
{
6353
 
        WERROR result;
6354
 
        NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
6355
 
        int snum;
6356
 
        print_status_struct prt_status;
6357
 
        print_queue_struct *queue = NULL;
6358
 
        uint32_t count;
6359
 
 
6360
 
        /* that's an [in out] buffer */
6361
 
 
6362
 
        if (!r->in.buffer && (r->in.offered != 0)) {
6363
 
                return WERR_INVALID_PARAM;
6364
 
        }
6365
 
 
6366
 
        DEBUG(4,("_spoolss_EnumJobs\n"));
6367
 
 
6368
 
        *r->out.needed = 0;
6369
 
        *r->out.count = 0;
6370
 
        *r->out.info = NULL;
6371
 
 
6372
 
        /* lookup the printer snum and tdb entry */
6373
 
 
6374
 
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6375
 
                return WERR_BADFID;
6376
 
        }
6377
 
 
6378
 
        result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
6379
 
        if (!W_ERROR_IS_OK(result)) {
6380
 
                return result;
6381
 
        }
6382
 
 
6383
 
        count = print_queue_status(snum, &queue, &prt_status);
6384
 
        DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6385
 
                count, prt_status.status, prt_status.message));
6386
 
 
6387
 
        if (count == 0) {
6388
 
                SAFE_FREE(queue);
6389
 
                free_a_printer(&ntprinter, 2);
6390
 
                return WERR_OK;
6391
 
        }
6392
 
 
6393
 
        switch (r->in.level) {
6394
 
        case 1:
6395
 
                result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6396
 
                                         ntprinter, r->out.info, r->out.count);
6397
 
                break;
6398
 
        case 2:
6399
 
                result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6400
 
                                         ntprinter, r->out.info, r->out.count);
6401
 
                break;
6402
 
        case 3:
6403
 
                result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6404
 
                                         ntprinter, r->out.info, r->out.count);
6405
 
                break;
6406
 
        default:
6407
 
                result = WERR_UNKNOWN_LEVEL;
6408
 
                break;
6409
 
        }
6410
 
 
6411
 
        SAFE_FREE(queue);
6412
 
        free_a_printer(&ntprinter, 2);
6413
 
 
6414
 
        if (!W_ERROR_IS_OK(result)) {
6415
 
                return result;
6416
 
        }
6417
 
 
6418
 
        *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6419
 
                                                     spoolss_EnumJobs, NULL,
6420
 
                                                     *r->out.info, r->in.level,
6421
 
                                                     *r->out.count);
6422
 
        *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6423
 
        *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6424
 
 
6425
 
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6426
 
}
6427
 
 
6428
 
/****************************************************************
6429
 
 _spoolss_ScheduleJob
6430
 
****************************************************************/
6431
 
 
6432
 
WERROR _spoolss_ScheduleJob(pipes_struct *p,
6433
 
                            struct spoolss_ScheduleJob *r)
6434
 
{
6435
 
        return WERR_OK;
6436
 
}
6437
 
 
6438
 
/****************************************************************
6439
 
 _spoolss_SetJob
6440
 
****************************************************************/
6441
 
 
6442
 
WERROR _spoolss_SetJob(pipes_struct *p,
6443
 
                       struct spoolss_SetJob *r)
6444
 
{
6445
 
        int snum;
6446
 
        WERROR errcode = WERR_BADFUNC;
6447
 
 
6448
 
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6449
 
                return WERR_BADFID;
6450
 
        }
6451
 
 
6452
 
        if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6453
 
                return WERR_INVALID_PRINTER_NAME;
6454
 
        }
6455
 
 
6456
 
        switch (r->in.command) {
6457
 
        case SPOOLSS_JOB_CONTROL_CANCEL:
6458
 
        case SPOOLSS_JOB_CONTROL_DELETE:
6459
 
                if (print_job_delete(p->server_info, snum, r->in.job_id, &errcode)) {
6460
 
                        errcode = WERR_OK;
6461
 
                }
6462
 
                break;
6463
 
        case SPOOLSS_JOB_CONTROL_PAUSE:
6464
 
                if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) {
6465
 
                        errcode = WERR_OK;
6466
 
                }
6467
 
                break;
6468
 
        case SPOOLSS_JOB_CONTROL_RESTART:
6469
 
        case SPOOLSS_JOB_CONTROL_RESUME:
6470
 
                if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) {
6471
 
                        errcode = WERR_OK;
6472
 
                }
6473
 
                break;
6474
 
        default:
6475
 
                return WERR_UNKNOWN_LEVEL;
6476
 
        }
6477
 
 
6478
 
        return errcode;
6479
 
}
6480
 
 
6481
 
/****************************************************************************
6482
 
 Enumerates all printer drivers by level and architecture.
6483
 
****************************************************************************/
6484
 
 
6485
 
static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6486
 
                                                       const char *servername,
6487
 
                                                       const char *architecture,
6488
 
                                                       uint32_t level,
6489
 
                                                       union spoolss_DriverInfo **info_p,
6490
 
                                                       uint32_t *count_p)
6491
 
{
6492
 
        int i;
6493
 
        int ndrivers;
6494
 
        uint32_t version;
6495
 
        fstring *list = NULL;
6496
 
        struct spoolss_DriverInfo8 *driver;
6497
 
        union spoolss_DriverInfo *info = NULL;
6498
 
        uint32_t count = 0;
6499
 
        WERROR result = WERR_OK;
6500
 
 
6501
 
        *count_p = 0;
6502
 
        *info_p = NULL;
6503
 
 
6504
 
        for (version=0; version<DRIVER_MAX_VERSION; version++) {
6505
 
                list = NULL;
6506
 
                ndrivers = get_ntdrivers(&list, architecture, version);
6507
 
                DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
6508
 
                        ndrivers, architecture, version));
6509
 
 
6510
 
                if (ndrivers == -1) {
6511
 
                        result = WERR_NOMEM;
6512
 
                        goto out;
6513
 
                }
6514
 
 
6515
 
                if (ndrivers != 0) {
6516
 
                        info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6517
 
                                                    union spoolss_DriverInfo,
6518
 
                                                    count + ndrivers);
6519
 
                        if (!info) {
6520
 
                                DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6521
 
                                        "failed to enlarge driver info buffer!\n"));
6522
 
                                result = WERR_NOMEM;
6523
 
                                goto out;
6524
 
                        }
6525
 
                }
6526
 
 
6527
 
                for (i=0; i<ndrivers; i++) {
6528
 
                        DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
6529
 
                        ZERO_STRUCT(driver);
6530
 
                        result = get_a_printer_driver(mem_ctx, &driver, list[i],
6531
 
                                                      architecture, version);
6532
 
                        if (!W_ERROR_IS_OK(result)) {
6533
 
                                goto out;
6534
 
                        }
6535
 
 
6536
 
                        switch (level) {
6537
 
                        case 1:
6538
 
                                result = fill_printer_driver_info1(info, &info[count+i].info1,
6539
 
                                                                   driver, servername);
6540
 
                                break;
6541
 
                        case 2:
6542
 
                                result = fill_printer_driver_info2(info, &info[count+i].info2,
6543
 
                                                                   driver, servername);
6544
 
                                break;
6545
 
                        case 3:
6546
 
                                result = fill_printer_driver_info3(info, &info[count+i].info3,
6547
 
                                                                   driver, servername);
6548
 
                                break;
6549
 
                        case 4:
6550
 
                                result = fill_printer_driver_info4(info, &info[count+i].info4,
6551
 
                                                                   driver, servername);
6552
 
                                break;
6553
 
                        case 5:
6554
 
                                result = fill_printer_driver_info5(info, &info[count+i].info5,
6555
 
                                                                   driver, servername);
6556
 
                                break;
6557
 
                        case 6:
6558
 
                                result = fill_printer_driver_info6(info, &info[count+i].info6,
6559
 
                                                                   driver, servername);
6560
 
                                break;
6561
 
                        case 8:
6562
 
                                result = fill_printer_driver_info8(info, &info[count+i].info8,
6563
 
                                                                   driver, servername);
6564
 
                                break;
6565
 
                        default:
6566
 
                                result = WERR_UNKNOWN_LEVEL;
6567
 
                                break;
6568
 
                        }
6569
 
 
6570
 
                        free_a_printer_driver(driver);
6571
 
 
6572
 
                        if (!W_ERROR_IS_OK(result)) {
6573
 
                                goto out;
6574
 
                        }
6575
 
                }
6576
 
 
6577
 
                count += ndrivers;
6578
 
                SAFE_FREE(list);
6579
 
        }
6580
 
 
6581
 
 out:
6582
 
        SAFE_FREE(list);
6583
 
 
6584
 
        if (!W_ERROR_IS_OK(result)) {
6585
 
                TALLOC_FREE(info);
6586
 
                return result;
6587
 
        }
6588
 
 
6589
 
        *info_p = info;
6590
 
        *count_p = count;
6591
 
 
6592
 
        return WERR_OK;
6593
 
}
6594
 
 
6595
 
/****************************************************************************
6596
 
 Enumerates all printer drivers by level.
6597
 
****************************************************************************/
6598
 
 
6599
 
static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
6600
 
                                       const char *servername,
6601
 
                                       const char *architecture,
6602
 
                                       uint32_t level,
6603
 
                                       union spoolss_DriverInfo **info_p,
6604
 
                                       uint32_t *count_p)
6605
 
{
6606
 
        uint32_t a,i;
6607
 
        WERROR result = WERR_OK;
6608
 
 
6609
 
        if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
6610
 
 
6611
 
                for (a=0; archi_table[a].long_archi != NULL; a++) {
6612
 
 
6613
 
                        union spoolss_DriverInfo *info = NULL;
6614
 
                        uint32_t count = 0;
6615
 
 
6616
 
                        result = enumprinterdrivers_level_by_architecture(mem_ctx,
6617
 
                                                                          servername,
6618
 
                                                                          archi_table[a].long_archi,
6619
 
                                                                          level,
6620
 
                                                                          &info,
6621
 
                                                                          &count);
6622
 
                        if (!W_ERROR_IS_OK(result)) {
6623
 
                                continue;
6624
 
                        }
6625
 
 
6626
 
                        for (i=0; i < count; i++) {
6627
 
                                ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
6628
 
                                             info[i], info_p, count_p);
6629
 
                        }
6630
 
                }
6631
 
 
6632
 
                return result;
6633
 
        }
6634
 
 
6635
 
        return enumprinterdrivers_level_by_architecture(mem_ctx,
6636
 
                                                        servername,
6637
 
                                                        architecture,
6638
 
                                                        level,
6639
 
                                                        info_p,
6640
 
                                                        count_p);
6641
 
}
6642
 
 
6643
 
/****************************************************************
6644
 
 _spoolss_EnumPrinterDrivers
6645
 
****************************************************************/
6646
 
 
6647
 
WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
6648
 
                                   struct spoolss_EnumPrinterDrivers *r)
6649
 
{
6650
 
        const char *cservername;
6651
 
        WERROR result;
6652
 
 
6653
 
        /* that's an [in out] buffer */
6654
 
 
6655
 
        if (!r->in.buffer && (r->in.offered != 0)) {
6656
 
                return WERR_INVALID_PARAM;
6657
 
        }
6658
 
 
6659
 
        DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6660
 
 
6661
 
        *r->out.needed = 0;
6662
 
        *r->out.count = 0;
6663
 
        *r->out.info = NULL;
6664
 
 
6665
 
        cservername = canon_servername(r->in.server);
6666
 
 
6667
 
        if (!is_myname_or_ipaddr(cservername)) {
6668
 
                return WERR_UNKNOWN_PRINTER_DRIVER;
6669
 
        }
6670
 
 
6671
 
        result = enumprinterdrivers_level(p->mem_ctx, cservername,
6672
 
                                          r->in.environment,
6673
 
                                          r->in.level,
6674
 
                                          r->out.info,
6675
 
                                          r->out.count);
6676
 
        if (!W_ERROR_IS_OK(result)) {
6677
 
                return result;
6678
 
        }
6679
 
 
6680
 
        *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6681
 
                                                     spoolss_EnumPrinterDrivers, NULL,
6682
 
                                                     *r->out.info, r->in.level,
6683
 
                                                     *r->out.count);
6684
 
        *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6685
 
        *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6686
 
 
6687
 
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6688
 
}
6689
 
 
6690
 
/****************************************************************************
6691
 
****************************************************************************/
6692
 
 
6693
 
static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
6694
 
                               struct spoolss_FormInfo1 *r,
6695
 
                               const nt_forms_struct *form)
6696
 
{
6697
 
        r->form_name    = talloc_strdup(mem_ctx, form->name);
6698
 
        W_ERROR_HAVE_NO_MEMORY(r->form_name);
6699
 
 
6700
 
        r->flags        = form->flag;
6701
 
        r->size.width   = form->width;
6702
 
        r->size.height  = form->length;
6703
 
        r->area.left    = form->left;
6704
 
        r->area.top     = form->top;
6705
 
        r->area.right   = form->right;
6706
 
        r->area.bottom  = form->bottom;
6707
 
 
6708
 
        return WERR_OK;
6709
 
}
6710
 
 
6711
 
/****************************************************************
6712
 
 spoolss_enumforms_level1
6713
 
****************************************************************/
6714
 
 
6715
 
static WERROR spoolss_enumforms_level1(TALLOC_CTX *mem_ctx,
6716
 
                                       const nt_forms_struct *builtin_forms,
6717
 
                                       uint32_t num_builtin_forms,
6718
 
                                       const nt_forms_struct *user_forms,
6719
 
                                       uint32_t num_user_forms,
6720
 
                                       union spoolss_FormInfo **info_p,
6721
 
                                       uint32_t *count)
6722
 
{
6723
 
        union spoolss_FormInfo *info;
6724
 
        WERROR result = WERR_OK;
6725
 
        int i;
6726
 
 
6727
 
        *count = num_builtin_forms + num_user_forms;
6728
 
 
6729
 
        info = TALLOC_ARRAY(mem_ctx, union spoolss_FormInfo, *count);
6730
 
        W_ERROR_HAVE_NO_MEMORY(info);
6731
 
 
6732
 
        /* construct the list of form structures */
6733
 
        for (i=0; i<num_builtin_forms; i++) {
6734
 
                DEBUGADD(6,("Filling builtin form number [%d]\n",i));
6735
 
                result = fill_form_info_1(info, &info[i].info1,
6736
 
                                          &builtin_forms[i]);
6737
 
                if (!W_ERROR_IS_OK(result)) {
6738
 
                        goto out;
6739
 
                }
6740
 
        }
6741
 
 
6742
 
        for (i=0; i<num_user_forms; i++) {
6743
 
                DEBUGADD(6,("Filling user form number [%d]\n",i));
6744
 
                result = fill_form_info_1(info, &info[i+num_builtin_forms].info1,
6745
 
                                          &user_forms[i]);
6746
 
                if (!W_ERROR_IS_OK(result)) {
6747
 
                        goto out;
6748
 
                }
6749
 
        }
6750
 
 
6751
 
 out:
6752
 
        if (!W_ERROR_IS_OK(result)) {
6753
 
                TALLOC_FREE(info);
6754
 
                *count = 0;
6755
 
                return result;
6756
 
        }
6757
 
 
6758
 
        *info_p = info;
6759
 
 
6760
 
        return WERR_OK;
6761
 
}
6762
 
 
6763
 
/****************************************************************
6764
 
 _spoolss_EnumForms
6765
 
****************************************************************/
6766
 
 
6767
 
WERROR _spoolss_EnumForms(pipes_struct *p,
6768
 
                          struct spoolss_EnumForms *r)
6769
 
{
6770
 
        WERROR result;
6771
 
        nt_forms_struct *user_forms = NULL;
6772
 
        nt_forms_struct *builtin_forms = NULL;
6773
 
        uint32_t num_user_forms;
6774
 
        uint32_t num_builtin_forms;
6775
 
 
6776
 
        *r->out.count = 0;
6777
 
        *r->out.needed = 0;
6778
 
        *r->out.info = NULL;
6779
 
 
6780
 
        /* that's an [in out] buffer */
6781
 
 
6782
 
        if (!r->in.buffer && (r->in.offered != 0) ) {
6783
 
                return WERR_INVALID_PARAM;
6784
 
        }
6785
 
 
6786
 
        DEBUG(4,("_spoolss_EnumForms\n"));
6787
 
        DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6788
 
        DEBUGADD(5,("Info level [%d]\n",          r->in.level));
6789
 
 
6790
 
        num_builtin_forms = get_builtin_ntforms(&builtin_forms);
6791
 
        DEBUGADD(5,("Number of builtin forms [%d]\n", num_builtin_forms));
6792
 
        num_user_forms = get_ntforms(&user_forms);
6793
 
        DEBUGADD(5,("Number of user forms [%d]\n", num_user_forms));
6794
 
 
6795
 
        if (num_user_forms + num_builtin_forms == 0) {
6796
 
                SAFE_FREE(builtin_forms);
6797
 
                SAFE_FREE(user_forms);
6798
 
                return WERR_NO_MORE_ITEMS;
6799
 
        }
6800
 
 
6801
 
        switch (r->in.level) {
6802
 
        case 1:
6803
 
                result = spoolss_enumforms_level1(p->mem_ctx,
6804
 
                                                  builtin_forms,
6805
 
                                                  num_builtin_forms,
6806
 
                                                  user_forms,
6807
 
                                                  num_user_forms,
6808
 
                                                  r->out.info,
6809
 
                                                  r->out.count);
6810
 
                break;
6811
 
        default:
6812
 
                result = WERR_UNKNOWN_LEVEL;
6813
 
                break;
6814
 
        }
6815
 
 
6816
 
        SAFE_FREE(user_forms);
6817
 
        SAFE_FREE(builtin_forms);
6818
 
 
6819
 
        if (!W_ERROR_IS_OK(result)) {
6820
 
                return result;
6821
 
        }
6822
 
 
6823
 
        *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6824
 
                                                     spoolss_EnumForms, NULL,
6825
 
                                                     *r->out.info, r->in.level,
6826
 
                                                     *r->out.count);
6827
 
        *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6828
 
        *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6829
 
 
6830
 
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6831
 
}
6832
 
 
6833
 
/****************************************************************
6834
 
****************************************************************/
6835
 
 
6836
 
static WERROR find_form_byname(const char *name,
6837
 
                               nt_forms_struct *form)
6838
 
{
6839
 
        nt_forms_struct *list = NULL;
6840
 
        int num_forms = 0, i = 0;
6841
 
 
6842
 
        if (get_a_builtin_ntform_by_string(name, form)) {
6843
 
                return WERR_OK;
6844
 
        }
6845
 
 
6846
 
        num_forms = get_ntforms(&list);
6847
 
        DEBUGADD(5,("Number of forms [%d]\n", num_forms));
6848
 
 
6849
 
        if (num_forms == 0) {
6850
 
                return WERR_BADFID;
6851
 
        }
6852
 
 
6853
 
        /* Check if the requested name is in the list of form structures */
6854
 
        for (i = 0; i < num_forms; i++) {
6855
 
 
6856
 
                DEBUG(4,("checking form %s (want %s)\n", list[i].name, name));
6857
 
 
6858
 
                if (strequal(name, list[i].name)) {
6859
 
                        DEBUGADD(6,("Found form %s number [%d]\n", name, i));
6860
 
                        *form = list[i];
6861
 
                        SAFE_FREE(list);
6862
 
                        return WERR_OK;
6863
 
                }
6864
 
        }
6865
 
 
6866
 
        SAFE_FREE(list);
6867
 
 
6868
 
        return WERR_BADFID;
6869
 
}
6870
 
 
6871
 
/****************************************************************
6872
 
 _spoolss_GetForm
6873
 
****************************************************************/
6874
 
 
6875
 
WERROR _spoolss_GetForm(pipes_struct *p,
6876
 
                        struct spoolss_GetForm *r)
6877
 
{
6878
 
        WERROR result;
6879
 
        nt_forms_struct form;
6880
 
 
6881
 
        /* that's an [in out] buffer */
6882
 
 
6883
 
        if (!r->in.buffer && (r->in.offered != 0)) {
6884
 
                return WERR_INVALID_PARAM;
6885
 
        }
6886
 
 
6887
 
        DEBUG(4,("_spoolss_GetForm\n"));
6888
 
        DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6889
 
        DEBUGADD(5,("Info level [%d]\n",          r->in.level));
6890
 
 
6891
 
        result = find_form_byname(r->in.form_name, &form);
6892
 
        if (!W_ERROR_IS_OK(result)) {
6893
 
                TALLOC_FREE(r->out.info);
6894
 
                return result;
6895
 
        }
6896
 
 
6897
 
        switch (r->in.level) {
6898
 
        case 1:
6899
 
                result = fill_form_info_1(p->mem_ctx,
6900
 
                                          &r->out.info->info1,
6901
 
                                          &form);
6902
 
                break;
6903
 
 
6904
 
        default:
6905
 
                result = WERR_UNKNOWN_LEVEL;
6906
 
                break;
6907
 
        }
6908
 
 
6909
 
        if (!W_ERROR_IS_OK(result)) {
6910
 
                TALLOC_FREE(r->out.info);
6911
 
                return result;
6912
 
        }
6913
 
 
6914
 
        *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_FormInfo, NULL,
6915
 
                                               r->out.info, r->in.level);
6916
 
        r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
6917
 
 
6918
 
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6919
 
}
6920
 
 
6921
 
/****************************************************************************
6922
 
****************************************************************************/
6923
 
 
6924
 
static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
6925
 
                          struct spoolss_PortInfo1 *r,
6926
 
                          const char *name)
6927
 
{
6928
 
        r->port_name = talloc_strdup(mem_ctx, name);
6929
 
        W_ERROR_HAVE_NO_MEMORY(r->port_name);
6930
 
 
6931
 
        return WERR_OK;
6932
 
}
6933
 
 
6934
 
/****************************************************************************
6935
 
 TODO: This probably needs distinguish between TCP/IP and Local ports
6936
 
 somehow.
6937
 
****************************************************************************/
6938
 
 
6939
 
static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
6940
 
                          struct spoolss_PortInfo2 *r,
6941
 
                          const char *name)
6942
 
{
6943
 
        r->port_name = talloc_strdup(mem_ctx, name);
6944
 
        W_ERROR_HAVE_NO_MEMORY(r->port_name);
6945
 
 
6946
 
        r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
6947
 
        W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
6948
 
 
6949
 
        r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
6950
 
        W_ERROR_HAVE_NO_MEMORY(r->description);
6951
 
 
6952
 
        r->port_type = SPOOLSS_PORT_TYPE_WRITE;
6953
 
        r->reserved = 0;
6954
 
 
6955
 
        return WERR_OK;
6956
 
}
6957
 
 
6958
 
 
6959
 
/****************************************************************************
6960
 
 wrapper around the enumer ports command
6961
 
****************************************************************************/
6962
 
 
6963
 
static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
6964
 
{
6965
 
        char *cmd = lp_enumports_cmd();
6966
 
        char **qlines = NULL;
6967
 
        char *command = NULL;
6968
 
        int numlines;
6969
 
        int ret;
6970
 
        int fd;
6971
 
 
6972
 
        *count = 0;
6973
 
        *lines = NULL;
6974
 
 
6975
 
        /* if no hook then just fill in the default port */
6976
 
 
6977
 
        if ( !*cmd ) {
6978
 
                if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
6979
 
                        return WERR_NOMEM;
6980
 
                }
6981
 
                if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
6982
 
                        TALLOC_FREE(qlines);
6983
 
                        return WERR_NOMEM;
6984
 
                }
6985
 
                qlines[1] = NULL;
6986
 
                numlines = 1;
6987
 
        }
6988
 
        else {
6989
 
                /* we have a valid enumport command */
6990
 
 
6991
 
                command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
6992
 
                if (!command) {
6993
 
                        return WERR_NOMEM;
6994
 
                }
6995
 
 
6996
 
                DEBUG(10,("Running [%s]\n", command));
6997
 
                ret = smbrun(command, &fd);
6998
 
                DEBUG(10,("Returned [%d]\n", ret));
6999
 
                TALLOC_FREE(command);
7000
 
                if (ret != 0) {
7001
 
                        if (fd != -1) {
7002
 
                                close(fd);
7003
 
                        }
7004
 
                        return WERR_ACCESS_DENIED;
7005
 
                }
7006
 
 
7007
 
                numlines = 0;
7008
 
                qlines = fd_lines_load(fd, &numlines, 0, NULL);
7009
 
                DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7010
 
                close(fd);
7011
 
        }
7012
 
 
7013
 
        *count = numlines;
7014
 
        *lines = qlines;
7015
 
 
7016
 
        return WERR_OK;
7017
 
}
7018
 
 
7019
 
/****************************************************************************
7020
 
 enumports level 1.
7021
 
****************************************************************************/
7022
 
 
7023
 
static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7024
 
                                union spoolss_PortInfo **info_p,
7025
 
                                uint32_t *count)
7026
 
{
7027
 
        union spoolss_PortInfo *info = NULL;
7028
 
        int i=0;
7029
 
        WERROR result = WERR_OK;
7030
 
        char **qlines = NULL;
7031
 
        int numlines = 0;
7032
 
 
7033
 
        result = enumports_hook(talloc_tos(), &numlines, &qlines );
7034
 
        if (!W_ERROR_IS_OK(result)) {
7035
 
                goto out;
7036
 
        }
7037
 
 
7038
 
        if (numlines) {
7039
 
                info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7040
 
                if (!info) {
7041
 
                        DEBUG(10,("Returning WERR_NOMEM\n"));
7042
 
                        result = WERR_NOMEM;
7043
 
                        goto out;
7044
 
                }
7045
 
 
7046
 
                for (i=0; i<numlines; i++) {
7047
 
                        DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7048
 
                        result = fill_port_1(info, &info[i].info1, qlines[i]);
7049
 
                        if (!W_ERROR_IS_OK(result)) {
7050
 
                                goto out;
7051
 
                        }
7052
 
                }
7053
 
        }
7054
 
        TALLOC_FREE(qlines);
7055
 
 
7056
 
out:
7057
 
        if (!W_ERROR_IS_OK(result)) {
7058
 
                TALLOC_FREE(info);
7059
 
                TALLOC_FREE(qlines);
7060
 
                *count = 0;
7061
 
                *info_p = NULL;
7062
 
                return result;
7063
 
        }
7064
 
 
7065
 
        *info_p = info;
7066
 
        *count = numlines;
7067
 
 
7068
 
        return WERR_OK;
7069
 
}
7070
 
 
7071
 
/****************************************************************************
7072
 
 enumports level 2.
7073
 
****************************************************************************/
7074
 
 
7075
 
static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7076
 
                                union spoolss_PortInfo **info_p,
7077
 
                                uint32_t *count)
7078
 
{
7079
 
        union spoolss_PortInfo *info = NULL;
7080
 
        int i=0;
7081
 
        WERROR result = WERR_OK;
7082
 
        char **qlines = NULL;
7083
 
        int numlines = 0;
7084
 
 
7085
 
        result = enumports_hook(talloc_tos(), &numlines, &qlines );
7086
 
        if (!W_ERROR_IS_OK(result)) {
7087
 
                goto out;
7088
 
        }
7089
 
 
7090
 
        if (numlines) {
7091
 
                info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7092
 
                if (!info) {
7093
 
                        DEBUG(10,("Returning WERR_NOMEM\n"));
7094
 
                        result = WERR_NOMEM;
7095
 
                        goto out;
7096
 
                }
7097
 
 
7098
 
                for (i=0; i<numlines; i++) {
7099
 
                        DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7100
 
                        result = fill_port_2(info, &info[i].info2, qlines[i]);
7101
 
                        if (!W_ERROR_IS_OK(result)) {
7102
 
                                goto out;
7103
 
                        }
7104
 
                }
7105
 
        }
7106
 
        TALLOC_FREE(qlines);
7107
 
 
7108
 
out:
7109
 
        if (!W_ERROR_IS_OK(result)) {
7110
 
                TALLOC_FREE(info);
7111
 
                TALLOC_FREE(qlines);
7112
 
                *count = 0;
7113
 
                *info_p = NULL;
7114
 
                return result;
7115
 
        }
7116
 
 
7117
 
        *info_p = info;
7118
 
        *count = numlines;
7119
 
 
7120
 
        return WERR_OK;
7121
 
}
7122
 
 
7123
 
/****************************************************************
7124
 
 _spoolss_EnumPorts
7125
 
****************************************************************/
7126
 
 
7127
 
WERROR _spoolss_EnumPorts(pipes_struct *p,
7128
 
                          struct spoolss_EnumPorts *r)
7129
 
{
7130
 
        WERROR result;
7131
 
 
7132
 
        /* that's an [in out] buffer */
7133
 
 
7134
 
        if (!r->in.buffer && (r->in.offered != 0)) {
7135
 
                return WERR_INVALID_PARAM;
7136
 
        }
7137
 
 
7138
 
        DEBUG(4,("_spoolss_EnumPorts\n"));
7139
 
 
7140
 
        *r->out.count = 0;
7141
 
        *r->out.needed = 0;
7142
 
        *r->out.info = NULL;
7143
 
 
7144
 
        switch (r->in.level) {
7145
 
        case 1:
7146
 
                result = enumports_level_1(p->mem_ctx, r->out.info,
7147
 
                                           r->out.count);
7148
 
                break;
7149
 
        case 2:
7150
 
                result = enumports_level_2(p->mem_ctx, r->out.info,
7151
 
                                           r->out.count);
7152
 
                break;
7153
 
        default:
7154
 
                return WERR_UNKNOWN_LEVEL;
7155
 
        }
7156
 
 
7157
 
        if (!W_ERROR_IS_OK(result)) {
7158
 
                return result;
7159
 
        }
7160
 
 
7161
 
        *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7162
 
                                                     spoolss_EnumPorts, NULL,
7163
 
                                                     *r->out.info, r->in.level,
7164
 
                                                     *r->out.count);
7165
 
        *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7166
 
        *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7167
 
 
7168
 
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7169
 
}
7170
 
 
7171
 
/****************************************************************************
7172
 
****************************************************************************/
7173
 
 
7174
 
static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
7175
 
                                           const char *server,
7176
 
                                           struct spoolss_SetPrinterInfoCtr *info_ctr,
7177
 
                                           struct spoolss_DeviceMode *devmode,
7178
 
                                           struct security_descriptor *sec_desc,
7179
 
                                           struct spoolss_UserLevelCtr *user_ctr,
7180
 
                                           struct policy_handle *handle)
7181
 
{
7182
 
        NT_PRINTER_INFO_LEVEL *printer = NULL;
7183
 
        fstring name;
7184
 
        int     snum;
7185
 
        WERROR err = WERR_OK;
7186
 
 
7187
 
        if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
7188
 
                DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7189
 
                return WERR_NOMEM;
7190
 
        }
7191
 
 
7192
 
        /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7193
 
        if (!convert_printer_info(info_ctr, printer)) {
7194
 
                free_a_printer(&printer, 2);
7195
 
                return WERR_NOMEM;
7196
 
        }
7197
 
 
7198
 
        /* check to see if the printer already exists */
7199
 
 
7200
 
        if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
7201
 
                DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7202
 
                        printer->info_2->sharename));
7203
 
                free_a_printer(&printer, 2);
7204
 
                return WERR_PRINTER_ALREADY_EXISTS;
7205
 
        }
7206
 
 
7207
 
        /* FIXME!!!  smbd should check to see if the driver is installed before
7208
 
           trying to add a printer like this  --jerry */
7209
 
 
7210
 
        if (*lp_addprinter_cmd() ) {
7211
 
                if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7212
 
                                       printer) ) {
7213
 
                        free_a_printer(&printer,2);
7214
 
                        return WERR_ACCESS_DENIED;
7215
 
                }
7216
 
        } else {
7217
 
                DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7218
 
                        "smb.conf parameter \"addprinter command\" is defined. This"
7219
 
                        "parameter must exist for this call to succeed\n",
7220
 
                        printer->info_2->sharename ));
7221
 
        }
7222
 
 
7223
 
        /* use our primary netbios name since get_a_printer() will convert
7224
 
           it to what the client expects on a case by case basis */
7225
 
 
7226
 
        slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
7227
 
             printer->info_2->sharename);
7228
 
 
7229
 
 
7230
 
        if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
7231
 
                free_a_printer(&printer,2);
7232
 
                return WERR_ACCESS_DENIED;
7233
 
        }
7234
 
 
7235
 
        /* you must be a printer admin to add a new printer */
7236
 
        if (!print_access_check(p->server_info, snum, PRINTER_ACCESS_ADMINISTER)) {
7237
 
                free_a_printer(&printer,2);
7238
 
                return WERR_ACCESS_DENIED;
7239
 
        }
7240
 
 
7241
 
        /*
7242
 
         * Do sanity check on the requested changes for Samba.
7243
 
         */
7244
 
 
7245
 
        if (!check_printer_ok(printer->info_2, snum)) {
7246
 
                free_a_printer(&printer,2);
7247
 
                return WERR_INVALID_PARAM;
7248
 
        }
7249
 
 
7250
 
        /*
7251
 
         * When a printer is created, the drivername bound to the printer is used
7252
 
         * to lookup previously saved driver initialization info, which is then
7253
 
         * bound to the new printer, simulating what happens in the Windows arch.
7254
 
         */
7255
 
 
7256
 
        if (!devmode)
7257
 
        {
7258
 
                set_driver_init(printer, 2);
7259
 
        }
7260
 
        else
7261
 
        {
7262
 
                /* A valid devmode was included, convert and link it
7263
 
                */
7264
 
                DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7265
 
 
7266
 
                if (!convert_devicemode(printer->info_2->printername, devmode,
7267
 
                                        &printer->info_2->devmode)) {
7268
 
                        return  WERR_NOMEM;
7269
 
                }
7270
 
        }
7271
 
 
7272
 
        /* write the ASCII on disk */
7273
 
        err = mod_a_printer(printer, 2);
7274
 
        if (!W_ERROR_IS_OK(err)) {
7275
 
                free_a_printer(&printer,2);
7276
 
                return err;
7277
 
        }
7278
 
 
7279
 
        if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
7280
 
                /* Handle open failed - remove addition. */
7281
 
                del_a_printer(printer->info_2->sharename);
7282
 
                free_a_printer(&printer,2);
7283
 
                ZERO_STRUCTP(handle);
7284
 
                return WERR_ACCESS_DENIED;
7285
 
        }
7286
 
 
7287
 
        update_c_setprinter(false);
7288
 
        free_a_printer(&printer,2);
7289
 
 
7290
 
        return WERR_OK;
7291
 
}
7292
 
 
7293
 
/****************************************************************
7294
 
 _spoolss_AddPrinterEx
7295
 
****************************************************************/
7296
 
 
7297
 
WERROR _spoolss_AddPrinterEx(pipes_struct *p,
7298
 
                             struct spoolss_AddPrinterEx *r)
7299
 
{
7300
 
        switch (r->in.info_ctr->level) {
7301
 
        case 1:
7302
 
                /* we don't handle yet */
7303
 
                /* but I know what to do ... */
7304
 
                return WERR_UNKNOWN_LEVEL;
7305
 
        case 2:
7306
 
                return spoolss_addprinterex_level_2(p, r->in.server,
7307
 
                                                    r->in.info_ctr,
7308
 
                                                    r->in.devmode_ctr->devmode,
7309
 
                                                    r->in.secdesc_ctr->sd,
7310
 
                                                    r->in.userlevel_ctr,
7311
 
                                                    r->out.handle);
7312
 
        default:
7313
 
                return WERR_UNKNOWN_LEVEL;
7314
 
        }
7315
 
}
7316
 
 
7317
 
/****************************************************************
7318
 
 _spoolss_AddPrinter
7319
 
****************************************************************/
7320
 
 
7321
 
WERROR _spoolss_AddPrinter(pipes_struct *p,
7322
 
                           struct spoolss_AddPrinter *r)
7323
 
{
7324
 
        struct spoolss_AddPrinterEx a;
7325
 
        struct spoolss_UserLevelCtr userlevel_ctr;
7326
 
 
7327
 
        ZERO_STRUCT(userlevel_ctr);
7328
 
 
7329
 
        userlevel_ctr.level = 1;
7330
 
 
7331
 
        a.in.server             = r->in.server;
7332
 
        a.in.info_ctr           = r->in.info_ctr;
7333
 
        a.in.devmode_ctr        = r->in.devmode_ctr;
7334
 
        a.in.secdesc_ctr        = r->in.secdesc_ctr;
7335
 
        a.in.userlevel_ctr      = &userlevel_ctr;
7336
 
        a.out.handle            = r->out.handle;
7337
 
 
7338
 
        return _spoolss_AddPrinterEx(p, &a);
7339
 
}
7340
 
 
7341
 
/****************************************************************
7342
 
 _spoolss_AddPrinterDriver
7343
 
****************************************************************/
7344
 
 
7345
 
WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
7346
 
                                 struct spoolss_AddPrinterDriver *r)
7347
 
{
7348
 
        WERROR err = WERR_OK;
7349
 
        char *driver_name = NULL;
7350
 
        uint32_t version;
7351
 
        const char *fn;
7352
 
 
7353
 
        switch (p->hdr_req.opnum) {
7354
 
                case NDR_SPOOLSS_ADDPRINTERDRIVER:
7355
 
                        fn = "_spoolss_AddPrinterDriver";
7356
 
                        break;
7357
 
                case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7358
 
                        fn = "_spoolss_AddPrinterDriverEx";
7359
 
                        break;
7360
 
                default:
7361
 
                        return WERR_INVALID_PARAM;
7362
 
        }
7363
 
 
7364
 
 
7365
 
        /* FIXME */
7366
 
        if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7367
 
                /* Clever hack from Martin Zielinski <mz@seh.de>
7368
 
                 * to allow downgrade from level 8 (Vista).
7369
 
                 */
7370
 
                DEBUG(0,("%s: level %d not yet implemented\n", fn,
7371
 
                        r->in.info_ctr->level));
7372
 
                return WERR_UNKNOWN_LEVEL;
7373
 
        }
7374
 
 
7375
 
        DEBUG(5,("Cleaning driver's information\n"));
7376
 
        err = clean_up_driver_struct(p, r->in.info_ctr);
7377
 
        if (!W_ERROR_IS_OK(err))
7378
 
                goto done;
7379
 
 
7380
 
        DEBUG(5,("Moving driver to final destination\n"));
7381
 
        if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7382
 
                                                              &err)) ) {
7383
 
                goto done;
7384
 
        }
7385
 
 
7386
 
        if (add_a_printer_driver(p->mem_ctx, r->in.info_ctr, &driver_name, &version)!=0) {
7387
 
                err = WERR_ACCESS_DENIED;
7388
 
                goto done;
7389
 
        }
7390
 
 
7391
 
        /*
7392
 
         * I think this is where he DrvUpgradePrinter() hook would be
7393
 
         * be called in a driver's interface DLL on a Windows NT 4.0/2k
7394
 
         * server.  Right now, we just need to send ourselves a message
7395
 
         * to update each printer bound to this driver.   --jerry
7396
 
         */
7397
 
 
7398
 
        if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7399
 
                DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7400
 
                        fn, driver_name));
7401
 
        }
7402
 
 
7403
 
        /*
7404
 
         * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7405
 
         * decide if the driver init data should be deleted. The rules are:
7406
 
         *  1) never delete init data if it is a 9x driver, they don't use it anyway
7407
 
         *  2) delete init data only if there is no 2k/Xp driver
7408
 
         *  3) always delete init data
7409
 
         * The generalized rule is always use init data from the highest order driver.
7410
 
         * It is necessary to follow the driver install by an initialization step to
7411
 
         * finish off this process.
7412
 
        */
7413
 
 
7414
 
        switch (version) {
7415
 
                /*
7416
 
                 * 9x printer driver - never delete init data
7417
 
                */
7418
 
                case 0:
7419
 
                        DEBUG(10,("%s: init data not deleted for 9x driver [%s]\n",
7420
 
                                fn, driver_name));
7421
 
                        break;
7422
 
 
7423
 
                /*
7424
 
                 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7425
 
                 * there is no 2k/Xp driver init data for this driver name.
7426
 
                */
7427
 
                case 2:
7428
 
                {
7429
 
                        struct spoolss_DriverInfo8 *driver1;
7430
 
 
7431
 
                        if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &driver1, driver_name, "Windows NT x86", 3))) {
7432
 
                                /*
7433
 
                                 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7434
 
                                */
7435
 
                                if (!del_driver_init(driver_name))
7436
 
                                        DEBUG(6,("%s: del_driver_init(%s) Nt failed!\n",
7437
 
                                                fn, driver_name));
7438
 
                        } else {
7439
 
                                /*
7440
 
                                 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7441
 
                                */
7442
 
                                free_a_printer_driver(driver1);
7443
 
                                DEBUG(10,("%s: init data not deleted for Nt driver [%s]\n",
7444
 
                                        fn, driver_name));
7445
 
                        }
7446
 
                }
7447
 
                break;
7448
 
 
7449
 
                /*
7450
 
                 * 2k or Xp printer driver - always delete init data
7451
 
                */
7452
 
                case 3:
7453
 
                        if (!del_driver_init(driver_name))
7454
 
                                DEBUG(6,("%s: del_driver_init(%s) 2k/Xp failed!\n",
7455
 
                                        fn, driver_name));
7456
 
                        break;
7457
 
 
7458
 
                default:
7459
 
                        DEBUG(0,("%s: invalid level=%d\n", fn,
7460
 
                                r->in.info_ctr->level));
7461
 
                        break;
7462
 
        }
7463
 
 
7464
 
 
7465
 
done:
7466
 
        return err;
7467
 
}
7468
 
 
7469
 
/****************************************************************
7470
 
 _spoolss_AddPrinterDriverEx
7471
 
****************************************************************/
7472
 
 
7473
 
WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
7474
 
                                   struct spoolss_AddPrinterDriverEx *r)
7475
 
{
7476
 
        struct spoolss_AddPrinterDriver a;
7477
 
 
7478
 
        /*
7479
 
         * we only support the semantics of AddPrinterDriver()
7480
 
         * i.e. only copy files that are newer than existing ones
7481
 
         */
7482
 
 
7483
 
        if (r->in.flags == 0) {
7484
 
                return WERR_INVALID_PARAM;
7485
 
        }
7486
 
 
7487
 
        if (r->in.flags != APD_COPY_NEW_FILES) {
7488
 
                return WERR_ACCESS_DENIED;
7489
 
        }
7490
 
 
7491
 
        a.in.servername         = r->in.servername;
7492
 
        a.in.info_ctr           = r->in.info_ctr;
7493
 
 
7494
 
        return _spoolss_AddPrinterDriver(p, &a);
7495
 
}
7496
 
 
7497
 
/****************************************************************************
7498
 
****************************************************************************/
7499
 
 
7500
 
struct _spoolss_paths {
7501
 
        int type;
7502
 
        const char *share;
7503
 
        const char *dir;
7504
 
};
7505
 
 
7506
 
enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7507
 
 
7508
 
static const struct _spoolss_paths spoolss_paths[]= {
7509
 
        { SPOOLSS_DRIVER_PATH,          "print$",       "DRIVERS" },
7510
 
        { SPOOLSS_PRTPROCS_PATH,        "prnproc$",     "PRTPROCS" }
7511
 
};
7512
 
 
7513
 
static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7514
 
                                          const char *servername,
7515
 
                                          const char *environment,
7516
 
                                          int component,
7517
 
                                          char **path)
7518
 
{
7519
 
        const char *pservername = NULL;
7520
 
        const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7521
 
        const char *short_archi;
7522
 
 
7523
 
        *path = NULL;
7524
 
 
7525
 
        /* environment may be empty */
7526
 
        if (environment && strlen(environment)) {
7527
 
                long_archi = environment;
7528
 
        }
7529
 
 
7530
 
        /* servername may be empty */
7531
 
        if (servername && strlen(servername)) {
7532
 
                pservername = canon_servername(servername);
7533
 
 
7534
 
                if (!is_myname_or_ipaddr(pservername)) {
7535
 
                        return WERR_INVALID_PARAM;
7536
 
                }
7537
 
        }
7538
 
 
7539
 
        if (!(short_archi = get_short_archi(long_archi))) {
7540
 
                return WERR_INVALID_ENVIRONMENT;
7541
 
        }
7542
 
 
7543
 
        switch (component) {
7544
 
        case SPOOLSS_PRTPROCS_PATH:
7545
 
        case SPOOLSS_DRIVER_PATH:
7546
 
                if (pservername) {
7547
 
                        *path = talloc_asprintf(mem_ctx,
7548
 
                                        "\\\\%s\\%s\\%s",
7549
 
                                        pservername,
7550
 
                                        spoolss_paths[component].share,
7551
 
                                        short_archi);
7552
 
                } else {
7553
 
                        *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7554
 
                                        SPOOLSS_DEFAULT_SERVER_PATH,
7555
 
                                        spoolss_paths[component].dir,
7556
 
                                        short_archi);
7557
 
                }
7558
 
                break;
7559
 
        default:
7560
 
                return WERR_INVALID_PARAM;
7561
 
        }
7562
 
 
7563
 
        if (!*path) {
7564
 
                return WERR_NOMEM;
7565
 
        }
7566
 
 
7567
 
        return WERR_OK;
7568
 
}
7569
 
 
7570
 
/****************************************************************************
7571
 
****************************************************************************/
7572
 
 
7573
 
static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7574
 
                                          const char *servername,
7575
 
                                          const char *environment,
7576
 
                                          struct spoolss_DriverDirectoryInfo1 *r)
7577
 
{
7578
 
        WERROR werr;
7579
 
        char *path = NULL;
7580
 
 
7581
 
        werr = compose_spoolss_server_path(mem_ctx,
7582
 
                                           servername,
7583
 
                                           environment,
7584
 
                                           SPOOLSS_DRIVER_PATH,
7585
 
                                           &path);
7586
 
        if (!W_ERROR_IS_OK(werr)) {
7587
 
                return werr;
7588
 
        }
7589
 
 
7590
 
        DEBUG(4,("printer driver directory: [%s]\n", path));
7591
 
 
7592
 
        r->directory_name = path;
7593
 
 
7594
 
        return WERR_OK;
7595
 
}
7596
 
 
7597
 
/****************************************************************
7598
 
 _spoolss_GetPrinterDriverDirectory
7599
 
****************************************************************/
7600
 
 
7601
 
WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
7602
 
                                          struct spoolss_GetPrinterDriverDirectory *r)
7603
 
{
7604
 
        WERROR werror;
7605
 
 
7606
 
        /* that's an [in out] buffer */
7607
 
 
7608
 
        if (!r->in.buffer && (r->in.offered != 0)) {
7609
 
                return WERR_INVALID_PARAM;
7610
 
        }
7611
 
 
7612
 
        DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7613
 
                r->in.level));
7614
 
 
7615
 
        *r->out.needed = 0;
7616
 
 
7617
 
        /* r->in.level is ignored */
7618
 
 
7619
 
        werror = getprinterdriverdir_level_1(p->mem_ctx,
7620
 
                                             r->in.server,
7621
 
                                             r->in.environment,
7622
 
                                             &r->out.info->info1);
7623
 
        if (!W_ERROR_IS_OK(werror)) {
7624
 
                TALLOC_FREE(r->out.info);
7625
 
                return werror;
7626
 
        }
7627
 
 
7628
 
        *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo, NULL,
7629
 
                                               r->out.info, r->in.level);
7630
 
        r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7631
 
 
7632
 
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7633
 
}
7634
 
 
7635
 
/****************************************************************
7636
 
 _spoolss_EnumPrinterData
7637
 
****************************************************************/
7638
 
 
7639
 
WERROR _spoolss_EnumPrinterData(pipes_struct *p,
7640
 
                                struct spoolss_EnumPrinterData *r)
7641
 
{
7642
 
        NT_PRINTER_INFO_LEVEL *printer = NULL;
7643
 
        Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
7644
 
        int             snum;
7645
 
        WERROR          result;
7646
 
        struct regval_blob      *val = NULL;
7647
 
        NT_PRINTER_DATA *p_data;
7648
 
        int             i, key_index, num_values;
7649
 
        int             name_length;
7650
 
 
7651
 
        *r->out.value_needed    = 0;
7652
 
        *r->out.type            = REG_NONE;
7653
 
        *r->out.data_needed     = 0;
7654
 
 
7655
 
        DEBUG(5,("_spoolss_EnumPrinterData\n"));
7656
 
 
7657
 
        if (!Printer) {
7658
 
                DEBUG(2,("_spoolss_EnumPrinterData: Invalid handle (%s:%u:%u).\n",
7659
 
                        OUR_HANDLE(r->in.handle)));
7660
 
                return WERR_BADFID;
7661
 
        }
7662
 
 
7663
 
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7664
 
                return WERR_BADFID;
7665
 
        }
7666
 
 
7667
 
        result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
7668
 
        if (!W_ERROR_IS_OK(result)) {
7669
 
                return result;
7670
 
        }
7671
 
 
7672
 
        p_data = printer->info_2->data;
7673
 
        key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
7674
 
 
7675
 
        result = WERR_OK;
7676
 
 
7677
 
        /*
7678
 
         * The NT machine wants to know the biggest size of value and data
7679
 
         *
7680
 
         * cf: MSDN EnumPrinterData remark section
7681
 
         */
7682
 
 
7683
 
        if (!r->in.value_offered && !r->in.data_offered && (key_index != -1)) {
7684
 
 
7685
 
                uint32_t biggest_valuesize = 0;
7686
 
                uint32_t biggest_datasize = 0;
7687
 
 
7688
 
                DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7689
 
 
7690
 
                num_values = regval_ctr_numvals( p_data->keys[key_index].values );
7691
 
 
7692
 
                for ( i=0; i<num_values; i++ )
7693
 
                {
7694
 
                        val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
7695
 
 
7696
 
                        name_length = strlen(val->valuename);
7697
 
                        if ( strlen(val->valuename) > biggest_valuesize )
7698
 
                                biggest_valuesize = name_length;
7699
 
 
7700
 
                        if ( val->size > biggest_datasize )
7701
 
                                biggest_datasize = val->size;
7702
 
 
7703
 
                        DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
7704
 
                                biggest_datasize));
7705
 
                }
7706
 
 
7707
 
                /* the value is an UNICODE string but real_value_size is the length
7708
 
                   in bytes including the trailing 0 */
7709
 
 
7710
 
                *r->out.value_needed = 2 * (1 + biggest_valuesize);
7711
 
                *r->out.data_needed  = biggest_datasize;
7712
 
 
7713
 
                DEBUG(6,("final values: [%d], [%d]\n",
7714
 
                        *r->out.value_needed, *r->out.data_needed));
7715
 
 
7716
 
                goto done;
7717
 
        }
7718
 
 
7719
 
        /*
7720
 
         * the value len is wrong in NT sp3
7721
 
         * that's the number of bytes not the number of unicode chars
7722
 
         */
7723
 
 
7724
 
        if (key_index != -1) {
7725
 
                val = regval_ctr_specific_value(p_data->keys[key_index].values,
7726
 
                                                r->in.enum_index);
7727
 
        }
7728
 
 
7729
 
        if (!val) {
7730
 
 
7731
 
                /* out_value should default to "" or else NT4 has
7732
 
                   problems unmarshalling the response */
7733
 
 
7734
 
                if (r->in.value_offered) {
7735
 
                        *r->out.value_needed = 1;
7736
 
                        r->out.value_name = talloc_strdup(r, "");
7737
 
                        if (!r->out.value_name) {
7738
 
                                result = WERR_NOMEM;
7739
 
                                goto done;
7740
 
                        }
7741
 
                } else {
7742
 
                        r->out.value_name = NULL;
7743
 
                        *r->out.value_needed = 0;
7744
 
                }
7745
 
 
7746
 
                /* the data is counted in bytes */
7747
 
 
7748
 
                *r->out.data_needed = r->in.data_offered;
7749
 
 
7750
 
                result = WERR_NO_MORE_ITEMS;
7751
 
        } else {
7752
 
                /*
7753
 
                 * the value is:
7754
 
                 * - counted in bytes in the request
7755
 
                 * - counted in UNICODE chars in the max reply
7756
 
                 * - counted in bytes in the real size
7757
 
                 *
7758
 
                 * take a pause *before* coding not *during* coding
7759
 
                 */
7760
 
 
7761
 
                /* name */
7762
 
                if (r->in.value_offered) {
7763
 
                        r->out.value_name = talloc_strdup(r, regval_name(val));
7764
 
                        if (!r->out.value_name) {
7765
 
                                result = WERR_NOMEM;
7766
 
                                goto done;
7767
 
                        }
7768
 
                        *r->out.value_needed = strlen_m_term(regval_name(val)) * 2;
7769
 
                } else {
7770
 
                        r->out.value_name = NULL;
7771
 
                        *r->out.value_needed = 0;
7772
 
                }
7773
 
 
7774
 
                /* type */
7775
 
 
7776
 
                *r->out.type = regval_type(val);
7777
 
 
7778
 
                /* data - counted in bytes */
7779
 
 
7780
 
                /*
7781
 
                 * See the section "Dynamically Typed Query Parameters"
7782
 
                 * in MS-RPRN.
7783
 
                 */
7784
 
 
7785
 
                if (r->out.data && regval_data_p(val) &&
7786
 
                                regval_size(val) && r->in.data_offered) {
7787
 
                        memcpy(r->out.data, regval_data_p(val),
7788
 
                                MIN(regval_size(val),r->in.data_offered));
7789
 
                }
7790
 
 
7791
 
                *r->out.data_needed = regval_size(val);
7792
 
        }
7793
 
 
7794
 
done:
7795
 
        free_a_printer(&printer, 2);
7796
 
        return result;
7797
 
}
7798
 
 
7799
 
/****************************************************************
7800
 
 _spoolss_SetPrinterData
7801
 
****************************************************************/
7802
 
 
7803
 
WERROR _spoolss_SetPrinterData(pipes_struct *p,
7804
 
                               struct spoolss_SetPrinterData *r)
7805
 
{
7806
 
        struct spoolss_SetPrinterDataEx r2;
7807
 
 
7808
 
        r2.in.handle            = r->in.handle;
7809
 
        r2.in.key_name          = "PrinterDriverData";
7810
 
        r2.in.value_name        = r->in.value_name;
7811
 
        r2.in.type              = r->in.type;
7812
 
        r2.in.data              = r->in.data;
7813
 
        r2.in.offered           = r->in.offered;
7814
 
 
7815
 
        return _spoolss_SetPrinterDataEx(p, &r2);
7816
 
}
7817
 
 
7818
 
/****************************************************************
7819
 
 _spoolss_ResetPrinter
7820
 
****************************************************************/
7821
 
 
7822
 
WERROR _spoolss_ResetPrinter(pipes_struct *p,
7823
 
                             struct spoolss_ResetPrinter *r)
7824
 
{
7825
 
        Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
7826
 
        int             snum;
7827
 
 
7828
 
        DEBUG(5,("_spoolss_ResetPrinter\n"));
7829
 
 
7830
 
        /*
7831
 
         * All we do is to check to see if the handle and queue is valid.
7832
 
         * This call really doesn't mean anything to us because we only
7833
 
         * support RAW printing.   --jerry
7834
 
         */
7835
 
 
7836
 
        if (!Printer) {
7837
 
                DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7838
 
                        OUR_HANDLE(r->in.handle)));
7839
 
                return WERR_BADFID;
7840
 
        }
7841
 
 
7842
 
        if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7843
 
                return WERR_BADFID;
7844
 
 
7845
 
 
7846
 
        /* blindly return success */
7847
 
        return WERR_OK;
7848
 
}
7849
 
 
7850
 
/****************************************************************
7851
 
 _spoolss_DeletePrinterData
7852
 
****************************************************************/
7853
 
 
7854
 
WERROR _spoolss_DeletePrinterData(pipes_struct *p,
7855
 
                                  struct spoolss_DeletePrinterData *r)
7856
 
{
7857
 
        struct spoolss_DeletePrinterDataEx r2;
7858
 
 
7859
 
        r2.in.handle            = r->in.handle;
7860
 
        r2.in.key_name          = "PrinterDriverData";
7861
 
        r2.in.value_name        = r->in.value_name;
7862
 
 
7863
 
        return _spoolss_DeletePrinterDataEx(p, &r2);
7864
 
}
7865
 
 
7866
 
/****************************************************************
7867
 
 _spoolss_AddForm
7868
 
****************************************************************/
7869
 
 
7870
 
WERROR _spoolss_AddForm(pipes_struct *p,
7871
 
                        struct spoolss_AddForm *r)
7872
 
{
7873
 
        struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7874
 
        nt_forms_struct tmpForm;
7875
 
        int snum = -1;
7876
 
        WERROR status = WERR_OK;
7877
 
        NT_PRINTER_INFO_LEVEL *printer = NULL;
7878
 
        SE_PRIV se_printop = SE_PRINT_OPERATOR;
7879
 
 
7880
 
        int count=0;
7881
 
        nt_forms_struct *list=NULL;
7882
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7883
 
 
7884
 
        DEBUG(5,("_spoolss_AddForm\n"));
7885
 
 
7886
 
        if (!Printer) {
7887
 
                DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
7888
 
                        OUR_HANDLE(r->in.handle)));
7889
 
                return WERR_BADFID;
7890
 
        }
7891
 
 
7892
 
 
7893
 
        /* forms can be added on printer of on the print server handle */
7894
 
 
7895
 
        if ( Printer->printer_type == SPLHND_PRINTER )
7896
 
        {
7897
 
                if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7898
 
                        return WERR_BADFID;
7899
 
 
7900
 
                status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
7901
 
                if (!W_ERROR_IS_OK(status))
7902
 
                        goto done;
7903
 
        }
7904
 
 
7905
 
        /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7906
 
           and not a printer admin, then fail */
7907
 
 
7908
 
        if ((p->server_info->utok.uid != sec_initial_uid()) &&
7909
 
             !user_has_privileges(p->server_info->ptok, &se_printop) &&
7910
 
             !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7911
 
                                          pdb_get_domain(p->server_info->sam_account),
7912
 
                                          NULL,
7913
 
                                          p->server_info->ptok,
7914
 
                                          lp_printer_admin(snum))) {
7915
 
                DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
7916
 
                return WERR_ACCESS_DENIED;
7917
 
        }
7918
 
 
7919
 
        /* can't add if builtin */
7920
 
 
7921
 
        if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
7922
 
                status = WERR_FILE_EXISTS;
7923
 
                goto done;
7924
 
        }
7925
 
 
7926
 
        count = get_ntforms(&list);
7927
 
 
7928
 
        if(!add_a_form(&list, form, &count)) {
7929
 
                status =  WERR_NOMEM;
7930
 
                goto done;
7931
 
        }
7932
 
 
7933
 
        become_root();
7934
 
        write_ntforms(&list, count);
7935
 
        unbecome_root();
7936
 
 
7937
 
        /*
7938
 
         * ChangeID must always be set if this is a printer
7939
 
         */
7940
 
 
7941
 
        if ( Printer->printer_type == SPLHND_PRINTER )
7942
 
                status = mod_a_printer(printer, 2);
7943
 
 
7944
 
done:
7945
 
        if ( printer )
7946
 
                free_a_printer(&printer, 2);
7947
 
        SAFE_FREE(list);
7948
 
 
7949
 
        return status;
7950
 
}
7951
 
 
7952
 
/****************************************************************
7953
 
 _spoolss_DeleteForm
7954
 
****************************************************************/
7955
 
 
7956
 
WERROR _spoolss_DeleteForm(pipes_struct *p,
7957
 
                           struct spoolss_DeleteForm *r)
7958
 
{
7959
 
        const char *form_name = r->in.form_name;
7960
 
        nt_forms_struct tmpForm;
7961
 
        int count=0;
7962
 
        nt_forms_struct *list=NULL;
7963
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7964
 
        int snum = -1;
7965
 
        WERROR status = WERR_OK;
7966
 
        NT_PRINTER_INFO_LEVEL *printer = NULL;
7967
 
        SE_PRIV se_printop = SE_PRINT_OPERATOR;
7968
 
        bool ret = false;
7969
 
 
7970
 
        DEBUG(5,("_spoolss_DeleteForm\n"));
7971
 
 
7972
 
        if (!Printer) {
7973
 
                DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
7974
 
                        OUR_HANDLE(r->in.handle)));
7975
 
                return WERR_BADFID;
7976
 
        }
7977
 
 
7978
 
        /* forms can be deleted on printer of on the print server handle */
7979
 
 
7980
 
        if ( Printer->printer_type == SPLHND_PRINTER )
7981
 
        {
7982
 
                if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7983
 
                        return WERR_BADFID;
7984
 
 
7985
 
                status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
7986
 
                if (!W_ERROR_IS_OK(status))
7987
 
                        goto done;
7988
 
        }
7989
 
 
7990
 
        if ((p->server_info->utok.uid != sec_initial_uid()) &&
7991
 
             !user_has_privileges(p->server_info->ptok, &se_printop) &&
7992
 
             !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7993
 
                                          pdb_get_domain(p->server_info->sam_account),
7994
 
                                          NULL,
7995
 
                                          p->server_info->ptok,
7996
 
                                          lp_printer_admin(snum))) {
7997
 
                DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
7998
 
                return WERR_ACCESS_DENIED;
7999
 
        }
8000
 
 
8001
 
 
8002
 
        /* can't delete if builtin */
8003
 
 
8004
 
        if (get_a_builtin_ntform_by_string(form_name,&tmpForm)) {
8005
 
                status = WERR_INVALID_PARAM;
8006
 
                goto done;
8007
 
        }
8008
 
 
8009
 
        count = get_ntforms(&list);
8010
 
 
8011
 
        become_root();
8012
 
        ret = delete_a_form(&list, form_name, &count, &status);
8013
 
        unbecome_root();
8014
 
        if (ret == false) {
8015
 
                goto done;
8016
 
        }
8017
 
 
8018
 
        /*
8019
 
         * ChangeID must always be set if this is a printer
8020
 
         */
8021
 
 
8022
 
        if ( Printer->printer_type == SPLHND_PRINTER )
8023
 
                status = mod_a_printer(printer, 2);
8024
 
 
8025
 
done:
8026
 
        if ( printer )
8027
 
                free_a_printer(&printer, 2);
8028
 
        SAFE_FREE(list);
8029
 
 
8030
 
        return status;
8031
 
}
8032
 
 
8033
 
/****************************************************************
8034
 
 _spoolss_SetForm
8035
 
****************************************************************/
8036
 
 
8037
 
WERROR _spoolss_SetForm(pipes_struct *p,
8038
 
                        struct spoolss_SetForm *r)
8039
 
{
8040
 
        struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8041
 
        nt_forms_struct tmpForm;
8042
 
        int snum = -1;
8043
 
        WERROR status = WERR_OK;
8044
 
        NT_PRINTER_INFO_LEVEL *printer = NULL;
8045
 
        SE_PRIV se_printop = SE_PRINT_OPERATOR;
8046
 
 
8047
 
        int count=0;
8048
 
        nt_forms_struct *list=NULL;
8049
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8050
 
 
8051
 
        DEBUG(5,("_spoolss_SetForm\n"));
8052
 
 
8053
 
        if (!Printer) {
8054
 
                DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8055
 
                        OUR_HANDLE(r->in.handle)));
8056
 
                return WERR_BADFID;
8057
 
        }
8058
 
 
8059
 
        /* forms can be modified on printer of on the print server handle */
8060
 
 
8061
 
        if ( Printer->printer_type == SPLHND_PRINTER )
8062
 
        {
8063
 
                if (!get_printer_snum(p, r->in.handle, &snum, NULL))
8064
 
                        return WERR_BADFID;
8065
 
 
8066
 
                status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8067
 
                if (!W_ERROR_IS_OK(status))
8068
 
                        goto done;
8069
 
        }
8070
 
 
8071
 
        /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
8072
 
           and not a printer admin, then fail */
8073
 
 
8074
 
        if ((p->server_info->utok.uid != sec_initial_uid()) &&
8075
 
             !user_has_privileges(p->server_info->ptok, &se_printop) &&
8076
 
             !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8077
 
                                          pdb_get_domain(p->server_info->sam_account),
8078
 
                                          NULL,
8079
 
                                          p->server_info->ptok,
8080
 
                                          lp_printer_admin(snum))) {
8081
 
                DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
8082
 
                return WERR_ACCESS_DENIED;
8083
 
        }
8084
 
 
8085
 
        /* can't set if builtin */
8086
 
        if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8087
 
                status = WERR_INVALID_PARAM;
8088
 
                goto done;
8089
 
        }
8090
 
 
8091
 
        count = get_ntforms(&list);
8092
 
        update_a_form(&list, form, count);
8093
 
        become_root();
8094
 
        write_ntforms(&list, count);
8095
 
        unbecome_root();
8096
 
 
8097
 
        /*
8098
 
         * ChangeID must always be set if this is a printer
8099
 
         */
8100
 
 
8101
 
        if ( Printer->printer_type == SPLHND_PRINTER )
8102
 
                status = mod_a_printer(printer, 2);
8103
 
 
8104
 
 
8105
 
done:
8106
 
        if ( printer )
8107
 
                free_a_printer(&printer, 2);
8108
 
        SAFE_FREE(list);
8109
 
 
8110
 
        return status;
8111
 
}
8112
 
 
8113
 
/****************************************************************************
8114
 
 fill_print_processor1
8115
 
****************************************************************************/
8116
 
 
8117
 
static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8118
 
                                    struct spoolss_PrintProcessorInfo1 *r,
8119
 
                                    const char *print_processor_name)
8120
 
{
8121
 
        r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8122
 
        W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8123
 
 
8124
 
        return WERR_OK;
8125
 
}
8126
 
 
8127
 
/****************************************************************************
8128
 
 enumprintprocessors level 1.
8129
 
****************************************************************************/
8130
 
 
8131
 
static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8132
 
                                          union spoolss_PrintProcessorInfo **info_p,
8133
 
                                          uint32_t *count)
8134
 
{
8135
 
        union spoolss_PrintProcessorInfo *info;
8136
 
        WERROR result;
8137
 
 
8138
 
        info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8139
 
        W_ERROR_HAVE_NO_MEMORY(info);
8140
 
 
8141
 
        *count = 1;
8142
 
 
8143
 
        result = fill_print_processor1(info, &info[0].info1, "winprint");
8144
 
        if (!W_ERROR_IS_OK(result)) {
8145
 
                goto out;
8146
 
        }
8147
 
 
8148
 
 out:
8149
 
        if (!W_ERROR_IS_OK(result)) {
8150
 
                TALLOC_FREE(info);
8151
 
                *count = 0;
8152
 
                return result;
8153
 
        }
8154
 
 
8155
 
        *info_p = info;
8156
 
 
8157
 
        return WERR_OK;
8158
 
}
8159
 
 
8160
 
/****************************************************************
8161
 
 _spoolss_EnumPrintProcessors
8162
 
****************************************************************/
8163
 
 
8164
 
WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
8165
 
                                    struct spoolss_EnumPrintProcessors *r)
8166
 
{
8167
 
        WERROR result;
8168
 
 
8169
 
        /* that's an [in out] buffer */
8170
 
 
8171
 
        if (!r->in.buffer && (r->in.offered != 0)) {
8172
 
                return WERR_INVALID_PARAM;
8173
 
        }
8174
 
 
8175
 
        DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8176
 
 
8177
 
        /*
8178
 
         * Enumerate the print processors ...
8179
 
         *
8180
 
         * Just reply with "winprint", to keep NT happy
8181
 
         * and I can use my nice printer checker.
8182
 
         */
8183
 
 
8184
 
        *r->out.count = 0;
8185
 
        *r->out.needed = 0;
8186
 
        *r->out.info = NULL;
8187
 
 
8188
 
        switch (r->in.level) {
8189
 
        case 1:
8190
 
                result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8191
 
                                                     r->out.count);
8192
 
                break;
8193
 
        default:
8194
 
                return WERR_UNKNOWN_LEVEL;
8195
 
        }
8196
 
 
8197
 
        if (!W_ERROR_IS_OK(result)) {
8198
 
                return result;
8199
 
        }
8200
 
 
8201
 
        *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8202
 
                                                     spoolss_EnumPrintProcessors, NULL,
8203
 
                                                     *r->out.info, r->in.level,
8204
 
                                                     *r->out.count);
8205
 
        *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8206
 
        *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8207
 
 
8208
 
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8209
 
}
8210
 
 
8211
 
/****************************************************************************
8212
 
 fill_printprocdatatype1
8213
 
****************************************************************************/
8214
 
 
8215
 
static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8216
 
                                      struct spoolss_PrintProcDataTypesInfo1 *r,
8217
 
                                      const char *name_array)
8218
 
{
8219
 
        r->name_array = talloc_strdup(mem_ctx, name_array);
8220
 
        W_ERROR_HAVE_NO_MEMORY(r->name_array);
8221
 
 
8222
 
        return WERR_OK;
8223
 
}
8224
 
 
8225
 
/****************************************************************************
8226
 
 enumprintprocdatatypes level 1.
8227
 
****************************************************************************/
8228
 
 
8229
 
static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8230
 
                                             union spoolss_PrintProcDataTypesInfo **info_p,
8231
 
                                             uint32_t *count)
8232
 
{
8233
 
        WERROR result;
8234
 
        union spoolss_PrintProcDataTypesInfo *info;
8235
 
 
8236
 
        info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8237
 
        W_ERROR_HAVE_NO_MEMORY(info);
8238
 
 
8239
 
        *count = 1;
8240
 
 
8241
 
        result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8242
 
        if (!W_ERROR_IS_OK(result)) {
8243
 
                goto out;
8244
 
        }
8245
 
 
8246
 
 out:
8247
 
        if (!W_ERROR_IS_OK(result)) {
8248
 
                TALLOC_FREE(info);
8249
 
                *count = 0;
8250
 
                return result;
8251
 
        }
8252
 
 
8253
 
        *info_p = info;
8254
 
 
8255
 
        return WERR_OK;
8256
 
}
8257
 
 
8258
 
/****************************************************************
8259
 
 _spoolss_EnumPrintProcDataTypes
8260
 
****************************************************************/
8261
 
 
8262
 
WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
8263
 
                                       struct spoolss_EnumPrintProcDataTypes *r)
8264
 
{
8265
 
        WERROR result;
8266
 
 
8267
 
        /* that's an [in out] buffer */
8268
 
 
8269
 
        if (!r->in.buffer && (r->in.offered != 0)) {
8270
 
                return WERR_INVALID_PARAM;
8271
 
        }
8272
 
 
8273
 
        DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8274
 
 
8275
 
        *r->out.count = 0;
8276
 
        *r->out.needed = 0;
8277
 
        *r->out.info = NULL;
8278
 
 
8279
 
        switch (r->in.level) {
8280
 
        case 1:
8281
 
                result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8282
 
                                                        r->out.count);
8283
 
                break;
8284
 
        default:
8285
 
                return WERR_UNKNOWN_LEVEL;
8286
 
        }
8287
 
 
8288
 
        *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8289
 
                                                     spoolss_EnumPrintProcDataTypes, NULL,
8290
 
                                                     *r->out.info, r->in.level,
8291
 
                                                     *r->out.count);
8292
 
        *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8293
 
        *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8294
 
 
8295
 
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8296
 
}
8297
 
 
8298
 
/****************************************************************************
8299
 
 fill_monitor_1
8300
 
****************************************************************************/
8301
 
 
8302
 
static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8303
 
                             struct spoolss_MonitorInfo1 *r,
8304
 
                             const char *monitor_name)
8305
 
{
8306
 
        r->monitor_name                 = talloc_strdup(mem_ctx, monitor_name);
8307
 
        W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8308
 
 
8309
 
        return WERR_OK;
8310
 
}
8311
 
 
8312
 
/****************************************************************************
8313
 
 fill_monitor_2
8314
 
****************************************************************************/
8315
 
 
8316
 
static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8317
 
                             struct spoolss_MonitorInfo2 *r,
8318
 
                             const char *monitor_name,
8319
 
                             const char *environment,
8320
 
                             const char *dll_name)
8321
 
{
8322
 
        r->monitor_name                 = talloc_strdup(mem_ctx, monitor_name);
8323
 
        W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8324
 
        r->environment                  = talloc_strdup(mem_ctx, environment);
8325
 
        W_ERROR_HAVE_NO_MEMORY(r->environment);
8326
 
        r->dll_name                     = talloc_strdup(mem_ctx, dll_name);
8327
 
        W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8328
 
 
8329
 
        return WERR_OK;
8330
 
}
8331
 
 
8332
 
/****************************************************************************
8333
 
 enumprintmonitors level 1.
8334
 
****************************************************************************/
8335
 
 
8336
 
static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8337
 
                                        union spoolss_MonitorInfo **info_p,
8338
 
                                        uint32_t *count)
8339
 
{
8340
 
        union spoolss_MonitorInfo *info;
8341
 
        WERROR result = WERR_OK;
8342
 
 
8343
 
        info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8344
 
        W_ERROR_HAVE_NO_MEMORY(info);
8345
 
 
8346
 
        *count = 2;
8347
 
 
8348
 
        result = fill_monitor_1(info, &info[0].info1,
8349
 
                                SPL_LOCAL_PORT);
8350
 
        if (!W_ERROR_IS_OK(result)) {
8351
 
                goto out;
8352
 
        }
8353
 
 
8354
 
        result = fill_monitor_1(info, &info[1].info1,
8355
 
                                SPL_TCPIP_PORT);
8356
 
        if (!W_ERROR_IS_OK(result)) {
8357
 
                goto out;
8358
 
        }
8359
 
 
8360
 
out:
8361
 
        if (!W_ERROR_IS_OK(result)) {
8362
 
                TALLOC_FREE(info);
8363
 
                *count = 0;
8364
 
                return result;
8365
 
        }
8366
 
 
8367
 
        *info_p = info;
8368
 
 
8369
 
        return WERR_OK;
8370
 
}
8371
 
 
8372
 
/****************************************************************************
8373
 
 enumprintmonitors level 2.
8374
 
****************************************************************************/
8375
 
 
8376
 
static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8377
 
                                        union spoolss_MonitorInfo **info_p,
8378
 
                                        uint32_t *count)
8379
 
{
8380
 
        union spoolss_MonitorInfo *info;
8381
 
        WERROR result = WERR_OK;
8382
 
 
8383
 
        info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8384
 
        W_ERROR_HAVE_NO_MEMORY(info);
8385
 
 
8386
 
        *count = 2;
8387
 
 
8388
 
        result = fill_monitor_2(info, &info[0].info2,
8389
 
                                SPL_LOCAL_PORT,
8390
 
                                "Windows NT X86", /* FIXME */
8391
 
                                "localmon.dll");
8392
 
        if (!W_ERROR_IS_OK(result)) {
8393
 
                goto out;
8394
 
        }
8395
 
 
8396
 
        result = fill_monitor_2(info, &info[1].info2,
8397
 
                                SPL_TCPIP_PORT,
8398
 
                                "Windows NT X86", /* FIXME */
8399
 
                                "tcpmon.dll");
8400
 
        if (!W_ERROR_IS_OK(result)) {
8401
 
                goto out;
8402
 
        }
8403
 
 
8404
 
out:
8405
 
        if (!W_ERROR_IS_OK(result)) {
8406
 
                TALLOC_FREE(info);
8407
 
                *count = 0;
8408
 
                return result;
8409
 
        }
8410
 
 
8411
 
        *info_p = info;
8412
 
 
8413
 
        return WERR_OK;
8414
 
}
8415
 
 
8416
 
/****************************************************************
8417
 
 _spoolss_EnumMonitors
8418
 
****************************************************************/
8419
 
 
8420
 
WERROR _spoolss_EnumMonitors(pipes_struct *p,
8421
 
                             struct spoolss_EnumMonitors *r)
8422
 
{
8423
 
        WERROR result;
8424
 
 
8425
 
        /* that's an [in out] buffer */
8426
 
 
8427
 
        if (!r->in.buffer && (r->in.offered != 0)) {
8428
 
                return WERR_INVALID_PARAM;
8429
 
        }
8430
 
 
8431
 
        DEBUG(5,("_spoolss_EnumMonitors\n"));
8432
 
 
8433
 
        /*
8434
 
         * Enumerate the print monitors ...
8435
 
         *
8436
 
         * Just reply with "Local Port", to keep NT happy
8437
 
         * and I can use my nice printer checker.
8438
 
         */
8439
 
 
8440
 
        *r->out.count = 0;
8441
 
        *r->out.needed = 0;
8442
 
        *r->out.info = NULL;
8443
 
 
8444
 
        switch (r->in.level) {
8445
 
        case 1:
8446
 
                result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8447
 
                                                   r->out.count);
8448
 
                break;
8449
 
        case 2:
8450
 
                result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8451
 
                                                   r->out.count);
8452
 
                break;
8453
 
        default:
8454
 
                return WERR_UNKNOWN_LEVEL;
8455
 
        }
8456
 
 
8457
 
        if (!W_ERROR_IS_OK(result)) {
8458
 
                return result;
8459
 
        }
8460
 
 
8461
 
        *r->out.needed  = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8462
 
                                                     spoolss_EnumMonitors, NULL,
8463
 
                                                     *r->out.info, r->in.level,
8464
 
                                                     *r->out.count);
8465
 
        *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8466
 
        *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8467
 
 
8468
 
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8469
 
}
8470
 
 
8471
 
/****************************************************************************
8472
 
****************************************************************************/
8473
 
 
8474
 
static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8475
 
                             const print_queue_struct *queue,
8476
 
                             int count, int snum,
8477
 
                             const NT_PRINTER_INFO_LEVEL *ntprinter,
8478
 
                             uint32_t jobid,
8479
 
                             struct spoolss_JobInfo1 *r)
8480
 
{
8481
 
        int i = 0;
8482
 
        bool found = false;
8483
 
 
8484
 
        for (i=0; i<count && found == false; i++) {
8485
 
                if (queue[i].job == (int)jobid) {
8486
 
                        found = true;
8487
 
                }
8488
 
        }
8489
 
 
8490
 
        if (found == false) {
8491
 
                /* NT treats not found as bad param... yet another bad choice */
8492
 
                return WERR_INVALID_PARAM;
8493
 
        }
8494
 
 
8495
 
        return fill_job_info1(mem_ctx,
8496
 
                              r,
8497
 
                              &queue[i-1],
8498
 
                              i,
8499
 
                              snum,
8500
 
                              ntprinter);
8501
 
}
8502
 
 
8503
 
/****************************************************************************
8504
 
****************************************************************************/
8505
 
 
8506
 
static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8507
 
                             const print_queue_struct *queue,
8508
 
                             int count, int snum,
8509
 
                             const NT_PRINTER_INFO_LEVEL *ntprinter,
8510
 
                             uint32_t jobid,
8511
 
                             struct spoolss_JobInfo2 *r)
8512
 
{
8513
 
        int i = 0;
8514
 
        bool found = false;
8515
 
        struct spoolss_DeviceMode *devmode;
8516
 
        NT_DEVICEMODE *nt_devmode;
8517
 
        WERROR result;
8518
 
 
8519
 
        for (i=0; i<count && found == false; i++) {
8520
 
                if (queue[i].job == (int)jobid) {
8521
 
                        found = true;
8522
 
                }
8523
 
        }
8524
 
 
8525
 
        if (found == false) {
8526
 
                /* NT treats not found as bad param... yet another bad
8527
 
                   choice */
8528
 
                return WERR_INVALID_PARAM;
8529
 
        }
8530
 
 
8531
 
        /*
8532
 
         * if the print job does not have a DEVMODE associated with it,
8533
 
         * just use the one for the printer. A NULL devicemode is not
8534
 
         *  a failure condition
8535
 
         */
8536
 
 
8537
 
        nt_devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8538
 
        if (nt_devmode) {
8539
 
                devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode);
8540
 
                W_ERROR_HAVE_NO_MEMORY(devmode);
8541
 
                result = convert_nt_devicemode(devmode, devmode, nt_devmode);
8542
 
                if (!W_ERROR_IS_OK(result)) {
8543
 
                        return result;
8544
 
                }
8545
 
        } else {
8546
 
                devmode = construct_dev_mode(mem_ctx, lp_const_servicename(snum));
8547
 
                W_ERROR_HAVE_NO_MEMORY(devmode);
8548
 
        }
8549
 
 
8550
 
        return fill_job_info2(mem_ctx,
8551
 
                              r,
8552
 
                              &queue[i-1],
8553
 
                              i,
8554
 
                              snum,
8555
 
                              ntprinter,
8556
 
                              devmode);
8557
 
}
8558
 
 
8559
 
/****************************************************************
8560
 
 _spoolss_GetJob
8561
 
****************************************************************/
8562
 
 
8563
 
WERROR _spoolss_GetJob(pipes_struct *p,
8564
 
                       struct spoolss_GetJob *r)
8565
 
{
8566
 
        WERROR result = WERR_OK;
8567
 
        NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
8568
 
        int snum;
8569
 
        int count;
8570
 
        print_queue_struct      *queue = NULL;
8571
 
        print_status_struct prt_status;
8572
 
 
8573
 
        /* that's an [in out] buffer */
8574
 
 
8575
 
        if (!r->in.buffer && (r->in.offered != 0)) {
8576
 
                return WERR_INVALID_PARAM;
8577
 
        }
8578
 
 
8579
 
        DEBUG(5,("_spoolss_GetJob\n"));
8580
 
 
8581
 
        *r->out.needed = 0;
8582
 
 
8583
 
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8584
 
                return WERR_BADFID;
8585
 
        }
8586
 
 
8587
 
        result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
8588
 
        if (!W_ERROR_IS_OK(result)) {
8589
 
                return result;
8590
 
        }
8591
 
 
8592
 
        count = print_queue_status(snum, &queue, &prt_status);
8593
 
 
8594
 
        DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8595
 
                     count, prt_status.status, prt_status.message));
8596
 
 
8597
 
        switch (r->in.level) {
8598
 
        case 1:
8599
 
                result = getjob_level_1(p->mem_ctx,
8600
 
                                        queue, count, snum, ntprinter,
8601
 
                                        r->in.job_id, &r->out.info->info1);
8602
 
                break;
8603
 
        case 2:
8604
 
                result = getjob_level_2(p->mem_ctx,
8605
 
                                        queue, count, snum, ntprinter,
8606
 
                                        r->in.job_id, &r->out.info->info2);
8607
 
                break;
8608
 
        default:
8609
 
                result = WERR_UNKNOWN_LEVEL;
8610
 
                break;
8611
 
        }
8612
 
 
8613
 
        SAFE_FREE(queue);
8614
 
        free_a_printer(&ntprinter, 2);
8615
 
 
8616
 
        if (!W_ERROR_IS_OK(result)) {
8617
 
                TALLOC_FREE(r->out.info);
8618
 
                return result;
8619
 
        }
8620
 
 
8621
 
        *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, NULL,
8622
 
                                               r->out.info, r->in.level);
8623
 
        r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8624
 
 
8625
 
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8626
 
}
8627
 
 
8628
 
/****************************************************************
8629
 
 _spoolss_GetPrinterDataEx
8630
 
****************************************************************/
8631
 
 
8632
 
WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
8633
 
                                 struct spoolss_GetPrinterDataEx *r)
8634
 
{
8635
 
 
8636
 
        Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
8637
 
        struct regval_blob              *val = NULL;
8638
 
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
8639
 
        int                     snum = 0;
8640
 
        WERROR result = WERR_OK;
8641
 
        DATA_BLOB blob;
8642
 
 
8643
 
        DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8644
 
 
8645
 
        DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8646
 
                r->in.key_name, r->in.value_name));
8647
 
 
8648
 
        /* in case of problem, return some default values */
8649
 
 
8650
 
        *r->out.needed  = 0;
8651
 
        *r->out.type    = REG_NONE;
8652
 
 
8653
 
        if (!Printer) {
8654
 
                DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8655
 
                        OUR_HANDLE(r->in.handle)));
8656
 
                result = WERR_BADFID;
8657
 
                goto done;
8658
 
        }
8659
 
 
8660
 
        /* Is the handle to a printer or to the server? */
8661
 
 
8662
 
        if (Printer->printer_type == SPLHND_SERVER) {
8663
 
 
8664
 
                union spoolss_PrinterData data;
8665
 
 
8666
 
                result = getprinterdata_printer_server(p->mem_ctx,
8667
 
                                                       r->in.value_name,
8668
 
                                                       r->out.type,
8669
 
                                                       &data);
8670
 
                if (!W_ERROR_IS_OK(result)) {
8671
 
                        goto done;
8672
 
                }
8673
 
 
8674
 
                result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8675
 
                                                  *r->out.type, &data);
8676
 
                if (!W_ERROR_IS_OK(result)) {
8677
 
                        goto done;
8678
 
                }
8679
 
 
8680
 
                *r->out.needed = blob.length;
8681
 
 
8682
 
                if (r->in.offered >= *r->out.needed) {
8683
 
                        memcpy(r->out.data, blob.data, blob.length);
8684
 
                }
8685
 
 
8686
 
                return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8687
 
        }
8688
 
 
8689
 
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8690
 
                result = WERR_BADFID;
8691
 
                goto done;
8692
 
        }
8693
 
 
8694
 
        result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
8695
 
        if (!W_ERROR_IS_OK(result)) {
8696
 
                goto done;
8697
 
        }
8698
 
 
8699
 
        /* check to see if the keyname is valid */
8700
 
        if (!strlen(r->in.key_name)) {
8701
 
                result = WERR_INVALID_PARAM;
8702
 
                goto done;
8703
 
        }
8704
 
 
8705
 
        /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
8706
 
 
8707
 
        if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8708
 
            strequal(r->in.value_name, "ChangeId")) {
8709
 
                *r->out.type = REG_DWORD;
8710
 
                *r->out.needed = 4;
8711
 
                if (r->in.offered >= *r->out.needed) {
8712
 
                        SIVAL(r->out.data, 0, printer->info_2->changeid);
8713
 
                        result = WERR_OK;
8714
 
                }
8715
 
                goto done;
8716
 
        }
8717
 
 
8718
 
        if (lookup_printerkey(printer->info_2->data, r->in.key_name) == -1) {
8719
 
                DEBUG(4,("_spoolss_GetPrinterDataEx: "
8720
 
                        "Invalid keyname [%s]\n", r->in.key_name ));
8721
 
                result = WERR_BADFILE;
8722
 
                goto done;
8723
 
        }
8724
 
 
8725
 
        val = get_printer_data(printer->info_2,
8726
 
                               r->in.key_name, r->in.value_name);
8727
 
        if (!val) {
8728
 
                result = WERR_BADFILE;
8729
 
                goto done;
8730
 
        }
8731
 
 
8732
 
        *r->out.needed = regval_size(val);
8733
 
        *r->out.type = regval_type(val);
8734
 
 
8735
 
        if (r->in.offered >= *r->out.needed) {
8736
 
                memcpy(r->out.data, regval_data_p(val), regval_size(val));
8737
 
        }
8738
 
 done:
8739
 
        if (printer) {
8740
 
                free_a_printer(&printer, 2);
8741
 
        }
8742
 
 
8743
 
        if (!W_ERROR_IS_OK(result)) {
8744
 
                return result;
8745
 
        }
8746
 
 
8747
 
        *r->out.type    = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8748
 
        r->out.data     = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8749
 
 
8750
 
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8751
 
}
8752
 
 
8753
 
/****************************************************************
8754
 
 _spoolss_SetPrinterDataEx
8755
 
****************************************************************/
8756
 
 
8757
 
WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
8758
 
                                 struct spoolss_SetPrinterDataEx *r)
8759
 
{
8760
 
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
8761
 
        int                     snum = 0;
8762
 
        WERROR                  result = WERR_OK;
8763
 
        Printer_entry           *Printer = find_printer_index_by_hnd(p, r->in.handle);
8764
 
        char                    *oid_string;
8765
 
 
8766
 
        DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8767
 
 
8768
 
        /* From MSDN documentation of SetPrinterDataEx: pass request to
8769
 
           SetPrinterData if key is "PrinterDriverData" */
8770
 
 
8771
 
        if (!Printer) {
8772
 
                DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8773
 
                        OUR_HANDLE(r->in.handle)));
8774
 
                return WERR_BADFID;
8775
 
        }
8776
 
 
8777
 
        if (Printer->printer_type == SPLHND_SERVER) {
8778
 
                DEBUG(10,("_spoolss_SetPrinterDataEx: "
8779
 
                        "Not implemented for server handles yet\n"));
8780
 
                return WERR_INVALID_PARAM;
8781
 
        }
8782
 
 
8783
 
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8784
 
                return WERR_BADFID;
8785
 
        }
8786
 
 
8787
 
        /*
8788
 
         * Access check : NT returns "access denied" if you make a
8789
 
         * SetPrinterData call without the necessary privildge.
8790
 
         * we were originally returning OK if nothing changed
8791
 
         * which made Win2k issue **a lot** of SetPrinterData
8792
 
         * when connecting to a printer  --jerry
8793
 
         */
8794
 
 
8795
 
        if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8796
 
                DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8797
 
                        "change denied by handle access permissions\n"));
8798
 
                return WERR_ACCESS_DENIED;
8799
 
        }
8800
 
 
8801
 
        result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
8802
 
        if (!W_ERROR_IS_OK(result)) {
8803
 
                return result;
8804
 
        }
8805
 
 
8806
 
        /* check for OID in valuename */
8807
 
 
8808
 
        oid_string = strchr(r->in.value_name, ',');
8809
 
        if (oid_string) {
8810
 
                *oid_string = '\0';
8811
 
                oid_string++;
8812
 
        }
8813
 
 
8814
 
        /*
8815
 
         * When client side code sets a magic printer data key, detect it and save
8816
 
         * the current printer data and the magic key's data (its the DEVMODE) for
8817
 
         * future printer/driver initializations.
8818
 
         */
8819
 
        if ((r->in.type == REG_BINARY) && strequal(r->in.value_name, PHANTOM_DEVMODE_KEY)) {
8820
 
                /* Set devmode and printer initialization info */
8821
 
                result = save_driver_init(printer, 2, r->in.data, r->in.offered);
8822
 
 
8823
 
                srv_spoolss_reset_printerdata(printer->info_2->drivername);
8824
 
 
8825
 
                goto done;
8826
 
        }
8827
 
 
8828
 
        /* save the registry data */
8829
 
 
8830
 
        result = set_printer_dataex(printer, r->in.key_name, r->in.value_name,
8831
 
                                    r->in.type, r->in.data, r->in.offered);
8832
 
 
8833
 
        if (W_ERROR_IS_OK(result)) {
8834
 
                /* save the OID if one was specified */
8835
 
                if (oid_string) {
8836
 
                        char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
8837
 
                                r->in.key_name, SPOOL_OID_KEY);
8838
 
                        if (!str) {
8839
 
                                result = WERR_NOMEM;
8840
 
                                goto done;
8841
 
                        }
8842
 
 
8843
 
                        /*
8844
 
                         * I'm not checking the status here on purpose.  Don't know
8845
 
                         * if this is right, but I'm returning the status from the
8846
 
                         * previous set_printer_dataex() call.  I have no idea if
8847
 
                         * this is right.    --jerry
8848
 
                         */
8849
 
 
8850
 
                        set_printer_dataex(printer, str, r->in.value_name,
8851
 
                                           REG_SZ, (uint8_t *)oid_string,
8852
 
                                           strlen(oid_string)+1);
8853
 
                }
8854
 
 
8855
 
                result = mod_a_printer(printer, 2);
8856
 
        }
8857
 
 
8858
 
 done:
8859
 
        free_a_printer(&printer, 2);
8860
 
 
8861
 
        return result;
8862
 
}
8863
 
 
8864
 
/****************************************************************
8865
 
 _spoolss_DeletePrinterDataEx
8866
 
****************************************************************/
8867
 
 
8868
 
WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
8869
 
                                    struct spoolss_DeletePrinterDataEx *r)
8870
 
{
8871
 
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
8872
 
        int             snum=0;
8873
 
        WERROR          status = WERR_OK;
8874
 
        Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
8875
 
 
8876
 
        DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8877
 
 
8878
 
        if (!Printer) {
8879
 
                DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8880
 
                        "Invalid handle (%s:%u:%u).\n",
8881
 
                        OUR_HANDLE(r->in.handle)));
8882
 
                return WERR_BADFID;
8883
 
        }
8884
 
 
8885
 
        if (!get_printer_snum(p, r->in.handle, &snum, NULL))
8886
 
                return WERR_BADFID;
8887
 
 
8888
 
        if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8889
 
                DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8890
 
                        "printer properties change denied by handle\n"));
8891
 
                return WERR_ACCESS_DENIED;
8892
 
        }
8893
 
 
8894
 
        if (!r->in.value_name || !r->in.key_name) {
8895
 
                return WERR_NOMEM;
8896
 
        }
8897
 
 
8898
 
        status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8899
 
        if (!W_ERROR_IS_OK(status))
8900
 
                return status;
8901
 
 
8902
 
        status = delete_printer_dataex( printer, r->in.key_name, r->in.value_name );
8903
 
 
8904
 
        if ( W_ERROR_IS_OK(status) )
8905
 
                mod_a_printer( printer, 2 );
8906
 
 
8907
 
        free_a_printer(&printer, 2);
8908
 
 
8909
 
        return status;
8910
 
}
8911
 
 
8912
 
/****************************************************************
8913
 
 _spoolss_EnumPrinterKey
8914
 
****************************************************************/
8915
 
 
8916
 
WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
8917
 
                               struct spoolss_EnumPrinterKey *r)
8918
 
{
8919
 
        fstring         *keynames = NULL;
8920
 
        int             num_keys;
8921
 
        Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
8922
 
        NT_PRINTER_DATA *data;
8923
 
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
8924
 
        int             snum = 0;
8925
 
        WERROR          result = WERR_BADFILE;
8926
 
        int i;
8927
 
        const char **array = NULL;
8928
 
        DATA_BLOB blob;
8929
 
 
8930
 
        DEBUG(4,("_spoolss_EnumPrinterKey\n"));
8931
 
 
8932
 
        if (!Printer) {
8933
 
                DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
8934
 
                        OUR_HANDLE(r->in.handle)));
8935
 
                return WERR_BADFID;
8936
 
        }
8937
 
 
8938
 
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8939
 
                return WERR_BADFID;
8940
 
        }
8941
 
 
8942
 
        result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8943
 
        if (!W_ERROR_IS_OK(result)) {
8944
 
                return result;
8945
 
        }
8946
 
 
8947
 
        /* get the list of subkey names */
8948
 
 
8949
 
        data = printer->info_2->data;
8950
 
 
8951
 
        num_keys = get_printer_subkeys(data, r->in.key_name, &keynames);
8952
 
        if (num_keys == -1) {
8953
 
                result = WERR_BADFILE;
8954
 
                goto done;
8955
 
        }
8956
 
 
8957
 
        array = talloc_zero_array(r->out.key_buffer, const char *, num_keys + 2);
8958
 
        if (!array) {
8959
 
                result = WERR_NOMEM;
8960
 
                goto done;
8961
 
        }
8962
 
 
8963
 
        if (!num_keys) {
8964
 
                array[0] = talloc_strdup(array, "");
8965
 
                if (!array[0]) {
8966
 
                        result = WERR_NOMEM;
8967
 
                        goto done;
8968
 
                }
8969
 
        }
8970
 
 
8971
 
        for (i=0; i < num_keys; i++) {
8972
 
 
8973
 
                DEBUG(10,("_spoolss_EnumPrinterKey: adding keyname: %s\n",
8974
 
                        keynames[i]));
8975
 
 
8976
 
                array[i] = talloc_strdup(array, keynames[i]);
8977
 
                if (!array[i]) {
8978
 
                        result = WERR_NOMEM;
8979
 
                        goto done;
8980
 
                }
8981
 
        }
8982
 
 
8983
 
        if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
8984
 
                result = WERR_NOMEM;
8985
 
                goto done;
8986
 
        }
8987
 
 
8988
 
        *r->out._ndr_size = r->in.offered / 2;
8989
 
        *r->out.needed = blob.length;
8990
 
 
8991
 
        if (r->in.offered < *r->out.needed) {
8992
 
                result = WERR_MORE_DATA;
8993
 
        } else {
8994
 
                result = WERR_OK;
8995
 
                r->out.key_buffer->string_array = array;
8996
 
        }
8997
 
 
8998
 
 done:
8999
 
        if (!W_ERROR_IS_OK(result)) {
9000
 
                TALLOC_FREE(array);
9001
 
                if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
9002
 
                        *r->out.needed = 0;
9003
 
                }
9004
 
        }
9005
 
 
9006
 
        free_a_printer(&printer, 2);
9007
 
        SAFE_FREE(keynames);
9008
 
 
9009
 
        return result;
9010
 
}
9011
 
 
9012
 
/****************************************************************
9013
 
 _spoolss_DeletePrinterKey
9014
 
****************************************************************/
9015
 
 
9016
 
WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
9017
 
                                 struct spoolss_DeletePrinterKey *r)
9018
 
{
9019
 
        Printer_entry           *Printer = find_printer_index_by_hnd(p, r->in.handle);
9020
 
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
9021
 
        int                     snum=0;
9022
 
        WERROR                  status;
9023
 
 
9024
 
        DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9025
 
 
9026
 
        if (!Printer) {
9027
 
                DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9028
 
                        OUR_HANDLE(r->in.handle)));
9029
 
                return WERR_BADFID;
9030
 
        }
9031
 
 
9032
 
        /* if keyname == NULL, return error */
9033
 
 
9034
 
        if ( !r->in.key_name )
9035
 
                return WERR_INVALID_PARAM;
9036
 
 
9037
 
        if (!get_printer_snum(p, r->in.handle, &snum, NULL))
9038
 
                return WERR_BADFID;
9039
 
 
9040
 
        if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9041
 
                DEBUG(3, ("_spoolss_DeletePrinterKey: "
9042
 
                        "printer properties change denied by handle\n"));
9043
 
                return WERR_ACCESS_DENIED;
9044
 
        }
9045
 
 
9046
 
        status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9047
 
        if (!W_ERROR_IS_OK(status))
9048
 
                return status;
9049
 
 
9050
 
        /* delete the key and all subneys */
9051
 
 
9052
 
        status = delete_all_printer_data( printer->info_2, r->in.key_name );
9053
 
 
9054
 
        if ( W_ERROR_IS_OK(status) )
9055
 
                status = mod_a_printer(printer, 2);
9056
 
 
9057
 
        free_a_printer( &printer, 2 );
9058
 
 
9059
 
        return status;
9060
 
}
9061
 
 
9062
 
/****************************************************************
9063
 
****************************************************************/
9064
 
 
9065
 
static WERROR registry_value_to_printer_enum_value(TALLOC_CTX *mem_ctx,
9066
 
                                                   struct regval_blob *v,
9067
 
                                                   struct spoolss_PrinterEnumValues *r)
9068
 
{
9069
 
        r->data = TALLOC_ZERO_P(mem_ctx, DATA_BLOB);
9070
 
        W_ERROR_HAVE_NO_MEMORY(r->data);
9071
 
 
9072
 
        r->value_name   = talloc_strdup(mem_ctx, regval_name(v));
9073
 
        W_ERROR_HAVE_NO_MEMORY(r->value_name);
9074
 
 
9075
 
        r->type         = regval_type(v);
9076
 
        r->data_length  = regval_size(v);
9077
 
 
9078
 
        if (r->data_length) {
9079
 
                *r->data = data_blob_talloc(r->data, regval_data_p(v), regval_size(v));
9080
 
        }
9081
 
 
9082
 
        return WERR_OK;
9083
 
}
9084
 
 
9085
 
/****************************************************************
9086
 
 _spoolss_EnumPrinterDataEx
9087
 
****************************************************************/
9088
 
 
9089
 
WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
9090
 
                                  struct spoolss_EnumPrinterDataEx *r)
9091
 
{
9092
 
        uint32_t        count = 0;
9093
 
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
9094
 
        struct spoolss_PrinterEnumValues *info = NULL;
9095
 
        NT_PRINTER_DATA         *p_data;
9096
 
        Printer_entry   *Printer = find_printer_index_by_hnd(p, r->in.handle);
9097
 
        int             snum;
9098
 
        WERROR          result;
9099
 
        int             key_index;
9100
 
        int             i;
9101
 
 
9102
 
        DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
9103
 
 
9104
 
        *r->out.count = 0;
9105
 
        *r->out.needed = 0;
9106
 
        *r->out.info = NULL;
9107
 
 
9108
 
        if (!Printer) {
9109
 
                DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
9110
 
                        OUR_HANDLE(r->in.handle)));
9111
 
                return WERR_BADFID;
9112
 
        }
9113
 
 
9114
 
        /*
9115
 
         * first check for a keyname of NULL or "".  Win2k seems to send
9116
 
         * this a lot and we should send back WERR_INVALID_PARAM
9117
 
         * no need to spend time looking up the printer in this case.
9118
 
         * --jerry
9119
 
         */
9120
 
 
9121
 
        if (!strlen(r->in.key_name)) {
9122
 
                result = WERR_INVALID_PARAM;
9123
 
                goto done;
9124
 
        }
9125
 
 
9126
 
        /* get the printer off of disk */
9127
 
 
9128
 
        if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9129
 
                return WERR_BADFID;
9130
 
        }
9131
 
 
9132
 
        ZERO_STRUCT(printer);
9133
 
        result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9134
 
        if (!W_ERROR_IS_OK(result)) {
9135
 
                return result;
9136
 
        }
9137
 
 
9138
 
        /* now look for a match on the key name */
9139
 
 
9140
 
        p_data = printer->info_2->data;
9141
 
 
9142
 
        key_index = lookup_printerkey(p_data, r->in.key_name);
9143
 
        if (key_index == -1) {
9144
 
                DEBUG(10,("_spoolss_EnumPrinterDataEx: Unknown keyname [%s]\n",
9145
 
                        r->in.key_name));
9146
 
                result = WERR_INVALID_PARAM;
9147
 
                goto done;
9148
 
        }
9149
 
 
9150
 
        /* allocate the memory for the array of pointers -- if necessary */
9151
 
 
9152
 
        count = regval_ctr_numvals(p_data->keys[key_index].values);
9153
 
        if (!count) {
9154
 
                result = WERR_OK; /* ??? */
9155
 
                goto done;
9156
 
        }
9157
 
 
9158
 
        info = TALLOC_ZERO_ARRAY(p->mem_ctx,
9159
 
                                 struct spoolss_PrinterEnumValues,
9160
 
                                 count);
9161
 
        if (!info) {
9162
 
                DEBUG(0,("_spoolss_EnumPrinterDataEx: talloc() failed\n"));
9163
 
                result = WERR_NOMEM;
9164
 
                goto done;
9165
 
        }
9166
 
 
9167
 
        /*
9168
 
         * loop through all params and build the array to pass
9169
 
         * back to the  client
9170
 
         */
9171
 
 
9172
 
        for (i=0; i < count; i++) {
9173
 
 
9174
 
                struct regval_blob      *val;
9175
 
 
9176
 
                /* lookup the registry value */
9177
 
 
9178
 
                val = regval_ctr_specific_value(p_data->keys[key_index].values, i);
9179
 
 
9180
 
                DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val)));
9181
 
 
9182
 
                /* copy the data */
9183
 
 
9184
 
                result = registry_value_to_printer_enum_value(info, val, &info[i]);
9185
 
                if (!W_ERROR_IS_OK(result)) {
9186
 
                        goto done;
9187
 
                }
9188
 
        }
9189
 
 
9190
 
#if 0 /* FIXME - gd */
9191
 
        /* housekeeping information in the reply */
9192
 
 
9193
 
        /* Fix from Martin Zielinski <mz@seh.de> - ensure
9194
 
         * the hand marshalled container size is a multiple
9195
 
         * of 4 bytes for RPC alignment.
9196
 
         */
9197
 
 
9198
 
        if (needed % 4) {
9199
 
                needed += 4-(needed % 4);
9200
 
        }
9201
 
#endif
9202
 
        *r->out.count   = count;
9203
 
        *r->out.info    = info;
9204
 
 
9205
 
 done:
9206
 
 
9207
 
        if (printer) {
9208
 
                free_a_printer(&printer, 2);
9209
 
        }
9210
 
 
9211
 
        if (!W_ERROR_IS_OK(result)) {
9212
 
                return result;
9213
 
        }
9214
 
 
9215
 
        *r->out.needed  = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
9216
 
                                               spoolss_EnumPrinterDataEx, NULL,
9217
 
                                               *r->out.info,
9218
 
                                               *r->out.count);
9219
 
        *r->out.info    = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
9220
 
        *r->out.count   = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
9221
 
 
9222
 
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
9223
 
}
9224
 
 
9225
 
/****************************************************************************
9226
 
****************************************************************************/
9227
 
 
9228
 
static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9229
 
                                                 const char *servername,
9230
 
                                                 const char *environment,
9231
 
                                                 struct spoolss_PrintProcessorDirectoryInfo1 *r)
9232
 
{
9233
 
        WERROR werr;
9234
 
        char *path = NULL;
9235
 
 
9236
 
        werr = compose_spoolss_server_path(mem_ctx,
9237
 
                                           servername,
9238
 
                                           environment,
9239
 
                                           SPOOLSS_PRTPROCS_PATH,
9240
 
                                           &path);
9241
 
        if (!W_ERROR_IS_OK(werr)) {
9242
 
                return werr;
9243
 
        }
9244
 
 
9245
 
        DEBUG(4,("print processor directory: [%s]\n", path));
9246
 
 
9247
 
        r->directory_name = path;
9248
 
 
9249
 
        return WERR_OK;
9250
 
}
9251
 
 
9252
 
/****************************************************************
9253
 
 _spoolss_GetPrintProcessorDirectory
9254
 
****************************************************************/
9255
 
 
9256
 
WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
9257
 
                                           struct spoolss_GetPrintProcessorDirectory *r)
9258
 
{
9259
 
        WERROR result;
9260
 
 
9261
 
        /* that's an [in out] buffer */
9262
 
 
9263
 
        if (!r->in.buffer && (r->in.offered != 0)) {
9264
 
                return WERR_INVALID_PARAM;
9265
 
        }
9266
 
 
9267
 
        DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9268
 
                r->in.level));
9269
 
 
9270
 
        *r->out.needed = 0;
9271
 
 
9272
 
        /* r->in.level is ignored */
9273
 
 
9274
 
        /* We always should reply with a local print processor directory so that
9275
 
         * users are not forced to have a [prnproc$] share on the Samba spoolss
9276
 
         * server - Guenther */
9277
 
 
9278
 
        result = getprintprocessordirectory_level_1(p->mem_ctx,
9279
 
                                                    NULL, /* r->in.server */
9280
 
                                                    r->in.environment,
9281
 
                                                    &r->out.info->info1);
9282
 
        if (!W_ERROR_IS_OK(result)) {
9283
 
                TALLOC_FREE(r->out.info);
9284
 
                return result;
9285
 
        }
9286
 
 
9287
 
        *r->out.needed  = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo, NULL,
9288
 
                                               r->out.info, r->in.level);
9289
 
        r->out.info     = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9290
 
 
9291
 
        return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9292
 
}
9293
 
 
9294
 
/*******************************************************************
9295
 
 ********************************************************************/
9296
 
 
9297
 
static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9298
 
                               const char *dllname)
9299
 
{
9300
 
        enum ndr_err_code ndr_err;
9301
 
        struct spoolss_MonitorUi ui;
9302
 
 
9303
 
        ui.dll_name = dllname;
9304
 
 
9305
 
        ndr_err = ndr_push_struct_blob(buf, mem_ctx, NULL, &ui,
9306
 
                       (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9307
 
        if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9308
 
                NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9309
 
        }
9310
 
        return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9311
 
}
9312
 
 
9313
 
/*******************************************************************
9314
 
 Streams the monitor UI DLL name in UNICODE
9315
 
*******************************************************************/
9316
 
 
9317
 
static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9318
 
                               NT_USER_TOKEN *token, DATA_BLOB *in,
9319
 
                               DATA_BLOB *out, uint32_t *needed)
9320
 
{
9321
 
        const char *dllname = "tcpmonui.dll";
9322
 
 
9323
 
        *needed = (strlen(dllname)+1) * 2;
9324
 
 
9325
 
        if (out->length < *needed) {
9326
 
                return WERR_INSUFFICIENT_BUFFER;
9327
 
        }
9328
 
 
9329
 
        if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9330
 
                return WERR_NOMEM;
9331
 
        }
9332
 
 
9333
 
        return WERR_OK;
9334
 
}
9335
 
 
9336
 
/*******************************************************************
9337
 
 ********************************************************************/
9338
 
 
9339
 
static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9340
 
                             struct spoolss_PortData1 *port1,
9341
 
                             const DATA_BLOB *buf)
9342
 
{
9343
 
        enum ndr_err_code ndr_err;
9344
 
        ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port1,
9345
 
                       (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9346
 
        if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9347
 
                NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9348
 
        }
9349
 
        return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9350
 
}
9351
 
 
9352
 
/*******************************************************************
9353
 
 ********************************************************************/
9354
 
 
9355
 
static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9356
 
                             struct spoolss_PortData2 *port2,
9357
 
                             const DATA_BLOB *buf)
9358
 
{
9359
 
        enum ndr_err_code ndr_err;
9360
 
        ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port2,
9361
 
                       (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9362
 
        if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9363
 
                NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9364
 
        }
9365
 
        return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9366
 
}
9367
 
 
9368
 
/*******************************************************************
9369
 
 Create a new TCP/IP port
9370
 
*******************************************************************/
9371
 
 
9372
 
static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9373
 
                             NT_USER_TOKEN *token, DATA_BLOB *in,
9374
 
                             DATA_BLOB *out, uint32_t *needed)
9375
 
{
9376
 
        struct spoolss_PortData1 port1;
9377
 
        struct spoolss_PortData2 port2;
9378
 
        char *device_uri = NULL;
9379
 
        uint32_t version;
9380
 
 
9381
 
        const char *portname;
9382
 
        const char *hostaddress;
9383
 
        const char *queue;
9384
 
        uint32_t port_number;
9385
 
        uint32_t protocol;
9386
 
 
9387
 
        /* peek for spoolss_PortData version */
9388
 
 
9389
 
        if (!in || (in->length < (128 + 4))) {
9390
 
                return WERR_GENERAL_FAILURE;
9391
 
        }
9392
 
 
9393
 
        version = IVAL(in->data, 128);
9394
 
 
9395
 
        switch (version) {
9396
 
                case 1:
9397
 
                        ZERO_STRUCT(port1);
9398
 
 
9399
 
                        if (!pull_port_data_1(mem_ctx, &port1, in)) {
9400
 
                                return WERR_NOMEM;
9401
 
                        }
9402
 
 
9403
 
                        portname        = port1.portname;
9404
 
                        hostaddress     = port1.hostaddress;
9405
 
                        queue           = port1.queue;
9406
 
                        protocol        = port1.protocol;
9407
 
                        port_number     = port1.port_number;
9408
 
 
9409
 
                        break;
9410
 
                case 2:
9411
 
                        ZERO_STRUCT(port2);
9412
 
 
9413
 
                        if (!pull_port_data_2(mem_ctx, &port2, in)) {
9414
 
                                return WERR_NOMEM;
9415
 
                        }
9416
 
 
9417
 
                        portname        = port2.portname;
9418
 
                        hostaddress     = port2.hostaddress;
9419
 
                        queue           = port2.queue;
9420
 
                        protocol        = port2.protocol;
9421
 
                        port_number     = port2.port_number;
9422
 
 
9423
 
                        break;
9424
 
                default:
9425
 
                        DEBUG(1,("xcvtcp_addport: "
9426
 
                                "unknown version of port_data: %d\n", version));
9427
 
                        return WERR_UNKNOWN_PORT;
9428
 
        }
9429
 
 
9430
 
        /* create the device URI and call the add_port_hook() */
9431
 
 
9432
 
        switch (protocol) {
9433
 
        case PROTOCOL_RAWTCP_TYPE:
9434
 
                device_uri = talloc_asprintf(mem_ctx,
9435
 
                                "socket://%s:%d/", hostaddress,
9436
 
                                port_number);
9437
 
                break;
9438
 
 
9439
 
        case PROTOCOL_LPR_TYPE:
9440
 
                device_uri = talloc_asprintf(mem_ctx,
9441
 
                        "lpr://%s/%s", hostaddress, queue );
9442
 
                break;
9443
 
 
9444
 
        default:
9445
 
                return WERR_UNKNOWN_PORT;
9446
 
        }
9447
 
 
9448
 
        if (!device_uri) {
9449
 
                return WERR_NOMEM;
9450
 
        }
9451
 
 
9452
 
        return add_port_hook(mem_ctx, token, portname, device_uri);
9453
 
}
9454
 
 
9455
 
/*******************************************************************
9456
 
*******************************************************************/
9457
 
 
9458
 
struct xcv_api_table xcvtcp_cmds[] = {
9459
 
        { "MonitorUI",  xcvtcp_monitorui },
9460
 
        { "AddPort",    xcvtcp_addport},
9461
 
        { NULL,         NULL }
9462
 
};
9463
 
 
9464
 
static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9465
 
                                     NT_USER_TOKEN *token, const char *command,
9466
 
                                     DATA_BLOB *inbuf,
9467
 
                                     DATA_BLOB *outbuf,
9468
 
                                     uint32_t *needed )
9469
 
{
9470
 
        int i;
9471
 
 
9472
 
        DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9473
 
 
9474
 
        for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9475
 
                if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9476
 
                        return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9477
 
        }
9478
 
 
9479
 
        return WERR_BADFUNC;
9480
 
}
9481
 
 
9482
 
/*******************************************************************
9483
 
*******************************************************************/
9484
 
#if 0   /* don't support management using the "Local Port" monitor */
9485
 
 
9486
 
static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9487
 
                                 NT_USER_TOKEN *token, DATA_BLOB *in,
9488
 
                                 DATA_BLOB *out, uint32_t *needed)
9489
 
{
9490
 
        const char *dllname = "localui.dll";
9491
 
 
9492
 
        *needed = (strlen(dllname)+1) * 2;
9493
 
 
9494
 
        if (out->length < *needed) {
9495
 
                return WERR_INSUFFICIENT_BUFFER;
9496
 
        }
9497
 
 
9498
 
        if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9499
 
                return WERR_NOMEM;
9500
 
        }
9501
 
 
9502
 
        return WERR_OK;
9503
 
}
9504
 
 
9505
 
/*******************************************************************
9506
 
*******************************************************************/
9507
 
 
9508
 
struct xcv_api_table xcvlocal_cmds[] = {
9509
 
        { "MonitorUI",  xcvlocal_monitorui },
9510
 
        { NULL,         NULL }
9511
 
};
9512
 
#else
9513
 
struct xcv_api_table xcvlocal_cmds[] = {
9514
 
        { NULL,         NULL }
9515
 
};
9516
 
#endif
9517
 
 
9518
 
 
9519
 
 
9520
 
/*******************************************************************
9521
 
*******************************************************************/
9522
 
 
9523
 
static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9524
 
                                       NT_USER_TOKEN *token, const char *command,
9525
 
                                       DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9526
 
                                       uint32_t *needed)
9527
 
{
9528
 
        int i;
9529
 
 
9530
 
        DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9531
 
 
9532
 
        for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9533
 
                if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9534
 
                        return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9535
 
        }
9536
 
        return WERR_BADFUNC;
9537
 
}
9538
 
 
9539
 
/****************************************************************
9540
 
 _spoolss_XcvData
9541
 
****************************************************************/
9542
 
 
9543
 
WERROR _spoolss_XcvData(pipes_struct *p,
9544
 
                        struct spoolss_XcvData *r)
9545
 
{
9546
 
        Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9547
 
        DATA_BLOB out_data = data_blob_null;
9548
 
        WERROR werror;
9549
 
 
9550
 
        if (!Printer) {
9551
 
                DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9552
 
                        OUR_HANDLE(r->in.handle)));
9553
 
                return WERR_BADFID;
9554
 
        }
9555
 
 
9556
 
        /* Has to be a handle to the TCP/IP port monitor */
9557
 
 
9558
 
        if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9559
 
                DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9560
 
                return WERR_BADFID;
9561
 
        }
9562
 
 
9563
 
        /* requires administrative access to the server */
9564
 
 
9565
 
        if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9566
 
                DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9567
 
                return WERR_ACCESS_DENIED;
9568
 
        }
9569
 
 
9570
 
        /* Allocate the outgoing buffer */
9571
 
 
9572
 
        if (r->in.out_data_size) {
9573
 
                out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9574
 
                if (out_data.data == NULL) {
9575
 
                        return WERR_NOMEM;
9576
 
                }
9577
 
        }
9578
 
 
9579
 
        switch ( Printer->printer_type ) {
9580
 
        case SPLHND_PORTMON_TCP:
9581
 
                werror = process_xcvtcp_command(p->mem_ctx,
9582
 
                                                p->server_info->ptok,
9583
 
                                                r->in.function_name,
9584
 
                                                &r->in.in_data, &out_data,
9585
 
                                                r->out.needed);
9586
 
                break;
9587
 
        case SPLHND_PORTMON_LOCAL:
9588
 
                werror = process_xcvlocal_command(p->mem_ctx,
9589
 
                                                  p->server_info->ptok,
9590
 
                                                  r->in.function_name,
9591
 
                                                  &r->in.in_data, &out_data,
9592
 
                                                  r->out.needed);
9593
 
                break;
9594
 
        default:
9595
 
                werror = WERR_INVALID_PRINT_MONITOR;
9596
 
        }
9597
 
 
9598
 
        if (!W_ERROR_IS_OK(werror)) {
9599
 
                return werror;
9600
 
        }
9601
 
 
9602
 
        *r->out.status_code = 0;
9603
 
 
9604
 
        if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9605
 
                memcpy(r->out.out_data, out_data.data,
9606
 
                        MIN(r->in.out_data_size, out_data.length));
9607
 
        }
9608
 
 
9609
 
        return WERR_OK;
9610
 
}
9611
 
 
9612
 
/****************************************************************
9613
 
 _spoolss_AddPrintProcessor
9614
 
****************************************************************/
9615
 
 
9616
 
WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
9617
 
                                  struct spoolss_AddPrintProcessor *r)
9618
 
{
9619
 
        /* for now, just indicate success and ignore the add.  We'll
9620
 
           automatically set the winprint processor for printer
9621
 
           entries later.  Used to debug the LexMark Optra S 1855 PCL
9622
 
           driver --jerry */
9623
 
 
9624
 
        return WERR_OK;
9625
 
}
9626
 
 
9627
 
/****************************************************************
9628
 
 _spoolss_AddPort
9629
 
****************************************************************/
9630
 
 
9631
 
WERROR _spoolss_AddPort(pipes_struct *p,
9632
 
                        struct spoolss_AddPort *r)
9633
 
{
9634
 
        /* do what w2k3 does */
9635
 
 
9636
 
        return WERR_NOT_SUPPORTED;
9637
 
}
9638
 
 
9639
 
/****************************************************************
9640
 
 _spoolss_GetPrinterDriver
9641
 
****************************************************************/
9642
 
 
9643
 
WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
9644
 
                                 struct spoolss_GetPrinterDriver *r)
9645
 
{
9646
 
        p->rng_fault_state = true;
9647
 
        return WERR_NOT_SUPPORTED;
9648
 
}
9649
 
 
9650
 
/****************************************************************
9651
 
 _spoolss_ReadPrinter
9652
 
****************************************************************/
9653
 
 
9654
 
WERROR _spoolss_ReadPrinter(pipes_struct *p,
9655
 
                            struct spoolss_ReadPrinter *r)
9656
 
{
9657
 
        p->rng_fault_state = true;
9658
 
        return WERR_NOT_SUPPORTED;
9659
 
}
9660
 
 
9661
 
/****************************************************************
9662
 
 _spoolss_WaitForPrinterChange
9663
 
****************************************************************/
9664
 
 
9665
 
WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
9666
 
                                     struct spoolss_WaitForPrinterChange *r)
9667
 
{
9668
 
        p->rng_fault_state = true;
9669
 
        return WERR_NOT_SUPPORTED;
9670
 
}
9671
 
 
9672
 
/****************************************************************
9673
 
 _spoolss_ConfigurePort
9674
 
****************************************************************/
9675
 
 
9676
 
WERROR _spoolss_ConfigurePort(pipes_struct *p,
9677
 
                              struct spoolss_ConfigurePort *r)
9678
 
{
9679
 
        p->rng_fault_state = true;
9680
 
        return WERR_NOT_SUPPORTED;
9681
 
}
9682
 
 
9683
 
/****************************************************************
9684
 
 _spoolss_DeletePort
9685
 
****************************************************************/
9686
 
 
9687
 
WERROR _spoolss_DeletePort(pipes_struct *p,
9688
 
                           struct spoolss_DeletePort *r)
9689
 
{
9690
 
        p->rng_fault_state = true;
9691
 
        return WERR_NOT_SUPPORTED;
9692
 
}
9693
 
 
9694
 
/****************************************************************
9695
 
 _spoolss_CreatePrinterIC
9696
 
****************************************************************/
9697
 
 
9698
 
WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
9699
 
                                struct spoolss_CreatePrinterIC *r)
9700
 
{
9701
 
        p->rng_fault_state = true;
9702
 
        return WERR_NOT_SUPPORTED;
9703
 
}
9704
 
 
9705
 
/****************************************************************
9706
 
 _spoolss_PlayGDIScriptOnPrinterIC
9707
 
****************************************************************/
9708
 
 
9709
 
WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
9710
 
                                         struct spoolss_PlayGDIScriptOnPrinterIC *r)
9711
 
{
9712
 
        p->rng_fault_state = true;
9713
 
        return WERR_NOT_SUPPORTED;
9714
 
}
9715
 
 
9716
 
/****************************************************************
9717
 
 _spoolss_DeletePrinterIC
9718
 
****************************************************************/
9719
 
 
9720
 
WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
9721
 
                                struct spoolss_DeletePrinterIC *r)
9722
 
{
9723
 
        p->rng_fault_state = true;
9724
 
        return WERR_NOT_SUPPORTED;
9725
 
}
9726
 
 
9727
 
/****************************************************************
9728
 
 _spoolss_AddPrinterConnection
9729
 
****************************************************************/
9730
 
 
9731
 
WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
9732
 
                                     struct spoolss_AddPrinterConnection *r)
9733
 
{
9734
 
        p->rng_fault_state = true;
9735
 
        return WERR_NOT_SUPPORTED;
9736
 
}
9737
 
 
9738
 
/****************************************************************
9739
 
 _spoolss_DeletePrinterConnection
9740
 
****************************************************************/
9741
 
 
9742
 
WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
9743
 
                                        struct spoolss_DeletePrinterConnection *r)
9744
 
{
9745
 
        p->rng_fault_state = true;
9746
 
        return WERR_NOT_SUPPORTED;
9747
 
}
9748
 
 
9749
 
/****************************************************************
9750
 
 _spoolss_PrinterMessageBox
9751
 
****************************************************************/
9752
 
 
9753
 
WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
9754
 
                                  struct spoolss_PrinterMessageBox *r)
9755
 
{
9756
 
        p->rng_fault_state = true;
9757
 
        return WERR_NOT_SUPPORTED;
9758
 
}
9759
 
 
9760
 
/****************************************************************
9761
 
 _spoolss_AddMonitor
9762
 
****************************************************************/
9763
 
 
9764
 
WERROR _spoolss_AddMonitor(pipes_struct *p,
9765
 
                           struct spoolss_AddMonitor *r)
9766
 
{
9767
 
        p->rng_fault_state = true;
9768
 
        return WERR_NOT_SUPPORTED;
9769
 
}
9770
 
 
9771
 
/****************************************************************
9772
 
 _spoolss_DeleteMonitor
9773
 
****************************************************************/
9774
 
 
9775
 
WERROR _spoolss_DeleteMonitor(pipes_struct *p,
9776
 
                              struct spoolss_DeleteMonitor *r)
9777
 
{
9778
 
        p->rng_fault_state = true;
9779
 
        return WERR_NOT_SUPPORTED;
9780
 
}
9781
 
 
9782
 
/****************************************************************
9783
 
 _spoolss_DeletePrintProcessor
9784
 
****************************************************************/
9785
 
 
9786
 
WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
9787
 
                                     struct spoolss_DeletePrintProcessor *r)
9788
 
{
9789
 
        p->rng_fault_state = true;
9790
 
        return WERR_NOT_SUPPORTED;
9791
 
}
9792
 
 
9793
 
/****************************************************************
9794
 
 _spoolss_AddPrintProvidor
9795
 
****************************************************************/
9796
 
 
9797
 
WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
9798
 
                                 struct spoolss_AddPrintProvidor *r)
9799
 
{
9800
 
        p->rng_fault_state = true;
9801
 
        return WERR_NOT_SUPPORTED;
9802
 
}
9803
 
 
9804
 
/****************************************************************
9805
 
 _spoolss_DeletePrintProvidor
9806
 
****************************************************************/
9807
 
 
9808
 
WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
9809
 
                                    struct spoolss_DeletePrintProvidor *r)
9810
 
{
9811
 
        p->rng_fault_state = true;
9812
 
        return WERR_NOT_SUPPORTED;
9813
 
}
9814
 
 
9815
 
/****************************************************************
9816
 
 _spoolss_FindFirstPrinterChangeNotification
9817
 
****************************************************************/
9818
 
 
9819
 
WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
9820
 
                                                   struct spoolss_FindFirstPrinterChangeNotification *r)
9821
 
{
9822
 
        p->rng_fault_state = true;
9823
 
        return WERR_NOT_SUPPORTED;
9824
 
}
9825
 
 
9826
 
/****************************************************************
9827
 
 _spoolss_FindNextPrinterChangeNotification
9828
 
****************************************************************/
9829
 
 
9830
 
WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
9831
 
                                                  struct spoolss_FindNextPrinterChangeNotification *r)
9832
 
{
9833
 
        p->rng_fault_state = true;
9834
 
        return WERR_NOT_SUPPORTED;
9835
 
}
9836
 
 
9837
 
/****************************************************************
9838
 
 _spoolss_RouterFindFirstPrinterChangeNotificationOld
9839
 
****************************************************************/
9840
 
 
9841
 
WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
9842
 
                                                            struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9843
 
{
9844
 
        p->rng_fault_state = true;
9845
 
        return WERR_NOT_SUPPORTED;
9846
 
}
9847
 
 
9848
 
/****************************************************************
9849
 
 _spoolss_ReplyOpenPrinter
9850
 
****************************************************************/
9851
 
 
9852
 
WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
9853
 
                                 struct spoolss_ReplyOpenPrinter *r)
9854
 
{
9855
 
        p->rng_fault_state = true;
9856
 
        return WERR_NOT_SUPPORTED;
9857
 
}
9858
 
 
9859
 
/****************************************************************
9860
 
 _spoolss_RouterReplyPrinter
9861
 
****************************************************************/
9862
 
 
9863
 
WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
9864
 
                                   struct spoolss_RouterReplyPrinter *r)
9865
 
{
9866
 
        p->rng_fault_state = true;
9867
 
        return WERR_NOT_SUPPORTED;
9868
 
}
9869
 
 
9870
 
/****************************************************************
9871
 
 _spoolss_ReplyClosePrinter
9872
 
****************************************************************/
9873
 
 
9874
 
WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
9875
 
                                  struct spoolss_ReplyClosePrinter *r)
9876
 
{
9877
 
        p->rng_fault_state = true;
9878
 
        return WERR_NOT_SUPPORTED;
9879
 
}
9880
 
 
9881
 
/****************************************************************
9882
 
 _spoolss_AddPortEx
9883
 
****************************************************************/
9884
 
 
9885
 
WERROR _spoolss_AddPortEx(pipes_struct *p,
9886
 
                          struct spoolss_AddPortEx *r)
9887
 
{
9888
 
        p->rng_fault_state = true;
9889
 
        return WERR_NOT_SUPPORTED;
9890
 
}
9891
 
 
9892
 
/****************************************************************
9893
 
 _spoolss_RouterFindFirstPrinterChangeNotification
9894
 
****************************************************************/
9895
 
 
9896
 
WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
9897
 
                                                         struct spoolss_RouterFindFirstPrinterChangeNotification *r)
9898
 
{
9899
 
        p->rng_fault_state = true;
9900
 
        return WERR_NOT_SUPPORTED;
9901
 
}
9902
 
 
9903
 
/****************************************************************
9904
 
 _spoolss_SpoolerInit
9905
 
****************************************************************/
9906
 
 
9907
 
WERROR _spoolss_SpoolerInit(pipes_struct *p,
9908
 
                            struct spoolss_SpoolerInit *r)
9909
 
{
9910
 
        p->rng_fault_state = true;
9911
 
        return WERR_NOT_SUPPORTED;
9912
 
}
9913
 
 
9914
 
/****************************************************************
9915
 
 _spoolss_ResetPrinterEx
9916
 
****************************************************************/
9917
 
 
9918
 
WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
9919
 
                               struct spoolss_ResetPrinterEx *r)
9920
 
{
9921
 
        p->rng_fault_state = true;
9922
 
        return WERR_NOT_SUPPORTED;
9923
 
}
9924
 
 
9925
 
/****************************************************************
9926
 
 _spoolss_RouterReplyPrinterEx
9927
 
****************************************************************/
9928
 
 
9929
 
WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
9930
 
                                     struct spoolss_RouterReplyPrinterEx *r)
9931
 
{
9932
 
        p->rng_fault_state = true;
9933
 
        return WERR_NOT_SUPPORTED;
9934
 
}
9935
 
 
9936
 
/****************************************************************
9937
 
 _spoolss_44
9938
 
****************************************************************/
9939
 
 
9940
 
WERROR _spoolss_44(pipes_struct *p,
9941
 
                   struct spoolss_44 *r)
9942
 
{
9943
 
        p->rng_fault_state = true;
9944
 
        return WERR_NOT_SUPPORTED;
9945
 
}
9946
 
 
9947
 
/****************************************************************
9948
 
 _spoolss_47
9949
 
****************************************************************/
9950
 
 
9951
 
WERROR _spoolss_47(pipes_struct *p,
9952
 
                   struct spoolss_47 *r)
9953
 
{
9954
 
        p->rng_fault_state = true;
9955
 
        return WERR_NOT_SUPPORTED;
9956
 
}
9957
 
 
9958
 
/****************************************************************
9959
 
 _spoolss_4a
9960
 
****************************************************************/
9961
 
 
9962
 
WERROR _spoolss_4a(pipes_struct *p,
9963
 
                   struct spoolss_4a *r)
9964
 
{
9965
 
        p->rng_fault_state = true;
9966
 
        return WERR_NOT_SUPPORTED;
9967
 
}
9968
 
 
9969
 
/****************************************************************
9970
 
 _spoolss_4b
9971
 
****************************************************************/
9972
 
 
9973
 
WERROR _spoolss_4b(pipes_struct *p,
9974
 
                   struct spoolss_4b *r)
9975
 
{
9976
 
        p->rng_fault_state = true;
9977
 
        return WERR_NOT_SUPPORTED;
9978
 
}
9979
 
 
9980
 
/****************************************************************
9981
 
 _spoolss_4c
9982
 
****************************************************************/
9983
 
 
9984
 
WERROR _spoolss_4c(pipes_struct *p,
9985
 
                   struct spoolss_4c *r)
9986
 
{
9987
 
        p->rng_fault_state = true;
9988
 
        return WERR_NOT_SUPPORTED;
9989
 
}
9990
 
 
9991
 
/****************************************************************
9992
 
 _spoolss_53
9993
 
****************************************************************/
9994
 
 
9995
 
WERROR _spoolss_53(pipes_struct *p,
9996
 
                   struct spoolss_53 *r)
9997
 
{
9998
 
        p->rng_fault_state = true;
9999
 
        return WERR_NOT_SUPPORTED;
10000
 
}
10001
 
 
10002
 
/****************************************************************
10003
 
 _spoolss_55
10004
 
****************************************************************/
10005
 
 
10006
 
WERROR _spoolss_55(pipes_struct *p,
10007
 
                   struct spoolss_55 *r)
10008
 
{
10009
 
        p->rng_fault_state = true;
10010
 
        return WERR_NOT_SUPPORTED;
10011
 
}
10012
 
 
10013
 
/****************************************************************
10014
 
 _spoolss_56
10015
 
****************************************************************/
10016
 
 
10017
 
WERROR _spoolss_56(pipes_struct *p,
10018
 
                   struct spoolss_56 *r)
10019
 
{
10020
 
        p->rng_fault_state = true;
10021
 
        return WERR_NOT_SUPPORTED;
10022
 
}
10023
 
 
10024
 
/****************************************************************
10025
 
 _spoolss_57
10026
 
****************************************************************/
10027
 
 
10028
 
WERROR _spoolss_57(pipes_struct *p,
10029
 
                   struct spoolss_57 *r)
10030
 
{
10031
 
        p->rng_fault_state = true;
10032
 
        return WERR_NOT_SUPPORTED;
10033
 
}
10034
 
 
10035
 
/****************************************************************
10036
 
 _spoolss_5a
10037
 
****************************************************************/
10038
 
 
10039
 
WERROR _spoolss_5a(pipes_struct *p,
10040
 
                   struct spoolss_5a *r)
10041
 
{
10042
 
        p->rng_fault_state = true;
10043
 
        return WERR_NOT_SUPPORTED;
10044
 
}
10045
 
 
10046
 
/****************************************************************
10047
 
 _spoolss_5b
10048
 
****************************************************************/
10049
 
 
10050
 
WERROR _spoolss_5b(pipes_struct *p,
10051
 
                   struct spoolss_5b *r)
10052
 
{
10053
 
        p->rng_fault_state = true;
10054
 
        return WERR_NOT_SUPPORTED;
10055
 
}
10056
 
 
10057
 
/****************************************************************
10058
 
 _spoolss_5c
10059
 
****************************************************************/
10060
 
 
10061
 
WERROR _spoolss_5c(pipes_struct *p,
10062
 
                   struct spoolss_5c *r)
10063
 
{
10064
 
        p->rng_fault_state = true;
10065
 
        return WERR_NOT_SUPPORTED;
10066
 
}
10067
 
 
10068
 
/****************************************************************
10069
 
 _spoolss_5d
10070
 
****************************************************************/
10071
 
 
10072
 
WERROR _spoolss_5d(pipes_struct *p,
10073
 
                   struct spoolss_5d *r)
10074
 
{
10075
 
        p->rng_fault_state = true;
10076
 
        return WERR_NOT_SUPPORTED;
10077
 
}
10078
 
 
10079
 
/****************************************************************
10080
 
 _spoolss_5e
10081
 
****************************************************************/
10082
 
 
10083
 
WERROR _spoolss_5e(pipes_struct *p,
10084
 
                   struct spoolss_5e *r)
10085
 
{
10086
 
        p->rng_fault_state = true;
10087
 
        return WERR_NOT_SUPPORTED;
10088
 
}
10089
 
 
10090
 
/****************************************************************
10091
 
 _spoolss_5f
10092
 
****************************************************************/
10093
 
 
10094
 
WERROR _spoolss_5f(pipes_struct *p,
10095
 
                   struct spoolss_5f *r)
10096
 
{
10097
 
        p->rng_fault_state = true;
10098
 
        return WERR_NOT_SUPPORTED;
10099
 
}
10100
 
 
10101
 
/****************************************************************
10102
 
 _spoolss_60
10103
 
****************************************************************/
10104
 
 
10105
 
WERROR _spoolss_60(pipes_struct *p,
10106
 
                   struct spoolss_60 *r)
10107
 
{
10108
 
        p->rng_fault_state = true;
10109
 
        return WERR_NOT_SUPPORTED;
10110
 
}
10111
 
 
10112
 
/****************************************************************
10113
 
 _spoolss_61
10114
 
****************************************************************/
10115
 
 
10116
 
WERROR _spoolss_61(pipes_struct *p,
10117
 
                   struct spoolss_61 *r)
10118
 
{
10119
 
        p->rng_fault_state = true;
10120
 
        return WERR_NOT_SUPPORTED;
10121
 
}
10122
 
 
10123
 
/****************************************************************
10124
 
 _spoolss_62
10125
 
****************************************************************/
10126
 
 
10127
 
WERROR _spoolss_62(pipes_struct *p,
10128
 
                   struct spoolss_62 *r)
10129
 
{
10130
 
        p->rng_fault_state = true;
10131
 
        return WERR_NOT_SUPPORTED;
10132
 
}
10133
 
 
10134
 
/****************************************************************
10135
 
 _spoolss_63
10136
 
****************************************************************/
10137
 
 
10138
 
WERROR _spoolss_63(pipes_struct *p,
10139
 
                   struct spoolss_63 *r)
10140
 
{
10141
 
        p->rng_fault_state = true;
10142
 
        return WERR_NOT_SUPPORTED;
10143
 
}
10144
 
 
10145
 
/****************************************************************
10146
 
 _spoolss_64
10147
 
****************************************************************/
10148
 
 
10149
 
WERROR _spoolss_64(pipes_struct *p,
10150
 
                   struct spoolss_64 *r)
10151
 
{
10152
 
        p->rng_fault_state = true;
10153
 
        return WERR_NOT_SUPPORTED;
10154
 
}
10155
 
 
10156
 
/****************************************************************
10157
 
 _spoolss_65
10158
 
****************************************************************/
10159
 
 
10160
 
WERROR _spoolss_65(pipes_struct *p,
10161
 
                   struct spoolss_65 *r)
10162
 
{
10163
 
        p->rng_fault_state = true;
10164
 
        return WERR_NOT_SUPPORTED;
10165
 
}
10166
 
 
10167
 
/****************************************************************
10168
 
 _spoolss_GetCorePrinterDrivers
10169
 
****************************************************************/
10170
 
 
10171
 
WERROR _spoolss_GetCorePrinterDrivers(pipes_struct *p,
10172
 
                                      struct spoolss_GetCorePrinterDrivers *r)
10173
 
{
10174
 
        p->rng_fault_state = true;
10175
 
        return WERR_NOT_SUPPORTED;
10176
 
}
10177
 
 
10178
 
/****************************************************************
10179
 
 _spoolss_67
10180
 
****************************************************************/
10181
 
 
10182
 
WERROR _spoolss_67(pipes_struct *p,
10183
 
                   struct spoolss_67 *r)
10184
 
{
10185
 
        p->rng_fault_state = true;
10186
 
        return WERR_NOT_SUPPORTED;
10187
 
}
10188
 
 
10189
 
/****************************************************************
10190
 
 _spoolss_GetPrinterDriverPackagePath
10191
 
****************************************************************/
10192
 
 
10193
 
WERROR _spoolss_GetPrinterDriverPackagePath(pipes_struct *p,
10194
 
                                            struct spoolss_GetPrinterDriverPackagePath *r)
10195
 
{
10196
 
        p->rng_fault_state = true;
10197
 
        return WERR_NOT_SUPPORTED;
10198
 
}
10199
 
 
10200
 
/****************************************************************
10201
 
 _spoolss_69
10202
 
****************************************************************/
10203
 
 
10204
 
WERROR _spoolss_69(pipes_struct *p,
10205
 
                   struct spoolss_69 *r)
10206
 
{
10207
 
        p->rng_fault_state = true;
10208
 
        return WERR_NOT_SUPPORTED;
10209
 
}
10210
 
 
10211
 
/****************************************************************
10212
 
 _spoolss_6a
10213
 
****************************************************************/
10214
 
 
10215
 
WERROR _spoolss_6a(pipes_struct *p,
10216
 
                   struct spoolss_6a *r)
10217
 
{
10218
 
        p->rng_fault_state = true;
10219
 
        return WERR_NOT_SUPPORTED;
10220
 
}
10221
 
 
10222
 
/****************************************************************
10223
 
 _spoolss_6b
10224
 
****************************************************************/
10225
 
 
10226
 
WERROR _spoolss_6b(pipes_struct *p,
10227
 
                   struct spoolss_6b *r)
10228
 
{
10229
 
        p->rng_fault_state = true;
10230
 
        return WERR_NOT_SUPPORTED;
10231
 
}
10232
 
 
10233
 
/****************************************************************
10234
 
 _spoolss_6c
10235
 
****************************************************************/
10236
 
 
10237
 
WERROR _spoolss_6c(pipes_struct *p,
10238
 
                   struct spoolss_6c *r)
10239
 
{
10240
 
        p->rng_fault_state = true;
10241
 
        return WERR_NOT_SUPPORTED;
10242
 
}
10243
 
 
10244
 
/****************************************************************
10245
 
 _spoolss_6d
10246
 
****************************************************************/
10247
 
 
10248
 
WERROR _spoolss_6d(pipes_struct *p,
10249
 
                   struct spoolss_6d *r)
10250
 
{
10251
 
        p->rng_fault_state = true;
10252
 
        return WERR_NOT_SUPPORTED;
10253
 
}