source: branches/samba-3.0/source/python/py_spoolss_printers.c

Last change on this file was 1, checked in by Paul Smedley, 18 years ago

Initial code import

File size: 10.0 KB
Line 
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
25PyObject *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
98PyObject *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
124PyObject *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
179PyObject *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
269PyObject *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
402done:
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
414PyObject *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
456done:
457 if (cli)
458 cli_shutdown(cli);
459
460 if (mem_ctx)
461 talloc_destroy(mem_ctx);
462
463 return result;
464}
Note: See TracBrowser for help on using the repository browser.