Fix return value for enumprinterdrivers(), getprinterdriverdir().
[bbaumbach/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|iO!s", kwlist, &server, &level, &PyDict_Type,
42                     &creds, &arch))
43                 return NULL;
44         
45         /* Call rpc function */
46         
47         if (!(cli = open_pipe_creds(
48                       server, creds, cli_spoolss_initialise, &errstr))) {
49                 PyErr_SetString(spoolss_error, errstr);
50                 free(errstr);
51                 goto done;
52         }
53
54         if (!(mem_ctx = talloc_init())) {
55                 PyErr_SetString(
56                         spoolss_error, "unable to init talloc context\n");
57                 goto done;
58         }       
59
60         werror = cli_spoolss_enumprinterdrivers(
61                 cli, mem_ctx, 0, &needed, level, arch,
62                 &num_drivers, &ctr);
63
64         if (W_ERROR_V(werror) == ERRinsufficientbuffer)
65                 werror = cli_spoolss_enumprinterdrivers(
66                         cli, mem_ctx, needed, NULL, level, arch, 
67                         &num_drivers, &ctr);
68
69         if (!W_ERROR_IS_OK(werror)) {
70                 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
71                 goto done;
72         }
73
74         /* Return value */
75
76         switch (level) {
77         case 1:
78                 result = PyDict_New();
79                 
80                 for (i = 0; i < num_drivers; i++) {
81                         PyObject *value;
82                         fstring name;
83                         
84                         rpcstr_pull(name, ctr.info1[i].name.buffer,
85                                     sizeof(fstring), -1, STR_TERMINATE);
86
87                         py_from_DRIVER_INFO_1(&value, &ctr.info1[i]);
88
89                         PyDict_SetItemString(
90                                 value, "level", PyInt_FromLong(1));
91
92                         PyDict_SetItemString(result, name, value);
93                 }
94                 
95                 break;
96         case 2: 
97                 result = PyDict_New();
98
99                 for(i = 0; i < num_drivers; i++) {
100                         PyObject *value;
101                         fstring name;
102
103                         rpcstr_pull(name, ctr.info2[i].name.buffer,
104                                     sizeof(fstring), -1, STR_TERMINATE);
105
106                         py_from_DRIVER_INFO_2(&value, &ctr.info2[i]);
107
108                         PyDict_SetItemString(
109                                 value, "level", PyInt_FromLong(2));
110
111                         PyDict_SetItemString(result, name, value);
112                 }
113
114                 break;
115         case 3: 
116                 result = PyDict_New();
117
118                 for(i = 0; i < num_drivers; i++) {
119                         PyObject *value;
120                         fstring name;
121
122                         rpcstr_pull(name, ctr.info3[i].name.buffer,
123                                     sizeof(fstring), -1, STR_TERMINATE);
124
125                         py_from_DRIVER_INFO_3(&value, &ctr.info3[i]);
126
127                         PyDict_SetItemString(
128                                 value, "level", PyInt_FromLong(3));
129
130                         PyDict_SetItemString(result, name, value);
131                 }
132
133                 break;
134         case 6: 
135                 result = PyDict_New();
136
137                 for(i = 0; i < num_drivers; i++) {
138                         PyObject *value;
139                         fstring name;
140
141                         rpcstr_pull(name, ctr.info6[i].name.buffer,
142                                     sizeof(fstring), -1, STR_TERMINATE);
143
144                         py_from_DRIVER_INFO_6(&value, &ctr.info6[i]);
145
146                         PyDict_SetItemString(
147                                 value, "level", PyInt_FromLong(6));
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 6:
214                 py_from_DRIVER_INFO_6(&result,  ctr.info6);
215                 break;
216         default:
217                 break;
218         }
219         
220         Py_INCREF(result);
221         return result;
222 }
223
224 /* Fetch printer driver directory */
225
226 PyObject *spoolss_getprinterdriverdir(PyObject *self, PyObject *args, 
227                                       PyObject *kw)
228 {
229         WERROR werror;
230         PyObject *result = NULL, *creds = NULL;
231         DRIVER_DIRECTORY_CTR ctr;
232         uint32 needed, level = 1;
233         char *arch = "Windows NT x86", *server, *errstr;
234         static char *kwlist[] = {"server", "level", "arch", "creds", NULL};
235         struct cli_state *cli = NULL;
236         TALLOC_CTX *mem_ctx = NULL;
237
238         /* Parse parameters */
239
240         if (!PyArg_ParseTupleAndKeywords(
241                     args, kw, "s|isO!", kwlist, &server, &level,
242                     &arch, &PyDict_Type, &creds))
243                 return NULL;
244
245         /* Call rpc function */
246
247         if (!(cli = open_pipe_creds(
248                       server, creds, cli_spoolss_initialise, &errstr))) {
249                 PyErr_SetString(spoolss_error, errstr);
250                 free(errstr);
251                 goto done;
252         }
253         
254         if (!(mem_ctx = talloc_init())) {
255                 PyErr_SetString(
256                         spoolss_error, "unable to init talloc context\n");
257                 goto done;
258         }       
259
260         werror = cli_spoolss_getprinterdriverdir(
261                 cli, mem_ctx, 0, &needed, level, arch, &ctr);
262
263         if (W_ERROR_V(werror) == ERRinsufficientbuffer)
264                 werror = cli_spoolss_getprinterdriverdir(
265                         cli, mem_ctx, needed, NULL, level, arch, &ctr);
266
267         if (!W_ERROR_IS_OK(werror)) {
268                 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
269                 goto done;
270         }
271
272         /* Return value */
273         
274         switch (level) {
275         case 1:
276                 py_from_DRIVER_DIRECTORY_1(&result, ctr.info1);
277                 PyDict_SetItemString(
278                         result, "level", PyInt_FromLong(1));
279                 break;
280         default:
281                 PyErr_SetString(spoolss_error, "unknown info level");
282                 goto done;      
283         }
284         
285  done:
286         if (cli)
287                 cli_shutdown(cli);
288         
289         if (mem_ctx)
290                 talloc_destroy(mem_ctx);
291
292         return result;
293 }
294
295 PyObject *spoolss_addprinterdriver(PyObject *self, PyObject *args,
296                                    PyObject *kw)
297 {
298         static char *kwlist[] = { "server", "info", "creds", NULL };
299         char *server, *errstr;
300         uint32 level;
301         PyObject *info, *result = NULL, *creds = NULL, *level_obj;
302         WERROR werror;
303         TALLOC_CTX *mem_ctx;
304         struct cli_state *cli;
305         PRINTER_DRIVER_CTR ctr;
306         union {
307                 DRIVER_INFO_3 driver_3;
308         } dinfo;
309
310         if (!PyArg_ParseTupleAndKeywords(
311                     args, kw, "sO!|O!", kwlist, &server, &PyDict_Type,
312                     &info, &PyDict_Type, &creds))
313                 return NULL;
314         
315         if (server[0] == '\\' && server[1] == '\\')
316                 server += 2;
317
318         if (!(mem_ctx = talloc_init())) {
319                 PyErr_SetString(
320                         spoolss_error, "unable to init talloc context\n");
321                 return NULL;
322         }
323
324         if (!(cli = open_pipe_creds(
325                       server, creds, cli_spoolss_initialise, &errstr))) {
326                 PyErr_SetString(spoolss_error, errstr);
327                 free(errstr);
328                 goto done;
329         }
330
331         if ((level_obj = PyDict_GetItemString(info, "level"))) {
332
333                 if (!PyInt_Check(level_obj)) {
334                         PyErr_SetString(spoolss_error, 
335                                         "level not an integer");
336                         goto done;
337                 }
338
339                 level = PyInt_AsLong(level_obj);
340
341                 /* Only level 2, 3 supported by NT */
342
343                 if (level != 3) {
344                         PyErr_SetString(spoolss_error,
345                                         "unsupported info level");
346                         goto done;
347                 }
348
349         } else {
350                 PyErr_SetString(spoolss_error, "no info level present");
351                 goto done;
352         }
353         
354         ZERO_STRUCT(ctr);
355         
356         switch(level) {
357         case 3:
358                 ctr.info3 = &dinfo.driver_3;
359
360                 if (!py_to_DRIVER_INFO_3(&dinfo.driver_3, info)) {
361                         PyErr_SetString(spoolss_error,
362                                         "error converting to driver info 3");
363                         goto done;
364                 }
365
366                 break;
367         default:
368                 PyErr_SetString(spoolss_error, "unsupported info level");
369                 goto done;
370         }
371
372         werror = cli_spoolss_addprinterdriver(cli, mem_ctx, level, &ctr);
373
374         if (!W_ERROR_IS_OK(werror)) {
375                 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
376                 goto done;
377         }
378
379         Py_INCREF(Py_None);
380         result = Py_None;
381
382 done:
383         cli_shutdown(cli);
384         talloc_destroy(mem_ctx);
385         
386         return result;
387         
388 }
389
390 PyObject *spoolss_addprinterdriverex(PyObject *self, PyObject *args,
391                                              PyObject *kw)
392 {
393         /* Not supported by Samba server */
394         
395         PyErr_SetString(spoolss_error, "Not implemented");
396         return NULL;
397 }
398         
399 PyObject *spoolss_deleteprinterdriver(PyObject *self, PyObject *args,
400                                       PyObject *kw)
401 {
402         PyErr_SetString(spoolss_error, "Not implemented");
403         return NULL;
404 }
405
406 PyObject *spoolss_deleteprinterdriverex(PyObject *self, PyObject *args,
407                                         PyObject *kw)
408 {
409         PyErr_SetString(spoolss_error, "Not implemented");
410         return NULL;
411 }