/* ** Retrieve next message... ** @return #1 entry's distinguished name. ** @return #2 table with entry's attributes and values. */ static int next_message (lua_State *L) { search_data *search = getsearch (L); conn_data *conn; struct timeval *timeout = NULL; /* ??? function parameter ??? */ LDAPMessage *res; int rc; int ret; lua_rawgeti (L, LUA_REGISTRYINDEX, search->conn); conn = (conn_data *)lua_touserdata (L, -1); /* get connection */ rc = ldap_result (conn->ld, search->msgid, LDAP_MSG_ONE, timeout, &res); if (rc == 0) return faildirect (L, LUALDAP_PREFIX"result timeout expired"); else if (rc == -1) return faildirect (L, LUALDAP_PREFIX"result error"); else if (rc == LDAP_RES_SEARCH_RESULT) { /* last message => nil */ /* close search object to avoid reuse */ search_close (L, search); ret = 0; } else { LDAPMessage *msg = ldap_first_message (conn->ld, res); switch (ldap_msgtype (msg)) { case LDAP_RES_SEARCH_ENTRY: { LDAPMessage *entry = ldap_first_entry (conn->ld, msg); push_dn (L, conn->ld, entry); lua_newtable (L); set_attribs (L, conn->ld, entry, lua_gettop (L)); ret = 2; /* two return values */ break; } /*No reference to LDAP_RES_SEARCH_REFERENCE on MSDN. Maybe there is a replacement to it?*/ #ifdef LDAP_RES_SEARCH_REFERENCE case LDAP_RES_SEARCH_REFERENCE: { LDAPMessage *ref = ldap_first_reference (conn->ld, msg); push_dn (L, conn->ld, ref); /* is this supposed to work? */ lua_pushnil (L); ret = 2; /* two return values */ break; } #endif case LDAP_RES_SEARCH_RESULT: /* close search object to avoid reuse */ search_close (L, search); ret = 0; break; default: ldap_msgfree (res); return luaL_error (L, LUALDAP_PREFIX"error on search result chain"); } } ldap_msgfree (res); return ret; }
static int search_iterator(lua_State *L) { LDAPMessage *result, *message, *entry; lua_apr_ldap_object *object; struct timeval *timeout; int status, msgid; object = lua_touserdata(L, lua_upvalueindex(1)); msgid = lua_tointeger(L, lua_upvalueindex(2)); timeout = lua_touserdata(L, lua_upvalueindex(3)); status = ldap_result(object->ldap, msgid, LDAP_MSG_ONE, timeout, &result); if (status == 0) raise_error_status(L, APR_TIMEUP); else if (status == -1) /* TODO Can we get a more specific error (message) here? ld_errno? */ raise_error_message(L, "Unspecified error"); else if (status == LDAP_RES_SEARCH_RESULT) { /* end of search results */ return 0; } else { message = ldap_first_message(object->ldap, result); switch (ldap_msgtype(message)) { case LDAP_RES_SEARCH_ENTRY: entry = ldap_first_entry(object->ldap, message); push_distinguished_name(L, object->ldap, entry); lua_newtable(L); set_attributes(L, object->ldap, entry, lua_gettop(L)); ldap_msgfree(result); return 2; /* No reference to LDAP_RES_SEARCH_REFERENCE on MSDN. Maybe is has a replacement? */ # ifdef LDAP_RES_SEARCH_REFERENCE case LDAP_RES_SEARCH_REFERENCE: { LDAPMessage *reference = ldap_first_reference(object->ldap, message); push_distinguished_name(L, object->ldap, reference); /* is this supposed to work? */ ldap_msgfree(result); return 1; } # endif case LDAP_RES_SEARCH_RESULT: /* end of search results */ ldap_msgfree(result); return 0; default: ldap_msgfree(result); raise_error_message(L, "unhandled message type in search results"); } } /* shouldn't be reached. */ ldap_msgfree(result); return 0; }
/*********************************************************************** * ldap_first_reference (WLDAP32.@) * * Get the first reference from a result message. * * PARAMS * ld [I] Pointer to an LDAP context. * res [I] Search result message. * * RETURNS * Success: The first reference. * Failure: NULL */ WLDAP32_LDAPMessage * CDECL WLDAP32_ldap_first_reference( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *res ) { #ifdef HAVE_LDAP_FIRST_REFERENCE TRACE( "(%p, %p)\n", ld, res ); if (!ld) return NULL; return ldap_first_reference( ld, res ); #else return NULL; #endif }
/* * 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. */ PyObject * LDAPmessage_to_python(LDAP *ld, LDAPMessage *m) { /* we convert an LDAP message into a python structure. * It is always a list of dictionaries. * We always free m. */ PyObject* result; LDAPMessage* entry; 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; } /* 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); 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); return NULL; } Py_DECREF(valuestr); } ldap_value_free_len(bvals); } Py_DECREF( valuelist ); ldap_memfree(attr); } entrytuple = Py_BuildValue("(sO)", dn, attrdict); ldap_memfree(dn); Py_DECREF(attrdict); 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, NULL, 0) != LDAP_SUCCESS) { Py_DECREF(result); ldap_msgfree( m ); return LDAPerror( ld, "ldap_parse_reference" ); } 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 ); } entrytuple = Py_BuildValue("(sO)", NULL, reflist); Py_DECREF(reflist); PyList_Append(result, entrytuple); Py_DECREF(entrytuple); } ldap_msgfree( m ); return result; }