mirror of
				https://github.com/samba-team/samba.git
				synced 2025-10-30 08:23:49 +03:00 
			
		
		
		
	
						-
					
				
			
		
		
			
				
	
	
		
			498 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			498 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* 
 | |
|    Python wrappers for DCERPC/SMB client routines.
 | |
| 
 | |
|    Copyright (C) Tim Potter, 2002
 | |
|    
 | |
|    This program is free software; you can redistribute it and/or modify
 | |
|    it under the terms of the GNU General Public License as published by
 | |
|    the Free Software Foundation; either version 2 of the License, or
 | |
|    (at your option) any later version.
 | |
|    
 | |
|    This program is distributed in the hope that it will be useful,
 | |
|    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
|    GNU General Public License for more details.
 | |
|    
 | |
|    You should have received a copy of the GNU General Public License
 | |
|    along with this program; if not, write to the Free Software
 | |
|    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | |
| */
 | |
| 
 | |
| #include "python/py_samr.h"
 | |
| 
 | |
| /* 
 | |
|  * Exceptions raised by this module 
 | |
|  */
 | |
| 
 | |
| PyObject *samr_error;		/* This indicates a non-RPC related error
 | |
| 				   such as name lookup failure */
 | |
| 
 | |
| PyObject *samr_ntstatus;	/* This exception is raised when a RPC call
 | |
| 				   returns a status code other than
 | |
| 				   NT_STATUS_OK */
 | |
| 
 | |
| /* SAMR connect handle object */
 | |
| 
 | |
| static void py_samr_connect_hnd_dealloc(PyObject* self)
 | |
| {
 | |
| 	PyObject_Del(self);
 | |
| }
 | |
| 
 | |
| PyObject *new_samr_domain_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 | |
| 				     POLICY_HND *pol)
 | |
| {
 | |
| 	samr_domain_hnd_object *o;
 | |
| 
 | |
| 	o = PyObject_New(samr_domain_hnd_object, &samr_domain_hnd_type);
 | |
| 
 | |
| 	o->cli = cli;
 | |
| 	o->mem_ctx = mem_ctx;
 | |
| 	memcpy(&o->domain_pol, pol, sizeof(POLICY_HND));
 | |
| 
 | |
| 	return (PyObject*)o;
 | |
| }
 | |
| 
 | |
| static PyObject *samr_open_domain(PyObject *self, PyObject *args, PyObject *kw)
 | |
