~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/python/py_spoolss_printers.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
   Python wrappers for DCERPC/SMB client routines.
3
 
 
4
 
   Copyright (C) Tim Potter, 2002
5
 
   
6
 
   This program is free software; you can redistribute it and/or modify
7
 
   it under the terms of the GNU General Public License as published by
8
 
   the Free Software Foundation; either version 2 of the License, or
9
 
   (at your option) any later version.
10
 
   
11
 
   This program is distributed in the hope that it will be useful,
12
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
   GNU General Public License for more details.
15
 
   
16
 
   You should have received a copy of the GNU General Public License
17
 
   along with this program; if not, write to the Free Software
18
 
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
 
*/
20
 
 
21
 
#include "python/py_spoolss.h"
22
 
 
23
 
/* Open a printer */
24
 
 
25
 
PyObject *spoolss_openprinter(PyObject *self, PyObject *args, PyObject *kw)
26
 
{
27
 
        char *unc_name, *server, *errstr;
28
 
        TALLOC_CTX *mem_ctx = NULL;
29
 
        POLICY_HND hnd;
30
 
        WERROR werror;
31
 
        PyObject *result = NULL, *creds = NULL;
32
 
        static char *kwlist[] = { "printername", "creds", "access", NULL };
33
 
        uint32 desired_access = MAXIMUM_ALLOWED_ACCESS;
34
 
        struct cli_state *cli;
35
 
 
36
 
        if (!PyArg_ParseTupleAndKeywords(
37
 
                    args, kw, "s|Oi", kwlist, &unc_name, &creds,
38
 
                    &desired_access))
39
 
                return NULL;
40
 
 
41
 
        if (unc_name[0] != '\\' || unc_name[1] != '\\') {
42
 
                PyErr_SetString(PyExc_ValueError, "UNC name required");
43
 
                return NULL;
44
 
        }
45
 
 
46
 
        server = SMB_STRDUP(unc_name + 2);
47
 
 
48
 
        if (strchr(server, '\\')) {
49
 
                char *c = strchr(server, '\\');
50
 
                *c = 0;
51
 
        }
52
 
 
53
 
        if (creds && creds != Py_None && !PyDict_Check(creds)) {
54
 
                PyErr_SetString(PyExc_TypeError, 
55
 
                                "credentials must be dictionary or None");
56
 
                return NULL;
57
 
        }
58
 
 
59
 
        if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
60
 
                PyErr_SetString(spoolss_error, errstr);
61
 
                free(errstr);
62
 
                goto done;
63
 
        }
64
 
 
65
 
        if (!(mem_ctx = talloc_init("spoolss_openprinter"))) {
66
 
                PyErr_SetString(spoolss_error, 
67
 
                                "unable to init talloc context\n");
68
 
                goto done;
69
 
        }
70
 
 
71
 
        werror = rpccli_spoolss_open_printer_ex(
72
 
                cli->pipe_list, mem_ctx, unc_name, "", desired_access, server, 
73
 
                "", &hnd);
74
 
 
75
 
        if (!W_ERROR_IS_OK(werror)) {
76
 
                PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
77
 
                goto done;
78
 
        }
79
 
 
80
 
        result = new_spoolss_policy_hnd_object(cli, mem_ctx, &hnd);
81
 
 
82
 
 done:
83
 
        if (!result) {
84
 
                if (cli)
85
 
                        cli_shutdown(cli);
86
 
 
87
 
                if (mem_ctx)
88
 
                        talloc_destroy(mem_ctx);
89
 
        }
90
 
 
91
 
        SAFE_FREE(server);
92
 
 
93
 
        return result;
94
 
}
95
 
 
96
 
/* Close a printer */
97
 
 
98
 
PyObject *spoolss_closeprinter(PyObject *self, PyObject *args)
99
 
{
100
 
        PyObject *po;
101
 
        spoolss_policy_hnd_object *hnd;
102
 
        WERROR result;
103
 
 
104
 
        /* Parse parameters */
105
 
 
106
 
        if (!PyArg_ParseTuple(args, "O!", &spoolss_policy_hnd_type, &po))
107
 
                return NULL;
108
 
 
109
 
        hnd = (spoolss_policy_hnd_object *)po;
110
 
 
111
 
        /* Call rpc function */
112
 
 
113
 
        result = rpccli_spoolss_close_printer(
114
 
                hnd->cli, hnd->mem_ctx, &hnd->pol);
115
 
 
116
 
        /* Return value */
117
 
 
118
 
        Py_INCREF(Py_None);
119
 
        return Py_None; 
120
 
}
121
 
 
122
 
