Merge a trivial fix across from HEAD. Not that this
[Samba.git] / source / python / py_spoolss_printers.c
blobd011681acc212f722555e854cb8ce8cf8f87a919
1 /*
2 Python wrappers for DCERPC/SMB client routines.
4 Copyright (C) Tim Potter, 2002
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.
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.
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.
21 #include "python/py_spoolss.h"
23 /* Open a printer */
25 PyObject *spoolss_openprinter(PyObject *self, PyObject *args, PyObject *kw)
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;
36 if (!PyArg_ParseTupleAndKeywords(
37 args, kw, "s|Oi", kwlist, &unc_name, &creds,
38 &desired_access))
39 return NULL;
41 if (unc_name[0] != '\\' || unc_name[1] != '\\') {
42 PyErr_SetString(PyExc_ValueError, "UNC name required");
43 return NULL;
46 server = strdup(unc_name + 2);
48 if (strchr(server, '\\')) {
49 char *c = strchr(server, '\\');
50 *c = 0;
53 if (creds && creds != Py_None && !PyDict_Check(creds)) {
54 PyErr_SetString(PyExc_TypeError,
55 "credentials must be dictionary or None");
56 return NULL;
59 if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
60 PyErr_SetString(spoolss_error, errstr);
61 free(errstr);
62 goto done;
65 if (!(mem_ctx = talloc_init("spoolss_openprinter"))) {
66 PyErr_SetString(spoolss_error,
67 "unable to init talloc context\n");
68 goto done;
71 werror = cli_spoolss_open_printer_ex(
72 cli, mem_ctx, unc_name, "", desired_access, server,
73 "", &hnd);
75 if (!W_ERROR_IS_OK(werror)) {
76 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
77 goto done;
80 result = new_spoolss_policy_hnd_object(cli, mem_ctx, &hnd);
82 done:
83 if (!result) {
84 if (cli)
85 cli_shutdown(cli);
87 if (mem_ctx)
88 talloc_destroy(mem_ctx);
91 SAFE_FREE(server);
93 return result;
96 /* Close a printer */
98 PyObject *spoolss_closeprinter(PyObject *self, PyObject *args)
100 PyObject *po;
101 spoolss_policy_hnd_object *hnd;
102 WERROR result;
104 /* Parse parameters */
106 if (!PyArg_ParseTuple(args, "O!", &spoolss_policy_hnd_type, &po))
107 return NULL;
109 hnd = (spoolss_policy_hnd_object *)po;
111 /* Call rpc function */
113 result = cli_spoolss_close_printer(hnd->cli, hnd->mem_ctx, &hnd->pol);
115 /* Return value */
117 Py_INCREF(Py_None);
118 return Py_None;
121 /* Fetch printer information */
123 PyObject *spoolss_hnd_getprinter(PyObject *self, PyObject *args, PyObject *kw)
125 spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
126 WERROR werror;
127 PyObject *result = NULL;
128 PRINTER_INFO_CTR ctr;
129 int level = 1;
130 uint32 needed;
131 static char *kwlist[] = {"level", NULL};
133 /* Parse parameters */
135 if (!PyArg_ParseTupleAndKeywords(args, kw, "|i", kwlist, &level))
136 return NULL;
138 ZERO_STRUCT(ctr);
140 /* Call rpc function */
142 werror = cli_spoolss_getprinter(
143 hnd->cli, hnd->mem_ctx, 0, &needed, &hnd->pol, level, &ctr);
145 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
146 werror = cli_spoolss_getprinter(
147 hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol,
148 level, &ctr);
150 /* Return value */
152 if (!W_ERROR_IS_OK(werror)) {
153 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
154 return NULL;
157 result = Py_None;
159 switch (level) {
161 case 0:
162 py_from_PRINTER_INFO_0(&result, ctr.printers_0);
163 break;
165 case 1:
166 py_from_PRINTER_INFO_1(&result, ctr.printers_1);
167 break;
169 case 2:
170 py_from_PRINTER_INFO_2(&result, ctr.printers_2);
171 break;
173 case 3:
174 py_from_PRINTER_INFO_3(&result, ctr.printers_3);
175 break;
178 Py_INCREF(result);
179 return result;
182 /* Set printer information */
184 PyObject *spoolss_hnd_setprinter(PyObject *self, PyObject *args, PyObject *kw)
186 spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
187 WERROR werror;
188 PyObject *info;
189 PRINTER_INFO_CTR ctr;
190 uint32 level;
191 static char *kwlist[] = {"dict", NULL};
192 union {
193 PRINTER_INFO_1 printers_1;
194 PRINTER_INFO_2 printers_2;
195 PRINTER_INFO_3 printers_3;
196 } pinfo;
198 /* Parse parameters */
200 if (!PyArg_ParseTupleAndKeywords(
201 args, kw, "O!", kwlist, &PyDict_Type, &info))
202 return NULL;
204 if (!get_level_value(info, &level)) {
205 PyErr_SetString(spoolss_error, "invalid info level");
206 return NULL;
209 if (level < 1 && level > 3) {
210 PyErr_SetString(spoolss_error, "unsupported info level");
211 return NULL;
214 /* Fill in printer info */
216 ZERO_STRUCT(ctr);
218 switch (level) {
219 case 1:
220 ctr.printers_1 = &pinfo.printers_1;
222 if (!py_to_PRINTER_INFO_1(ctr.printers_1, info)){
223 PyErr_SetString(spoolss_error,
224 "error converting printer to info 1");
225 return NULL;
228 break;
229 case 2:
230 ctr.printers_2 = &pinfo.printers_2;
232 if (!py_to_PRINTER_INFO_2(ctr.printers_2, info,
233 hnd->mem_ctx)){
234 PyErr_SetString(spoolss_error,
235 "error converting printer to info 2");
236 return NULL;
239 break;
240 case 3:
241 ctr.printers_3 = &pinfo.printers_3;
243 if (!py_to_PRINTER_INFO_3(ctr.printers_3, info,
244 hnd->mem_ctx)) {
245 PyErr_SetString(spoolss_error,
246 "error converting to printer info 3");
247 return NULL;
250 break;
251 default:
252 PyErr_SetString(spoolss_error, "unsupported info level");
253 return NULL;
256 /* Call rpc function */
258 werror = cli_spoolss_setprinter(hnd->cli, hnd->mem_ctx, &hnd->pol,
259 level, &ctr, 0);
261 /* Return value */
263 if (!W_ERROR_IS_OK(werror)) {
264 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
265 return NULL;
268 Py_INCREF(Py_None);
269 return Py_None;
272 /* Enumerate printers */
274 PyObject *spoolss_enumprinters(PyObject *self, PyObject *args, PyObject *kw)
276 WERROR werror;
277 PyObject *result = NULL, *creds = NULL;
278 PRINTER_INFO_CTR ctr;
279 int level = 1, flags = PRINTER_ENUM_LOCAL, i;
280 uint32 needed, num_printers;
281 static char *kwlist[] = {"server", "name", "level", "flags",
282 "creds", NULL};
283 TALLOC_CTX *mem_ctx = NULL;
284 struct cli_state *cli = NULL;
285 char *server, *errstr, *name = NULL;
287 /* Parse parameters */
289 if (!PyArg_ParseTupleAndKeywords(
290 args, kw, "s|siiO", kwlist, &server, &name, &level,
291 &flags, &creds))
292 return NULL;
294 if (server[0] != '\\' || server[1] != '\\') {
295 PyErr_SetString(PyExc_ValueError, "UNC name required");
296 return NULL;
299 server += 2;
301 if (creds && creds != Py_None && !PyDict_Check(creds)) {
302 PyErr_SetString(PyExc_TypeError,
303 "credentials must be dictionary or None");
304 return NULL;
307 if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
308 PyErr_SetString(spoolss_error, errstr);
309 free(errstr);
310 goto done;
313 if (!(mem_ctx = talloc_init("spoolss_enumprinters"))) {
314 PyErr_SetString(
315 spoolss_error, "unable to init talloc context\n");
316 goto done;
319 /* This RPC is weird. By setting the server name to different
320 values we can get different behaviour. If however the server
321 name is not specified, we default it to being the full server
322 name as this is probably what the caller intended. To pass a
323 NULL name, pass a value of "" */
325 if (!name)
326 name = server;
327 else {
328 if (!name[0])
329 name = NULL;
332 /* Call rpc function */
334 werror = cli_spoolss_enum_printers(
335 cli, mem_ctx, 0, &needed, name, flags, level,
336 &num_printers, &ctr);
338 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
339 werror = cli_spoolss_enum_printers(
340 cli, mem_ctx, needed, NULL, name, flags,
341 level, &num_printers, &ctr);
343 if (!W_ERROR_IS_OK(werror)) {
344 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
345 goto done;
348 /* Return value */
350 switch (level) {
351 case 0:
352 result = PyDict_New();
354 for (i = 0; i < num_printers; i++) {
355 PyObject *value;
356 fstring s;
358 rpcstr_pull(s, ctr.printers_0[i].printername.buffer,
359 sizeof(fstring), -1, STR_TERMINATE);
361 py_from_PRINTER_INFO_0(&value, &ctr.printers_0[i]);
363 PyDict_SetItemString(
364 value, "level", PyInt_FromLong(0));
366 PyDict_SetItemString(result, s, value);
369 break;
370 case 1:
371 result = PyDict_New();
373 for(i = 0; i < num_printers; i++) {
374 PyObject *value;
375 fstring s;
377 rpcstr_pull(s, ctr.printers_1[i].name.buffer,
378 sizeof(fstring), -1, STR_TERMINATE);
380 py_from_PRINTER_INFO_1(&value, &ctr.printers_1[i]);
382 PyDict_SetItemString(
383 value, "level", PyInt_FromLong(1));
385 PyDict_SetItemString(result, s, value);
388 break;
389 case 2:
390 result = PyDict_New();
392 for(i = 0; i < num_printers; i++) {
393 PyObject *value;
394 fstring s;
396 rpcstr_pull(s, ctr.printers_2[i].printername.buffer,
397 sizeof(fstring), -1, STR_TERMINATE);
399 py_from_PRINTER_INFO_2(&value, &ctr.printers_2[i]);
401 PyDict_SetItemString(
402 value, "level", PyInt_FromLong(2));
404 PyDict_SetItemString(result, s, value);
407 break;
408 default:
409 PyErr_SetString(spoolss_error, "unknown info level");
410 goto done;
413 done:
414 if (cli)
415 cli_shutdown(cli);
417 if (mem_ctx)
418 talloc_destroy(mem_ctx);
420 return result;
423 /* Add a printer */
425 PyObject *spoolss_addprinterex(PyObject *self, PyObject *args, PyObject *kw)
427 static char *kwlist[] = { "server", "printername", "info", "creds",
428 NULL};
429 char *printername, *server, *errstr;
430 PyObject *info, *result = NULL, *creds = NULL;
431 struct cli_state *cli = NULL;
432 TALLOC_CTX *mem_ctx = NULL;
433 PRINTER_INFO_CTR ctr;
434 PRINTER_INFO_2 info2;
435 WERROR werror;
437 if (!PyArg_ParseTupleAndKeywords(
438 args, kw, "ssO!|O!", kwlist, &server, &printername,
439 &PyDict_Type, &info, &PyDict_Type, &creds))
440 return NULL;
442 if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
443 PyErr_SetString(spoolss_error, errstr);
444 free(errstr);
445 goto done;
448 if (!(mem_ctx = talloc_init("spoolss_addprinterex"))) {
449 PyErr_SetString(
450 spoolss_error, "unable to init talloc context\n");
451 goto done;
454 if (!py_to_PRINTER_INFO_2(&info2, info, mem_ctx)) {
455 PyErr_SetString(spoolss_error,
456 "error converting to printer info 2");
457 goto done;
460 ctr.printers_2 = &info2;
462 werror = cli_spoolss_addprinterex(cli, mem_ctx, 2, &ctr);
464 Py_INCREF(Py_None);
465 result = Py_None;
467 done:
468 if (cli)
469 cli_shutdown(cli);
471 if (mem_ctx)
472 talloc_destroy(mem_ctx);
474 return result;