Apply the changes that Derrell Lipman supplied ...
[Samba/gebeck_regimport.git] / source3 / python / py_samr.c
blob57acd74bedb138c5d45d4c4e073cb2751385312b
1 /*
2 Python wrappers for DCERPC/SMB client routines.
4 Copyright (C) Tim Potter, 2002
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.
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.
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.
21 #include "python/py_samr.h"
23 /*
24 * Exceptions raised by this module
27 PyObject *samr_error; /* This indicates a non-RPC related error
28 such as name lookup failure */
30 PyObject *samr_ntstatus; /* This exception is raised when a RPC call
31 returns a status code other than
32 NT_STATUS_OK */
34 /* SAMR group handle object */
36 static void py_samr_group_hnd_dealloc(PyObject* self)
38 PyObject_Del(self);
41 static PyMethodDef samr_group_methods[] = {
42 { NULL }
45 static PyObject *py_samr_group_hnd_getattr(PyObject *self, char *attrname)
47 return Py_FindMethod(samr_group_methods, self, attrname);
50 PyTypeObject samr_group_hnd_type = {
51 PyObject_HEAD_INIT(NULL)
53 "SAMR Group Handle",
54 sizeof(samr_group_hnd_object),
56 py_samr_group_hnd_dealloc, /*tp_dealloc*/
57 0, /*tp_print*/
58 py_samr_group_hnd_getattr, /*tp_getattr*/
59 0, /*tp_setattr*/
60 0, /*tp_compare*/
61 0, /*tp_repr*/
62 0, /*tp_as_number*/
63 0, /*tp_as_sequence*/
64 0, /*tp_as_mapping*/
65 0, /*tp_hash */
68 PyObject *new_samr_group_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
69 POLICY_HND *pol)
71 samr_group_hnd_object *o;
73 o = PyObject_New(samr_group_hnd_object, &samr_group_hnd_type);
75 o->cli = cli;
76 o->mem_ctx = mem_ctx;
77 memcpy(&o->group_pol, pol, sizeof(POLICY_HND));
79 return (PyObject*)o;
82 /* Alias handle object */
84 static void py_samr_alias_hnd_dealloc(PyObject* self)
86 PyObject_Del(self);
89 static PyMethodDef samr_alias_methods[] = {
90 { NULL }
93 static PyObject *py_samr_alias_hnd_getattr(PyObject *self, char *attrname)
95 return Py_FindMethod(samr_alias_methods, self, attrname);
98 PyTypeObject samr_alias_hnd_type = {
99 PyObject_HEAD_INIT(NULL)
101 "SAMR Alias Handle",
102 sizeof(samr_alias_hnd_object),
104 py_samr_alias_hnd_dealloc, /*tp_dealloc*/
105 0, /*tp_print*/
106 py_samr_alias_hnd_getattr, /*tp_getattr*/
107 0, /*tp_setattr*/
108 0, /*tp_compare*/
109 0, /*tp_repr*/
110 0, /*tp_as_number*/
111 0, /*tp_as_sequence*/
112 0, /*tp_as_mapping*/
113 0, /*tp_hash */
116 PyObject *new_samr_alias_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
117 POLICY_HND *pol)
119 samr_alias_hnd_object *o;
121 o = PyObject_New(samr_alias_hnd_object, &samr_alias_hnd_type);
123 o->cli = cli;
124 o->mem_ctx = mem_ctx;
125 memcpy(&o->alias_pol, pol, sizeof(POLICY_HND));
127 return (PyObject*)o;
130 /* SAMR user handle object */
132 static void py_samr_user_hnd_dealloc(PyObject* self)
134 PyObject_Del(self);
137 static PyObject *samr_set_user_info2(PyObject *self, PyObject *args,
138 PyObject *kw)
140 samr_user_hnd_object *user_hnd = (samr_user_hnd_object *)self;
141 static char *kwlist[] = { "dict", NULL };
142 PyObject *info, *result = NULL;
143 SAM_USERINFO_CTR ctr;
144 TALLOC_CTX *mem_ctx;
145 uchar sess_key[16];
146 NTSTATUS ntstatus;
147 int level;
148 union {
149 SAM_USER_INFO_10 id10;
150 SAM_USER_INFO_21 id21;
151 } pinfo;
153 if (!PyArg_ParseTupleAndKeywords(
154 args, kw, "O!", kwlist, &PyDict_Type, &info))
155 return NULL;
157 if (!get_level_value(info, &level)) {
158 PyErr_SetString(samr_error, "invalid info level");
159 return NULL;
162 ZERO_STRUCT(ctr);
164 ctr.switch_value = level;
166 switch(level) {
167 case 0x10:
168 ctr.info.id10 = &pinfo.id10;
170 if (!py_to_SAM_USER_INFO_10(ctr.info.id10, info)) {
171 PyErr_SetString(
172 samr_error, "error converting user info");
173 goto done;
176 break;
177 case 21:
178 ctr.info.id21 = &pinfo.id21;
180 if (!py_to_SAM_USER_INFO_21(ctr.info.id21, info)) {
181 PyErr_SetString(
182 samr_error, "error converting user info");
183 goto done;
186 break;
187 default:
188 PyErr_SetString(samr_error, "unsupported info level");
189 goto done;
192 /* Call RPC function */
194 if (!(mem_ctx = talloc_init("samr_set_user_info2"))) {
195 PyErr_SetString(
196 samr_error, "unable to init talloc context\n");
197 goto done;
200 ntstatus = cli_samr_set_userinfo2(
201 user_hnd->cli, mem_ctx, &user_hnd->user_pol, level,
202 sess_key, &ctr);
204 talloc_destroy(mem_ctx);
206 if (!NT_STATUS_IS_OK(ntstatus)) {
207 PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
208 goto done;
211 Py_INCREF(Py_None);
212 result = Py_None;
214 done:
215 return result;
218 static PyObject *samr_delete_dom_user(PyObject *self, PyObject *args,
219 PyObject *kw)
221 samr_user_hnd_object *user_hnd = (samr_user_hnd_object *)self;
222 static char *kwlist[] = { NULL };
223 NTSTATUS ntstatus;
224 TALLOC_CTX *mem_ctx;
225 PyObject *result = NULL;
227 if (!PyArg_ParseTupleAndKeywords(
228 args, kw, "", kwlist))
229 return NULL;
231 if (!(mem_ctx = talloc_init("samr_delete_dom_user"))) {
232 PyErr_SetString(samr_error, "unable to init talloc context");
233 return NULL;
236 ntstatus = cli_samr_delete_dom_user(
237 user_hnd->cli, mem_ctx, &user_hnd->user_pol);
239 if (!NT_STATUS_IS_OK(ntstatus)) {
240 PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
241 goto done;
244 Py_INCREF(Py_None);
245 result = Py_None;
247 done:
248 talloc_destroy(mem_ctx);
250 return result;
253 static PyMethodDef samr_user_methods[] = {
254 { "delete_domain_user", (PyCFunction)samr_delete_dom_user,
255 METH_VARARGS | METH_KEYWORDS,
256 "Delete domain user." },
257 { "set_user_info2", (PyCFunction)samr_set_user_info2,
258 METH_VARARGS | METH_KEYWORDS,
259 "Set user info 2" },
260 { NULL }
263 static PyObject *py_samr_user_hnd_getattr(PyObject *self, char *attrname)
265 return Py_FindMethod(samr_user_methods, self, attrname);
268 PyTypeObject samr_user_hnd_type = {
269 PyObject_HEAD_INIT(NULL)
271 "SAMR User Handle",
272 sizeof(samr_user_hnd_object),
274 py_samr_user_hnd_dealloc, /*tp_dealloc*/
275 0, /*tp_print*/
276 py_samr_user_hnd_getattr, /*tp_getattr*/
277 0, /*tp_setattr*/
278 0, /*tp_compare*/
279 0, /*tp_repr*/
280 0, /*tp_as_number*/
281 0, /*tp_as_sequence*/
282 0, /*tp_as_mapping*/
283 0, /*tp_hash */
286 PyObject *new_samr_user_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
287 POLICY_HND *pol)
289 samr_user_hnd_object *o;
291 o = PyObject_New(samr_user_hnd_object, &samr_user_hnd_type);
293 o->cli = cli;
294 o->mem_ctx = mem_ctx;
295 memcpy(&o->user_pol, pol, sizeof(POLICY_HND));
297 return (PyObject*)o;
300 /* SAMR connect handle object */
302 static void py_samr_connect_hnd_dealloc(PyObject* self)
304 PyObject_Del(self);
307 PyObject *new_samr_domain_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
308 POLICY_HND *pol)
310 samr_domain_hnd_object *o;
312 o = PyObject_New(samr_domain_hnd_object, &samr_domain_hnd_type);
314 o->cli = cli;
315 o->mem_ctx = mem_ctx;
316 memcpy(&o->domain_pol, pol, sizeof(POLICY_HND));
318 return (PyObject*)o;
321 static PyObject *samr_open_domain(PyObject *self, PyObject *args, PyObject *kw)
323 samr_connect_hnd_object *connect_hnd = (samr_connect_hnd_object *)self;
324 static char *kwlist[] = { "sid", "access", NULL };
325 uint32 desired_access = MAXIMUM_ALLOWED_ACCESS;
326 char *sid_str;
327 DOM_SID sid;
328 TALLOC_CTX *mem_ctx = NULL;
329 POLICY_HND domain_pol;
330 NTSTATUS ntstatus;
331 PyObject *result = NULL;
333 if (!PyArg_ParseTupleAndKeywords(
334 args, kw, "s|i", kwlist, &sid_str, &desired_access))
335 return NULL;
337 if (!string_to_sid(&sid, sid_str)) {
338 PyErr_SetString(PyExc_TypeError, "string is not a sid");
339 return NULL;
342 if (!(mem_ctx = talloc_init("samr_open_domain"))) {
343 PyErr_SetString(samr_error, "unable to init talloc context");
344 return NULL;
347 ntstatus = cli_samr_open_domain(
348 connect_hnd->cli, mem_ctx, &connect_hnd->connect_pol,
349 desired_access, &sid, &domain_pol);
351 if (!NT_STATUS_IS_OK(ntstatus)) {
352 PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
353 goto done;
356 result = new_samr_domain_hnd_object(
357 connect_hnd->cli, mem_ctx, &domain_pol);
359 done:
360 if (!result) {
361 if (mem_ctx)
362 talloc_destroy(mem_ctx);
365 return result;
368 static PyMethodDef samr_connect_methods[] = {
369 { "open_domain", (PyCFunction)samr_open_domain,
370 METH_VARARGS | METH_KEYWORDS,
371 "Open a handle on a domain" },
373 { NULL }
376 static PyObject *py_samr_connect_hnd_getattr(PyObject *self, char *attrname)
378 return Py_FindMethod(samr_connect_methods, self, attrname);
381 PyTypeObject samr_connect_hnd_type = {
382 PyObject_HEAD_INIT(NULL)
384 "SAMR Connect Handle",
385 sizeof(samr_connect_hnd_object),
387 py_samr_connect_hnd_dealloc, /*tp_dealloc*/
388 0, /*tp_print*/
389 py_samr_connect_hnd_getattr, /*tp_getattr*/
390 0, /*tp_setattr*/
391 0, /*tp_compare*/
392 0, /*tp_repr*/
393 0, /*tp_as_number*/
394 0, /*tp_as_sequence*/
395 0, /*tp_as_mapping*/
396 0, /*tp_hash */
399 PyObject *new_samr_connect_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
400 POLICY_HND *pol)
402 samr_connect_hnd_object *o;
404 o = PyObject_New(samr_connect_hnd_object, &samr_connect_hnd_type);
406 o->cli = cli;
407 o->mem_ctx = mem_ctx;
408 memcpy(&o->connect_pol, pol, sizeof(POLICY_HND));
410 return (PyObject*)o;
413 /* SAMR domain handle object */
415 static void py_samr_domain_hnd_dealloc(PyObject* self)
417 PyObject_Del(self);
420 static PyObject *samr_enum_dom_groups(PyObject *self, PyObject *args,
421 PyObject *kw)
423 samr_domain_hnd_object *domain_hnd = (samr_domain_hnd_object *)self;
424 static char *kwlist[] = { NULL };
425 TALLOC_CTX *mem_ctx;
426 /* uint32 desired_access = MAXIMUM_ALLOWED_ACCESS; */
427 uint32 start_idx, size, num_dom_groups;
428 struct acct_info *dom_groups;
429 NTSTATUS result;
430 PyObject *py_result = NULL;
432 if (!PyArg_ParseTupleAndKeywords(args, kw, "", kwlist))
433 return NULL;
435 if (!(mem_ctx = talloc_init("samr_enum_dom_groups"))) {
436 PyErr_SetString(samr_error, "unable to init talloc context");
437 return NULL;
440 start_idx = 0;
441 size = 0xffff;
443 do {
444 result = cli_samr_enum_dom_groups(
445 domain_hnd->cli, mem_ctx, &domain_hnd->domain_pol,
446 &start_idx, size, &dom_groups, &num_dom_groups);
448 if (NT_STATUS_IS_OK(result) ||
449 NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
450 py_from_acct_info(&py_result, dom_groups,
451 num_dom_groups);
454 } while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
456 return py_result;
459 static PyObject *samr_create_dom_user(PyObject *self, PyObject *args,
460 PyObject *kw)
462 samr_domain_hnd_object *domain_hnd = (samr_domain_hnd_object *)self;
463 static char *kwlist[] = { "account_name", "acb_info", NULL };
464 char *account_name;
465 NTSTATUS ntstatus;
466 uint32 unknown = 0xe005000b; /* Access mask? */
467 uint32 user_rid;
468 PyObject *result = NULL;
469 TALLOC_CTX *mem_ctx;
470 uint16 acb_info = ACB_NORMAL;
471 POLICY_HND user_pol;
473 if (!PyArg_ParseTupleAndKeywords(
474 args, kw, "s|i", kwlist, &account_name, &acb_info))
475 return NULL;
477 if (!(mem_ctx = talloc_init("samr_create_dom_user"))) {
478 PyErr_SetString(samr_error, "unable to init talloc context");
479 return NULL;
482 ntstatus = cli_samr_create_dom_user(
483 domain_hnd->cli, mem_ctx, &domain_hnd->domain_pol,
484 account_name, acb_info, unknown, &user_pol, &user_rid);
486 if (!NT_STATUS_IS_OK(ntstatus)) {
487 PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
488 talloc_destroy(mem_ctx);
489 goto done;
492 result = new_samr_user_hnd_object(
493 domain_hnd->cli, mem_ctx, &user_pol);
495 done:
497 return result;
500 static PyMethodDef samr_domain_methods[] = {
501 { "enum_domain_groups", (PyCFunction)samr_enum_dom_groups,
502 METH_VARARGS | METH_KEYWORDS, "Enumerate domain groups" },
503 { "create_domain_user", (PyCFunction)samr_create_dom_user,
504 METH_VARARGS | METH_KEYWORDS, "Create domain user" },
505 { NULL }
508 static PyObject *py_samr_domain_hnd_getattr(PyObject *self, char *attrname)
510 return Py_FindMethod(samr_domain_methods, self, attrname);
513 PyTypeObject samr_domain_hnd_type = {
514 PyObject_HEAD_INIT(NULL)
516 "SAMR Domain Handle",
517 sizeof(samr_domain_hnd_object),
519 py_samr_domain_hnd_dealloc, /*tp_dealloc*/
520 0, /*tp_print*/
521 py_samr_domain_hnd_getattr, /*tp_getattr*/
522 0, /*tp_setattr*/
523 0, /*tp_compare*/
524 0, /*tp_repr*/
525 0, /*tp_as_number*/
526 0, /*tp_as_sequence*/
527 0, /*tp_as_mapping*/
528 0, /*tp_hash */
531 static PyObject *samr_connect(PyObject *self, PyObject *args, PyObject *kw)
533 static char *kwlist[] = { "server", "creds", "access", NULL };
534 uint32 desired_access = MAXIMUM_ALLOWED_ACCESS;
535 char *server, *errstr;
536 struct cli_state *cli = NULL;
537 POLICY_HND hnd;
538 TALLOC_CTX *mem_ctx = NULL;
539 PyObject *result = NULL, *creds = NULL;
540 NTSTATUS ntstatus;
542 if (!PyArg_ParseTupleAndKeywords(
543 args, kw, "s|Oi", kwlist, &server, &creds,
544 &desired_access))
545 return NULL;
547 if (server[0] != '\\' || server[1] != '\\') {
548 PyErr_SetString(PyExc_ValueError, "UNC name required");
549 return NULL;
552 server += 2;
554 if (creds && creds != Py_None && !PyDict_Check(creds)) {
555 PyErr_SetString(PyExc_TypeError,
556 "credentials must be dictionary or None");
557 return NULL;
560 if (!(cli = open_pipe_creds(server, creds, PI_SAMR, &errstr))) {
561 PyErr_SetString(samr_error, errstr);
562 free(errstr);
563 return NULL;
566 if (!(mem_ctx = talloc_init("samr_connect"))) {
567 PyErr_SetString(samr_ntstatus,
568 "unable to init talloc context\n");
569 goto done;
572 ntstatus = cli_samr_connect(cli, mem_ctx, desired_access, &hnd);
574 if (!NT_STATUS_IS_OK(ntstatus)) {
575 cli_shutdown(cli);
576 PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
577 goto done;
580 result = new_samr_connect_hnd_object(cli, mem_ctx, &hnd);
582 done:
583 if (!result) {
584 if (cli)
585 cli_shutdown(cli);
587 if (mem_ctx)
588 talloc_destroy(mem_ctx);
591 return result;
595 * Module initialisation
598 static PyMethodDef samr_methods[] = {
600 /* Open/close samr connect handles */
602 { "connect", (PyCFunction)samr_connect,
603 METH_VARARGS | METH_KEYWORDS,
604 "Open a connect handle" },
606 { NULL }
609 static struct const_vals {
610 char *name;
611 uint32 value;
612 } module_const_vals[] = {
614 /* Account control bits */
616 { "ACB_DISABLED", 0x0001 },
617 { "ACB_HOMDIRREQ", 0x0002 },
618 { "ACB_PWNOTREQ", 0x0004 },
619 { "ACB_TEMPDUP", 0x0008 },
620 { "ACB_NORMAL", 0x0010 },
621 { "ACB_MNS", 0x0020 },
622 { "ACB_DOMTRUST", 0x0040 },
623 { "ACB_WSTRUST", 0x0080 },
624 { "ACB_SVRTRUST", 0x0100 },
625 { "ACB_PWNOEXP", 0x0200 },
626 { "ACB_AUTOLOCK", 0x0400 },
628 { NULL }
631 static void const_init(PyObject *dict)
633 struct const_vals *tmp;
634 PyObject *obj;
636 for (tmp = module_const_vals; tmp->name; tmp++) {
637 obj = PyInt_FromLong(tmp->value);
638 PyDict_SetItemString(dict, tmp->name, obj);
639 Py_DECREF(obj);
643 void initsamr(void)
645 PyObject *module, *dict;
647 /* Initialise module */
649 module = Py_InitModule("samr", samr_methods);
650 dict = PyModule_GetDict(module);
652 samr_error = PyErr_NewException("samr.error", NULL, NULL);
653 PyDict_SetItemString(dict, "error", samr_error);
655 samr_ntstatus = PyErr_NewException("samr.ntstatus", NULL, NULL);
656 PyDict_SetItemString(dict, "ntstatus", samr_ntstatus);
658 /* Initialise policy handle object */
660 samr_connect_hnd_type.ob_type = &PyType_Type;
661 samr_domain_hnd_type.ob_type = &PyType_Type;
662 samr_user_hnd_type.ob_type = &PyType_Type;
663 samr_group_hnd_type.ob_type = &PyType_Type;
664 samr_alias_hnd_type.ob_type = &PyType_Type;
666 /* Initialise constants */
668 const_init(dict);
670 /* Do samba initialisation */
672 py_samba_init();
674 setup_logging("samr", True);
675 DEBUGLEVEL = 10;