deb-python-pyldap/Modules/message.c

279 lines
7.4 KiB
C

/* 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;
PyObject* pydn;
dn = ldap_get_dn( ld, entry );
if (dn == NULL) {
Py_DECREF(result);
ldap_msgfree( m );
return LDAPerror( ld, "ldap_get_dn" );
}
pydn = PyUnicode_FromString(dn);
if (pydn == NULL) {
Py_DECREF(result);
ldap_msgfree( m );
ldap_memfree(dn);
return NULL;
}
attrdict = PyDict_New();
if (attrdict == NULL) {
Py_DECREF(pydn);
Py_DECREF(result);
ldap_msgfree( m );
ldap_memfree(dn);
return NULL;
}
rc = ldap_get_entry_controls( ld, entry, &serverctrls );
if (rc) {
Py_DECREF(pydn);
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(pydn);
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;
PyObject* pyattr;
pyattr = PyUnicode_FromString(attr);
struct berval ** bvals =
ldap_get_values_len( ld, entry, attr );
/* Find which list to append to */
if ( PyDict_Contains( attrdict, pyattr ) ) {
valuelist = PyDict_GetItem( attrdict, pyattr );
} else {
valuelist = PyList_New(0);
if (valuelist != NULL && PyDict_SetItem(attrdict,
pyattr, valuelist) == -1) {
Py_DECREF(valuelist);
valuelist = NULL; /* catch error later */
}
}
if (valuelist == NULL) {
Py_DECREF(pydn);
Py_DECREF(pyattr);
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(pydn);
Py_DECREF(pyattr);
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(pyattr);
Py_DECREF( valuelist );
ldap_memfree(attr);
}
if (add_ctrls) {
entrytuple = Py_BuildValue("(OOO)", pydn, attrdict, pyctrls);
} else {
entrytuple = Py_BuildValue("(OO)", pydn, attrdict);
}
Py_DECREF(pydn);
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++) {
/* A referal is a distinguishedName => unicode */
PyObject *refstr = PyUnicode_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;
}