diff options
Diffstat (limited to 'source3/python')
-rw-r--r-- | source3/python/py_common_proto.h | 32 | ||||
-rw-r--r-- | source3/python/py_lsa.c | 462 | ||||
-rw-r--r-- | source3/python/py_smb.c | 224 | ||||
-rw-r--r-- | source3/python/py_smb.h | 42 |
4 files changed, 760 insertions, 0 deletions
diff --git a/source3/python/py_common_proto.h b/source3/python/py_common_proto.h new file mode 100644 index 0000000000..89f0f35fc9 --- /dev/null +++ b/source3/python/py_common_proto.h @@ -0,0 +1,32 @@ +#ifndef _PY_COMMON_PROTO_H +#define _PY_COMMON_PROTO_H + +/* This file is automatically generated with "make proto". DO NOT EDIT */ + + +/* The following definitions come from python/py_common.c */ + +PyObject *py_werror_tuple(WERROR werror); +PyObject *py_ntstatus_tuple(NTSTATUS ntstatus); +void py_samba_init(void); +PyObject *get_debuglevel(PyObject *self, PyObject *args); +PyObject *set_debuglevel(PyObject *self, PyObject *args); +PyObject *py_setup_logging(PyObject *self, PyObject *args, PyObject *kw); +BOOL py_parse_creds(PyObject *creds, char **username, char **domain, + char **password, char **errstr); +struct cli_state *open_pipe_creds(char *server, PyObject *creds, + char *pipe_name, char **errstr); +BOOL get_level_value(PyObject *dict, uint32 *level); + +/* The following definitions come from python/py_ntsec.c */ + +BOOL py_from_SID(PyObject **obj, DOM_SID *sid); +BOOL py_to_SID(DOM_SID *sid, PyObject *obj); +BOOL py_from_ACE(PyObject **dict, SEC_ACE *ace); +BOOL py_to_ACE(SEC_ACE *ace, PyObject *dict); +BOOL py_from_ACL(PyObject **dict, SEC_ACL *acl); +BOOL py_to_ACL(SEC_ACL *acl, PyObject *dict, TALLOC_CTX *mem_ctx); +BOOL py_from_SECDESC(PyObject **dict, SEC_DESC *sd); +BOOL py_to_SECDESC(SEC_DESC **sd, PyObject *dict, TALLOC_CTX *mem_ctx); + +#endif /* _PY_COMMON_PROTO_H */ diff --git a/source3/python/py_lsa.c b/source3/python/py_lsa.c new file mode 100644 index 0000000000..0584cf716b --- /dev/null +++ b/source3/python/py_lsa.c @@ -0,0 +1,462 @@ +/* + 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_lsa.h" + +PyObject *new_lsa_policy_hnd_object(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol) +{ + lsa_policy_hnd_object *o; + + o = PyObject_New(lsa_policy_hnd_object, &lsa_policy_hnd_type); + + o->cli = cli; + o->mem_ctx = mem_ctx; + memcpy(&o->pol, pol, sizeof(POLICY_HND)); + + return (PyObject*)o; +} + +/* + * Exceptions raised by this module + */ + +PyObject *lsa_error; /* This indicates a non-RPC related error + such as name lookup failure */ + +PyObject *lsa_ntstatus; /* This exception is raised when a RPC call + returns a status code other than + NT_STATUS_OK */ + +/* + * Open/close lsa handles + */ + +static PyObject *lsa_open_policy(PyObject *self, PyObject *args, + PyObject *kw) +{ + static char *kwlist[] = { "servername", "creds", "access", NULL }; + char *server, *errstr; + PyObject *creds = NULL, *result = NULL; + uint32 desired_access = MAXIMUM_ALLOWED_ACCESS; + struct cli_state *cli = NULL; + NTSTATUS ntstatus; + TALLOC_CTX *mem_ctx = NULL; + POLICY_HND hnd; + + if (!PyArg_ParseTupleAndKeywords( + args, kw, "s|Oi", kwlist, &server, &creds, &desired_access)) + return NULL; + + if (creds && creds != Py_None && !PyDict_Check(creds)) { + PyErr_SetString(PyExc_TypeError, + "credentials must be dictionary or None"); + return NULL; + } + + if (server[0] != '\\' || server[1] != '\\') { + PyErr_SetString(PyExc_ValueError, "UNC name required"); + return NULL; + } + + server += 2; + + if (!(cli = open_pipe_creds(server, creds, PIPE_LSARPC, &errstr))) { + PyErr_SetString(lsa_error, errstr); + free(errstr); + return NULL; + } + + if (!(mem_ctx = talloc_init())) { + PyErr_SetString(lsa_error, "unable to init talloc context\n"); + goto done; + } + + ntstatus = cli_lsa_open_policy(cli, mem_ctx, True, + SEC_RIGHTS_MAXIMUM_ALLOWED, &hnd); + + if (!NT_STATUS_IS_OK(ntstatus)) { + PyErr_SetObject(lsa_ntstatus, py_ntstatus_tuple(ntstatus)); + goto done; + } + + result = new_lsa_policy_hnd_object(cli, mem_ctx, &hnd); + +done: + if (!result) { + if (cli) + cli_shutdown(cli); + + if (mem_ctx) + talloc_destroy(mem_ctx); + } + + return result; +} + +static PyObject *lsa_close(PyObject *self, PyObject *args, PyObject *kw) +{ + PyObject *po; + lsa_policy_hnd_object *hnd; + NTSTATUS result; + + /* Parse parameters */ + + if (!PyArg_ParseTuple(args, "O!", &lsa_policy_hnd_type, &po)) + return NULL; + + hnd = (lsa_policy_hnd_object *)po; + + /* Call rpc function */ + + result = cli_lsa_close(hnd->cli, hnd->mem_ctx, &hnd->pol); + + /* Cleanup samba stuff */ + + cli_shutdown(hnd->cli); + talloc_destroy(hnd->mem_ctx); + + /* Return value */ + + Py_INCREF(Py_None); + return Py_None; +} + +static PyObject *lsa_lookup_names(PyObject *self, PyObject *args) +{ + PyObject *py_names, *result; + NTSTATUS ntstatus; + lsa_policy_hnd_object *hnd = (lsa_policy_hnd_object *)self; + int num_names, i; + const char **names; + DOM_SID *sids; + uint32 *name_types; + + if (!PyArg_ParseTuple(args, "O", &py_names)) + return NULL; + + if (!PyList_Check(py_names) && !PyString_Check(py_names)) { + PyErr_SetString(PyExc_TypeError, "must be list or string"); + return NULL; + } + + if (PyList_Check(py_names)) { + + /* Convert list to char ** array */ + + num_names = PyList_Size(py_names); + names = (const char **)talloc( + hnd->mem_ctx, num_names * sizeof(char *)); + + for (i = 0; i < num_names; i++) { + PyObject *obj = PyList_GetItem(py_names, i); + + names[i] = talloc_strdup(hnd->mem_ctx, PyString_AsString(obj)); + } + + } else { + + /* Just a single element */ + + num_names = 1; + names = (const char **)talloc(hnd->mem_ctx, sizeof(char *)); + + names[0] = PyString_AsString(py_names); + } + + ntstatus = cli_lsa_lookup_names(hnd->cli, hnd->mem_ctx, &hnd->pol, + num_names, names, &sids, &name_types); + + if (!NT_STATUS_IS_OK(ntstatus) && NT_STATUS_V(ntstatus) != 0x107) { + PyErr_SetObject(lsa_ntstatus, py_ntstatus_tuple(ntstatus)); + return NULL; + } + + result = PyList_New(num_names); + + for (i = 0; i < num_names; i++) { + PyObject *sid_obj, *obj; + + py_from_SID(&sid_obj, &sids[i]); + + obj = Py_BuildValue("(Oi)", sid_obj, name_types[i]); + + PyList_SetItem(result, i, obj); + } + + return result; +} + +static PyObject *lsa_lookup_sids(PyObject *self, PyObject *args, + PyObject *kw) +{ + PyObject *py_sids, *result; + NTSTATUS ntstatus; + int num_sids, i; + char **domains, **names; + uint32 *types; + lsa_policy_hnd_object *hnd = (lsa_policy_hnd_object *)self; + DOM_SID *sids; + + if (!PyArg_ParseTuple(args, "O", &py_sids)) + return NULL; + + if (!PyList_Check(py_sids) && !PyString_Check(py_sids)) { + PyErr_SetString(PyExc_TypeError, "must be list or string"); + return NULL; + } + + if (PyList_Check(py_sids)) { + + /* Convert dictionary to char ** array */ + + num_sids = PyList_Size(py_sids); + sids = (DOM_SID *)talloc(hnd->mem_ctx, num_sids * sizeof(DOM_SID)); + + memset(sids, 0, num_sids * sizeof(DOM_SID)); + + for (i = 0; i < num_sids; i++) { + PyObject *obj = PyList_GetItem(py_sids, i); + + string_to_sid(&sids[i], PyString_AsString(obj)); + } + + } else { + + /* Just a single element */ + + num_sids = 1; + sids = (DOM_SID *)talloc(hnd->mem_ctx, sizeof(DOM_SID)); + + string_to_sid(&sids[0], PyString_AsString(py_sids)); + } + + ntstatus = cli_lsa_lookup_sids(hnd->cli, hnd->mem_ctx, &hnd->pol, + num_sids, sids, &domains, &names, + &types); + + if (!NT_STATUS_IS_OK(ntstatus)) { + PyErr_SetObject(lsa_ntstatus, py_ntstatus_tuple(ntstatus)); + return NULL; + } + + result = PyList_New(num_sids); + + for (i = 0; i < num_sids; i++) { + PyObject *obj; + + obj = Py_BuildValue("{sssssi}", "username", names[i], + "domain", domains[i], "name_type", + types[i]); + + PyList_SetItem(result, i, obj); + } + + return result; +} + +static PyObject *lsa_enum_trust_dom(PyObject *self, PyObject *args) +{ + lsa_policy_hnd_object *hnd = (lsa_policy_hnd_object *)self; + NTSTATUS ntstatus; + uint32 enum_ctx = 0, num_domains, i; + char **domain_names; + DOM_SID *domain_sids; + PyObject *result; + + if (!PyArg_ParseTuple(args, "")) + return NULL; + + ntstatus = cli_lsa_enum_trust_dom( + hnd->cli, hnd->mem_ctx, &hnd->pol, &enum_ctx, + &num_domains, &domain_names, &domain_sids); + + if (!NT_STATUS_IS_OK(ntstatus)) { + PyErr_SetObject(lsa_ntstatus, py_ntstatus_tuple(ntstatus)); + return NULL; + } + + result = PyList_New(num_domains); + + for (i = 0; i < num_domains; i++) { + fstring sid_str; + + sid_to_string(sid_str, &domain_sids[i]); + PyList_SetItem( + result, i, + Py_BuildValue("(ss)", domain_names[i], sid_str)); + } + + return result; +} + +/* + * Method dispatch tables + */ + +static PyMethodDef lsa_hnd_methods[] = { + + /* SIDs<->names */ + + { "lookup_sids", (PyCFunction)lsa_lookup_sids, + METH_VARARGS | METH_KEYWORDS, + "Convert sids to names." }, + + { "lookup_names", (PyCFunction)lsa_lookup_names, + METH_VARARGS | METH_KEYWORDS, + "Convert names to sids." }, + + /* Trusted domains */ + + { "enum_trusted_domains", (PyCFunction)lsa_enum_trust_dom, + METH_VARARGS, + "Enumerate trusted domains." }, + + { NULL } +}; + +static void py_lsa_policy_hnd_dealloc(PyObject* self) +{ + PyObject_Del(self); +} + +static PyObject *py_lsa_policy_hnd_getattr(PyObject *self, char *attrname) +{ + return Py_FindMethod(lsa_hnd_methods, self, attrname); +} + +PyTypeObject lsa_policy_hnd_type = { + PyObject_HEAD_INIT(NULL) + 0, + "LSA Policy Handle", + sizeof(lsa_policy_hnd_object), + 0, + py_lsa_policy_hnd_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + py_lsa_policy_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 */ +}; + +static PyMethodDef lsa_methods[] = { + + /* Open/close lsa handles */ + + { "open_policy", (PyCFunction)lsa_open_policy, + METH_VARARGS | METH_KEYWORDS, + "Open a policy handle" }, + + { "close", (PyCFunction)lsa_close, + METH_VARARGS, + "Close a policy handle" }, + + /* Other stuff - this should really go into a samba config module + but for the moment let's leave it here. */ + + { "setup_logging", (PyCFunction)py_setup_logging, + METH_VARARGS | METH_KEYWORDS, + "Set up debug logging. + +Initialises Samba's debug logging system. One argument is expected which +is a boolean specifying whether debugging is interactive and sent to stdout +or logged to a file. + +Example: + +>>> spoolss.setup_logging(interactive = 1)" }, + + { "get_debuglevel", (PyCFunction)get_debuglevel, + METH_VARARGS, + "Set the current debug level. + +Example: + +>>> spoolss.get_debuglevel() +0" }, + + { "set_debuglevel", (PyCFunction)set_debuglevel, + METH_VARARGS, + "Get the current debug level. + +Example: + +>>> spoolss.set_debuglevel(10)" }, + + { 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); + } +} + +/* + * Module initialisation + */ + +void initlsa(void) +{ + PyObject *module, *dict; + + /* Initialise module */ + + module = Py_InitModule("lsa", lsa_methods); + dict = PyModule_GetDict(module); + + lsa_error = PyErr_NewException("lsa.error", NULL, NULL); + PyDict_SetItemString(dict, "error", lsa_error); + + lsa_ntstatus = PyErr_NewException("lsa.ntstatus", NULL, NULL); + PyDict_SetItemString(dict, "ntstatus", lsa_ntstatus); + + /* Initialise policy handle object */ + + lsa_policy_hnd_type.ob_type = &PyType_Type; + + /* Initialise constants */ + + const_init(dict); + + /* Do samba initialisation */ + + py_samba_init(); + + setup_logging("lsa", True); + DEBUGLEVEL = 10; +} diff --git a/source3/python/py_smb.c b/source3/python/py_smb.c new file mode 100644 index 0000000000..77d7bb32fc --- /dev/null +++ b/source3/python/py_smb.c @@ -0,0 +1,224 @@ +/* + 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_smb.h" + +/* Create a new cli_state python object */ + +PyObject *new_cli_state_object(struct cli_state *cli) +{ + cli_state_object *o; + + o = PyObject_New(cli_state_object, &cli_state_type); + + o->cli = cli; + + return (PyObject*)o; +} + +static PyObject *py_smb_connect(PyObject *self, PyObject *args, PyObject *kw) +{ + static char *kwlist[] = { "server", NULL }; + struct cli_state *cli; + char *server; + struct in_addr ip; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "s", kwlist, &server)) + return NULL; + + if (!(cli = cli_initialise(NULL))) + return NULL; + + ZERO_STRUCT(ip); + + if (!cli_connect(cli, server, &ip)) + return NULL; + + return new_cli_state_object(cli); +} + +static PyObject *py_smb_session_request(PyObject *self, PyObject *args, + PyObject *kw) +{ + cli_state_object *cli = (cli_state_object *)self; + static char *kwlist[] = { "called", "calling", NULL }; + char *calling_name = NULL, *called_name; + struct nmb_name calling, called; + extern pstring global_myname; + BOOL result; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "s|s", kwlist, &called_name, + &calling_name)) + return NULL; + + if (!calling_name) + calling_name = global_myname; + + make_nmb_name(&calling, calling_name, 0x00); + make_nmb_name(&called, called_name, 0x20); + + result = cli_session_request(cli->cli, &calling, &called); + + return Py_BuildValue("i", result); +} + +static PyObject *py_smb_negprot(PyObject *self, PyObject *args, PyObject *kw) +{ + cli_state_object *cli = (cli_state_object *)self; + static char *kwlist[] = { NULL }; + BOOL result; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "", kwlist)) + return NULL; + + result = cli_negprot(cli->cli); + + return Py_BuildValue("i", result); +} + +static PyObject *py_smb_session_setup(PyObject *self, PyObject *args, + PyObject *kw) +{ + cli_state_object *cli = (cli_state_object *)self; + static char *kwlist[] = { "creds" }; + PyObject *creds; + char *username, *domain, *password, *errstr; + BOOL result; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "O", kwlist, &creds)) + return NULL; + + if (!py_parse_creds(creds, &username, &domain, &password, &errstr)) { + free(errstr); + return NULL; + } + + result = cli_session_setup( + cli->cli, username, password, strlen(password) + 1, + password, strlen(password) + 1, domain); + + return Py_BuildValue("i", result); +} + +static PyObject *py_smb_tconx(PyObject *self, PyObject *args, PyObject *kw) +{ + cli_state_object *cli = (cli_state_object *)self; + static char *kwlist[] = { "service", "creds" }; + PyObject *creds; + char *service, *username, *domain, *password, *errstr; + BOOL result; + + if (!PyArg_ParseTupleAndKeywords(args, kw, "sO", kwlist, &service, + &creds)) + return NULL; + + if (!py_parse_creds(creds, &username, &domain, &password, &errstr)) { + free(errstr); + return NULL; + } + + result = cli_send_tconX( + cli->cli, service, strequal(service, "IPC$") ? "IPC" : "?????", + password, strlen(password) + 1); + + return Py_BuildValue("i", result); +} + +static PyMethodDef smb_hnd_methods[] = { + + { "session_request", (PyCFunction)py_smb_session_request, + METH_VARARGS | METH_KEYWORDS, "Request a session" }, + + { "negprot", (PyCFunction)py_smb_negprot, + METH_VARARGS | METH_KEYWORDS, "Protocol negotiation" }, + + { "session_setup", (PyCFunction)py_smb_session_setup, + METH_VARARGS | METH_KEYWORDS, "Session setup" }, + + { "tconx", (PyCFunction)py_smb_tconx, + METH_VARARGS | METH_KEYWORDS, "Tree connect" }, + + { NULL } +}; + +/* + * Method dispatch tables + */ + +static PyMethodDef smb_methods[] = { + + { "connect", (PyCFunction)py_smb_connect, METH_VARARGS | METH_KEYWORDS, + "Connect to a host" }, + + { NULL } +}; + +static void py_cli_state_dealloc(PyObject* self) +{ + PyObject_Del(self); +} + +static PyObject *py_cli_state_getattr(PyObject *self, char *attrname) +{ + return Py_FindMethod(smb_hnd_methods, self, attrname); +} + +PyTypeObject cli_state_type = { + PyObject_HEAD_INIT(NULL) + 0, + "SMB client connection", + sizeof(cli_state_object), + 0, + py_cli_state_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + py_cli_state_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 */ +}; + +/* + * Module initialisation + */ + +void initsmb(void) +{ + PyObject *module, *dict; + + /* Initialise module */ + + module = Py_InitModule("smb", smb_methods); + dict = PyModule_GetDict(module); + + /* Initialise policy handle object */ + + cli_state_type.ob_type = &PyType_Type; + + /* Do samba initialisation */ + + py_samba_init(); + + setup_logging("smb", True); + DEBUGLEVEL = 10; +} diff --git a/source3/python/py_smb.h b/source3/python/py_smb.h new file mode 100644 index 0000000000..18677b4905 --- /dev/null +++ b/source3/python/py_smb.h @@ -0,0 +1,42 @@ +/* + 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. +*/ + +#ifndef _PY_SMB_H +#define _PY_SMB_H + +#include "includes.h" +#include "Python.h" + +#include "python/py_common_proto.h" + +/* cli_state handle object */ + +typedef struct { + PyObject_HEAD + struct cli_state *cli; +} cli_state_object; + +/* Exceptions raised by this module */ + +extern PyTypeObject cli_state_type; + +extern PyObject *smb_ntstatus; + +#endif /* _PY_SMB_H */ |