2010-04-04 01:48:35 +02:00
/*
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/>.
*/
2010-12-12 21:40:03 +01:00
# include <Python.h>
2017-01-02 08:51:19 +01:00
# include "python/py3compat.h"
2010-12-12 18:42:58 +01:00
# include "includes.h"
2010-12-12 21:40:03 +01:00
# include <ldb.h>
# include <pyldb.h>
2010-04-04 01:48:35 +02:00
# include "param/pyparam.h"
2010-04-04 01:51:04 +02:00
# include "auth/credentials/pycredentials.h"
2010-04-04 02:01:47 +02:00
# include "ldb_wrap.h"
# include "lib/ldb-samba/ldif_handlers.h"
2010-04-04 02:20:52 +02:00
# include "auth/pyauth.h"
2018-05-31 15:12:46 +12:00
# include "source4/dsdb/common/util.h"
2019-03-11 16:39:13 +13:00
# include "lib/ldb/include/ldb_private.h"
2010-04-04 01:48:35 +02:00
2010-12-29 18:09:09 +01:00
2010-04-04 01:48:35 +02:00
static PyObject * pyldb_module ;
2010-04-04 02:07:46 +02:00
static PyObject * py_ldb_error ;
2014-12-03 13:59:58 +01:00
static PyTypeObject PySambaLdb ;
2010-04-04 01:48:35 +02:00
2010-04-04 02:07:46 +02:00
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 ) ) ) ;
}
2010-04-04 01:48:35 +02:00
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 ;
2018-04-20 16:23:42 +12:00
ldb = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2010-04-08 22:59:16 +02:00
2010-07-16 14:32:42 +10:00
lp_ctx = lpcfg_from_py_object ( ldb , py_lp_ctx ) ;
2010-04-04 01:48:35 +02:00
if ( lp_ctx = = NULL ) {
PyErr_SetString ( PyExc_TypeError , " Expected loadparm object " ) ;
return NULL ;
}
ldb_set_opaque ( ldb , " loadparm " , lp_ctx ) ;
Py_RETURN_NONE ;
}
2010-04-04 01:51:04 +02:00
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 ;
}
2018-04-20 16:23:42 +12:00
ldb = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2010-04-04 01:51:04 +02:00
ldb_set_opaque ( ldb , " credentials " , creds ) ;
Py_RETURN_NONE ;
}
2010-04-04 01:54:57 +02:00
/* 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 ;
2010-04-04 02:07:46 +02:00
int ret ;
2010-04-04 01:54:57 +02:00
TALLOC_CTX * tmp_ctx ;
if ( ! PyArg_ParseTuple ( args , " si " , & py_opaque_name , & value ) )
return NULL ;
2018-04-20 16:23:42 +12:00
ldb = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2010-04-04 01:54:57 +02:00
/* 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 ;
2010-12-29 18:56:13 +01:00
}
2010-04-04 01:54:57 +02:00
tmp_ctx = talloc_new ( ldb ) ;
if ( tmp_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2010-12-29 18:56:13 +01:00
2010-04-04 01:54:57 +02:00
new_val = talloc ( tmp_ctx , int ) ;
if ( new_val = = NULL ) {
talloc_free ( tmp_ctx ) ;
PyErr_NoMemory ( ) ;
return NULL ;
}
2010-12-29 18:56:13 +01:00
2010-04-04 01:54:57 +02:00
opaque_name_talloc = talloc_strdup ( tmp_ctx , py_opaque_name ) ;
if ( opaque_name_talloc = = NULL ) {
talloc_free ( tmp_ctx ) ;
PyErr_NoMemory ( ) ;
return NULL ;
}
2010-12-29 18:56:13 +01:00
2010-04-04 01:54:57 +02:00
* new_val = value ;
/* cache the domain_sid in the ldb */
2010-04-04 02:07:46 +02:00
ret = ldb_set_opaque ( ldb , opaque_name_talloc , new_val ) ;
2010-12-29 18:56:13 +01:00
2010-04-04 02:07:46 +02:00
if ( ret ! = LDB_SUCCESS ) {
2010-04-04 01:54:57 +02:00
talloc_free ( tmp_ctx ) ;
2010-04-04 02:07:46 +02:00
PyErr_SetLdbError ( py_ldb_error , ret , ldb ) ;
2010-04-04 01:54:57 +02:00
return NULL ;
}
talloc_steal ( ldb , new_val ) ;
talloc_steal ( ldb , opaque_name_talloc ) ;
talloc_free ( tmp_ctx ) ;
Py_RETURN_NONE ;
}
2019-05-02 19:51:34 +01:00
static PyObject * py_ldb_set_utf8_casefold ( PyObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2010-04-04 02:01:47 +02:00
{
struct ldb_context * ldb ;
2018-04-20 16:23:42 +12:00
ldb = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2010-04-04 02:01:47 +02:00
ldb_set_utf8_fns ( ldb , NULL , wrap_casefold ) ;
Py_RETURN_NONE ;
}
2010-04-04 02:20:52 +02:00
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 ;
2011-04-05 16:15:27 +10:00
mod_samba_auth = PyImport_ImportModule ( " samba.dcerpc.auth " ) ;
2010-04-04 02:20:52 +02:00
if ( mod_samba_auth = = NULL )
return NULL ;
2011-04-05 16:15:27 +10:00
PyAuthSession_Type = PyObject_GetAttrString ( mod_samba_auth , " session_info " ) ;
2019-01-23 15:15:07 +00:00
if ( PyAuthSession_Type = = NULL ) {
Py_CLEAR ( mod_samba_auth ) ;
2010-04-04 02:20:52 +02:00
return NULL ;
2019-01-23 15:15:07 +00:00
}
2010-04-04 02:20:52 +02:00
ret = PyArg_ParseTuple ( args , " O! " , PyAuthSession_Type , & py_session_info ) ;
Py_DECREF ( PyAuthSession_Type ) ;
Py_DECREF ( mod_samba_auth ) ;
if ( ! ret )
return NULL ;
2018-04-20 16:23:42 +12:00
ldb = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2010-04-04 02:20:52 +02:00
info = PyAuthSession_AsSession ( py_session_info ) ;
2018-05-31 15:12:46 +12:00
ldb_set_opaque ( ldb , DSDB_SESSION_INFO , info ) ;
2010-04-04 02:20:52 +02:00
Py_RETURN_NONE ;
}
2019-03-11 16:39:13 +13:00
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 ;
2018-04-20 16:23:42 +12:00
ldb_ctx = pyldb_Ldb_AsLdbContext ( ( PyObject * ) self ) ;
2019-03-11 16:39:13 +13:00
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 ;
}
2019-05-02 19:51:34 +01:00
static PyObject * py_ldb_register_samba_handlers ( PyObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2010-04-04 02:07:46 +02:00
{
struct ldb_context * ldb ;
int ret ;
/* XXX: Perhaps call this from PySambaLdb's init function ? */
2018-04-20 16:23:42 +12:00
ldb = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2010-04-04 02:07:46 +02:00
ret = ldb_register_samba_handlers ( ldb ) ;
PyErr_LDB_ERROR_IS_ERR_RAISE ( py_ldb_error , ret , ldb ) ;
Py_RETURN_NONE ;
}
2010-04-04 01:48:35 +02:00
static PyMethodDef py_samba_ldb_methods [ ] = {
{ " set_loadparm " , ( PyCFunction ) py_ldb_set_loadparm , METH_VARARGS ,
2010-04-04 02:07:46 +02:00
" ldb_set_loadparm(session_info) \n "
2010-04-04 01:48:35 +02:00
" Set loadparm context to use when connecting. " } ,
2010-04-04 02:01:47 +02:00
{ " set_credentials " , ( PyCFunction ) py_ldb_set_credentials , METH_VARARGS ,
2010-04-04 02:07:46 +02:00
" ldb_set_credentials(credentials) \n "
2010-04-04 01:51:04 +02:00
" Set credentials to use when connecting. " } ,
2010-04-04 01:54:57 +02:00
{ " set_opaque_integer " , ( PyCFunction ) py_ldb_set_opaque_integer ,
METH_VARARGS , NULL } ,
2010-04-04 02:01:47 +02:00
{ " set_utf8_casefold " , ( PyCFunction ) py_ldb_set_utf8_casefold ,
METH_NOARGS ,
2010-04-04 02:07:46 +02:00
" ldb_set_utf8_casefold() \n "
2010-04-04 02:01:47 +02:00
" Set the right Samba casefolding function for UTF8 charset. " } ,
2010-04-04 02:07:46 +02:00
{ " register_samba_handlers " , ( PyCFunction ) py_ldb_register_samba_handlers ,
METH_NOARGS ,
" register_samba_handlers() \n "
" Register Samba-specific LDB modules and schemas. " } ,
2010-04-04 02:20:52 +02:00
{ " set_session_info " , ( PyCFunction ) py_ldb_set_session_info , METH_VARARGS ,
" set_session_info(session_info) \n "
" Set session info to use when connecting. " } ,
2019-03-11 16:39:13 +13:00
{ " samba_schema_attribute_add " ,
( PyCFunction ) py_ldb_samba_schema_attribute_add ,
METH_VARARGS , NULL } ,
2020-05-05 13:47:39 +12:00
{ 0 } ,
2010-04-04 01:48:35 +02:00
} ;
2017-01-02 08:51:19 +01:00
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 ,
} ;
2010-04-04 01:48:35 +02:00
static PyTypeObject PySambaLdb = {
2010-12-29 18:56:13 +01:00
. tp_name = " samba._ldb.Ldb " ,
2010-04-04 01:48:35 +02:00
. tp_doc = " Connection to a LDB database. " ,
. tp_methods = py_samba_ldb_methods ,
. tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
} ;
2019-03-11 16:39:13 +13:00
2017-01-02 08:51:19 +01:00
MODULE_INIT_FUNC ( _ldb )
2010-04-04 01:48:35 +02:00
{
PyObject * m ;
pyldb_module = PyImport_ImportModule ( " ldb " ) ;
if ( pyldb_module = = NULL )
2017-01-02 08:51:19 +01:00
return NULL ;
2010-04-04 01:48:35 +02:00
PySambaLdb . tp_base = ( PyTypeObject * ) PyObject_GetAttrString ( pyldb_module , " Ldb " ) ;
2019-01-23 15:15:07 +00:00
if ( PySambaLdb . tp_base = = NULL ) {
Py_CLEAR ( pyldb_module ) ;
2017-01-02 08:51:19 +01:00
return NULL ;
2019-01-23 15:15:07 +00:00
}
2010-04-04 01:48:35 +02:00
2010-04-04 02:07:46 +02:00
py_ldb_error = PyObject_GetAttrString ( pyldb_module , " LdbError " ) ;
2019-01-23 15:15:07 +00:00
Py_CLEAR ( pyldb_module ) ;
2010-04-04 01:48:35 +02:00
if ( PyType_Ready ( & PySambaLdb ) < 0 )
2017-01-02 08:51:19 +01:00
return NULL ;
2010-04-04 01:48:35 +02:00
2017-01-02 08:51:19 +01:00
m = PyModule_Create ( & moduledef ) ;
2010-04-04 01:48:35 +02:00
if ( m = = NULL )
2017-01-02 08:51:19 +01:00
return NULL ;
2010-04-04 01:48:35 +02:00
Py_INCREF ( & PySambaLdb ) ;
PyModule_AddObject ( m , " Ldb " , ( PyObject * ) & PySambaLdb ) ;
2017-01-02 08:51:19 +01:00
2019-03-11 16:39:13 +13:00
# define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
ADD_LDB_STRING ( SYNTAX_SAMBA_INT32 ) ;
2017-01-02 08:51:19 +01:00
return m ;
2010-04-04 01:48:35 +02:00
}