r5283: Merge -r5279 and-r5280 from trunk.
[samba.git] / source / 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("spoolss_enumprinterdrivers"))) {
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         int version = 2;
181         static char *kwlist[] = {"level", "arch", NULL};
182
183         /* Parse parameters */
184
185         if (!PyArg_ParseTupleAndKeywords(
186                     args, kw, "|is", kwlist, &level, &arch))
187                 return NULL;
188
189         /* Call rpc function */
190
191         werror = cli_spoolss_getprinterdriver(
192                 hnd->cli, hnd->mem_ctx, 0, &needed, &hnd->pol, level,
193                 arch, version, &ctr);
194
195         if (W_ERROR_V(werror) == ERRinsufficientbuffer)
196                 werror = cli_spoolss_getprinterdriver(
197                         hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol,
198                         level, arch, version, &ctr);
199
200         if (!W_ERROR_IS_OK(werror)) {
201                 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
202                 return NULL;
203         }
204
205         /* Return value */
206         
207         switch (level) {
208         case 1:
209                 py_from_DRIVER_INFO_1(&result, ctr.info1);
210                 break;
211         case 2: 
212                 py_from_DRIVER_INFO_2(&result, ctr.info2);
213                 break;
214         case 3: 
215                 py_from_DRIVER_INFO_3(&result, ctr.info3);
216                 break;
217         case 6:
218                 py_from_DRIVER_INFO_6(&result, ctr.info6);
219                 break;
220         default:
221                 PyErr_SetString(spoolss_error, "unsupported info level");
222                 return NULL;
223         }
224         
225         Py_INCREF(result);
226         return result;
227 }
228
229 /* Fetch printer driver directory */
230
231 PyObject *spoolss_getprinterdriverdir(PyObject *self, PyObject *args, 
232                                       PyObject *kw)
233 {
234         WERROR werror;
235         PyObject *result = NULL, *creds = NULL;
236         DRIVER_DIRECTORY_CTR ctr;
237         uint32 needed, level = 1;
238         char *arch = "Windows NT x86", *server, *errstr;
239         static char *kwlist[] = {"server", "level", "arch", "creds", NULL};
240         struct cli_state *cli = NULL;
241         TALLOC_CTX *mem_ctx = NULL;
242
243         /* Parse parameters */
244
245         if (!PyArg_ParseTupleAndKeywords(
246                     args, kw, "s|isO", kwlist, &server, &level,
247                     &arch, &creds))
248                 return NULL;
249
250         if (server[0] != '\\' || server[1] != '\\') {
251                 PyErr_SetString(PyExc_ValueError, "UNC name required");
252                 return NULL;
253         }
254
255         server += 2;
256
257         if (creds && creds != Py_None && !PyDict_Check(creds)) {
258                 PyErr_SetString(PyExc_TypeError, 
259                                 "credentials must be dictionary or None");
260                 return NULL;
261         }
262
263         /* Call rpc function */
264
265         if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
266                 PyErr_SetString(spoolss_error, errstr);
267                 free(errstr);
268                 goto done;
269         }
270         
271         if (!(mem_ctx = talloc_init("spoolss_getprinterdriverdir"))) {
272                 PyErr_SetString(
273                         spoolss_error, "unable to init talloc context\n");
274                 goto done;
275         }       
276
277         werror = cli_spoolss_getprinterdriverdir(
278                 cli, mem_ctx, 0, &needed, level, arch, &ctr);
279
280         if (W_ERROR_V(werror) == ERRinsufficientbuffer)
281                 werror = cli_spoolss_getprinterdriverdir(
282                         cli, mem_ctx, needed, NULL, level, arch, &ctr);
283
284         if (!W_ERROR_IS_OK(werror)) {
285                 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
286                 goto done;
287         }
288
289         /* Return value */
290         
291         switch (level) {
292         case 1:
293                 py_from_DRIVER_DIRECTORY_1(&result, ctr.info1);
294                 break;
295         default:
296                 PyErr_SetString(spoolss_error, "unknown info level");
297                 goto done;      
298         }
299         
300  done:
301         if (cli)
302                 cli_shutdown(cli);
303         
304         if (mem_ctx)
305                 talloc_destroy(mem_ctx);
306
307         return result;
308 }
309
310 PyObject *spoolss_addprinterdriver(PyObject *self, PyObject *args,
311                                    PyObject *kw)
312 {
313         static char *kwlist[] = { "server", "info", "creds", NULL };
314         char *server, *errstr;
315         uint32 level;
316         PyObject *info, *result = NULL, *creds = NULL;
317         WERROR werror;
318         TALLOC_CTX *mem_ctx = NULL;
319         struct cli_state *cli = NULL;
320         PRINTER_DRIVER_CTR ctr;
321         union {
322                 DRIVER_INFO_3 driver_3;
323         } dinfo;
324
325         if (!PyArg_ParseTupleAndKeywords(
326                     args, kw, "sO!|O", kwlist, &server, &PyDict_Type,
327                     &info, &creds))
328                 return NULL;
329         
330         if (server[0] == '\\' || server[1] == '\\')
331                 server += 2;
332
333         if (creds && creds != Py_None && !PyDict_Check(creds)) {
334                 PyErr_SetString(PyExc_TypeError, 
335                                 "credentials must be dictionary or None");
336                 return NULL;
337         }
338
339         if (!(mem_ctx = talloc_init("spoolss_addprinterdriver"))) {
340                 PyErr_SetString(
341                         spoolss_error, "unable to init talloc context\n");
342                 return NULL;
343         }
344
345         if (!(cli = open_pipe_creds(server, creds, PI_SPOOLSS, &errstr))) {
346                 PyErr_SetString(spoolss_error, errstr);
347                 free(errstr);
348                 goto done;
349         }
350
351         if (!get_level_value(info, &level)) {
352                 PyErr_SetString(spoolss_error, "invalid info level");
353                 goto done;
354         }
355
356         if (level != 3) {
357                 PyErr_SetString(spoolss_error, "unsupported info level");
358                 goto done;
359         }
360
361         ZERO_STRUCT(ctr);
362         ZERO_STRUCT(dinfo);
363
364         switch(level) {
365         case 3:
366                 ctr.info3 = &dinfo.driver_3;
367
368                 if (!py_to_DRIVER_INFO_3(&dinfo.driver_3, info, mem_ctx)) {
369                         PyErr_SetString(spoolss_error,
370                                         "error converting to driver info 3");
371                         goto done;
372                 }
373
374                 break;
375         default:
376                 PyErr_SetString(spoolss_error, "unsupported info level");
377                 goto done;
378         }
379
380         werror = cli_spoolss_addprinterdriver(cli, mem_ctx, level, &ctr);
381
382         if (!W_ERROR_IS_OK(werror)) {
383                 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
384                 goto done;
385         }
386
387         Py_INCREF(Py_None);
388         result = Py_None;
389
390 done:
391         if (cli)
392                 cli_shutdown(cli);
393
394         if (mem_ctx)
395                 talloc_destroy(mem_ctx);
396         
397         return result;
398         
399 }
400
401 PyObject *spoolss_addprinterdriverex(PyObject *self, PyObject *args,
402                                              PyObject *kw)
403 {
404         /* Not supported by Samba server */
405         
406         PyErr_SetString(spoolss_error, "Not implemented");
407         return NULL;
408 }
409         
410 PyObject *spoolss_deleteprinterdriver(PyObject *self, PyObject *args,
411                                       PyObject *kw)
412 {
413         PyErr_SetString(spoolss_error, "Not implemented");
414         return NULL;
415 }
416
417 PyObject *spoolss_deleteprinterdriverex(PyObject *self, PyObject *args,
418                                         PyObject *kw)
419 {
420         PyErr_SetString(spoolss_error, "Not implemented");
421         return NULL;
422 }