Added samr_open_domain() call.
[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())) {
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 PyMethodDef samr_domain_methods[] = {
155         { NULL }
156 };
157
158 static PyObject *py_samr_domain_hnd_getattr(PyObject *self, char *attrname)
159 {
160         return Py_FindMethod(samr_domain_methods, self, attrname);
161 }
162
163 PyTypeObject samr_domain_hnd_type = {
164         PyObject_HEAD_INIT(NULL)
165         0,
166         "SAMR Domain Handle",
167         sizeof(samr_domain_hnd_object),
168         0,
169         py_samr_domain_hnd_dealloc, /*tp_dealloc*/
170         0,          /*tp_print*/
171         py_samr_domain_hnd_getattr,          /*tp_getattr*/
172         0,          /*tp_setattr*/
173         0,          /*tp_compare*/
174         0,          /*tp_repr*/
175         0,          /*tp_as_number*/
176         0,          /*tp_as_sequence*/
177         0,          /*tp_as_mapping*/
178         0,          /*tp_hash */
179 };
180
181 /* SAMR user handle object */
182
183 static void py_samr_user_hnd_dealloc(PyObject* self)
184 {
185         PyObject_Del(self);
186 }
187
188 static PyMethodDef samr_user_methods[] = {
189         { NULL }
190 };
191
192 static PyObject *py_samr_user_hnd_getattr(PyObject *self, char *attrname)
193 {
194         return Py_FindMethod(samr_user_methods, self, attrname);
195 }
196
197 PyTypeObject samr_user_hnd_type = {
198         PyObject_HEAD_INIT(NULL)
199         0,
200         "SAMR User Handle",
201         sizeof(samr_user_hnd_object),
202         0,
203         py_samr_user_hnd_dealloc, /*tp_dealloc*/
204         0,          /*tp_print*/
205         py_samr_user_hnd_getattr,          /*tp_getattr*/
206         0,          /*tp_setattr*/
207         0,          /*tp_compare*/
208         0,          /*tp_repr*/
209         0,          /*tp_as_number*/
210         0,          /*tp_as_sequence*/
211         0,          /*tp_as_mapping*/
212         0,          /*tp_hash */
213 };
214
215 PyObject *new_samr_user_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
216                                       POLICY_HND *pol)
217 {
218         samr_user_hnd_object *o;
219
220         o = PyObject_New(samr_user_hnd_object, &samr_user_hnd_type);
221
222         o->cli = cli;
223         o->mem_ctx = mem_ctx;
224         memcpy(&o->user_pol, pol, sizeof(POLICY_HND));
225
226         return (PyObject*)o;
227 }
228
229 /* SAMR group handle object */
230
231 static void py_samr_group_hnd_dealloc(PyObject* self)
232 {
233         PyObject_Del(self);
234 }
235
236 static PyMethodDef samr_group_methods[] = {
237         { NULL }
238 };
239
240 static PyObject *py_samr_group_hnd_getattr(PyObject *self, char *attrname)
241 {
242         return Py_FindMethod(samr_group_methods, self, attrname);
243 }
244
245 PyTypeObject samr_group_hnd_type = {
246         PyObject_HEAD_INIT(NULL)
247         0,
248         "SAMR Group Handle",
249         sizeof(samr_group_hnd_object),
250         0,
251         py_samr_group_hnd_dealloc, /*tp_dealloc*/
252         0,          /*tp_print*/
253         py_samr_group_hnd_getattr,          /*tp_getattr*/
254         0,          /*tp_setattr*/
255         0,          /*tp_compare*/
256         0,          /*tp_repr*/
257         0,          /*tp_as_number*/
258         0,          /*tp_as_sequence*/
259         0,          /*tp_as_mapping*/
260         0,          /*tp_hash */
261 };
262
263 PyObject *new_samr_group_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
264                                       POLICY_HND *pol)
265 {
266         samr_group_hnd_object *o;
267
268         o = PyObject_New(samr_group_hnd_object, &samr_group_hnd_type);
269
270         o->cli = cli;
271         o->mem_ctx = mem_ctx;
272         memcpy(&o->group_pol, pol, sizeof(POLICY_HND));
273
274         return (PyObject*)o;
275 }
276
277 /* Alias handle object */
278
279 static void py_samr_alias_hnd_dealloc(PyObject* self)
280 {
281         PyObject_Del(self);
282 }
283
284 static PyMethodDef samr_alias_methods[] = {
285         { NULL }
286 };
287
288 static PyObject *py_samr_alias_hnd_getattr(PyObject *self, char *attrname)
289 {
290         return Py_FindMethod(samr_alias_methods, self, attrname);
291 }
292
293 PyTypeObject samr_alias_hnd_type = {
294         PyObject_HEAD_INIT(NULL)
295         0,
296         "SAMR Alias Handle",
297         sizeof(samr_alias_hnd_object),
298         0,
299         py_samr_alias_hnd_dealloc, /*tp_dealloc*/
300         0,          /*tp_print*/
301         py_samr_alias_hnd_getattr,          /*tp_getattr*/
302         0,          /*tp_setattr*/
303         0,          /*tp_compare*/
304         0,          /*tp_repr*/
305         0,          /*tp_as_number*/
306         0,          /*tp_as_sequence*/
307         0,          /*tp_as_mapping*/
308         0,          /*tp_hash */
309 };
310
311 PyObject *new_samr_alias_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
312                                       POLICY_HND *pol)
313 {
314         samr_alias_hnd_object *o;
315
316         o = PyObject_New(samr_alias_hnd_object, &samr_alias_hnd_type);
317
318         o->cli = cli;
319         o->mem_ctx = mem_ctx;
320         memcpy(&o->alias_pol, pol, sizeof(POLICY_HND));
321
322         return (PyObject*)o;
323 }
324
325 static PyObject *samr_connect(PyObject *self, PyObject *args, PyObject *kw)
326 {
327         static char *kwlist[] = { "server", "creds", "access", NULL };
328         uint32 desired_access = MAXIMUM_ALLOWED_ACCESS;
329         char *server, *errstr;
330         struct cli_state *cli = NULL;
331         POLICY_HND hnd;
332         TALLOC_CTX *mem_ctx = NULL;
333         PyObject *result = NULL, *creds = NULL;
334         NTSTATUS ntstatus;
335
336         if (!PyArg_ParseTupleAndKeywords(
337                     args, kw, "s|Oi", kwlist, &server, &creds,
338                     &desired_access)) 
339                 return NULL;
340
341         if (server[0] != '\\' || server[1] != '\\') {
342                 PyErr_SetString(PyExc_ValueError, "UNC name required");
343                 return NULL;
344         }
345
346         server += 2;
347
348         if (creds && creds != Py_None && !PyDict_Check(creds)) {
349                 PyErr_SetString(PyExc_TypeError, 
350                                 "credentials must be dictionary or None");
351                 return NULL;
352         }
353
354         if (!(cli = open_pipe_creds(server, creds, PIPE_SAMR, &errstr))) {
355                 PyErr_SetString(samr_error, errstr);
356                 free(errstr);
357                 return NULL;
358         }
359
360         if (!(mem_ctx = talloc_init())) {
361                 PyErr_SetString(samr_ntstatus,
362                                 "unable to init talloc context\n");
363                 goto done;
364         }
365
366         ntstatus = cli_samr_connect(cli, mem_ctx, desired_access, &hnd);
367
368         if (!NT_STATUS_IS_OK(ntstatus)) {
369                 cli_shutdown(cli);
370                 SAFE_FREE(cli);
371                 PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
372                 goto done;
373         }
374
375         result = new_samr_connect_hnd_object(cli, mem_ctx, &hnd);
376
377 done:
378         if (!result) {
379                 if (cli)
380                         cli_shutdown(cli);
381
382                 if (mem_ctx)
383                         talloc_destroy(mem_ctx);
384         }
385
386         return result;
387 }
388
389 /*
390  * Module initialisation 
391  */
392
393 static PyMethodDef samr_methods[] = {
394
395         /* Open/close samr connect handles */
396         
397         { "connect", (PyCFunction)samr_connect, 
398           METH_VARARGS | METH_KEYWORDS, 
399           "Open a connect handle" },
400         
401         { NULL }
402 };
403
404 static struct const_vals {
405         char *name;
406         uint32 value;
407 } module_const_vals[] = {
408         { NULL }
409 };
410
411 static void const_init(PyObject *dict)
412 {
413         struct const_vals *tmp;
414         PyObject *obj;
415
416         for (tmp = module_const_vals; tmp->name; tmp++) {
417                 obj = PyInt_FromLong(tmp->value);
418                 PyDict_SetItemString(dict, tmp->name, obj);
419                 Py_DECREF(obj);
420         }
421 }
422
423 void initsamr(void)
424 {
425         PyObject *module, *dict;
426
427         /* Initialise module */
428
429         module = Py_InitModule("samr", samr_methods);
430         dict = PyModule_GetDict(module);
431
432         samr_error = PyErr_NewException("samr.error", NULL, NULL);
433         PyDict_SetItemString(dict, "error", samr_error);
434
435         samr_ntstatus = PyErr_NewException("samr.ntstatus", NULL, NULL);
436         PyDict_SetItemString(dict, "ntstatus", samr_ntstatus);
437
438         /* Initialise policy handle object */
439
440         samr_connect_hnd_type.ob_type = &PyType_Type;
441         samr_domain_hnd_type.ob_type = &PyType_Type;
442         samr_user_hnd_type.ob_type = &PyType_Type;
443         samr_group_hnd_type.ob_type = &PyType_Type;
444         samr_alias_hnd_type.ob_type = &PyType_Type;
445
446         /* Initialise constants */
447
448         const_init(dict);
449
450         /* Do samba initialisation */
451
452         py_samba_init();
453
454         setup_logging("samr", True);
455         DEBUGLEVEL = 10;
456 }