| {
 | |
| 	samr_connect_hnd_object *connect_hnd = (samr_connect_hnd_object *)self;
 | |
| 	static char *kwlist[] = { "sid", "access", NULL };
 | |
| 	uint32 desired_access = MAXIMUM_ALLOWED_ACCESS;
 | |
| 	char *sid_str;
 | |
| 	DOM_SID sid;
 | |
| 	TALLOC_CTX *mem_ctx = NULL;
 | |
| 	POLICY_HND domain_pol;
 | |
| 	NTSTATUS ntstatus;
 | |
| 	PyObject *result = NULL;
 | |
| 
 | |
| 	if (!PyArg_ParseTupleAndKeywords(
 | |
| 		    args, kw, "s|i", kwlist, &sid_str, &desired_access))
 | |
| 		return NULL;
 | |
| 
 | |
| 	if (!string_to_sid(&sid, sid_str)) {
 | |
| 		PyErr_SetString(PyExc_TypeError, "string is not a sid");
 | |
| 		return NULL;
 | |
| 	}
 | |
| 
 | |
| 	if (!(mem_ctx = talloc_init("samr_open_domain"))) {
 | |
| 		PyErr_SetString(samr_error, "unable to init talloc context");
 | |
| 		return NULL;
 | |
| 	}
 | |
| 
 | |
| 	ntstatus = cli_samr_open_domain(
 | |
| 		connect_hnd->cli, mem_ctx, &connect_hnd->connect_pol,
 | |
| 		desired_access, &sid, &domain_pol);
 | |
| 					
 | |
| 	if (!NT_STATUS_IS_OK(ntstatus)) {
 | |
| 		PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
 | |
| 		goto done;
 | |
| 	}
 | |
| 
 | |
| 	result = new_samr_domain_hnd_object(
 | |
| 		connect_hnd->cli, mem_ctx, &domain_pol);
 | |
| 
 | |
| done:
 | |
| 	if (!result) {
 | |
| 		if (mem_ctx)
 | |
| 			talloc_destroy(mem_ctx);
 | |
| 	}
 | |
| 
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| static PyMethodDef samr_connect_methods[] = {
 | |
| 	{ "open_domain", (PyCFunction)samr_open_domain,
 | |
| 	  METH_VARARGS | METH_KEYWORDS,
 | |
| 	  "Open a handle on a domain" },
 | |
| 
 | |
| 	{ NULL }
 | |
| };
 | |
| 
 | |
| static PyObject *py_samr_connect_hnd_getattr(PyObject *self, char *attrname)
 | |
| {
 | |
| 	return Py_FindMethod(samr_connect_methods, self, attrname);
 | |
| }
 | |
| 
 | |
| PyTypeObject samr_connect_hnd_type = {
 | |
| 	PyObject_HEAD_INIT(NULL)
 | |
| 	0,
 | |
| 	"SAMR Connect Handle",
 | |
| 	sizeof(samr_connect_hnd_object),
 | |
| 	0,
 | |
| 	py_samr_connect_hnd_dealloc, /*tp_dealloc*/
 | |
| 	0,          /*tp_print*/
 | |
| 	py_samr_connect_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_connect_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx,
 | |
| 				      POLICY_HND *pol)
 | |
| {
 | |
| 	samr_connect_hnd_object *o;
 | |
| 
 | |
| 	o = PyObject_New(samr_connect_hnd_object, &samr_connect_hnd_type);
 | |
| 
 | |
| 	o->cli = cli;
 | |
| 	o->mem_ctx = mem_ctx;
 | |
| 	memcpy(&o->connect_pol, pol, sizeof(POLICY_HND));
 | |
| 
 | |
| 	return (PyObject*)o;
 | |
| }
 | |
| 
 | |
| /* SAMR domain handle object */
 | |
| 
 | |
| static void py_samr_domain_hnd_dealloc(PyObject* self)
 | |
| {
 | |
| 	PyObject_Del(self);
 | |
| }
 | |
| 
 | |
| static PyObject *samr_enum_dom_groups(PyObject *self, PyObject *args, 
 | |
| 				      PyObject *kw)
 | |
| {
 | |
| 	samr_domain_hnd_object *domain_hnd = (samr_domain_hnd_object *)self;
 | |
| 	static char *kwlist[] = { NULL };
 | |
| 	TALLOC_CTX *mem_ctx;
 | |
| 	uint32 desired_access = MAXIMUM_ALLOWED_ACCESS;
 | |
| 	uint32 start_idx, size, num_dom_groups;
 | |
| 	struct acct_info *dom_groups;
 | |
| 	NTSTATUS result;
 | |
| 	PyObject *py_result = NULL;
 | |
| 	
 | |
| 	if (!PyArg_ParseTupleAndKeywords(
 | |
| 		    args, kw, "", kwlist))
 | |
| 		return NULL;
 | |
| 
 | |
| 	if (!(mem_ctx = talloc_init("samr_enum_dom_groups"))) {
 | |
| 		PyErr_SetString(samr_error, "unable to init talloc context");
 | |
| 		return NULL;
 | |
| 	}
 | |
| 
 | |
| 	start_idx = 0;
 | |
| 	size = 0xffff;
 | |
| 
 | |
| 	do {
 | |
| 		result = cli_samr_enum_dom_groups(
 | |
| 			domain_hnd->cli, mem_ctx, &domain_hnd->domain_pol,
 | |
| 			&start_idx, size, &dom_groups, &num_dom_groups);
 | |
| 
 | |
| 		if (NT_STATUS_IS_OK(result) ||
 | |
| 		    NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES)) {
 | |
| 			py_from_acct_info(&py_result, dom_groups,
 | |
| 					  num_dom_groups);
 | |
| 		}
 | |
| 
 | |
| 	} while (NT_STATUS_V(result) == NT_STATUS_V(STATUS_MORE_ENTRIES));
 | |
| 
 | |
| 	return py_result;
 | |
| }	
 | |
| 
 | |
| static PyMethodDef samr_domain_methods[] = {
 | |
| 	{ "enum_domain_groups", (PyCFunction)samr_enum_dom_groups,
 | |
| 	  METH_VARARGS | METH_KEYWORDS, "Enumerate domain groups" },
 | |
|   	{ NULL }
 | |
| };
 | |
| 
 | |
| static PyObject *py_samr_domain_hnd_getattr(PyObject *self, char *attrname)
 | |
| {
 | |
| 	return Py_FindMethod(samr_domain_methods, self, attrname);
 | |
| }
 | |
| 
 | |
| PyTypeObject samr_domain_hnd_type = {
 | |
| 	PyObject_HEAD_INIT(NULL)
 | |
| 	0,
 | |
| 	"SAMR Domain Handle",
 | |
| 	sizeof(samr_domain_hnd_object),
 | |
| 	0,
 | |
| 	py_samr_domain_hnd_dealloc, /*tp_dealloc*/
 | |
| 	0,          /*tp_print*/
 | |
| 	py_samr_domain_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 */
 | |
| };
 | |
| 
 | |
