From 5b444916bfb2266182d62500d679d2ec08a7c53b Mon Sep 17 00:00:00 2001 From: Amitay Isaacs Date: Mon, 15 Aug 2011 17:21:38 +1000 Subject: s3-passdb: Python wrapper for passdb - Added Groupmap python wrapper - Added passdb methods getgrsid, getgrgid, getgrnam create_dom_group, delete_dom_group add_group_mapping_entry, update_group_mapping_entry, delete_group_mapping_entry enum_group_mapping, enum_group_members add_groupmem, del_groupmem create_alias, delete_alias get_aliasinfo, set_aliasinfo add_aliasmem, del_aliasmem, enum_aliasmem get_account_policy, set_account_policy search_groups, search_aliases Pair-Programmed-With: Andrew Bartlett Signed-off-by: Andrew Bartlett --- source3/passdb/py_passdb.c | 1557 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 1416 insertions(+), 141 deletions(-) diff --git a/source3/passdb/py_passdb.c b/source3/passdb/py_passdb.c index 30c3f8ccc9..2b3ac52110 100644 --- a/source3/passdb/py_passdb.c +++ b/source3/passdb/py_passdb.c @@ -46,6 +46,7 @@ static PyTypeObject *dom_sid_Type = NULL; static PyTypeObject *guid_Type = NULL; staticforward PyTypeObject PySamu; +staticforward PyTypeObject PyGroupmap; staticforward PyTypeObject PyPDB; static PyObject *py_pdb_error; @@ -949,13 +950,189 @@ static PyObject *py_samu_new(PyTypeObject *type, PyObject *args, PyObject *kwarg } static PyTypeObject PySamu = { - .tp_name = "passdb.samu", + .tp_name = "passdb.Samu", .tp_basicsize = sizeof(pytalloc_Object), .tp_getset = py_samu_getsetters, .tp_methods = NULL, .tp_new = py_samu_new, .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, - .tp_doc = "samu() -> samu object\n", + .tp_doc = "Samu() -> samu object\n", +}; + + +static PyObject *py_groupmap_get_gid(PyObject *obj, void *closure) +{ + GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj); + PyObject *py_gid; + + py_gid = PyInt_FromLong(group_map->gid); + return py_gid; +} + +static int py_groupmap_set_gid(PyObject *obj, PyObject *value, void *closure) +{ + GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj); + + PY_CHECK_TYPE(&PyInt_Type, value, return -1;); + group_map->gid = PyInt_AsLong(value); + return 0; +} + +static PyObject *py_groupmap_get_sid(PyObject *obj, void *closure) +{ + GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj); + PyObject *py_sid; + struct dom_sid *group_sid; + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + group_sid = dom_sid_dup(mem_ctx, &group_map->sid); + if (group_sid == NULL) { + PyErr_NoMemory(); + talloc_free(mem_ctx); + return NULL; + } + + py_sid = pytalloc_steal(dom_sid_Type, group_sid); + + talloc_free(mem_ctx); + + return py_sid; +} + +static int py_groupmap_set_sid(PyObject *obj, PyObject *value, void *closure) +{ + GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj); + + PY_CHECK_TYPE(dom_sid_Type, value, return -1;); + group_map->sid = *pytalloc_get_type(value, struct dom_sid); + return 0; +} + +static PyObject *py_groupmap_get_sid_name_use(PyObject *obj, void *closure) +{ + GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj); + PyObject *py_sid_name_use; + + py_sid_name_use = PyInt_FromLong(group_map->sid_name_use); + return py_sid_name_use; +} + +static int py_groupmap_set_sid_name_use(PyObject *obj, PyObject *value, void *closure) +{ + GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj); + + PY_CHECK_TYPE(&PyInt_Type, value, return -1;); + group_map->sid_name_use = PyInt_AsLong(value); + return 0; +} + +static PyObject *py_groupmap_get_nt_name(PyObject *obj, void *closure) +{ + GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj); + PyObject *py_nt_name; + if (group_map->nt_name == NULL) { + py_nt_name = Py_None; + Py_INCREF(py_nt_name); + } else { + py_nt_name = PyString_FromString(group_map->nt_name); + } + return py_nt_name; +} + +static int py_groupmap_set_nt_name(PyObject *obj, PyObject *value, void *closure) +{ + GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj); + + PY_CHECK_TYPE(&PyString_Type, value, return -1;); + if (value == Py_None) { + fstrcpy(group_map->nt_name, NULL); + } else { + fstrcpy(group_map->nt_name, PyString_AsString(value)); + } + return 0; +} + +static PyObject *py_groupmap_get_comment(PyObject *obj, void *closure) +{ + GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj); + PyObject *py_comment; + if (group_map->comment == NULL) { + py_comment = Py_None; + Py_INCREF(py_comment); + } else { + py_comment = PyString_FromString(group_map->comment); + } + return py_comment; +} + +static int py_groupmap_set_comment(PyObject *obj, PyObject *value, void *closure) +{ + GROUP_MAP *group_map = (GROUP_MAP *)pytalloc_get_ptr(obj); + + PY_CHECK_TYPE(&PyString_Type, value, return -1;); + if (value == Py_None) { + fstrcpy(group_map->comment, NULL); + } else { + fstrcpy(group_map->comment, PyString_AsString(value)); + } + return 0; +} + +static PyGetSetDef py_groupmap_getsetters[] = { + { discard_const_p(char, "gid"), py_groupmap_get_gid, py_groupmap_set_gid }, + { discard_const_p(char, "sid"), py_groupmap_get_sid, py_groupmap_set_sid }, + { discard_const_p(char, "sid_name_use"), py_groupmap_get_sid_name_use, py_groupmap_set_sid_name_use }, + { discard_const_p(char, "nt_name"), py_groupmap_get_nt_name, py_groupmap_set_nt_name }, + { discard_const_p(char, "comment"), py_groupmap_get_comment, py_groupmap_set_comment }, + { NULL } +}; + +static PyObject *py_groupmap_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + GROUP_MAP *group_map; + TALLOC_CTX *mem_ctx; + PyObject *py_group_map; + + mem_ctx = talloc_new(NULL); + if (mem_ctx == NULL) { + PyErr_NoMemory(); + return NULL; + } + + group_map = talloc_zero(mem_ctx, GROUP_MAP); + if (group_map == NULL) { + PyErr_NoMemory(); + talloc_free(mem_ctx); + return NULL; + } + + py_group_map = pytalloc_steal(type, group_map); + if (py_group_map == NULL) { + PyErr_NoMemory(); + talloc_free(mem_ctx); + return NULL; + } + + talloc_free(mem_ctx); + + return py_group_map; +} + + +static PyTypeObject PyGroupmap = { + .tp_name = "passdb.Groupmap", + .tp_basicsize = sizeof(pytalloc_Object), + .tp_getset = py_groupmap_getsetters, + .tp_methods = NULL, + .tp_new = py_groupmap_new, + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + .tp_doc = "Groupmap() -> group map object\n", }; @@ -975,53 +1152,949 @@ static PyObject *py_pdb_domain_info(pytalloc_Object *self, PyObject *args) return NULL; } - domain_info = methods->get_domain_info(methods, tframe); - if (! domain_info) { - Py_RETURN_NONE; - } + domain_info = methods->get_domain_info(methods, tframe); + if (! domain_info) { + Py_RETURN_NONE; + } + + sid = dom_sid_dup(tframe, &domain_info->sid); + if (sid == NULL) { + PyErr_NoMemory(); + talloc_free(tframe); + return NULL; + } + + guid = talloc(tframe, struct GUID); + if (guid == NULL) { + PyErr_NoMemory(); + talloc_free(tframe); + return NULL; + } + *guid = domain_info->guid; + + if ((py_domain_info = PyDict_New()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + PyDict_SetItemString(py_domain_info, "name", PyString_FromString(domain_info->name)); + PyDict_SetItemString(py_domain_info, "dns_domain", PyString_FromString(domain_info->name)); + PyDict_SetItemString(py_domain_info, "dns_forest", PyString_FromString(domain_info->name)); + PyDict_SetItemString(py_domain_info, "dom_sid", pytalloc_steal(dom_sid_Type, sid)); + PyDict_SetItemString(py_domain_info, "guid", pytalloc_steal(guid_Type, guid)); + + talloc_free(tframe); + + return py_domain_info; +} + + +static PyObject *py_pdb_getsampwnam(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + const char *username; + struct pdb_methods *methods; + struct samu *sam_acct; + PyObject *py_sam_acct; + TALLOC_CTX *tframe; + + if (!PyArg_ParseTuple(args, "s:getsampwnam", &username)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + py_sam_acct = py_samu_new(&PySamu, NULL, NULL); + if (py_sam_acct == NULL) { + PyErr_NoMemory(); + talloc_free(tframe); + return NULL; + } + sam_acct = (struct samu *)pytalloc_get_ptr(py_sam_acct); + + status = methods->getsampwnam(methods, sam_acct, username); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to get user information for '%s', (%d,%s)", + username, + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + Py_DECREF(py_sam_acct); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + return py_sam_acct; +} + +static PyObject *py_pdb_getsampwsid(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + struct samu *sam_acct; + PyObject *py_sam_acct; + TALLOC_CTX *tframe; + PyObject *py_user_sid; + + if (!PyArg_ParseTuple(args, "O:getsampwsid", &py_user_sid)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + py_sam_acct = py_samu_new(&PySamu, NULL, NULL); + if (py_sam_acct == NULL) { + PyErr_NoMemory(); + talloc_free(tframe); + return NULL; + } + sam_acct = (struct samu *)pytalloc_get_ptr(py_sam_acct); + + status = methods->getsampwsid(methods, sam_acct, pytalloc_get_ptr(py_user_sid)); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to get user information from SID, (%d,%s)", + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + Py_DECREF(py_sam_acct); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + return py_sam_acct; +} + +static PyObject *py_pdb_create_user(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + const char *username; + unsigned int acct_flags; + unsigned int rid; + TALLOC_CTX *tframe; + + if (!PyArg_ParseTuple(args, "sI:create_user", &username, &acct_flags)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + status = methods->create_user(methods, tframe, username, acct_flags, &rid); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to create user (%s), (%d,%s)", + username, + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + return PyInt_FromLong(rid); +} + +static PyObject *py_pdb_delete_user(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + TALLOC_CTX *tframe; + struct samu *sam_acct; + PyObject *py_sam_acct; + + if (!PyArg_ParseTuple(args, "O!:delete_user", &PySamu, &py_sam_acct)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + sam_acct = pytalloc_get_ptr(py_sam_acct); + + status = methods->delete_user(methods, tframe, sam_acct); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to delete user, (%d,%s)", + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + Py_RETURN_NONE; +} + +static PyObject *py_pdb_add_sam_account(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + TALLOC_CTX *tframe; + struct samu *sam_acct; + PyObject *py_sam_acct; + + if (!PyArg_ParseTuple(args, "O!:add_sam_account", &PySamu, &py_sam_acct)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + sam_acct = pytalloc_get_ptr(py_sam_acct); + + status = methods->add_sam_account(methods, sam_acct); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to add sam account, (%d,%s)", + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + Py_RETURN_NONE; +} + +static PyObject *py_pdb_update_sam_account(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + TALLOC_CTX *tframe; + struct samu *sam_acct; + PyObject *py_sam_acct; + + if (!PyArg_ParseTuple(args, "O!:update_sam_account", &PySamu, &py_sam_acct)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + sam_acct = pytalloc_get_ptr(py_sam_acct); + + status = methods->update_sam_account(methods, sam_acct); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to update sam account, (%d,%s)", + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + Py_RETURN_NONE; +} + +static PyObject *py_pdb_delete_sam_account(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + TALLOC_CTX *tframe; + struct samu *sam_acct; + PyObject *py_sam_acct; + + if (!PyArg_ParseTuple(args, "O!:delete_sam_account", &PySamu, &py_sam_acct)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + sam_acct = pytalloc_get_ptr(py_sam_acct); + + status = methods->delete_sam_account(methods, sam_acct); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to delete sam account, (%d,%s)", + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + Py_RETURN_NONE; +} + +static PyObject *py_pdb_rename_sam_account(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + TALLOC_CTX *tframe; + struct samu *sam_acct; + const char *new_username; + PyObject *py_sam_acct; + + if (!PyArg_ParseTuple(args, "O!s:rename_sam_account", &PySamu, &py_sam_acct, + &new_username)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + sam_acct = pytalloc_get_ptr(py_sam_acct); + + status = methods->rename_sam_account(methods, sam_acct, new_username); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to rename sam account, (%d,%s)", + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + Py_RETURN_NONE; +} + + +static PyObject *py_pdb_getgrsid(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + TALLOC_CTX *tframe; + GROUP_MAP *group_map; + struct dom_sid *domain_sid; + PyObject *py_domain_sid, *py_group_map; + + if (!PyArg_ParseTuple(args, "O!:getgrsid", dom_sid_Type, &py_domain_sid)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + domain_sid = pytalloc_get_ptr(py_domain_sid); + + py_group_map = py_groupmap_new(&PyGroupmap, NULL, NULL); + if (py_group_map == NULL) { + PyErr_NoMemory(); + talloc_free(tframe); + return NULL; + } + + group_map = pytalloc_get_ptr(py_group_map); + + status = methods->getgrsid(methods, group_map, *domain_sid); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to get group information by sid, (%d,%s)", + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + return py_group_map; +} + + +static PyObject *py_pdb_getgrgid(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + TALLOC_CTX *tframe; + GROUP_MAP *group_map; + PyObject *py_group_map; + unsigned int gid_value; + + if (!PyArg_ParseTuple(args, "I:getgrgid", &gid_value)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + py_group_map = py_groupmap_new(&PyGroupmap, NULL, NULL); + if (py_group_map == NULL) { + PyErr_NoMemory(); + talloc_free(tframe); + return NULL; + } + + group_map = pytalloc_get_ptr(py_group_map); + + status = methods->getgrgid(methods, group_map, gid_value); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to get group information by gid, (%d,%s)", + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + return py_group_map; +} + + +static PyObject *py_pdb_getgrnam(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + TALLOC_CTX *tframe; + GROUP_MAP *group_map; + PyObject *py_group_map; + const char *groupname; + + if (!PyArg_ParseTuple(args, "s:getgrnam", &groupname)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + py_group_map = py_groupmap_new(&PyGroupmap, NULL, NULL); + if (py_group_map == NULL) { + PyErr_NoMemory(); + talloc_free(tframe); + return NULL; + } + + group_map = pytalloc_get_ptr(py_group_map); + + status = methods->getgrnam(methods, group_map, groupname); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to get group information by name, (%d,%s)", + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + return py_group_map; +} + + +static PyObject *py_pdb_create_dom_group(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + TALLOC_CTX *tframe; + const char *groupname; + uint32_t group_rid; + + if (!PyArg_ParseTuple(args, "s:create_dom_group", &groupname)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + status = methods->create_dom_group(methods, tframe, groupname, &group_rid); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to create domain group (%s), (%d,%s)", + groupname, + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + return PyInt_FromLong(group_rid); +} + + +static PyObject *py_pdb_delete_dom_group(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + TALLOC_CTX *tframe; + unsigned int group_rid; + + if (!PyArg_ParseTuple(args, "I:delete_dom_group", &group_rid)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + status = methods->delete_dom_group(methods, tframe, group_rid); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to delete domain group (rid=%d), (%d,%s)", + group_rid, + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + Py_RETURN_NONE; +} + + +static PyObject *py_pdb_add_group_mapping_entry(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + TALLOC_CTX *tframe; + PyObject *py_group_map; + GROUP_MAP *group_map; + + if (!PyArg_ParseTuple(args, "O!:add_group_mapping_entry", &PyGroupmap, &py_group_map)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + group_map = pytalloc_get_ptr(py_group_map); + + status = methods->add_group_mapping_entry(methods, group_map); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to add group mapping entry, (%d,%s)", + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + Py_RETURN_NONE; +} + + +static PyObject *py_pdb_update_group_mapping_entry(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + TALLOC_CTX *tframe; + PyObject *py_group_map; + GROUP_MAP *group_map; + + if (!PyArg_ParseTuple(args, "O!:update_group_mapping_entry", &PyGroupmap, &py_group_map)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + group_map = pytalloc_get_ptr(py_group_map); + + status = methods->update_group_mapping_entry(methods, group_map); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to update group mapping entry, (%d,%s)", + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + Py_RETURN_NONE; +} + + +static PyObject *py_pdb_delete_group_mapping_entry(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + TALLOC_CTX *tframe; + PyObject *py_group_sid; + struct dom_sid *group_sid; + + if (!PyArg_ParseTuple(args, "O!:delete_group_mapping_entry", dom_sid_Type, &py_group_sid)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + group_sid = pytalloc_get_ptr(py_group_sid); + + status = methods->delete_group_mapping_entry(methods, *group_sid); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to delete group mapping entry, (%d,%s)", + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + Py_RETURN_NONE; +} + + +static PyObject *py_pdb_enum_group_mapping(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + TALLOC_CTX *tframe; + enum lsa_SidType sid_name_use; + int lsa_sidtype_value; + int unix_only; + PyObject *py_domain_sid; + struct dom_sid *domain_sid; + GROUP_MAP *gmap, *group_map; + size_t num_entries; + PyObject *py_gmap_list, *py_group_map; + int i; + + if (!PyArg_ParseTuple(args, "O!ii:enum_group_mapping", dom_sid_Type, &py_domain_sid, + &lsa_sidtype_value, &unix_only)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + sid_name_use = lsa_sidtype_value; + + domain_sid = pytalloc_get_ptr(py_domain_sid); + + status = methods->enum_group_mapping(methods, domain_sid, sid_name_use, + &gmap, &num_entries, unix_only); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to enumerate group mappings, (%d,%s)", + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + py_gmap_list = PyList_New(0); + if (py_gmap_list == NULL) { + PyErr_NoMemory(); + talloc_free(tframe); + return NULL; + } + + for(i=0; ienum_group_members(methods, tframe, group_sid, + &member_rids, &num_members); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to enumerate group members, (%d,%s)", + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + py_rid_list = PyList_New(0); + if (py_rid_list == NULL) { + PyErr_NoMemory(); + talloc_free(tframe); + return NULL; + } + + for(i=0; iadd_groupmem(methods, tframe, group_rid, member_rid); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to add group member, (%d,%s)", + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + Py_RETURN_NONE; +} + + +static PyObject *py_pdb_del_groupmem(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + TALLOC_CTX *tframe; + uint32_t group_rid, member_rid; + + if (!PyArg_ParseTuple(args, "II:del_groupmem", &group_rid, &member_rid)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + status = methods->del_groupmem(methods, tframe, group_rid, member_rid); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to rename sam account, (%d,%s)", + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + Py_RETURN_NONE; +} + + +static PyObject *py_pdb_create_alias(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + TALLOC_CTX *tframe; + const char *alias_name; + uint32_t rid; + + if (!PyArg_ParseTuple(args, "s:create_alias", &alias_name)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + status = methods->create_alias(methods, alias_name, &rid); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to create alias (%s), (%d,%s)", + alias_name, + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + + return PyInt_FromLong(rid); +} + + +static PyObject *py_pdb_delete_alias(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + TALLOC_CTX *tframe; + PyObject *py_alias_sid; + struct dom_sid *alias_sid; + + if (!PyArg_ParseTuple(args, "O!:delete_alias", dom_sid_Type, &py_alias_sid)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + alias_sid = pytalloc_get_ptr(py_alias_sid); + + status = methods->delete_alias(methods, alias_sid); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to delete alias, (%d,%s)", + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + talloc_free(tframe); + return NULL; + } + + talloc_free(tframe); + Py_RETURN_NONE; +} + + +static PyObject *py_pdb_get_aliasinfo(pytalloc_Object *self, PyObject *args) +{ + NTSTATUS status; + struct pdb_methods *methods; + TALLOC_CTX *tframe; + PyObject *py_alias_sid; + struct dom_sid *alias_sid; + struct acct_info alias_info; + PyObject *py_alias_info; + + if (!PyArg_ParseTuple(args, "O!:get_aliasinfo", dom_sid_Type, &py_alias_sid)) { + return NULL; + } + + methods = pytalloc_get_ptr(self); + + if ((tframe = talloc_stackframe()) == NULL) { + PyErr_NoMemory(); + return NULL; + } + + alias_sid = pytalloc_get_ptr(py_alias_sid); - sid = dom_sid_dup(tframe, &domain_info->sid); - if (sid == NULL) { - PyErr_NoMemory(); + status = methods->get_aliasinfo(methods, alias_sid, &alias_info); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Unable to get alias information, (%d,%s)", + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); talloc_free(tframe); return NULL; } - guid = talloc(tframe, struct GUID); - if (guid == NULL) { + py_alias_info = PyDict_New(); + if (py_alias_info == NULL) { PyErr_NoMemory(); talloc_free(tframe); return NULL; } - *guid = domain_info->guid; - - if ((py_domain_info = PyDict_New()) == NULL) { - PyErr_NoMemory(); - return NULL; - } - PyDict_SetItemString(py_domain_info, "name", PyString_FromString(domain_info->name)); - PyDict_SetItemString(py_domain_info, "dns_domain", PyString_FromString(domain_info->name)); - PyDict_SetItemString(py_domain_info, "dns_forest", PyString_FromString(domain_info->name)); - PyDict_SetItemString(py_domain_info, "dom_sid", pytalloc_steal(dom_sid_Type, sid)); - PyDict_SetItemString(py_domain_info, "guid", pytalloc_steal(guid_Type, guid)); + PyDict_SetItemString(py_alias_info, "acct_name", PyString_FromString(alias_info.acct_name)); + PyDict_SetItemString(py_alias_info, "acct_desc", PyString_FromString(alias_info.acct_desc)); + PyDict_SetItemString(py_alias_info, "rid", PyInt_FromLong(alias_info.rid)); talloc_free(tframe); - return py_domain_info; + return py_alias_info; } -static PyObject *py_pdb_getsampwnam(pytalloc_Object *self, PyObject *args) +static PyObject *py_pdb_set_aliasinfo(pytalloc_Object *self, PyObject *args) { NTSTATUS status; - const char *username; struct pdb_methods *methods; - struct samu *sam_acct; - PyObject *py_sam_acct; TALLOC_CTX *tframe; + PyObject *py_alias_sid, *py_alias_info; + struct dom_sid *alias_sid; + struct acct_info alias_info; - if (!PyArg_ParseTuple(args, "s:getsampwnam", &username)) { + if (!PyArg_ParseTuple(args, "O!O:set_alias_info", dom_sid_Type, &py_alias_sid, + &py_alias_info)) { return NULL; } @@ -1032,39 +2105,35 @@ static PyObject *py_pdb_getsampwnam(pytalloc_Object *self, PyObject *args) return NULL; } - py_sam_acct = py_samu_new(&PySamu, NULL, NULL); - if (py_sam_acct == NULL) { - PyErr_NoMemory(); - talloc_free(tframe); - return NULL; - } - sam_acct = (struct samu *)pytalloc_get_ptr(py_sam_acct); + alias_sid = pytalloc_get_ptr(py_alias_sid); - status = methods->getsampwnam(methods, sam_acct, username); + fstrcpy(alias_info.acct_name, PyString_AsString(PyDict_GetItemString(py_alias_info, "acct_name"))); + fstrcpy(alias_info.acct_desc, PyString_AsString(PyDict_GetItemString(py_alias_info, "acct_desc"))); + + status = methods->set_aliasinfo(methods, alias_sid, &alias_info); if (!NT_STATUS_IS_OK(status)) { - PyErr_Format(py_pdb_error, "Unable to get user information for '%s', (%d,%s)", - username, + PyErr_Format(py_pdb_error, "Unable to set alias information, (%d,%s)", NT_STATUS_V(status), get_friendly_nt_error_msg(status)); - Py_DECREF(py_sam_acct); talloc_free(tframe); return NULL; } talloc_free(tframe); - return py_sam_acct; + Py_RETURN_NONE; } -static PyObject *py_pdb_getsampwsid(pytalloc_Object *self, PyObject *args) + +static PyObject *py_pdb_add_aliasmem(pytalloc_Object *self, PyObject *args) { NTSTATUS status; struct pdb_methods *methods; - struct samu *sam_acct; - PyObject *py_sam_acct; TALLOC_CTX *tframe; - PyObject *py_user_sid; + PyObject *py_alias_sid, *py_member_sid; + struct dom_sid *alias_sid, *member_sid; - if (!PyArg_ParseTuple(args, "O:getsampwsid", &py_user_sid)) { + if (!PyArg_ParseTuple(args, "O!O!:add_aliasmem", dom_sid_Type, &py_alias_sid, + dom_sid_Type, &py_member_sid)) { return NULL; } @@ -1075,38 +2144,33 @@ static PyObject *py_pdb_getsampwsid(pytalloc_Object *self, PyObject *args) return NULL; } - py_sam_acct = py_samu_new(&PySamu, NULL, NULL); - if (py_sam_acct == NULL) { - PyErr_NoMemory(); - talloc_free(tframe); - return NULL; - } - sam_acct = (struct samu *)pytalloc_get_ptr(py_sam_acct); + alias_sid = pytalloc_get_ptr(py_alias_sid); + member_sid = pytalloc_get_ptr(py_member_sid); - status = methods->getsampwsid(methods, sam_acct, pytalloc_get_ptr(py_user_sid)); + status = methods->add_aliasmem(methods, alias_sid, member_sid); if (!NT_STATUS_IS_OK(status)) { - PyErr_Format(py_pdb_error, "Unable to get user information from SID, (%d,%s)", + PyErr_Format(py_pdb_error, "Unable to add member to alias, (%d,%s)", NT_STATUS_V(status), get_friendly_nt_error_msg(status)); - Py_DECREF(py_sam_acct); talloc_free(tframe); return NULL; } talloc_free(tframe); - return py_sam_acct; + Py_RETURN_NONE; } -static PyObject *py_pdb_create_user(pytalloc_Object *self, PyObject *args) + +static PyObject *py_pdb_del_aliasmem(pytalloc_Object *self, PyObject *args) { NTSTATUS status; struct pdb_methods *methods; - const char *username; - unsigned int acct_flags; - unsigned int rid; TALLOC_CTX *tframe; + PyObject *py_alias_sid, *py_member_sid; + const struct dom_sid *alias_sid, *member_sid; - if (!PyArg_ParseTuple(args, "sI:create_user", &username, &acct_flags)) { + if (!PyArg_ParseTuple(args, "O!O!:del_aliasmem", dom_sid_Type, &py_alias_sid, + dom_sid_Type, &py_member_sid)) { return NULL; } @@ -1117,10 +2181,12 @@ static PyObject *py_pdb_create_user(pytalloc_Object *self, PyObject *args) return NULL; } - status = methods->create_user(methods, tframe, username, acct_flags, &rid); + alias_sid = pytalloc_get_ptr(py_alias_sid); + member_sid = pytalloc_get_ptr(py_member_sid); + + status = methods->del_aliasmem(methods, alias_sid, member_sid); if (!NT_STATUS_IS_OK(status)) { - PyErr_Format(py_pdb_error, "Unable to create user (%s), (%d,%s)", - username, + PyErr_Format(py_pdb_error, "Unable to delete member from alias, (%d,%s)", NT_STATUS_V(status), get_friendly_nt_error_msg(status)); talloc_free(tframe); @@ -1128,18 +2194,22 @@ static PyObject *py_pdb_create_user(pytalloc_Object *self, PyObject *args) } talloc_free(tframe); - return PyInt_FromLong(rid); + Py_RETURN_NONE; } -static PyObject *py_pdb_delete_user(pytalloc_Object *self, PyObject *args) + +static PyObject *py_pdb_enum_aliasmem(pytalloc_Object *self, PyObject *args) { NTSTATUS status; struct pdb_methods *methods; TALLOC_CTX *tframe; - struct samu *sam_acct; - PyObject *py_sam_acct; + PyObject *py_alias_sid; + struct dom_sid *alias_sid, *member_sid; + PyObject *py_member_list, *py_member_sid; + size_t num_members; + int i; - if (!PyArg_ParseTuple(args, "O!:delete_user", &PySamu, &py_sam_acct)) { + if (!PyArg_ParseTuple(args, "O!:enum_aliasmem", dom_sid_Type, &py_alias_sid)) { return NULL; } @@ -1150,32 +2220,47 @@ static PyObject *py_pdb_delete_user(pytalloc_Object *self, PyObject *args) return NULL; } - sam_acct = pytalloc_get_ptr(py_sam_acct); + alias_sid = pytalloc_get_ptr(py_alias_sid); - status = methods->delete_user(methods, tframe, sam_acct); + status = methods->enum_aliasmem(methods, alias_sid, tframe, &member_sid, &num_members); if (!NT_STATUS_IS_OK(status)) { - PyErr_Format(py_pdb_error, "Unable to delete user, (%d,%s)", + PyErr_Format(py_pdb_error, "Unable to enumerate members for alias, (%d,%s)", NT_STATUS_V(status), get_friendly_nt_error_msg(status)); talloc_free(tframe); return NULL; } + py_member_list = PyList_New(0); + if (py_member_list == NULL) { + PyErr_NoMemory(); + talloc_free(tframe); + return NULL; + } + + for(i=0; iadd_sam_account(methods, sam_acct); - if (!NT_STATUS_IS_OK(status)) { - PyErr_Format(py_pdb_error, "Unable to add sam account, (%d,%s)", - NT_STATUS_V(status), - get_friendly_nt_error_msg(status)); - talloc_free(tframe); + py_acct_policy = PyDict_New(); + if (py_acct_policy == NULL) { + PyErr_NoMemory(); return NULL; } + account_policy_names_list(tframe, &names, &count); + for (i=0; iget_account_policy(methods, type, &value); + if (NT_STATUS_IS_OK(status)) { + PyDict_SetItemString(py_acct_policy, names[i], PyInt_FromLong(value)); + } + } + talloc_free(tframe); - Py_RETURN_NONE; + + return py_acct_policy; } -static PyObject *py_pdb_update_sam_account(pytalloc_Object *self, PyObject *args) + +static PyObject *py_pdb_set_account_policy(pytalloc_Object *self, PyObject *args) { NTSTATUS status; struct pdb_methods *methods; TALLOC_CTX *tframe; - struct samu *sam_acct; - PyObject *py_sam_acct; + PyObject *py_acct_policy, *py_value; + const char **names; + int count, i; + enum pdb_policy_type type; - if (!PyArg_ParseTuple(args, "O!:update_sam_account", &PySamu, &py_sam_acct)) { + if (!PyArg_ParseTuple(args, "O!:set_account_policy", PyDict_Type, &py_acct_policy)) { return NULL; } @@ -1218,30 +2311,37 @@ static PyObject *py_pdb_update_sam_account(pytalloc_Object *self, PyObject *args return NULL; } - sam_acct = pytalloc_get_ptr(py_sam_acct); - - status = methods->update_sam_account(methods, sam_acct); - if (!NT_STATUS_IS_OK(status)) { - PyErr_Format(py_pdb_error, "Unable to update sam account, (%d,%s)", - NT_STATUS_V(status), - get_friendly_nt_error_msg(status)); - talloc_free(tframe); - return NULL; + account_policy_names_list(tframe, &names, &count); + for (i=0; iset_account_policy(methods, type, PyInt_AsLong(py_value)); + if (!NT_STATUS_IS_OK(status)) { + PyErr_Format(py_pdb_error, "Error setting account policy (%s), (%d,%s)", + names[i], + NT_STATUS_V(status), + get_friendly_nt_error_msg(status)); + } + } } + talloc_free(tframe); + Py_RETURN_NONE; } -static PyObject *py_pdb_delete_sam_account(pytalloc_Object *self, PyObject *args) +static PyObject *py_pdb_search_users(pytalloc_Object *self, PyObject *args) { NTSTATUS status; struct pdb_methods *methods; TALLOC_CTX *tframe; - struct samu *sam_acct; - PyObject *py_sam_acct; + unsigned int acct_flags; + struct pdb_search *search; + struct samr_displayentry *entry; + PyObject *py_userlist, *py_dict; - if (!PyArg_ParseTuple(args, "O!:delete_sam_account", &PySamu, &py_sam_acct)) { + if (!PyArg_ParseTuple(args, "I:search_users", &acct_flags)) { return NULL; } @@ -1252,34 +2352,65 @@ static PyObject *py_pdb_delete_sam_account(pytalloc_Object *self, PyObject *args return NULL; } - sam_acct = pytalloc_get_ptr(py_sam_acct); + search = talloc_zero(tframe, struct pdb_search); + if (search == NULL) { + PyErr_NoMemory(); + talloc_free(tframe); + return NULL; + } - status = methods->delete_sam_account(methods, sam_acct); - if (!NT_STATUS_IS_OK(status)) { - PyErr_Format(py_pdb_error, "Unable to delete sam account, (%d,%s)", + if (!methods->search_users(methods, search, acct_flags)) { + PyErr_Format(py_pdb_error, "Unable to search users, (%d,%s)", NT_STATUS_V(status), get_friendly_nt_error_msg(status)); talloc_free(tframe); return NULL; } + entry = talloc_zero(tframe, struct samr_displayentry); + if (entry == NULL) { + PyErr_NoMemory(); + talloc_free(tframe); + return NULL; + } + + py_userlist = PyList_New(0); + if (py_userlist == NULL) { + PyErr_NoMemory(); + talloc_free(tframe); + return NULL; + } + + while (search->next_entry(search, entry)) { + py_dict = PyDict_New(); + if (py_dict == NULL) { + PyErr_NoMemory(); + } else { + PyDict_SetItemString(py_dict, "idx", PyInt_FromLong(entry->idx)); + PyDict_SetItemString(py_dict, "rid", PyInt_FromLong(entry->rid)); + PyDict_SetItemString(py_dict, "acct_flags", PyInt_FromLong(entry->acct_flags)); + PyDict_SetItemString(py_dict, "account_name", PyString_FromString(entry->account_name)); + PyDict_SetItemString(py_dict, "fullname", PyString_FromString(entry->fullname)); + PyDict_SetItemString(py_dict, "description", PyString_FromString(entry->description)); + PyList_Append(py_userlist, py_dict); + } + } + search->search_end(search); + talloc_free(tframe); - Py_RETURN_NONE; + + return py_userlist; } -static PyObject *py_pdb_rename_sam_account(pytalloc_Object *self, PyObject *args) + +static PyObject *py_pdb_search_groups(pytalloc_Object *self) { NTSTATUS status; struct pdb_methods *methods; TALLOC_CTX *tframe; - struct samu *sam_acct; - const char *new_username; - PyObject *py_sam_acct; - - if (!PyArg_ParseTuple(args, "O!s:rename_sam_account", &PySamu, &py_sam_acct, - &new_username)) { - return NULL; - } + struct pdb_search *search; + struct samr_displayentry *entry; + PyObject *py_grouplist, *py_dict; methods = pytalloc_get_ptr(self); @@ -1288,32 +2419,69 @@ static PyObject *py_pdb_rename_sam_account(pytalloc_Object *self, PyObject *args return NULL; } - sam_acct = pytalloc_get_ptr(py_sam_acct); + search = talloc_zero(tframe, struct pdb_search); + if (search == NULL) { + PyErr_NoMemory(); + talloc_free(tframe); + return NULL; + } - status = methods->rename_sam_account(methods, sam_acct, new_username); - if (!NT_STATUS_IS_OK(status)) { - PyErr_Format(py_pdb_error, "Unable to rename sam account, (%d,%s)", + if (!methods->search_groups(methods, search)) { + PyErr_Format(py_pdb_error, "Unable to search groups, (%d,%s)", NT_STATUS_V(status), get_friendly_nt_error_msg(status)); talloc_free(tframe); return NULL; } + entry = talloc_zero(tframe, struct samr_displayentry); + if (entry == NULL) { + PyErr_NoMemory(); + talloc_free(tframe); + return NULL; + } + + py_grouplist = PyList_New(0); + if (py_grouplist == NULL) { + PyErr_NoMemory(); + talloc_free(tframe); + return NULL; + } + + while (search->next_entry(search, entry)) { + py_dict = PyDict_New(); + if (py_dict == NULL) { + PyErr_NoMemory(); + } else { + PyDict_SetItemString(py_dict, "idx", PyInt_FromLong(entry->idx)); + PyDict_SetItemString(py_dict, "rid", PyInt_FromLong(entry->rid)); + PyDict_SetItemString(py_dict, "acct_flags", PyInt_FromLong(entry->acct_flags)); + PyDict_SetItemString(py_dict, "account_name", PyString_FromString(entry->account_name)); + PyDict_SetItemString(py_dict, "fullname", PyString_FromString(entry->fullname)); + PyDict_SetItemString(py_dict, "description", PyString_FromString(entry->description)); + PyList_Append(py_grouplist, py_dict); + } + } + search->search_end(search); + talloc_free(tframe); - Py_RETURN_NONE; + + return py_grouplist; } -static PyObject *py_pdb_search_users(pytalloc_Object *self, PyObject *args) + +static PyObject *py_pdb_search_aliases(pytalloc_Object *self, PyObject *args) { NTSTATUS status; struct pdb_methods *methods; TALLOC_CTX *tframe; - unsigned int acct_flags; struct pdb_search *search; struct samr_displayentry *entry; - PyObject *py_userlist, *py_dict; + PyObject *py_aliaslist, *py_dict; + PyObject *py_domain_sid; + struct dom_sid *dom_sid; - if (!PyArg_ParseTuple(args, "I:search_users", &acct_flags)) { + if (!PyArg_ParseTuple(args, "O!:search_users", dom_sid_Type, &py_domain_sid)) { return NULL; } @@ -1324,6 +2492,8 @@ static PyObject *py_pdb_search_users(pytalloc_Object *self, PyObject *args) return NULL; } + dom_sid = pytalloc_get_ptr(py_domain_sid); + search = talloc_zero(tframe, struct pdb_search); if (search == NULL) { PyErr_NoMemory(); @@ -1331,8 +2501,8 @@ static PyObject *py_pdb_search_users(pytalloc_Object *self, PyObject *args) return NULL; } - if (!methods->search_users(methods, search, acct_flags)) { - PyErr_Format(py_pdb_error, "Unable to search users, (%d,%s)", + if (!methods->search_aliases(methods, search, dom_sid)) { + PyErr_Format(py_pdb_error, "Unable to search aliases, (%d,%s)", NT_STATUS_V(status), get_friendly_nt_error_msg(status)); talloc_free(tframe); @@ -1346,8 +2516,8 @@ static PyObject *py_pdb_search_users(pytalloc_Object *self, PyObject *args) return NULL; } - py_userlist = PyList_New(0); - if (py_userlist == NULL) { + py_aliaslist = PyList_New(0); + if (py_aliaslist == NULL) { PyErr_NoMemory(); talloc_free(tframe); return NULL; @@ -1364,26 +2534,26 @@ static PyObject *py_pdb_search_users(pytalloc_Object *self, PyObject *args) PyDict_SetItemString(py_dict, "account_name", PyString_FromString(entry->account_name)); PyDict_SetItemString(py_dict, "fullname", PyString_FromString(entry->fullname)); PyDict_SetItemString(py_dict, "description", PyString_FromString(entry->description)); - PyList_Append(py_userlist, py_dict); + PyList_Append(py_aliaslist, py_dict); } } search->search_end(search); talloc_free(tframe); - return py_userlist; + return py_aliaslist; } static PyMethodDef py_pdb_methods[] = { { "domain_info", (PyCFunction)py_pdb_domain_info, METH_NOARGS, "domain_info() -> str\n\n \ - Get domain for the database." }, + Get domain information for the database." }, { "getsampwnam", (PyCFunction)py_pdb_getsampwnam, METH_VARARGS, "getsampwnam(username) -> samu object\n\n \ - Get user information." }, + Get user information by name." }, { "getsampwsid", (PyCFunction)py_pdb_getsampwsid, METH_VARARGS, - "getsampwsid(sid) -> samu object\n\n \ - Get user information from user_sid (dcerpc.security.dom_sid object)." }, + "getsampwsid(user_sid) -> samu object\n\n \ + Get user information by sid (dcerpc.security.dom_sid object)." }, { "create_user", (PyCFunction)py_pdb_create_user, METH_VARARGS, "create_user(username, acct_flags) -> rid\n\n \ Create user. acct_flags are samr account control flags." }, @@ -1402,11 +2572,105 @@ static PyMethodDef py_pdb_methods[] = { { "rename_sam_account", (PyCFunction)py_pdb_rename_sam_account, METH_VARARGS, "rename_sam_account(samu object1, new_username) -> None\n\n \ Rename SAM account." }, + /* update_login_attempts */ + { "getgrsid", (PyCFunction)py_pdb_getgrsid, METH_VARARGS, + "getgrsid(group_sid) -> groupmap object\n\n \ + Get group information by sid (dcerpc.security.dom_sid object)." }, + { "getgrgid", (PyCFunction)py_pdb_getgrgid, METH_VARARGS, + "getgrsid(gid) -> groupmap object\n\n \ + Get group information by gid." }, + { "getgrnam", (PyCFunction)py_pdb_getgrnam, METH_VARARGS, + "getgrsid(groupname) -> groupmap object\n\n \ + Get group information by name." }, + { "create_dom_group", (PyCFunction)py_pdb_create_dom_group, METH_VARARGS, + "create_dom_group(groupname) -> group_rid\n\n \ + Create new domain group by name." }, + { "delete_dom_group", (PyCFunction)py_pdb_delete_dom_group, METH_VARARGS, + "delete_dom_group(group_rid) -> None\n\n \ + Delete domain group identified by rid" }, + { "add_group_mapping_entry", (PyCFunction)py_pdb_add_group_mapping_entry, METH_VARARGS, + "add_group_mapping_entry(groupmap) -> None\n \ + Add group mapping entry for groupmap object." }, + { "update_group_mapping_entry", (PyCFunction)py_pdb_update_group_mapping_entry, METH_VARARGS, + "update_group_mapping_entry(groupmap) -> None\n\n \ + Update group mapping entry for groupmap object." }, + { "delete_group_mapping_entry", (PyCFunction)py_pdb_delete_group_mapping_entry, METH_VARARGS, + "delete_group_mapping_entry(groupmap) -> None\n\n \ + Delete group mapping entry for groupmap object." }, + { "enum_group_mapping", (PyCFunction)py_pdb_enum_group_mapping, METH_VARARGS, + "enum_group_mapping(domain_sid) -> List\n\n \ + Return list of group mappings as groupmap objects." }, + { "enum_group_members", (PyCFunction)py_pdb_enum_group_members, METH_VARARGS, + "enum_group_members(group_sid) -> List\n\n \ + Return list of group members." }, + /* enum_group_memberships */ + /* set_unix_primary_group */ + { "add_groupmem", (PyCFunction)py_pdb_add_groupmem, METH_VARARGS, + "add_groupmem(group_rid, member_rid) -> None\n\n \ + Add user to group." }, + { "del_groupmem", (PyCFunction)py_pdb_del_groupmem, METH_VARARGS, + "del_groupmem(group_rid, member_rid) -> None\n\n \ + Remove user from from group." }, + { "create_alias", (PyCFunction)py_pdb_create_alias, METH_VARARGS, + "create_alias(alias_name) -> alias_rid\n\n \ + Create alias entry." }, + { "delete_alias", (PyCFunction)py_pdb_delete_alias, METH_VARARGS, + "delete_alias(alias_sid) -> None\n\n \ + Delete alias entry." }, + { "get_aliasinfo", (PyCFunction)py_pdb_get_aliasinfo, METH_VARARGS, + "get_aliasinfo(alias_sid) -> Mapping\n\n \ + Get alias information as a dictionary with keys - acct_name, acct_desc, rid." }, + { "set_aliasinfo", (PyCFunction)py_pdb_set_aliasinfo, METH_VARARGS, + "set_alias_info(alias_sid, Mapping) -> None\n\n \ + Set alias information from a dictionary with keys - acct_name, acct_desc." }, + { "add_aliasmem", (PyCFunction)py_pdb_add_aliasmem, METH_VARARGS, + "add_aliasmem(alias_sid, member_sid) -> None\n\n \ + Add user to alias entry." }, + { "del_aliasmem", (PyCFunction)py_pdb_del_aliasmem, METH_VARARGS, + "del_aliasmem(alias_sid, member_sid) -> None\n\n \ + Remove a user from alias entry." }, + { "enum_aliasmem", (PyCFunction)py_pdb_enum_aliasmem, METH_VARARGS, + "enum_aliasmem(alias_sid) -> List\n\n \ + Return a list of users for alias entry." }, + /* enum_alias_memberships */ + /* lookup_rids */ + /* lookup_names */ + { "get_account_policy", (PyCFunction)py_pdb_get_account_policy, METH_NOARGS, + "get_account_policy() -> Mapping\n\n \ + Get account policy information as a dictionary." }, + { "set_account_policy", (PyCFunction)py_pdb_set_account_policy, METH_VARARGS, + "get_account_policy(Mapping) -> None\n\n \ + Set account policy settings from a dicionary." }, + /* get_seq_num */ { "search_users", (PyCFunction)py_pdb_search_users, METH_VARARGS, "search_users(acct_flags) -> List\n\n \ Search users. acct_flags are samr account control flags.\n \ - Each entry in the list is a dictionary with keys - \ - idx, rid, acct_flags, account_name, fullname, description." }, + Each list entry is dictionary with keys - idx, rid, acct_flags, account_name, fullname, description." }, + { "search_groups", (PyCFunction)py_pdb_search_groups, METH_NOARGS, + "search_groups() -> List\n\n \ + Search unix only groups. \n \ + Each list entry is dictionary with keys - idx, rid, acct_flags, account_name, fullname, description." }, + { "search_aliases", (PyCFunction)py_pdb_search_aliases, METH_VARARGS, + "search_aliases(domain_sid) -> List\n\n \ + Search aliases. domain_sid is dcerpc.security.dom_sid object.\n \ + Each list entry is dictionary with keys - idx, rid, acct_flags, account_name, fullname, description." }, + /* uid_to_sid */ + /* gid_to_sid */ + /* sid_to_id */ + /* capabilities */ + /* new_rid */ + /* get_trusteddom_pw */ + /* set_trusteddom_pw */ + /* del_trusteddom_pw */ + /* enum_trusteddoms */ + /* get_trusted_domain */ + /* get_trusted_domain_by_sid */ + /* set_trusted_domain */ + /* del_trusted_domain */ + /* enum_trusted_domains */ + /* get_secret */ + /* set_secret */ + /* delete_secret */ { NULL }, }; @@ -1603,6 +2867,11 @@ void initpassdb(void) return; } + PyGroupmap.tp_base = talloc_type; + if (PyType_Ready(&PyGroupmap) < 0) { + return; + } + m = Py_InitModule3("passdb", py_passdb_methods, "SAMBA Password Database"); if (m == NULL) { return; @@ -1616,6 +2885,12 @@ void initpassdb(void) Py_INCREF(&PyPDB); PyModule_AddObject(m, "PDB", (PyObject *)&PyPDB); + Py_INCREF(&PySamu); + PyModule_AddObject(m, "Samu", (PyObject *)&PySamu); + + Py_INCREF(&PyGroupmap); + PyModule_AddObject(m, "Groupmap", (PyObject *)&PyGroupmap); + /* Import dom_sid type from dcerpc.security */ mod = PyImport_ImportModule("samba.dcerpc.security"); if (mod == NULL) { -- cgit