Throw a spoolss.werror exception when the rpc client routines return
[samba.git] / source / python / py_spoolss_printers.c
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
25 PyObject *spoolss_openprinter(PyObject *self, PyObject *args, PyObject *kw)
26 {
27         char *full_name, *computer_name = NULL;
28         TALLOC_CTX *mem_ctx;
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|O!i", kwlist, &full_name, &PyDict_Type, &creds,
38                 &desired_access)) {
39
40                 goto done;
41         }
42
43         /* FIXME: Return name format exception for names without a UNC
44            prefix */ 
45
46         computer_name = strdup(full_name + 2);
47
48         if (strchr(computer_name, '\\')) {
49                 char *c = strchr(computer_name, '\\');
50                 *c = 0;
51         }
52
53         if (!(cli = open_pipe_creds(computer_name, creds, 
54                                     cli_spoolss_initialise, NULL))) {
55                 fprintf(stderr, "could not initialise cli state\n");
56                 goto done;
57         }
58
59         if (!(mem_ctx = talloc_init())) {
60                 fprintf(stderr, "unable to initialise talloc context\n");
61                 goto done;
62         }
63
64         werror = cli_spoolss_open_printer_ex(
65                 cli, mem_ctx, full_name, "", desired_access, computer_name, 
66                 "", &hnd);
67
68         if (!W_ERROR_IS_OK(werror)) {
69                 cli_shutdown(cli);
70                 SAFE_FREE(cli);
71                 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
72                 goto done;
73         }
74
75         result = new_policy_hnd_object(cli, mem_ctx, &hnd);
76
77  done:
78         SAFE_FREE(computer_name);
79
80         return result;
81 }
82
83 /* Close a printer */
84
85 PyObject *spoolss_closeprinter(PyObject *self, PyObject *args)
86 {
87         PyObject *po;
88         spoolss_policy_hnd_object *hnd;
89         WERROR result;
90
91         /* Parse parameters */
92
93         if (!PyArg_ParseTuple(args, "O!", &spoolss_policy_hnd_type, &po))
94                 return NULL;
95
96         hnd = (spoolss_policy_hnd_object *)po;
97
98         /* Call rpc function */
99
100         result = cli_spoolss_close_printer(hnd->cli, hnd->mem_ctx, &hnd->pol);
101
102         /* Cleanup samba stuf */
103
104         cli_shutdown(hnd->cli);
105         talloc_destroy(hnd->mem_ctx);
106
107         /* Return value */
108
109         Py_INCREF(Py_None);
110         return Py_None; 
111 }
112
113 /* Fetch printer information */
114
115 PyObject *spoolss_getprinter(PyObject *self, PyObject *args, PyObject *kw)
116 {
117         spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
118         WERROR werror;
119         PyObject *result = NULL;
120         PRINTER_INFO_CTR ctr;
121         int level = 1;
122         uint32 needed;
123         static char *kwlist[] = {"level", NULL};
124
125         /* Parse parameters */
126
127         if (!PyArg_ParseTupleAndKeywords(args, kw, "|i", kwlist, &level))
128                 return NULL;
129         
130         /* Call rpc function */
131         
132         werror = cli_spoolss_getprinter(
133                 hnd->cli, hnd->mem_ctx, 0, &needed, &hnd->pol, level, &ctr);
134
135         if (W_ERROR_V(werror) == ERRinsufficientbuffer)
136                 werror = cli_spoolss_getprinter(
137                         hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol,
138                         level, &ctr);
139
140         /* Return value */
141
142         if (!W_ERROR_IS_OK(werror)) {
143                 PyErr_SetObject(spoolss_werror,
144                                 PyInt_FromLong(W_ERROR_V(werror)));
145                 return NULL;
146         }
147
148         result = Py_None;
149
150         switch (level) {
151                 
152         case 0:
153                 py_from_PRINTER_INFO_0(&result, ctr.printers_0);
154                 break;
155
156         case 1:
157                 py_from_PRINTER_INFO_1(&result, ctr.printers_1);
158                 break;
159
160         case 2:
161                 py_from_PRINTER_INFO_2(&result, ctr.printers_2);
162                 break;
163
164         case 3:
165                 py_from_PRINTER_INFO_3(&result, ctr.printers_3);
166                 break;
167         }
168
169         PyDict_SetItemString(result, "level", PyInt_FromLong(level));
170
171  done:
172         Py_INCREF(result);
173         return result;
174 }
175
176 /* Set printer information */
177
178 PyObject *spoolss_setprinter(PyObject *self, PyObject *args, PyObject *kw)
179 {
180         spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
181         WERROR werror;
182         PyObject *info, *level_obj;
183         PRINTER_INFO_CTR ctr;
184         uint32 level;
185         static char *kwlist[] = {"dict", NULL};
186         union {
187                 PRINTER_INFO_0 printers_0;
188                 PRINTER_INFO_1 printers_1;
189                 PRINTER_INFO_2 printers_2;
190                 PRINTER_INFO_3 printers_3;
191                 PRINTER_INFO_4 printers_4;
192                 PRINTER_INFO_5 printers_5;
193         } pinfo;
194
195         /* Parse parameters */
196
197         if (!PyArg_ParseTupleAndKeywords(args, kw, "O!", kwlist, 
198                                          &PyDict_Type, &info))
199                 return NULL;
200         
201         /* Check dictionary contains a level */
202
203         if ((level_obj = PyDict_GetItemString(info, "level"))) {
204
205                 if (!PyInt_Check(level_obj))
206                         goto error;
207
208                 level = PyInt_AsLong(level_obj);
209
210         } else {
211         error:
212                 PyErr_SetString(spoolss_error, "invalid info");
213                 return NULL;
214         }
215
216         /* Fill in printer info */
217
218         ZERO_STRUCT(ctr);
219
220         switch (level) {
221         case 2: {
222                 PyObject *devmode_obj;
223
224                 ctr.printers_2 = &pinfo.printers_2;
225
226                 if (!py_to_PRINTER_INFO_2(&pinfo.printers_2, info))
227                         goto error;
228
229 #if 0
230                 devmode_obj = PyDict_GetItemString(info, "device_mode");
231
232                 pinfo.printers_2.devmode = talloc(
233                         hnd->mem_ctx, sizeof(DEVICEMODE));
234
235                 PyDEVICEMODE_AsDEVICEMODE(pinfo.printers_2.devmode, 
236                                           devmode_obj);
237
238 #else
239
240                 /* FIXME: can we actually set the security descriptor using
241                    a setprinter level 2? */
242
243                 pinfo.printers_2.secdesc = NULL;
244                 pinfo.printers_2.secdesc = NULL;
245
246 #endif
247                 break;
248         }
249         default:
250                 PyErr_SetString(spoolss_error, "unsupported info level");
251                 return NULL;
252         }
253
254         /* Call rpc function */
255         
256         werror = cli_spoolss_setprinter(hnd->cli, hnd->mem_ctx, &hnd->pol,
257                                         level, &ctr, 0);
258
259         /* Return value */
260
261         if (!W_ERROR_IS_OK(werror)) {
262                 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
263                 return NULL;
264         }
265
266         Py_INCREF(Py_None);
267         return Py_None;
268 }
269
270 /* Enumerate printers */
271
272 PyObject *spoolss_enumprinters(PyObject *self, PyObject *args, PyObject *kw)
273 {
274         WERROR werror;
275         PyObject *result, *creds = NULL;
276         PRINTER_INFO_CTR ctr;
277         int level = 1, flags = PRINTER_ENUM_LOCAL, i;
278         uint32 needed, num_printers;
279         static char *kwlist[] = {"server", "name", "level", "flags", 
280                                  "creds", NULL};
281         TALLOC_CTX *mem_ctx = NULL;
282         struct cli_state *cli = NULL;
283         char *server, *name = NULL;
284
285         /* Parse parameters */
286
287         if (!PyArg_ParseTupleAndKeywords(args, kw, "s|siiO!", kwlist, 
288                                          &server, &name, &level, &flags, 
289                                          &PyDict_Type, &creds))
290                 return NULL;
291         
292         if (server[0] == '\\' && server[1] == '\\')
293                 server += 2;
294
295         mem_ctx = talloc_init();
296         cli = open_pipe_creds(server, creds, cli_spoolss_initialise, NULL);
297
298         /* Call rpc function */
299         
300         werror = cli_spoolss_enum_printers(
301                 cli, mem_ctx, 0, &needed, flags, level,
302                 &num_printers, &ctr);
303
304         if (W_ERROR_V(werror) == ERRinsufficientbuffer)
305                 werror = cli_spoolss_enum_printers(
306                         cli, mem_ctx, needed, NULL, flags, level,
307                         &num_printers, &ctr);
308
309         /* Return value */
310         
311         if (!W_ERROR_IS_OK(werror)) {
312                 PyErr_SetObject(spoolss_werror,
313                                 PyInt_FromLong(W_ERROR_V(werror)));
314                 return NULL;
315         }
316
317         result = PyList_New(num_printers);
318
319         switch (level) {
320         case 0: 
321                 for (i = 0; i < num_printers; i++) {
322                         PyObject *value;
323
324                         py_from_PRINTER_INFO_0(&value, &ctr.printers_0[i]);
325
326                         PyList_SetItem(result, i, value);
327                 }
328
329                 break;
330         case 1:
331                 for(i = 0; i < num_printers; i++) {
332                         PyObject *value;
333
334                         py_from_PRINTER_INFO_1(&value, &ctr.printers_1[i]);
335
336                         PyList_SetItem(result, i, value);
337                 }
338                 
339                 break;
340         case 2:
341                 for(i = 0; i < num_printers; i++) {
342                         PyObject *value;
343
344                         py_from_PRINTER_INFO_2(&value, &ctr.printers_2[i]);
345
346                         PyList_SetItem(result, i, value);
347                 }
348                 
349                 break;
350         case 3:
351                 for(i = 0; i < num_printers; i++) {
352                         PyObject *value;
353
354                         py_from_PRINTER_INFO_3(&value, &ctr.printers_3[i]);
355
356                         PyList_SetItem(result, i, value);
357                 }
358                 
359                 break;
360         }
361
362         Py_INCREF(result);
363         return result;
364 }