LCOV - code coverage report
Current view: top level - lib/ldb-samba - pyldb.c (source / functions) Hit Total Coverage
Test: coverage report for master 7edf5467 Lines: 78 99 78.8 %
Date: 2024-03-23 18:40:31 Functions: 7 8 87.5 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Python interface to ldb, Samba-specific functions
       5             : 
       6             :    Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
       7             : 
       8             :    This library is free software; you can redistribute it and/or
       9             :    modify it under the terms of the GNU Lesser General Public
      10             :    License as published by the Free Software Foundation; either
      11             :    version 3 of the License, or (at your option) any later version.
      12             : 
      13             :    This library is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      16             :    Lesser General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU Lesser General Public
      19             :    License along with this library; if not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "lib/replace/system/python.h"
      23             : #include "python/py3compat.h"
      24             : #include "includes.h"
      25             : #include <ldb.h>
      26             : #include <pyldb.h>
      27             : #include "param/pyparam.h"
      28             : #include "auth/credentials/pycredentials.h"
      29             : #include "ldb_wrap.h"
      30             : #include "lib/ldb-samba/ldif_handlers.h"
      31             : #include "auth/pyauth.h"
      32             : #include "source4/dsdb/common/util.h"
      33             : #include "lib/ldb/include/ldb_private.h"
      34             : 
      35             : 
      36             : static PyObject *pyldb_module;
      37             : static PyObject *py_ldb_error;
      38             : static PyTypeObject PySambaLdb;
      39             : 
      40           0 : static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
      41             : {
      42           0 :         if (ret == LDB_ERR_PYTHON_EXCEPTION)
      43           0 :                 return; /* Python exception should already be set, just keep that */
      44             : 
      45           0 :         PyErr_SetObject(error, 
      46             :                         Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
      47           0 :                         ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
      48             : }
      49             : 
      50       34867 : static PyObject *py_ldb_set_loadparm(PyObject *self, PyObject *args)
      51             : {
      52         407 :         PyObject *py_lp_ctx;
      53         407 :         struct loadparm_context *lp_ctx;
      54         407 :         struct ldb_context *ldb;
      55             : 
      56       34867 :         if (!PyArg_ParseTuple(args, "O", &py_lp_ctx))
      57           0 :                 return NULL;
      58             : 
      59       34867 :         ldb = pyldb_Ldb_AS_LDBCONTEXT(self);
      60             : 
      61       34867 :         lp_ctx = lpcfg_from_py_object(ldb, py_lp_ctx);
      62       34867 :         if (lp_ctx == NULL) {
      63           0 :                 PyErr_SetString(PyExc_TypeError, "Expected loadparm object");
      64           0 :                 return NULL;
      65             :         }
      66             : 
      67       34867 :         ldb_set_opaque(ldb, "loadparm", lp_ctx);
      68             : 
      69       34867 :         Py_RETURN_NONE;
      70             : }
      71             : 
      72       31807 : static PyObject *py_ldb_set_credentials(PyObject *self, PyObject *args)
      73             : {
      74         110 :         PyObject *py_creds;
      75         110 :         struct cli_credentials *creds;
      76         110 :         struct ldb_context *ldb;
      77             : 
      78       31807 :         if (!PyArg_ParseTuple(args, "O", &py_creds))
      79           0 :                 return NULL;
      80             : 
      81       31807 :         creds = cli_credentials_from_py_object(py_creds);
      82       31807 :         if (creds == NULL) {
      83           0 :                 PyErr_SetString(PyExc_TypeError, "Expected credentials object");
      84           0 :                 return NULL;
      85             :         }
      86             : 
      87       31807 :         ldb = pyldb_Ldb_AS_LDBCONTEXT(self);
      88             : 
      89       31807 :         ldb_set_opaque(ldb, "credentials", creds);
      90             : 
      91       31807 :         Py_RETURN_NONE;
      92             : }
      93             : 
      94       35348 : static PyObject *py_ldb_set_utf8_casefold(PyObject *self,
      95             :                 PyObject *Py_UNUSED(ignored))
      96             : {
      97         450 :         struct ldb_context *ldb;
      98             : 
      99       35348 :         ldb = pyldb_Ldb_AS_LDBCONTEXT(self);
     100             : 
     101       35348 :         ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
     102             : 
     103       35348 :         Py_RETURN_NONE;
     104             : }
     105             : 
     106       24429 : static PyObject *py_ldb_set_session_info(PyObject *self, PyObject *args)
     107             : {
     108         463 :         PyObject *py_session_info;
     109         463 :         struct auth_session_info *info;
     110         463 :         struct ldb_context *ldb;
     111         463 :         PyObject *mod_samba_auth;
     112         463 :         PyObject *PyAuthSession_Type;
     113         463 :         bool ret;
     114             : 
     115       24429 :         mod_samba_auth = PyImport_ImportModule("samba.dcerpc.auth");
     116       24429 :         if (mod_samba_auth == NULL)
     117           0 :                 return NULL;
     118             : 
     119       24429 :         PyAuthSession_Type = PyObject_GetAttrString(mod_samba_auth, "session_info");
     120       24429 :         if (PyAuthSession_Type == NULL) {
     121           0 :                 Py_CLEAR(mod_samba_auth);
     122           0 :                 return NULL;
     123             :         }
     124             : 
     125       24429 :         ret = PyArg_ParseTuple(args, "O!", PyAuthSession_Type, &py_session_info);
     126             : 
     127       17878 :         Py_DECREF(PyAuthSession_Type);
     128       24429 :         Py_DECREF(mod_samba_auth);
     129             : 
     130       24429 :         if (!ret)
     131           0 :                 return NULL;
     132             : 
     133       24429 :         ldb = pyldb_Ldb_AS_LDBCONTEXT(self);
     134             : 
     135       24429 :         info = PyAuthSession_AsSession(py_session_info);
     136             : 
     137       24429 :         ldb_set_opaque(ldb, DSDB_SESSION_INFO, info);
     138             : 
     139       24429 :         Py_RETURN_NONE;
     140             : }
     141             : 
     142           4 : static PyObject *py_ldb_samba_schema_attribute_add(PyLdbObject *self,
     143             :                                                    PyObject *args)
     144             : {
     145           4 :         char *attribute, *syntax;
     146           4 :         const struct ldb_schema_syntax *s;
     147           4 :         unsigned int flags;
     148           4 :         int ret;
     149           4 :         struct ldb_context *ldb_ctx;
     150             : 
     151           4 :         if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
     152           0 :                 return NULL;
     153             : 
     154           4 :         ldb_ctx = pyldb_Ldb_AsLdbContext((PyObject *)self);
     155             : 
     156           4 :         s = ldb_samba_syntax_by_name(ldb_ctx, syntax);
     157           4 :         ret = ldb_schema_attribute_add_with_syntax(ldb_ctx, attribute,
     158             :                                                    flags, s);
     159             : 
     160           4 :         PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_error, ret, ldb_ctx);
     161             : 
     162           4 :         Py_RETURN_NONE;
     163             : }
     164             : 
     165       35348 : static PyObject *py_ldb_register_samba_handlers(PyObject *self,
     166             :                 PyObject *Py_UNUSED(ignored))
     167             : {
     168         450 :         struct ldb_context *ldb;
     169         450 :         int ret;
     170             : 
     171             :         /* XXX: Perhaps call this from PySambaLdb's init function ? */
     172             : 
     173       35348 :         ldb = pyldb_Ldb_AS_LDBCONTEXT(self);
     174       35348 :         ret = ldb_register_samba_handlers(ldb);
     175             : 
     176       35348 :         PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_error, ret, ldb);
     177             : 
     178       35348 :         Py_RETURN_NONE;
     179             : }
     180             : 
     181             : static PyMethodDef py_samba_ldb_methods[] = {
     182             :         { "set_loadparm", (PyCFunction)py_ldb_set_loadparm, METH_VARARGS, 
     183             :                 "set_loadparm(session_info)\n"
     184             :                 "Set loadparm context to use when connecting." },
     185             :         { "set_credentials", (PyCFunction)py_ldb_set_credentials, METH_VARARGS,
     186             :                 "set_credentials(credentials)\n"
     187             :                 "Set credentials to use when connecting." },
     188             :         { "set_utf8_casefold", (PyCFunction)py_ldb_set_utf8_casefold, 
     189             :                 METH_NOARGS,
     190             :                 "set_utf8_casefold()\n"
     191             :                 "Set the right Samba casefolding function for UTF8 charset." },
     192             :         { "register_samba_handlers", (PyCFunction)py_ldb_register_samba_handlers,
     193             :                 METH_NOARGS,
     194             :                 "register_samba_handlers()\n"
     195             :                 "Register Samba-specific LDB modules and schemas." },
     196             :         { "set_session_info", (PyCFunction)py_ldb_set_session_info, METH_VARARGS,
     197             :                 "set_session_info(session_info)\n"
     198             :                 "Set session info to use when connecting." },
     199             :         { "samba_schema_attribute_add",
     200             :                 (PyCFunction)py_ldb_samba_schema_attribute_add,
     201             :                 METH_VARARGS, NULL },
     202             :         {0},
     203             : };
     204             : 
     205             : static struct PyModuleDef moduledef = {
     206             :     PyModuleDef_HEAD_INIT,
     207             :     .m_name = "_ldb",
     208             :     .m_doc = "Samba-specific LDB python bindings",
     209             :     .m_size = -1,
     210             :     .m_methods = py_samba_ldb_methods,
     211             : };
     212             : 
     213             : static PyTypeObject PySambaLdb = {
     214             :         .tp_name = "samba._ldb.Ldb",
     215             :         .tp_doc = "Connection to a LDB database.",
     216             :         .tp_methods = py_samba_ldb_methods,
     217             :         .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
     218             : };
     219             : 
     220             : 
     221       12824 : MODULE_INIT_FUNC(_ldb)
     222             : {
     223         563 :         PyObject *m;
     224             : 
     225       12824 :         pyldb_module = PyImport_ImportModule("ldb");
     226       12824 :         if (pyldb_module == NULL)
     227           0 :                 return NULL;
     228             : 
     229       12824 :         PySambaLdb.tp_base = (PyTypeObject *)PyObject_GetAttrString(pyldb_module, "Ldb");
     230       12824 :         if (PySambaLdb.tp_base == NULL) {
     231           0 :                 Py_CLEAR(pyldb_module);
     232           0 :                 return NULL;
     233             :         }
     234             : 
     235       12824 :         py_ldb_error = PyObject_GetAttrString(pyldb_module, "LdbError");
     236             : 
     237       12824 :         Py_CLEAR(pyldb_module);
     238             : 
     239       12824 :         if (PyType_Ready(&PySambaLdb) < 0)
     240           0 :                 return NULL;
     241             : 
     242       12824 :         m = PyModule_Create(&moduledef);
     243       12824 :         if (m == NULL)
     244           0 :                 return NULL;
     245             : 
     246       10694 :         Py_INCREF(&PySambaLdb);
     247       12824 :         PyModule_AddObject(m, "Ldb", (PyObject *)&PySambaLdb);
     248             : 
     249             : #define ADD_LDB_STRING(val)  PyModule_AddStringConstant(m, #val, LDB_## val)
     250       12824 :         ADD_LDB_STRING(SYNTAX_SAMBA_INT32);
     251             : 
     252       12824 :         return m;
     253             : }

Generated by: LCOV version 1.14