/* Fetch printer information */
123
 
 
124
 
PyObject *spoolss_hnd_getprinter(PyObject *self, PyObject *args, PyObject *kw)
125
 
{
126
 
        spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
127
 
        WERROR werror;
128
 
        PyObject *result = NULL;
129
 
        PRINTER_INFO_CTR ctr;
130
 
        int level = 1;
131
 
        static char *kwlist[] = {"level", NULL};
132
 
        
133
 
        /* Parse parameters */
134
 
 
135
 
        if (!PyArg_ParseTupleAndKeywords(args, kw, "|i", kwlist, &level))
136
 
                return NULL;
137
 
        
138
 
        ZERO_STRUCT(ctr);
139
 
 
140
 
        /* Call rpc function */
141
 
        
142
 
        werror = rpccli_spoolss_getprinter(
143
 
                hnd->cli, hnd->mem_ctx, &hnd->pol, level, &ctr);
144
 
 
145
 
        /* Return value */
146
 
 
147
 
        if (!W_ERROR_IS_OK(werror)) {
148
 
                PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
149
 
                return NULL;
150
 
        }
151
 
 
152
 
        result = Py_None;
153
 
 
154
 
        switch (level) {
155
 
                
156
 
        case 0:
157
 
                py_from_PRINTER_INFO_0(&result, ctr.printers_0);
158
 
                break;
159
 
 
160
 
        case 1:
161
 
                py_from_PRINTER_INFO_1(&result, ctr.printers_1);
162
 
                break;
163
 
 
164
 
        case 2:
165
 
                py_from_PRINTER_INFO_2(&result, ctr.printers_2);
166
 
                break;
167
 
 
168
 
        case 3:
169
 
                py_from_PRINTER_INFO_3(&result, ctr.printers_3);
170
 
                break;
171
 
        }
172
 
 
173
 
        Py_INCREF(result);
174
 
        return result;
175
 
}
176
 
 
177
 
/* Set printer information */
178
 
 
179
 
PyObject *spoolss_hnd_setprinter(PyObject *self, PyObject *args, PyObject *kw)
180
 
{
181
 
        spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
182
 
        WERROR werror;
183
 
        PyObject *info;
184
 
        PRINTER_INFO_CTR ctr;
185
 
        uint32 level;
186
 
        static char *kwlist[] = {"dict", NULL};
187
 
        union {
188
 
                PRINTER_INFO_1 printers_1;
189
 
                PRINTER_INFO_2 printers_2;
190
 
                PRINTER_INFO_3 printers_3;
191
 
        } pinfo;
192
 
 
193
 
        /* Parse parameters */
194
 
 
195
 
        if (!PyArg_ParseTupleAndKeywords(
196
 
                    args, kw, "O!", kwlist, &PyDict_Type, &info))
197
 
                return NULL;
198
 
        
199
 
        if (!get_level_value(info, &level)) {
200
 
                PyErr_SetString(spoolss_error, "invalid info level");
201
 
                return NULL;
202
 
        }
203
 
 
204
 
        if (level < 1 && level > 3) {
205
 
                PyErr_SetString(spoolss_error, "unsupported info level");
206
 
                return NULL;
207
 
        }
208
 
 
209
 
        /* Fill in printer info */
210
 
 
211
 
        ZERO_STRUCT(ctr);
212
 
 
213
 
        switch (level) {
214
 
        case 1:
215
 
                ctr.printers_1 = &pinfo.printers_1;
216
 
 
217
 
                if (!py_to_PRINTER_INFO_1(ctr.printers_1, info)){
218
 
                        PyErr_SetString(spoolss_error, 
219
 
                                        "error converting printer to info 1");
220
 
                        return NULL;
221
 
                }
222
 
 
223
 
                break;
224
 
        case 2:
225
 
                ctr.printers_2 = &pinfo.printers_2;
226
 
 
227
 
                if (!py_to_PRINTER_INFO_2(ctr.printers_2, info,
228
 
                                          hnd->mem_ctx)){
229
 
                        PyErr_SetString(spoolss_error, 
230
 
                                        "error converting printer to info 2");
231
 
                        return NULL;
232
 
                }
233
 
 
234
 
                break;
235
 
        case 3:
236
 
                ctr.printers_3 = &pinfo.printers_3;
237
 
 
238
 
                if (!py_to_PRINTER_INFO_3(ctr.printers_3, info,
239
 
                                          hnd->mem_ctx)) {
240
 
                        PyErr_SetString(spoolss_error,
241
 
                                        "error converting to printer info 3");
242
 
                        return NULL;
243
 
                }
244
 
 
245
 
                break;
246
 
        default:
247
 
                PyErr_SetString(spoolss_error, "unsupported info level");
248
 
                return NULL;
249
 
        }
250
 
 
251
 
        /* Call rpc function */
252
 
        
253
 
        werror = rpccli_spoolss_setprinter(
254
 
                hnd->cli, hnd->mem_ctx, &hnd->pol, level, &ctr, 0);
255
 
 
256
 
        /* Return value */
257
 
 
258
 
        if (!W_ERROR_IS_OK(werror)) {
259
 
                PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
260
 
                return NULL;
261
 
        }
262
 
 
263
 
        Py_INCREF(Py_None);
264
 
        return Py_None;
265
 
}
266
 
 
267
 
