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