Zero some more return values.
[sfrench/samba-autobuild/.git] / source3 / python / py_spoolss_drivers.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 /* Enumerate printer drivers */
24
25 PyObject *spoolss_enumprinterdrivers(PyObject *self, PyObject *args,
26                                      PyObject *kw)
27 {
28         WERROR werror;
29         PyObject *result = NULL, *creds = NULL;
30         PRINTER_DRIVER_CTR ctr;
31         int level = 1, i;
32         uint32 needed, num_drivers;
33         char *arch = "Windows NT x86", *server, *errstr;
34         static char *kwlist[] = {"server", "level", "creds", "arch", NULL};
35         struct cli_state *cli = NULL;
36         TALLOC_CTX *mem_ctx = NULL;
37         
38         /* Parse parameters */
39
40         if (!PyArg_ParseTupleAndKeywords(
41                     args, kw, "s|iOs", kwlist, &server, &level, &creds,
42                     &arch)) 
43                 return NULL;
44         
45         if (server[0] != '\\' || server[1] != '\\') {
46                 PyErr_SetString(PyExc_ValueError, "UNC name required");
47                 return NULL;
48         }
49
50         server += 2;
51
52         if (creds && creds != Py_None && !PyDict_Check(creds)) {
53                 PyErr_SetString(PyExc_TypeError, 
54                                 "credentials must be dictionary or None");
55                 return NULL;
56         }
57
58         /* Call rpc function */
59         
60         if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
61                 PyErr_SetString(spoolss_error, errstr);
62                 free(errstr);
63                 goto done;
64         }
65
66         if (!(mem_ctx = talloc_init())) {
67                 PyErr_SetString(
68                         spoolss_error, "unable to init talloc context\n");
69                 goto done;
70         }       
71
72         werror = cli_spoolss_enumprinterdrivers(
73                 cli, mem_ctx, 0, &needed, level, arch,
74                 &num_drivers, &ctr);
75
76         if (W_ERROR_V(werror) == ERRinsufficientbuffer)
77                 werror = cli_spoolss_enumprinterdrivers(
78                         cli, mem_ctx, needed, NULL, level, arch, 
79                         &num_drivers, &ctr);
80
81         if (!W_ERROR_IS_OK(werror)) {
82                 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
83                 goto done;
84         }
85
86         /* Return value */
87
88         switch (level) {
89         case 1:
90                 result = PyDict_New();
91                 
92                 for (i = 0; i < num_drivers; i++) {
93                         PyObject *value;
94                         fstring name;
95                         
96                         rpcstr_pull(name, ctr.info1[i].name.buffer,
97                                     sizeof(fstring), -1, STR_TERMINATE);
98
99                         py_from_DRIVER_INFO_1(&value, &ctr.info1[i]);
100
101                         PyDict_SetItemString(result, name, value);
102                 }
103                 
104                 break;
105         case 2: 
106                 result = PyDict_New();
107
108                 for(i = 0; i < num_drivers; i++) {
109                         PyObject *value;
110                         fstring name;
111
112                         rpcstr_pull(name, ctr.info2[i].name.buffer,
113                                     sizeof(fstring), -1, STR_TERMINATE);
114
115                         py_from_DRIVER_INFO_2(&value, &ctr.info2[i]);
116
117                         PyDict_SetItemString(result, name, value);
118                 }
119
120                 break;
121         case 3: 
122                 result = PyDict_New();
123
124                 for(i = 0; i < num_drivers; i++) {
125                         PyObject *value;
126                         fstring name;
127
128                         rpcstr_pull(name, ctr.info3[i].name.buffer,
129                                     sizeof(fstring), -1, STR_TERMINATE);
130
131                         py_from_DRIVER_INFO_3(&value, &ctr.info3[i]);
132
133                         PyDict_SetItemString(result, name, value);
134                 }
135
136                 break;
137         case 6: 
138                 result = PyDict_New();
139
140                 for(i = 0; i < num_drivers; i++) {
141                         PyObject *value;
142                         fstring name;
143
144                         rpcstr_pull(name, ctr.info6[i].name.buffer,
145                                     sizeof(fstring), -1, STR_TERMINATE);
146
147                         py_from_DRIVER_INFO_6(&value, &ctr.info6[i]);
148
149                         PyList_SetItem(result, i, value);
150                 }
151
152                 break;
153         default:
154                 PyErr_SetString(spoolss_error, "unknown info level");
155                 goto done;
156         }
157         
158  done:
159         if (cli)
160                 cli_shutdown(cli);
161
162         if (mem_ctx)
163                 talloc_destroy(mem_ctx);
164
165         return result;
166 }
167
168 /* Fetch printer driver */
169
170 PyObject *spoolss_hnd_getprinterdriver(PyObject *self, PyObject *args,
171                                    PyObject *kw)
172 {
173         spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
174         WERROR werror;
175         PyObject *result = Py_None;
176         PRINTER_DRIVER_CTR ctr;
177         int level = 1;
178         uint32 needed;
179         char *arch = "Windows NT x86";
180         static char *kwlist[] = {"level", "arch", NULL};
181
182         /* Parse parameters */
183
184         if (!PyArg_ParseTupleAndKeywords(
185                     args, kw, "|is", kwlist, &level, &arch))
186                 return NULL;
187
188         /* Call rpc function */
189
190         werror = cli_spoolss_getprinterdriver(
191                 hnd->cli, hnd->mem_ctx, 0, &needed, &hnd->pol, level,
192                 arch, &ctr);
193
194         if (W_ERROR_V(werror) == ERRinsufficientbuffer)
195                 werror = cli_spoolss_getprinterdriver(
196                         hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol,
197                         level, arch, &ctr);
198
199         if (!W_ERROR_IS_OK(werror)) {
200                 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
201                 return NULL;
202         }
203
204         /* Return value */
205         
206         switch (level) {
207         case 1:
208                 py_from_DRIVER_INFO_1(&result, ctr.info1);
209                 break;
210         case 2: 
211                 py_from_DRIVER_INFO_2(&result, ctr.info2);
212                 break;
213         case 3: 
214                 py_from_DRIVER_INFO_3(&result, ctr.info3);
215                 break;
216         case 6:
217                 py_from_DRIVER_INFO_6(&result, ctr.info6);
218                 break;
219         default:
220                 PyErr_SetString(spoolss_error, "unsupported info level");
221                 return NULL;
222         }
223         
224         Py_INCREF(result);
225         return result;
226 }
227
228 /* Fetch printer driver directory */
229
230 PyObject *spoolss_getprinterdriverdir(PyObject *self, PyObject *args, 
231                                       PyObject *kw)
232 {
233         WERROR werror;
234         PyObject *result = NULL, *creds = NULL;
235         DRIVER_DIRECTORY_CTR ctr;
236         uint32 needed, level = 1;
237         char *arch = "Windows NT x86", *server, *errstr;
238         static char *kwlist[] = {"server", "level", "arch", "creds", NULL};
239         struct cli_state *cli = NULL;
240         TALLOC_CTX *mem_ctx = NULL;
241
242         /* Parse parameters */
243
244         if (!PyArg_ParseTupleAndKeywords(
245                     args, kw, "s|isO", kwlist, &server, &level,
246                     &arch, &creds))
247                 return NULL;
248
249         if (server[0] != '\\' || server[1] != '\\') {
250                 PyErr_SetString(PyExc_ValueError, "UNC name required");
251                 return NULL;
252         }
253
254         server += 2;
255
256         if (creds && creds != Py_None && !PyDict_Check(creds)) {
257                 PyErr_SetString(PyExc_TypeError, 
258                                 "credentials must be dictionary or None");
259                 return NULL;
260         }
261
262         /* Call rpc function */
263
264         if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
265                 PyErr_SetString(spoolss_error, errstr);
266                 free(errstr);
267                 goto done;
268         }
269         
270         if (!(mem_ctx = talloc_init())) {
271                 PyErr_SetString(
272                         spoolss_error, "unable to init talloc context\n");
273                 goto done;
274         }       
275
276         werror = cli_spoolss_getprinterdriverdir(
277                 cli, mem_ctx, 0, &needed, level, arch, &ctr);
278
279         if (W_ERROR_V(werror) == ERRinsufficientbuffer)
280                 werror = cli_spoolss_getprinterdriverdir(
281                         cli, mem_ctx, needed, NULL, level, arch, &ctr);
282
283         if (!W_ERROR_IS_OK(werror)) {
284                 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
285                 goto done;
286         }
287
288         /* Return value */
289         
290         switch (level) {
291         case 1:
292                 py_from_DRIVER_DIRECTORY_1(&result, ctr.info1);
293                 break;
294         default:
295                 PyErr_SetString(spoolss_error, "unknown info level");
296                 goto done;      
297         }
298         
299  done:
300         if (cli)
301                 cli_shutdown(cli);
302         
303         if (mem_ctx)
304                 talloc_destroy(mem_ctx);
305
306         return result;
307 }
308
309 PyObject *spoolss_addprinterdriver(PyObject *self, PyObject *args,
310                                    PyObject *kw)
311 {
312         static char *kwlist[] = { "server", "info", "creds", NULL };
313         char *server, *errstr;
314         uint32 level;
315         PyObject *info, *result = NULL, *creds = NULL;
316         WERROR werror;
317         TALLOC_CTX *mem_ctx = NULL;
318         struct cli_state *cli = NULL;
319         PRINTER_DRIVER_CTR ctr;
320         union {
321                 DRIVER_INFO_3 driver_3;
322         } dinfo;
323
324         if (!PyArg_ParseTupleAndKeywords(
325                     args, kw, "sO!|O", kwlist, &server, &PyDict_Type,
326                     &info, &creds))
327                 return NULL;
328         
329         if (server[0] == '\\' || server[1] == '\\')
330                 server += 2;
331
332         if (creds && creds != Py_None && !PyDict_Check(creds)) {
333                 PyErr_SetString(PyExc_TypeError, 
334                                 "credentials must be dictionary or None");
335                 return NULL;
336         }
337
338         if (!(mem_ctx = talloc_init())) {
339                 PyErr_SetString(
340                         spoolss_error, "unable to init talloc context\n");
341                 return NULL;
342         }
343
344         if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
345                 PyErr_SetString(spoolss_error, errstr);
346                 free(errstr);
347                 goto done;
348         }
349
350         if (!get_level_value(info, &level)) {
351                 PyErr_SetString(spoolss_error, "invalid info level");
352                 goto done;
353         }
354
355         if (level != 3) {
356                 PyErr_SetString(spoolss_error, "unsupported info level");
357                 goto done;
358         }
359
360         ZERO_STRUCT(ctr);
361         ZERO_STRUCT(dinfo);
362
363         switch(level) {
364         case 3:
365                 ctr.info3 = &dinfo.driver_3;
366
367                 if (!py_to_DRIVER_INFO_3(&dinfo.driver_3, info)) {
368                         PyErr_SetString(spoolss_error,
369                                         "error converting to driver info 3");
370                         goto done;
371                 }
372
373                 break;
374         default:
375                 PyErr_SetString(spoolss_error, "unsupported info level");
376                 goto done;
377         }
378
379         werror = cli_spoolss_addprinterdriver(cli, mem_ctx, level, &ctr);
380
381         if (!W_ERROR_IS_OK(werror)) {
382                 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
383                 goto done;
384         }
385
386         Py_INCREF(Py_None);
387         result = Py_None;
388
389 done:
390         if (cli)
391                 cli_shutdown(cli);
392
393         if (mem_ctx)
394                 talloc_destroy(mem_ctx);
395         
396         return result;
397         
398 }
399
400 PyObject *spoolss_addprinterdriverex(PyObject *self, PyObject *args,
401                                              PyObject *kw)
402 {
403         /* Not supported by Samba server */
404         
405         PyErr_SetString(spoolss_error, "Not implemented");
406         return NULL;
407 }
408         
409 PyObject *spoolss_deleteprinterdriver(PyObject *self, PyObject *args,
410                                       PyObject *kw)
411 {
412         PyErr_SetString(spoolss_error, "Not implemented");
413         return NULL;
414 }
415
416 PyObject *spoolss_deleteprinterdriverex(PyObject *self, PyObject *args,
417                                         PyObject *kw)
418 {
419         PyErr_SetString(spoolss_error, "Not implemented");
420         return NULL;
421 }