Samba 3: added Samba 3.0.24 sources
[tomato.git] / release / src / router / samba3 / source / python / py_spoolss_printers.c
blob25cd051f3cc54277ac9e5df88904178a680a0ea0
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 = SMB_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 = rpccli_spoolss_open_printer_ex(
72 cli->pipe_list, 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 = rpccli_spoolss_close_printer(
114 hnd->cli, hnd->mem_ctx, &hnd->pol);
116 /* Return value */
118 Py_INCREF(Py_None);
119 return Py_None;
122 /* Fetch printer information */
124 PyObject *spoolss_hnd_getprinter(PyObject *self, PyObject *args, PyObject *kw)
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};
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 = rpccli_spoolss_getprinter(
143 hnd->cli, hnd->mem_ctx, &hnd->pol, level, &ctr);
145 /* Return value */
147 if (!W_ERROR_IS_OK(werror)) {
148 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
149 return NULL;
152 result = Py_None;
154 switch (level) {
156 case 0:
157 py_from_PRINTER_INFO_0(&result, ctr.printers_0);
158 break;
160 case 1:
161 py_from_PRINTER_INFO_1(&result, ctr.printers_1);
162 break;
164 case 2:
165 py_from_PRINTER_INFO_2(&result, ctr.printers_2);
166 break;
168 case 3:
169 py_from_PRINTER_INFO_3(&result, ctr.printers_3);
170 break;
173 Py_INCREF(result);
174 return result;
177 /* Set printer information */
179 PyObject *spoolss_hnd_setprinter(PyObject *self, PyObject *args, PyObject *kw)
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;
193 /* Parse parameters */
195 if (!PyArg_ParseTupleAndKeywords(
196 args, kw, "O!", kwlist, &PyDict_Type, &info))
197 return NULL;
199 if (!get_level_value(info, &level)) {
200 PyErr_SetString(spoolss_error, "invalid info level");
201 return NULL;
204 if (level < 1 && level > 3) {
205 PyErr_SetString(spoolss_error, "unsupported info level");
206 return NULL;
209 /* Fill in printer info */
211 ZERO_STRUCT(ctr);
213 switch (level) {
214 case 1:
215 ctr.printers_1 = &pinfo.printers_1;
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;
223 break;
224 case 2:
225 ctr.printers_2 = &pinfo.printers_2;
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;
234 break;
235 case 3:
236 ctr.printers_3 = &pinfo.printers_3;
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;
245 break;
246 default:
247 PyErr_SetString(spoolss_error, "unsupported info level");
248 return NULL;
251 /* Call rpc function */
253 werror = rpccli_spoolss_setprinter(
254 hnd->cli, hnd->mem_ctx, &hnd->pol, level, &ctr, 0);
256 /* Return value */
258 if (!W_ERROR_IS_OK(werror)) {
259 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
260 return NULL;
263 Py_INCREF(Py_None);
264 return Py_None;
267 /* Enumerate printers */
269 PyObject *spoolss_enumprinters(PyObject *self, PyObject *args, PyObject *kw)
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;
282 /* Parse parameters */
284 if (!PyArg_ParseTupleAndKeywords(
285 args, kw, "s|siiO", kwlist, &server, &name, &level,
286 &flags, &creds))
287 return NULL;
289 if (server[0] != '\\' || server[1] != '\\') {
290 PyErr_SetString(PyExc_ValueError, "UNC name required");
291 return NULL;
294 server += 2;
296 if (creds && creds != Py_None && !PyDict_Check(creds)) {
297 PyErr_SetString(PyExc_TypeError,
298 "credentials must be dictionary or None");
299 return NULL;
302 if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
303 PyErr_SetString(spoolss_error, errstr);
304 free(errstr);
305 goto done;
308 if (!(mem_ctx = talloc_init("spoolss_enumprinters"))) {
309 PyErr_SetString(
310 spoolss_error, "unable to init talloc context\n");
311 goto done;
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 "" */
320 if (!name)
321 name = server;
322 else {
323 if (!name[0])
324 name = NULL;
327 /* Call rpc function */
329 werror = rpccli_spoolss_enum_printers(
330 cli->pipe_list, mem_ctx, name, flags, level, &num_printers, &ctr);
332 if (!W_ERROR_IS_OK(werror)) {
333 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
334 goto done;
337 /* Return value */
339 switch (level) {
340 case 0:
341 result = PyDict_New();
343 for (i = 0; i < num_printers; i++) {
344 PyObject *value;
345 fstring s;
347 rpcstr_pull(s, ctr.printers_0[i].printername.buffer,
348 sizeof(fstring), -1, STR_TERMINATE);
350 py_from_PRINTER_INFO_0(&value, &ctr.printers_0[i]);
352 PyDict_SetItemString(
353 value, "level", PyInt_FromLong(0));
355 PyDict_SetItemString(result, s, value);
358 break;
359 case 1:
360 result = PyDict_New();
362 for(i = 0; i < num_printers; i++) {
363 PyObject *value;
364 fstring s;
366 rpcstr_pull(s, ctr.printers_1[i].name.buffer,
367 sizeof(fstring), -1, STR_TERMINATE);
369 py_from_PRINTER_INFO_1(&value, &ctr.printers_1[i]);
371 PyDict_SetItemString(
372 value, "level", PyInt_FromLong(1));
374 PyDict_SetItemString(result, s, value);
377 break;
378 case 2:
379 result = PyDict_New();
381 for(i = 0; i < num_printers; i++) {
382 PyObject *value;
383 fstring s;
385 rpcstr_pull(s, ctr.printers_2[i].printername.buffer,
386 sizeof(fstring), -1, STR_TERMINATE);
388 py_from_PRINTER_INFO_2(&value, &ctr.printers_2[i]);
390 PyDict_SetItemString(
391 value, "level", PyInt_FromLong(2));
393 PyDict_SetItemString(result, s, value);
396 break;
397 default:
398 PyErr_SetString(spoolss_error, "unknown info level");
399 goto done;
402 done:
403 if (cli)
404 cli_shutdown(cli);
406 if (mem_ctx)
407 talloc_destroy(mem_ctx);
409 return result;
412 /* Add a printer */
414 PyObject *spoolss_addprinterex(PyObject *self, PyObject *args, PyObject *kw)
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;
426 if (!PyArg_ParseTupleAndKeywords(
427 args, kw, "ssO!|O!", kwlist, &server, &printername,
428 &PyDict_Type, &info, &PyDict_Type, &creds))
429 return NULL;
431 if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
432 PyErr_SetString(spoolss_error, errstr);
433 free(errstr);
434 goto done;
437 if (!(mem_ctx = talloc_init("spoolss_addprinterex"))) {
438 PyErr_SetString(
439 spoolss_error, "unable to init talloc context\n");
440 goto done;
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;
449 ctr.printers_2 = &info2;
451 werror = rpccli_spoolss_addprinterex(cli->pipe_list, mem_ctx, 2, &ctr);
453 Py_INCREF(Py_None);
454 result = Py_None;
456 done:
457 if (cli)
458 cli_shutdown(cli);
460 if (mem_ctx)
461 talloc_destroy(mem_ctx);
463 return result;