This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.
[kai/samba.git] / source / python / py_samr.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_samr.h"
22
23 /* 
24  * Exceptions raised by this module 
25  */
26
27 PyObject *samr_error;           /* This indicates a non-RPC related error
28                                    such as name lookup failure */
29
30 PyObject *samr_ntstatus;        /* This exception is raised when a RPC call
31                                    returns a status code other than
32                                    NT_STATUS_OK */
33
34 /* SAMR connect handle object */
35
36 static void py_samr_connect_hnd_dealloc(PyObject* self)
37 {
38         PyObject_Del(self);
39 }
40
41 PyObject *new_samr_domain_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
42                                      POLICY_HND *pol)
43 {
44         samr_domain_hnd_object *o;
45
46         o = PyObject_New(samr_domain_hnd_object, &samr_domain_hnd_type);
47
48         o->cli = cli;
49         o->mem_ctx = mem_ctx;
50         memcpy(&o->domain_pol, pol, sizeof(POLICY_HND));
51
52         return (PyObject*)o;
53 }
54
55 static PyObject *samr_open_domain(PyObject *self, PyObject *args, PyObject *kw)
56 {
57         samr_connect_hnd_object *connect_hnd = (samr_connect_hnd_object *)self;
58         static char *kwlist[] = { "sid", "access", NULL };
59         uint32 desired_access = MAXIMUM_ALLOWED_ACCESS;
60         char *sid_str;
61         DOM_SID sid;
62         TALLOC_CTX *mem_ctx = NULL;
63         POLICY_HND domain_pol;
64         NTSTATUS ntstatus;
65         PyObject *result = NULL;
66
67         if (!PyArg_ParseTupleAndKeywords(
68                     args, kw, "s|i", kwlist, &sid_str, &desired_access))
69                 return NULL;
70
71         if (!string_to_sid(&sid, sid_str)) {
72                 PyErr_SetString(PyExc_TypeError, "string is not a sid");
73                 return NULL;
74         }
75
76         if (!(mem_ctx = talloc_init("samr_open_domain"))) {
77                 PyErr_SetString(samr_error, "unable to init talloc context");
78                 return NULL;
79         }
80
81         ntstatus = cli_samr_open_domain(
82                 connect_hnd->cli, mem_ctx, &connect_hnd->connect_pol,
83                 desired_access, &sid, &domain_pol);
84                                         
85         if (!NT_STATUS_IS_OK(ntstatus)) {
86                 PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
87                 goto done;
88         }
89
90         result = new_samr_domain_hnd_object(
91                 connect_hnd->cli, mem_ctx, &domain_pol);
92
93 done:
94         if (!result) {
95                 if (mem_ctx)
96                         talloc_destroy(mem_ctx);
97         }
98
99         return result;
100 }
101
102 static PyMethodDef samr_connect_methods[] = {
103         { "open_domain", (PyCFunction)samr_open_domain,
104           METH_VARARGS | METH_KEYWORDS,
105           "Open a handle on a domain" },
106
107         { NULL }
108 };
109
110 static PyObject *py_samr_connect_hnd_getattr(PyObject *self, char *attrname)
111 {
112         return Py_FindMethod(samr_connect_methods, self, attrname);
113 }
114
115 PyTypeObject samr_connect_hnd_type = {
116         PyObject_HEAD_INIT(NULL)
117         0,
118         "SAMR Connect Handle",
119         sizeof(samr_connect_hnd_object),
120         0,
121         py_samr_connect_hnd_dealloc, /*tp_dealloc*/
122         0,          /*tp_print*/
123         py_samr_connect_hnd_getattr,          /*tp_getattr*/
124         0,          /*tp_setattr*/
125         0,          /*tp_compare*/
126         0,          /*tp_repr*/
127         0,          /*tp_as_number*/
128         0,          /*tp_as_sequence*/
129         0,          /*tp_as_mapping*/
130         0,          /*tp_hash */
131 };
132
133 PyObject *new_samr_connect_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
134                                       POLICY_HND *pol)
135 {
136         samr_connect_hnd_object *o;
137
138         o = PyObject_New(samr_connect_hnd_object, &samr_connect_hnd_type);
139
140         o->cli = cli;
141         o->mem_ctx = mem_ctx;
142         memcpy(&o->connect_pol, pol, sizeof(POLICY_HND));
143
144         return (PyObject*)o;
145 }
146
147 /* SAMR domain handle object */
148
149 static void py_samr_domain_hnd_dealloc(PyObject* self)
150 {
151         PyObject_Del(self);
152 }
153
154 static PyObject *samr_enum_dom_groups(PyObject *self, PyObject *args, 
155                                       PyObject *kw)
156 {
157         samr_domain_hnd_object *domain_hnd = (samr_domain_hnd_object *)self;
158         static char *kwlist[] = { NULL };
159         TALLOC_CTX *mem_ctx;
160 /*      uint32 desired_access = MAXIMUM_ALLOWED_ACCESS; */
161         uint32 start_idx, size, num_dom_groups;
162         struct acct_info *dom_groups;
163         NTSTATUS result;
164         PyObject *py_result = NULL;
165         
166         if (!PyArg_ParseTupleAndKeywords(
167                     args, kw, "", kwlist))
168                 return NULL;
169
170         if (!(mem_ctx = talloc_init("samr_enum_dom_groups"))) {
171                 PyErr_SetString(samr_error, "unable to init talloc context");
172                 return NULL;
173         }
174
175         start_idx = 0;
176         size = 0xffff;
177
178         do {
179                 result = cli_samr_enum_dom_groups(
180                         domain_hnd->cli, mem_ctx, &domain_hnd->domain_pol,
181                         &start_idx, size, &dom_groups, &num_dom_groups);
182
183                 if (NT_STATUS_IS_OK(result) ||
184                     NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
185                         py_from_acct_info(&py_result, dom_groups,
186                                           num_dom_groups);
187                 }
188
189         } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
190
191         return py_result;
192 }       
193
194 static PyMethodDef samr_domain_methods[] = {
195         { "enum_domain_groups", (PyCFunction)samr_enum_dom_groups,
196           METH_VARARGS | METH_KEYWORDS, "Enumerate domain groups" },
197         { NULL }
198 };
199
200 static PyObject *py_samr_domain_hnd_getattr(PyObject *self, char *attrname)
201 {
202         return Py_FindMethod(samr_domain_methods, self, attrname);
203 }
204
205 PyTypeObject samr_domain_hnd_type = {
206         PyObject_HEAD_INIT(NULL)
207         0,
208         "SAMR Domain Handle",
209         sizeof(samr_domain_hnd_object),
210         0,
211         py_samr_domain_hnd_dealloc, /*tp_dealloc*/
212         0,          /*tp_print*/
213         py_samr_domain_hnd_getattr,          /*tp_getattr*/
214         0,          /*tp_setattr*/
215         0,          /*tp_compare*/
216         0,          /*tp_repr*/
217         0,          /*tp_as_number*/
218         0,          /*tp_as_sequence*/
219         0,          /*tp_as_mapping*/
220         0,          /*tp_hash */
221 };
222
223 /* SAMR user handle object */
224
225 static void py_samr_user_hnd_dealloc(PyObject* self)
226 {
227         PyObject_Del(self);
228 }
229
230 static PyMethodDef samr_user_methods[] = {
231         { NULL }
232 };
233
234 static PyObject *py_samr_user_hnd_getattr(PyObject *self, char *attrname)
235 {
236         return Py_FindMethod(samr_user_methods, self, attrname);
237 }
238
239 PyTypeObject samr_user_hnd_type = {
240         PyObject_HEAD_INIT(NULL)
241         0,
242         "SAMR User Handle",
243         sizeof(samr_user_hnd_object),
244         0,
245         py_samr_user_hnd_dealloc, /*tp_dealloc*/
246         0,          /*tp_print*/
247         py_samr_user_hnd_getattr,          /*tp_getattr*/
248         0,          /*tp_setattr*/
249         0,          /*tp_compare*/
250         0,          /*tp_repr*/
251         0,          /*tp_as_number*/
252         0,          /*tp_as_sequence*/
253         0,          /*tp_as_mapping*/
254         0,          /*tp_hash */
255 };
256
257 PyObject *new_samr_user_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
258                                       POLICY_HND *pol)
259 {
260         samr_user_hnd_object *o;
261
262         o = PyObject_New(samr_user_hnd_object, &samr_user_hnd_type);
263
264         o->cli = cli;
265         o->mem_ctx = mem_ctx;
266         memcpy(&o->user_pol, pol, sizeof(POLICY_HND));
267
268         return (PyObject*)o;
269 }
270
271 /* SAMR group handle object */
272
273 static void py_samr_group_hnd_dealloc(PyObject* self)
274 {
275         PyObject_Del(self);
276 }
277
278 static PyMethodDef samr_group_methods[] = {
279         { NULL }
280 };
281
282 static PyObject *py_samr_group_hnd_getattr(PyObject *self, char *attrname)
283 {
284         return Py_FindMethod(samr_group_methods, self, attrname);
285 }
286
287 PyTypeObject samr_group_hnd_type = {
288         PyObject_HEAD_INIT(NULL)
289         0,
290         "SAMR Group Handle",
291         sizeof(samr_group_hnd_object),
292         0,
293         py_samr_group_hnd_dealloc, /*tp_dealloc*/
294         0,          /*tp_print*/
295         py_samr_group_hnd_getattr,          /*tp_getattr*/
296         0,          /*tp_setattr*/
297         0,          /*tp_compare*/
298         0,          /*tp_repr*/
299         0,          /*tp_as_number*/
300         0,          /*tp_as_sequence*/
301         0,          /*tp_as_mapping*/
302         0,          /*tp_hash */
303 };
304
305 PyObject *new_samr_group_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
306                                       POLICY_HND *pol)
307 {
308         samr_group_hnd_object *o;
309
310         o = PyObject_New(samr_group_hnd_object, &samr_group_hnd_type);
311
312         o->cli = cli;
313         o->mem_ctx = mem_ctx;
314         memcpy(&o->group_pol, pol, sizeof(POLICY_HND));
315
316         return (PyObject*)o;
317 }
318
319 /* Alias handle object */
320
321 static void py_samr_alias_hnd_dealloc(PyObject* self)
322 {
323         PyObject_Del(self);
324 }
325
326 static PyMethodDef samr_alias_methods[] = {
327         { NULL }
328 };
329
330 static PyObject *py_samr_alias_hnd_getattr(PyObject *self, char *attrname)
331 {
332         return Py_FindMethod(samr_alias_methods, self, attrname);
333 }
334
335 PyTypeObject samr_alias_hnd_type = {
336         PyObject_HEAD_INIT(NULL)
337         0,
338         "SAMR Alias Handle",
339         sizeof(samr_alias_hnd_object),
340         0,
341         py_samr_alias_hnd_dealloc, /*tp_dealloc*/
342         0,          /*tp_print*/
343         py_samr_alias_hnd_getattr,          /*tp_getattr*/
344         0,          /*tp_setattr*/
345         0,          /*tp_compare*/
346         0,          /*tp_repr*/
347         0,          /*tp_as_number*/
348         0,          /*tp_as_sequence*/
349         0,          /*tp_as_mapping*/
350         0,          /*tp_hash */
351 };
352
353 PyObject *new_samr_alias_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
354                                       POLICY_HND *pol)
355 {
356         samr_alias_hnd_object *o;
357
358         o = PyObject_New(samr_alias_hnd_object, &samr_alias_hnd_type);
359
360         o->cli = cli;
361         o->mem_ctx = mem_ctx;
362         memcpy(&o->alias_pol, pol, sizeof(POLICY_HND));
363
364         return (PyObject*)o;
365 }
366
367 static PyObject *samr_connect(PyObject *self, PyObject *args, PyObject *kw)
368 {
369         static char *kwlist[] = { "server", "creds", "access", NULL };
370         uint32 desired_access = MAXIMUM_ALLOWED_ACCESS;
371         char *server, *errstr;
372         struct cli_state *cli = NULL;
373         POLICY_HND hnd;
374         TALLOC_CTX *mem_ctx = NULL;
375         PyObject *result = NULL, *creds = NULL;
376         NTSTATUS ntstatus;
377
378         if (!PyArg_ParseTupleAndKeywords(
379                     args, kw, "s|Oi", kwlist, &server, &creds,
380                     &desired_access)) 
381                 return NULL;
382
383         if (server[0] != '\\' || server[1] != '\\') {
384                 PyErr_SetString(PyExc_ValueError, "UNC name required");
385                 return NULL;
386         }
387
388         server += 2;
389
390         if (creds && creds != Py_None && !PyDict_Check(creds)) {
391                 PyErr_SetString(PyExc_TypeError, 
392                                 "credentials must be dictionary or None");
393                 return NULL;
394         }
395
396         if (!(cli = open_pipe_creds(server, creds, PI_SAMR, &errstr))) {
397                 PyErr_SetString(samr_error, errstr);
398                 free(errstr);
399                 return NULL;
400         }
401
402         if (!(mem_ctx = talloc_init("samr_connect"))) {
403                 PyErr_SetString(samr_ntstatus,
404                                 "unable to init talloc context\n");
405                 goto done;
406         }
407
408         ntstatus = cli_samr_connect(cli, mem_ctx, desired_access, &hnd);
409
410         if (!NT_STATUS_IS_OK(ntstatus)) {
411                 cli_shutdown(cli);
412                 PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
413                 goto done;
414         }
415
416         result = new_samr_connect_hnd_object(cli, mem_ctx, &hnd);
417
418 done:
419         if (!result) {
420                 if (cli)
421                         cli_shutdown(cli);
422
423                 if (mem_ctx)
424                         talloc_destroy(mem_ctx);
425         }
426
427         return result;
428 }
429
430 /*
431  * Module initialisation 
432  */
433
434 static PyMethodDef samr_methods[] = {
435
436         /* Open/close samr connect handles */
437         
438         { "connect", (PyCFunction)samr_connect, 
439           METH_VARARGS | METH_KEYWORDS, 
440           "Open a connect handle" },
441         
442         { NULL }
443 };
444
445 static struct const_vals {
446         char *name;
447         uint32 value;
448 } module_const_vals[] = {
449         { NULL }
450 };
451
452 static void const_init(PyObject *dict)
453 {
454         struct const_vals *tmp;
455         PyObject *obj;
456
457         for (tmp = module_const_vals; tmp->name; tmp++) {
458                 obj = PyInt_FromLong(tmp->value);
459                 PyDict_SetItemString(dict, tmp->name, obj);
460                 Py_DECREF(obj);
461         }
462 }
463
464 void initsamr(void)
465 {
466         PyObject *module, *dict;
467
468         /* Initialise module */
469
470         module = Py_InitModule("samr", samr_methods);
471         dict = PyModule_GetDict(module);
472
473         samr_error = PyErr_NewException("samr.error", NULL, NULL);
474         PyDict_SetItemString(dict, "error", samr_error);
475
476         samr_ntstatus = PyErr_NewException("samr.ntstatus", NULL, NULL);
477         PyDict_SetItemString(dict, "ntstatus", samr_ntstatus);
478
479         /* Initialise policy handle object */
480
481         samr_connect_hnd_type.ob_type = &PyType_Type;
482         samr_domain_hnd_type.ob_type = &PyType_Type;
483         samr_user_hnd_type.ob_type = &PyType_Type;
484         samr_group_hnd_type.ob_type = &PyType_Type;
485         samr_alias_hnd_type.ob_type = &PyType_Type;
486
487         /* Initialise constants */
488
489         const_init(dict);
490
491         /* Do samba initialisation */
492
493         py_samba_init();
494
495         setup_logging("samr", True);
496         DEBUGLEVEL = 10;
497 }