/* Enumerate printers */
268
 
 
269
 
PyObject *spoolss_enumprinters(PyObject *self, PyObject *args, PyObject *kw)
270
 
{
271
 
        WERROR werror;
272
 
        PyObject *result = NULL, *creds = NULL;
273
 
        PRINTER_INFO_CTR ctr;
274
 
        int level = 1, flags = PRINTER_ENUM_LOCAL, i;
275
 
        uint32 num_printers;
276
 
        static char *kwlist[] = {"server", "name", "level", "flags", 
277
 
                                 "creds", NULL};
278
 
        TALLOC_CTX *mem_ctx = NULL;
279
 
        struct cli_state *cli = NULL;
280
 
        char *server, *errstr, *name = NULL;
281
 
 
282
 
        /* Parse parameters */
283
 
 
284
 
        if (!PyArg_ParseTupleAndKeywords(
285
 
                    args, kw, "s|siiO", kwlist, &server, &name, &level, 
286
 
                    &flags, &creds))
287
 
                return NULL;
288
 
        
289
 
        if (server[0] != '\\' || server[1] != '\\') {
290
 
                PyErr_SetString(PyExc_ValueError, "UNC name required");
291
 
                return NULL;
292
 
        }
293
 
 
294
 
        server += 2;
295
 
 
296
 
        if (creds && creds != Py_None && !PyDict_Check(creds)) {
297
 
                PyErr_SetString(PyExc_TypeError, 
298
 
                                "credentials must be dictionary or None");
299
 
                return NULL;
300
 
        }
301
 
 
302
 
        if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
303
 
                PyErr_SetString(spoolss_error, errstr);
304
 
                free(errstr);
305
 
                goto done;
306
 
        }
307
 
 
308
 
        if (!(mem_ctx = talloc_init("spoolss_enumprinters"))) {
309
 
                PyErr_SetString(
310
 
                        spoolss_error, "unable to init talloc context\n");
311
 
                goto done;
312
 
        }
313
 
 
314
 
        /* This RPC is weird.  By setting the server name to different
315
 
           values we can get different behaviour.  If however the server
316
 
           name is not specified, we default it to being the full server
317
 
           name as this is probably what the caller intended.  To pass a
318
 
           NULL name, pass a value of "" */
319
 
 
320
 
        if (!name)
321
 
                name = server;
322
 
        else {
323
 
                if (!name[0])
324
 
                        name = NULL;
325
 
        }
326
 
 
327
 
        /* Call rpc function */
328
 
        
329
 
        werror = rpccli_spoolss_enum_printers(
330
 
                cli->pipe_list, mem_ctx, name, flags, level, &num_printers, &ctr);
331
 
 
332
 
        if (!W_ERROR_IS_OK(werror)) {
333
 
                PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
334
 
                goto done;
335
 
        }
336
 
 
337
 
        /* Return value */
