088dc54576bd721d84a3aa16a63d16910fd88dba
[jra/samba/.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 = Py_None, *creds = NULL;
30         PRINTER_DRIVER_CTR ctr;
31         int level = 1, i;
32         uint32 needed, num_drivers;
33         char *arch = "Windows NT x86", *server_name;
34         static char *kwlist[] = {"server", "creds", "level", "arch", NULL};
35         struct cli_state *cli = NULL;
36         TALLOC_CTX *mem_ctx = NULL;
37
38         /* Parse parameters */
39
40         if (!PyArg_ParseTupleAndKeywords(args, kw, "s|O!is", kwlist, 
41                                          &server_name, &PyDict_Type, &creds,
42                                          &level, &arch))
43                 return NULL;
44         
45         /* Call rpc function */
46         
47         if (!(cli = open_pipe_creds(server_name, creds, 
48                                     cli_spoolss_initialise, NULL))) {
49                 fprintf(stderr, "could not initialise cli state\n");
50                 goto done;
51         }
52
53         if (!(mem_ctx = talloc_init())) {
54                 fprintf(stderr, "unable to initialise talloc context\n");
55                 goto done;
56         }       
57
58         werror = cli_spoolss_enumprinterdrivers(
59                 cli, mem_ctx, 0, &needed, level, arch,
60                 &num_drivers, &ctr);
61
62         if (W_ERROR_V(werror) == ERRinsufficientbuffer)
63                 werror = cli_spoolss_enumprinterdrivers(
64                         cli, mem_ctx, needed, NULL, level, arch, 
65                         &num_drivers, &ctr);
66
67         if (!W_ERROR_IS_OK(werror)) {
68                 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
69                 goto done;
70         }
71
72         /* Return value */
73         
74         switch (level) {
75         case 1:
76                 result = PyDict_New();
77                 
78                 for (i = 0; i < num_drivers; i++) {
79                         PyObject *value;
80                         fstring name;
81                         
82                         rpcstr_pull(name, ctr.info1[i].name.buffer,
83                                     sizeof(fstring), -1, STR_TERMINATE);
84
85                         py_from_DRIVER_INFO_1(&value, &ctr.info1[i]);
86
87                         PyDict_SetItemString(
88                                 value, "level", PyInt_FromLong(1));
89
90                         PyDict_SetItemString(result, name, value);
91                 }
92                 
93                 break;
94         case 2: 
95                 result = PyDict_New();
96
97                 for(i = 0; i < num_drivers; i++) {
98                         PyObject *value;
99                         fstring name;
100
101                         rpcstr_pull(name, ctr.info2[i].name.buffer,
102                                     sizeof(fstring), -1, STR_TERMINATE);
103
104                         py_from_DRIVER_INFO_2(&value, &ctr.info2[i]);
105
106                         PyDict_SetItemString(
107                                 value, "level", PyInt_FromLong(2));
108
109                         PyDict_SetItemString(result, name, value);
110                 }
111
112                 break;
113         case 3: 
114                 result = PyDict_New();
115
116                 for(i = 0; i < num_drivers; i++) {
117                         PyObject *value;
118                         fstring name;
119
120                         rpcstr_pull(name, ctr.info3[i].name.buffer,
121                                     sizeof(fstring), -1, STR_TERMINATE);
122
123                         py_from_DRIVER_INFO_3(&value, &ctr.info3[i]);
124
125                         PyDict_SetItemString(
126                                 value, "level", PyInt_FromLong(3));
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                         PyDict_SetItemString(
145                                 value, "level", PyInt_FromLong(6));
146
147                         PyList_SetItem(result, i, value);
148                 }
149
150                 break;
151         default:
152                 PyErr_SetString(spoolss_error, "unknown info level returned");
153                 result = NULL;
154                 break;
155         }
156         
157  done:
158         if (cli)
159                 cli_shutdown(cli);
160
161         if (mem_ctx)
162                 talloc_destroy(mem_ctx);
163
164         Py_INCREF(result);
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(args, kw, "|is", kwlist, 
185                                          &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 = Py_None, *creds = NULL;
231         DRIVER_DIRECTORY_CTR ctr;
232         uint32 needed, level;
233         char *arch = "Windows NT x86", *server_name;
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(args, kw, "s|isO!", kwlist, 
241                                          &server_name, &level, &arch,
242                                          &PyDict_Type, &creds))
243                 return NULL;
244
245         /* Call rpc function */
246
247         if (!(cli = open_pipe_creds(server_name, creds, 
248                                     cli_spoolss_initialise, NULL))) {
249                 fprintf(stderr, "could not initialise cli state\n");
250                 goto done;
251         }
252
253         if (!(mem_ctx = talloc_init())) {
254                 fprintf(stderr, "unable to initialise talloc context\n");
255                 goto done;
256         }       
257
258         werror = cli_spoolss_getprinterdriverdir(
259                 cli, mem_ctx, 0, &needed, level, arch, &ctr);
260
261         if (W_ERROR_V(werror) == ERRinsufficientbuffer)
262                 werror = cli_spoolss_getprinterdriverdir(
263                         cli, mem_ctx, needed, NULL, level, arch, &ctr);
264
265         if (!W_ERROR_IS_OK(werror)) {
266                 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
267                 return NULL;
268         }
269
270         /* Return value */
271         
272         switch (level) {
273         case 1:
274                 py_from_DRIVER_DIRECTORY_1(&result, ctr.info1);
275                 break;
276         }
277         
278  done:
279         if (cli)
280                 cli_shutdown(cli);
281         
282         if (mem_ctx)
283                 talloc_destroy(mem_ctx);
284
285         Py_INCREF(result);
286         return result;
287 }
288
289 PyObject *spoolss_addprinterdriver(PyObject *self, PyObject *args,
290                                    PyObject *kw)
291 {
292         static char *kwlist[] = { "server", "info", "creds", NULL };
293         char *server;
294         uint32 level;
295         PyObject *info, *result = NULL, *creds = NULL, *level_obj;
296         WERROR werror;
297         TALLOC_CTX *mem_ctx;
298         struct cli_state *cli;
299         PRINTER_DRIVER_CTR ctr;
300         union {
301                 DRIVER_INFO_3 driver_3;
302         } dinfo;
303
304         if (!PyArg_ParseTupleAndKeywords(
305                     args, kw, "sO!|O!", kwlist, &server, &PyDict_Type,
306                     &info, &PyDict_Type, &creds))
307                 return NULL;
308         
309         if (server[0] == '\\' && server[1] == '\\')
310                 server += 2;
311
312         mem_ctx = talloc_init();
313
314         if (!(cli = open_pipe_creds(server, creds, cli_spoolss_initialise,
315                                     NULL)))
316                 goto done;
317
318         if ((level_obj = PyDict_GetItemString(info, "level"))) {
319
320                 if (!PyInt_Check(level_obj)) {
321                         PyErr_SetString(spoolss_error, 
322                                         "level not an integer");
323                         goto done;
324                 }
325
326                 level = PyInt_AsLong(level_obj);
327
328                 /* Only level 2, 3 supported by NT */
329
330                 if (level != 3) {
331                         PyErr_SetString(spoolss_error,
332                                         "unsupported info level");
333                         goto done;
334                 }
335
336         } else {
337                 PyErr_SetString(spoolss_error, "no info level present");
338                 goto done;
339         }
340
341         ZERO_STRUCT(ctr);
342
343         switch(level) {
344         case 3:
345                 ctr.info3 = &dinfo.driver_3;
346
347                 if (!py_to_DRIVER_INFO_3(&dinfo.driver_3, info)) {
348                         PyErr_SetString(spoolss_error,
349                                         "error converting to driver info 3");
350                         goto done;
351                 }
352
353                 break;
354         default:
355                 PyErr_SetString(spoolss_error, "unsupported info level");
356                 goto done;
357         }
358
359         werror = cli_spoolss_addprinterdriver(cli, mem_ctx, level, &ctr);
360
361         if (!W_ERROR_IS_OK(werror)) {
362                 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
363                 goto done;
364         }
365
366         Py_INCREF(Py_None);
367         result = Py_None;
368
369 done:
370         cli_shutdown(cli);
371         talloc_destroy(mem_ctx);
372
373         return result;
374 }
375
376 PyObject *spoolss_addprinterdriverex(PyObject *self, PyObject *args,
377                                      PyObject *kw)
378 {
379         /* Not supported by Samba server */
380
381         PyErr_SetString(spoolss_error, "Not implemented");
382         return NULL;
383 }
384
385 PyObject *spoolss_deleteprinterdriver(PyObject *self, PyObject *args,
386                                       PyObject *kw)
387 {
388         PyErr_SetString(spoolss_error, "Not implemented");
389         return NULL;
390 }
391
392 PyObject *spoolss_deleteprinterdriverex(PyObject *self, PyObject *args,
393                                         PyObject *kw)
394 {
395         PyErr_SetString(spoolss_error, "Not implemented");
396         return NULL;
397 }