2008-12-19 04:22:07 +03:00
/*
Unix SMB / CIFS implementation .
2009-04-23 03:21:47 +04:00
Python interface to ldb .
2008-12-19 04:22:07 +03:00
Copyright ( C ) 2005 , 2006 Tim Potter < tpot @ samba . org >
Copyright ( C ) 2006 Simo Sorce < idra @ samba . org >
2010-05-07 04:15:28 +04:00
Copyright ( C ) 2007 - 2010 Jelmer Vernooij < jelmer @ samba . org >
Copyright ( C ) 2009 - 2010 Matthias Dieter Wallnöfer
2011-06-22 07:49:37 +04:00
Copyright ( C ) 2009 - 2011 Andrew Tridgell
Copyright ( C ) 2009 - 2011 Andrew Bartlett
2008-12-19 04:22:07 +03:00
2010-12-29 20:56:13 +03:00
* * NOTE ! The following LGPL license applies to the ldb
* * library . This does NOT imply that all of Samba is released
* * under the LGPL
2009-05-31 18:19:11 +04:00
2008-12-19 04:22:07 +03:00
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/>.
*/
2023-11-09 13:35:56 +03:00
# include "lib/replace/system/python.h"
2010-12-12 23:40:03 +03:00
# include "ldb_private.h"
2015-08-21 11:22:22 +03:00
# include "ldb_handlers.h"
2008-12-19 04:22:07 +03:00
# include "pyldb.h"
2016-01-22 02:06:45 +03:00
# include "dlinklist.h"
2019-05-02 21:51:05 +03:00
/* discard signature of 'func' in favour of 'target_sig' */
# define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func
2016-01-22 02:06:45 +03:00
struct py_ldb_search_iterator_reply ;
typedef struct {
PyObject_HEAD
TALLOC_CTX * mem_ctx ;
PyLdbObject * ldb ;
struct {
struct ldb_request * req ;
struct py_ldb_search_iterator_reply * next ;
struct py_ldb_search_iterator_reply * result ;
PyObject * exception ;
} state ;
} PyLdbSearchIteratorObject ;
struct py_ldb_search_iterator_reply {
struct py_ldb_search_iterator_reply * prev , * next ;
PyLdbSearchIteratorObject * py_iter ;
PyObject * obj ;
} ;
2008-12-19 04:22:07 +03:00
2010-12-29 20:09:09 +03:00
void initldb ( void ) ;
2023-11-08 00:43:38 +03:00
static PyObject * PyLdbMessage_FromMessage ( struct ldb_message * msg , PyLdbObject * pyldb ) ;
2010-12-30 21:39:14 +03:00
static PyObject * PyExc_LdbError ;
2014-12-03 15:59:58 +03:00
static PyTypeObject PyLdbControl ;
static PyTypeObject PyLdbResult ;
2016-01-22 02:06:45 +03:00
static PyTypeObject PyLdbSearchIterator ;
2014-12-03 15:59:58 +03:00
static PyTypeObject PyLdbMessage ;
2024-03-13 07:28:07 +03:00
# define pyldb_Message_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessage)
2014-12-03 15:59:58 +03:00
static PyTypeObject PyLdbDn ;
2011-08-07 19:08:56 +04:00
# define pyldb_Dn_Check(ob) PyObject_TypeCheck(ob, &PyLdbDn)
2014-12-03 15:59:58 +03:00
static PyTypeObject PyLdb ;
static PyTypeObject PyLdbMessageElement ;
2011-08-07 19:08:56 +04:00
# define pyldb_MessageElement_Check(ob) PyObject_TypeCheck(ob, &PyLdbMessageElement)
2015-03-04 00:29:09 +03:00
static PyTypeObject PyLdbTree ;
2010-12-30 21:39:14 +03:00
static struct ldb_message_element * PyObject_AsMessageElement (
TALLOC_CTX * mem_ctx ,
PyObject * set_obj ,
2011-04-10 21:48:07 +04:00
unsigned int flags ,
2010-12-30 21:39:14 +03:00
const char * attr_name ) ;
2018-05-11 15:48:29 +03:00
static PyTypeObject PyLdbBytesType ;
2010-12-29 20:09:09 +03:00
2018-11-12 19:06:10 +03:00
# define PYARG_STR_UNI "es"
2018-05-11 15:48:29 +03:00
static PyObject * PyLdbBytes_FromStringAndSize ( const char * msg , int size )
{
PyObject * result = NULL ;
PyObject * args = NULL ;
args = Py_BuildValue ( " (y#) " , msg , size ) ;
2023-08-25 05:20:50 +03:00
if ( args = = NULL ) {
return NULL ;
}
2018-05-11 15:48:29 +03:00
result = PyLdbBytesType . tp_new ( & PyLdbBytesType , args , NULL ) ;
Py_DECREF ( args ) ;
return result ;
}
2008-12-23 13:25:06 +03:00
2015-06-09 11:36:26 +03:00
static PyObject * richcmp ( int cmp_val , int op )
{
int ret ;
switch ( op ) {
case Py_LT : ret = cmp_val < 0 ; break ;
case Py_LE : ret = cmp_val < = 0 ; break ;
case Py_EQ : ret = cmp_val = = 0 ; break ;
case Py_NE : ret = cmp_val ! = 0 ; break ;
case Py_GT : ret = cmp_val > 0 ; break ;
case Py_GE : ret = cmp_val > = 0 ; break ;
default :
Py_INCREF ( Py_NotImplemented ) ;
return Py_NotImplemented ;
}
return PyBool_FromLong ( ret ) ;
}
2011-02-07 09:50:36 +03:00
static PyObject * py_ldb_control_str ( PyLdbControlObject * self )
{
if ( self - > data ! = NULL ) {
char * control = ldb_control_to_string ( self - > mem_ctx , self - > data ) ;
if ( control = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2019-06-07 11:45:52 +03:00
return PyUnicode_FromString ( control ) ;
2011-02-07 09:50:36 +03:00
} else {
2019-06-07 11:45:52 +03:00
return PyUnicode_FromString ( " ldb control " ) ;
2011-02-07 09:50:36 +03:00
}
}
static void py_ldb_control_dealloc ( PyLdbControlObject * self )
{
if ( self - > mem_ctx ! = NULL ) {
talloc_free ( self - > mem_ctx ) ;
}
2011-02-26 21:35:27 +03:00
self - > data = NULL ;
2015-03-04 00:29:07 +03:00
Py_TYPE ( self ) - > tp_free ( self ) ;
2011-02-07 09:50:36 +03:00
}
2015-06-09 18:44:40 +03:00
/* Create a text (rather than bytes) interface for a LDB result object */
static PyObject * wrap_text ( const char * type , PyObject * wrapped )
{
PyObject * mod , * cls , * constructor , * inst ;
mod = PyImport_ImportModule ( " _ldb_text " ) ;
if ( mod = = NULL )
return NULL ;
cls = PyObject_GetAttrString ( mod , type ) ;
Py_DECREF ( mod ) ;
if ( cls = = NULL ) {
Py_DECREF ( mod ) ;
return NULL ;
}
constructor = PyObject_GetAttrString ( cls , " _wrap " ) ;
Py_DECREF ( cls ) ;
if ( constructor = = NULL ) {
return NULL ;
}
inst = PyObject_CallFunction ( constructor , discard_const_p ( char , " O " ) , wrapped ) ;
Py_DECREF ( constructor ) ;
return inst ;
}
2019-05-02 21:51:05 +03:00
static PyObject * py_ldb_control_get_oid ( PyLdbControlObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2011-02-07 09:50:36 +03:00
{
2019-06-07 11:45:52 +03:00
return PyUnicode_FromString ( self - > data - > oid ) ;
2011-02-07 09:50:36 +03:00
}
2019-05-02 21:51:05 +03:00
static PyObject * py_ldb_control_get_critical ( PyLdbControlObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2011-02-07 09:50:36 +03:00
{
return PyBool_FromLong ( self - > data - > critical ) ;
}
2019-05-15 12:30:29 +03:00
static int py_ldb_control_set_critical ( PyLdbControlObject * self , PyObject * value , void * closure )
2011-02-07 09:50:36 +03:00
{
2021-09-25 02:16:09 +03:00
if ( value = = NULL ) {
PyErr_SetString ( PyExc_AttributeError , " cannot delete critical flag " ) ;
return - 1 ;
}
2011-02-07 09:50:36 +03:00
if ( PyObject_IsTrue ( value ) ) {
self - > data - > critical = true ;
} else {
self - > data - > critical = false ;
}
return 0 ;
}
static PyObject * py_ldb_control_new ( PyTypeObject * type , PyObject * args , PyObject * kwargs )
{
char * data = NULL ;
const char * const kwnames [ ] = { " ldb " , " data " , NULL } ;
struct ldb_control * parsed_controls ;
PyLdbControlObject * ret ;
PyObject * py_ldb ;
TALLOC_CTX * mem_ctx ;
struct ldb_context * ldb_ctx ;
2015-03-04 00:29:11 +03:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " O!s " ,
2011-02-07 09:50:36 +03:00
discard_const_p ( char * , kwnames ) ,
2015-03-04 00:29:11 +03:00
& PyLdb , & py_ldb , & data ) )
2011-02-07 09:50:36 +03:00
return NULL ;
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2018-04-20 07:23:42 +03:00
ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT ( py_ldb ) ;
2011-02-07 09:50:36 +03:00
parsed_controls = ldb_parse_control_from_string ( ldb_ctx , mem_ctx , data ) ;
if ( ! parsed_controls ) {
talloc_free ( mem_ctx ) ;
PyErr_SetString ( PyExc_ValueError , " unable to parse control string " ) ;
return NULL ;
}
ret = PyObject_New ( PyLdbControlObject , type ) ;
if ( ret = = NULL ) {
PyErr_NoMemory ( ) ;
talloc_free ( mem_ctx ) ;
return NULL ;
}
ret - > mem_ctx = mem_ctx ;
2011-02-26 21:35:27 +03:00
ret - > data = talloc_move ( mem_ctx , & parsed_controls ) ;
2011-02-07 09:50:36 +03:00
if ( ret - > data = = NULL ) {
Py_DECREF ( ret ) ;
PyErr_NoMemory ( ) ;
talloc_free ( mem_ctx ) ;
return NULL ;
}
return ( PyObject * ) ret ;
}
static PyGetSetDef py_ldb_control_getset [ ] = {
2018-12-13 13:34:37 +03:00
{
. name = discard_const_p ( char , " oid " ) ,
. get = ( getter ) py_ldb_control_get_oid ,
} ,
{
. name = discard_const_p ( char , " critical " ) ,
. get = ( getter ) py_ldb_control_get_critical ,
. set = ( setter ) py_ldb_control_set_critical ,
} ,
{ . name = NULL } ,
2011-02-07 09:50:36 +03:00
} ;
static PyTypeObject PyLdbControl = {
. tp_name = " ldb.control " ,
. tp_dealloc = ( destructor ) py_ldb_control_dealloc ,
. tp_getattro = PyObject_GenericGetAttr ,
. tp_basicsize = sizeof ( PyLdbControlObject ) ,
. tp_getset = py_ldb_control_getset ,
. tp_doc = " LDB control. " ,
. tp_str = ( reprfunc ) py_ldb_control_str ,
. tp_new = py_ldb_control_new ,
. tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
} ;
2018-05-11 15:48:29 +03:00
static PyObject * py_ldb_bytes_str ( PyBytesObject * self )
{
char * msg = NULL ;
Py_ssize_t size ;
int result = 0 ;
if ( ! PyBytes_Check ( self ) ) {
PyErr_Format ( PyExc_TypeError , " Unexpected type " ) ;
return NULL ;
}
result = PyBytes_AsStringAndSize ( ( PyObject * ) self , & msg , & size ) ;
if ( result ! = 0 ) {
PyErr_Format ( PyExc_TypeError , " Failed to extract bytes " ) ;
return NULL ;
}
return PyUnicode_FromStringAndSize ( msg , size ) ;
}
static PyTypeObject PyLdbBytesType = {
PyVarObject_HEAD_INIT ( NULL , 0 )
. tp_name = " ldb.bytes " ,
. tp_doc = " str/bytes (with custom str) " ,
. tp_str = ( reprfunc ) py_ldb_bytes_str ,
. tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
} ;
2009-07-18 18:11:21 +04:00
2014-04-29 11:32:45 +04:00
static PyObject * PyObject_FromLdbValue ( const struct ldb_val * val )
2008-12-19 04:22:07 +03:00
{
2018-05-11 15:48:29 +03:00
return PyLdbBytes_FromStringAndSize ( ( const char * ) val - > data , val - > length ) ;
2008-12-19 04:22:07 +03:00
}
2015-08-21 11:10:28 +03:00
static PyObject * PyStr_FromLdbValue ( const struct ldb_val * val )
{
2019-06-07 12:01:19 +03:00
return PyUnicode_FromStringAndSize ( ( const char * ) val - > data , val - > length ) ;
2015-08-21 11:10:28 +03:00
}
2011-02-07 09:50:36 +03:00
/**
* Create a Python object from a ldb_result .
*
* @ param result LDB result to convert
* @ return Python object with converted result ( a list object )
*/
static PyObject * PyLdbControl_FromControl ( struct ldb_control * control )
{
TALLOC_CTX * ctl_ctx = talloc_new ( NULL ) ;
PyLdbControlObject * ctrl ;
if ( ctl_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
ctrl = ( PyLdbControlObject * ) PyLdbControl . tp_alloc ( & PyLdbControl , 0 ) ;
if ( ctrl = = NULL ) {
2011-02-26 21:35:27 +03:00
talloc_free ( ctl_ctx ) ;
2011-02-07 09:50:36 +03:00
PyErr_NoMemory ( ) ;
return NULL ;
}
ctrl - > mem_ctx = ctl_ctx ;
ctrl - > data = talloc_steal ( ctrl - > mem_ctx , control ) ;
if ( ctrl - > data = = NULL ) {
Py_DECREF ( ctrl ) ;
PyErr_NoMemory ( ) ;
return NULL ;
}
return ( PyObject * ) ctrl ;
}
2009-03-21 00:52:57 +03:00
/**
* Create a Python object from a ldb_result .
*
* @ param result LDB result to convert
* @ return Python object with converted result ( a list object )
*/
2023-11-08 00:43:38 +03:00
static PyObject * PyLdbResult_FromResult ( struct ldb_result * result , PyLdbObject * pyldb )
2008-12-19 04:22:07 +03:00
{
2011-02-07 09:50:36 +03:00
PyLdbResultObject * ret ;
PyObject * list , * controls , * referals ;
2010-11-06 19:48:39 +03:00
Py_ssize_t i ;
2011-02-07 09:50:36 +03:00
2008-12-21 00:21:39 +03:00
if ( result = = NULL ) {
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2011-02-07 09:50:36 +03:00
}
ret = ( PyLdbResultObject * ) PyLdbResult . tp_alloc ( & PyLdbResult , 0 ) ;
if ( ret = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2023-11-08 00:43:38 +03:00
ret - > pyldb = pyldb ;
Py_INCREF ( ret - > pyldb ) ;
2011-02-07 09:50:36 +03:00
list = PyList_New ( result - > count ) ;
if ( list = = NULL ) {
PyErr_NoMemory ( ) ;
Py_DECREF ( ret ) ;
return NULL ;
}
2008-12-19 04:22:07 +03:00
for ( i = 0 ; i < result - > count ; i + + ) {
2023-11-08 00:43:38 +03:00
PyObject * pymessage = PyLdbMessage_FromMessage ( result - > msgs [ i ] , pyldb ) ;
2023-11-22 05:01:47 +03:00
if ( pymessage = = NULL ) {
Py_DECREF ( ret ) ;
Py_DECREF ( list ) ;
return NULL ;
}
PyList_SetItem ( list , i , pymessage ) ;
2008-12-19 04:22:07 +03:00
}
2011-02-07 09:50:36 +03:00
ret - > mem_ctx = talloc_new ( NULL ) ;
if ( ret - > mem_ctx = = NULL ) {
Py_DECREF ( list ) ;
Py_DECREF ( ret ) ;
PyErr_NoMemory ( ) ;
return NULL ;
}
ret - > msgs = list ;
if ( result - > controls ) {
2015-03-04 00:29:08 +03:00
i = 0 ;
while ( result - > controls [ i ] ) {
i + + ;
}
controls = PyList_New ( i ) ;
2011-02-07 09:50:36 +03:00
if ( controls = = NULL ) {
Py_DECREF ( ret ) ;
2024-01-31 07:26:45 +03:00
Py_DECREF ( list ) ;
2011-02-07 09:50:36 +03:00
PyErr_NoMemory ( ) ;
return NULL ;
}
for ( i = 0 ; result - > controls [ i ] ; i + + ) {
PyObject * ctrl = ( PyObject * ) PyLdbControl_FromControl ( result - > controls [ i ] ) ;
if ( ctrl = = NULL ) {
Py_DECREF ( ret ) ;
2024-01-31 07:26:45 +03:00
Py_DECREF ( list ) ;
2011-02-07 09:50:36 +03:00
Py_DECREF ( controls ) ;
PyErr_NoMemory ( ) ;
return NULL ;
}
PyList_SetItem ( controls , i , ctrl ) ;
}
} else {
/*
* No controls so we keep an empty list
*/
controls = PyList_New ( 0 ) ;
if ( controls = = NULL ) {
Py_DECREF ( ret ) ;
2024-01-31 07:26:45 +03:00
Py_DECREF ( list ) ;
2011-02-07 09:50:36 +03:00
PyErr_NoMemory ( ) ;
return NULL ;
}
}
ret - > controls = controls ;
i = 0 ;
while ( result - > refs & & result - > refs [ i ] ) {
i + + ;
}
referals = PyList_New ( i ) ;
if ( referals = = NULL ) {
Py_DECREF ( ret ) ;
2024-01-31 07:26:45 +03:00
Py_DECREF ( list ) ;
2011-02-07 09:50:36 +03:00
PyErr_NoMemory ( ) ;
return NULL ;
}
for ( i = 0 ; result - > refs & & result - > refs [ i ] ; i + + ) {
2019-06-07 11:45:52 +03:00
PyList_SetItem ( referals , i , PyUnicode_FromString ( result - > refs [ i ] ) ) ;
2011-02-07 09:50:36 +03:00
}
ret - > referals = referals ;
return ( PyObject * ) ret ;
2008-12-19 04:22:07 +03:00
}
2024-03-13 07:28:57 +03:00
/*
* PyErr_interal_LDB_DN_OR_RAISE does exactly what
* PyErr__LDB_DN_OR_RAISE does , but rather than going through the
* Python layer to import the Dn object , it directly uses the the
* address of the PyTypeObject . This is faster , but can only be done
* in pyldb . c .
*/
# define PyErr_internal_LDB_DN_OR_RAISE(_py_obj, dn) do { \
PyLdbDnObject * _py_dn = NULL ; \
if ( _py_obj = = NULL | | ! pyldb_Dn_Check ( _py_obj ) ) { \
PyErr_SetString ( PyExc_TypeError , " ldb Dn object required " ) ; \
return NULL ; \
} \
_py_dn = ( PyLdbDnObject * ) _py_obj ; \
dn = pyldb_Dn_AS_DN ( _py_dn ) ; \
if ( _py_dn - > pyldb - > ldb_ctx ! = ldb_dn_get_ldb_context ( dn ) ) { \
PyErr_SetString ( PyExc_RuntimeError , \
" Dn has a stale LDB connection " ) ; \
return NULL ; \
} \
} while ( 0 )
2024-03-14 06:38:14 +03:00
static PyObject * py_ldb_dn_validate ( PyObject * self ,
2019-05-02 21:51:05 +03:00
PyObject * Py_UNUSED ( ignored ) )
2008-12-19 04:22:07 +03:00
{
2024-03-14 06:38:14 +03:00
struct ldb_dn * dn = NULL ;
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
2024-03-14 06:38:14 +03:00
return PyBool_FromLong ( ldb_dn_validate ( dn ) ) ;
2008-12-19 04:22:07 +03:00
}
2019-05-02 21:51:05 +03:00
static PyObject * py_ldb_dn_is_valid ( PyLdbDnObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2008-12-19 04:22:07 +03:00
{
2008-12-23 07:07:29 +03:00
return PyBool_FromLong ( ldb_dn_is_valid ( self - > dn ) ) ;
2008-12-19 04:22:07 +03:00
}
2019-05-02 21:51:05 +03:00
static PyObject * py_ldb_dn_is_special ( PyLdbDnObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2008-12-19 04:22:07 +03:00
{
2008-12-23 07:07:29 +03:00
return PyBool_FromLong ( ldb_dn_is_special ( self - > dn ) ) ;
2008-12-19 04:22:07 +03:00
}
2024-03-14 06:38:14 +03:00
static PyObject * py_ldb_dn_is_null ( PyObject * self ,
2019-05-02 21:51:05 +03:00
PyObject * Py_UNUSED ( ignored ) )
2008-12-19 04:22:07 +03:00
{
2024-03-14 06:38:14 +03:00
struct ldb_dn * dn = NULL ;
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
2024-03-14 06:38:14 +03:00
return PyBool_FromLong ( ldb_dn_is_null ( dn ) ) ;
2008-12-19 04:22:07 +03:00
}
2024-02-29 03:07:47 +03:00
2024-04-10 05:40:42 +03:00
static PyObject * py_ldb_dn_get_casefold ( PyObject * self ,
2019-05-02 21:51:05 +03:00
PyObject * Py_UNUSED ( ignored ) )
2008-12-19 04:22:07 +03:00
{
2024-04-10 05:40:42 +03:00
const char * s = NULL ;
struct ldb_dn * dn = NULL ;
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
2024-04-10 05:40:42 +03:00
s = ldb_dn_get_casefold ( dn ) ;
2024-03-08 01:02:23 +03:00
if ( s = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
return PyUnicode_FromString ( s ) ;
2008-12-19 04:22:07 +03:00
}
2024-03-14 06:38:14 +03:00
static PyObject * py_ldb_dn_get_linearized ( PyObject * self ,
2023-08-01 00:26:27 +03:00
PyObject * Py_UNUSED ( ignored ) )
2008-12-19 04:22:07 +03:00
{
2024-03-14 06:38:14 +03:00
struct ldb_dn * dn = NULL ;
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
2024-03-14 06:38:14 +03:00
return PyUnicode_FromString ( ldb_dn_get_linearized ( dn ) ) ;
2008-12-19 04:22:07 +03:00
}
2024-03-14 06:38:14 +03:00
static PyObject * py_ldb_dn_canonical_str ( PyObject * self ,
2019-05-02 21:51:05 +03:00
PyObject * Py_UNUSED ( ignored ) )
2008-12-19 04:22:07 +03:00
{
2024-03-14 06:38:14 +03:00
struct ldb_dn * dn = NULL ;
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
2024-03-14 06:38:14 +03:00
return PyUnicode_FromString ( ldb_dn_canonical_string ( dn , dn ) ) ;
2008-12-19 04:22:07 +03:00
}
2024-03-14 06:38:14 +03:00
static PyObject * py_ldb_dn_canonical_ex_str ( PyObject * self ,
2019-05-02 21:51:05 +03:00
PyObject * Py_UNUSED ( ignored ) )
2008-12-19 04:22:07 +03:00
{
2024-03-14 06:38:14 +03:00
struct ldb_dn * dn = NULL ;
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
2024-03-14 06:38:14 +03:00
return PyUnicode_FromString ( ldb_dn_canonical_ex_string ( dn , dn ) ) ;
2008-12-19 04:22:07 +03:00
}
2024-03-14 07:07:52 +03:00
static PyObject * py_ldb_dn_extended_str ( PyObject * self , PyObject * args , PyObject * kwargs )
2011-06-22 07:49:37 +04:00
{
const char * const kwnames [ ] = { " mode " , NULL } ;
int mode = 1 ;
2024-03-14 07:07:52 +03:00
struct ldb_dn * dn = NULL ;
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
2011-06-22 07:49:37 +04:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " |i " ,
discard_const_p ( char * , kwnames ) ,
2024-03-14 07:32:51 +03:00
& mode ) ) {
2011-06-22 07:49:37 +04:00
return NULL ;
2024-03-14 07:32:51 +03:00
}
2024-03-14 07:07:52 +03:00
return PyUnicode_FromString ( ldb_dn_get_extended_linearized ( dn , dn , mode ) ) ;
2011-06-22 07:49:37 +04:00
}
2024-03-14 07:10:17 +03:00
static PyObject * py_ldb_dn_get_extended_component ( PyObject * self , PyObject * args )
2011-06-22 08:44:12 +04:00
{
char * name ;
2024-03-14 07:10:17 +03:00
const struct ldb_val * val = NULL ;
struct ldb_dn * dn = NULL ;
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
2011-06-22 08:44:12 +04:00
2024-03-14 07:32:51 +03:00
if ( ! PyArg_ParseTuple ( args , " s " , & name ) ) {
2011-06-22 08:44:12 +04:00
return NULL ;
2024-03-14 07:32:51 +03:00
}
2024-03-14 07:10:17 +03:00
val = ldb_dn_get_extended_component ( dn , name ) ;
2011-06-22 08:44:12 +04:00
if ( val = = NULL ) {
Py_RETURN_NONE ;
}
2015-06-09 18:44:40 +03:00
return PyBytes_FromStringAndSize ( ( const char * ) val - > data , val - > length ) ;
2011-06-22 08:44:12 +04:00
}
2024-03-15 01:00:50 +03:00
static PyObject * py_ldb_dn_set_extended_component ( PyObject * self , PyObject * args )
2011-06-22 08:44:12 +04:00
{
char * name ;
2015-08-21 11:10:28 +03:00
int err ;
2017-11-19 10:19:03 +03:00
uint8_t * value = NULL ;
2016-01-04 02:42:06 +03:00
Py_ssize_t size = 0 ;
2024-03-15 01:00:50 +03:00
struct ldb_dn * dn = NULL ;
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
2011-06-22 08:44:12 +04:00
2017-11-19 10:19:03 +03:00
if ( ! PyArg_ParseTuple ( args , " sz# " , & name , ( char * * ) & value , & size ) )
2011-06-22 08:44:12 +04:00
return NULL ;
2015-08-21 11:10:28 +03:00
if ( value = = NULL ) {
2024-03-15 01:00:50 +03:00
err = ldb_dn_set_extended_component ( dn , name , NULL ) ;
2011-06-22 08:44:12 +04:00
} else {
struct ldb_val val ;
2015-08-21 11:10:28 +03:00
val . data = ( uint8_t * ) value ;
2015-06-09 18:44:40 +03:00
val . length = size ;
2024-03-15 01:00:50 +03:00
err = ldb_dn_set_extended_component ( dn , name , & val ) ;
2011-06-22 08:44:12 +04:00
}
if ( err ! = LDB_SUCCESS ) {
PyErr_SetString ( PyExc_TypeError , " Failed to set extended component " ) ;
return NULL ;
}
Py_RETURN_NONE ;
}
2008-12-19 04:22:07 +03:00
static PyObject * py_ldb_dn_repr ( PyLdbDnObject * self )
{
2019-06-07 11:45:52 +03:00
PyObject * str = PyUnicode_FromString ( ldb_dn_get_linearized ( self - > dn ) ) ;
2015-06-09 18:44:40 +03:00
PyObject * repr , * result ;
if ( str = = NULL )
return NULL ;
repr = PyObject_Repr ( str ) ;
if ( repr = = NULL ) {
Py_DECREF ( str ) ;
return NULL ;
}
2019-06-07 12:21:15 +03:00
result = PyUnicode_FromFormat ( " Dn(%s) " , PyUnicode_AsUTF8 ( repr ) ) ;
2015-06-09 18:44:40 +03:00
Py_DECREF ( str ) ;
Py_DECREF ( repr ) ;
return result ;
2008-12-19 04:22:07 +03:00
}
static PyObject * py_ldb_dn_check_special ( PyLdbDnObject * self , PyObject * args )
{
char * name ;
if ( ! PyArg_ParseTuple ( args , " s " , & name ) )
return NULL ;
2015-03-04 00:29:06 +03:00
return PyBool_FromLong ( ldb_dn_check_special ( self - > dn , name ) ) ;
2008-12-19 04:22:07 +03:00
}
2008-12-19 19:08:35 +03:00
2024-03-14 07:19:21 +03:00
static PyObject * py_ldb_dn_richcmp ( PyObject * pydn1 , PyObject * pydn2 , int op )
2008-12-19 04:22:07 +03:00
{
2009-08-21 11:50:04 +04:00
int ret ;
2024-03-14 07:19:21 +03:00
struct ldb_dn * dn1 = NULL ;
struct ldb_dn * dn2 = NULL ;
if ( ! pyldb_Dn_Check ( pydn2 ) ) {
2015-06-09 11:36:26 +03:00
Py_INCREF ( Py_NotImplemented ) ;
return Py_NotImplemented ;
}
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( pydn1 , dn1 ) ;
PyErr_internal_LDB_DN_OR_RAISE ( pydn2 , dn2 ) ;
2024-03-14 07:19:21 +03:00
ret = ldb_dn_compare ( dn1 , dn2 ) ;
2015-06-09 11:36:26 +03:00
return richcmp ( ret , op ) ;
2008-12-19 04:22:07 +03:00
}
2024-03-14 07:21:34 +03:00
static PyObject * py_ldb_dn_get_parent ( PyObject * self ,
2019-05-02 21:51:05 +03:00
PyObject * Py_UNUSED ( ignored ) )
2008-12-19 16:41:44 +03:00
{
2024-03-14 07:21:34 +03:00
struct ldb_dn * dn = NULL ;
2009-06-17 20:25:21 +04:00
struct ldb_dn * parent ;
2024-03-14 07:21:34 +03:00
PyLdbDnObject * py_ret = NULL ;
PyLdbDnObject * dn_self = NULL ;
2023-06-06 04:56:32 +03:00
TALLOC_CTX * mem_ctx = NULL ;
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
2024-03-14 07:21:34 +03:00
2023-06-06 04:56:32 +03:00
if ( ldb_dn_get_comp_num ( dn ) < 1 ) {
Py_RETURN_NONE ;
}
mem_ctx = talloc_new ( NULL ) ;
2023-06-15 01:07:56 +03:00
if ( mem_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2009-06-17 20:25:21 +04:00
2009-06-17 22:32:35 +04:00
parent = ldb_dn_get_parent ( mem_ctx , dn ) ;
if ( parent = = NULL ) {
2023-06-06 04:56:32 +03:00
PyErr_NoMemory ( ) ;
2009-06-17 22:32:35 +04:00
talloc_free ( mem_ctx ) ;
2023-06-06 04:56:32 +03:00
return NULL ;
2009-06-17 22:32:35 +04:00
}
2009-06-17 20:25:21 +04:00
2009-06-17 22:32:35 +04:00
py_ret = ( PyLdbDnObject * ) PyLdbDn . tp_alloc ( & PyLdbDn , 0 ) ;
if ( py_ret = = NULL ) {
PyErr_NoMemory ( ) ;
talloc_free ( mem_ctx ) ;
return NULL ;
}
2024-03-14 07:21:34 +03:00
dn_self = ( PyLdbDnObject * ) self ;
2009-06-17 22:32:35 +04:00
py_ret - > mem_ctx = mem_ctx ;
py_ret - > dn = parent ;
2024-03-14 07:21:34 +03:00
py_ret - > pyldb = dn_self - > pyldb ;
2023-11-08 00:43:38 +03:00
Py_INCREF ( py_ret - > pyldb ) ;
2009-06-17 22:32:35 +04:00
return ( PyObject * ) py_ret ;
2008-12-19 16:41:44 +03:00
}
2024-04-10 05:41:09 +03:00
static PyObject * py_ldb_dn_add_child ( PyObject * self , PyObject * args )
2008-12-19 16:41:44 +03:00
{
2024-04-10 05:41:09 +03:00
PyObject * py_other = NULL ;
struct ldb_dn * dn = NULL ;
struct ldb_dn * other = NULL ;
2024-03-15 02:11:18 +03:00
TALLOC_CTX * tmp_ctx = NULL ;
2022-09-30 01:46:40 +03:00
bool ok ;
2024-04-10 05:41:09 +03:00
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
2024-04-10 05:41:09 +03:00
2024-03-15 02:11:18 +03:00
if ( ! PyArg_ParseTuple ( args , " O " , & py_other ) ) {
2008-12-19 16:41:44 +03:00
return NULL ;
2024-03-15 02:11:18 +03:00
}
/*
* pyldb_Object_AsDn only uses tmp_ctx if py_other is str / bytes , in
* which case it allocates a struct ldb_dn . If py_other is a PyLdbDn ,
* tmp_ctx is unused and the underlying dn is borrowed .
*
* The pieces of other are reassembled onto dn using dn itself as a
* talloc context ( ldb_dn_add_child assumes all dns are talloc
* contexts ) , after which we don ' t need any temporary DN we made .
*/
tmp_ctx = talloc_new ( NULL ) ;
if ( tmp_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2008-12-19 16:41:44 +03:00
2024-03-15 02:11:18 +03:00
ok = pyldb_Object_AsDn ( tmp_ctx ,
py_other ,
ldb_dn_get_ldb_context ( dn ) ,
& other ) ;
if ( ! ok ) {
TALLOC_FREE ( tmp_ctx ) ;
2008-12-19 19:08:35 +03:00
return NULL ;
2024-03-15 02:11:18 +03:00
}
2008-12-19 16:41:44 +03:00
2022-09-30 01:46:40 +03:00
ok = ldb_dn_add_child ( dn , other ) ;
2024-03-15 02:11:18 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-09-30 01:46:40 +03:00
if ( ! ok ) {
PyErr_SetLdbError ( PyExc_LdbError , LDB_ERR_OPERATIONS_ERROR , NULL ) ;
return NULL ;
}
Py_RETURN_TRUE ;
2008-12-19 16:41:44 +03:00
}
2024-03-14 07:24:48 +03:00
static PyObject * py_ldb_dn_add_base ( PyObject * self , PyObject * args )
2008-12-19 16:41:44 +03:00
{
2024-03-15 02:38:00 +03:00
PyObject * py_other = NULL ;
2024-03-14 07:24:48 +03:00
struct ldb_dn * other = NULL ;
struct ldb_dn * dn = NULL ;
2024-03-15 02:38:00 +03:00
TALLOC_CTX * tmp_ctx = NULL ;
2022-09-30 01:46:40 +03:00
bool ok ;
2024-03-14 07:24:48 +03:00
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
2024-03-14 07:24:48 +03:00
2024-03-15 02:38:00 +03:00
if ( ! PyArg_ParseTuple ( args , " O " , & py_other ) ) {
2008-12-19 16:41:44 +03:00
return NULL ;
2024-03-15 02:38:00 +03:00
}
2008-12-19 16:41:44 +03:00
2024-03-15 02:38:00 +03:00
/*
* As noted in py_ldb_dn_add_child ( ) comments , if py_other is a
* string , other is an ephemeral struct ldb_dn , but if py_other is a
* python DN , other points to the corresponding long - lived DN .
*/
tmp_ctx = talloc_new ( NULL ) ;
if ( tmp_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
ok = pyldb_Object_AsDn ( tmp_ctx ,
py_other ,
ldb_dn_get_ldb_context ( dn ) ,
& other ) ;
if ( ! ok ) {
TALLOC_FREE ( tmp_ctx ) ;
2008-12-19 19:08:35 +03:00
return NULL ;
2024-03-15 02:38:00 +03:00
}
2008-12-19 19:08:35 +03:00
2022-09-30 01:46:40 +03:00
ok = ldb_dn_add_base ( dn , other ) ;
2024-03-15 02:38:00 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2022-09-30 01:46:40 +03:00
if ( ! ok ) {
PyErr_SetLdbError ( PyExc_LdbError , LDB_ERR_OPERATIONS_ERROR , NULL ) ;
return NULL ;
}
Py_RETURN_TRUE ;
2008-12-19 16:41:44 +03:00
}
2024-03-17 07:56:09 +03:00
static PyObject * py_ldb_dn_copy ( struct ldb_dn * dn , PyLdbObject * pyldb ) ;
static PyObject * py_ldb_dn_copy_method ( PyObject * self , PyObject * args )
{
struct ldb_dn * dn = NULL ;
PyLdbObject * pyldb = NULL ;
PyObject * obj = Py_None ;
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
if ( ! PyArg_ParseTuple ( args , " |O " , & obj ) ) {
return NULL ;
}
if ( obj = = Py_None ) {
/*
* With no argument , or None , dn . copy ( ) uses its own ldb .
*
* There is not much reason to do this , other than as a
* convenience in this situation :
*
* > > > msg . dn = dn . copy ( msg . ldb )
*
* when you don ' t know whether msg has a dn or not ( if msg . ldb
* is None , msg will now belong to this dn ' s ldb ) .
*/
pyldb = ( ( PyLdbDnObject * ) self ) - > pyldb ;
} else if ( PyObject_TypeCheck ( obj , & PyLdb ) ) {
pyldb = ( PyLdbObject * ) obj ;
} else {
PyErr_Format ( PyExc_TypeError ,
" Expected Ldb or None " ) ;
return NULL ;
}
if ( pyldb ! = ( ( PyLdbDnObject * ) self ) - > pyldb ) {
/*
* This is unfortunate , but we can ' t make a copy of the dn directly ,
* since the opaque struct ldb_dn has a pointer to the ldb it knows ,
* and it is the WRONG ONE .
*
* Instead we go via string serialisation .
*/
char * dn_str = NULL ;
struct ldb_dn * new_dn = NULL ;
dn_str = ldb_dn_get_extended_linearized ( pyldb - > mem_ctx , dn , 1 ) ;
if ( dn_str = = NULL ) {
PyErr_Format ( PyExc_RuntimeError ,
" Could not linearize DN " ) ;
return NULL ;
}
new_dn = ldb_dn_new ( pyldb - > mem_ctx ,
pyldb - > ldb_ctx ,
dn_str ) ;
if ( new_dn = = NULL ) {
PyErr_Format ( PyExc_RuntimeError ,
" Could not re-parse DN '%s' " ,
dn_str ) ;
TALLOC_FREE ( dn_str ) ;
return NULL ;
}
TALLOC_FREE ( dn_str ) ;
dn = new_dn ;
}
return py_ldb_dn_copy ( dn , pyldb ) ;
}
2024-03-14 06:38:14 +03:00
static PyObject * py_ldb_dn_remove_base_components ( PyObject * self , PyObject * args )
2012-07-06 13:57:10 +04:00
{
2024-03-14 06:38:14 +03:00
struct ldb_dn * dn = NULL ;
2012-07-06 13:57:10 +04:00
int i ;
2022-09-30 01:46:40 +03:00
bool ok ;
2024-03-14 07:32:51 +03:00
if ( ! PyArg_ParseTuple ( args , " i " , & i ) ) {
2012-07-06 13:57:10 +04:00
return NULL ;
2024-03-14 07:32:51 +03:00
}
2012-07-06 13:57:10 +04:00
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
2012-07-06 13:57:10 +04:00
2022-09-30 01:46:40 +03:00
ok = ldb_dn_remove_base_components ( dn , i ) ;
if ( ! ok ) {
PyErr_SetLdbError ( PyExc_LdbError , LDB_ERR_OPERATIONS_ERROR , NULL ) ;
return NULL ;
}
Py_RETURN_TRUE ;
2012-07-06 13:57:10 +04:00
}
2024-03-14 06:38:14 +03:00
static PyObject * py_ldb_dn_is_child_of ( PyObject * self , PyObject * args )
2011-05-24 01:30:15 +04:00
{
PyObject * py_base ;
struct ldb_dn * dn , * base ;
2024-03-14 07:32:51 +03:00
if ( ! PyArg_ParseTuple ( args , " O " , & py_base ) ) {
2011-05-24 01:30:15 +04:00
return NULL ;
2024-03-14 07:32:51 +03:00
}
2011-05-24 01:30:15 +04:00
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
2011-05-24 01:30:15 +04:00
2015-10-14 03:49:01 +03:00
if ( ! pyldb_Object_AsDn ( NULL , py_base , ldb_dn_get_ldb_context ( dn ) , & base ) )
2011-05-24 01:30:15 +04:00
return NULL ;
2011-07-14 07:17:49 +04:00
return PyBool_FromLong ( ldb_dn_compare_base ( base , dn ) = = 0 ) ;
2011-05-24 01:30:15 +04:00
}
2024-03-14 06:38:14 +03:00
static PyObject * py_ldb_dn_get_component_name ( PyObject * self , PyObject * args )
2014-04-29 11:35:31 +04:00
{
2024-03-14 06:38:14 +03:00
struct ldb_dn * dn = NULL ;
2014-04-29 11:35:31 +04:00
const char * name ;
unsigned int num = 0 ;
2024-03-14 07:32:51 +03:00
if ( ! PyArg_ParseTuple ( args , " I " , & num ) ) {
2014-04-29 11:35:31 +04:00
return NULL ;
2024-03-14 07:32:51 +03:00
}
2014-04-29 11:35:31 +04:00
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
2014-04-29 11:35:31 +04:00
name = ldb_dn_get_component_name ( dn , num ) ;
if ( name = = NULL ) {
Py_RETURN_NONE ;
}
2019-06-07 11:45:52 +03:00
return PyUnicode_FromString ( name ) ;
2014-04-29 11:35:31 +04:00
}
2024-03-14 06:38:14 +03:00
static PyObject * py_ldb_dn_get_component_value ( PyObject * self , PyObject * args )
2014-04-29 11:35:31 +04:00
{
2024-03-14 06:38:14 +03:00
struct ldb_dn * dn = NULL ;
2014-04-29 11:35:31 +04:00
const struct ldb_val * val ;
unsigned int num = 0 ;
2024-03-14 07:32:51 +03:00
if ( ! PyArg_ParseTuple ( args , " I " , & num ) ) {
2014-04-29 11:35:31 +04:00
return NULL ;
2024-03-14 07:32:51 +03:00
}
2014-04-29 11:35:31 +04:00
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
2014-04-29 11:35:31 +04:00
val = ldb_dn_get_component_val ( dn , num ) ;
if ( val = = NULL ) {
Py_RETURN_NONE ;
}
2015-08-21 11:10:28 +03:00
return PyStr_FromLdbValue ( val ) ;
2014-04-29 11:35:31 +04:00
}
2024-03-14 06:38:14 +03:00
static PyObject * py_ldb_dn_set_component ( PyObject * self , PyObject * args )
2014-04-29 11:35:31 +04:00
{
unsigned int num = 0 ;
2015-08-21 11:10:28 +03:00
char * name = NULL , * value = NULL ;
2020-05-05 04:47:39 +03:00
struct ldb_val val = { 0 } ;
2015-08-21 11:10:28 +03:00
int err ;
Py_ssize_t size = 0 ;
2024-03-14 06:38:14 +03:00
struct ldb_dn * dn = NULL ;
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
2014-04-29 11:35:31 +04:00
2024-03-14 07:32:51 +03:00
if ( ! PyArg_ParseTuple ( args , " Iss# " , & num , & name , & value , & size ) ) {
2014-04-29 11:35:31 +04:00
return NULL ;
2024-03-14 07:32:51 +03:00
}
2014-04-29 11:35:31 +04:00
2015-08-21 11:10:28 +03:00
val . data = ( unsigned char * ) value ;
val . length = size ;
2014-04-29 11:35:31 +04:00
2024-03-14 06:38:14 +03:00
err = ldb_dn_set_component ( dn , num , name , val ) ;
2014-04-29 11:35:31 +04:00
if ( err ! = LDB_SUCCESS ) {
PyErr_SetString ( PyExc_TypeError , " Failed to set component " ) ;
return NULL ;
}
Py_RETURN_NONE ;
}
2024-03-14 06:38:14 +03:00
static PyObject * py_ldb_dn_get_rdn_name ( PyObject * self ,
2019-05-02 21:51:05 +03:00
PyObject * Py_UNUSED ( ignored ) )
2014-04-29 11:35:31 +04:00
{
2024-03-14 06:38:14 +03:00
struct ldb_dn * dn = NULL ;
2014-04-29 11:35:31 +04:00
const char * name ;
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
2014-04-29 11:35:31 +04:00
name = ldb_dn_get_rdn_name ( dn ) ;
if ( name = = NULL ) {
Py_RETURN_NONE ;
}
2019-06-07 11:45:52 +03:00
return PyUnicode_FromString ( name ) ;
2014-04-29 11:35:31 +04:00
}
2024-03-14 06:38:14 +03:00
static PyObject * py_ldb_dn_get_rdn_value ( PyObject * self ,
2019-05-02 21:51:05 +03:00
PyObject * Py_UNUSED ( ignored ) )
2014-04-29 11:35:31 +04:00
{
2024-03-14 06:38:14 +03:00
struct ldb_dn * dn = NULL ;
2014-04-29 11:35:31 +04:00
const struct ldb_val * val ;
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
2014-04-29 11:35:31 +04:00
val = ldb_dn_get_rdn_val ( dn ) ;
if ( val = = NULL ) {
Py_RETURN_NONE ;
}
2015-08-21 11:10:28 +03:00
return PyStr_FromLdbValue ( val ) ;
2014-04-29 11:35:31 +04:00
}
2008-12-19 04:22:07 +03:00
static PyMethodDef py_ldb_dn_methods [ ] = {
2024-02-29 03:07:47 +03:00
{ " validate " , ( PyCFunction ) py_ldb_dn_validate , METH_NOARGS ,
2008-12-19 04:22:07 +03:00
" S.validate() -> bool \n "
" Validate DN is correct. " } ,
{ " is_valid " , ( PyCFunction ) py_ldb_dn_is_valid , METH_NOARGS ,
" S.is_valid() -> bool \n " } ,
{ " is_special " , ( PyCFunction ) py_ldb_dn_is_special , METH_NOARGS ,
" S.is_special() -> bool \n "
" Check whether this is a special LDB DN. " } ,
{ " is_null " , ( PyCFunction ) py_ldb_dn_is_null , METH_NOARGS ,
" Check whether this is a null DN. " } ,
{ " get_casefold " , ( PyCFunction ) py_ldb_dn_get_casefold , METH_NOARGS ,
NULL } ,
2019-05-02 21:51:05 +03:00
{ " get_linearized " , PY_DISCARD_FUNC_SIG ( PyCFunction ,
py_ldb_dn_get_linearized ) ,
METH_NOARGS ,
2008-12-19 04:22:07 +03:00
NULL } ,
{ " canonical_str " , ( PyCFunction ) py_ldb_dn_canonical_str , METH_NOARGS ,
" S.canonical_str() -> string \n "
" Canonical version of this DN (like a posix path). " } ,
2011-07-14 07:17:49 +04:00
{ " is_child_of " , ( PyCFunction ) py_ldb_dn_is_child_of , METH_VARARGS ,
" S.is_child_of(basedn) -> int \n Returns True if this DN is a child of basedn \n " } ,
2008-12-19 04:22:07 +03:00
{ " canonical_ex_str " , ( PyCFunction ) py_ldb_dn_canonical_ex_str , METH_NOARGS ,
" S.canonical_ex_str() -> string \n "
" Canonical version of this DN (like a posix path, with terminating newline). " } ,
2019-05-02 21:51:05 +03:00
{ " extended_str " , PY_DISCARD_FUNC_SIG ( PyCFunction ,
py_ldb_dn_extended_str ) ,
METH_VARARGS | METH_KEYWORDS ,
2011-06-22 07:49:37 +04:00
" S.extended_str(mode=1) -> string \n "
" Extended version of this DN " } ,
2008-12-19 16:41:44 +03:00
{ " parent " , ( PyCFunction ) py_ldb_dn_get_parent , METH_NOARGS ,
" S.parent() -> dn \n "
" Get the parent for this DN. " } ,
2024-02-29 03:07:47 +03:00
{ " add_child " , ( PyCFunction ) py_ldb_dn_add_child , METH_VARARGS ,
2022-09-30 01:46:40 +03:00
" S.add_child(dn) -> bool \n "
2008-12-19 16:41:44 +03:00
" Add a child DN to this DN. " } ,
{ " add_base " , ( PyCFunction ) py_ldb_dn_add_base , METH_VARARGS ,
2022-09-30 01:46:40 +03:00
" S.add_base(dn) -> bool \n "
2008-12-19 16:41:44 +03:00
" Add a base DN to this DN. " } ,
2024-03-17 07:56:09 +03:00
{ " copy " , ( PyCFunction ) py_ldb_dn_copy_method , METH_VARARGS ,
" dn.copy(ldb) -> dn \n "
" Make a copy of this DN, attached to the given ldb object. " } ,
2012-07-06 13:57:10 +04:00
{ " remove_base_components " , ( PyCFunction ) py_ldb_dn_remove_base_components , METH_VARARGS ,
" S.remove_base_components(int) -> bool \n "
" Remove a number of DN components from the base of this DN. " } ,
2008-12-19 19:08:35 +03:00
{ " check_special " , ( PyCFunction ) py_ldb_dn_check_special , METH_VARARGS ,
2010-12-30 05:43:23 +03:00
" S.check_special(name) -> bool \n \n "
" Check if name is a special DN name " } ,
2011-06-22 08:44:12 +04:00
{ " get_extended_component " , ( PyCFunction ) py_ldb_dn_get_extended_component , METH_VARARGS ,
" S.get_extended_component(name) -> string \n \n "
" returns a DN extended component as a binary string " } ,
{ " set_extended_component " , ( PyCFunction ) py_ldb_dn_set_extended_component , METH_VARARGS ,
2014-04-29 11:34:48 +04:00
" S.set_extended_component(name, value) -> None \n \n "
2011-06-22 08:44:12 +04:00
" set a DN extended component as a binary string " } ,
2014-04-29 11:35:31 +04:00
{ " get_component_name " , ( PyCFunction ) py_ldb_dn_get_component_name , METH_VARARGS ,
" S.get_component_name(num) -> string \n "
" get the attribute name of the specified component " } ,
{ " get_component_value " , ( PyCFunction ) py_ldb_dn_get_component_value , METH_VARARGS ,
" S.get_component_value(num) -> string \n "
" get the attribute value of the specified component as a binary string " } ,
{ " set_component " , ( PyCFunction ) py_ldb_dn_set_component , METH_VARARGS ,
2021-04-28 07:48:55 +03:00
" S.set_component(num, name, value) -> None \n "
2014-04-29 11:35:31 +04:00
" set the attribute name and value of the specified component " } ,
{ " get_rdn_name " , ( PyCFunction ) py_ldb_dn_get_rdn_name , METH_NOARGS ,
" S.get_rdn_name() -> string \n "
" get the RDN attribute name " } ,
{ " get_rdn_value " , ( PyCFunction ) py_ldb_dn_get_rdn_value , METH_NOARGS ,
" S.get_rdn_value() -> string \n "
" get the RDN attribute value as a binary string " } ,
2020-05-05 04:47:39 +03:00
{ 0 }
2008-12-19 04:22:07 +03:00
} ;
2024-03-17 04:24:03 +03:00
static PyObject * py_ldb_dn_get_ldb ( PyLdbDnObject * self , void * closure )
{
if ( self - > pyldb = = NULL ) {
Py_RETURN_NONE ;
}
Py_INCREF ( self - > pyldb ) ;
return ( PyObject * ) self - > pyldb ;
}
static PyGetSetDef py_ldb_dn_getset [ ] = {
{
. name = discard_const_p ( char , " ldb " ) ,
. get = ( getter ) py_ldb_dn_get_ldb ,
. doc = discard_const_p ( /* for Py 3.6; 3.7+ have const char* */
char , " returns the associated ldb object (or None) " )
} ,
{ . name = NULL } ,
} ;
2008-12-19 16:41:44 +03:00
static Py_ssize_t py_ldb_dn_len ( PyLdbDnObject * self )
{
2024-03-14 07:26:38 +03:00
struct ldb_dn * dn = pyldb_Dn_AS_DN ( self ) ;
if ( dn = = NULL | | self - > pyldb - > ldb_ctx ! = ldb_dn_get_ldb_context ( dn ) ) {
return - 1 ;
}
return ldb_dn_get_comp_num ( dn ) ;
2008-12-19 16:41:44 +03:00
}
2011-08-01 06:39:48 +04:00
/*
copy a DN as a python object
*/
2023-11-08 00:43:38 +03:00
static PyObject * py_ldb_dn_copy ( struct ldb_dn * dn , PyLdbObject * pyldb )
2011-08-01 06:39:48 +04:00
{
2023-08-25 05:22:15 +03:00
TALLOC_CTX * mem_ctx = NULL ;
struct ldb_dn * new_dn = NULL ;
2011-08-01 06:39:48 +04:00
PyLdbDnObject * py_ret ;
2024-03-18 02:24:53 +03:00
if ( ldb_dn_get_ldb_context ( dn ) ! = pyldb - > ldb_ctx ) {
/*
* We can ' t do this , because we can ' t ( for now ) change the ldb
* pointer of the underlying dn returned by ldb_dn_copy ( ) .
*
* This error means someone editing this file got confused ,
* which is quite understandable .
*/
PyErr_SetString ( PyExc_RuntimeError ,
" py_ldb_dn_copy can't copy to a new LDB " ) ;
return NULL ;
}
2023-08-25 05:22:15 +03:00
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
return PyErr_NoMemory ( ) ;
}
new_dn = ldb_dn_copy ( mem_ctx , dn ) ;
if ( new_dn = = NULL ) {
talloc_free ( mem_ctx ) ;
return PyErr_NoMemory ( ) ;
}
2011-08-01 06:39:48 +04:00
py_ret = ( PyLdbDnObject * ) PyLdbDn . tp_alloc ( & PyLdbDn , 0 ) ;
if ( py_ret = = NULL ) {
2023-08-25 05:22:15 +03:00
talloc_free ( mem_ctx ) ;
2011-08-01 06:39:48 +04:00
PyErr_NoMemory ( ) ;
return NULL ;
}
2023-08-25 05:22:15 +03:00
py_ret - > mem_ctx = mem_ctx ;
py_ret - > dn = new_dn ;
2023-11-08 00:43:38 +03:00
py_ret - > pyldb = pyldb ;
Py_INCREF ( py_ret - > pyldb ) ;
2011-08-01 06:39:48 +04:00
return ( PyObject * ) py_ret ;
}
2024-03-14 07:27:58 +03:00
static PyObject * py_ldb_dn_concat ( PyObject * self , PyObject * py_other )
2008-12-19 16:41:44 +03:00
{
2023-08-25 05:22:15 +03:00
TALLOC_CTX * mem_ctx = NULL ;
2024-03-14 07:27:58 +03:00
struct ldb_dn * dn = NULL ;
struct ldb_dn * other = NULL ;
2023-08-25 05:22:15 +03:00
struct ldb_dn * new_dn = NULL ;
2024-03-14 07:27:58 +03:00
PyLdbDnObject * py_ret = NULL ;
2011-08-07 19:08:56 +04:00
2024-03-14 07:27:58 +03:00
2024-03-13 07:28:57 +03:00
PyErr_internal_LDB_DN_OR_RAISE ( self , dn ) ;
PyErr_internal_LDB_DN_OR_RAISE ( py_other , other ) ;
2009-06-17 22:23:54 +04:00
2023-08-25 05:22:15 +03:00
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
return PyErr_NoMemory ( ) ;
}
new_dn = ldb_dn_copy ( mem_ctx , dn ) ;
if ( new_dn = = NULL ) {
talloc_free ( mem_ctx ) ;
return PyErr_NoMemory ( ) ;
}
if ( ! ldb_dn_add_base ( new_dn , other ) ) {
PyErr_SetString ( PyExc_RuntimeError , " unable to concatenate DNs " ) ;
talloc_free ( mem_ctx ) ;
return NULL ;
}
2009-06-17 22:23:54 +04:00
py_ret = ( PyLdbDnObject * ) PyLdbDn . tp_alloc ( & PyLdbDn , 0 ) ;
if ( py_ret = = NULL ) {
2023-08-25 05:22:15 +03:00
talloc_free ( mem_ctx ) ;
2009-06-17 22:23:54 +04:00
PyErr_NoMemory ( ) ;
return NULL ;
}
2023-08-25 05:22:15 +03:00
py_ret - > mem_ctx = mem_ctx ;
py_ret - > dn = new_dn ;
2024-03-14 07:27:58 +03:00
py_ret - > pyldb = ( ( PyLdbDnObject * ) self ) - > pyldb ;
2023-11-08 00:43:38 +03:00
Py_INCREF ( py_ret - > pyldb ) ;
2009-06-17 22:23:54 +04:00
return ( PyObject * ) py_ret ;
2008-12-19 16:41:44 +03:00
}
static PySequenceMethods py_ldb_dn_seq = {
. sq_length = ( lenfunc ) py_ldb_dn_len ,
. sq_concat = ( binaryfunc ) py_ldb_dn_concat ,
} ;
static PyObject * py_ldb_dn_new ( PyTypeObject * type , PyObject * args , PyObject * kwargs )
{
2018-09-24 14:20:20 +03:00
struct ldb_dn * ret = NULL ;
char * str = NULL ;
PyObject * py_ldb = NULL ;
struct ldb_context * ldb_ctx = NULL ;
TALLOC_CTX * mem_ctx = NULL ;
PyLdbDnObject * py_ret = NULL ;
2009-02-05 13:04:28 +03:00
const char * const kwnames [ ] = { " ldb " , " dn " , NULL } ;
2008-12-19 19:08:35 +03:00
2023-12-05 01:53:58 +03:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " O! " PYARG_STR_UNI ,
2009-02-05 13:04:28 +03:00
discard_const_p ( char * , kwnames ) ,
2023-12-05 01:53:58 +03:00
& PyLdb , & py_ldb , " utf8 " , & str ) )
2018-09-24 14:20:20 +03:00
goto out ;
2008-12-19 19:08:35 +03:00
2018-04-20 07:23:42 +03:00
ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT ( py_ldb ) ;
2009-05-31 18:19:11 +04:00
2009-06-17 22:17:35 +04:00
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
2018-09-24 14:20:20 +03:00
goto out ;
2009-06-17 22:17:35 +04:00
}
ret = ldb_dn_new ( mem_ctx , ldb_ctx , str ) ;
2011-03-04 12:44:22 +03:00
if ( ! ldb_dn_validate ( ret ) ) {
2009-06-17 22:17:35 +04:00
talloc_free ( mem_ctx ) ;
2008-12-19 16:41:44 +03:00
PyErr_SetString ( PyExc_ValueError , " unable to parse dn string " ) ;
2018-09-24 14:20:20 +03:00
goto out ;
2008-12-19 16:41:44 +03:00
}
2008-12-23 07:07:29 +03:00
py_ret = ( PyLdbDnObject * ) type - > tp_alloc ( type , 0 ) ;
2018-09-24 13:28:47 +03:00
if ( py_ret = = NULL ) {
2009-06-17 22:17:35 +04:00
talloc_free ( mem_ctx ) ;
2008-12-23 07:07:29 +03:00
PyErr_NoMemory ( ) ;
2018-09-24 14:20:20 +03:00
goto out ;
2008-12-23 07:07:29 +03:00
}
2009-06-17 22:17:35 +04:00
py_ret - > mem_ctx = mem_ctx ;
2008-12-23 07:07:29 +03:00
py_ret - > dn = ret ;
2023-11-08 00:43:38 +03:00
py_ret - > pyldb = ( PyLdbObject * ) py_ldb ;
Py_INCREF ( py_ret - > pyldb ) ;
2018-09-24 14:20:20 +03:00
out :
if ( str ! = NULL ) {
PyMem_Free ( discard_const_p ( char , str ) ) ;
}
2008-12-23 07:07:29 +03:00
return ( PyObject * ) py_ret ;
2008-12-19 16:41:44 +03:00
}
2008-12-23 07:07:29 +03:00
static void py_ldb_dn_dealloc ( PyLdbDnObject * self )
{
talloc_free ( self - > mem_ctx ) ;
2023-11-08 00:43:38 +03:00
Py_DECREF ( self - > pyldb ) ;
2010-12-29 17:58:12 +03:00
PyObject_Del ( self ) ;
2008-12-19 19:08:35 +03:00
}
2010-12-30 21:39:14 +03:00
static PyTypeObject PyLdbDn = {
2010-04-04 03:48:35 +04:00
. tp_name = " ldb.Dn " ,
2008-12-19 04:22:07 +03:00
. tp_methods = py_ldb_dn_methods ,
. tp_str = ( reprfunc ) py_ldb_dn_get_linearized ,
. tp_repr = ( reprfunc ) py_ldb_dn_repr ,
2015-06-09 11:36:26 +03:00
. tp_richcompare = ( richcmpfunc ) py_ldb_dn_richcmp ,
2008-12-19 16:41:44 +03:00
. tp_as_sequence = & py_ldb_dn_seq ,
2024-03-17 04:24:03 +03:00
. tp_getset = py_ldb_dn_getset ,
2008-12-19 04:22:07 +03:00
. tp_doc = " A LDB distinguished name. " ,
2008-12-19 16:41:44 +03:00
. tp_new = py_ldb_dn_new ,
2008-12-23 07:07:29 +03:00
. tp_dealloc = ( destructor ) py_ldb_dn_dealloc ,
2011-01-17 08:23:23 +03:00
. tp_basicsize = sizeof ( PyLdbDnObject ) ,
2008-12-21 05:08:14 +03:00
. tp_flags = Py_TPFLAGS_DEFAULT ,
2008-12-19 04:22:07 +03:00
} ;
/* Debug */
2008-12-19 19:08:35 +03:00
static void py_ldb_debug ( void * context , enum ldb_debug_level level , const char * fmt , va_list ap ) PRINTF_ATTRIBUTE ( 3 , 0 ) ;
2008-12-19 04:22:07 +03:00
static void py_ldb_debug ( void * context , enum ldb_debug_level level , const char * fmt , va_list ap )
{
2009-02-05 13:04:28 +03:00
PyObject * fn = ( PyObject * ) context ;
2023-05-23 05:07:08 +03:00
PyObject * result = NULL ;
result = PyObject_CallFunction ( fn , discard_const_p ( char , " (i,O) " ) , level , PyUnicode_FromFormatV ( fmt , ap ) ) ;
Py_XDECREF ( result ) ;
2008-12-19 04:22:07 +03:00
}
2015-06-10 16:40:34 +03:00
static PyObject * py_ldb_debug_func ;
2012-03-02 06:46:13 +04:00
static PyObject * py_ldb_set_debug ( PyObject * self , PyObject * args )
2008-12-19 04:22:07 +03:00
{
PyObject * cb ;
2012-03-02 06:46:13 +04:00
struct ldb_context * ldb_ctx ;
2009-05-31 18:19:11 +04:00
2008-12-19 04:22:07 +03:00
if ( ! PyArg_ParseTuple ( args , " O " , & cb ) )
return NULL ;
2015-06-10 16:40:34 +03:00
if ( py_ldb_debug_func ! = NULL ) {
Py_DECREF ( py_ldb_debug_func ) ;
}
2008-12-19 04:22:07 +03:00
Py_INCREF ( cb ) ;
2015-06-10 16:40:34 +03:00
/* FIXME: DECREF cb when exiting program */
py_ldb_debug_func = cb ;
2018-04-20 07:23:42 +03:00
ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2012-03-02 06:46:13 +04:00
PyErr_LDB_ERROR_IS_ERR_RAISE ( PyExc_LdbError ,
ldb_set_debug ( ldb_ctx , py_ldb_debug , cb ) ,
ldb_ctx ) ;
2009-05-31 18:19:11 +04:00
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 04:22:07 +03:00
}
static PyObject * py_ldb_set_create_perms ( PyTypeObject * self , PyObject * args )
{
unsigned int perms ;
if ( ! PyArg_ParseTuple ( args , " I " , & perms ) )
return NULL ;
2018-04-20 07:23:42 +03:00
ldb_set_create_perms ( pyldb_Ldb_AS_LDBCONTEXT ( self ) , perms ) ;
2008-12-19 04:22:07 +03:00
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 04:22:07 +03:00
}
static PyObject * py_ldb_set_modules_dir ( PyTypeObject * self , PyObject * args )
{
char * modules_dir ;
if ( ! PyArg_ParseTuple ( args , " s " , & modules_dir ) )
return NULL ;
2018-04-20 07:23:42 +03:00
ldb_set_modules_dir ( pyldb_Ldb_AS_LDBCONTEXT ( self ) , modules_dir ) ;
2008-12-19 04:22:07 +03:00
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 04:22:07 +03:00
}
2019-05-02 21:51:05 +03:00
static PyObject * py_ldb_transaction_start ( PyLdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2008-12-19 04:22:07 +03:00
{
2018-04-20 07:23:42 +03:00
struct ldb_context * ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2012-03-02 06:46:13 +04:00
int ldb_err ;
ldb_err = ldb_transaction_start ( ldb_ctx ) ;
PyErr_LDB_ERROR_IS_ERR_RAISE ( PyExc_LdbError , ldb_err , ldb_ctx ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 04:22:07 +03:00
}
2019-05-02 21:51:05 +03:00
static PyObject * py_ldb_transaction_commit ( PyLdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2008-12-19 04:22:07 +03:00
{
2018-04-20 07:23:42 +03:00
struct ldb_context * ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2012-03-02 06:46:13 +04:00
int ldb_err ;
ldb_err = ldb_transaction_commit ( ldb_ctx ) ;
PyErr_LDB_ERROR_IS_ERR_RAISE ( PyExc_LdbError , ldb_err , ldb_ctx ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 04:22:07 +03:00
}
2019-05-02 21:51:05 +03:00
static PyObject * py_ldb_transaction_prepare_commit ( PyLdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2009-11-26 07:32:06 +03:00
{
2018-04-20 07:23:42 +03:00
struct ldb_context * ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2012-03-02 06:46:13 +04:00
int ldb_err ;
ldb_err = ldb_transaction_prepare_commit ( ldb_ctx ) ;
PyErr_LDB_ERROR_IS_ERR_RAISE ( PyExc_LdbError , ldb_err , ldb_ctx ) ;
2009-11-26 07:32:06 +03:00
Py_RETURN_NONE ;
}
2019-05-02 21:51:05 +03:00
static PyObject * py_ldb_transaction_cancel ( PyLdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2008-12-19 04:22:07 +03:00
{
2018-04-20 07:23:42 +03:00
struct ldb_context * ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2012-03-02 06:46:13 +04:00
int ldb_err ;
ldb_err = ldb_transaction_cancel ( ldb_ctx ) ;
PyErr_LDB_ERROR_IS_ERR_RAISE ( PyExc_LdbError , ldb_err , ldb_ctx ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 04:22:07 +03:00
}
2019-05-02 21:51:05 +03:00
static PyObject * py_ldb_setup_wellknown_attributes ( PyLdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2008-12-19 04:22:07 +03:00
{
2018-04-20 07:23:42 +03:00
struct ldb_context * ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2012-03-02 06:46:13 +04:00
int ldb_err ;
ldb_err = ldb_setup_wellknown_attributes ( ldb_ctx ) ;
PyErr_LDB_ERROR_IS_ERR_RAISE ( PyExc_LdbError , ldb_err , ldb_ctx ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 04:22:07 +03:00
}
static PyObject * py_ldb_repr ( PyLdbObject * self )
{
2019-06-07 11:45:52 +03:00
return PyUnicode_FromString ( " <ldb connection> " ) ;
2008-12-19 04:22:07 +03:00
}
2019-05-02 21:51:05 +03:00
static PyObject * py_ldb_get_root_basedn ( PyLdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2008-12-19 04:22:07 +03:00
{
2018-04-20 07:23:42 +03:00
struct ldb_dn * dn = ldb_get_root_basedn ( pyldb_Ldb_AS_LDBCONTEXT ( self ) ) ;
2008-12-19 04:22:07 +03:00
if ( dn = = NULL )
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2023-11-08 00:43:38 +03:00
return py_ldb_dn_copy ( dn , self ) ;
2008-12-19 04:22:07 +03:00
}
2019-05-02 21:51:05 +03:00
static PyObject * py_ldb_get_schema_basedn ( PyLdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2008-12-19 04:22:07 +03:00
{
2018-04-20 07:23:42 +03:00
struct ldb_dn * dn = ldb_get_schema_basedn ( pyldb_Ldb_AS_LDBCONTEXT ( self ) ) ;
2008-12-19 04:22:07 +03:00
if ( dn = = NULL )
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2023-11-08 00:43:38 +03:00
return py_ldb_dn_copy ( dn , self ) ;
2008-12-19 04:22:07 +03:00
}
2019-05-02 21:51:05 +03:00
static PyObject * py_ldb_get_config_basedn ( PyLdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2008-12-19 04:22:07 +03:00
{
2018-04-20 07:23:42 +03:00
struct ldb_dn * dn = ldb_get_config_basedn ( pyldb_Ldb_AS_LDBCONTEXT ( self ) ) ;
2008-12-19 04:22:07 +03:00
if ( dn = = NULL )
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2023-11-08 00:43:38 +03:00
return py_ldb_dn_copy ( dn , self ) ;
2008-12-19 04:22:07 +03:00
}
2019-05-02 21:51:05 +03:00
static PyObject * py_ldb_get_default_basedn ( PyLdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2008-12-19 04:22:07 +03:00
{
2018-04-20 07:23:42 +03:00
struct ldb_dn * dn = ldb_get_default_basedn ( pyldb_Ldb_AS_LDBCONTEXT ( self ) ) ;
2008-12-19 04:22:07 +03:00
if ( dn = = NULL )
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2023-11-08 00:43:38 +03:00
return py_ldb_dn_copy ( dn , self ) ;
2008-12-19 04:22:07 +03:00
}
2015-06-09 18:44:40 +03:00
static const char * * PyList_AsStrList ( TALLOC_CTX * mem_ctx , PyObject * list ,
const char * paramname )
2008-12-19 16:41:44 +03:00
{
const char * * ret ;
2010-11-06 19:48:39 +03:00
Py_ssize_t i ;
2008-12-19 16:41:44 +03:00
if ( ! PyList_Check ( list ) ) {
2009-03-20 02:33:43 +03:00
PyErr_Format ( PyExc_TypeError , " %s is not a list " , paramname ) ;
2008-12-19 16:41:44 +03:00
return NULL ;
}
2008-12-19 19:08:35 +03:00
ret = talloc_array ( NULL , const char * , PyList_Size ( list ) + 1 ) ;
2010-12-30 22:11:59 +03:00
if ( ret = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2008-12-19 16:41:44 +03:00
for ( i = 0 ; i < PyList_Size ( list ) ; i + + ) {
2015-06-09 18:44:40 +03:00
const char * str = NULL ;
Py_ssize_t size ;
2008-12-19 16:41:44 +03:00
PyObject * item = PyList_GetItem ( list , i ) ;
2019-06-15 14:14:49 +03:00
if ( ! PyUnicode_Check ( item ) ) {
2009-03-20 02:33:43 +03:00
PyErr_Format ( PyExc_TypeError , " %s should be strings " , paramname ) ;
2015-06-09 18:44:40 +03:00
talloc_free ( ret ) ;
return NULL ;
}
2019-06-07 12:44:48 +03:00
str = PyUnicode_AsUTF8AndSize ( item , & size ) ;
2015-06-09 18:44:40 +03:00
if ( str = = NULL ) {
talloc_free ( ret ) ;
2008-12-19 16:41:44 +03:00
return NULL ;
}
2015-06-09 18:44:40 +03:00
ret [ i ] = talloc_strndup ( ret , str , size ) ;
2008-12-19 16:41:44 +03:00
}
2008-12-19 19:08:35 +03:00
ret [ i ] = NULL ;
2008-12-19 16:41:44 +03:00
return ret ;
}
2024-03-06 02:57:15 +03:00
static PyObject * py_ldb_connect ( PyLdbObject * self , PyObject * args , PyObject * kwargs ) ;
2008-12-21 01:00:23 +03:00
static int py_ldb_init ( PyLdbObject * self , PyObject * args , PyObject * kwargs )
2008-12-19 04:22:07 +03:00
{
2009-02-05 13:04:28 +03:00
const char * const kwnames [ ] = { " url " , " flags " , " options " , NULL } ;
2008-12-19 16:41:44 +03:00
char * url = NULL ;
2024-03-06 02:57:15 +03:00
PyObject * py_options = NULL ;
2011-04-10 21:48:07 +04:00
unsigned int flags = 0 ;
2008-12-19 16:41:44 +03:00
2011-04-10 21:48:07 +04:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " |zIO:Ldb.__init__ " ,
2009-02-05 13:04:28 +03:00
discard_const_p ( char * , kwnames ) ,
2024-03-06 02:57:15 +03:00
& url , & flags , & py_options ) ) {
2008-12-21 01:00:23 +03:00
return - 1 ;
2008-12-19 16:41:44 +03:00
}
2009-05-31 18:19:11 +04:00
2008-12-19 16:41:44 +03:00
if ( url ! = NULL ) {
2024-03-06 02:57:15 +03:00
/* py_ldb_connect returns py_None on success, NULL on error */
PyObject * result = py_ldb_connect ( self , args , kwargs ) ;
if ( result = = NULL ) {
2008-12-21 01:00:23 +03:00
return - 1 ;
}
2024-03-06 02:57:15 +03:00
Py_DECREF ( result ) ;
2019-07-04 04:26:20 +03:00
} else {
2024-03-06 02:57:15 +03:00
struct ldb_context * ldb = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2019-07-04 04:26:20 +03:00
ldb_set_flags ( ldb , flags ) ;
2008-12-19 16:41:44 +03:00
}
2008-12-21 01:00:23 +03:00
return 0 ;
}
2008-12-19 16:41:44 +03:00
2008-12-21 01:00:23 +03:00
static PyObject * py_ldb_new ( PyTypeObject * type , PyObject * args , PyObject * kwargs )
{
2023-08-25 05:22:15 +03:00
TALLOC_CTX * mem_ctx = NULL ;
2008-12-23 07:07:29 +03:00
PyLdbObject * ret ;
2008-12-21 01:00:23 +03:00
struct ldb_context * ldb ;
2023-08-25 05:22:15 +03:00
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
return PyErr_NoMemory ( ) ;
}
ldb = ldb_init ( mem_ctx , NULL ) ;
if ( ldb = = NULL ) {
talloc_free ( mem_ctx ) ;
2008-12-21 01:00:23 +03:00
PyErr_NoMemory ( ) ;
return NULL ;
}
2023-08-25 05:22:15 +03:00
ret = ( PyLdbObject * ) type - > tp_alloc ( type , 0 ) ;
if ( ret = = NULL ) {
talloc_free ( mem_ctx ) ;
2008-12-23 07:07:29 +03:00
PyErr_NoMemory ( ) ;
return NULL ;
}
2023-08-25 05:22:15 +03:00
ret - > mem_ctx = mem_ctx ;
2009-06-17 22:43:25 +04:00
2008-12-23 07:07:29 +03:00
ret - > ldb_ctx = ldb ;
return ( PyObject * ) ret ;
2008-12-19 04:22:07 +03:00
}
static PyObject * py_ldb_connect ( PyLdbObject * self , PyObject * args , PyObject * kwargs )
{
2018-04-12 08:07:38 +03:00
char * url = NULL ;
2011-04-10 21:48:07 +04:00
unsigned int flags = 0 ;
2008-12-19 04:22:07 +03:00
PyObject * py_options = Py_None ;
int ret ;
const char * * options ;
2009-02-05 13:04:28 +03:00
const char * const kwnames [ ] = { " url " , " flags " , " options " , NULL } ;
2012-03-02 06:46:13 +04:00
struct ldb_context * ldb_ctx ;
2009-02-05 13:04:28 +03:00
2018-04-18 05:37:12 +03:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " z|IO " ,
2009-02-05 13:04:28 +03:00
discard_const_p ( char * , kwnames ) ,
& url , & flags , & py_options ) )
2008-12-19 04:22:07 +03:00
return NULL ;
if ( py_options = = Py_None ) {
options = NULL ;
} else {
2015-06-09 18:44:40 +03:00
options = PyList_AsStrList ( NULL , py_options , " options " ) ;
2008-12-19 16:41:44 +03:00
if ( options = = NULL )
2008-12-19 04:22:07 +03:00
return NULL ;
}
2009-05-31 18:19:11 +04:00
2018-04-20 07:23:42 +03:00
ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2012-03-02 06:46:13 +04:00
ret = ldb_connect ( ldb_ctx , url , flags , options ) ;
2008-12-19 04:22:07 +03:00
talloc_free ( options ) ;
2012-03-02 06:46:13 +04:00
PyErr_LDB_ERROR_IS_ERR_RAISE ( PyExc_LdbError , ret , ldb_ctx ) ;
2008-12-19 04:22:07 +03:00
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 04:22:07 +03:00
}
2011-06-14 10:39:49 +04:00
static PyObject * py_ldb_modify ( PyLdbObject * self , PyObject * args , PyObject * kwargs )
2008-12-19 04:22:07 +03:00
{
PyObject * py_msg ;
2009-11-20 14:22:38 +03:00
PyObject * py_controls = Py_None ;
struct ldb_context * ldb_ctx ;
struct ldb_request * req ;
struct ldb_control * * parsed_controls ;
struct ldb_message * msg ;
2008-12-19 04:22:07 +03:00
int ret ;
2010-06-20 20:06:54 +04:00
TALLOC_CTX * mem_ctx ;
2011-06-14 10:39:49 +04:00
bool validate = true ;
const char * const kwnames [ ] = { " message " , " controls " , " validate " , NULL } ;
2010-06-20 20:06:54 +04:00
2011-06-14 10:39:49 +04:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " O|Ob " ,
discard_const_p ( char * , kwnames ) ,
& py_msg , & py_controls , & validate ) )
2008-12-19 04:22:07 +03:00
return NULL ;
2010-06-20 20:06:54 +04:00
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2018-04-20 07:23:42 +03:00
ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2009-11-20 14:22:38 +03:00
if ( py_controls = = Py_None ) {
parsed_controls = NULL ;
} else {
2015-06-09 18:44:40 +03:00
const char * * controls = PyList_AsStrList ( mem_ctx , py_controls , " controls " ) ;
2015-03-04 00:29:13 +03:00
if ( controls = = NULL ) {
talloc_free ( mem_ctx ) ;
return NULL ;
}
2010-06-20 20:06:54 +04:00
parsed_controls = ldb_parse_control_strings ( ldb_ctx , mem_ctx , controls ) ;
2023-01-17 02:33:17 +03:00
if ( controls [ 0 ] ! = NULL & & parsed_controls = = NULL ) {
talloc_free ( mem_ctx ) ;
PyErr_SetLdbError ( PyExc_LdbError , LDB_ERR_OPERATIONS_ERROR , ldb_ctx ) ;
return NULL ;
}
2009-11-20 14:22:38 +03:00
talloc_free ( controls ) ;
}
2024-03-13 07:28:07 +03:00
if ( ! pyldb_Message_Check ( py_msg ) ) {
2008-12-19 04:22:07 +03:00
PyErr_SetString ( PyExc_TypeError , " Expected Ldb Message " ) ;
2010-06-20 20:06:54 +04:00
talloc_free ( mem_ctx ) ;
2008-12-19 04:22:07 +03:00
return NULL ;
}
2011-08-07 19:08:56 +04:00
msg = pyldb_Message_AsMessage ( py_msg ) ;
2009-11-20 14:22:38 +03:00
2011-06-14 10:39:49 +04:00
if ( validate ) {
ret = ldb_msg_sanity_check ( ldb_ctx , msg ) ;
if ( ret ! = LDB_SUCCESS ) {
2012-03-02 00:26:27 +04:00
PyErr_SetLdbError ( PyExc_LdbError , ret , ldb_ctx ) ;
2011-06-14 10:39:49 +04:00
talloc_free ( mem_ctx ) ;
return NULL ;
}
2010-06-20 20:06:54 +04:00
}
2009-11-20 14:22:38 +03:00
2010-06-20 20:06:54 +04:00
ret = ldb_build_mod_req ( & req , ldb_ctx , mem_ctx , msg , parsed_controls ,
NULL , ldb_op_default_callback , NULL ) ;
2015-06-09 18:44:40 +03:00
if ( ret ! = LDB_SUCCESS ) {
2009-11-20 14:22:38 +03:00
PyErr_SetString ( PyExc_TypeError , " failed to build request " ) ;
2010-06-20 20:06:54 +04:00
talloc_free ( mem_ctx ) ;
2009-11-20 14:22:38 +03:00
return NULL ;
}
2008-12-19 04:22:07 +03:00
2010-12-21 16:05:18 +03:00
/* do request and autostart a transaction */
2009-11-20 14:22:38 +03:00
/* Then let's LDB handle the message error in case of pb as they are meaningful */
2010-06-20 20:06:54 +04:00
ret = ldb_transaction_start ( ldb_ctx ) ;
if ( ret ! = LDB_SUCCESS ) {
talloc_free ( mem_ctx ) ;
2012-03-02 00:26:27 +04:00
PyErr_SetLdbError ( PyExc_LdbError , ret , ldb_ctx ) ;
return NULL ;
2010-12-21 16:05:18 +03:00
}
2009-11-20 14:22:38 +03:00
2010-12-21 16:05:18 +03:00
ret = ldb_request ( ldb_ctx , req ) ;
if ( ret = = LDB_SUCCESS ) {
2011-09-20 19:41:10 +04:00
ret = ldb_wait ( req - > handle , LDB_WAIT_ALL ) ;
2010-12-21 16:05:18 +03:00
}
2009-11-20 14:22:38 +03:00
if ( ret = = LDB_SUCCESS ) {
2010-12-21 16:05:18 +03:00
ret = ldb_transaction_commit ( ldb_ctx ) ;
} else {
2009-11-20 14:22:38 +03:00
ldb_transaction_cancel ( ldb_ctx ) ;
}
2010-06-20 20:06:54 +04:00
talloc_free ( mem_ctx ) ;
PyErr_LDB_ERROR_IS_ERR_RAISE ( PyExc_LdbError , ret , ldb_ctx ) ;
2008-12-19 04:22:07 +03:00
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 04:22:07 +03:00
}
2009-09-23 00:51:25 +04:00
2010-11-18 23:09:01 +03:00
/**
* Obtain a ldb message from a Python Dictionary object .
*
* @ param mem_ctx Memory context
* @ param py_obj Python Dictionary object
* @ param ldb_ctx LDB context
* @ param mod_flags Flags to be set on every message element
* @ return ldb_message on success or NULL on failure
*/
static struct ldb_message * PyDict_AsMessage ( TALLOC_CTX * mem_ctx ,
PyObject * py_obj ,
struct ldb_context * ldb_ctx ,
unsigned int mod_flags )
{
struct ldb_message * msg ;
unsigned int msg_pos = 0 ;
Py_ssize_t dict_pos = 0 ;
PyObject * key , * value ;
struct ldb_message_element * msg_el ;
PyObject * dn_value = PyDict_GetItemString ( py_obj , " dn " ) ;
msg = ldb_msg_new ( mem_ctx ) ;
2013-08-18 23:51:49 +04:00
if ( msg = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2010-11-18 23:09:01 +03:00
msg - > elements = talloc_zero_array ( msg , struct ldb_message_element , PyDict_Size ( py_obj ) ) ;
2023-07-07 01:42:38 +03:00
if ( msg - > elements = = NULL ) {
PyErr_NoMemory ( ) ;
TALLOC_FREE ( msg ) ;
return NULL ;
}
2010-11-18 23:09:01 +03:00
if ( dn_value ) {
2024-03-25 12:33:02 +03:00
struct ldb_dn * dn = NULL ;
if ( ! pyldb_Object_AsDn ( msg , dn_value , ldb_ctx , & dn ) ) {
2010-11-18 23:09:01 +03:00
PyErr_SetString ( PyExc_TypeError , " unable to import dn object " ) ;
2023-07-07 01:42:01 +03:00
TALLOC_FREE ( msg ) ;
2010-11-18 23:09:01 +03:00
return NULL ;
}
2024-03-25 12:33:02 +03:00
if ( dn = = NULL ) {
2010-11-18 23:09:01 +03:00
PyErr_SetString ( PyExc_TypeError , " dn set but not found " ) ;
2023-07-07 01:42:01 +03:00
TALLOC_FREE ( msg ) ;
2010-11-18 23:09:01 +03:00
return NULL ;
}
2024-03-25 12:33:02 +03:00
msg - > dn = talloc_reference ( msg , dn ) ;
if ( msg - > dn = = NULL ) {
talloc_free ( mem_ctx ) ;
PyErr_NoMemory ( ) ;
return NULL ;
}
2010-11-18 23:09:01 +03:00
} else {
PyErr_SetString ( PyExc_TypeError , " no dn set " ) ;
2023-07-07 01:42:01 +03:00
TALLOC_FREE ( msg ) ;
2010-11-18 23:09:01 +03:00
return NULL ;
}
while ( PyDict_Next ( py_obj , & dict_pos , & key , & value ) ) {
2019-06-07 12:21:15 +03:00
const char * key_str = PyUnicode_AsUTF8 ( key ) ;
2012-02-11 15:48:20 +04:00
if ( ldb_attr_cmp ( key_str , " dn " ) ! = 0 ) {
2010-11-18 23:09:01 +03:00
msg_el = PyObject_AsMessageElement ( msg - > elements , value ,
mod_flags , key_str ) ;
if ( msg_el = = NULL ) {
2015-03-04 00:29:12 +03:00
PyErr_Format ( PyExc_TypeError , " unable to import element '%s' " , key_str ) ;
2023-07-07 01:42:01 +03:00
TALLOC_FREE ( msg ) ;
2010-11-18 23:09:01 +03:00
return NULL ;
}
memcpy ( & msg - > elements [ msg_pos ] , msg_el , sizeof ( * msg_el ) ) ;
2023-07-07 02:28:01 +03:00
/*
* PyObject_AsMessageElement might have returned a
* reference to an existing MessageElement , and so left
* the name and flags unchanged . Thus if those members
* aren ’ t set , we ’ ll assume that the user forgot to
* initialize them .
*/
if ( msg - > elements [ msg_pos ] . name = = NULL ) {
/* No name was set — set it now. */
msg - > elements [ msg_pos ] . name = talloc_strdup ( msg - > elements , key_str ) ;
if ( msg - > elements [ msg_pos ] . name = = NULL ) {
PyErr_NoMemory ( ) ;
TALLOC_FREE ( msg ) ;
return NULL ;
}
}
if ( msg - > elements [ msg_pos ] . flags = = 0 ) {
/* No flags were set — set them now. */
msg - > elements [ msg_pos ] . flags = mod_flags ;
}
2010-11-18 23:09:01 +03:00
msg_pos + + ;
}
}
msg - > num_elements = msg_pos ;
return msg ;
}
2011-06-14 10:41:35 +04:00
static PyObject * py_ldb_add ( PyLdbObject * self , PyObject * args , PyObject * kwargs )
2008-12-19 04:22:07 +03:00
{
2010-11-18 23:09:01 +03:00
PyObject * py_obj ;
2008-12-19 04:22:07 +03:00
int ret ;
2009-09-23 00:51:25 +04:00
struct ldb_context * ldb_ctx ;
struct ldb_request * req ;
2010-11-18 23:09:01 +03:00
struct ldb_message * msg = NULL ;
2009-09-23 00:51:25 +04:00
PyObject * py_controls = Py_None ;
2009-06-17 22:43:25 +04:00
TALLOC_CTX * mem_ctx ;
2009-09-23 00:51:25 +04:00
struct ldb_control * * parsed_controls ;
2011-06-14 10:41:35 +04:00
const char * const kwnames [ ] = { " message " , " controls " , NULL } ;
2008-12-19 04:22:07 +03:00
2011-06-14 10:41:35 +04:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " O|O " ,
discard_const_p ( char * , kwnames ) ,
& py_obj , & py_controls ) )
2008-12-19 04:22:07 +03:00
return NULL ;
2009-06-17 22:43:25 +04:00
mem_ctx = talloc_new ( NULL ) ;
2010-06-19 00:08:58 +04:00
if ( mem_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2018-04-20 07:23:42 +03:00
ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2010-06-19 00:08:58 +04:00
2009-09-23 00:51:25 +04:00
if ( py_controls = = Py_None ) {
parsed_controls = NULL ;
} else {
2015-06-09 18:44:40 +03:00
const char * * controls = PyList_AsStrList ( mem_ctx , py_controls , " controls " ) ;
2015-03-04 00:29:13 +03:00
if ( controls = = NULL ) {
talloc_free ( mem_ctx ) ;
return NULL ;
}
2010-06-19 00:08:58 +04:00
parsed_controls = ldb_parse_control_strings ( ldb_ctx , mem_ctx , controls ) ;
2023-01-17 02:33:17 +03:00
if ( controls [ 0 ] ! = NULL & & parsed_controls = = NULL ) {
talloc_free ( mem_ctx ) ;
PyErr_SetLdbError ( PyExc_LdbError , LDB_ERR_OPERATIONS_ERROR , ldb_ctx ) ;
return NULL ;
}
2009-09-23 00:51:25 +04:00
talloc_free ( controls ) ;
}
2008-12-19 04:22:07 +03:00
2024-03-13 07:28:07 +03:00
if ( pyldb_Message_Check ( py_obj ) ) {
2011-08-07 19:08:56 +04:00
msg = pyldb_Message_AsMessage ( py_obj ) ;
2010-11-18 23:09:01 +03:00
} else if ( PyDict_Check ( py_obj ) ) {
msg = PyDict_AsMessage ( mem_ctx , py_obj , ldb_ctx , LDB_FLAG_MOD_ADD ) ;
2008-12-21 00:21:39 +03:00
} else {
2010-11-18 23:09:01 +03:00
PyErr_SetString ( PyExc_TypeError ,
" Dictionary or LdbMessage object expected! " ) ;
2008-12-21 00:21:39 +03:00
}
2010-11-18 23:09:01 +03:00
if ( ! msg ) {
/* we should have a PyErr already set */
talloc_free ( mem_ctx ) ;
return NULL ;
}
2009-09-23 00:51:25 +04:00
ret = ldb_msg_sanity_check ( ldb_ctx , msg ) ;
2010-12-21 16:05:18 +03:00
if ( ret ! = LDB_SUCCESS ) {
2012-03-02 00:26:27 +04:00
PyErr_SetLdbError ( PyExc_LdbError , ret , ldb_ctx ) ;
2009-09-23 00:51:25 +04:00
talloc_free ( mem_ctx ) ;
return NULL ;
2010-12-21 16:05:18 +03:00
}
2009-09-23 00:51:25 +04:00
2010-12-21 16:05:18 +03:00
ret = ldb_build_add_req ( & req , ldb_ctx , mem_ctx , msg , parsed_controls ,
2010-06-19 00:08:58 +04:00
NULL , ldb_op_default_callback , NULL ) ;
2010-12-21 16:05:18 +03:00
if ( ret ! = LDB_SUCCESS ) {
2009-09-23 00:51:25 +04:00
PyErr_SetString ( PyExc_TypeError , " failed to build request " ) ;
talloc_free ( mem_ctx ) ;
return NULL ;
}
2009-05-31 18:19:11 +04:00
2009-09-23 00:51:25 +04:00
/* do request and autostart a transaction */
/* Then let's LDB handle the message error in case of pb as they are meaningful */
2010-12-21 16:05:18 +03:00
ret = ldb_transaction_start ( ldb_ctx ) ;
if ( ret ! = LDB_SUCCESS ) {
2009-09-23 00:51:25 +04:00
talloc_free ( mem_ctx ) ;
2012-03-02 00:26:27 +04:00
PyErr_SetLdbError ( PyExc_LdbError , ret , ldb_ctx ) ;
return NULL ;
2010-12-21 16:05:18 +03:00
}
2009-09-23 00:51:25 +04:00
2010-12-21 16:05:18 +03:00
ret = ldb_request ( ldb_ctx , req ) ;
if ( ret = = LDB_SUCCESS ) {
2011-06-21 13:32:02 +04:00
ret = ldb_wait ( req - > handle , LDB_WAIT_ALL ) ;
2012-03-02 06:46:13 +04:00
}
2009-09-23 00:51:25 +04:00
if ( ret = = LDB_SUCCESS ) {
2011-06-21 13:32:02 +04:00
ret = ldb_transaction_commit ( ldb_ctx ) ;
2010-12-21 16:05:18 +03:00
} else {
ldb_transaction_cancel ( ldb_ctx ) ;
2009-09-23 00:51:25 +04:00
}
2010-06-19 00:08:58 +04:00
2009-06-17 22:43:25 +04:00
talloc_free ( mem_ctx ) ;
2010-06-19 00:08:58 +04:00
PyErr_LDB_ERROR_IS_ERR_RAISE ( PyExc_LdbError , ret , ldb_ctx ) ;
2008-12-19 04:22:07 +03:00
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 04:22:07 +03:00
}
2011-06-14 10:41:35 +04:00
static PyObject * py_ldb_delete ( PyLdbObject * self , PyObject * args , PyObject * kwargs )
2008-12-19 04:22:07 +03:00
{
PyObject * py_dn ;
struct ldb_dn * dn ;
int ret ;
2010-06-19 00:04:07 +04:00
struct ldb_context * ldb_ctx ;
struct ldb_request * req ;
PyObject * py_controls = Py_None ;
2009-11-15 16:23:32 +03:00
TALLOC_CTX * mem_ctx ;
2010-06-19 00:04:07 +04:00
struct ldb_control * * parsed_controls ;
2011-06-14 10:41:35 +04:00
const char * const kwnames [ ] = { " dn " , " controls " , NULL } ;
2010-06-19 00:04:07 +04:00
2011-06-14 10:41:35 +04:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " O|O " ,
discard_const_p ( char * , kwnames ) ,
& py_dn , & py_controls ) )
2008-12-19 04:22:07 +03:00
return NULL ;
2009-11-15 16:23:32 +03:00
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2018-04-20 07:23:42 +03:00
ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2010-06-19 00:04:07 +04:00
if ( py_controls = = Py_None ) {
parsed_controls = NULL ;
} else {
2015-06-09 18:44:40 +03:00
const char * * controls = PyList_AsStrList ( mem_ctx , py_controls , " controls " ) ;
2015-03-04 00:29:13 +03:00
if ( controls = = NULL ) {
talloc_free ( mem_ctx ) ;
return NULL ;
}
2010-06-19 00:04:07 +04:00
parsed_controls = ldb_parse_control_strings ( ldb_ctx , mem_ctx , controls ) ;
2023-01-17 02:33:17 +03:00
if ( controls [ 0 ] ! = NULL & & parsed_controls = = NULL ) {
talloc_free ( mem_ctx ) ;
PyErr_SetLdbError ( PyExc_LdbError , LDB_ERR_OPERATIONS_ERROR , ldb_ctx ) ;
return NULL ;
}
2010-06-19 00:04:07 +04:00
talloc_free ( controls ) ;
}
2011-08-07 19:08:56 +04:00
if ( ! pyldb_Object_AsDn ( mem_ctx , py_dn , ldb_ctx , & dn ) ) {
2010-06-19 00:04:07 +04:00
talloc_free ( mem_ctx ) ;
return NULL ;
}
ret = ldb_build_del_req ( & req , ldb_ctx , mem_ctx , dn , parsed_controls ,
NULL , ldb_op_default_callback , NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
PyErr_SetString ( PyExc_TypeError , " failed to build request " ) ;
2009-11-15 16:23:32 +03:00
talloc_free ( mem_ctx ) ;
2008-12-19 04:22:07 +03:00
return NULL ;
2009-11-15 16:23:32 +03:00
}
2008-12-19 04:22:07 +03:00
2010-06-19 00:04:07 +04:00
/* do request and autostart a transaction */
/* Then let's LDB handle the message error in case of pb as they are meaningful */
ret = ldb_transaction_start ( ldb_ctx ) ;
if ( ret ! = LDB_SUCCESS ) {
talloc_free ( mem_ctx ) ;
2012-03-02 00:26:27 +04:00
PyErr_SetLdbError ( PyExc_LdbError , ret , ldb_ctx ) ;
return NULL ;
2010-06-19 00:04:07 +04:00
}
ret = ldb_request ( ldb_ctx , req ) ;
if ( ret = = LDB_SUCCESS ) {
ret = ldb_wait ( req - > handle , LDB_WAIT_ALL ) ;
}
if ( ret = = LDB_SUCCESS ) {
ret = ldb_transaction_commit ( ldb_ctx ) ;
} else {
ldb_transaction_cancel ( ldb_ctx ) ;
}
2009-11-15 16:23:32 +03:00
talloc_free ( mem_ctx ) ;
2010-06-19 00:04:07 +04:00
PyErr_LDB_ERROR_IS_ERR_RAISE ( PyExc_LdbError , ret , ldb_ctx ) ;
2008-12-19 04:22:07 +03:00
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 04:22:07 +03:00
}
2011-06-14 10:41:35 +04:00
static PyObject * py_ldb_rename ( PyLdbObject * self , PyObject * args , PyObject * kwargs )
2008-12-19 04:22:07 +03:00
{
PyObject * py_dn1 , * py_dn2 ;
struct ldb_dn * dn1 , * dn2 ;
int ret ;
2009-06-17 22:43:25 +04:00
TALLOC_CTX * mem_ctx ;
2010-09-05 02:57:16 +04:00
PyObject * py_controls = Py_None ;
struct ldb_control * * parsed_controls ;
struct ldb_context * ldb_ctx ;
struct ldb_request * req ;
2011-06-14 10:41:35 +04:00
const char * const kwnames [ ] = { " dn1 " , " dn2 " , " controls " , NULL } ;
2010-06-20 20:06:54 +04:00
2018-04-20 07:23:42 +03:00
ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2010-09-05 02:57:16 +04:00
2011-06-14 10:41:35 +04:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " OO|O " ,
discard_const_p ( char * , kwnames ) ,
& py_dn1 , & py_dn2 , & py_controls ) )
2008-12-19 04:22:07 +03:00
return NULL ;
2010-09-05 02:57:16 +04:00
2009-06-17 22:43:25 +04:00
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2010-06-20 20:06:54 +04:00
2010-09-05 02:57:16 +04:00
if ( py_controls = = Py_None ) {
parsed_controls = NULL ;
} else {
2015-06-09 18:44:40 +03:00
const char * * controls = PyList_AsStrList ( mem_ctx , py_controls , " controls " ) ;
2015-03-04 00:29:13 +03:00
if ( controls = = NULL ) {
talloc_free ( mem_ctx ) ;
return NULL ;
}
2010-09-05 02:57:16 +04:00
parsed_controls = ldb_parse_control_strings ( ldb_ctx , mem_ctx , controls ) ;
2023-01-17 02:33:17 +03:00
if ( controls [ 0 ] ! = NULL & & parsed_controls = = NULL ) {
talloc_free ( mem_ctx ) ;
PyErr_SetLdbError ( PyExc_LdbError , LDB_ERR_OPERATIONS_ERROR , ldb_ctx ) ;
return NULL ;
}
2010-09-05 02:57:16 +04:00
talloc_free ( controls ) ;
}
2011-09-13 17:01:51 +04:00
if ( ! pyldb_Object_AsDn ( mem_ctx , py_dn1 , ldb_ctx , & dn1 ) ) {
2009-06-17 22:43:25 +04:00
talloc_free ( mem_ctx ) ;
2008-12-19 19:08:35 +03:00
return NULL ;
2009-06-17 22:43:25 +04:00
}
2008-12-19 19:08:35 +03:00
2011-09-13 17:01:51 +04:00
if ( ! pyldb_Object_AsDn ( mem_ctx , py_dn2 , ldb_ctx , & dn2 ) ) {
2009-06-17 22:43:25 +04:00
talloc_free ( mem_ctx ) ;
2008-12-19 19:08:35 +03:00
return NULL ;
2009-06-17 22:43:25 +04:00
}
2008-12-19 04:22:07 +03:00
2010-09-05 02:57:16 +04:00
ret = ldb_build_rename_req ( & req , ldb_ctx , mem_ctx , dn1 , dn2 , parsed_controls ,
NULL , ldb_op_default_callback , NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
PyErr_SetString ( PyExc_TypeError , " failed to build request " ) ;
talloc_free ( mem_ctx ) ;
return NULL ;
}
/* do request and autostart a transaction */
/* Then let's LDB handle the message error in case of pb as they are meaningful */
ret = ldb_transaction_start ( ldb_ctx ) ;
if ( ret ! = LDB_SUCCESS ) {
talloc_free ( mem_ctx ) ;
2012-03-02 00:26:27 +04:00
PyErr_SetLdbError ( PyExc_LdbError , ret , ldb_ctx ) ;
return NULL ;
2010-09-05 02:57:16 +04:00
}
ret = ldb_request ( ldb_ctx , req ) ;
if ( ret = = LDB_SUCCESS ) {
ret = ldb_wait ( req - > handle , LDB_WAIT_ALL ) ;
}
if ( ret = = LDB_SUCCESS ) {
ret = ldb_transaction_commit ( ldb_ctx ) ;
} else {
ldb_transaction_cancel ( ldb_ctx ) ;
}
2009-06-17 22:43:25 +04:00
talloc_free ( mem_ctx ) ;
2010-09-05 02:57:16 +04:00
PyErr_LDB_ERROR_IS_ERR_RAISE ( PyExc_LdbError , ret , ldb_ctx ) ;
2008-12-19 04:22:07 +03:00
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 04:22:07 +03:00
}
static PyObject * py_ldb_schema_attribute_remove ( PyLdbObject * self , PyObject * args )
{
char * name ;
if ( ! PyArg_ParseTuple ( args , " s " , & name ) )
return NULL ;
2018-04-20 07:23:42 +03:00
ldb_schema_attribute_remove ( pyldb_Ldb_AS_LDBCONTEXT ( self ) , name ) ;
2008-12-19 04:22:07 +03:00
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 04:22:07 +03:00
}
static PyObject * py_ldb_schema_attribute_add ( PyLdbObject * self , PyObject * args )
{
char * attribute , * syntax ;
unsigned int flags ;
int ret ;
2012-03-02 06:46:13 +04:00
struct ldb_context * ldb_ctx ;
2008-12-19 04:22:07 +03:00
if ( ! PyArg_ParseTuple ( args , " sIs " , & attribute , & flags , & syntax ) )
return NULL ;
2018-04-20 07:23:42 +03:00
ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2012-03-02 06:46:13 +04:00
ret = ldb_schema_attribute_add ( ldb_ctx , attribute , flags , syntax ) ;
2008-12-19 04:22:07 +03:00
2012-03-02 06:46:13 +04:00
PyErr_LDB_ERROR_IS_ERR_RAISE ( PyExc_LdbError , ret , ldb_ctx ) ;
2008-12-19 04:22:07 +03:00
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 04:22:07 +03:00
}
2023-11-08 00:43:38 +03:00
static PyObject * ldb_ldif_to_pyobject ( PyLdbObject * pyldb , struct ldb_ldif * ldif )
2008-12-19 04:22:07 +03:00
{
2023-03-13 16:35:20 +03:00
PyObject * obj = NULL ;
PyObject * result = NULL ;
2023-11-08 00:43:38 +03:00
struct ldb_context * ldb = pyldb - > ldb_ctx ;
2023-03-13 16:35:20 +03:00
2008-12-19 04:22:07 +03:00
if ( ldif = = NULL ) {
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 04:22:07 +03:00
}
2023-03-13 16:35:20 +03:00
switch ( ldif - > changetype ) {
case LDB_CHANGETYPE_NONE :
case LDB_CHANGETYPE_ADD :
2023-11-08 00:43:38 +03:00
obj = PyLdbMessage_FromMessage ( ldif - > msg , pyldb ) ;
2023-03-13 16:35:20 +03:00
break ;
case LDB_CHANGETYPE_MODIFY :
2023-11-08 00:43:38 +03:00
obj = PyLdbMessage_FromMessage ( ldif - > msg , pyldb ) ;
2023-03-13 16:35:20 +03:00
break ;
2023-03-13 16:55:12 +03:00
case LDB_CHANGETYPE_DELETE :
if ( ldif - > msg - > num_elements ! = 0 ) {
PyErr_Format ( PyExc_ValueError ,
" CHANGETYPE(DELETE) with num_elements=%u " ,
ldif - > msg - > num_elements ) ;
return NULL ;
}
2023-11-08 00:43:38 +03:00
obj = pyldb_Dn_FromDn ( ldif - > msg - > dn , pyldb ) ;
2023-03-13 16:55:12 +03:00
break ;
2023-03-13 16:58:29 +03:00
case LDB_CHANGETYPE_MODRDN : {
struct ldb_dn * olddn = NULL ;
PyObject * olddn_obj = NULL ;
bool deleteoldrdn = false ;
PyObject * deleteoldrdn_obj = NULL ;
struct ldb_dn * newdn = NULL ;
PyObject * newdn_obj = NULL ;
int ret ;
ret = ldb_ldif_parse_modrdn ( ldb ,
ldif ,
ldif ,
& olddn ,
NULL ,
& deleteoldrdn ,
NULL ,
& newdn ) ;
if ( ret ! = LDB_SUCCESS ) {
PyErr_Format ( PyExc_ValueError ,
" ldb_ldif_parse_modrdn() failed " ) ;
return NULL ;
}
2023-11-08 00:43:38 +03:00
olddn_obj = pyldb_Dn_FromDn ( olddn , pyldb ) ;
2023-03-13 16:58:29 +03:00
if ( olddn_obj = = NULL ) {
return NULL ;
}
if ( deleteoldrdn ) {
deleteoldrdn_obj = Py_True ;
} else {
deleteoldrdn_obj = Py_False ;
}
2023-11-08 00:43:38 +03:00
newdn_obj = pyldb_Dn_FromDn ( newdn , pyldb ) ;
2023-03-25 18:34:57 +03:00
if ( newdn_obj = = NULL ) {
2023-03-13 16:58:29 +03:00
deleteoldrdn_obj = NULL ;
Py_CLEAR ( olddn_obj ) ;
return NULL ;
}
obj = Py_BuildValue ( discard_const_p ( char , " {s:O,s:O,s:O} " ) ,
" olddn " , olddn_obj ,
" deleteoldrdn " , deleteoldrdn_obj ,
" newdn " , newdn_obj ) ;
Py_CLEAR ( olddn_obj ) ;
deleteoldrdn_obj = NULL ;
Py_CLEAR ( newdn_obj ) ;
}
break ;
2023-03-13 16:35:20 +03:00
default :
PyErr_Format ( PyExc_NotImplementedError ,
" Unsupported LDB_CHANGETYPE(%u) " ,
ldif - > changetype ) ;
return NULL ;
}
if ( obj = = NULL ) {
return NULL ;
}
/* We don't want this being attached * to the 'ldb' any more */
result = Py_BuildValue ( discard_const_p ( char , " (iO) " ) ,
ldif - > changetype ,
obj ) ;
Py_CLEAR ( obj ) ;
return result ;
2008-12-19 04:22:07 +03:00
}
2010-11-15 05:20:31 +03:00
static PyObject * py_ldb_write_ldif ( PyLdbObject * self , PyObject * args )
2009-08-26 09:59:00 +04:00
{
int changetype ;
PyObject * py_msg ;
struct ldb_ldif ldif ;
PyObject * ret ;
char * string ;
TALLOC_CTX * mem_ctx ;
if ( ! PyArg_ParseTuple ( args , " Oi " , & py_msg , & changetype ) )
return NULL ;
2024-03-13 07:28:07 +03:00
if ( ! pyldb_Message_Check ( py_msg ) ) {
2009-08-26 09:59:00 +04:00
PyErr_SetString ( PyExc_TypeError , " Expected Ldb Message for msg " ) ;
return NULL ;
}
2011-08-07 19:08:56 +04:00
ldif . msg = pyldb_Message_AsMessage ( py_msg ) ;
2009-08-26 09:59:00 +04:00
ldif . changetype = changetype ;
mem_ctx = talloc_new ( NULL ) ;
2023-08-25 05:22:15 +03:00
if ( mem_ctx = = NULL ) {
return PyErr_NoMemory ( ) ;
}
2009-08-26 09:59:00 +04:00
2018-04-20 07:23:42 +03:00
string = ldb_ldif_write_string ( pyldb_Ldb_AS_LDBCONTEXT ( self ) , mem_ctx , & ldif ) ;
2009-08-26 09:59:00 +04:00
if ( ! string ) {
PyErr_SetString ( PyExc_KeyError , " Failed to generate LDIF " ) ;
2023-08-30 00:47:28 +03:00
talloc_free ( mem_ctx ) ;
2009-08-26 09:59:00 +04:00
return NULL ;
}
2019-06-07 11:45:52 +03:00
ret = PyUnicode_FromString ( string ) ;
2009-08-26 09:59:00 +04:00
talloc_free ( mem_ctx ) ;
return ret ;
}
2008-12-19 04:22:07 +03:00
static PyObject * py_ldb_parse_ldif ( PyLdbObject * self , PyObject * args )
{
2015-03-04 00:29:10 +03:00
PyObject * list , * ret ;
2008-12-19 04:22:07 +03:00
struct ldb_ldif * ldif ;
const char * s ;
2017-12-11 05:57:30 +03:00
struct ldb_dn * last_dn = NULL ;
2008-12-19 04:22:07 +03:00
2009-07-06 03:31:38 +04:00
TALLOC_CTX * mem_ctx ;
2008-12-21 00:21:39 +03:00
if ( ! PyArg_ParseTuple ( args , " s " , & s ) )
2008-12-19 04:22:07 +03:00
return NULL ;
2009-07-06 03:31:38 +04:00
mem_ctx = talloc_new ( NULL ) ;
if ( ! mem_ctx ) {
Py_RETURN_NONE ;
}
2008-12-19 04:22:07 +03:00
list = PyList_New ( 0 ) ;
2023-08-25 05:20:50 +03:00
if ( list = = NULL ) {
talloc_free ( mem_ctx ) ;
return NULL ;
}
2009-07-06 03:31:38 +04:00
while ( s & & * s ! = ' \0 ' ) {
ldif = ldb_ldif_read_string ( self - > ldb_ctx , & s ) ;
talloc_steal ( mem_ctx , ldif ) ;
if ( ldif ) {
2019-01-23 21:43:43 +03:00
int res = 0 ;
2023-11-08 00:43:38 +03:00
PyObject * py_ldif = ldb_ldif_to_pyobject ( self , ldif ) ;
2019-01-23 21:43:43 +03:00
if ( py_ldif = = NULL ) {
Py_CLEAR ( list ) ;
2023-03-13 16:35:20 +03:00
if ( PyErr_Occurred ( ) = = NULL ) {
PyErr_BadArgument ( ) ;
}
2019-01-23 21:43:43 +03:00
talloc_free ( mem_ctx ) ;
return NULL ;
}
res = PyList_Append ( list , py_ldif ) ;
Py_CLEAR ( py_ldif ) ;
if ( res = = - 1 ) {
Py_CLEAR ( list ) ;
talloc_free ( mem_ctx ) ;
return NULL ;
}
2017-12-11 05:57:30 +03:00
last_dn = ldif - > msg - > dn ;
2009-07-06 03:31:38 +04:00
} else {
2017-12-11 05:57:30 +03:00
const char * last_dn_str = NULL ;
const char * err_string = NULL ;
if ( last_dn = = NULL ) {
PyErr_SetString ( PyExc_ValueError ,
" unable to parse LDIF "
" string at first chunk " ) ;
2019-01-23 21:43:43 +03:00
Py_CLEAR ( list ) ;
2017-12-11 05:57:30 +03:00
talloc_free ( mem_ctx ) ;
return NULL ;
}
last_dn_str
= ldb_dn_get_linearized ( last_dn ) ;
err_string
= talloc_asprintf ( mem_ctx ,
" unable to parse ldif "
" string AFTER %s " ,
last_dn_str ) ;
PyErr_SetString ( PyExc_ValueError ,
err_string ) ;
2009-07-06 03:31:38 +04:00
talloc_free ( mem_ctx ) ;
2019-01-23 21:43:43 +03:00
Py_CLEAR ( list ) ;
2009-07-06 03:31:38 +04:00
return NULL ;
}
2008-12-19 04:22:07 +03:00
}
2009-07-06 03:31:38 +04:00
talloc_free ( mem_ctx ) ; /* The pyobject already has a reference to the things it needs */
2015-03-04 00:29:10 +03:00
ret = PyObject_GetIter ( list ) ;
Py_DECREF ( list ) ;
return ret ;
2008-12-19 04:22:07 +03:00
}
2009-08-24 14:11:43 +04:00
static PyObject * py_ldb_msg_diff ( PyLdbObject * self , PyObject * args )
{
2010-07-16 14:40:50 +04:00
int ldb_ret ;
2009-08-24 14:11:43 +04:00
PyObject * py_msg_old ;
PyObject * py_msg_new ;
struct ldb_message * diff ;
2010-07-16 14:40:50 +04:00
struct ldb_context * ldb ;
2009-08-24 14:11:43 +04:00
PyObject * py_ret ;
2021-09-13 02:15:17 +03:00
TALLOC_CTX * mem_ctx = NULL ;
2009-08-24 14:11:43 +04:00
if ( ! PyArg_ParseTuple ( args , " OO " , & py_msg_old , & py_msg_new ) )
return NULL ;
2024-03-13 07:28:07 +03:00
if ( ! pyldb_Message_Check ( py_msg_old ) ) {
2009-08-24 14:11:43 +04:00
PyErr_SetString ( PyExc_TypeError , " Expected Ldb Message for old message " ) ;
return NULL ;
}
2024-03-13 07:28:07 +03:00
if ( ! pyldb_Message_Check ( py_msg_new ) ) {
2009-08-24 14:11:43 +04:00
PyErr_SetString ( PyExc_TypeError , " Expected Ldb Message for new message " ) ;
return NULL ;
}
2021-09-13 02:15:17 +03:00
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2018-04-20 07:23:42 +03:00
ldb = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2021-09-13 02:15:17 +03:00
ldb_ret = ldb_msg_difference ( ldb , mem_ctx ,
2011-08-07 19:08:56 +04:00
pyldb_Message_AsMessage ( py_msg_old ) ,
pyldb_Message_AsMessage ( py_msg_new ) ,
2010-07-16 14:40:50 +04:00
& diff ) ;
if ( ldb_ret ! = LDB_SUCCESS ) {
2021-09-13 02:15:17 +03:00
talloc_free ( mem_ctx ) ;
2009-10-01 16:02:59 +04:00
PyErr_SetString ( PyExc_RuntimeError , " Failed to generate the Ldb Message diff " ) ;
2009-10-01 15:59:02 +04:00
return NULL ;
}
2009-08-24 14:11:43 +04:00
2021-09-13 02:15:17 +03:00
diff = ldb_msg_copy ( mem_ctx , diff ) ;
if ( diff = = NULL ) {
2023-08-30 00:47:28 +03:00
talloc_free ( mem_ctx ) ;
2021-09-13 02:15:17 +03:00
PyErr_NoMemory ( ) ;
return NULL ;
}
2023-11-08 00:43:38 +03:00
py_ret = PyLdbMessage_FromMessage ( diff , self ) ;
2009-08-24 14:11:43 +04:00
2021-09-13 02:15:17 +03:00
talloc_free ( mem_ctx ) ;
2010-07-16 14:40:50 +04:00
2009-08-24 14:11:43 +04:00
return py_ret ;
}
2008-12-19 04:22:07 +03:00
static PyObject * py_ldb_schema_format_value ( PyLdbObject * self , PyObject * args )
{
const struct ldb_schema_attribute * a ;
struct ldb_val old_val ;
struct ldb_val new_val ;
TALLOC_CTX * mem_ctx ;
PyObject * ret ;
char * element_name ;
PyObject * val ;
2015-06-09 18:44:40 +03:00
Py_ssize_t size ;
int result ;
2008-12-19 04:22:07 +03:00
if ( ! PyArg_ParseTuple ( args , " sO " , & element_name , & val ) )
return NULL ;
2009-05-31 18:19:11 +04:00
2015-06-09 18:44:40 +03:00
result = PyBytes_AsStringAndSize ( val , ( char * * ) & old_val . data , & size ) ;
old_val . length = size ;
2009-05-31 18:19:11 +04:00
2015-06-09 18:44:40 +03:00
if ( result ! = 0 ) {
2014-11-09 06:28:47 +03:00
PyErr_SetString ( PyExc_RuntimeError , " Failed to convert passed value to String " ) ;
return NULL ;
}
2018-04-20 07:23:42 +03:00
a = ldb_schema_attribute_by_name ( pyldb_Ldb_AS_LDBCONTEXT ( self ) , element_name ) ;
2008-12-19 04:22:07 +03:00
if ( a = = NULL ) {
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 04:22:07 +03:00
}
2009-05-31 18:19:11 +04:00
2014-11-09 06:31:36 +03:00
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2018-04-20 07:23:42 +03:00
if ( a - > syntax - > ldif_write_fn ( pyldb_Ldb_AS_LDBCONTEXT ( self ) , mem_ctx , & old_val , & new_val ) ! = 0 ) {
2008-12-19 04:22:07 +03:00
talloc_free ( mem_ctx ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 04:22:07 +03:00
}
2015-06-09 18:44:40 +03:00
ret = PyBytes_FromStringAndSize ( ( const char * ) new_val . data , new_val . length ) ;
2008-12-19 04:22:07 +03:00
talloc_free ( mem_ctx ) ;
return ret ;
}
2008-12-19 16:41:44 +03:00
static PyObject * py_ldb_search ( PyLdbObject * self , PyObject * args , PyObject * kwargs )
{
PyObject * py_base = Py_None ;
2009-10-27 21:07:53 +03:00
int scope = LDB_SCOPE_DEFAULT ;
2008-12-19 16:41:44 +03:00
char * expr = NULL ;
PyObject * py_attrs = Py_None ;
PyObject * py_controls = Py_None ;
2009-02-05 13:04:28 +03:00
const char * const kwnames [ ] = { " base " , " scope " , " expression " , " attrs " , " controls " , NULL } ;
2008-12-19 16:41:44 +03:00
int ret ;
struct ldb_result * res ;
struct ldb_request * req ;
const char * * attrs ;
struct ldb_context * ldb_ctx ;
struct ldb_control * * parsed_controls ;
struct ldb_dn * base ;
2009-06-17 20:26:40 +04:00
PyObject * py_ret ;
2010-06-20 20:20:00 +04:00
TALLOC_CTX * mem_ctx ;
2008-12-19 16:41:44 +03:00
2009-10-27 21:11:15 +03:00
/* type "int" rather than "enum" for "scope" is intentional */
2009-02-05 13:04:28 +03:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " |OizOO " ,
discard_const_p ( char * , kwnames ) ,
& py_base , & scope , & expr , & py_attrs , & py_controls ) )
2008-12-19 16:41:44 +03:00
return NULL ;
2010-06-20 20:20:00 +04:00
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2018-04-20 07:23:42 +03:00
ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2008-12-19 16:41:44 +03:00
if ( py_attrs = = Py_None ) {
attrs = NULL ;
} else {
2015-06-09 18:44:40 +03:00
attrs = PyList_AsStrList ( mem_ctx , py_attrs , " attrs " ) ;
2010-06-20 20:20:00 +04:00
if ( attrs = = NULL ) {
talloc_free ( mem_ctx ) ;
2008-12-19 16:41:44 +03:00
return NULL ;
2010-06-20 20:20:00 +04:00
}
2008-12-19 16:41:44 +03:00
}
if ( py_base = = Py_None ) {
base = ldb_get_default_basedn ( ldb_ctx ) ;
} else {
2016-01-22 02:05:09 +03:00
if ( ! pyldb_Object_AsDn ( mem_ctx , py_base , ldb_ctx , & base ) ) {
2016-01-05 07:59:32 +03:00
talloc_free ( mem_ctx ) ;
2008-12-19 16:41:44 +03:00
return NULL ;
2009-06-17 20:36:16 +04:00
}
2008-12-19 16:41:44 +03:00
}
if ( py_controls = = Py_None ) {
parsed_controls = NULL ;
} else {
2015-06-09 18:44:40 +03:00
const char * * controls = PyList_AsStrList ( mem_ctx , py_controls , " controls " ) ;
2015-03-04 00:29:13 +03:00
if ( controls = = NULL ) {
talloc_free ( mem_ctx ) ;
return NULL ;
}
2010-06-20 20:20:00 +04:00
parsed_controls = ldb_parse_control_strings ( ldb_ctx , mem_ctx , controls ) ;
2023-01-17 02:33:17 +03:00
if ( controls [ 0 ] ! = NULL & & parsed_controls = = NULL ) {
talloc_free ( mem_ctx ) ;
PyErr_SetLdbError ( PyExc_LdbError , LDB_ERR_OPERATIONS_ERROR , ldb_ctx ) ;
return NULL ;
}
2008-12-19 16:41:44 +03:00
talloc_free ( controls ) ;
}
2010-06-20 20:20:00 +04:00
res = talloc_zero ( mem_ctx , struct ldb_result ) ;
2008-12-19 19:08:35 +03:00
if ( res = = NULL ) {
2008-12-19 16:41:44 +03:00
PyErr_NoMemory ( ) ;
2010-06-20 20:20:00 +04:00
talloc_free ( mem_ctx ) ;
2008-12-19 16:41:44 +03:00
return NULL ;
}
2010-06-20 20:20:00 +04:00
ret = ldb_build_search_req ( & req , ldb_ctx , mem_ctx ,
2008-12-19 16:41:44 +03:00
base ,
scope ,
expr ,
attrs ,
parsed_controls ,
res ,
ldb_search_default_callback ,
NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
2010-06-20 20:20:00 +04:00
talloc_free ( mem_ctx ) ;
2012-03-02 00:26:27 +04:00
PyErr_SetLdbError ( PyExc_LdbError , ret , ldb_ctx ) ;
2008-12-19 16:41:44 +03:00
return NULL ;
}
2010-10-04 00:43:33 +04:00
talloc_steal ( req , attrs ) ;
2008-12-19 16:41:44 +03:00
ret = ldb_request ( ldb_ctx , req ) ;
2009-05-31 18:19:11 +04:00
2008-12-19 16:41:44 +03:00
if ( ret = = LDB_SUCCESS ) {
ret = ldb_wait ( req - > handle , LDB_WAIT_ALL ) ;
}
2009-01-07 08:29:23 +03:00
if ( ret ! = LDB_SUCCESS ) {
2010-06-20 20:20:00 +04:00
talloc_free ( mem_ctx ) ;
2012-03-02 00:26:27 +04:00
PyErr_SetLdbError ( PyExc_LdbError , ret , ldb_ctx ) ;
2009-01-07 08:29:23 +03:00
return NULL ;
}
2023-11-08 00:43:38 +03:00
py_ret = PyLdbResult_FromResult ( res , self ) ;
2009-06-17 20:26:40 +04:00
2010-06-20 20:20:00 +04:00
talloc_free ( mem_ctx ) ;
2009-06-17 20:26:40 +04:00
return py_ret ;
2008-12-19 16:41:44 +03:00
}
2016-01-22 02:06:45 +03:00
static int py_ldb_search_iterator_reply_destructor ( struct py_ldb_search_iterator_reply * reply )
{
if ( reply - > py_iter ! = NULL ) {
DLIST_REMOVE ( reply - > py_iter - > state . next , reply ) ;
if ( reply - > py_iter - > state . result = = reply ) {
reply - > py_iter - > state . result = NULL ;
}
reply - > py_iter = NULL ;
}
2023-04-24 01:42:39 +03:00
Py_CLEAR ( reply - > obj ) ;
2016-01-22 02:06:45 +03:00
return 0 ;
}
static int py_ldb_search_iterator_callback ( struct ldb_request * req ,
struct ldb_reply * ares )
{
PyLdbSearchIteratorObject * py_iter = ( PyLdbSearchIteratorObject * ) req - > context ;
struct ldb_result result = { . msgs = NULL } ;
struct py_ldb_search_iterator_reply * reply = NULL ;
if ( ares = = NULL ) {
return ldb_request_done ( req , LDB_ERR_OPERATIONS_ERROR ) ;
}
if ( ares - > error ! = LDB_SUCCESS ) {
int ret = ares - > error ;
TALLOC_FREE ( ares ) ;
return ldb_request_done ( req , ret ) ;
}
reply = talloc_zero ( py_iter - > mem_ctx ,
struct py_ldb_search_iterator_reply ) ;
if ( reply = = NULL ) {
TALLOC_FREE ( ares ) ;
return ldb_request_done ( req , LDB_ERR_OPERATIONS_ERROR ) ;
}
reply - > py_iter = py_iter ;
talloc_set_destructor ( reply , py_ldb_search_iterator_reply_destructor ) ;
switch ( ares - > type ) {
case LDB_REPLY_ENTRY :
2023-11-08 00:43:38 +03:00
reply - > obj = PyLdbMessage_FromMessage ( ares - > message , py_iter - > ldb ) ;
2016-01-22 02:06:45 +03:00
if ( reply - > obj = = NULL ) {
TALLOC_FREE ( ares ) ;
return ldb_request_done ( req , LDB_ERR_OPERATIONS_ERROR ) ;
}
DLIST_ADD_END ( py_iter - > state . next , reply ) ;
TALLOC_FREE ( ares ) ;
return LDB_SUCCESS ;
case LDB_REPLY_REFERRAL :
2019-06-07 11:45:52 +03:00
reply - > obj = PyUnicode_FromString ( ares - > referral ) ;
2016-01-22 02:06:45 +03:00
if ( reply - > obj = = NULL ) {
TALLOC_FREE ( ares ) ;
return ldb_request_done ( req , LDB_ERR_OPERATIONS_ERROR ) ;
}
DLIST_ADD_END ( py_iter - > state . next , reply ) ;
TALLOC_FREE ( ares ) ;
return LDB_SUCCESS ;
case LDB_REPLY_DONE :
result = ( struct ldb_result ) { . controls = ares - > controls } ;
2023-11-08 00:43:38 +03:00
reply - > obj = PyLdbResult_FromResult ( & result , py_iter - > ldb ) ;
2016-01-22 02:06:45 +03:00
if ( reply - > obj = = NULL ) {
TALLOC_FREE ( ares ) ;
return ldb_request_done ( req , LDB_ERR_OPERATIONS_ERROR ) ;
}
py_iter - > state . result = reply ;
TALLOC_FREE ( ares ) ;
return ldb_request_done ( req , LDB_SUCCESS ) ;
}
TALLOC_FREE ( ares ) ;
return ldb_request_done ( req , LDB_ERR_OPERATIONS_ERROR ) ;
}
static PyObject * py_ldb_search_iterator ( PyLdbObject * self , PyObject * args , PyObject * kwargs )
{
PyObject * py_base = Py_None ;
int scope = LDB_SCOPE_DEFAULT ;
int timeout = 0 ;
char * expr = NULL ;
PyObject * py_attrs = Py_None ;
PyObject * py_controls = Py_None ;
const char * const kwnames [ ] = { " base " , " scope " , " expression " , " attrs " , " controls " , " timeout " , NULL } ;
int ret ;
const char * * attrs ;
struct ldb_context * ldb_ctx ;
struct ldb_control * * parsed_controls ;
struct ldb_dn * base ;
PyLdbSearchIteratorObject * py_iter ;
/* type "int" rather than "enum" for "scope" is intentional */
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " |OizOOi " ,
discard_const_p ( char * , kwnames ) ,
& py_base , & scope , & expr , & py_attrs , & py_controls , & timeout ) )
return NULL ;
py_iter = ( PyLdbSearchIteratorObject * ) PyLdbSearchIterator . tp_alloc ( & PyLdbSearchIterator , 0 ) ;
if ( py_iter = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
py_iter - > ldb = self ;
Py_INCREF ( self ) ;
ZERO_STRUCT ( py_iter - > state ) ;
py_iter - > mem_ctx = talloc_new ( NULL ) ;
if ( py_iter - > mem_ctx = = NULL ) {
Py_DECREF ( py_iter ) ;
PyErr_NoMemory ( ) ;
return NULL ;
}
2018-04-20 07:23:42 +03:00
ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2016-01-22 02:06:45 +03:00
if ( py_attrs = = Py_None ) {
attrs = NULL ;
} else {
attrs = PyList_AsStrList ( py_iter - > mem_ctx , py_attrs , " attrs " ) ;
if ( attrs = = NULL ) {
Py_DECREF ( py_iter ) ;
PyErr_NoMemory ( ) ;
return NULL ;
}
}
if ( py_base = = Py_None ) {
base = ldb_get_default_basedn ( ldb_ctx ) ;
} else {
if ( ! pyldb_Object_AsDn ( py_iter - > mem_ctx , py_base , ldb_ctx , & base ) ) {
Py_DECREF ( py_iter ) ;
PyErr_NoMemory ( ) ;
return NULL ;
}
}
if ( py_controls = = Py_None ) {
parsed_controls = NULL ;
} else {
const char * * controls = NULL ;
controls = PyList_AsStrList ( py_iter - > mem_ctx ,
py_controls , " controls " ) ;
if ( controls = = NULL ) {
Py_DECREF ( py_iter ) ;
PyErr_NoMemory ( ) ;
return NULL ;
}
parsed_controls = ldb_parse_control_strings ( ldb_ctx ,
py_iter - > mem_ctx ,
controls ) ;
if ( controls [ 0 ] ! = NULL & & parsed_controls = = NULL ) {
Py_DECREF ( py_iter ) ;
2023-01-17 02:33:17 +03:00
PyErr_SetLdbError ( PyExc_LdbError , LDB_ERR_OPERATIONS_ERROR , ldb_ctx ) ;
2016-01-22 02:06:45 +03:00
return NULL ;
}
talloc_free ( controls ) ;
}
ret = ldb_build_search_req ( & py_iter - > state . req ,
ldb_ctx ,
py_iter - > mem_ctx ,
base ,
scope ,
expr ,
attrs ,
parsed_controls ,
py_iter ,
py_ldb_search_iterator_callback ,
NULL ) ;
if ( ret ! = LDB_SUCCESS ) {
Py_DECREF ( py_iter ) ;
PyErr_SetLdbError ( PyExc_LdbError , ret , ldb_ctx ) ;
return NULL ;
}
ldb_set_timeout ( ldb_ctx , py_iter - > state . req , timeout ) ;
ret = ldb_request ( ldb_ctx , py_iter - > state . req ) ;
if ( ret ! = LDB_SUCCESS ) {
Py_DECREF ( py_iter ) ;
PyErr_SetLdbError ( PyExc_LdbError , ret , ldb_ctx ) ;
return NULL ;
}
return ( PyObject * ) py_iter ;
}
2008-12-19 16:41:44 +03:00
static PyObject * py_ldb_get_opaque ( PyLdbObject * self , PyObject * args )
{
char * name ;
void * data ;
2008-12-19 19:08:35 +03:00
if ( ! PyArg_ParseTuple ( args , " s " , & name ) )
2008-12-19 16:41:44 +03:00
return NULL ;
2018-04-20 07:23:42 +03:00
data = ldb_get_opaque ( pyldb_Ldb_AS_LDBCONTEXT ( self ) , name ) ;
2008-12-19 16:41:44 +03:00
2008-12-21 06:36:16 +03:00
if ( data = = NULL )
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-21 06:36:16 +03:00
2024-03-01 06:23:58 +03:00
if ( data = = ( void * ) 1 ) {
/*
* This value is sometimes used to indicate that a opaque is
* set .
*/
Py_RETURN_TRUE ;
}
2008-12-19 16:41:44 +03:00
2024-03-01 06:23:58 +03:00
{
/*
* Let ’ s hope the opaque data is actually a talloc pointer ,
* otherwise calling this would be Very Bad .
*/
const bool * opaque = talloc_get_type ( data , bool ) ;
if ( opaque ! = NULL ) {
return PyBool_FromLong ( * opaque ) ;
}
}
{
const unsigned long long * opaque = talloc_get_type (
data , unsigned long long ) ;
if ( opaque ! = NULL ) {
return PyLong_FromUnsignedLongLong ( * opaque ) ;
}
}
{
const char * opaque = talloc_get_type ( data , char ) ;
if ( opaque ! = NULL ) {
return PyUnicode_FromString ( opaque ) ;
}
}
PyErr_SetString ( PyExc_ValueError , " Unsupported type for opaque " ) ;
return NULL ;
2008-12-19 16:41:44 +03:00
}
static PyObject * py_ldb_set_opaque ( PyLdbObject * self , PyObject * args )
{
char * name ;
PyObject * data ;
2024-03-01 06:23:53 +03:00
void * value = NULL ;
int ret ;
2008-12-19 16:41:44 +03:00
2008-12-19 19:08:35 +03:00
if ( ! PyArg_ParseTuple ( args , " sO " , & name , & data ) )
2008-12-19 16:41:44 +03:00
return NULL ;
2024-03-01 06:23:53 +03:00
if ( data = = Py_None ) {
value = NULL ;
} else if ( PyBool_Check ( data ) ) {
bool * opaque = NULL ;
bool b ;
{
const int is_true = PyObject_IsTrue ( data ) ;
if ( is_true = = - 1 ) {
return NULL ;
}
b = is_true ;
}
2024-03-04 03:02:54 +03:00
opaque = talloc ( self - > ldb_ctx , bool ) ;
2024-03-01 06:23:53 +03:00
if ( opaque = = NULL ) {
return PyErr_NoMemory ( ) ;
}
* opaque = b ;
value = opaque ;
} else if ( PyLong_Check ( data ) ) {
unsigned long long * opaque = NULL ;
const unsigned long long n = PyLong_AsUnsignedLongLong ( data ) ;
if ( n = = - 1 & & PyErr_Occurred ( ) ) {
return NULL ;
}
2024-03-04 03:02:54 +03:00
opaque = talloc ( self - > ldb_ctx , unsigned long long ) ;
2024-03-01 06:23:53 +03:00
if ( opaque = = NULL ) {
return PyErr_NoMemory ( ) ;
}
* opaque = n ;
value = opaque ;
} else if ( PyUnicode_Check ( data ) ) {
char * opaque = NULL ;
const char * s = PyUnicode_AsUTF8 ( data ) ;
if ( s = = NULL ) {
return NULL ;
}
2024-03-04 03:02:54 +03:00
opaque = talloc_strdup ( self - > ldb_ctx , s ) ;
2024-03-01 06:23:53 +03:00
if ( opaque = = NULL ) {
return PyErr_NoMemory ( ) ;
}
/*
* Assign the right type to the talloc pointer , so that
* py_ldb_get_opaque ( ) can recognize it .
*/
talloc_set_name_const ( opaque , " char " ) ;
2008-12-19 16:41:44 +03:00
2024-03-01 06:23:53 +03:00
value = opaque ;
} else {
PyErr_SetString ( PyExc_ValueError ,
" Unsupported type for opaque " ) ;
return NULL ;
}
ret = ldb_set_opaque ( pyldb_Ldb_AS_LDBCONTEXT ( self ) , name , value ) ;
if ( ret ) {
PyErr_SetLdbError ( PyExc_LdbError ,
ret ,
pyldb_Ldb_AS_LDBCONTEXT ( self ) ) ;
return NULL ;
}
2008-12-19 16:41:44 +03:00
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 16:41:44 +03:00
}
2010-06-21 10:55:18 +04:00
static PyObject * py_ldb_sequence_number ( PyLdbObject * self , PyObject * args )
{
2018-04-20 07:23:42 +03:00
struct ldb_context * ldb = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2010-06-21 10:55:18 +04:00
int type , ret ;
uint64_t value ;
if ( ! PyArg_ParseTuple ( args , " i " , & type ) )
return NULL ;
/* FIXME: More interpretation */
ret = ldb_sequence_number ( ldb , type , & value ) ;
2012-03-02 00:26:27 +04:00
PyErr_LDB_ERROR_IS_ERR_RAISE ( PyExc_LdbError , ret , ldb ) ;
2010-06-21 10:55:18 +04:00
return PyLong_FromLongLong ( value ) ;
}
2015-08-21 11:22:22 +03:00
2023-03-24 13:49:02 +03:00
static PyObject * py_ldb_whoami ( PyLdbObject * self , PyObject * args )
{
struct ldb_context * ldb = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
struct ldb_result * res = NULL ;
struct ldb_extended * ext_res = NULL ;
size_t len = 0 ;
int ret ;
ret = ldb_extended ( ldb , LDB_EXTENDED_WHOAMI_OID , NULL , & res ) ;
PyErr_LDB_ERROR_IS_ERR_RAISE ( PyExc_LdbError , ret , ldb ) ;
ext_res = res - > extended ;
if ( ext_res = = NULL ) {
PyErr_SetString ( PyExc_TypeError , " Got no exop reply " ) ;
return NULL ;
}
if ( strcmp ( ext_res - > oid , LDB_EXTENDED_WHOAMI_OID ) ! = 0 ) {
PyErr_SetString ( PyExc_TypeError , " Got wrong reply OID " ) ;
return NULL ;
}
len = talloc_get_size ( ext_res - > data ) ;
if ( len = = 0 ) {
Py_RETURN_NONE ;
}
return PyUnicode_FromStringAndSize ( ext_res - > data , len ) ;
}
2023-12-06 01:18:27 +03:00
static PyObject * py_ldb_disconnect ( PyLdbObject * self , PyObject * args )
{
size_t ref_count ;
void * parent = NULL ;
TALLOC_CTX * mem_ctx = NULL ;
struct ldb_context * ldb = NULL ;
if ( self - > ldb_ctx = = NULL ) {
/* It is hard to see how we'd get here. */
PyErr_SetLdbError ( PyExc_LdbError , LDB_ERR_OPERATIONS_ERROR , NULL ) ;
return NULL ;
}
ref_count = talloc_reference_count ( self - > ldb_ctx ) ;
if ( ref_count ! = 0 ) {
PyErr_SetString ( PyExc_RuntimeError ,
" ldb.disconnect() not possible as "
" object still has C (or second "
" python object) references " ) ;
return NULL ;
}
parent = talloc_parent ( self - > ldb_ctx ) ;
if ( parent ! = self - > mem_ctx ) {
PyErr_SetString ( PyExc_RuntimeError ,
" ldb.disconnect() not possible as "
" object is not talloc owned by this "
" python object! " ) ;
return NULL ;
}
/*
* This recapitulates py_ldb_new ( ) , cleaning out all the
* connections and state , but leaving the python object in a
* workable condition .
*/
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
return PyErr_NoMemory ( ) ;
}
ldb = ldb_init ( mem_ctx , NULL ) ;
if ( ldb = = NULL ) {
talloc_free ( mem_ctx ) ;
PyErr_NoMemory ( ) ;
return NULL ;
}
/*
* Notice we allocate the new mem_ctx and ldb before freeing
* the old one . This has two purposes : 1 , the python object
* will still be consistent if an exception happens , and 2 , it
* ensures the new ldb can ' t have the same memory address as
* the old one , and ldb address equality is a guard we use in
* Python DNs and such . Repeated calls to disconnect ( ) * can * make
* this happen , so we don ' t advise doing that .
*/
TALLOC_FREE ( self - > mem_ctx ) ;
self - > mem_ctx = mem_ctx ;
self - > ldb_ctx = ldb ;
Py_RETURN_NONE ;
}
2015-08-21 11:22:22 +03:00
static const struct ldb_dn_extended_syntax test_dn_syntax = {
. name = " TEST " ,
. read_fn = ldb_handler_copy ,
. write_clear_fn = ldb_handler_copy ,
. write_hex_fn = ldb_handler_copy ,
} ;
2019-05-02 21:51:05 +03:00
static PyObject * py_ldb_register_test_extensions ( PyLdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2015-08-21 11:22:22 +03:00
{
2018-04-20 07:23:42 +03:00
struct ldb_context * ldb = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2015-08-21 11:22:22 +03:00
int ret ;
ret = ldb_dn_extended_add_syntax ( ldb , LDB_ATTR_FLAG_FIXED , & test_dn_syntax ) ;
PyErr_LDB_ERROR_IS_ERR_RAISE ( PyExc_LdbError , ret , ldb ) ;
Py_RETURN_NONE ;
}
2008-12-19 04:22:07 +03:00
static PyMethodDef py_ldb_methods [ ] = {
2024-02-29 03:07:47 +03:00
{ " set_debug " , ( PyCFunction ) py_ldb_set_debug , METH_VARARGS ,
2008-12-19 04:22:07 +03:00
" S.set_debug(callback) -> None \n "
" Set callback for LDB debug messages. \n "
" The callback should accept a debug level and debug text. " } ,
2024-02-29 03:07:47 +03:00
{ " set_create_perms " , ( PyCFunction ) py_ldb_set_create_perms , METH_VARARGS ,
2008-12-19 04:22:07 +03:00
" S.set_create_perms(mode) -> None \n "
" Set mode to use when creating new LDB files. " } ,
{ " set_modules_dir " , ( PyCFunction ) py_ldb_set_modules_dir , METH_VARARGS ,
" S.set_modules_dir(path) -> None \n "
" Set path LDB should search for modules " } ,
2024-02-29 03:07:47 +03:00
{ " transaction_start " , ( PyCFunction ) py_ldb_transaction_start , METH_NOARGS ,
2008-12-19 04:22:07 +03:00
" S.transaction_start() -> None \n "
" Start a new transaction. " } ,
2009-11-26 07:32:06 +03:00
{ " transaction_prepare_commit " , ( PyCFunction ) py_ldb_transaction_prepare_commit , METH_NOARGS ,
" S.transaction_prepare_commit() -> None \n "
" prepare to commit a new transaction (2-stage commit). " } ,
2024-02-29 03:07:47 +03:00
{ " transaction_commit " , ( PyCFunction ) py_ldb_transaction_commit , METH_NOARGS ,
2008-12-19 04:22:07 +03:00
" S.transaction_commit() -> None \n "
" commit a new transaction. " } ,
2024-02-29 03:07:47 +03:00
{ " transaction_cancel " , ( PyCFunction ) py_ldb_transaction_cancel , METH_NOARGS ,
2008-12-19 04:22:07 +03:00
" S.transaction_cancel() -> None \n "
" cancel a new transaction. " } ,
2024-02-29 03:07:47 +03:00
{ " setup_wellknown_attributes " , ( PyCFunction ) py_ldb_setup_wellknown_attributes , METH_NOARGS ,
2008-12-19 04:22:07 +03:00
NULL } ,
{ " get_root_basedn " , ( PyCFunction ) py_ldb_get_root_basedn , METH_NOARGS ,
NULL } ,
{ " get_schema_basedn " , ( PyCFunction ) py_ldb_get_schema_basedn , METH_NOARGS ,
NULL } ,
{ " get_default_basedn " , ( PyCFunction ) py_ldb_get_default_basedn , METH_NOARGS ,
NULL } ,
{ " get_config_basedn " , ( PyCFunction ) py_ldb_get_config_basedn , METH_NOARGS ,
NULL } ,
2019-05-02 21:51:05 +03:00
{ " connect " , PY_DISCARD_FUNC_SIG ( PyCFunction , py_ldb_connect ) ,
METH_VARARGS | METH_KEYWORDS ,
2008-12-19 16:41:44 +03:00
" S.connect(url, flags=0, options=None) -> None \n "
2008-12-19 04:22:07 +03:00
" Connect to a LDB URL. " } ,
2019-05-02 21:51:05 +03:00
{ " modify " , PY_DISCARD_FUNC_SIG ( PyCFunction , py_ldb_modify ) ,
METH_VARARGS | METH_KEYWORDS ,
2011-06-14 10:39:49 +04:00
" S.modify(message, controls=None, validate=False) -> None \n "
2008-12-19 04:22:07 +03:00
" Modify an entry. " } ,
2019-05-02 21:51:05 +03:00
{ " add " , PY_DISCARD_FUNC_SIG ( PyCFunction , py_ldb_add ) ,
METH_VARARGS | METH_KEYWORDS ,
2011-06-14 10:41:35 +04:00
" S.add(message, controls=None) -> None \n "
2008-12-19 04:22:07 +03:00
" Add an entry. " } ,
2019-05-02 21:51:05 +03:00
{ " delete " , PY_DISCARD_FUNC_SIG ( PyCFunction , py_ldb_delete ) ,
METH_VARARGS | METH_KEYWORDS ,
2011-06-14 10:41:35 +04:00
" S.delete(dn, controls=None) -> None \n "
2008-12-19 04:22:07 +03:00
" Remove an entry. " } ,
2019-05-02 21:51:05 +03:00
{ " rename " , PY_DISCARD_FUNC_SIG ( PyCFunction , py_ldb_rename ) ,
METH_VARARGS | METH_KEYWORDS ,
2011-06-14 10:41:35 +04:00
" S.rename(old_dn, new_dn, controls=None) -> None \n "
2008-12-19 04:22:07 +03:00
" Rename an entry. " } ,
2019-05-02 21:51:05 +03:00
{ " search " , PY_DISCARD_FUNC_SIG ( PyCFunction , py_ldb_search ) ,
METH_VARARGS | METH_KEYWORDS ,
2016-01-22 02:06:04 +03:00
" S.search(base=None, scope=None, expression=None, attrs=None, controls=None) -> result \n "
2008-12-19 16:41:44 +03:00
" Search in a database. \n "
" \n "
" :param base: Optional base DN to search \n "
" :param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE) \n "
" :param expression: Optional search expression \n "
" :param attrs: Attributes to return (defaults to all) \n "
" :param controls: Optional list of controls \n "
2016-01-22 02:06:04 +03:00
" :return: ldb.Result object \n "
2008-12-19 16:41:44 +03:00
} ,
2019-05-02 21:51:05 +03:00
{ " search_iterator " , PY_DISCARD_FUNC_SIG ( PyCFunction ,
py_ldb_search_iterator ) ,
METH_VARARGS | METH_KEYWORDS ,
2016-01-22 02:06:45 +03:00
" S.search_iterator(base=None, scope=None, expression=None, attrs=None, controls=None, timeout=None) -> iterator \n "
" Search in a database. \n "
" \n "
" :param base: Optional base DN to search \n "
" :param scope: Search scope (SCOPE_BASE, SCOPE_ONELEVEL or SCOPE_SUBTREE) \n "
" :param expression: Optional search expression \n "
" :param attrs: Attributes to return (defaults to all) \n "
" :param controls: Optional list of controls \n "
" :param timeout: Optional timeout in seconds (defaults to 300), 0 means the default, -1 no timeout \n "
" :return: ldb.SearchIterator object that provides results when they arrive \n "
} ,
2008-12-19 04:22:07 +03:00
{ " schema_attribute_remove " , ( PyCFunction ) py_ldb_schema_attribute_remove , METH_VARARGS ,
NULL } ,
{ " schema_attribute_add " , ( PyCFunction ) py_ldb_schema_attribute_add , METH_VARARGS ,
NULL } ,
{ " schema_format_value " , ( PyCFunction ) py_ldb_schema_format_value , METH_VARARGS ,
NULL } ,
{ " parse_ldif " , ( PyCFunction ) py_ldb_parse_ldif , METH_VARARGS ,
" S.parse_ldif(ldif) -> iter(messages) \n "
2008-12-21 00:21:39 +03:00
" Parse a string formatted using LDIF. " } ,
2009-08-26 09:59:00 +04:00
{ " write_ldif " , ( PyCFunction ) py_ldb_write_ldif , METH_VARARGS ,
" S.write_ldif(message, changetype) -> ldif \n "
" Print the message as a string formatted using LDIF. " } ,
2009-08-24 14:11:43 +04:00
{ " msg_diff " , ( PyCFunction ) py_ldb_msg_diff , METH_VARARGS ,
" S.msg_diff(Message) -> Message \n "
" Return an LDB Message of the difference between two Message objects. " } ,
2008-12-21 06:36:16 +03:00
{ " get_opaque " , ( PyCFunction ) py_ldb_get_opaque , METH_VARARGS ,
2008-12-21 00:21:39 +03:00
" S.get_opaque(name) -> value \n "
" Get an opaque value set on this LDB connection. \n "
" :note: The returned value may not be useful in Python. "
2008-12-19 16:41:44 +03:00
} ,
2008-12-21 06:36:16 +03:00
{ " set_opaque " , ( PyCFunction ) py_ldb_set_opaque , METH_VARARGS ,
2008-12-19 16:41:44 +03:00
" S.set_opaque(name, value) -> None \n "
" Set an opaque value on this LDB connection. \n "
2008-12-21 00:21:39 +03:00
" :note: Passing incorrect values may cause crashes. " } ,
2010-06-21 10:55:18 +04:00
{ " sequence_number " , ( PyCFunction ) py_ldb_sequence_number , METH_VARARGS ,
" S.sequence_number(type) -> value \n "
" Return the value of the sequence according to the requested type " } ,
2023-03-24 13:49:02 +03:00
{ " whoami " ,
( PyCFunction ) py_ldb_whoami ,
METH_NOARGS ,
2023-12-06 01:18:47 +03:00
" S.whoami() -> value \n "
2023-03-24 13:49:02 +03:00
" Return the RFC4532 whoami string " ,
} ,
2023-12-06 01:18:27 +03:00
{ " disconnect " ,
( PyCFunction ) py_ldb_disconnect ,
METH_NOARGS ,
" S.disconnect() -> None \n "
" Make this Ldb object unusable, disconnect and free the "
" underlying LDB, releasing any file handles and sockets. " ,
} ,
2015-08-21 11:22:22 +03:00
{ " _register_test_extensions " , ( PyCFunction ) py_ldb_register_test_extensions , METH_NOARGS ,
" S._register_test_extensions() -> None \n "
" Register internal extensions used in testing " } ,
2020-05-05 04:47:39 +03:00
{ 0 } ,
2008-12-19 04:22:07 +03:00
} ;
2008-12-19 16:41:44 +03:00
static int py_ldb_contains ( PyLdbObject * self , PyObject * obj )
{
2018-04-20 07:23:42 +03:00
struct ldb_context * ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT ( self ) ;
2008-12-19 19:08:35 +03:00
struct ldb_dn * dn ;
2008-12-19 16:41:44 +03:00
struct ldb_result * result ;
2010-11-06 19:49:18 +03:00
unsigned int count ;
2008-12-19 16:41:44 +03:00
int ret ;
2008-12-19 19:08:35 +03:00
2011-08-07 19:08:56 +04:00
if ( ! pyldb_Object_AsDn ( ldb_ctx , obj , ldb_ctx , & dn ) ) {
2008-12-19 19:08:35 +03:00
return - 1 ;
2010-11-09 01:21:57 +03:00
}
2008-12-19 19:08:35 +03:00
2010-11-06 19:49:18 +03:00
ret = ldb_search ( ldb_ctx , ldb_ctx , & result , dn , LDB_SCOPE_BASE , NULL ,
NULL ) ;
2008-12-19 19:08:35 +03:00
if ( ret ! = LDB_SUCCESS ) {
2009-04-23 03:21:47 +04:00
PyErr_SetLdbError ( PyExc_LdbError , ret , ldb_ctx ) ;
2008-12-19 19:08:35 +03:00
return - 1 ;
}
2008-12-19 16:41:44 +03:00
count = result - > count ;
talloc_free ( result ) ;
2010-11-09 01:21:57 +03:00
if ( count > 1 ) {
PyErr_Format ( PyExc_RuntimeError ,
" Searching for [%s] dn gave %u results! " ,
ldb_dn_get_linearized ( dn ) ,
count ) ;
return - 1 ;
2010-11-06 19:49:18 +03:00
}
2010-11-09 01:21:57 +03:00
return count ;
2008-12-19 16:41:44 +03:00
}
static PySequenceMethods py_ldb_seq = {
. sq_contains = ( objobjproc ) py_ldb_contains ,
} ;
2008-12-23 07:07:29 +03:00
static void py_ldb_dealloc ( PyLdbObject * self )
{
talloc_free ( self - > mem_ctx ) ;
2015-03-04 00:29:07 +03:00
Py_TYPE ( self ) - > tp_free ( self ) ;
2008-12-19 19:08:35 +03:00
}
2010-12-30 21:39:14 +03:00
static PyTypeObject PyLdb = {
2010-04-04 03:48:35 +04:00
. tp_name = " ldb.Ldb " ,
2008-12-19 04:22:07 +03:00
. tp_methods = py_ldb_methods ,
. tp_repr = ( reprfunc ) py_ldb_repr ,
. tp_new = py_ldb_new ,
2008-12-21 01:00:23 +03:00
. tp_init = ( initproc ) py_ldb_init ,
2008-12-23 07:07:29 +03:00
. tp_dealloc = ( destructor ) py_ldb_dealloc ,
2008-12-21 01:00:23 +03:00
. tp_getattro = PyObject_GenericGetAttr ,
2008-12-19 04:22:07 +03:00
. tp_basicsize = sizeof ( PyLdbObject ) ,
. tp_doc = " Connection to a LDB database. " ,
2008-12-19 16:41:44 +03:00
. tp_as_sequence = & py_ldb_seq ,
2008-12-19 19:08:35 +03:00
. tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
2008-12-19 04:22:07 +03:00
} ;
2011-02-07 09:50:36 +03:00
static void py_ldb_result_dealloc ( PyLdbResultObject * self )
{
talloc_free ( self - > mem_ctx ) ;
2023-04-24 01:42:39 +03:00
Py_CLEAR ( self - > msgs ) ;
Py_CLEAR ( self - > referals ) ;
Py_CLEAR ( self - > controls ) ;
2023-11-08 00:43:38 +03:00
Py_DECREF ( self - > pyldb ) ;
2015-03-04 00:29:07 +03:00
Py_TYPE ( self ) - > tp_free ( self ) ;
2011-02-07 09:50:36 +03:00
}
static PyObject * py_ldb_result_get_msgs ( PyLdbResultObject * self , void * closure )
{
Py_INCREF ( self - > msgs ) ;
return self - > msgs ;
}
static PyObject * py_ldb_result_get_controls ( PyLdbResultObject * self , void * closure )
{
Py_INCREF ( self - > controls ) ;
return self - > controls ;
}
static PyObject * py_ldb_result_get_referals ( PyLdbResultObject * self , void * closure )
{
Py_INCREF ( self - > referals ) ;
return self - > referals ;
}
static PyObject * py_ldb_result_get_count ( PyLdbResultObject * self , void * closure )
{
Py_ssize_t size ;
if ( self - > msgs = = NULL ) {
PyErr_SetString ( PyExc_AttributeError , " Count attribute is meaningless in this context " ) ;
return NULL ;
}
size = PyList_Size ( self - > msgs ) ;
2020-03-15 00:36:59 +03:00
return PyLong_FromLong ( size ) ;
2011-02-07 09:50:36 +03:00
}
static PyGetSetDef py_ldb_result_getset [ ] = {
2018-12-13 13:34:37 +03:00
{
. name = discard_const_p ( char , " controls " ) ,
. get = ( getter ) py_ldb_result_get_controls ,
} ,
{
. name = discard_const_p ( char , " msgs " ) ,
. get = ( getter ) py_ldb_result_get_msgs ,
} ,
{
. name = discard_const_p ( char , " referals " ) ,
. get = ( getter ) py_ldb_result_get_referals ,
} ,
{
. name = discard_const_p ( char , " count " ) ,
. get = ( getter ) py_ldb_result_get_count ,
} ,
{ . name = NULL } ,
2011-02-07 09:50:36 +03:00
} ;
static PyObject * py_ldb_result_iter ( PyLdbResultObject * self )
{
return PyObject_GetIter ( self - > msgs ) ;
}
static Py_ssize_t py_ldb_result_len ( PyLdbResultObject * self )
{
return PySequence_Size ( self - > msgs ) ;
}
static PyObject * py_ldb_result_find ( PyLdbResultObject * self , Py_ssize_t idx )
{
return PySequence_GetItem ( self - > msgs , idx ) ;
}
static PySequenceMethods py_ldb_result_seq = {
. sq_length = ( lenfunc ) py_ldb_result_len ,
. sq_item = ( ssizeargfunc ) py_ldb_result_find ,
} ;
static PyObject * py_ldb_result_repr ( PyLdbObject * self )
{
2019-06-07 11:45:52 +03:00
return PyUnicode_FromString ( " <ldb result> " ) ;
2011-02-07 09:50:36 +03:00
}
static PyTypeObject PyLdbResult = {
. tp_name = " ldb.Result " ,
. tp_repr = ( reprfunc ) py_ldb_result_repr ,
. tp_dealloc = ( destructor ) py_ldb_result_dealloc ,
. tp_iter = ( getiterfunc ) py_ldb_result_iter ,
. tp_getset = py_ldb_result_getset ,
. tp_getattro = PyObject_GenericGetAttr ,
. tp_basicsize = sizeof ( PyLdbResultObject ) ,
. tp_as_sequence = & py_ldb_result_seq ,
. tp_doc = " LDB result. " ,
. tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
} ;
2016-01-22 02:06:45 +03:00
static void py_ldb_search_iterator_dealloc ( PyLdbSearchIteratorObject * self )
{
2023-04-24 01:42:39 +03:00
Py_CLEAR ( self - > state . exception ) ;
2016-01-22 02:06:45 +03:00
TALLOC_FREE ( self - > mem_ctx ) ;
ZERO_STRUCT ( self - > state ) ;
2023-04-24 01:42:39 +03:00
Py_CLEAR ( self - > ldb ) ;
2016-01-22 02:06:45 +03:00
Py_TYPE ( self ) - > tp_free ( self ) ;
}
static PyObject * py_ldb_search_iterator_next ( PyLdbSearchIteratorObject * self )
{
PyObject * py_ret = NULL ;
if ( self - > state . req = = NULL ) {
PyErr_SetString ( PyExc_RuntimeError ,
" ldb.SearchIterator request already finished " ) ;
return NULL ;
}
/*
* TODO : do we want a non - blocking mode ?
* In future we may add an optional ' nonblocking '
* argument to search_iterator ( ) .
*
* For now we keep it simple and wait for at
* least one reply .
*/
while ( self - > state . next = = NULL ) {
int ret ;
if ( self - > state . result ! = NULL ) {
/*
* We ( already ) got a final result from the server .
*
* We stop the iteration and let
* py_ldb_search_iterator_result ( ) will deliver
* the result details .
*/
TALLOC_FREE ( self - > state . req ) ;
PyErr_SetNone ( PyExc_StopIteration ) ;
return NULL ;
}
ret = ldb_wait ( self - > state . req - > handle , LDB_WAIT_NONE ) ;
if ( ret ! = LDB_SUCCESS ) {
struct ldb_context * ldb_ctx ;
TALLOC_FREE ( self - > state . req ) ;
2018-04-20 07:23:42 +03:00
ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT ( self - > ldb ) ;
2016-01-22 02:06:45 +03:00
/*
* We stop the iteration and let
* py_ldb_search_iterator_result ( ) will deliver
* the exception .
*/
self - > state . exception = Py_BuildValue ( discard_const_p ( char , " (i,s) " ) ,
ret , ldb_errstring ( ldb_ctx ) ) ;
PyErr_SetNone ( PyExc_StopIteration ) ;
return NULL ;
}
}
py_ret = self - > state . next - > obj ;
self - > state . next - > obj = NULL ;
/* no TALLOC_FREE() as self->state.next is a list */
talloc_free ( self - > state . next ) ;
return py_ret ;
}
2019-05-02 21:51:05 +03:00
static PyObject * py_ldb_search_iterator_result ( PyLdbSearchIteratorObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2016-01-22 02:06:45 +03:00
{
PyObject * py_ret = NULL ;
if ( self - > state . req ! = NULL ) {
PyErr_SetString ( PyExc_RuntimeError ,
" ldb.SearchIterator request running " ) ;
return NULL ;
}
if ( self - > state . next ! = NULL ) {
PyErr_SetString ( PyExc_RuntimeError ,
" ldb.SearchIterator not fully consumed. " ) ;
return NULL ;
}
if ( self - > state . exception ! = NULL ) {
PyErr_SetObject ( PyExc_LdbError , self - > state . exception ) ;
2023-10-25 03:18:34 +03:00
Py_DECREF ( self - > state . exception ) ;
2016-01-22 02:06:45 +03:00
self - > state . exception = NULL ;
return NULL ;
}
if ( self - > state . result = = NULL ) {
PyErr_SetString ( PyExc_RuntimeError ,
" ldb.SearchIterator result already consumed " ) ;
return NULL ;
}
py_ret = self - > state . result - > obj ;
self - > state . result - > obj = NULL ;
TALLOC_FREE ( self - > state . result ) ;
return py_ret ;
}
2019-05-02 21:51:05 +03:00
static PyObject * py_ldb_search_iterator_abandon ( PyLdbSearchIteratorObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2016-01-22 02:06:45 +03:00
{
if ( self - > state . req = = NULL ) {
PyErr_SetString ( PyExc_RuntimeError ,
" ldb.SearchIterator request already finished " ) ;
return NULL ;
}
2023-04-24 01:42:39 +03:00
Py_CLEAR ( self - > state . exception ) ;
2016-01-22 02:06:45 +03:00
TALLOC_FREE ( self - > mem_ctx ) ;
ZERO_STRUCT ( self - > state ) ;
Py_RETURN_NONE ;
}
static PyMethodDef py_ldb_search_iterator_methods [ ] = {
{ " result " , ( PyCFunction ) py_ldb_search_iterator_result , METH_NOARGS ,
" S.result() -> ldb.Result (without msgs and referrals) \n " } ,
{ " abandon " , ( PyCFunction ) py_ldb_search_iterator_abandon , METH_NOARGS ,
" S.abandon() \n " } ,
2020-05-05 04:47:39 +03:00
{ 0 }
2016-01-22 02:06:45 +03:00
} ;
static PyObject * py_ldb_search_iterator_repr ( PyLdbSearchIteratorObject * self )
{
2019-06-07 11:45:52 +03:00
return PyUnicode_FromString ( " <ldb search iterator> " ) ;
2016-01-22 02:06:45 +03:00
}
static PyTypeObject PyLdbSearchIterator = {
. tp_name = " ldb.SearchIterator " ,
. tp_repr = ( reprfunc ) py_ldb_search_iterator_repr ,
. tp_dealloc = ( destructor ) py_ldb_search_iterator_dealloc ,
. tp_iter = PyObject_SelfIter ,
. tp_iternext = ( iternextfunc ) py_ldb_search_iterator_next ,
. tp_methods = py_ldb_search_iterator_methods ,
. tp_basicsize = sizeof ( PyLdbSearchIteratorObject ) ,
. tp_doc = " LDB search_iterator. " ,
. tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE ,
} ;
2009-03-21 03:00:18 +03:00
/**
* Create a ldb_message_element from a Python object .
*
2024-02-29 03:07:47 +03:00
* This will accept any sequence objects that contains strings , or
2009-03-21 03:00:18 +03:00
* a string object .
*
2023-07-07 02:18:49 +03:00
* A reference to set_obj might be borrowed .
2009-03-21 03:00:18 +03:00
*
* @ param mem_ctx Memory context
* @ param set_obj Python object to convert
2023-07-07 02:18:49 +03:00
* @ param flags ldb_message_element flags to set , if a new element is returned
* @ param attr_name Name of the attribute to set , if a new element is returned
2009-03-21 03:00:18 +03:00
* @ return New ldb_message_element , allocated as child of mem_ctx
*/
2010-12-30 21:39:14 +03:00
static struct ldb_message_element * PyObject_AsMessageElement (
TALLOC_CTX * mem_ctx ,
2010-11-06 18:29:06 +03:00
PyObject * set_obj ,
2011-04-10 21:48:07 +04:00
unsigned int flags ,
2010-11-06 18:29:06 +03:00
const char * attr_name )
2008-12-19 04:22:07 +03:00
{
2008-12-21 00:21:39 +03:00
struct ldb_message_element * me ;
2015-06-09 18:44:40 +03:00
const char * msg = NULL ;
Py_ssize_t size ;
int result ;
2008-12-19 19:08:35 +03:00
2011-08-07 19:08:56 +04:00
if ( pyldb_MessageElement_Check ( set_obj ) ) {
2010-07-15 08:00:48 +04:00
PyLdbMessageElementObject * set_obj_as_me = ( PyLdbMessageElementObject * ) set_obj ;
2010-12-30 22:11:59 +03:00
/* We have to talloc_reference() the memory context, not the pointer
* which may not actually be it ' s own context */
2010-07-15 08:00:48 +04:00
if ( talloc_reference ( mem_ctx , set_obj_as_me - > mem_ctx ) ) {
2011-08-07 19:08:56 +04:00
return pyldb_MessageElement_AsMessageElement ( set_obj ) ;
2010-07-15 08:00:48 +04:00
}
return NULL ;
}
2008-12-19 19:08:35 +03:00
me = talloc ( mem_ctx , struct ldb_message_element ) ;
2010-12-30 21:59:01 +03:00
if ( me = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
2008-12-19 04:22:07 +03:00
2009-08-04 01:58:16 +04:00
me - > name = talloc_strdup ( me , attr_name ) ;
2023-08-01 00:48:35 +03:00
if ( me - > name = = NULL ) {
PyErr_NoMemory ( ) ;
talloc_free ( me ) ;
return NULL ;
}
2008-12-21 00:21:39 +03:00
me - > flags = flags ;
2018-04-12 16:46:59 +03:00
if ( PyBytes_Check ( set_obj ) | | PyUnicode_Check ( set_obj ) ) {
2008-12-21 00:21:39 +03:00
me - > num_values = 1 ;
me - > values = talloc_array ( me , struct ldb_val , me - > num_values ) ;
2015-06-09 18:44:40 +03:00
if ( PyBytes_Check ( set_obj ) ) {
char * _msg = NULL ;
result = PyBytes_AsStringAndSize ( set_obj , & _msg , & size ) ;
if ( result ! = 0 ) {
talloc_free ( me ) ;
return NULL ;
}
msg = _msg ;
} else {
2019-06-07 12:44:48 +03:00
msg = PyUnicode_AsUTF8AndSize ( set_obj , & size ) ;
2015-06-09 18:44:40 +03:00
if ( msg = = NULL ) {
talloc_free ( me ) ;
return NULL ;
}
}
me - > values [ 0 ] . data = talloc_memdup ( me ,
( const uint8_t * ) msg ,
size + 1 ) ;
me - > values [ 0 ] . length = size ;
2008-12-21 00:21:39 +03:00
} else if ( PySequence_Check ( set_obj ) ) {
2010-11-06 19:48:39 +03:00
Py_ssize_t i ;
2008-12-21 00:21:39 +03:00
me - > num_values = PySequence_Size ( set_obj ) ;
me - > values = talloc_array ( me , struct ldb_val , me - > num_values ) ;
for ( i = 0 ; i < me - > num_values ; i + + ) {
PyObject * obj = PySequence_GetItem ( set_obj , i ) ;
2015-06-09 18:44:40 +03:00
if ( PyBytes_Check ( obj ) ) {
char * _msg = NULL ;
result = PyBytes_AsStringAndSize ( obj , & _msg , & size ) ;
if ( result ! = 0 ) {
talloc_free ( me ) ;
return NULL ;
}
msg = _msg ;
2018-04-12 16:46:59 +03:00
} else if ( PyUnicode_Check ( obj ) ) {
2019-06-07 12:44:48 +03:00
msg = PyUnicode_AsUTF8AndSize ( obj , & size ) ;
2015-06-09 18:44:40 +03:00
if ( msg = = NULL ) {
talloc_free ( me ) ;
return NULL ;
}
} else {
2010-08-22 08:50:22 +04:00
PyErr_Format ( PyExc_TypeError ,
2010-11-06 20:03:22 +03:00
" Expected string as element %zd in list " , i ) ;
2010-08-22 08:50:22 +04:00
talloc_free ( me ) ;
return NULL ;
}
2015-06-09 18:44:40 +03:00
me - > values [ i ] . data = talloc_memdup ( me ,
( const uint8_t * ) msg ,
size + 1 ) ;
me - > values [ i ] . length = size ;
2008-12-21 00:21:39 +03:00
}
} else {
2014-11-11 00:59:07 +03:00
PyErr_Format ( PyExc_TypeError ,
" String or List type expected for '%s' attribute " , attr_name ) ;
2008-12-21 00:21:39 +03:00
talloc_free ( me ) ;
me = NULL ;
}
return me ;
2008-12-19 04:22:07 +03:00
}
2010-11-06 19:48:39 +03:00
static PyObject * ldb_msg_element_to_set ( struct ldb_context * ldb_ctx ,
struct ldb_message_element * me )
2008-12-19 04:22:07 +03:00
{
2010-11-06 19:48:39 +03:00
Py_ssize_t i ;
2008-12-21 00:21:39 +03:00
PyObject * result ;
2008-12-19 04:22:07 +03:00
2008-12-21 00:21:39 +03:00
/* Python << 2.5 doesn't have PySet_New and PySet_Add. */
result = PyList_New ( me - > num_values ) ;
2023-08-25 05:20:50 +03:00
if ( result = = NULL ) {
return NULL ;
}
2008-12-19 04:22:07 +03:00
2008-12-21 00:21:39 +03:00
for ( i = 0 ; i < me - > num_values ; i + + ) {
2023-08-25 05:20:50 +03:00
PyObject * obj = NULL ;
int ret ;
obj = PyObject_FromLdbValue ( & me - > values [ i ] ) ;
if ( obj = = NULL ) {
Py_DECREF ( result ) ;
return NULL ;
}
ret = PyList_SetItem ( result , i , obj ) ;
if ( ret ) {
Py_DECREF ( obj ) ;
Py_DECREF ( result ) ;
return NULL ;
}
2008-12-21 00:21:39 +03:00
}
2008-12-19 04:22:07 +03:00
2008-12-21 00:21:39 +03:00
return result ;
2008-12-19 04:22:07 +03:00
}
2008-12-23 07:07:29 +03:00
static PyObject * py_ldb_msg_element_get ( PyLdbMessageElementObject * self , PyObject * args )
2008-12-19 04:22:07 +03:00
{
2010-11-06 19:50:25 +03:00
unsigned int i ;
if ( ! PyArg_ParseTuple ( args , " I " , & i ) )
2008-12-19 04:22:07 +03:00
return NULL ;
2011-08-07 19:08:56 +04:00
if ( i > = pyldb_MessageElement_AsMessageElement ( self ) - > num_values )
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 04:22:07 +03:00
2011-08-07 19:08:56 +04:00
return PyObject_FromLdbValue ( & ( pyldb_MessageElement_AsMessageElement ( self ) - > values [ i ] ) ) ;
2008-12-19 04:22:07 +03:00
}
2009-08-26 09:01:12 +04:00
static PyObject * py_ldb_msg_element_flags ( PyLdbMessageElementObject * self , PyObject * args )
{
2011-08-07 19:08:56 +04:00
struct ldb_message_element * el = pyldb_MessageElement_AsMessageElement ( self ) ;
2020-03-15 00:36:59 +03:00
return PyLong_FromLong ( el - > flags ) ;
2009-08-26 09:01:12 +04:00
}
static PyObject * py_ldb_msg_element_set_flags ( PyLdbMessageElementObject * self , PyObject * args )
{
2011-04-10 21:48:07 +04:00
unsigned int flags ;
2009-08-26 09:01:12 +04:00
struct ldb_message_element * el ;
2011-04-10 21:48:07 +04:00
if ( ! PyArg_ParseTuple ( args , " I " , & flags ) )
2009-08-26 09:01:12 +04:00
return NULL ;
2011-08-07 19:08:56 +04:00
el = pyldb_MessageElement_AsMessageElement ( self ) ;
2009-08-26 09:01:12 +04:00
el - > flags = flags ;
Py_RETURN_NONE ;
}
2008-12-19 04:22:07 +03:00
static PyMethodDef py_ldb_msg_element_methods [ ] = {
{ " get " , ( PyCFunction ) py_ldb_msg_element_get , METH_VARARGS , NULL } ,
2009-08-26 09:01:12 +04:00
{ " set_flags " , ( PyCFunction ) py_ldb_msg_element_set_flags , METH_VARARGS , NULL } ,
{ " flags " , ( PyCFunction ) py_ldb_msg_element_flags , METH_NOARGS , NULL } ,
2020-05-05 04:47:39 +03:00
{ 0 } ,
2008-12-19 04:22:07 +03:00
} ;
2008-12-19 16:41:44 +03:00
static Py_ssize_t py_ldb_msg_element_len ( PyLdbMessageElementObject * self )
{
2011-08-07 19:08:56 +04:00
return pyldb_MessageElement_AsMessageElement ( self ) - > num_values ;
2008-12-19 16:41:44 +03:00
}
2008-12-19 19:08:35 +03:00
static PyObject * py_ldb_msg_element_find ( PyLdbMessageElementObject * self , Py_ssize_t idx )
{
2011-08-07 19:08:56 +04:00
struct ldb_message_element * el = pyldb_MessageElement_AsMessageElement ( self ) ;
2008-12-19 19:08:35 +03:00
if ( idx < 0 | | idx > = el - > num_values ) {
PyErr_SetString ( PyExc_IndexError , " Out of range " ) ;
return NULL ;
}
2018-05-11 15:48:29 +03:00
return PyLdbBytes_FromStringAndSize ( ( char * ) el - > values [ idx ] . data , el - > values [ idx ] . length ) ;
2008-12-19 19:08:35 +03:00
}
2008-12-19 16:41:44 +03:00
static PySequenceMethods py_ldb_msg_element_seq = {
. sq_length = ( lenfunc ) py_ldb_msg_element_len ,
2008-12-19 19:08:35 +03:00
. sq_item = ( ssizeargfunc ) py_ldb_msg_element_find ,
2008-12-19 16:41:44 +03:00
} ;
2015-06-09 11:36:26 +03:00
static PyObject * py_ldb_msg_element_richcmp ( PyObject * self , PyObject * other , int op )
2008-12-19 16:41:44 +03:00
{
2015-06-09 11:36:26 +03:00
int ret ;
if ( ! pyldb_MessageElement_Check ( other ) ) {
Py_INCREF ( Py_NotImplemented ) ;
return Py_NotImplemented ;
}
ret = ldb_msg_element_compare ( pyldb_MessageElement_AsMessageElement ( self ) ,
2011-08-07 19:08:56 +04:00
pyldb_MessageElement_AsMessageElement ( other ) ) ;
2015-06-09 11:36:26 +03:00
return richcmp ( ret , op ) ;
2008-12-19 16:41:44 +03:00
}
2008-12-19 19:08:35 +03:00
static PyObject * py_ldb_msg_element_iter ( PyLdbMessageElementObject * self )
2008-12-19 16:41:44 +03:00
{
2011-08-19 11:26:33 +04:00
PyObject * el = ldb_msg_element_to_set ( NULL ,
pyldb_MessageElement_AsMessageElement ( self ) ) ;
2015-03-04 00:29:10 +03:00
PyObject * ret = PyObject_GetIter ( el ) ;
Py_DECREF ( el ) ;
return ret ;
2008-12-19 16:41:44 +03:00
}
2010-12-30 21:39:14 +03:00
static PyObject * PyLdbMessageElement_FromMessageElement ( struct ldb_message_element * el , TALLOC_CTX * mem_ctx )
2008-12-19 19:08:35 +03:00
{
2023-08-25 05:22:15 +03:00
TALLOC_CTX * ret_mem_ctx = NULL ;
2008-12-23 07:07:29 +03:00
PyLdbMessageElementObject * ret ;
2023-08-25 05:22:15 +03:00
ret_mem_ctx = talloc_new ( NULL ) ;
if ( ret_mem_ctx = = NULL ) {
return PyErr_NoMemory ( ) ;
}
if ( talloc_reference ( ret_mem_ctx , mem_ctx ) = = NULL ) {
talloc_free ( ret_mem_ctx ) ;
2008-12-23 07:07:29 +03:00
PyErr_NoMemory ( ) ;
return NULL ;
}
2023-08-25 05:22:15 +03:00
ret = PyObject_New ( PyLdbMessageElementObject , & PyLdbMessageElement ) ;
if ( ret = = NULL ) {
talloc_free ( ret_mem_ctx ) ;
2008-12-23 07:34:21 +03:00
PyErr_NoMemory ( ) ;
return NULL ;
}
2023-08-25 05:22:15 +03:00
ret - > mem_ctx = ret_mem_ctx ;
2008-12-23 07:07:29 +03:00
ret - > el = el ;
return ( PyObject * ) ret ;
2008-12-19 19:08:35 +03:00
}
static PyObject * py_ldb_msg_element_new ( PyTypeObject * type , PyObject * args , PyObject * kwargs )
{
PyObject * py_elements = NULL ;
struct ldb_message_element * el ;
2011-04-10 21:48:07 +04:00
unsigned int flags = 0 ;
2008-12-19 19:08:35 +03:00
char * name = NULL ;
2009-02-05 13:04:28 +03:00
const char * const kwnames [ ] = { " elements " , " flags " , " name " , NULL } ;
2008-12-23 07:07:29 +03:00
PyLdbMessageElementObject * ret ;
2009-06-17 22:43:25 +04:00
TALLOC_CTX * mem_ctx ;
2015-06-09 18:44:40 +03:00
const char * msg = NULL ;
Py_ssize_t size ;
int result ;
2009-02-05 13:04:28 +03:00
2011-04-10 21:48:07 +04:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " |OIs " ,
2009-02-05 13:04:28 +03:00
discard_const_p ( char * , kwnames ) ,
& py_elements , & flags , & name ) )
2008-12-19 19:08:35 +03:00
return NULL ;
2009-06-17 22:43:25 +04:00
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
el = talloc_zero ( mem_ctx , struct ldb_message_element ) ;
2010-12-30 21:59:01 +03:00
if ( el = = NULL ) {
PyErr_NoMemory ( ) ;
talloc_free ( mem_ctx ) ;
return NULL ;
}
2008-12-19 19:08:35 +03:00
if ( py_elements ! = NULL ) {
2010-11-06 19:48:39 +03:00
Py_ssize_t i ;
2018-04-12 16:46:59 +03:00
if ( PyBytes_Check ( py_elements ) | | PyUnicode_Check ( py_elements ) ) {
2015-06-09 18:44:40 +03:00
char * _msg = NULL ;
2008-12-21 00:21:39 +03:00
el - > num_values = 1 ;
el - > values = talloc_array ( el , struct ldb_val , 1 ) ;
2010-12-30 21:59:01 +03:00
if ( el - > values = = NULL ) {
talloc_free ( mem_ctx ) ;
PyErr_NoMemory ( ) ;
return NULL ;
}
2017-01-11 02:18:15 +03:00
if ( PyBytes_Check ( py_elements ) ) {
result = PyBytes_AsStringAndSize ( py_elements , & _msg , & size ) ;
msg = _msg ;
} else {
2019-06-07 12:44:48 +03:00
msg = PyUnicode_AsUTF8AndSize ( py_elements , & size ) ;
2017-01-11 02:18:15 +03:00
result = ( msg = = NULL ) ? - 1 : 0 ;
}
2015-06-09 18:44:40 +03:00
if ( result ! = 0 ) {
talloc_free ( mem_ctx ) ;
return NULL ;
}
2024-02-29 03:07:47 +03:00
el - > values [ 0 ] . data = talloc_memdup ( el - > values ,
2015-06-09 18:44:40 +03:00
( const uint8_t * ) msg , size + 1 ) ;
el - > values [ 0 ] . length = size ;
2008-12-23 07:34:21 +03:00
} else if ( PySequence_Check ( py_elements ) ) {
2008-12-21 00:21:39 +03:00
el - > num_values = PySequence_Size ( py_elements ) ;
el - > values = talloc_array ( el , struct ldb_val , el - > num_values ) ;
2010-12-30 21:59:01 +03:00
if ( el - > values = = NULL ) {
talloc_free ( mem_ctx ) ;
PyErr_NoMemory ( ) ;
return NULL ;
}
2008-12-21 00:21:39 +03:00
for ( i = 0 ; i < el - > num_values ; i + + ) {
PyObject * item = PySequence_GetItem ( py_elements , i ) ;
2010-12-30 21:59:01 +03:00
if ( item = = NULL ) {
talloc_free ( mem_ctx ) ;
return NULL ;
}
2015-06-09 18:44:40 +03:00
if ( PyBytes_Check ( item ) ) {
char * _msg = NULL ;
result = PyBytes_AsStringAndSize ( item , & _msg , & size ) ;
msg = _msg ;
2018-04-12 16:46:59 +03:00
} else if ( PyUnicode_Check ( item ) ) {
2019-06-07 12:44:48 +03:00
msg = PyUnicode_AsUTF8AndSize ( item , & size ) ;
2015-06-09 18:44:40 +03:00
result = ( msg = = NULL ) ? - 1 : 0 ;
} else {
2024-02-29 03:07:47 +03:00
PyErr_Format ( PyExc_TypeError ,
2010-11-06 20:03:22 +03:00
" Expected string as element %zd in list " , i ) ;
2015-06-09 18:44:40 +03:00
result = - 1 ;
}
if ( result ! = 0 ) {
2009-08-05 05:34:08 +04:00
talloc_free ( mem_ctx ) ;
return NULL ;
}
2011-01-03 03:43:51 +03:00
el - > values [ i ] . data = talloc_memdup ( el ,
2015-06-09 18:44:40 +03:00
( const uint8_t * ) msg , size + 1 ) ;
el - > values [ i ] . length = size ;
2008-12-21 00:21:39 +03:00
}
2008-12-23 07:34:21 +03:00
} else {
2024-02-29 03:07:47 +03:00
PyErr_SetString ( PyExc_TypeError ,
2008-12-23 07:34:21 +03:00
" Expected string or list " ) ;
2009-06-17 22:43:25 +04:00
talloc_free ( mem_ctx ) ;
2008-12-23 07:34:21 +03:00
return NULL ;
2008-12-19 19:08:35 +03:00
}
}
el - > flags = flags ;
2023-08-01 00:34:34 +03:00
if ( name ! = NULL ) {
el - > name = talloc_strdup ( el , name ) ;
2023-08-01 00:48:35 +03:00
if ( el - > name = = NULL ) {
talloc_free ( mem_ctx ) ;
return PyErr_NoMemory ( ) ;
}
2023-08-01 00:34:34 +03:00
}
2008-12-19 19:08:35 +03:00
2010-12-30 21:59:01 +03:00
ret = PyObject_New ( PyLdbMessageElementObject , type ) ;
2008-12-23 07:07:29 +03:00
if ( ret = = NULL ) {
2009-06-17 22:43:25 +04:00
talloc_free ( mem_ctx ) ;
2008-12-23 07:07:29 +03:00
return NULL ;
}
2009-06-17 22:43:25 +04:00
ret - > mem_ctx = mem_ctx ;
ret - > el = el ;
2008-12-23 07:07:29 +03:00
return ( PyObject * ) ret ;
2008-12-19 19:08:35 +03:00
}
static PyObject * py_ldb_msg_element_repr ( PyLdbMessageElementObject * self )
{
2008-12-21 00:21:39 +03:00
char * element_str = NULL ;
2010-11-06 19:48:39 +03:00
Py_ssize_t i ;
2011-08-07 19:08:56 +04:00
struct ldb_message_element * el = pyldb_MessageElement_AsMessageElement ( self ) ;
2015-03-04 00:29:10 +03:00
PyObject * ret , * repr ;
2008-12-21 00:21:39 +03:00
for ( i = 0 ; i < el - > num_values ; i + + ) {
PyObject * o = py_ldb_msg_element_find ( self , i ) ;
2015-03-04 00:29:10 +03:00
repr = PyObject_Repr ( o ) ;
2008-12-21 00:21:39 +03:00
if ( element_str = = NULL )
2019-06-07 12:21:15 +03:00
element_str = talloc_strdup ( NULL , PyUnicode_AsUTF8 ( repr ) ) ;
2008-12-21 00:21:39 +03:00
else
2019-06-07 12:21:15 +03:00
element_str = talloc_asprintf_append ( element_str , " ,%s " , PyUnicode_AsUTF8 ( repr ) ) ;
2015-03-04 00:29:10 +03:00
Py_DECREF ( repr ) ;
2023-02-13 04:57:24 +03:00
if ( element_str = = NULL ) {
return PyErr_NoMemory ( ) ;
}
2008-12-21 00:21:39 +03:00
}
2010-04-07 22:40:06 +04:00
if ( element_str ! = NULL ) {
2019-06-07 12:08:55 +03:00
ret = PyUnicode_FromFormat ( " MessageElement([%s]) " , element_str ) ;
2010-04-07 22:40:06 +04:00
talloc_free ( element_str ) ;
} else {
2019-06-07 11:45:52 +03:00
ret = PyUnicode_FromString ( " MessageElement([]) " ) ;
2010-04-07 22:40:06 +04:00
}
2008-12-21 00:21:39 +03:00
return ret ;
2008-12-19 19:08:35 +03:00
}
2008-12-21 09:34:27 +03:00
static PyObject * py_ldb_msg_element_str ( PyLdbMessageElementObject * self )
{
2011-08-07 19:08:56 +04:00
struct ldb_message_element * el = pyldb_MessageElement_AsMessageElement ( self ) ;
2008-12-21 09:34:27 +03:00
if ( el - > num_values = = 1 )
2019-06-07 12:01:19 +03:00
return PyUnicode_FromStringAndSize ( ( char * ) el - > values [ 0 ] . data , el - > values [ 0 ] . length ) ;
2010-12-21 16:05:18 +03:00
else
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-21 09:34:27 +03:00
}
2008-12-23 07:07:29 +03:00
static void py_ldb_msg_element_dealloc ( PyLdbMessageElementObject * self )
{
talloc_free ( self - > mem_ctx ) ;
2010-12-29 17:58:12 +03:00
PyObject_Del ( self ) ;
2008-12-23 07:07:29 +03:00
}
2015-06-09 18:44:40 +03:00
static PyObject * py_ldb_msg_element_get_text ( PyObject * self , void * closure )
{
return wrap_text ( " MessageElementTextWrapper " , self ) ;
}
static PyGetSetDef py_ldb_msg_element_getset [ ] = {
2018-12-13 13:34:37 +03:00
{
. name = discard_const_p ( char , " text " ) ,
. get = ( getter ) py_ldb_msg_element_get_text ,
} ,
{ . name = NULL }
2015-06-09 18:44:40 +03:00
} ;
2010-12-21 16:05:18 +03:00
static PyTypeObject PyLdbMessageElement = {
2010-04-04 03:48:35 +04:00
. tp_name = " ldb.MessageElement " ,
2008-12-19 04:22:07 +03:00
. tp_basicsize = sizeof ( PyLdbMessageElementObject ) ,
2008-12-23 07:07:29 +03:00
. tp_dealloc = ( destructor ) py_ldb_msg_element_dealloc ,
2008-12-19 19:08:35 +03:00
. tp_repr = ( reprfunc ) py_ldb_msg_element_repr ,
2008-12-21 09:34:27 +03:00
. tp_str = ( reprfunc ) py_ldb_msg_element_str ,
2008-12-19 04:22:07 +03:00
. tp_methods = py_ldb_msg_element_methods ,
2015-06-09 18:44:40 +03:00
. tp_getset = py_ldb_msg_element_getset ,
2015-06-09 11:36:26 +03:00
. tp_richcompare = ( richcmpfunc ) py_ldb_msg_element_richcmp ,
2008-12-19 19:08:35 +03:00
. tp_iter = ( getiterfunc ) py_ldb_msg_element_iter ,
2008-12-19 16:41:44 +03:00
. tp_as_sequence = & py_ldb_msg_element_seq ,
2008-12-19 19:08:35 +03:00
. tp_new = py_ldb_msg_element_new ,
2008-12-21 05:08:14 +03:00
. tp_flags = Py_TPFLAGS_DEFAULT ,
2011-12-08 23:28:18 +04:00
. tp_doc = " An element of a Message " ,
2008-12-19 04:22:07 +03:00
} ;
2010-11-18 23:11:30 +03:00
static PyObject * py_ldb_msg_from_dict ( PyTypeObject * type , PyObject * args )
{
PyObject * py_ldb ;
PyObject * py_dict ;
PyObject * py_ret ;
struct ldb_message * msg ;
struct ldb_context * ldb_ctx ;
unsigned int mod_flags = LDB_FLAG_MOD_REPLACE ;
if ( ! PyArg_ParseTuple ( args , " O!O!|I " ,
& PyLdb , & py_ldb , & PyDict_Type , & py_dict ,
& mod_flags ) ) {
return NULL ;
}
/* mask only flags we are going to use */
mod_flags = LDB_FLAG_MOD_TYPE ( mod_flags ) ;
if ( ! mod_flags ) {
PyErr_SetString ( PyExc_ValueError ,
" FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE "
" expected as mod_flag value " ) ;
return NULL ;
}
2018-04-20 07:23:42 +03:00
ldb_ctx = pyldb_Ldb_AS_LDBCONTEXT ( py_ldb ) ;
2010-11-18 23:11:30 +03:00
msg = PyDict_AsMessage ( ldb_ctx , py_dict , ldb_ctx , mod_flags ) ;
if ( ! msg ) {
return NULL ;
}
2023-11-08 00:43:38 +03:00
py_ret = PyLdbMessage_FromMessage ( msg , ( PyLdbObject * ) py_ldb ) ;
2010-11-18 23:11:30 +03:00
talloc_unlink ( ldb_ctx , msg ) ;
return py_ret ;
}
2024-03-14 06:41:43 +03:00
# define pyldb_Message_as_message(pyobj) ((PyLdbMessageObject *)pyobj)->msg
# define pyldb_Message_get_pyldb(pyobj) ((PyLdbMessageObject *)pyobj)->pyldb
/*
* PyErr_LDB_MESSAGE_OR_RAISE does 3 things :
* 1. checks that a PyObject is really a PyLdbMessageObject .
* 2. checks that the ldb that the PyLdbMessageObject knows is the ldb that
* its dn knows - - but only if the underlying message has a DN .
* 3. sets message to the relevant struct ldb_message * .
*
* We need to do all this to ensure the message belongs to the right
* ldb , lest it be freed before we are ready .
*/
# define PyErr_LDB_MESSAGE_OR_RAISE(_py_obj, message) do { \
PyLdbMessageObject * _py_message = NULL ; \
struct ldb_dn * _dn = NULL ; \
2024-03-13 07:28:07 +03:00
if ( _py_obj = = NULL | | ! pyldb_Message_Check ( _py_obj ) ) { \
2024-03-14 06:41:43 +03:00
PyErr_SetString ( PyExc_TypeError , \
" ldb Message object required " ) ; \
return NULL ; \
} \
_py_message = ( PyLdbMessageObject * ) _py_obj ; \
message = pyldb_Message_as_message ( _py_message ) ; \
_dn = message - > dn ; \
if ( _dn ! = NULL & & \
( _py_message - > pyldb - > ldb_ctx ! = ldb_dn_get_ldb_context ( _dn ) ) ) { \
PyErr_SetString ( PyExc_RuntimeError , \
" Message has a stale LDB connection " ) ; \
return NULL ; \
} \
} while ( 0 )
2024-03-15 03:08:03 +03:00
static PyObject * py_ldb_msg_remove_attr ( PyObject * self , PyObject * args )
2008-12-19 04:22:07 +03:00
{
char * name ;
2024-03-15 03:08:03 +03:00
struct ldb_message * msg = NULL ;
PyErr_LDB_MESSAGE_OR_RAISE ( self , msg ) ;
if ( ! PyArg_ParseTuple ( args , " s " , & name ) ) {
2008-12-19 04:22:07 +03:00
return NULL ;
2024-03-15 03:08:03 +03:00
}
2008-12-19 04:22:07 +03:00
2024-03-15 03:08:03 +03:00
ldb_msg_remove_attr ( msg , name ) ;
2008-12-19 04:22:07 +03:00
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-19 04:22:07 +03:00
}
2024-03-15 03:50:40 +03:00
static PyObject * py_ldb_msg_keys ( PyObject * self ,
2019-05-02 21:51:05 +03:00
PyObject * Py_UNUSED ( ignored ) )
2008-12-19 16:41:44 +03:00
{
2024-03-15 03:50:40 +03:00
struct ldb_message * msg = NULL ;
2010-11-06 19:48:39 +03:00
Py_ssize_t i , j = 0 ;
2024-03-15 03:50:40 +03:00
PyObject * obj = NULL ;
PyErr_LDB_MESSAGE_OR_RAISE ( self , msg ) ;
obj = PyList_New ( msg - > num_elements + ( msg - > dn ! = NULL ? 1 : 0 ) ) ;
2023-08-25 05:20:50 +03:00
if ( obj = = NULL ) {
return NULL ;
}
2008-12-19 16:41:44 +03:00
if ( msg - > dn ! = NULL ) {
2023-08-25 05:20:50 +03:00
PyObject * py_dn = NULL ;
int ret ;
py_dn = PyUnicode_FromString ( " dn " ) ;
if ( py_dn = = NULL ) {
Py_DECREF ( obj ) ;
return NULL ;
}
ret = PyList_SetItem ( obj , j , py_dn ) ;
if ( ret ) {
Py_DECREF ( py_dn ) ;
Py_DECREF ( obj ) ;
return NULL ;
}
2008-12-19 16:41:44 +03:00
j + + ;
}
for ( i = 0 ; i < msg - > num_elements ; i + + ) {
2023-08-25 05:20:50 +03:00
PyObject * py_name = NULL ;
int ret ;
py_name = PyUnicode_FromString ( msg - > elements [ i ] . name ) ;
if ( py_name = = NULL ) {
Py_DECREF ( obj ) ;
return NULL ;
}
ret = PyList_SetItem ( obj , j , py_name ) ;
if ( ret ) {
Py_DECREF ( py_name ) ;
Py_DECREF ( obj ) ;
return NULL ;
}
2008-12-19 16:41:44 +03:00
j + + ;
}
return obj ;
}
2021-09-25 05:39:59 +03:00
static int py_ldb_msg_contains ( PyLdbMessageObject * self , PyObject * py_name )
{
struct ldb_message_element * el = NULL ;
const char * name = NULL ;
2024-03-15 07:09:53 +03:00
struct ldb_message * msg = pyldb_Message_as_message ( self ) ;
struct ldb_dn * dn = msg - > dn ;
if ( dn ! = NULL & & ( self - > pyldb - > ldb_ctx ! = ldb_dn_get_ldb_context ( dn ) ) ) {
return - 1 ;
}
2021-09-25 05:39:59 +03:00
name = PyUnicode_AsUTF8 ( py_name ) ;
if ( name = = NULL ) {
return - 1 ;
}
if ( ! ldb_attr_cmp ( name , " dn " ) ) {
return 1 ;
}
el = ldb_msg_find_element ( msg , name ) ;
return el ! = NULL ? 1 : 0 ;
}
2024-03-15 03:08:03 +03:00
static PyObject * py_ldb_msg_getitem ( PyObject * self , PyObject * py_name )
2008-12-19 04:22:07 +03:00
{
2021-09-25 04:39:56 +03:00
struct ldb_message_element * el = NULL ;
const char * name = NULL ;
2024-03-15 03:08:03 +03:00
struct ldb_message * msg = NULL ;
PyErr_LDB_MESSAGE_OR_RAISE ( self , msg ) ;
2019-06-07 12:21:15 +03:00
name = PyUnicode_AsUTF8 ( py_name ) ;
2015-06-09 18:44:40 +03:00
if ( name = = NULL ) {
2009-09-14 19:03:30 +04:00
return NULL ;
}
2021-09-25 04:39:56 +03:00
if ( ! ldb_attr_cmp ( name , " dn " ) ) {
2024-03-15 03:08:03 +03:00
return pyldb_Dn_FromDn ( msg - > dn , pyldb_Message_get_pyldb ( self ) ) ;
2021-09-25 04:39:56 +03:00
}
2008-12-23 07:07:29 +03:00
el = ldb_msg_find_element ( msg , name ) ;
2008-12-21 00:21:39 +03:00
if ( el = = NULL ) {
PyErr_SetString ( PyExc_KeyError , " No such element " ) ;
return NULL ;
}
2021-09-25 04:39:56 +03:00
return PyLdbMessageElement_FromMessageElement ( el , msg - > elements ) ;
2008-12-21 00:21:39 +03:00
}
2024-03-15 03:08:03 +03:00
static PyObject * py_ldb_msg_get ( PyObject * self , PyObject * args , PyObject * kwargs )
2008-12-19 19:08:35 +03:00
{
2011-11-09 06:07:53 +04:00
PyObject * def = NULL ;
const char * kwnames [ ] = { " name " , " default " , " idx " , NULL } ;
const char * name = NULL ;
int idx = - 1 ;
struct ldb_message_element * el ;
2024-03-15 03:08:03 +03:00
struct ldb_message * msg = NULL ;
PyErr_LDB_MESSAGE_OR_RAISE ( self , msg ) ;
2011-11-09 06:07:53 +04:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " s|Oi:msg " ,
discard_const_p ( char * , kwnames ) , & name , & def , & idx ) ) {
2008-12-19 19:08:35 +03:00
return NULL ;
2011-11-09 06:07:53 +04:00
}
2008-12-19 19:08:35 +03:00
2011-11-09 06:07:53 +04:00
if ( strcasecmp ( name , " dn " ) = = 0 ) {
2024-03-15 03:08:03 +03:00
return pyldb_Dn_FromDn ( msg - > dn , pyldb_Message_get_pyldb ( self ) ) ;
2011-11-09 06:07:53 +04:00
}
el = ldb_msg_find_element ( msg , name ) ;
if ( el = = NULL | | ( idx ! = - 1 & & el - > num_values < = idx ) ) {
if ( def ! = NULL ) {
2015-06-11 11:16:48 +03:00
Py_INCREF ( def ) ;
2011-11-09 06:07:53 +04:00
return def ;
2011-06-11 16:57:02 +04:00
}
2011-11-09 06:07:53 +04:00
Py_RETURN_NONE ;
2009-09-14 19:03:30 +04:00
}
2011-11-09 06:07:53 +04:00
if ( idx = = - 1 ) {
return ( PyObject * ) PyLdbMessageElement_FromMessageElement ( el , msg - > elements ) ;
}
return PyObject_FromLdbValue ( & el - > values [ idx ] ) ;
2008-12-19 19:08:35 +03:00
}
2024-03-15 07:15:28 +03:00
static PyObject * py_ldb_msg_items ( PyObject * self ,
2019-05-02 21:51:05 +03:00
PyObject * Py_UNUSED ( ignored ) )
2008-12-19 19:08:35 +03:00
{
2024-03-15 07:15:28 +03:00
struct ldb_message * msg = NULL ;
2010-11-06 19:48:39 +03:00
Py_ssize_t i , j = 0 ;
2024-03-15 07:15:28 +03:00
PyObject * l = NULL ;
PyErr_LDB_MESSAGE_OR_RAISE ( self , msg ) ;
l = PyList_New ( msg - > num_elements + ( msg - > dn = = NULL ? 0 : 1 ) ) ;
2019-01-25 15:02:50 +03:00
if ( l = = NULL ) {
return PyErr_NoMemory ( ) ;
}
2008-12-19 19:08:35 +03:00
if ( msg - > dn ! = NULL ) {
2019-01-25 15:02:50 +03:00
PyObject * value = NULL ;
int res = 0 ;
2024-03-16 01:15:31 +03:00
PyObject * obj = pyldb_Dn_FromDn ( msg - > dn , pyldb_Message_get_pyldb ( self ) ) ;
if ( obj = = NULL ) {
Py_CLEAR ( l ) ;
return NULL ;
}
2019-01-25 15:02:50 +03:00
value = Py_BuildValue ( " (sO) " , " dn " , obj ) ;
2019-01-22 21:26:23 +03:00
Py_CLEAR ( obj ) ;
2019-01-25 15:02:50 +03:00
if ( value = = NULL ) {
Py_CLEAR ( l ) ;
return NULL ;
}
res = PyList_SetItem ( l , 0 , value ) ;
if ( res = = - 1 ) {
Py_CLEAR ( l ) ;
return NULL ;
}
2008-12-19 19:08:35 +03:00
j + + ;
}
for ( i = 0 ; i < msg - > num_elements ; i + + , j + + ) {
2019-01-25 15:02:50 +03:00
PyObject * value = NULL ;
int res = 0 ;
2024-03-16 01:15:31 +03:00
PyObject * py_el = PyLdbMessageElement_FromMessageElement ( & msg - > elements [ i ] ,
msg - > elements ) ;
if ( py_el = = NULL ) {
Py_CLEAR ( l ) ;
return NULL ;
}
2019-01-25 15:02:50 +03:00
value = Py_BuildValue ( " (sO) " , msg - > elements [ i ] . name , py_el ) ;
2021-05-28 05:15:43 +03:00
Py_CLEAR ( py_el ) ;
2019-01-25 15:02:50 +03:00
if ( value = = NULL ) {
Py_CLEAR ( l ) ;
return NULL ;
}
2021-05-28 05:15:43 +03:00
res = PyList_SetItem ( l , j , value ) ;
2019-01-25 15:02:50 +03:00
if ( res = = - 1 ) {
Py_CLEAR ( l ) ;
return NULL ;
}
2008-12-19 19:08:35 +03:00
}
return l ;
}
2024-03-15 07:16:34 +03:00
static PyObject * py_ldb_msg_elements ( PyObject * self ,
2019-05-02 21:51:05 +03:00
PyObject * Py_UNUSED ( ignored ) )
2010-12-21 16:05:18 +03:00
{
Py_ssize_t i = 0 ;
2024-03-15 07:16:34 +03:00
PyObject * l = NULL ;
struct ldb_message * msg = NULL ;
PyErr_LDB_MESSAGE_OR_RAISE ( self , msg ) ;
l = PyList_New ( msg - > num_elements ) ;
2023-08-25 05:20:50 +03:00
if ( l = = NULL ) {
return NULL ;
}
2010-12-21 16:05:18 +03:00
for ( i = 0 ; i < msg - > num_elements ; i + + ) {
2023-08-25 05:20:50 +03:00
PyObject * msg_el = NULL ;
int ret ;
msg_el = PyLdbMessageElement_FromMessageElement ( & msg - > elements [ i ] , msg - > elements ) ;
if ( msg_el = = NULL ) {
Py_DECREF ( l ) ;
return NULL ;
}
ret = PyList_SetItem ( l , i , msg_el ) ;
if ( ret ) {
Py_DECREF ( msg_el ) ;
Py_DECREF ( l ) ;
return NULL ;
}
2010-12-21 16:05:18 +03:00
}
return l ;
}
2024-03-15 03:08:03 +03:00
static PyObject * py_ldb_msg_add ( PyObject * self , PyObject * args )
2010-12-21 16:05:18 +03:00
{
2010-12-30 22:11:59 +03:00
PyLdbMessageElementObject * py_element ;
2014-11-12 03:17:56 +03:00
int i , ret ;
2010-12-21 16:05:18 +03:00
struct ldb_message_element * el ;
2014-11-12 03:17:56 +03:00
struct ldb_message_element * el_new ;
2024-03-15 03:08:03 +03:00
struct ldb_message * msg = NULL ;
PyErr_LDB_MESSAGE_OR_RAISE ( self , msg ) ;
2010-12-21 16:05:18 +03:00
2024-03-15 03:08:03 +03:00
if ( ! PyArg_ParseTuple ( args , " O! " , & PyLdbMessageElement , & py_element ) ) {
2010-12-21 16:05:18 +03:00
return NULL ;
2024-03-15 03:08:03 +03:00
}
2010-12-21 16:05:18 +03:00
2014-11-12 03:17:56 +03:00
el = py_element - > el ;
2010-12-21 16:05:18 +03:00
if ( el = = NULL ) {
2014-11-12 03:17:56 +03:00
PyErr_SetString ( PyExc_ValueError , " Invalid MessageElement object " ) ;
2010-12-21 16:05:18 +03:00
return NULL ;
}
2019-04-12 06:00:20 +03:00
if ( el - > name = = NULL ) {
PyErr_SetString ( PyExc_ValueError ,
" The element has no name " ) ;
return NULL ;
}
2014-11-12 03:17:56 +03:00
ret = ldb_msg_add_empty ( msg , el - > name , el - > flags , & el_new ) ;
2010-12-21 16:05:18 +03:00
PyErr_LDB_ERROR_IS_ERR_RAISE ( PyExc_LdbError , ret , NULL ) ;
2014-11-12 03:17:56 +03:00
/* now deep copy all attribute values */
el_new - > values = talloc_array ( msg - > elements , struct ldb_val , el - > num_values ) ;
if ( el_new - > values = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
el_new - > num_values = el - > num_values ;
for ( i = 0 ; i < el - > num_values ; i + + ) {
el_new - > values [ i ] = ldb_val_dup ( el_new - > values , & el - > values [ i ] ) ;
if ( el_new - > values [ i ] . data = = NULL
& & el - > values [ i ] . length ! = 0 ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
}
2010-12-21 16:05:18 +03:00
Py_RETURN_NONE ;
}
static PyMethodDef py_ldb_msg_methods [ ] = {
2010-11-18 23:11:30 +03:00
{ " from_dict " , ( PyCFunction ) py_ldb_msg_from_dict , METH_CLASS | METH_VARARGS ,
2024-03-25 12:30:29 +03:00
" Message.from_dict(ldb, dict, mod_flag) -> ldb.Message \n "
2010-11-18 23:11:30 +03:00
" Class method to create ldb.Message object from Dictionary. \n "
2010-12-21 16:05:18 +03:00
" mod_flag is one of FLAG_MOD_ADD, FLAG_MOD_REPLACE or FLAG_MOD_DELETE. " } ,
2019-05-02 21:51:05 +03:00
{ " keys " , ( PyCFunction ) py_ldb_msg_keys , METH_NOARGS ,
2010-12-21 16:05:18 +03:00
" S.keys() -> list \n \n "
" Return sequence of all attribute names. " } ,
2024-02-29 03:07:47 +03:00
{ " remove " , ( PyCFunction ) py_ldb_msg_remove_attr , METH_VARARGS ,
2010-12-21 16:05:18 +03:00
" S.remove(name) \n \n "
" Remove all entries for attributes with the specified name. " } ,
2019-05-02 21:51:05 +03:00
{ " get " , PY_DISCARD_FUNC_SIG ( PyCFunction , py_ldb_msg_get ) ,
METH_VARARGS | METH_KEYWORDS ,
2011-11-09 06:07:53 +04:00
" msg.get(name,default=None,idx=None) -> string \n "
" idx is the index into the values array \n "
" if idx is None, then a list is returned \n "
" if idx is not None, then the element with that index is returned \n "
" if you pass the special name 'dn' then the DN object is returned \n " } ,
2008-12-19 19:08:35 +03:00
{ " items " , ( PyCFunction ) py_ldb_msg_items , METH_NOARGS , NULL } ,
2010-12-21 16:05:18 +03:00
{ " elements " , ( PyCFunction ) py_ldb_msg_elements , METH_NOARGS , NULL } ,
{ " add " , ( PyCFunction ) py_ldb_msg_add , METH_VARARGS ,
2014-11-20 06:06:01 +03:00
" S.add(element) \n \n "
2010-12-21 16:05:18 +03:00
" Add an element to this message. " } ,
2020-05-05 04:47:39 +03:00
{ 0 } ,
2008-12-19 19:08:35 +03:00
} ;
2024-03-15 03:50:40 +03:00
static PyObject * py_ldb_msg_iter ( PyObject * self )
2008-12-21 06:36:16 +03:00
{
PyObject * list , * iter ;
2019-05-02 21:51:05 +03:00
list = py_ldb_msg_keys ( self , NULL ) ;
2024-04-18 03:47:28 +03:00
if ( list = = NULL ) {
return NULL ;
}
2008-12-21 06:36:16 +03:00
iter = PyObject_GetIter ( list ) ;
Py_DECREF ( list ) ;
return iter ;
}
2008-12-19 19:08:35 +03:00
static int py_ldb_msg_setitem ( PyLdbMessageObject * self , PyObject * name , PyObject * value )
2008-12-19 04:22:07 +03:00
{
2018-11-12 19:19:21 +03:00
const char * attr_name ;
2009-08-04 01:58:16 +04:00
2019-06-07 12:21:15 +03:00
attr_name = PyUnicode_AsUTF8 ( name ) ;
2015-06-09 18:44:40 +03:00
if ( attr_name = = NULL ) {
2009-08-04 01:58:16 +04:00
PyErr_SetNone ( PyExc_TypeError ) ;
return - 1 ;
}
2010-12-21 16:05:18 +03:00
2008-12-19 04:22:07 +03:00
if ( value = = NULL ) {
2009-08-04 01:58:16 +04:00
/* delitem */
2008-12-23 07:07:29 +03:00
ldb_msg_remove_attr ( self - > msg , attr_name ) ;
2008-12-19 04:22:07 +03:00
} else {
2012-01-03 07:25:56 +04:00
int ret ;
2009-08-04 01:58:16 +04:00
struct ldb_message_element * el = PyObject_AsMessageElement ( self - > msg ,
2010-07-15 08:01:56 +04:00
value , 0 , attr_name ) ;
2014-11-20 06:07:47 +03:00
if ( el = = NULL ) {
2008-12-19 19:08:35 +03:00
return - 1 ;
2014-11-20 06:07:47 +03:00
}
2023-07-07 02:28:01 +03:00
if ( el - > name = = NULL ) {
/*
* If ‘ value ’ is a MessageElement ,
* PyObject_AsMessageElement ( ) will have returned a
* reference to it without setting the name . We don ’ t
* want to modify the original object to set the name
* ourselves , but making a copy would result in
* different behaviour for a caller relying on a
* reference being kept . Rather than continue with a
* NULL name ( and probably fail later on ) , let ’ s catch
* this potential mistake early .
*/
PyErr_SetString ( PyExc_ValueError , " MessageElement has no name set " ) ;
talloc_unlink ( self - > msg , el ) ;
return - 1 ;
}
2011-08-07 19:08:56 +04:00
ldb_msg_remove_attr ( pyldb_Message_AsMessage ( self ) , attr_name ) ;
2012-01-03 07:25:56 +04:00
ret = ldb_msg_add ( pyldb_Message_AsMessage ( self ) , el , el - > flags ) ;
if ( ret ! = LDB_SUCCESS ) {
PyErr_SetLdbError ( PyExc_LdbError , ret , NULL ) ;
2023-07-07 01:43:15 +03:00
talloc_unlink ( self - > msg , el ) ;
2012-01-03 07:25:56 +04:00
return - 1 ;
}
2008-12-19 04:22:07 +03:00
}
2008-12-19 19:08:35 +03:00
return 0 ;
2008-12-19 04:22:07 +03:00
}
2008-12-19 16:41:44 +03:00
static Py_ssize_t py_ldb_msg_length ( PyLdbMessageObject * self )
{
2011-08-07 19:08:56 +04:00
return pyldb_Message_AsMessage ( self ) - > num_elements ;
2008-12-19 16:41:44 +03:00
}
2021-09-25 05:39:59 +03:00
static PySequenceMethods py_ldb_msg_sequence = {
. sq_contains = ( objobjproc ) py_ldb_msg_contains ,
} ;
2008-12-19 04:22:07 +03:00
static PyMappingMethods py_ldb_msg_mapping = {
2008-12-19 16:41:44 +03:00
. mp_length = ( lenfunc ) py_ldb_msg_length ,
2008-12-19 04:22:07 +03:00
. mp_subscript = ( binaryfunc ) py_ldb_msg_getitem ,
. mp_ass_subscript = ( objobjargproc ) py_ldb_msg_setitem ,
} ;
static PyObject * py_ldb_msg_new ( PyTypeObject * type , PyObject * args , PyObject * kwargs )
{
2009-02-05 13:04:28 +03:00
const char * const kwnames [ ] = { " dn " , NULL } ;
2008-12-19 19:08:35 +03:00
struct ldb_message * ret ;
2009-08-03 20:15:16 +04:00
TALLOC_CTX * mem_ctx ;
2008-12-19 19:08:35 +03:00
PyObject * pydn = NULL ;
2008-12-23 07:07:29 +03:00
PyLdbMessageObject * py_ret ;
2009-02-05 13:04:28 +03:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " |O " ,
discard_const_p ( char * , kwnames ) ,
& pydn ) )
2008-12-19 04:22:07 +03:00
return NULL ;
2009-08-03 20:15:16 +04:00
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
PyErr_NoMemory ( ) ;
return NULL ;
}
ret = ldb_msg_new ( mem_ctx ) ;
2008-12-19 19:08:35 +03:00
if ( ret = = NULL ) {
2009-08-03 20:15:16 +04:00
talloc_free ( mem_ctx ) ;
2008-12-19 19:08:35 +03:00
PyErr_NoMemory ( ) ;
return NULL ;
}
2009-06-17 21:01:06 +04:00
if ( pydn ! = NULL ) {
2009-06-17 22:17:35 +04:00
struct ldb_dn * dn ;
2011-08-07 19:08:56 +04:00
if ( ! pyldb_Object_AsDn ( NULL , pydn , NULL , & dn ) ) {
2009-08-03 20:15:16 +04:00
talloc_free ( mem_ctx ) ;
2008-12-19 19:08:35 +03:00
return NULL ;
2009-06-17 21:01:06 +04:00
}
2009-06-17 22:17:35 +04:00
ret - > dn = talloc_reference ( ret , dn ) ;
2023-08-25 05:22:15 +03:00
if ( ret - > dn = = NULL ) {
talloc_free ( mem_ctx ) ;
return PyErr_NoMemory ( ) ;
}
2009-06-17 21:01:06 +04:00
}
2008-12-19 19:08:35 +03:00
2008-12-23 07:07:29 +03:00
py_ret = ( PyLdbMessageObject * ) type - > tp_alloc ( type , 0 ) ;
if ( py_ret = = NULL ) {
PyErr_NoMemory ( ) ;
2009-08-03 20:15:16 +04:00
talloc_free ( mem_ctx ) ;
2008-12-23 07:07:29 +03:00
return NULL ;
}
2009-08-03 20:15:16 +04:00
py_ret - > mem_ctx = mem_ctx ;
py_ret - > msg = ret ;
2023-11-08 00:43:38 +03:00
if ( pydn ! = NULL ) {
py_ret - > pyldb = ( ( PyLdbDnObject * ) pydn ) - > pyldb ;
Py_INCREF ( py_ret - > pyldb ) ;
}
2008-12-23 07:07:29 +03:00
return ( PyObject * ) py_ret ;
2008-12-19 04:22:07 +03:00
}
2023-11-08 00:43:38 +03:00
static PyObject * PyLdbMessage_FromMessage ( struct ldb_message * msg , PyLdbObject * pyldb )
2008-12-19 04:22:07 +03:00
{
2023-08-25 05:22:15 +03:00
TALLOC_CTX * mem_ctx = NULL ;
struct ldb_message * msg_ref = NULL ;
2008-12-23 07:07:29 +03:00
PyLdbMessageObject * ret ;
2023-08-25 05:22:15 +03:00
mem_ctx = talloc_new ( NULL ) ;
if ( mem_ctx = = NULL ) {
return PyErr_NoMemory ( ) ;
}
msg_ref = talloc_reference ( mem_ctx , msg ) ;
if ( msg_ref = = NULL ) {
talloc_free ( mem_ctx ) ;
return PyErr_NoMemory ( ) ;
}
2008-12-23 07:07:29 +03:00
ret = ( PyLdbMessageObject * ) PyLdbMessage . tp_alloc ( & PyLdbMessage , 0 ) ;
if ( ret = = NULL ) {
2023-08-25 05:22:15 +03:00
talloc_free ( mem_ctx ) ;
2008-12-23 07:07:29 +03:00
PyErr_NoMemory ( ) ;
return NULL ;
}
2023-08-25 05:22:15 +03:00
ret - > mem_ctx = mem_ctx ;
ret - > msg = msg_ref ;
2023-11-08 00:43:38 +03:00
ret - > pyldb = pyldb ;
Py_INCREF ( ret - > pyldb ) ;
2008-12-23 07:07:29 +03:00
return ( PyObject * ) ret ;
2008-12-19 04:22:07 +03:00
}
2024-03-15 03:08:03 +03:00
static PyObject * py_ldb_msg_get_dn ( PyObject * self , void * closure )
2008-12-19 19:08:35 +03:00
{
2024-03-15 03:08:03 +03:00
struct ldb_message * msg = NULL ;
PyErr_LDB_MESSAGE_OR_RAISE ( self , msg ) ;
return pyldb_Dn_FromDn ( msg - > dn , pyldb_Message_get_pyldb ( self ) ) ;
2008-12-19 19:08:35 +03:00
}
2024-03-15 07:17:25 +03:00
static int py_ldb_msg_set_dn ( PyObject * self , PyObject * value , void * closure )
2008-12-19 19:08:35 +03:00
{
2024-03-15 07:17:25 +03:00
/*
* no PyErr_LDB_MESSAGE_OR_RAISE here , because this returns int .
*
* Also , since this is trying to replace the dn , we don ' t need to
* check the old one .
*/
struct ldb_message * msg = pyldb_Message_as_message ( self ) ;
2023-08-25 05:22:15 +03:00
struct ldb_dn * dn = NULL ;
2024-03-15 07:17:25 +03:00
PyLdbObject * pyldb = pyldb_Message_get_pyldb ( self ) ;
PyLdbMessageObject * self_as_msg = ( PyLdbMessageObject * ) self ;
2021-09-25 02:12:16 +03:00
if ( value = = NULL ) {
PyErr_SetString ( PyExc_AttributeError , " cannot delete dn " ) ;
return - 1 ;
}
2011-08-07 19:08:56 +04:00
if ( ! pyldb_Dn_Check ( value ) ) {
2015-03-04 00:29:12 +03:00
PyErr_SetString ( PyExc_TypeError , " expected dn " ) ;
2009-08-03 20:15:16 +04:00
return - 1 ;
}
2023-08-25 05:22:15 +03:00
dn = talloc_reference ( msg , pyldb_Dn_AS_DN ( value ) ) ;
if ( dn = = NULL ) {
PyErr_NoMemory ( ) ;
return - 1 ;
}
2024-03-15 07:17:25 +03:00
if ( pyldb ! = NULL ) {
if ( pyldb - > ldb_ctx ! = ldb_dn_get_ldb_context ( dn ) ) {
PyErr_SetString ( PyExc_RuntimeError ,
" DN is from the wrong LDB " ) ;
return - 1 ;
}
Py_DECREF ( pyldb ) ;
2023-11-08 00:43:38 +03:00
}
2024-03-15 07:17:25 +03:00
msg - > dn = dn ;
self_as_msg - > pyldb = ( ( PyLdbDnObject * ) value ) - > pyldb ;
Py_INCREF ( self_as_msg - > pyldb ) ;
2023-11-08 00:43:38 +03:00
2008-12-19 19:08:35 +03:00
return 0 ;
}
2015-06-09 18:44:40 +03:00
static PyObject * py_ldb_msg_get_text ( PyObject * self , void * closure )
{
return wrap_text ( " MessageTextWrapper " , self ) ;
}
2024-03-17 04:25:18 +03:00
static PyObject * py_ldb_msg_get_ldb ( PyLdbMessageObject * self , void * closure )
{
if ( self - > pyldb = = NULL ) {
Py_RETURN_NONE ;
}
Py_INCREF ( self - > pyldb ) ;
return ( PyObject * ) self - > pyldb ;
}
2008-12-19 19:08:35 +03:00
static PyGetSetDef py_ldb_msg_getset [ ] = {
2018-12-13 13:34:37 +03:00
{
. name = discard_const_p ( char , " dn " ) ,
. get = ( getter ) py_ldb_msg_get_dn ,
. set = ( setter ) py_ldb_msg_set_dn ,
} ,
{
. name = discard_const_p ( char , " text " ) ,
. get = ( getter ) py_ldb_msg_get_text ,
} ,
2024-03-17 04:25:18 +03:00
{
. name = discard_const_p ( char , " ldb " ) ,
. get = ( getter ) py_ldb_msg_get_ldb ,
. doc = discard_const_p (
char , " returns the associated ldb object (or None) " )
} ,
2018-12-13 13:34:37 +03:00
{ . name = NULL } ,
2008-12-19 19:08:35 +03:00
} ;
2008-12-21 00:21:39 +03:00
static PyObject * py_ldb_msg_repr ( PyLdbMessageObject * self )
{
2015-06-10 16:41:57 +03:00
PyObject * dict = PyDict_New ( ) , * ret , * repr ;
2023-08-25 05:20:50 +03:00
const char * repr_str = NULL ;
if ( dict = = NULL ) {
return NULL ;
}
2023-08-30 00:47:28 +03:00
if ( PyDict_Update ( dict , ( PyObject * ) self ) ! = 0 ) {
Py_DECREF ( dict ) ;
2008-12-21 00:21:39 +03:00
return NULL ;
2023-08-30 00:47:28 +03:00
}
2015-06-10 16:41:57 +03:00
repr = PyObject_Repr ( dict ) ;
if ( repr = = NULL ) {
Py_DECREF ( dict ) ;
return NULL ;
}
2023-08-25 05:20:50 +03:00
repr_str = PyUnicode_AsUTF8 ( repr ) ;
if ( repr_str = = NULL ) {
Py_DECREF ( repr ) ;
Py_DECREF ( dict ) ;
return NULL ;
}
ret = PyUnicode_FromFormat ( " Message(%s) " , repr_str ) ;
2015-06-10 16:41:57 +03:00
Py_DECREF ( repr ) ;
2008-12-21 00:21:39 +03:00
Py_DECREF ( dict ) ;
return ret ;
}
2008-12-23 07:07:29 +03:00
static void py_ldb_msg_dealloc ( PyLdbMessageObject * self )
{
talloc_free ( self - > mem_ctx ) ;
2023-11-08 00:43:38 +03:00
/* The pyldb element will only be present if a DN is assigned */
if ( self - > pyldb ) {
Py_DECREF ( self - > pyldb ) ;
}
2010-12-29 17:58:12 +03:00
PyObject_Del ( self ) ;
2008-12-23 07:07:29 +03:00
}
2015-06-09 11:36:26 +03:00
static PyObject * py_ldb_msg_richcmp ( PyLdbMessageObject * py_msg1 ,
PyLdbMessageObject * py_msg2 , int op )
2010-05-07 04:15:28 +04:00
{
2015-06-09 11:36:26 +03:00
struct ldb_message * msg1 , * msg2 ;
2010-05-07 04:15:28 +04:00
unsigned int i ;
int ret ;
2024-03-13 07:28:07 +03:00
if ( ! pyldb_Message_Check ( py_msg2 ) ) {
2015-06-09 11:36:26 +03:00
Py_INCREF ( Py_NotImplemented ) ;
return Py_NotImplemented ;
}
2024-03-15 07:04:59 +03:00
PyErr_LDB_MESSAGE_OR_RAISE ( py_msg1 , msg1 ) ;
PyErr_LDB_MESSAGE_OR_RAISE ( py_msg2 , msg2 ) ;
2024-03-14 06:36:07 +03:00
/*
* FIXME : this can be a non - transitive compare , unsuitable for
* sorting .
*
* supposing msg1 , msg2 , and msg3 have 1 , 2 , and 3 elements
* each . msg2 has a NULL DN , while msg1 has a DN that compares
* higher than msg3 . Then :
*
* msg1 < msg2 , due to num_elements .
* msg2 < msg3 , due to num_elements .
* msg1 > msg3 , due to DNs .
*/
2010-06-07 23:26:33 +04:00
if ( ( msg1 - > dn ! = NULL ) | | ( msg2 - > dn ! = NULL ) ) {
ret = ldb_dn_compare ( msg1 - > dn , msg2 - > dn ) ;
if ( ret ! = 0 ) {
2015-06-09 11:36:26 +03:00
return richcmp ( ret , op ) ;
2010-06-07 23:26:33 +04:00
}
2010-05-07 04:15:28 +04:00
}
2024-03-15 05:47:55 +03:00
if ( msg1 - > num_elements > msg2 - > num_elements ) {
return richcmp ( 1 , op ) ;
}
if ( msg1 - > num_elements < msg2 - > num_elements ) {
return richcmp ( - 1 , op ) ;
2010-05-07 04:15:28 +04:00
}
for ( i = 0 ; i < msg1 - > num_elements ; i + + ) {
ret = ldb_msg_element_compare_name ( & msg1 - > elements [ i ] ,
& msg2 - > elements [ i ] ) ;
if ( ret ! = 0 ) {
2015-06-09 11:36:26 +03:00
return richcmp ( ret , op ) ;
2010-05-07 04:15:28 +04:00
}
ret = ldb_msg_element_compare ( & msg1 - > elements [ i ] ,
& msg2 - > elements [ i ] ) ;
if ( ret ! = 0 ) {
2015-06-09 11:36:26 +03:00
return richcmp ( ret , op ) ;
2010-05-07 04:15:28 +04:00
}
}
2015-06-09 11:36:26 +03:00
return richcmp ( 0 , op ) ;
2010-05-07 04:15:28 +04:00
}
2010-12-30 21:39:14 +03:00
static PyTypeObject PyLdbMessage = {
2010-04-04 03:48:35 +04:00
. tp_name = " ldb.Message " ,
2008-12-19 04:22:07 +03:00
. tp_methods = py_ldb_msg_methods ,
2008-12-19 19:08:35 +03:00
. tp_getset = py_ldb_msg_getset ,
2021-09-25 05:39:59 +03:00
. tp_as_sequence = & py_ldb_msg_sequence ,
2008-12-19 04:22:07 +03:00
. tp_as_mapping = & py_ldb_msg_mapping ,
. tp_basicsize = sizeof ( PyLdbMessageObject ) ,
2008-12-23 07:07:29 +03:00
. tp_dealloc = ( destructor ) py_ldb_msg_dealloc ,
2008-12-19 04:22:07 +03:00
. tp_new = py_ldb_msg_new ,
2008-12-21 00:21:39 +03:00
. tp_repr = ( reprfunc ) py_ldb_msg_repr ,
2008-12-21 05:08:14 +03:00
. tp_flags = Py_TPFLAGS_DEFAULT ,
2008-12-21 06:36:16 +03:00
. tp_iter = ( getiterfunc ) py_ldb_msg_iter ,
2015-06-09 11:36:26 +03:00
. tp_richcompare = ( richcmpfunc ) py_ldb_msg_richcmp ,
2011-12-08 23:28:18 +04:00
. tp_doc = " A LDB Message " ,
2008-12-19 04:22:07 +03:00
} ;
2008-12-23 07:07:29 +03:00
static void py_ldb_tree_dealloc ( PyLdbTreeObject * self )
{
talloc_free ( self - > mem_ctx ) ;
2010-12-29 17:58:12 +03:00
PyObject_Del ( self ) ;
2008-12-19 19:08:35 +03:00
}
2010-12-30 21:39:14 +03:00
static PyTypeObject PyLdbTree = {
2010-04-04 03:48:35 +04:00
. tp_name = " ldb.Tree " ,
2008-12-19 19:08:35 +03:00
. tp_basicsize = sizeof ( PyLdbTreeObject ) ,
2008-12-23 07:07:29 +03:00
. tp_dealloc = ( destructor ) py_ldb_tree_dealloc ,
2008-12-21 05:08:14 +03:00
. tp_flags = Py_TPFLAGS_DEFAULT ,
2011-12-08 23:28:18 +04:00
. tp_doc = " A search tree " ,
2008-12-19 19:08:35 +03:00
} ;
2008-12-19 04:22:07 +03:00
static PyObject * py_timestring ( PyObject * module , PyObject * args )
{
2010-11-06 18:29:27 +03:00
/* most times "time_t" is a signed integer type with 32 or 64 bit:
* http : //stackoverflow.com/questions/471248/what-is-ultimately-a-time-t-typedef-to */
long int t_val ;
2008-12-19 04:22:07 +03:00
char * tresult ;
PyObject * ret ;
2010-11-06 18:29:27 +03:00
if ( ! PyArg_ParseTuple ( args , " l " , & t_val ) )
2008-12-19 04:22:07 +03:00
return NULL ;
2010-11-06 18:29:27 +03:00
tresult = ldb_timestring ( NULL , ( time_t ) t_val ) ;
2021-01-19 18:53:55 +03:00
if ( tresult = = NULL ) {
/*
* Most likely EOVERFLOW from gmtime ( )
*/
PyErr_SetFromErrno ( PyExc_OSError ) ;
return NULL ;
}
2019-06-07 11:45:52 +03:00
ret = PyUnicode_FromString ( tresult ) ;
2008-12-21 00:21:39 +03:00
talloc_free ( tresult ) ;
return ret ;
2008-12-19 04:22:07 +03:00
}
static PyObject * py_string_to_time ( PyObject * module , PyObject * args )
{
char * str ;
2024-02-14 04:22:53 +03:00
time_t t ;
if ( ! PyArg_ParseTuple ( args , " s " , & str ) ) {
2008-12-19 04:22:07 +03:00
return NULL ;
2024-02-14 04:22:53 +03:00
}
t = ldb_string_to_time ( str ) ;
2008-12-19 04:22:07 +03:00
2024-02-14 04:22:53 +03:00
if ( t = = 0 & & errno ! = 0 ) {
PyErr_SetFromErrno ( PyExc_ValueError ) ;
return NULL ;
}
return PyLong_FromLong ( t ) ;
2008-12-19 04:22:07 +03:00
}
static PyObject * py_valid_attr_name ( PyObject * self , PyObject * args )
{
char * name ;
if ( ! PyArg_ParseTuple ( args , " s " , & name ) )
return NULL ;
return PyBool_FromLong ( ldb_valid_attr_name ( name ) ) ;
}
2011-07-28 11:03:06 +04:00
/*
encode a string using RFC2254 rules
*/
static PyObject * py_binary_encode ( PyObject * self , PyObject * args )
{
char * str , * encoded ;
2016-01-04 02:42:06 +03:00
Py_ssize_t size = 0 ;
2011-07-28 11:03:06 +04:00
struct ldb_val val ;
PyObject * ret ;
if ( ! PyArg_ParseTuple ( args , " s# " , & str , & size ) )
return NULL ;
val . data = ( uint8_t * ) str ;
val . length = size ;
encoded = ldb_binary_encode ( NULL , val ) ;
if ( encoded = = NULL ) {
PyErr_SetString ( PyExc_TypeError , " unable to encode binary string " ) ;
return NULL ;
}
2019-06-07 11:45:52 +03:00
ret = PyUnicode_FromString ( encoded ) ;
2011-07-28 11:03:06 +04:00
talloc_free ( encoded ) ;
return ret ;
}
/*
decode a string using RFC2254 rules
*/
static PyObject * py_binary_decode ( PyObject * self , PyObject * args )
{
char * str ;
struct ldb_val val ;
PyObject * ret ;
if ( ! PyArg_ParseTuple ( args , " s " , & str ) )
return NULL ;
val = ldb_binary_decode ( NULL , str ) ;
if ( val . data = = NULL ) {
PyErr_SetString ( PyExc_TypeError , " unable to decode binary string " ) ;
return NULL ;
}
2015-06-09 18:44:40 +03:00
ret = PyBytes_FromStringAndSize ( ( const char * ) val . data , val . length ) ;
2011-07-28 11:03:06 +04:00
talloc_free ( val . data ) ;
return ret ;
}
2008-12-19 04:22:07 +03:00
static PyMethodDef py_ldb_global_methods [ ] = {
2024-02-29 03:07:47 +03:00
{ " timestring " , py_timestring , METH_VARARGS ,
2011-12-08 23:28:18 +04:00
" S.timestring(int) -> string \n \n "
2008-12-19 04:22:07 +03:00
" Generate a LDAP time string from a UNIX timestamp " } ,
{ " string_to_time " , py_string_to_time , METH_VARARGS ,
2011-12-08 23:28:18 +04:00
" S.string_to_time(string) -> int \n \n "
2008-12-19 04:22:07 +03:00
" Parse a LDAP time string into a UNIX timestamp. " } ,
{ " valid_attr_name " , py_valid_attr_name , METH_VARARGS ,
2021-01-18 18:48:21 +03:00
" S.valid_attr_name(name) -> bool \n \n "
2008-12-19 04:22:07 +03:00
" Check whether the supplied name is a valid attribute name. " } ,
2011-07-28 11:03:06 +04:00
{ " binary_encode " , py_binary_encode , METH_VARARGS ,
2011-12-08 23:28:18 +04:00
" S.binary_encode(string) -> string \n \n "
2011-07-28 11:03:06 +04:00
" Perform a RFC2254 binary encoding on a string " } ,
{ " binary_decode " , py_binary_decode , METH_VARARGS ,
2011-12-08 23:28:18 +04:00
" S.binary_decode(string) -> string \n \n "
2011-07-28 11:03:06 +04:00
" Perform a RFC2254 binary decode on a string " } ,
2020-05-05 04:47:39 +03:00
{ 0 }
2008-12-19 04:22:07 +03:00
} ;
2015-06-09 11:36:26 +03:00
# define MODULE_DOC "An interface to LDB, a LDAP-like API that can either to talk an embedded database (TDB-based) or a standards-compliant LDAP server."
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT ,
. m_name = " ldb " ,
. m_doc = MODULE_DOC ,
. m_size = - 1 ,
. m_methods = py_ldb_global_methods ,
} ;
static PyObject * module_init ( void )
2008-12-19 04:22:07 +03:00
{
PyObject * m ;
2018-05-11 15:48:29 +03:00
PyLdbBytesType . tp_base = & PyBytes_Type ;
if ( PyType_Ready ( & PyLdbBytesType ) < 0 ) {
return NULL ;
}
2008-12-19 04:22:07 +03:00
if ( PyType_Ready ( & PyLdbDn ) < 0 )
2015-06-09 11:36:26 +03:00
return NULL ;
2008-12-19 04:22:07 +03:00
if ( PyType_Ready ( & PyLdbMessage ) < 0 )
2015-06-09 11:36:26 +03:00
return NULL ;
2008-12-19 04:22:07 +03:00
if ( PyType_Ready ( & PyLdbMessageElement ) < 0 )
2015-06-09 11:36:26 +03:00
return NULL ;
2008-12-19 04:22:07 +03:00
if ( PyType_Ready ( & PyLdb ) < 0 )
2015-06-09 11:36:26 +03:00
return NULL ;
2008-12-19 04:22:07 +03:00
2008-12-19 19:08:35 +03:00
if ( PyType_Ready ( & PyLdbTree ) < 0 )
2015-06-09 11:36:26 +03:00
return NULL ;
2008-12-19 19:08:35 +03:00
2011-02-07 09:50:36 +03:00
if ( PyType_Ready ( & PyLdbResult ) < 0 )
2015-06-09 11:36:26 +03:00
return NULL ;
2011-02-07 09:50:36 +03:00
2016-01-22 02:06:45 +03:00
if ( PyType_Ready ( & PyLdbSearchIterator ) < 0 )
return NULL ;
2011-02-07 09:50:36 +03:00
if ( PyType_Ready ( & PyLdbControl ) < 0 )
2015-06-09 11:36:26 +03:00
return NULL ;
2011-02-07 09:50:36 +03:00
2015-06-09 11:36:26 +03:00
m = PyModule_Create ( & moduledef ) ;
2008-12-19 04:22:07 +03:00
if ( m = = NULL )
2015-06-09 11:36:26 +03:00
return NULL ;
# define ADD_LDB_INT(val) PyModule_AddIntConstant(m, #val, LDB_ ## val)
ADD_LDB_INT ( SEQ_HIGHEST_SEQ ) ;
ADD_LDB_INT ( SEQ_HIGHEST_TIMESTAMP ) ;
ADD_LDB_INT ( SEQ_NEXT ) ;
ADD_LDB_INT ( SCOPE_DEFAULT ) ;
ADD_LDB_INT ( SCOPE_BASE ) ;
ADD_LDB_INT ( SCOPE_ONELEVEL ) ;
ADD_LDB_INT ( SCOPE_SUBTREE ) ;
ADD_LDB_INT ( CHANGETYPE_NONE ) ;
ADD_LDB_INT ( CHANGETYPE_ADD ) ;
ADD_LDB_INT ( CHANGETYPE_DELETE ) ;
ADD_LDB_INT ( CHANGETYPE_MODIFY ) ;
2023-03-13 16:58:29 +03:00
ADD_LDB_INT ( CHANGETYPE_MODRDN ) ;
2015-06-09 11:36:26 +03:00
ADD_LDB_INT ( FLAG_MOD_ADD ) ;
ADD_LDB_INT ( FLAG_MOD_REPLACE ) ;
ADD_LDB_INT ( FLAG_MOD_DELETE ) ;
2019-02-19 14:29:58 +03:00
ADD_LDB_INT ( FLAG_FORCE_NO_BASE64_LDIF ) ;
2015-06-09 11:36:26 +03:00
2016-02-05 15:55:31 +03:00
ADD_LDB_INT ( ATTR_FLAG_HIDDEN ) ;
ADD_LDB_INT ( ATTR_FLAG_UNIQUE_INDEX ) ;
ADD_LDB_INT ( ATTR_FLAG_SINGLE_VALUE ) ;
ADD_LDB_INT ( ATTR_FLAG_FORCE_BASE64_LDIF ) ;
2015-06-09 11:36:26 +03:00
ADD_LDB_INT ( SUCCESS ) ;
ADD_LDB_INT ( ERR_OPERATIONS_ERROR ) ;
ADD_LDB_INT ( ERR_PROTOCOL_ERROR ) ;
ADD_LDB_INT ( ERR_TIME_LIMIT_EXCEEDED ) ;
ADD_LDB_INT ( ERR_SIZE_LIMIT_EXCEEDED ) ;
ADD_LDB_INT ( ERR_COMPARE_FALSE ) ;
ADD_LDB_INT ( ERR_COMPARE_TRUE ) ;
ADD_LDB_INT ( ERR_AUTH_METHOD_NOT_SUPPORTED ) ;
ADD_LDB_INT ( ERR_STRONG_AUTH_REQUIRED ) ;
ADD_LDB_INT ( ERR_REFERRAL ) ;
ADD_LDB_INT ( ERR_ADMIN_LIMIT_EXCEEDED ) ;
ADD_LDB_INT ( ERR_UNSUPPORTED_CRITICAL_EXTENSION ) ;
ADD_LDB_INT ( ERR_CONFIDENTIALITY_REQUIRED ) ;
ADD_LDB_INT ( ERR_SASL_BIND_IN_PROGRESS ) ;
ADD_LDB_INT ( ERR_NO_SUCH_ATTRIBUTE ) ;
ADD_LDB_INT ( ERR_UNDEFINED_ATTRIBUTE_TYPE ) ;
ADD_LDB_INT ( ERR_INAPPROPRIATE_MATCHING ) ;
ADD_LDB_INT ( ERR_CONSTRAINT_VIOLATION ) ;
ADD_LDB_INT ( ERR_ATTRIBUTE_OR_VALUE_EXISTS ) ;
ADD_LDB_INT ( ERR_INVALID_ATTRIBUTE_SYNTAX ) ;
ADD_LDB_INT ( ERR_NO_SUCH_OBJECT ) ;
ADD_LDB_INT ( ERR_ALIAS_PROBLEM ) ;
ADD_LDB_INT ( ERR_INVALID_DN_SYNTAX ) ;
ADD_LDB_INT ( ERR_ALIAS_DEREFERENCING_PROBLEM ) ;
ADD_LDB_INT ( ERR_INAPPROPRIATE_AUTHENTICATION ) ;
ADD_LDB_INT ( ERR_INVALID_CREDENTIALS ) ;
ADD_LDB_INT ( ERR_INSUFFICIENT_ACCESS_RIGHTS ) ;
ADD_LDB_INT ( ERR_BUSY ) ;
ADD_LDB_INT ( ERR_UNAVAILABLE ) ;
ADD_LDB_INT ( ERR_UNWILLING_TO_PERFORM ) ;
ADD_LDB_INT ( ERR_LOOP_DETECT ) ;
ADD_LDB_INT ( ERR_NAMING_VIOLATION ) ;
ADD_LDB_INT ( ERR_OBJECT_CLASS_VIOLATION ) ;
ADD_LDB_INT ( ERR_NOT_ALLOWED_ON_NON_LEAF ) ;
ADD_LDB_INT ( ERR_NOT_ALLOWED_ON_RDN ) ;
ADD_LDB_INT ( ERR_ENTRY_ALREADY_EXISTS ) ;
ADD_LDB_INT ( ERR_OBJECT_CLASS_MODS_PROHIBITED ) ;
ADD_LDB_INT ( ERR_AFFECTS_MULTIPLE_DSAS ) ;
ADD_LDB_INT ( ERR_OTHER ) ;
ADD_LDB_INT ( FLG_RDONLY ) ;
ADD_LDB_INT ( FLG_NOSYNC ) ;
ADD_LDB_INT ( FLG_RECONNECT ) ;
ADD_LDB_INT ( FLG_NOMMAP ) ;
2018-01-08 21:41:32 +03:00
ADD_LDB_INT ( FLG_SHOW_BINARY ) ;
ADD_LDB_INT ( FLG_ENABLE_TRACING ) ;
ADD_LDB_INT ( FLG_DONT_CREATE_DB ) ;
2019-05-20 08:59:33 +03:00
ADD_LDB_INT ( PACKING_FORMAT ) ;
ADD_LDB_INT ( PACKING_FORMAT_V2 ) ;
2015-06-09 11:36:26 +03:00
/* Historical misspelling */
PyModule_AddIntConstant ( m , " ERR_ALIAS_DEREFERINCING_PROBLEM " , LDB_ERR_ALIAS_DEREFERENCING_PROBLEM ) ;
PyModule_AddStringConstant ( m , " __docformat__ " , " restructuredText " ) ;
2008-12-19 04:22:07 +03:00
2009-02-05 13:04:28 +03:00
PyExc_LdbError = PyErr_NewException ( discard_const_p ( char , " _ldb.LdbError " ) , NULL , NULL ) ;
2008-12-21 00:21:39 +03:00
PyModule_AddObject ( m , " LdbError " , PyExc_LdbError ) ;
2008-12-19 04:22:07 +03:00
2008-12-19 16:41:44 +03:00
Py_INCREF ( & PyLdb ) ;
Py_INCREF ( & PyLdbDn ) ;
Py_INCREF ( & PyLdbMessage ) ;
Py_INCREF ( & PyLdbMessageElement ) ;
2008-12-19 19:08:35 +03:00
Py_INCREF ( & PyLdbTree ) ;
2011-02-07 09:50:36 +03:00
Py_INCREF ( & PyLdbResult ) ;
Py_INCREF ( & PyLdbControl ) ;
2008-12-19 04:22:07 +03:00
2008-12-19 16:41:44 +03:00
PyModule_AddObject ( m , " Ldb " , ( PyObject * ) & PyLdb ) ;
PyModule_AddObject ( m , " Dn " , ( PyObject * ) & PyLdbDn ) ;
PyModule_AddObject ( m , " Message " , ( PyObject * ) & PyLdbMessage ) ;
PyModule_AddObject ( m , " MessageElement " , ( PyObject * ) & PyLdbMessageElement ) ;
2008-12-19 19:08:35 +03:00
PyModule_AddObject ( m , " Tree " , ( PyObject * ) & PyLdbTree ) ;
2024-02-15 07:07:34 +03:00
PyModule_AddObject ( m , " Result " , ( PyObject * ) & PyLdbResult ) ;
2011-02-07 09:50:36 +03:00
PyModule_AddObject ( m , " Control " , ( PyObject * ) & PyLdbControl ) ;
2010-10-05 02:36:21 +04:00
2015-06-09 11:36:26 +03:00
PyModule_AddStringConstant ( m , " __version__ " , PACKAGE_VERSION ) ;
2011-06-22 06:34:32 +04:00
2015-06-09 11:36:26 +03:00
# define ADD_LDB_STRING(val) PyModule_AddStringConstant(m, #val, LDB_## val)
2011-08-31 09:55:27 +04:00
ADD_LDB_STRING ( SYNTAX_DN ) ;
ADD_LDB_STRING ( SYNTAX_DIRECTORY_STRING ) ;
ADD_LDB_STRING ( SYNTAX_INTEGER ) ;
2019-03-14 08:05:23 +03:00
ADD_LDB_STRING ( SYNTAX_ORDERED_INTEGER ) ;
2011-08-31 09:55:27 +04:00
ADD_LDB_STRING ( SYNTAX_BOOLEAN ) ;
ADD_LDB_STRING ( SYNTAX_OCTET_STRING ) ;
ADD_LDB_STRING ( SYNTAX_UTC_TIME ) ;
ADD_LDB_STRING ( OID_COMPARATOR_AND ) ;
ADD_LDB_STRING ( OID_COMPARATOR_OR ) ;
2015-06-09 11:36:26 +03:00
return m ;
2008-12-19 04:22:07 +03:00
}
2015-06-09 11:36:26 +03:00
PyMODINIT_FUNC PyInit_ldb ( void ) ;
PyMODINIT_FUNC PyInit_ldb ( void )
{
return module_init ( ) ;
}