338
 
        
339
 
        switch (level) {
340
 
        case 0: 
341
 
                result = PyDict_New();
342
 
 
343
 
                for (i = 0; i < num_printers; i++) {
344
 
                        PyObject *value;
345
 
                        fstring s;
346
 
 
347
 
                        rpcstr_pull(s, ctr.printers_0[i].printername.buffer,
348
 
                                    sizeof(fstring), -1, STR_TERMINATE);
349
 
 
350
 
                        py_from_PRINTER_INFO_0(&value, &ctr.printers_0[i]);
351
 
 
352
 
                        PyDict_SetItemString(
353
 
                                value, "level", PyInt_FromLong(0));
354
 
 
355
 
                        PyDict_SetItemString(result, s, value);
356
 
                }
357
 
 
358
 
                break;
359
 
        case 1:
360
 
                result = PyDict_New();
361
 
 
362
 
                for(i = 0; i < num_printers; i++) {
363
 
                        PyObject *value;
364
 
                        fstring s;
365
 
 
366
 
                        rpcstr_pull(s, ctr.printers_1[i].name.buffer,
367
 
                                    sizeof(fstring), -1, STR_TERMINATE);
368
 
 
369
 
                        py_from_PRINTER_INFO_1(&value, &ctr.printers_1[i]);
370
 
 
371
 
                        PyDict_SetItemString(
372
 
                                value, "level", PyInt_FromLong(1));
373
 
 
374
 
                        PyDict_SetItemString(result, s, value);
375
 
                }
376
 
                
377
 
                break;
378
 
        case 2:
379
 
                result = PyDict_New();
380
 
 
381
 
                for(i = 0; i < num_printers; i++) {
382
 
                        PyObject *value;
383
 
                        fstring s;
384
 
 
385
 
                        rpcstr_pull(s, ctr.printers_2[i].printername.buffer,
386
 
                                    sizeof(fstring), -1, STR_TERMINATE);
387
 
 
388
 
                        py_from_PRINTER_INFO_2(&value, &ctr.printers_2[i]);
389
 
 
390
 
                        PyDict_SetItemString(
391
 
                                value, "level", PyInt_FromLong(2));
392
 
 
393
 
                        PyDict_SetItemString(result, s, value);
394
 
                }
395
 
                
396
 
                break;
397
 
        default:
398
 
                PyErr_SetString(spoolss_error, "unknown info level");
399
 
                goto done;
400
 
        }
401
 
 
402
 
done:
403
 
        if (cli)
404
 
                cli_shutdown(cli);
405
 
 
406
 
        if (mem_ctx)
407
 
                talloc_destroy(mem_ctx);
408
 
 
409
 
        return result;
410
 
}
411
 
 
412
 
/* Add a printer */
413
 
 
414
 
PyObject *spoolss_addprinterex(PyObject *self, PyObject *args, PyObject *kw)
415
 
{
416
 
        static char *kwlist[] = { "server", "printername", "info", "creds", 
417
 
                                  NULL};
418
 
        char *printername, *server, *errstr;
419
 
        PyObject *info, *result = NULL, *creds = NULL;
420
 
        struct cli_state *cli = NULL;
421
 
        TALLOC_CTX *mem_ctx = NULL;
422
 
        PRINTER_INFO_CTR ctr;
423
 
        PRINTER_INFO_2 info2;
424
 
        WERROR werror;
425
 
 
426
 
        if (!PyArg_ParseTupleAndKeywords(
427
 
                    args, kw, "ssO!|O!", kwlist, &server, &printername,
428
 
                    &PyDict_Type, &info, &PyDict_Type, &creds))
429
 
                return NULL;
430
 
 
431
 
        if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
432
 
                PyErr_SetString(spoolss_error, errstr);
433
 
                free(errstr);
434
 
                goto done;
435
 
        }
436
 
 
437
 
        if (!(mem_ctx = talloc_init("spoolss_addprinterex"))) {
438
 
                PyErr_SetString(
439
 
                        spoolss_error, "unable to init talloc context\n");
440
 
                goto done;
441
 
        }
442
 
 
443
 
        if (!py_to_PRINTER_INFO_2(&info2, info, mem_ctx)) {
444
 
                PyErr_SetString(spoolss_error,
445
 
                                "error converting to printer info 2");
446
 
                goto done;
447
 
        }
448
 
 
449
 
        ctr.printers_2 = &info2;
450
 
 
451
 
        werror = rpccli_spoolss_addprinterex(cli->pipe_list, mem_ctx, 2, &ctr);
452
 
 
453
 
        Py_INCREF(Py_None);
454
 
        result = Py_None;
455
 
 
456
 
done:
457
 
        if (cli)
458
 
                cli_shutdown(cli);
459
 
 
460
 
        if (mem_ctx)
461
 
                talloc_destroy(mem_ctx);
462
 
 
463
 
        return result;
464
 
}