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