1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-11 05:18:09 +03:00
samba-mirror/lib/ldb-samba/pyldb.c
Aaron Haslett 18438c8af2 ldb: tests for <= and >= integer indexing
Testing max, min and negative values for indexed 32 and 64 bit types.
This has to be done in two different files because the 64 bit type is
LDB_SYNTAX_INTEGER which is implemented at the ldb level, while the 32
bit is added in the ldb-samba module.  Schema syntax binding added for
ldb-samba.

We also need to make sure that full scans are not invoked for LMDB.

Pair-programmed-with: Garming Sam <garming@catalyst.net.nz>

Signed-off-by: Aaron Haslett <aaronhaslett@catalyst.net.nz>
Signed-off-by: Garming Sam <garming@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
2019-04-08 02:07:23 +00:00

319 lines
7.9 KiB
C

/*
Unix SMB/CIFS implementation.
Python interface to ldb, Samba-specific functions
Copyright (C) 2007-2010 Jelmer Vernooij <jelmer@samba.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include <Python.h>
#include "python/py3compat.h"
#include "includes.h"
#include <ldb.h>
#include <pyldb.h>
#include "param/pyparam.h"
#include "auth/credentials/pycredentials.h"
#include "ldb_wrap.h"
#include "lib/ldb-samba/ldif_handlers.h"
#include "auth/pyauth.h"
#include "source4/dsdb/common/util.h"
#include "lib/ldb/include/ldb_private.h"
static PyObject *pyldb_module;
static PyObject *py_ldb_error;
static PyTypeObject PySambaLdb;
static void PyErr_SetLdbError(PyObject *error, int ret, struct ldb_context *ldb_ctx)
{
if (ret == LDB_ERR_PYTHON_EXCEPTION)
return; /* Python exception should already be set, just keep that */
PyErr_SetObject(error,
Py_BuildValue(discard_const_p(char, "(i,s)"), ret,
ldb_ctx == NULL?ldb_strerror(ret):ldb_errstring(ldb_ctx)));
}
static PyObject *py_ldb_set_loadparm(PyObject *self, PyObject *args)
{
PyObject *py_lp_ctx;
struct loadparm_context *lp_ctx;
struct ldb_context *ldb;
if (!PyArg_ParseTuple(args, "O", &py_lp_ctx))
return NULL;
ldb = pyldb_Ldb_AsLdbContext(self);
lp_ctx = lpcfg_from_py_object(ldb, py_lp_ctx);
if (lp_ctx == NULL) {
PyErr_SetString(PyExc_TypeError, "Expected loadparm object");
return NULL;
}
ldb_set_opaque(ldb, "loadparm", lp_ctx);
Py_RETURN_NONE;
}
static PyObject *py_ldb_set_credentials(PyObject *self, PyObject *args)
{
PyObject *py_creds;
struct cli_credentials *creds;
struct ldb_context *ldb;
if (!PyArg_ParseTuple(args, "O", &py_creds))
return NULL;
creds = cli_credentials_from_py_object(py_creds);
if (creds == NULL) {
PyErr_SetString(PyExc_TypeError, "Expected credentials object");
return NULL;
}
ldb = pyldb_Ldb_AsLdbContext(self);
ldb_set_opaque(ldb, "credentials", creds);
Py_RETURN_NONE;
}
/* XXX: This function really should be in libldb's pyldb.c */
static PyObject *py_ldb_set_opaque_integer(PyObject *self, PyObject *args)
{
int value;
int *old_val, *new_val;
char *py_opaque_name, *opaque_name_talloc;
struct ldb_context *ldb;
int ret;
TALLOC_CTX *tmp_ctx;
if (!PyArg_ParseTuple(args, "si", &py_opaque_name, &value))
return NULL;
ldb = pyldb_Ldb_AsLdbContext(self);
/* see if we have a cached copy */
old_val = (int *)ldb_get_opaque(ldb, py_opaque_name);
/* XXX: We shouldn't just blindly assume that the value that is
* already present has the size of an int and is not shared
* with other code that may rely on it not changing.
* JRV 20100403 */
if (old_val) {
*old_val = value;
Py_RETURN_NONE;
}
tmp_ctx = talloc_new(ldb);
if (tmp_ctx == NULL) {
PyErr_NoMemory();
return NULL;
}
new_val = talloc(tmp_ctx, int);
if (new_val == NULL) {
talloc_free(tmp_ctx);
PyErr_NoMemory();
return NULL;
}
opaque_name_talloc = talloc_strdup(tmp_ctx, py_opaque_name);
if (opaque_name_talloc == NULL) {
talloc_free(tmp_ctx);
PyErr_NoMemory();
return NULL;
}
*new_val = value;
/* cache the domain_sid in the ldb */
ret = ldb_set_opaque(ldb, opaque_name_talloc, new_val);
if (ret != LDB_SUCCESS) {
talloc_free(tmp_ctx);
PyErr_SetLdbError(py_ldb_error, ret, ldb);
return NULL;
}
talloc_steal(ldb, new_val);
talloc_steal(ldb, opaque_name_talloc);
talloc_free(tmp_ctx);
Py_RETURN_NONE;
}
static PyObject *py_ldb_set_utf8_casefold(PyObject *self)
{
struct ldb_context *ldb;
ldb = pyldb_Ldb_AsLdbContext(self);
ldb_set_utf8_fns(ldb, NULL, wrap_casefold);
Py_RETURN_NONE;
}
static PyObject *py_ldb_set_session_info(PyObject *self, PyObject *args)
{
PyObject *py_session_info;
struct auth_session_info *info;
struct ldb_context *ldb;
PyObject *mod_samba_auth;
PyObject *PyAuthSession_Type;
bool ret;
mod_samba_auth = PyImport_ImportModule("samba.dcerpc.auth");
if (mod_samba_auth == NULL)
return NULL;
PyAuthSession_Type = PyObject_GetAttrString(mod_samba_auth, "session_info");
if (PyAuthSession_Type == NULL) {
Py_CLEAR(mod_samba_auth);
return NULL;
}
ret = PyArg_ParseTuple(args, "O!", PyAuthSession_Type, &py_session_info);
Py_DECREF(PyAuthSession_Type);
Py_DECREF(mod_samba_auth);
if (!ret)
return NULL;
ldb = pyldb_Ldb_AsLdbContext(self);
info = PyAuthSession_AsSession(py_session_info);
ldb_set_opaque(ldb, DSDB_SESSION_INFO, info);
Py_RETURN_NONE;
}
static PyObject *py_ldb_samba_schema_attribute_add(PyLdbObject *self,
PyObject *args)
{
char *attribute, *syntax;
const struct ldb_schema_syntax *s;
unsigned int flags;
int ret;
struct ldb_context *ldb_ctx;
if (!PyArg_ParseTuple(args, "sIs", &attribute, &flags, &syntax))
return NULL;
ldb_ctx = pyldb_Ldb_AsLdbContext(self);
s = ldb_samba_syntax_by_name(ldb_ctx, syntax);
ret = ldb_schema_attribute_add_with_syntax(ldb_ctx, attribute,
flags, s);
PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_error, ret, ldb_ctx);
Py_RETURN_NONE;
}
static PyObject *py_ldb_register_samba_handlers(PyObject *self)
{
struct ldb_context *ldb;
int ret;
/* XXX: Perhaps call this from PySambaLdb's init function ? */
ldb = pyldb_Ldb_AsLdbContext(self);
ret = ldb_register_samba_handlers(ldb);
PyErr_LDB_ERROR_IS_ERR_RAISE(py_ldb_error, ret, ldb);
Py_RETURN_NONE;
}
static PyMethodDef py_samba_ldb_methods[] = {
{ "set_loadparm", (PyCFunction)py_ldb_set_loadparm, METH_VARARGS,
"ldb_set_loadparm(session_info)\n"
"Set loadparm context to use when connecting." },
{ "set_credentials", (PyCFunction)py_ldb_set_credentials, METH_VARARGS,
"ldb_set_credentials(credentials)\n"
"Set credentials to use when connecting." },
{ "set_opaque_integer", (PyCFunction)py_ldb_set_opaque_integer,
METH_VARARGS, NULL },
{ "set_utf8_casefold", (PyCFunction)py_ldb_set_utf8_casefold,
METH_NOARGS,
"ldb_set_utf8_casefold()\n"
"Set the right Samba casefolding function for UTF8 charset." },
{ "register_samba_handlers", (PyCFunction)py_ldb_register_samba_handlers,
METH_NOARGS,
"register_samba_handlers()\n"
"Register Samba-specific LDB modules and schemas." },
{ "set_session_info", (PyCFunction)py_ldb_set_session_info, METH_VARARGS,
"set_session_info(session_info)\n"
"Set session info to use when connecting." },
{ "samba_schema_attribute_add",
(PyCFunction)py_ldb_samba_schema_attribute_add,
METH_VARARGS, NULL },
{ NULL },
};
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
.m_name = "_ldb",
.m_doc = "Samba-specific LDB python bindings",
.m_size = -1,
.m_methods = py_samba_ldb_methods,
};
static PyTypeObject PySambaLdb = {
.tp_name = "samba._ldb.Ldb",
.tp_doc = "Connection to a LDB database.",
.tp_methods = py_samba_ldb_methods,
.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
};
MODULE_INIT_FUNC(_ldb)
{
PyObject *m;
pyldb_module = PyImport_ImportModule("ldb");
if (pyldb_module == NULL)
return NULL;
PySambaLdb.tp_base = (PyTypeObject *)PyObject_GetAttrString(pyldb_module, "Ldb");
if (PySambaLdb.tp_base == NULL) {
Py_CLEAR(pyldb_module);
return NULL;
}
py_ldb_error = PyObject_GetAttrString(pyldb_module, "LdbError");
Py_CLEAR(pyldb_module);
if (PyType_Ready(&PySambaLdb) < 0)
return NULL;
m = PyModule_Create(&moduledef);
if (m == NULL)
return NULL;
Py_INCREF(&PySambaLdb);
PyModule_AddObject(m, "Ldb", (PyObject *)&PySambaLdb);
#define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
ADD_LDB_STRING(SYNTAX_SAMBA_INT32);
return m;
}