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