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
);
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
;
189 PRINTER_INFO_CTR ctr
;
191 static char *kwlist
[] = {"dict", NULL
};
193 PRINTER_INFO_1 printers_1
;
194 PRINTER_INFO_2 printers_2
;
195 PRINTER_INFO_3 printers_3
;
198 /* Parse parameters */
200 if (!PyArg_ParseTupleAndKeywords(
201 args
, kw
, "O!", kwlist
, &PyDict_Type
, &info
))
204 if (!get_level_value(info
, &level
)) {
205 PyErr_SetString(spoolss_error
, "invalid info level");
209 if (level
< 1 && level
> 3) {
210 PyErr_SetString(spoolss_error
, "unsupported info level");
214 /* Fill in printer info */
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");
230 ctr
.printers_2
= &pinfo
.printers_2
;
232 if (!py_to_PRINTER_INFO_2(ctr
.printers_2
, info
,
234 PyErr_SetString(spoolss_error
,
235 "error converting printer to info 2");
241 ctr
.printers_3
= &pinfo
.printers_3
;
243 if (!py_to_PRINTER_INFO_3(ctr
.printers_3
, info
,
245 PyErr_SetString(spoolss_error
,
246 "error converting to printer info 3");
252 PyErr_SetString(spoolss_error
, "unsupported info level");
256 /* Call rpc function */
258 werror
= cli_spoolss_setprinter(hnd
->cli
, hnd
->mem_ctx
, &hnd
->pol
,
263 if (!W_ERROR_IS_OK(werror
)) {
264 PyErr_SetObject(spoolss_werror
, py_werror_tuple(werror
));
272 /* Enumerate printers */
274 PyObject
*spoolss_enumprinters(PyObject
*self
, PyObject
*args
, PyObject
*kw
)
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",
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
,
294 if (server
[0] != '\\' || server
[1] != '\\') {
295 PyErr_SetString(PyExc_ValueError
, "UNC name required");
301 if (creds
&& creds
!= Py_None
&& !PyDict_Check(creds
)) {
302 PyErr_SetString(PyExc_TypeError
,
303 "credentials must be dictionary or None");
307 if (!(cli
= open_pipe_creds(server
, creds
, PI_SPOOLSS
, &errstr
))) {
308 PyErr_SetString(spoolss_error
, errstr
);
313 if (!(mem_ctx
= talloc_init("spoolss_enumprinters"))) {
315 spoolss_error
, "unable to init talloc context\n");
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 "" */
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
));
352 result
= PyDict_New();
354 for (i
= 0; i
< num_printers
; i
++) {
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
);
371 result
= PyDict_New();
373 for(i
= 0; i
< num_printers
; i
++) {
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
);
390 result
= PyDict_New();
392 for(i
= 0; i
< num_printers
; i
++) {
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
);
409 PyErr_SetString(spoolss_error
, "unknown info level");
418 talloc_destroy(mem_ctx
);
425 PyObject
*spoolss_addprinterex(PyObject
*self
, PyObject
*args
, PyObject
*kw
)
427 static char *kwlist
[] = { "server", "printername", "info", "creds",
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
;
437 if (!PyArg_ParseTupleAndKeywords(
438 args
, kw
, "ssO!|O!", kwlist
, &server
, &printername
,
439 &PyDict_Type
, &info
, &PyDict_Type
, &creds
))
442 if (!(cli
= open_pipe_creds(server
, creds
, PI_SPOOLSS
, &errstr
))) {
443 PyErr_SetString(spoolss_error
, errstr
);
448 if (!(mem_ctx
= talloc_init("spoolss_addprinterex"))) {
450 spoolss_error
, "unable to init talloc context\n");
454 if (!py_to_PRINTER_INFO_2(&info2
, info
, mem_ctx
)) {
455 PyErr_SetString(spoolss_error
,
456 "error converting to printer info 2");
460 ctr
.printers_2
= &info2
;
462 werror
= cli_spoolss_addprinterex(cli
, mem_ctx
, 2, &ctr
);
472 talloc_destroy(mem_ctx
);