Fixes for memory leaks by Chris Mikkelson
This commit is contained in:
377
Modules/ldapcontrol.c
Normal file
377
Modules/ldapcontrol.c
Normal file
@@ -0,0 +1,377 @@
|
||||
/* See http://www.python-ldap.org/ for details.
|
||||
* $Id: ldapcontrol.c,v 1.20 2011/10/26 18:38:06 stroeder Exp $ */
|
||||
|
||||
#include "common.h"
|
||||
#include "LDAPObject.h"
|
||||
#include "ldapcontrol.h"
|
||||
#include "berval.h"
|
||||
#include "errors.h"
|
||||
|
||||
#include "lber.h"
|
||||
|
||||
/* Prints to stdout the contents of an array of LDAPControl objects */
|
||||
|
||||
/* XXX: This is a debugging tool, and the printf generates some warnings
|
||||
* about pointer types. I left it here in case something breaks and we
|
||||
* need to inspect an LDAPControl structure.
|
||||
|
||||
static void
|
||||
LDAPControl_DumpList( LDAPControl** lcs ) {
|
||||
LDAPControl** lcp;
|
||||
LDAPControl* lc;
|
||||
for ( lcp = lcs; *lcp; lcp++ ) {
|
||||
lc = *lcp;
|
||||
printf("OID: %s\nCriticality: %d\nBER length: %d\nBER value: %x\n",
|
||||
lc->ldctl_oid, lc->ldctl_iscritical, lc->ldctl_value.bv_len,
|
||||
lc->ldctl_value.bv_val);
|
||||
}
|
||||
} */
|
||||
|
||||
/* Free a single LDAPControl object created by Tuple_to_LDAPControl */
|
||||
|
||||
static void
|
||||
LDAPControl_DEL( LDAPControl* lc )
|
||||
{
|
||||
if (lc == NULL)
|
||||
return;
|
||||
|
||||
if (lc->ldctl_oid)
|
||||
PyMem_DEL(lc->ldctl_oid);
|
||||
PyMem_DEL(lc);
|
||||
}
|
||||
|
||||
/* Free an array of LDAPControl objects created by LDAPControls_from_object */
|
||||
|
||||
void
|
||||
LDAPControl_List_DEL( LDAPControl** lcs )
|
||||
{
|
||||
LDAPControl** lcp;
|
||||
if (lcs == NULL)
|
||||
return;
|
||||
|
||||
for ( lcp = lcs; *lcp; lcp++ )
|
||||
LDAPControl_DEL( *lcp );
|
||||
|
||||
PyMem_DEL( lcs );
|
||||
}
|
||||
|
||||
/* Takes a tuple of the form:
|
||||
* (OID: string, Criticality: int/boolean, Value: string/None)
|
||||
* and converts it into an LDAPControl structure.
|
||||
*
|
||||
* The Value string should represent an ASN.1 encoded structure.
|
||||
*/
|
||||
|
||||
static LDAPControl*
|
||||
Tuple_to_LDAPControl( PyObject* tup )
|
||||
{
|
||||
char *oid;
|
||||
char iscritical;
|
||||
struct berval berbytes;
|
||||
PyObject *bytes;
|
||||
LDAPControl *lc = NULL;
|
||||
Py_ssize_t len;
|
||||
|
||||
if (!PyTuple_Check(tup)) {
|
||||
PyErr_SetObject(PyExc_TypeError, Py_BuildValue("sO",
|
||||
"expected a tuple", tup));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!PyArg_ParseTuple( tup, "sbO", &oid, &iscritical, &bytes ))
|
||||
return NULL;
|
||||
|
||||
lc = PyMem_NEW(LDAPControl, 1);
|
||||
if (lc == NULL) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lc->ldctl_iscritical = iscritical;
|
||||
|
||||
len = strlen(oid);
|
||||
lc->ldctl_oid = PyMem_NEW(char, len + 1);
|
||||
if (lc->ldctl_oid == NULL) {
|
||||
PyErr_NoMemory();
|
||||
LDAPControl_DEL(lc);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(lc->ldctl_oid, oid, len + 1);
|
||||
|
||||
/* The berval can either be None or a String */
|
||||
if (PyNone_Check(bytes)) {
|
||||
berbytes.bv_len = 0;
|
||||
berbytes.bv_val = NULL;
|
||||
}
|
||||
else if (PyString_Check(bytes)) {
|
||||
berbytes.bv_len = PyString_Size(bytes);
|
||||
berbytes.bv_val = PyString_AsString(bytes);
|
||||
}
|
||||
else {
|
||||
PyErr_SetObject(PyExc_TypeError, Py_BuildValue("sO",
|
||||
"expected a string", bytes));
|
||||
LDAPControl_DEL(lc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lc->ldctl_value = berbytes;
|
||||
|
||||
return lc;
|
||||
}
|
||||
|
||||
/* Convert a list of tuples (of a format acceptable to the Tuple_to_LDAPControl
|
||||
* function) into an array of LDAPControl objects. */
|
||||
|
||||
int
|
||||
LDAPControls_from_object(PyObject* list, LDAPControl ***controls_ret)
|
||||
{
|
||||
Py_ssize_t len, i;
|
||||
LDAPControl** ldcs;
|
||||
LDAPControl* ldc;
|
||||
PyObject* item;
|
||||
|
||||
if (!PySequence_Check(list)) {
|
||||
PyErr_SetObject(PyExc_TypeError, Py_BuildValue("sO",
|
||||
"expected a list", list));
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = PySequence_Length(list);
|
||||
ldcs = PyMem_NEW(LDAPControl*, len + 1);
|
||||
if (ldcs == NULL) {
|
||||
PyErr_NoMemory();
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
item = PySequence_GetItem(list, i);
|
||||
if (item == NULL) {
|
||||
PyMem_DEL(ldcs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ldc = Tuple_to_LDAPControl(item);
|
||||
if (ldc == NULL) {
|
||||
Py_DECREF(item);
|
||||
PyMem_DEL(ldcs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ldcs[i] = ldc;
|
||||
Py_DECREF(item);
|
||||
}
|
||||
|
||||
ldcs[len] = NULL;
|
||||
*controls_ret = ldcs;
|
||||
return 1;
|
||||
}
|
||||
|
||||
PyObject*
|
||||
LDAPControls_to_List(LDAPControl **ldcs)
|
||||
{
|
||||
PyObject *res = 0, *pyctrl;
|
||||
LDAPControl **tmp = ldcs;
|
||||
Py_ssize_t num_ctrls = 0, i;
|
||||
|
||||
if (tmp)
|
||||
while (*tmp++) num_ctrls++;
|
||||
|
||||
if (!(res = PyList_New(num_ctrls)))
|
||||
goto endlbl;
|
||||
|
||||
for (i = 0; i < num_ctrls; i++) {
|
||||
if (!(pyctrl = Py_BuildValue("sbO&", ldcs[i]->ldctl_oid,
|
||||
ldcs[i]->ldctl_iscritical,
|
||||
LDAPberval_to_object,
|
||||
&ldcs[i]->ldctl_value))) {
|
||||
goto endlbl;
|
||||
}
|
||||
PyList_SET_ITEM(res, i, pyctrl);
|
||||
}
|
||||
Py_INCREF(res);
|
||||
|
||||
endlbl:
|
||||
Py_XDECREF(res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* --------------- en-/decoders ------------- */
|
||||
|
||||
/* Matched Values, aka, Values Return Filter */
|
||||
static PyObject*
|
||||
encode_rfc3876(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *res = 0;
|
||||
int err;
|
||||
BerElement *vrber = 0;
|
||||
char *vrFilter;
|
||||
struct berval *ctrl_val;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:encode_valuesreturnfilter_control", &vrFilter)) {
|
||||
goto endlbl;
|
||||
}
|
||||
|
||||
if (!(vrber = ber_alloc_t(LBER_USE_DER))) {
|
||||
LDAPerr(LDAP_NO_MEMORY);
|
||||
goto endlbl;
|
||||
}
|
||||
|
||||
err = ldap_put_vrFilter(vrber, vrFilter);
|
||||
if (err == -1) {
|
||||
LDAPerr(LDAP_FILTER_ERROR);
|
||||
goto endlbl;
|
||||
}
|
||||
|
||||
err = ber_flatten(vrber, &ctrl_val);
|
||||
if (err == -1) {
|
||||
LDAPerr(LDAP_NO_MEMORY);
|
||||
goto endlbl;
|
||||
}
|
||||
|
||||
res = LDAPberval_to_object(ctrl_val);
|
||||
|
||||
endlbl:
|
||||
if (vrber)
|
||||
ber_free(vrber, 1);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
encode_rfc2696(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *res = 0;
|
||||
BerElement *ber = 0;
|
||||
struct berval cookie, *ctrl_val;
|
||||
Py_ssize_t cookie_len;
|
||||
unsigned long size;
|
||||
ber_tag_t tag;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "is#:encode_page_control", &size,
|
||||
&cookie.bv_val, &cookie_len)) {
|
||||
goto endlbl;
|
||||
}
|
||||
cookie.bv_len = (ber_len_t) cookie_len;
|
||||
|
||||
if (!(ber = ber_alloc_t(LBER_USE_DER))) {
|
||||
LDAPerr(LDAP_NO_MEMORY);
|
||||
goto endlbl;
|
||||
}
|
||||
|
||||
tag = ber_printf(ber, "{i", size);
|
||||
if (tag == LBER_ERROR) {
|
||||
LDAPerr(LDAP_ENCODING_ERROR);
|
||||
goto endlbl;
|
||||
}
|
||||
|
||||
if (!cookie.bv_len)
|
||||
tag = ber_printf(ber, "o", "", 0);
|
||||
else
|
||||
tag = ber_printf(ber, "O", &cookie);
|
||||
if (tag == LBER_ERROR) {
|
||||
LDAPerr(LDAP_ENCODING_ERROR);
|
||||
goto endlbl;
|
||||
}
|
||||
|
||||
tag = ber_printf(ber, /*{ */ "N}");
|
||||
if (tag == LBER_ERROR) {
|
||||
LDAPerr(LDAP_ENCODING_ERROR);
|
||||
goto endlbl;
|
||||
}
|
||||
|
||||
if (-1 == ber_flatten(ber, &ctrl_val)) {
|
||||
LDAPerr(LDAP_NO_MEMORY);
|
||||
goto endlbl;
|
||||
}
|
||||
|
||||
res = LDAPberval_to_object(ctrl_val);
|
||||
|
||||
endlbl:
|
||||
if (ber)
|
||||
ber_free(ber, 1);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static PyObject*
|
||||
decode_rfc2696(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *res = 0;
|
||||
BerElement *ber = 0;
|
||||
struct berval ldctl_value;
|
||||
ber_tag_t tag;
|
||||
struct berval *cookiep;
|
||||
unsigned long count;
|
||||
Py_ssize_t ldctl_value_len;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s#:decode_page_control",
|
||||
&ldctl_value.bv_val, &ldctl_value_len)) {
|
||||
goto endlbl;
|
||||
}
|
||||
ldctl_value.bv_len = (ber_len_t) ldctl_value_len;
|
||||
|
||||
if (!(ber = ber_init(&ldctl_value))) {
|
||||
LDAPerr(LDAP_NO_MEMORY);
|
||||
goto endlbl;
|
||||
}
|
||||
|
||||
tag = ber_scanf(ber, "{iO", &count, &cookiep);
|
||||
if (tag == LBER_ERROR) {
|
||||
LDAPerr(LDAP_DECODING_ERROR);
|
||||
goto endlbl;
|
||||
}
|
||||
|
||||
res = Py_BuildValue("(lO&)", count, LDAPberval_to_object, cookiep);
|
||||
|
||||
endlbl:
|
||||
if (ber)
|
||||
ber_free(ber, 1);
|
||||
return res;
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
encode_assertion_control(PyObject *self, PyObject *args)
|
||||
{
|
||||
int err;
|
||||
PyObject *res = 0;
|
||||
char *assertion_filterstr;
|
||||
struct berval ctrl_val;
|
||||
LDAP *ld = NULL;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:encode_assertion_control",
|
||||
&assertion_filterstr)) {
|
||||
goto endlbl;
|
||||
}
|
||||
|
||||
err = ldap_create(&ld);
|
||||
if (err != LDAP_SUCCESS)
|
||||
return LDAPerror(ld, "ldap_create");
|
||||
|
||||
err = ldap_create_assertion_control_value(ld,assertion_filterstr,&ctrl_val);
|
||||
if (err != LDAP_SUCCESS)
|
||||
return LDAPerror(ld, "ldap_create_assertion_control_value");
|
||||
|
||||
res = LDAPberval_to_object(&ctrl_val);
|
||||
|
||||
endlbl:
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static PyMethodDef methods[] = {
|
||||
{"encode_page_control", encode_rfc2696, METH_VARARGS },
|
||||
{"decode_page_control", decode_rfc2696, METH_VARARGS },
|
||||
{"encode_valuesreturnfilter_control", encode_rfc3876, METH_VARARGS },
|
||||
{"encode_assertion_control", encode_assertion_control, METH_VARARGS },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
void
|
||||
LDAPinit_control(PyObject *d)
|
||||
{
|
||||
LDAPadd_methods(d, methods);
|
||||
}
|
||||
|
||||
|
257
Modules/message.c
Normal file
257
Modules/message.c
Normal file
@@ -0,0 +1,257 @@
|
||||
/* See http://www.python-ldap.org/ for details.
|
||||
* $Id: message.c,v 1.19 2011/10/26 18:38:06 stroeder Exp $ */
|
||||
|
||||
#include "common.h"
|
||||
#include "message.h"
|
||||
#include "berval.h"
|
||||
#include "errors.h"
|
||||
#include "ldapcontrol.h"
|
||||
#include "constants.h"
|
||||
|
||||
/*
|
||||
* Converts an LDAP message into a Python structure.
|
||||
*
|
||||
* On success, returns a list of dictionaries.
|
||||
* On failure, returns NULL, and sets an error.
|
||||
*
|
||||
* The message m is always freed, regardless of return value.
|
||||
*
|
||||
* If add_ctrls is non-zero, per-entry/referral/partial/intermediate
|
||||
* controls will be added as a third item to each entry tuple
|
||||
*
|
||||
* If add_intermediates is non-zero, intermediate/partial results will
|
||||
* be returned
|
||||
*/
|
||||
PyObject *
|
||||
LDAPmessage_to_python(LDAP *ld, LDAPMessage *m, int add_ctrls, int add_intermediates)
|
||||
{
|
||||
/* we convert an LDAP message into a python structure.
|
||||
* It is always a list of dictionaries.
|
||||
* We always free m.
|
||||
*/
|
||||
|
||||
PyObject *result, *pyctrls = 0;
|
||||
LDAPMessage* entry;
|
||||
LDAPControl **serverctrls = 0;
|
||||
int rc;
|
||||
|
||||
result = PyList_New(0);
|
||||
if (result == NULL) {
|
||||
ldap_msgfree( m );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(entry = ldap_first_entry(ld,m);
|
||||
entry != NULL;
|
||||
entry = ldap_next_entry(ld,entry))
|
||||
{
|
||||
char *dn;
|
||||
char *attr;
|
||||
BerElement *ber = NULL;
|
||||
PyObject* entrytuple;
|
||||
PyObject* attrdict;
|
||||
|
||||
dn = ldap_get_dn( ld, entry );
|
||||
if (dn == NULL) {
|
||||
Py_DECREF(result);
|
||||
ldap_msgfree( m );
|
||||
return LDAPerror( ld, "ldap_get_dn" );
|
||||
}
|
||||
|
||||
attrdict = PyDict_New();
|
||||
if (attrdict == NULL) {
|
||||
Py_DECREF(result);
|
||||
ldap_msgfree( m );
|
||||
ldap_memfree(dn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rc = ldap_get_entry_controls( ld, entry, &serverctrls );
|
||||
if (rc) {
|
||||
Py_DECREF(result);
|
||||
ldap_msgfree( m );
|
||||
ldap_memfree(dn);
|
||||
return LDAPerror( ld, "ldap_get_entry_controls" );
|
||||
}
|
||||
|
||||
/* convert serverctrls to list of tuples */
|
||||
if ( ! ( pyctrls = LDAPControls_to_List( serverctrls ) ) ) {
|
||||
int err = LDAP_NO_MEMORY;
|
||||
ldap_set_option( ld, LDAP_OPT_ERROR_NUMBER, &err );
|
||||
Py_DECREF(result);
|
||||
ldap_msgfree( m );
|
||||
ldap_memfree(dn);
|
||||
ldap_controls_free(serverctrls);
|
||||
return LDAPerror( ld, "LDAPControls_to_List" );
|
||||
}
|
||||
ldap_controls_free(serverctrls);
|
||||
|
||||
/* Fill attrdict with lists */
|
||||
for( attr = ldap_first_attribute( ld, entry, &ber );
|
||||
attr != NULL;
|
||||
attr = ldap_next_attribute( ld, entry, ber )
|
||||
) {
|
||||
PyObject* valuelist;
|
||||
struct berval ** bvals =
|
||||
ldap_get_values_len( ld, entry, attr );
|
||||
|
||||
/* Find which list to append to */
|
||||
if ( PyMapping_HasKeyString( attrdict, attr ) ) {
|
||||
valuelist = PyMapping_GetItemString( attrdict, attr );
|
||||
} else {
|
||||
valuelist = PyList_New(0);
|
||||
if (valuelist != NULL && PyMapping_SetItemString(attrdict,
|
||||
attr, valuelist) == -1) {
|
||||
Py_DECREF(valuelist);
|
||||
valuelist = NULL; /* catch error later */
|
||||
}
|
||||
}
|
||||
|
||||
if (valuelist == NULL) {
|
||||
Py_DECREF(attrdict);
|
||||
Py_DECREF(result);
|
||||
if (ber != NULL)
|
||||
ber_free(ber, 0);
|
||||
ldap_msgfree( m );
|
||||
ldap_memfree(attr);
|
||||
ldap_memfree(dn);
|
||||
Py_XDECREF(pyctrls);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (bvals != NULL) {
|
||||
Py_ssize_t i;
|
||||
for (i=0; bvals[i]; i++) {
|
||||
PyObject *valuestr;
|
||||
|
||||
valuestr = LDAPberval_to_object(bvals[i]);
|
||||
if (PyList_Append( valuelist, valuestr ) == -1) {
|
||||
Py_DECREF(attrdict);
|
||||
Py_DECREF(result);
|
||||
Py_DECREF(valuestr);
|
||||
Py_DECREF(valuelist);
|
||||
if (ber != NULL)
|
||||
ber_free(ber, 0);
|
||||
ldap_msgfree( m );
|
||||
ldap_memfree(attr);
|
||||
ldap_memfree(dn);
|
||||
Py_XDECREF(pyctrls);
|
||||
return NULL;
|
||||
}
|
||||
Py_DECREF(valuestr);
|
||||
}
|
||||
ldap_value_free_len(bvals);
|
||||
}
|
||||
Py_DECREF( valuelist );
|
||||
ldap_memfree(attr);
|
||||
}
|
||||
|
||||
if (add_ctrls) {
|
||||
entrytuple = Py_BuildValue("(sOO)", dn, attrdict, pyctrls);
|
||||
} else {
|
||||
entrytuple = Py_BuildValue("(sO)", dn, attrdict);
|
||||
}
|
||||
ldap_memfree(dn);
|
||||
Py_DECREF(attrdict);
|
||||
Py_XDECREF(pyctrls);
|
||||
PyList_Append(result, entrytuple);
|
||||
Py_DECREF(entrytuple);
|
||||
if (ber != NULL)
|
||||
ber_free(ber, 0);
|
||||
}
|
||||
for(entry = ldap_first_reference(ld,m);
|
||||
entry != NULL;
|
||||
entry = ldap_next_reference(ld,entry))
|
||||
{
|
||||
char **refs = NULL;
|
||||
PyObject* entrytuple;
|
||||
PyObject* reflist = PyList_New(0);
|
||||
|
||||
if (reflist == NULL) {
|
||||
Py_DECREF(result);
|
||||
ldap_msgfree( m );
|
||||
return NULL;
|
||||
}
|
||||
if (ldap_parse_reference(ld, entry, &refs, &serverctrls, 0) != LDAP_SUCCESS) {
|
||||
Py_DECREF(reflist);
|
||||
Py_DECREF(result);
|
||||
ldap_msgfree( m );
|
||||
return LDAPerror( ld, "ldap_parse_reference" );
|
||||
}
|
||||
/* convert serverctrls to list of tuples */
|
||||
if ( ! ( pyctrls = LDAPControls_to_List( serverctrls ) ) ) {
|
||||
int err = LDAP_NO_MEMORY;
|
||||
ldap_set_option( ld, LDAP_OPT_ERROR_NUMBER, &err );
|
||||
Py_DECREF(reflist);
|
||||
Py_DECREF(result);
|
||||
ldap_msgfree( m );
|
||||
ldap_controls_free(serverctrls);
|
||||
return LDAPerror( ld, "LDAPControls_to_List" );
|
||||
}
|
||||
ldap_controls_free(serverctrls);
|
||||
if (refs) {
|
||||
Py_ssize_t i;
|
||||
for (i=0; refs[i] != NULL; i++) {
|
||||
PyObject *refstr = PyString_FromString(refs[i]);
|
||||
PyList_Append(reflist, refstr);
|
||||
Py_DECREF(refstr);
|
||||
}
|
||||
ber_memvfree( (void **) refs );
|
||||
}
|
||||
if (add_ctrls) {
|
||||
entrytuple = Py_BuildValue("(sOO)", NULL, reflist, pyctrls);
|
||||
} else {
|
||||
entrytuple = Py_BuildValue("(sO)", NULL, reflist);
|
||||
}
|
||||
Py_DECREF(reflist);
|
||||
Py_XDECREF(pyctrls);
|
||||
PyList_Append(result, entrytuple);
|
||||
Py_DECREF(entrytuple);
|
||||
}
|
||||
if (add_intermediates) {
|
||||
for(entry = ldap_first_message(ld,m);
|
||||
entry != NULL;
|
||||
entry = ldap_next_message(ld,entry))
|
||||
{
|
||||
/* list of tuples */
|
||||
/* each tuple is OID, Berval, controllist */
|
||||
if ( LDAP_RES_INTERMEDIATE == ldap_msgtype( entry ) ) {
|
||||
PyObject* valtuple;
|
||||
PyObject *valuestr;
|
||||
char *retoid = 0;
|
||||
struct berval *retdata = 0;
|
||||
|
||||
if (ldap_parse_intermediate( ld, entry, &retoid, &retdata, &serverctrls, 0 ) != LDAP_SUCCESS) {
|
||||
Py_DECREF(result);
|
||||
ldap_msgfree( m );
|
||||
return LDAPerror( ld, "ldap_parse_intermediate" );
|
||||
}
|
||||
/* convert serverctrls to list of tuples */
|
||||
if ( ! ( pyctrls = LDAPControls_to_List( serverctrls ) ) ) {
|
||||
int err = LDAP_NO_MEMORY;
|
||||
ldap_set_option( ld, LDAP_OPT_ERROR_NUMBER, &err );
|
||||
Py_DECREF(result);
|
||||
ldap_msgfree( m );
|
||||
ldap_controls_free(serverctrls);
|
||||
ldap_memfree( retoid );
|
||||
ber_bvfree( retdata );
|
||||
return LDAPerror( ld, "LDAPControls_to_List" );
|
||||
}
|
||||
ldap_controls_free(serverctrls);
|
||||
|
||||
valuestr = LDAPberval_to_object(retdata);
|
||||
ber_bvfree( retdata );
|
||||
valtuple = Py_BuildValue("(sOO)", retoid,
|
||||
valuestr ? valuestr : Py_None,
|
||||
pyctrls);
|
||||
ldap_memfree( retoid );
|
||||
Py_DECREF(valuestr);
|
||||
Py_XDECREF(pyctrls);
|
||||
PyList_Append(result, valtuple);
|
||||
Py_DECREF(valtuple);
|
||||
}
|
||||
}
|
||||
}
|
||||
ldap_msgfree( m );
|
||||
return result;
|
||||
}
|
Reference in New Issue
Block a user