r25598: Add missing become_root/unbecome_root around calls of add_aliases.
[Samba/gebeck_regimport.git] / source3 / python / py_spoolss_printers.c
blob306475800774105ca3f203c752024f2951ef2d89
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 3 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, see <http://www.gnu.org/licenses/>.
20 #include "python/py_spoolss.h"
22 /* Open a printer */
24 PyObject *spoolss_openprinter(PyObject *self, PyObject *args, PyObject *kw)
26 char *unc_name, *server, *errstr;
27 TALLOC_CTX *mem_ctx = NULL;
28 POLICY_HND hnd;
29 WERROR werror;
30 PyObject *result = NULL, *creds = NULL;
31 static char *kwlist[] = { "printername", "creds", "access", NULL };
32 uint32 desired_access = MAXIMUM_ALLOWED_ACCESS;
33 struct cli_state *cli;
35 if (!PyArg_ParseTupleAndKeywords(
36 args, kw, "s|Oi", kwlist, &unc_name, &creds,
37 &desired_access))
38 return NULL;
40 if (unc_name[0] != '\\' || unc_name[1] != '\\') {
41 PyErr_SetString(PyExc_ValueError, "UNC name required");
42 return NULL;
45 server = SMB_STRDUP(unc_name + 2);
47 if (strchr(server, '\\')) {
48 char *c = strchr(server, '\\');
49 *c = 0;
52 if (creds && creds != Py_None && !PyDict_Check(creds)) {
53 PyErr_SetString(PyExc_TypeError,
54 "credentials must be dictionary or None");
55 return NULL;
58 if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
59 PyErr_SetString(spoolss_error, errstr);
60 free(errstr);
61 goto done;
64 if (!(mem_ctx = talloc_init("spoolss_openprinter"))) {
65 PyErr_SetString(spoolss_error,
66 "unable to init talloc context\n");
67 goto done;
70 werror = rpccli_spoolss_open_printer_ex(
71 cli->pipe_list, mem_ctx, unc_name, "", desired_access, server,
72 "", &hnd);
74 if (!W_ERROR_IS_OK(werror)) {
75 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
76 goto done;
79 result = new_spoolss_policy_hnd_object(cli, mem_ctx, &hnd);
81 done:
82 if (!result) {
83 if (cli)
84 cli_shutdown(cli);
86 if (mem_ctx)
87 talloc_destroy(mem_ctx);
90 SAFE_FREE(server);
92 return result;
95 /* Close a printer */
97 PyObject *spoolss_closeprinter(PyObject *self, PyObject *args)
99 PyObject *po;
100 spoolss_policy_hnd_object *hnd;
101 WERROR result;
103 /* Parse parameters */
105 if (!PyArg_ParseTuple(args, "O!", &spoolss_policy_hnd_type, &po))
106 return NULL;
108 hnd = (spoolss_policy_hnd_object *)po;
110 /* Call rpc function */
112 result = rpccli_spoolss_close_printer(
113 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 static char *kwlist[] = {"level", NULL};
132 /* Parse parameters */
134 if (!PyArg_ParseTupleAndKeywords(args, kw, "|i", kwlist, &level))
135 return NULL;
137 ZERO_STRUCT(ctr);
139 /* Call rpc function */
141 werror = rpccli_spoolss_getprinter(
142 hnd->cli, hnd->mem_ctx, &hnd->pol, level, &ctr);
144 /* Return value */
146 if (!W_ERROR_IS_OK(werror)) {
147 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
148 return NULL;
151 result = Py_None;
153 switch (level) {
155 case 0:
156 py_from_PRINTER_INFO_0(&result, ctr.printers_0);
157 break;
159 case 1:
160 py_from_PRINTER_INFO_1(&result, ctr.printers_1);
161 break;
163 case 2:
164 py_from_PRINTER_INFO_2(&result, ctr.printers_2);
165 break;
167 case 3:
168 py_from_PRINTER_INFO_3(&result, ctr.printers_3);
169 break;
172 Py_INCREF(result);
173 return result;
176 /* Set printer information */
178 PyObject *spoolss_hnd_setprinter(PyObject *self, PyObject *args, PyObject *kw)
180 spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
181 WERROR werror;
182 PyObject *info;
183 PRINTER_INFO_CTR ctr;
184 uint32 level;
185 static char *kwlist[] = {"dict", NULL};
186 union {
187 PRINTER_INFO_1 printers_1;
188 PRINTER_INFO_2 printers_2;
189 PRINTER_INFO_3 printers_3;
190 } pinfo;
192 /* Parse parameters */
194 if (!PyArg_ParseTupleAndKeywords(
195 args, kw, "O!", kwlist, &PyDict_Type, &info))
196 return NULL;
198 if (!get_level_value(info, &level)) {
199 PyErr_SetString(spoolss_error, "invalid info level");
200 return NULL;
203 if (level < 1 && level > 3) {
204 PyErr_SetString(spoolss_error, "unsupported info level");
205 return NULL;
208 /* Fill in printer info */
210 ZERO_STRUCT(ctr);
212 switch (level) {
213 case 1:
214 ctr.printers_1 = &pinfo.printers_1;
216 if (!py_to_PRINTER_INFO_1(ctr.printers_1, info)){
217 PyErr_SetString(spoolss_error,
218 "error converting printer to info 1");
219 return NULL;
222 break;
223 case 2:
224 ctr.printers_2 = &pinfo.printers_2;
226 if (!py_to_PRINTER_INFO_2(ctr.printers_2, info,
227 hnd->mem_ctx)){
228 PyErr_SetString(spoolss_error,
229 "error converting printer to info 2");
230 return NULL;
233 break;
234 case 3:
235 ctr.printers_3 = &pinfo.printers_3;
237 if (!py_to_PRINTER_INFO_3(ctr.printers_3, info,
238 hnd->mem_ctx)) {
239 PyErr_SetString(spoolss_error,
240 "error converting to printer info 3");
241 return NULL;
244 break;
245 default:
246 PyErr_SetString(spoolss_error, "unsupported info level");
247 return NULL;
250 /* Call rpc function */
252 werror = rpccli_spoolss_setprinter(
253 hnd->cli, hnd->mem_ctx, &hnd->pol, level, &ctr, 0);
255 /* Return value */
257 if (!W_ERROR_IS_OK(werror)) {
258 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
259 return NULL;
262 Py_INCREF(Py_None);
263 return Py_None;
266 /* Enumerate printers */
268 PyObject *spoolss_enumprinters(PyObject *self, PyObject *args, PyObject *kw)
270 WERROR werror;
271 PyObject *result = NULL, *creds = NULL;
272 PRINTER_INFO_CTR ctr;
273 int level = 1, flags = PRINTER_ENUM_LOCAL, i;
274 uint32 num_printers;
275 static char *kwlist[] = {"server", "name", "level", "flags",
276 "creds", NULL};
277 TALLOC_CTX *mem_ctx = NULL;
278 struct cli_state *cli = NULL;
279 char *server, *errstr, *name = NULL;
281 /* Parse parameters */
283 if (!PyArg_ParseTupleAndKeywords(
284 args, kw, "s|siiO", kwlist, &server, &name, &level,
285 &flags, &creds))
286 return NULL;
288 if (server[0] != '\\' || server[1] != '\\') {
289 PyErr_SetString(PyExc_ValueError, "UNC name required");
290 return NULL;
293 server += 2;
295 if (creds && creds != Py_None && !PyDict_Check(creds)) {
296 PyErr_SetString(PyExc_TypeError,
297 "credentials must be dictionary or None");
298 return NULL;
301 if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
302 PyErr_SetString(spoolss_error, errstr);
303 free(errstr);
304 goto done;
307 if (!(mem_ctx = talloc_init("spoolss_enumprinters"))) {
308 PyErr_SetString(
309 spoolss_error, "unable to init talloc context\n");
310 goto done;
313 /* This RPC is weird. By setting the server name to different
314 values we can get different behaviour. If however the server
315 name is not specified, we default it to being the full server
316 name as this is probably what the caller intended. To pass a
317 NULL name, pass a value of "" */
319 if (!name)
320 name = server;
321 else {
322 if (!name[0])
323 name = NULL;
326 /* Call rpc function */
328 werror = rpccli_spoolss_enum_printers(
329 cli->pipe_list, mem_ctx, name, flags, level, &num_printers, &ctr);
331 if (!W_ERROR_IS_OK(werror)) {
332 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
333 goto done;
336 /* Return value */
338 switch (level) {
339 case 0:
340 result = PyDict_New();
342 for (i = 0; i < num_printers; i++) {
343 PyObject *value;
344 fstring s;
346 rpcstr_pull(s, ctr.printers_0[i].printername.buffer,
347 sizeof(fstring), -1, STR_TERMINATE);
349 py_from_PRINTER_INFO_0(&value, &ctr.printers_0[i]);
351 PyDict_SetItemString(
352 value, "level", PyInt_FromLong(0));
354 PyDict_SetItemString(result, s, value);
357 break;
358 case 1:
359 result = PyDict_New();
361 for(i = 0; i < num_printers; i++) {
362 PyObject *value;
363 fstring s;
365 rpcstr_pull(s, ctr.printers_1[i].name.buffer,
366 sizeof(fstring), -1, STR_TERMINATE);
368 py_from_PRINTER_INFO_1(&value, &ctr.printers_1[i]);
370 PyDict_SetItemString(
371 value, "level", PyInt_FromLong(1));
373 PyDict_SetItemString(result, s, value);
376 break;
377 case 2:
378 result = PyDict_New();
380 for(i = 0; i < num_printers; i++) {
381 PyObject *value;
382 fstring s;
384 rpcstr_pull(s, ctr.printers_2[i].printername.buffer,
385 sizeof(fstring), -1, STR_TERMINATE);
387 py_from_PRINTER_INFO_2(&value, &ctr.printers_2[i]);
389 PyDict_SetItemString(
390 value, "level", PyInt_FromLong(2));
392 PyDict_SetItemString(result, s, value);
395 break;
396 default:
397 PyErr_SetString(spoolss_error, "unknown info level");
398 goto done;
401 done:
402 if (cli)
403 cli_shutdown(cli);
405 if (mem_ctx)
406 talloc_destroy(mem_ctx);
408 return result;
411 /* Add a printer */
413 PyObject *spoolss_addprinterex(PyObject *self, PyObject *args, PyObject *kw)
415 static char *kwlist[] = { "server", "printername", "info", "creds",
416 NULL};
417 char *printername, *server, *errstr;
418 PyObject *info, *result = NULL, *creds = NULL;
419 struct cli_state *cli = NULL;
420 TALLOC_CTX *mem_ctx = NULL;
421 PRINTER_INFO_CTR ctr;
422 PRINTER_INFO_2 info2;
423 WERROR werror;
425 if (!PyArg_ParseTupleAndKeywords(
426 args, kw, "ssO!|O!", kwlist, &server, &printername,
427 &PyDict_Type, &info, &PyDict_Type, &creds))
428 return NULL;
430 if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
431 PyErr_SetString(spoolss_error, errstr);
432 free(errstr);
433 goto done;
436 if (!(mem_ctx = talloc_init("spoolss_addprinterex"))) {
437 PyErr_SetString(
438 spoolss_error, "unable to init talloc context\n");
439 goto done;
442 if (!py_to_PRINTER_INFO_2(&info2, info, mem_ctx)) {
443 PyErr_SetString(spoolss_error,
444 "error converting to printer info 2");
445 goto done;
448 ctr.printers_2 = &info2;
450 werror = rpccli_spoolss_addprinterex(cli->pipe_list, mem_ctx, 2, &ctr);
452 Py_INCREF(Py_None);
453 result = Py_None;
455 done:
456 if (cli)
457 cli_shutdown(cli);
459 if (mem_ctx)
460 talloc_destroy(mem_ctx);
462 return result;