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"
25 PyObject *spoolss_openprinter(PyObject *self, PyObject *args, PyObject *kw)
27 char *unc_name, *server, *errstr;
28 TALLOC_CTX *mem_ctx = NULL;
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,
41 if (unc_name[0] != '\\' || unc_name[1] != '\\') {
42 PyErr_SetString(PyExc_ValueError, "UNC name required");
46 server = strdup(unc_name + 2);
48 if (strchr(server, '\\')) {
49 char *c = strchr(server, '\\');
53 if (creds && creds != Py_None && !PyDict_Check(creds)) {
54 PyErr_SetString(PyExc_TypeError,
55 "credentials must be dictionary or None");
59 if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
60 PyErr_SetString(spoolss_error, errstr);
65 if (!(mem_ctx = talloc_init("spoolss_openprinter"))) {
66 PyErr_SetString(spoolss_error,
67 "unable to init talloc context\n");
71 werror = cli_spoolss_open_printer_ex(
72 cli, mem_ctx, unc_name, "", desired_access, server,
75 if (!W_ERROR_IS_OK(werror)) {
76 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
80 result = new_spoolss_policy_hnd_object(cli, mem_ctx, &hnd);
88 talloc_destroy(mem_ctx);
98 PyObject *spoolss_closeprinter(PyObject *self, PyObject *args)
101 spoolss_policy_hnd_object *hnd;
104 /* Parse parameters */
106 if (!PyArg_ParseTuple(args, "O!", &spoolss_policy_hnd_type, &po))
109 hnd = (spoolss_policy_hnd_object *)po;
111 /* Call rpc function */
113 result = cli_spoolss_close_printer(hnd->cli, hnd->mem_ctx, &hnd->pol);
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;
127 PyObject *result = NULL;
128 PRINTER_INFO_CTR ctr;
131 static char *kwlist[] = {"level", NULL};
133 /* Parse parameters */
135 if (!PyArg_ParseTupleAndKeywords(args, kw, "|i", kwlist, &level))
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,
152 if (!W_ERROR_IS_OK(werror)) {
153 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
162 py_from_PRINTER_INFO_0(&result, ctr.printers_0);
166 py_from_PRINTER_INFO_1(&result, ctr.printers_1);
170 py_from_PRINTER_INFO_2(&result, ctr.printers_2);
174 py_from_PRINTER_INFO_3(&result, ctr.printers_3);
177 /* These info levels are supported by NT4 and higher
178 but don't seem to be used by any clients we know of. */
185 /* These info levels are only supported by Windows 2000
198 /* Set printer information */
200 PyObject *spoolss_hnd_setprinter(PyObject *self, PyObject *args, PyObject *kw)
202 spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
205 PRINTER_INFO_CTR ctr;
207 static char *kwlist[] = {"dict", NULL};
209 PRINTER_INFO_1 printers_1;
210 PRINTER_INFO_2 printers_2;
211 PRINTER_INFO_3 printers_3;
214 /* Parse parameters */
216 if (!PyArg_ParseTupleAndKeywords(
217 args, kw, "O!", kwlist, &PyDict_Type, &info))
220 if (!get_level_value(info, &level)) {
221 PyErr_SetString(spoolss_error, "invalid info level");
225 if (level < 1 && level > 3) {
226 PyErr_SetString(spoolss_error, "unsupported info level");
230 /* Fill in printer info */
236 ctr.printers_1 = &pinfo.printers_1;
238 if (!py_to_PRINTER_INFO_1(ctr.printers_1, info)){
239 PyErr_SetString(spoolss_error,
240 "error converting printer to info 1");
246 ctr.printers_2 = &pinfo.printers_2;
248 if (!py_to_PRINTER_INFO_2(ctr.printers_2, info,
250 PyErr_SetString(spoolss_error,
251 "error converting printer to info 2");
257 ctr.printers_3 = &pinfo.printers_3;
259 if (!py_to_PRINTER_INFO_3(ctr.printers_3, info,
261 PyErr_SetString(spoolss_error,
262 "error converting to printer info 3");
268 PyErr_SetString(spoolss_error, "unsupported info level");
272 /* Call rpc function */
274 werror = cli_spoolss_setprinter(hnd->cli, hnd->mem_ctx, &hnd->pol,
279 if (!W_ERROR_IS_OK(werror)) {
280 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
288 /* Enumerate printers */
290 PyObject *spoolss_enumprinters(PyObject *self, PyObject *args, PyObject *kw)
293 PyObject *result = NULL, *creds = NULL;
294 PRINTER_INFO_CTR ctr;
295 int level = 1, flags = PRINTER_ENUM_LOCAL, i;
296 uint32 needed, num_printers;
297 static char *kwlist[] = {"server", "name", "level", "flags",
299 TALLOC_CTX *mem_ctx = NULL;
300 struct cli_state *cli = NULL;
301 char *server, *errstr, *name = NULL;
303 /* Parse parameters */
305 if (!PyArg_ParseTupleAndKeywords(
306 args, kw, "s|siiO", kwlist, &server, &name, &level,
310 if (server[0] != '\\' || server[1] != '\\') {
311 PyErr_SetString(PyExc_ValueError, "UNC name required");
317 if (creds && creds != Py_None && !PyDict_Check(creds)) {
318 PyErr_SetString(PyExc_TypeError,
319 "credentials must be dictionary or None");
323 if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
324 PyErr_SetString(spoolss_error, errstr);
329 if (!(mem_ctx = talloc_init("spoolss_enumprinters"))) {
331 spoolss_error, "unable to init talloc context\n");
335 /* This RPC is weird. By setting the server name to different
336 values we can get different behaviour. If however the server
337 name is not specified, we default it to being the full server
338 name as this is probably what the caller intended. To pass a
339 NULL name, pass a value of "" */
348 /* Call rpc function */
350 werror = cli_spoolss_enum_printers(
351 cli, mem_ctx, 0, &needed, name, flags, level,
352 &num_printers, &ctr);
354 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
355 werror = cli_spoolss_enum_printers(
356 cli, mem_ctx, needed, NULL, name, flags,
357 level, &num_printers, &ctr);
359 if (!W_ERROR_IS_OK(werror)) {
360 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
368 result = PyDict_New();
370 for (i = 0; i < num_printers; i++) {
374 rpcstr_pull(s, ctr.printers_0[i].printername.buffer,
375 sizeof(fstring), -1, STR_TERMINATE);
377 py_from_PRINTER_INFO_0(&value, &ctr.printers_0[i]);
379 PyDict_SetItemString(
380 value, "level", PyInt_FromLong(0));
382 PyDict_SetItemString(result, s, value);
387 result = PyDict_New();
389 for(i = 0; i < num_printers; i++) {
393 rpcstr_pull(s, ctr.printers_1[i].name.buffer,
394 sizeof(fstring), -1, STR_TERMINATE);
396 py_from_PRINTER_INFO_1(&value, &ctr.printers_1[i]);
398 PyDict_SetItemString(
399 value, "level", PyInt_FromLong(1));
401 PyDict_SetItemString(result, s, value);
406 result = PyDict_New();
408 for(i = 0; i < num_printers; i++) {
412 rpcstr_pull(s, ctr.printers_2[i].printername.buffer,
413 sizeof(fstring), -1, STR_TERMINATE);
415 py_from_PRINTER_INFO_2(&value, &ctr.printers_2[i]);
417 PyDict_SetItemString(
418 value, "level", PyInt_FromLong(2));
420 PyDict_SetItemString(result, s, value);
425 PyErr_SetString(spoolss_error, "unknown info level");
434 talloc_destroy(mem_ctx);
441 PyObject *spoolss_addprinterex(PyObject *self, PyObject *args, PyObject *kw)
443 static char *kwlist[] = { "server", "printername", "info", "creds",
445 char *printername, *server, *errstr;
446 PyObject *info, *result = NULL, *creds = NULL;
447 struct cli_state *cli = NULL;
448 TALLOC_CTX *mem_ctx = NULL;
449 PRINTER_INFO_CTR ctr;
450 PRINTER_INFO_2 info2;
453 if (!PyArg_ParseTupleAndKeywords(
454 args, kw, "ssO!|O!", kwlist, &server, &printername,
455 &PyDict_Type, &info, &PyDict_Type, &creds))
458 if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
459 PyErr_SetString(spoolss_error, errstr);
464 if (!(mem_ctx = talloc_init("spoolss_addprinterex"))) {
466 spoolss_error, "unable to init talloc context\n");
470 if (!py_to_PRINTER_INFO_2(&info2, info, mem_ctx)) {
471 PyErr_SetString(spoolss_error,
472 "error converting to printer info 2");
476 ctr.printers_2 = &info2;
478 werror = cli_spoolss_addprinterex(cli, mem_ctx, 2, &ctr);
488 talloc_destroy(mem_ctx);