From 223828642548c7e25f6189e274aa1edcdfe30c4f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 24 Mar 2003 06:31:49 +0000 Subject: Started working on python routines to add and delete domain users. Unfortunately users get created with the ACB mask set to disabled and must change password. The set_user_info2 call required to fix this doesn't quite work yet... (This used to be commit 55a341a367a7d1b18ae7ef04678479eb74b68ea3) --- source3/python/py_samr.c | 471 +++++++++++++++++++++++++++++------------- source3/python/py_samr.h | 5 + source3/python/py_samr_conv.c | 73 +++++++ source3/python/setup.py | 1 + 4 files changed, 404 insertions(+), 146 deletions(-) (limited to 'source3') diff --git a/source3/python/py_samr.c b/source3/python/py_samr.c index 182671d047..57acd74bed 100644 --- a/source3/python/py_samr.c +++ b/source3/python/py_samr.c @@ -31,6 +31,272 @@ PyObject *samr_ntstatus; /* This exception is raised when a RPC call returns a status code other than NT_STATUS_OK */ +/* SAMR group handle object */ + +static void py_samr_group_hnd_dealloc(PyObject* self) +{ + PyObject_Del(self); +} + +static PyMethodDef samr_group_methods[] = { + { NULL } +}; + +static PyObject *py_samr_group_hnd_getattr(PyObject *self, char *attrname) +{ + return Py_FindMethod(samr_group_methods, self, attrname); +} + +PyTypeObject samr_group_hnd_type = { + PyObject_HEAD_INIT(NULL) + 0, + "SAMR Group Handle", + sizeof(samr_group_hnd_object), + 0, + py_samr_group_hnd_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + py_samr_group_hnd_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ +}; + +PyObject *new_samr_group_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol) +{ + samr_group_hnd_object *o; + + o = PyObject_New(samr_group_hnd_object, &samr_group_hnd_type); + + o->cli = cli; + o->mem_ctx = mem_ctx; + memcpy(&o->group_pol, pol, sizeof(POLICY_HND)); + + return (PyObject*)o; +} + +/* Alias handle object */ + +static void py_samr_alias_hnd_dealloc(PyObject* self) +{ + PyObject_Del(self); +} + +static PyMethodDef samr_alias_methods[] = { + { NULL } +}; + +static PyObject *py_samr_alias_hnd_getattr(PyObject *self, char *attrname) +{ + return Py_FindMethod(samr_alias_methods, self, attrname); +} + +PyTypeObject samr_alias_hnd_type = { + PyObject_HEAD_INIT(NULL) + 0, + "SAMR Alias Handle", + sizeof(samr_alias_hnd_object), + 0, + py_samr_alias_hnd_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + py_samr_alias_hnd_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ +}; + +PyObject *new_samr_alias_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol) +{ + samr_alias_hnd_object *o; + + o = PyObject_New(samr_alias_hnd_object, &samr_alias_hnd_type); + + o->cli = cli; + o->mem_ctx = mem_ctx; + memcpy(&o->alias_pol, pol, sizeof(POLICY_HND)); + + return (PyObject*)o; +} + +/* SAMR user handle object */ + +static void py_samr_user_hnd_dealloc(PyObject* self) +{ + PyObject_Del(self); +} + +static PyObject *samr_set_user_info2(PyObject *self, PyObject *args, + PyObject *kw) +{ + samr_user_hnd_object *user_hnd = (samr_user_hnd_object *)self; + static char *kwlist[] = { "dict", NULL }; + PyObject *info, *result = NULL; + SAM_USERINFO_CTR ctr; + TALLOC_CTX *mem_ctx; + uchar sess_key[16]; + NTSTATUS ntstatus; + int level; + union { + SAM_USER_INFO_10 id10; + SAM_USER_INFO_21 id21; + } pinfo; + + if (!PyArg_ParseTupleAndKeywords( + args, kw, "O!", kwlist, &PyDict_Type, &info)) + return NULL; + + if (!get_level_value(info, &level)) { + PyErr_SetString(samr_error, "invalid info level"); + return NULL; + } + + ZERO_STRUCT(ctr); + + ctr.switch_value = level; + + switch(level) { + case 0x10: + ctr.info.id10 = &pinfo.id10; + + if (!py_to_SAM_USER_INFO_10(ctr.info.id10, info)) { + PyErr_SetString( + samr_error, "error converting user info"); + goto done; + } + + break; + case 21: + ctr.info.id21 = &pinfo.id21; + + if (!py_to_SAM_USER_INFO_21(ctr.info.id21, info)) { + PyErr_SetString( + samr_error, "error converting user info"); + goto done; + } + + break; + default: + PyErr_SetString(samr_error, "unsupported info level"); + goto done; + } + + /* Call RPC function */ + + if (!(mem_ctx = talloc_init("samr_set_user_info2"))) { + PyErr_SetString( + samr_error, "unable to init talloc context\n"); + goto done; + } + + ntstatus = cli_samr_set_userinfo2( + user_hnd->cli, mem_ctx, &user_hnd->user_pol, level, + sess_key, &ctr); + + talloc_destroy(mem_ctx); + + if (!NT_STATUS_IS_OK(ntstatus)) { + PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus)); + goto done; + } + + Py_INCREF(Py_None); + result = Py_None; + +done: + return result; +} + +static PyObject *samr_delete_dom_user(PyObject *self, PyObject *args, + PyObject *kw) +{ + samr_user_hnd_object *user_hnd = (samr_user_hnd_object *)self; + static char *kwlist[] = { NULL }; + NTSTATUS ntstatus; + TALLOC_CTX *mem_ctx; + PyObject *result = NULL; + + if (!PyArg_ParseTupleAndKeywords( + args, kw, "", kwlist)) + return NULL; + + if (!(mem_ctx = talloc_init("samr_delete_dom_user"))) { + PyErr_SetString(samr_error, "unable to init talloc context"); + return NULL; + } + + ntstatus = cli_samr_delete_dom_user( + user_hnd->cli, mem_ctx, &user_hnd->user_pol); + + if (!NT_STATUS_IS_OK(ntstatus)) { + PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus)); + goto done; + } + + Py_INCREF(Py_None); + result = Py_None; + +done: + talloc_destroy(mem_ctx); + + return result; +} + +static PyMethodDef samr_user_methods[] = { + { "delete_domain_user", (PyCFunction)samr_delete_dom_user, + METH_VARARGS | METH_KEYWORDS, + "Delete domain user." }, + { "set_user_info2", (PyCFunction)samr_set_user_info2, + METH_VARARGS | METH_KEYWORDS, + "Set user info 2" }, + { NULL } +}; + +static PyObject *py_samr_user_hnd_getattr(PyObject *self, char *attrname) +{ + return Py_FindMethod(samr_user_methods, self, attrname); +} + +PyTypeObject samr_user_hnd_type = { + PyObject_HEAD_INIT(NULL) + 0, + "SAMR User Handle", + sizeof(samr_user_hnd_object), + 0, + py_samr_user_hnd_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + py_samr_user_hnd_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ +}; + +PyObject *new_samr_user_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol) +{ + samr_user_hnd_object *o; + + o = PyObject_New(samr_user_hnd_object, &samr_user_hnd_type); + + o->cli = cli; + o->mem_ctx = mem_ctx; + memcpy(&o->user_pol, pol, sizeof(POLICY_HND)); + + return (PyObject*)o; +} + /* SAMR connect handle object */ static void py_samr_connect_hnd_dealloc(PyObject* self) @@ -163,8 +429,7 @@ static PyObject *samr_enum_dom_groups(PyObject *self, PyObject *args, NTSTATUS result; PyObject *py_result = NULL; - if (!PyArg_ParseTupleAndKeywords( - args, kw, "", kwlist)) + if (!PyArg_ParseTupleAndKeywords(args, kw, "", kwlist)) return NULL; if (!(mem_ctx = talloc_init("samr_enum_dom_groups"))) { @@ -191,9 +456,52 @@ static PyObject *samr_enum_dom_groups(PyObject *self, PyObject *args, return py_result; } +static PyObject *samr_create_dom_user(PyObject *self, PyObject *args, + PyObject *kw) +{ + samr_domain_hnd_object *domain_hnd = (samr_domain_hnd_object *)self; + static char *kwlist[] = { "account_name", "acb_info", NULL }; + char *account_name; + NTSTATUS ntstatus; + uint32 unknown = 0xe005000b; /* Access mask? */ + uint32 user_rid; + PyObject *result = NULL; + TALLOC_CTX *mem_ctx; + uint16 acb_info = ACB_NORMAL; + POLICY_HND user_pol; + + if (!PyArg_ParseTupleAndKeywords( + args, kw, "s|i", kwlist, &account_name, &acb_info)) + return NULL; + + if (!(mem_ctx = talloc_init("samr_create_dom_user"))) { + PyErr_SetString(samr_error, "unable to init talloc context"); + return NULL; + } + + ntstatus = cli_samr_create_dom_user( + domain_hnd->cli, mem_ctx, &domain_hnd->domain_pol, + account_name, acb_info, unknown, &user_pol, &user_rid); + + if (!NT_STATUS_IS_OK(ntstatus)) { + PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus)); + talloc_destroy(mem_ctx); + goto done; + } + + result = new_samr_user_hnd_object( + domain_hnd->cli, mem_ctx, &user_pol); + +done: + + return result; +} + static PyMethodDef samr_domain_methods[] = { { "enum_domain_groups", (PyCFunction)samr_enum_dom_groups, METH_VARARGS | METH_KEYWORDS, "Enumerate domain groups" }, + { "create_domain_user", (PyCFunction)samr_create_dom_user, + METH_VARARGS | METH_KEYWORDS, "Create domain user" }, { NULL } }; @@ -220,150 +528,6 @@ PyTypeObject samr_domain_hnd_type = { 0, /*tp_hash */ }; -/* SAMR user handle object */ - -static void py_samr_user_hnd_dealloc(PyObject* self) -{ - PyObject_Del(self); -} - -static PyMethodDef samr_user_methods[] = { - { NULL } -}; - -static PyObject *py_samr_user_hnd_getattr(PyObject *self, char *attrname) -{ - return Py_FindMethod(samr_user_methods, self, attrname); -} - -PyTypeObject samr_user_hnd_type = { - PyObject_HEAD_INIT(NULL) - 0, - "SAMR User Handle", - sizeof(samr_user_hnd_object), - 0, - py_samr_user_hnd_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - py_samr_user_hnd_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ -}; - -PyObject *new_samr_user_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol) -{ - samr_user_hnd_object *o; - - o = PyObject_New(samr_user_hnd_object, &samr_user_hnd_type); - - o->cli = cli; - o->mem_ctx = mem_ctx; - memcpy(&o->user_pol, pol, sizeof(POLICY_HND)); - - return (PyObject*)o; -} - -/* SAMR group handle object */ - -static void py_samr_group_hnd_dealloc(PyObject* self) -{ - PyObject_Del(self); -} - -static PyMethodDef samr_group_methods[] = { - { NULL } -}; - -static PyObject *py_samr_group_hnd_getattr(PyObject *self, char *attrname) -{ - return Py_FindMethod(samr_group_methods, self, attrname); -} - -PyTypeObject samr_group_hnd_type = { - PyObject_HEAD_INIT(NULL) - 0, - "SAMR Group Handle", - sizeof(samr_group_hnd_object), - 0, - py_samr_group_hnd_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - py_samr_group_hnd_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ -}; - -PyObject *new_samr_group_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol) -{ - samr_group_hnd_object *o; - - o = PyObject_New(samr_group_hnd_object, &samr_group_hnd_type); - - o->cli = cli; - o->mem_ctx = mem_ctx; - memcpy(&o->group_pol, pol, sizeof(POLICY_HND)); - - return (PyObject*)o; -} - -/* Alias handle object */ - -static void py_samr_alias_hnd_dealloc(PyObject* self) -{ - PyObject_Del(self); -} - -static PyMethodDef samr_alias_methods[] = { - { NULL } -}; - -static PyObject *py_samr_alias_hnd_getattr(PyObject *self, char *attrname) -{ - return Py_FindMethod(samr_alias_methods, self, attrname); -} - -PyTypeObject samr_alias_hnd_type = { - PyObject_HEAD_INIT(NULL) - 0, - "SAMR Alias Handle", - sizeof(samr_alias_hnd_object), - 0, - py_samr_alias_hnd_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - py_samr_alias_hnd_getattr, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ -}; - -PyObject *new_samr_alias_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol) -{ - samr_alias_hnd_object *o; - - o = PyObject_New(samr_alias_hnd_object, &samr_alias_hnd_type); - - o->cli = cli; - o->mem_ctx = mem_ctx; - memcpy(&o->alias_pol, pol, sizeof(POLICY_HND)); - - return (PyObject*)o; -} - static PyObject *samr_connect(PyObject *self, PyObject *args, PyObject *kw) { static char *kwlist[] = { "server", "creds", "access", NULL }; @@ -446,6 +610,21 @@ static struct const_vals { char *name; uint32 value; } module_const_vals[] = { + + /* Account control bits */ + + { "ACB_DISABLED", 0x0001 }, + { "ACB_HOMDIRREQ", 0x0002 }, + { "ACB_PWNOTREQ", 0x0004 }, + { "ACB_TEMPDUP", 0x0008 }, + { "ACB_NORMAL", 0x0010 }, + { "ACB_MNS", 0x0020 }, + { "ACB_DOMTRUST", 0x0040 }, + { "ACB_WSTRUST", 0x0080 }, + { "ACB_SVRTRUST", 0x0100 }, + { "ACB_PWNOEXP", 0x0200 }, + { "ACB_AUTOLOCK", 0x0400 }, + { NULL } }; diff --git a/source3/python/py_samr.h b/source3/python/py_samr.h index 3292eb97ec..4d2b0675b4 100644 --- a/source3/python/py_samr.h +++ b/source3/python/py_samr.h @@ -78,4 +78,9 @@ extern PyObject *samr_error; /* The following definitions are from py_samr_conv.c */ BOOL py_from_acct_info(PyObject **array, struct acct_info *info, int num_accts); +BOOL py_from_SAM_USER_INFO_10(PyObject **dict, SAM_USER_INFO_10 *info); +BOOL py_to_SAM_USER_INFO_10(SAM_USER_INFO_10 *info, PyObject *dict); +BOOL py_from_SAM_USER_INFO_21(PyObject **dict, SAM_USER_INFO_21 *info); +BOOL py_to_SAM_USER_INFO_21(SAM_USER_INFO_21 *info, PyObject *dict); + #endif /* _PY_SAMR_H */ diff --git a/source3/python/py_samr_conv.c b/source3/python/py_samr_conv.c index fdf71641e0..7523ee7dfc 100644 --- a/source3/python/py_samr_conv.c +++ b/source3/python/py_samr_conv.c @@ -21,6 +21,79 @@ #include "python/py_samr.h" #include "python/py_conv.h" +/* + * Convert between SAM_USER_INFO_10 and Python + */ + +struct pyconv py_SAM_USER_INFO_10[] = { + { "acb_info", PY_UINT32, offsetof(SAM_USER_INFO_10, acb_info) }, + { NULL } +}; + +BOOL py_from_SAM_USER_INFO_10(PyObject **dict, SAM_USER_INFO_10 *info) +{ + *dict = from_struct(info, py_SAM_USER_INFO_10); + PyDict_SetItemString(*dict, "level", PyInt_FromLong(0x10)); + return True; +} + +BOOL py_to_SAM_USER_INFO_10(SAM_USER_INFO_10 *info, PyObject *dict) +{ + PyObject *obj, *dict_copy = PyDict_Copy(dict); + BOOL result = False; + + if (!(obj = PyDict_GetItemString(dict_copy, "level")) || + !PyInt_Check(obj)) + goto done; + + PyDict_DelItemString(dict_copy, "level"); + + if (!to_struct(info, dict_copy, py_SAM_USER_INFO_10)) + goto done; + + result = True; + +done: + Py_DECREF(dict_copy); + return result; +} + +/* + * Convert between SAM_USER_INFO_21 and Python + */ + +struct pyconv py_SAM_USER_INFO_21[] = { + { NULL } +}; + +BOOL py_from_SAM_USER_INFO_21(PyObject **dict, SAM_USER_INFO_21 *info) +{ + *dict = from_struct(info, py_SAM_USER_INFO_21); + PyDict_SetItemString(*dict, "level", PyInt_FromLong(21)); + return True; +} + +BOOL py_to_SAM_USER_INFO_21(SAM_USER_INFO_21 *info, PyObject *dict) +{ + PyObject *obj, *dict_copy = PyDict_Copy(dict); + BOOL result = False; + + if (!(obj = PyDict_GetItemString(dict_copy, "level")) || + !PyInt_Check(obj)) + goto done; + + PyDict_DelItemString(dict_copy, "level"); + + if (!to_struct(info, dict_copy, py_SAM_USER_INFO_21)) + goto done; + + result = True; + +done: + Py_DECREF(dict_copy); + return result; +} + /* * Convert between acct_info and Python */ diff --git a/source3/python/setup.py b/source3/python/setup.py index 8bc8868a70..6569331031 100755 --- a/source3/python/setup.py +++ b/source3/python/setup.py @@ -116,6 +116,7 @@ setup( Extension(name = "samr", sources = [samba_srcdir + "python/py_samr.c", + samba_srcdir + "python/py_conv.c", samba_srcdir + "python/py_samr_conv.c", samba_srcdir + "python/py_common.c"], libraries = lib_list, -- cgit