| /* 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 };
 | |
| 	uint32 desired_access = MAXIMUM_ALLOWED_ACCESS;
 | |
| 	char *server, *errstr;
 | |
| 	struct cli_state *cli = NULL;
 | |
| 	POLICY_HND hnd;
 | |
| 	TALLOC_CTX *mem_ctx = NULL;
 | |
| 	PyObject *result = NULL, *creds = NULL;
 | |
| 	NTSTATUS ntstatus;
 | |
| 
 | |
| 	if (!PyArg_ParseTupleAndKeywords(
 | |
| 		    args, kw, "s|Oi", kwlist, &server, &creds,
 | |
| 		    &desired_access)) 
 | |
| 		return NULL;
 | |
| 
 | |
| 	if (server[0] != '\\' || server[1] != '\\') {
 | |
| 		PyErr_SetString(PyExc_ValueError, "UNC name required");
 | |
| 		return NULL;
 | |
| 	}
 | |
| 
 | |
| 	server += 2;
 | |
| 
 | |
| 	if (creds && creds != Py_None && !PyDict_Check(creds)) {
 | |
| 		PyErr_SetString(PyExc_TypeError, 
 | |
| 				"credentials must be dictionary or None");
 | |
| 		return NULL;
 | |
| 	}
 | |
| 
 | |
| 	if (!(cli = open_pipe_creds(server, creds, PI_SAMR, &errstr))) {
 | |
| 		PyErr_SetString(samr_error, errstr);
 | |
| 		free(errstr);
 | |
| 		return NULL;
 | |
| 	}
 | |
| 
 | |
| 	if (!(mem_ctx = talloc_init("samr_connect"))) {
 | |
| 		PyErr_SetString(samr_ntstatus,
 | |
| 				"unable to init talloc context\n");
 | |
| 		goto done;
 | |
| 	}
 | |
| 
 | |
| 	ntstatus = cli_samr_connect(cli, mem_ctx, desired_access, &hnd);
 | |
| 
 | |
| 	if (!NT_STATUS_IS_OK(ntstatus)) {
 | |
| 		cli_shutdown(cli);
 | |
| 		PyErr_SetObject(samr_ntstatus, py_ntstatus_tuple(ntstatus));
 | |
| 		goto done;
 | |
| 	}
 | |
| 
 | |
| 	result = new_samr_connect_hnd_object(cli, mem_ctx, &hnd);
 | |
| 
 | |
| done:
 | |
| 	if (!result) {
 | |
| 		if (cli)
 | |
| 			cli_shutdown(cli);
 | |
| 
 | |
| 		if (mem_ctx)
 | |
| 			talloc_destroy(mem_ctx);
 | |
| 	}
 | |
| 
 | |
| 	return result;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * Module initialisation 
 | |
|  */
 | |
| 
 | |
| static PyMethodDef samr_methods[] = {
 | |
| 
 | |
| 	/* Open/close samr connect handles */
 | |
| 	
 | |
| 	{ "connect", (PyCFunction)samr_connect, 
 | |
| 	  METH_VARARGS | METH_KEYWORDS, 
 | |
| 	  "Open a connect handle" },
 | |
| 	
 | |
| 	{ NULL }
 | |
| };
 | |
| 
 | |
| static struct const_vals {
 | |
| 	char *name;
 | |
| 	uint32 value;
 | |
| } module_const_vals[] = {
 | |
| 	{ NULL }
 | |
| };
 | |
| 
 | |
| static void const_init(PyObject *dict)
 | |
| {
 | |
| 	struct const_vals *tmp;
 | |
| 	PyObject *obj;
 | |
| 
 | |
| 	for (tmp = module_const_vals; tmp->name; tmp++) {
 | |
| 		obj = PyInt_FromLong(tmp->value);
 | |
| 		PyDict_SetItemString(dict, tmp->name, obj);
 | |
| 		Py_DECREF(obj);
 | |
| 	}
 | |
| }
 | |
| 
 | |
| void initsamr(void)
 | |
| {
 | |
| 	PyObject *module, *dict;
 | |
| 
 | |
| 	/* Initialise module */
 | |
| 
 | |
| 	module = Py_InitModule("samr", samr_methods);
 | |
| 	dict = PyModule_GetDict(module);
 | |
| 
 | |
| 	samr_error = PyErr_NewException("samr.error", NULL, NULL);
 | |
| 	PyDict_SetItemString(dict, "error", samr_error);
 | |
| 
 | |
| 	samr_ntstatus = PyErr_NewException("samr.ntstatus", NULL, NULL);
 | |
| 	PyDict_SetItemString(dict, "ntstatus", samr_ntstatus);
 | |
| 
 | |
| 	/* Initialise policy handle object */
 | |
| 
 | |
| 	samr_connect_hnd_type.ob_type = &PyType_Type;
 | |
| 	samr_domain_hnd_type.ob_type = &PyType_Type;
 | |
| 	samr_user_hnd_type.ob_type = &PyType_Type;
 | |
| 	samr_group_hnd_type.ob_type = &PyType_Type;
 | |
| 	samr_alias_hnd_type.ob_type = &PyType_Type;
 | |
| 
 | |
| 	/* Initialise constants */
 | |
| 
 | |
| 	const_init(dict);
 | |
| 
 | |
| 	/* Do samba initialisation */
 | |
| 
 | |
| 	py_samba_init();
 | |
| 
 | |
| 	setup_logging("samr", True);
 | |
| 	DEBUGLEVEL = 10;
 | |
| }
 |