• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt/router/samba-3.0.25b/source/python/
1/*
2   Python wrappers for DCERPC/SMB client routines.
3
4   Copyright (C) Tim Potter, 2002
5
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.
10
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.
15
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.
19*/
20
21#include "python/py_spoolss.h"
22
23/* Open a printer */
24
25PyObject *spoolss_openprinter(PyObject *self, PyObject *args, PyObject *kw)
26{
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;
35
36	if (!PyArg_ParseTupleAndKeywords(
37		    args, kw, "s|Oi", kwlist, &unc_name, &creds,
38		    &desired_access))
39		return NULL;
40
41	if (unc_name[0] != '\\' || unc_name[1] != '\\') {
42		PyErr_SetString(PyExc_ValueError, "UNC name required");
43		return NULL;
44	}
45
46	server = SMB_STRDUP(unc_name + 2);
47
48	if (strchr(server, '\\')) {
49		char *c = strchr(server, '\\');
50		*c = 0;
51	}
52
53	if (creds && creds != Py_None && !PyDict_Check(creds)) {
54		PyErr_SetString(PyExc_TypeError,
55				"credentials must be dictionary or None");
56		return NULL;
57	}
58
59	if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
60		PyErr_SetString(spoolss_error, errstr);
61		free(errstr);
62		goto done;
63	}
64
65	if (!(mem_ctx = talloc_init("spoolss_openprinter"))) {
66		PyErr_SetString(spoolss_error,
67				"unable to init talloc context\n");
68		goto done;
69	}
70
71	werror = rpccli_spoolss_open_printer_ex(
72		cli->pipe_list, mem_ctx, unc_name, "", desired_access, server,
73		"", &hnd);
74
75	if (!W_ERROR_IS_OK(werror)) {
76		PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
77		goto done;
78	}
79
80	result = new_spoolss_policy_hnd_object(cli, mem_ctx, &hnd);
81
82 done:
83	if (!result) {
84		if (cli)
85			cli_shutdown(cli);
86
87		if (mem_ctx)
88			talloc_destroy(mem_ctx);
89	}
90
91	SAFE_FREE(server);
92
93	return result;
94}
95
96/* Close a printer */
97
98PyObject *spoolss_closeprinter(PyObject *self, PyObject *args)
99{
100	PyObject *po;
101	spoolss_policy_hnd_object *hnd;
102	WERROR result;
103
104	/* Parse parameters */
105
106	if (!PyArg_ParseTuple(args, "O!", &spoolss_policy_hnd_type, &po))
107		return NULL;
108
109	hnd = (spoolss_policy_hnd_object *)po;
110
111	/* Call rpc function */
112
113	result = rpccli_spoolss_close_printer(
114		hnd->cli, hnd->mem_ctx, &hnd->pol);
115
116	/* Return value */
117
118	Py_INCREF(Py_None);
119	return Py_None;
120}
121
122/* Fetch printer information */
123
124PyObject *spoolss_hnd_getprinter(PyObject *self, PyObject *args, PyObject *kw)
125{
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};
132
133	/* Parse parameters */
134
135	if (!PyArg_ParseTupleAndKeywords(args, kw, "|i", kwlist, &level))
136		return NULL;
137
138	ZERO_STRUCT(ctr);
139
140	/* Call rpc function */
141
142	werror = rpccli_spoolss_getprinter(
143		hnd->cli, hnd->mem_ctx, &hnd->pol, level, &ctr);
144
145	/* Return value */
146
147	if (!W_ERROR_IS_OK(werror)) {
148		PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
149		return NULL;
150	}
151
152	result = Py_None;
153
154	switch (level) {
155
156	case 0:
157		py_from_PRINTER_INFO_0(&result, ctr.printers_0);
158		break;
159
160	case 1:
161		py_from_PRINTER_INFO_1(&result, ctr.printers_1);
162		break;
163
164	case 2:
165		py_from_PRINTER_INFO_2(&result, ctr.printers_2);
166		break;
167
168	case 3:
169		py_from_PRINTER_INFO_3(&result, ctr.printers_3);
170		break;
171	}
172
173	Py_INCREF(result);
174	return result;
175}
176
177/* Set printer information */
178
179PyObject *spoolss_hnd_setprinter(PyObject *self, PyObject *args, PyObject *kw)
180{
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;
192
193	/* Parse parameters */
194
195	if (!PyArg_ParseTupleAndKeywords(
196		    args, kw, "O!", kwlist, &PyDict_Type, &info))
197		return NULL;
198
199	if (!get_level_value(info, &level)) {
200		PyErr_SetString(spoolss_error, "invalid info level");
201		return NULL;
202	}
203
204	if (level < 1 && level > 3) {
205		PyErr_SetString(spoolss_error, "unsupported info level");
206		return NULL;
207	}
208
209	/* Fill in printer info */
210
211	ZERO_STRUCT(ctr);
212
213	switch (level) {
214	case 1:
215		ctr.printers_1 = &pinfo.printers_1;
216
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;
221		}
222
223		break;
224	case 2:
225		ctr.printers_2 = &pinfo.printers_2;
226
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;
232		}
233
234		break;
235	case 3:
236		ctr.printers_3 = &pinfo.printers_3;
237
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;
243		}
244
245		break;
246	default:
247		PyErr_SetString(spoolss_error, "unsupported info level");
248		return NULL;
249	}
250
251	/* Call rpc function */
252
253	werror = rpccli_spoolss_setprinter(
254		hnd->cli, hnd->mem_ctx, &hnd->pol, level, &ctr, 0);
255
256	/* Return value */
257
258	if (!W_ERROR_IS_OK(werror)) {
259		PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
260		return NULL;
261	}
262
263	Py_INCREF(Py_None);
264	return Py_None;
265}
266
267/* Enumerate printers */
268
269PyObject *spoolss_enumprinters(PyObject *self, PyObject *args, PyObject *kw)
270{
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;
281
282	/* Parse parameters */
283
284	if (!PyArg_ParseTupleAndKeywords(
285		    args, kw, "s|siiO", kwlist, &server, &name, &level,
286		    &flags, &creds))
287		return NULL;
288
289	if (server[0] != '\\' || server[1] != '\\') {
290		PyErr_SetString(PyExc_ValueError, "UNC name required");
291		return NULL;
292	}
293
294	server += 2;
295
296	if (creds && creds != Py_None && !PyDict_Check(creds)) {
297		PyErr_SetString(PyExc_TypeError,
298				"credentials must be dictionary or None");
299		return NULL;
300	}
301
302	if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
303		PyErr_SetString(spoolss_error, errstr);
304		free(errstr);
305		goto done;
306	}
307
308	if (!(mem_ctx = talloc_init("spoolss_enumprinters"))) {
309		PyErr_SetString(
310			spoolss_error, "unable to init talloc context\n");
311		goto done;
312	}
313
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 "" */
319
320	if (!name)
321		name = server;
322	else {
323		if (!name[0])
324			name = NULL;
325	}
326
327	/* Call rpc function */
328
329	werror = rpccli_spoolss_enum_printers(
330		cli->pipe_list, mem_ctx, name, flags, level, &num_printers, &ctr);
331
332	if (!W_ERROR_IS_OK(werror)) {
333		PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
334		goto done;
335	}
336
337	/* Return value */
338
339	switch (level) {
340	case 0:
341		result = PyDict_New();
342
343		for (i = 0; i < num_printers; i++) {
344			PyObject *value;
345			fstring s;
346
347			rpcstr_pull(s, ctr.printers_0[i].printername.buffer,
348				    sizeof(fstring), -1, STR_TERMINATE);
349
350			py_from_PRINTER_INFO_0(&value, &ctr.printers_0[i]);
351
352			PyDict_SetItemString(
353				value, "level", PyInt_FromLong(0));
354
355			PyDict_SetItemString(result, s, value);
356		}
357
358		break;
359	case 1:
360		result = PyDict_New();
361
362		for(i = 0; i < num_printers; i++) {
363			PyObject *value;
364			fstring s;
365
366			rpcstr_pull(s, ctr.printers_1[i].name.buffer,
367				    sizeof(fstring), -1, STR_TERMINATE);
368
369			py_from_PRINTER_INFO_1(&value, &ctr.printers_1[i]);
370
371			PyDict_SetItemString(
372				value, "level", PyInt_FromLong(1));
373
374			PyDict_SetItemString(result, s, value);
375		}
376
377		break;
378	case 2:
379		result = PyDict_New();
380
381		for(i = 0; i < num_printers; i++) {
382			PyObject *value;
383			fstring s;
384
385			rpcstr_pull(s, ctr.printers_2[i].printername.buffer,
386				    sizeof(fstring), -1, STR_TERMINATE);
387
388			py_from_PRINTER_INFO_2(&value, &ctr.printers_2[i]);
389
390			PyDict_SetItemString(
391				value, "level", PyInt_FromLong(2));
392
393			PyDict_SetItemString(result, s, value);
394		}
395
396		break;
397	default:
398		PyErr_SetString(spoolss_error, "unknown info level");
399		goto done;
400	}
401
402done:
403	if (cli)
404		cli_shutdown(cli);
405
406	if (mem_ctx)
407		talloc_destroy(mem_ctx);
408
409	return result;
410}
411
412/* Add a printer */
413
414PyObject *spoolss_addprinterex(PyObject *self, PyObject *args, PyObject *kw)
415{
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;
425
426	if (!PyArg_ParseTupleAndKeywords(
427		    args, kw, "ssO!|O!", kwlist, &server, &printername,
428		    &PyDict_Type, &info, &PyDict_Type, &creds))
429		return NULL;
430
431	if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
432		PyErr_SetString(spoolss_error, errstr);
433		free(errstr);
434		goto done;
435	}
436
437	if (!(mem_ctx = talloc_init("spoolss_addprinterex"))) {
438		PyErr_SetString(
439			spoolss_error, "unable to init talloc context\n");
440		goto done;
441	}
442
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;
447	}
448
449	ctr.printers_2 = &info2;
450
451	werror = rpccli_spoolss_addprinterex(cli->pipe_list, mem_ctx, 2, &ctr);
452
453	Py_INCREF(Py_None);
454	result = Py_None;
455
456done:
457	if (cli)
458		cli_shutdown(cli);
459
460	if (mem_ctx)
461		talloc_destroy(mem_ctx);
462
463	return result;
464}
465