Module: sip-router
Branch: janakj/ldap
Commit: 09e32928839c2be69caa0ad96a25b725b268482f
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=09e3292…
Author: Jan Janak <jan(a)iptel.org>
Committer: Jan Janak <jan(a)iptel.org>
Date: Mon May 12 15:01:17 2008 +0000
- parse and check the result message
- support for binary values
- better support for integers
- support for bitmap fields
---
modules/db_ldap/ld_cmd.c | 99 ++++++++++++++++++++++++++-------------------
modules/db_ldap/ld_fld.c | 77 +++++++++++++++++++++++++++--------
modules/db_ldap/ld_fld.h | 2 +-
modules/db_ldap/todo.txt | 2 -
4 files changed, 117 insertions(+), 63 deletions(-)
diff --git a/modules/db_ldap/ld_cmd.c b/modules/db_ldap/ld_cmd.c
index 8444bed..209db1e 100644
--- a/modules/db_ldap/ld_cmd.c
+++ b/modules/db_ldap/ld_cmd.c
@@ -251,27 +251,18 @@ int ld_cmd(db_cmd_t* cmd)
switch(cmd->type) {
case DB_PUT:
- ERR("ldap: DB_PUT not supported\n");
- goto error;
- break;
-
case DB_DEL:
- ERR("ldap: DB_DEL not supported\n");
+ case DB_UPD:
+ ERR("ldap: The driver does not support directory modifications yet.\n");
goto error;
break;
-
+
case DB_GET:
break;
- case DB_UPD:
- ERR("ldap: DB_UPD not supported\n");
- goto error;
- break;
-
case DB_SQL:
- ERR("ldap: DB_SQL not supported\n");
+ ERR("ldap: The driver does not support raw queries yet.\n");
goto error;
- break;
}
cfg = ld_find_config(&cmd->table);
@@ -293,7 +284,6 @@ int ld_cmd(db_cmd_t* cmd)
if (ld_resolve_fld(cmd->result, cfg) < 0) goto error;
if (build_result_array(&lcmd->result, cmd) < 0) goto error;
-
DB_SET_PAYLOAD(cmd, lcmd);
return 0;
@@ -314,10 +304,14 @@ int ld_cmd_exec(db_res_t* res, db_cmd_t* cmd)
struct ld_res* lres;
struct ld_cmd* lcmd;
struct ld_con* lcon;
- char* filter;
- int ret;
+ char* filter, *err_desc;
+ int ret, err;
LDAPMessage* msg;
+ filter = NULL;
+ err_desc = NULL;
+ msg = NULL;
+
/* First things first: retrieve connection info from the currently active
* connection and also mysql payload from the database command
*/
@@ -327,57 +321,72 @@ int ld_cmd_exec(db_res_t* res, db_cmd_t* cmd)
if (build_search_filter(&filter, cmd->match, &lcmd->filter) < 0) {
ERR("ldap: Error while building LDAP search filter\n");
- return -1;
+ goto error;
}
ret = ldap_search_ext_s(lcon->con, lcmd->base, lcmd->scope, filter,
lcmd->result, 0, NULL, NULL, NULL, 0, &msg);
- if (filter) pkg_free(filter);
if (ret != LDAP_SUCCESS) {
ERR("ldap: Error in ldap_search: %s\n", ldap_err2string(ret));
- return -1;
+ goto error;
+ }
+
+ ret = ldap_parse_result(lcon->con, msg, &err, NULL, &err_desc, NULL, NULL,
0);
+ if (ret != LDAP_SUCCESS) {
+ ERR("ldap: Error while reading result status: %s\n",
+ ldap_err2string(ret));
+ goto error;
}
+ if (err != LDAP_SUCCESS) {
+ ERR("ldap: LDAP server reports error: %s\n", ldap_err2string(err));
+ goto error;
+ }
+
if (res) {
lres = DB_GET_PAYLOAD(res);
- if (lres->msg) ldap_msgfree(lres->msg);
lres->msg = msg;
} else {
ldap_msgfree(msg);
}
+ if (filter) pkg_free(filter);
+ if (err_desc) ldap_memfree(err_desc);
return 0;
+
+ error:
+ if (filter) pkg_free(filter);
+ if (msg) ldap_msgfree(msg);
+ if (err_desc) ldap_memfree(err_desc);
+ return -1;
}
-int ld_cmd_first(db_res_t* res)
+/* Iterate to the next search result in the linked list
+ * of messages returned by the LDAP server and convert
+ * the field values.
+ */
+static int next_search_entry(db_res_t* res, LDAP* con)
{
- db_con_t* con;
struct ld_res* lres;
- struct ld_con* lcon;
lres = DB_GET_PAYLOAD(res);
- /* FIXME */
- con = res->cmd->ctx->con[db_payload_idx];
- lcon = DB_GET_PAYLOAD(con);
-
- lres->current = ldap_first_message(lcon->con, lres->msg);
while(lres->current) {
if (ldap_msgtype(lres->current) == LDAP_RES_SEARCH_ENTRY) {
break;
}
- lres->current = ldap_next_message(lcon->con, lres->msg);
+ lres->current = ldap_next_message(con, lres->current);
}
if (lres->current == NULL) return 1;
- if (ld_ldap2fld(res->cmd->result, lcon->con, lres->current) < 0) return
-1;
+ if (ld_ldap2fld(res->cmd->result, con, lres->current) < 0) return -1;
res->cur_rec->fld = res->cmd->result;
return 0;
}
-int ld_cmd_next(db_res_t* res)
+int ld_cmd_first(db_res_t* res)
{
db_con_t* con;
struct ld_res* lres;
@@ -388,19 +397,25 @@ int ld_cmd_next(db_res_t* res)
con = res->cmd->ctx->con[db_payload_idx];
lcon = DB_GET_PAYLOAD(con);
- if (lres->current == NULL) return 1;
+ lres->current = ldap_first_message(lcon->con, lres->msg);
+ return next_search_entry(res, lcon->con);
+}
+
+
+int ld_cmd_next(db_res_t* res)
+{
+ db_con_t* con;
+ struct ld_res* lres;
+ struct ld_con* lcon;
+
+ lres = DB_GET_PAYLOAD(res);
+ /* FIXME */
+ con = res->cmd->ctx->con[db_payload_idx];
+ lcon = DB_GET_PAYLOAD(con);
lres->current = ldap_next_message(lcon->con, lres->current);
- while(lres->current) {
- if (ldap_msgtype(lres->current) == LDAP_RES_SEARCH_ENTRY) {
- break;
- }
- lres->current = ldap_next_message(lcon->con, lres->current);
- }
- if (lres->current == NULL) return 1;
- if (ld_ldap2fld(res->cmd->result, lcon->con, lres->current) < 0) return
-1;
- res->cur_rec->fld = res->cmd->result;
- return 0;
+ return next_search_entry(res, lcon->con);
}
+
/** @} */
diff --git a/modules/db_ldap/ld_fld.c b/modules/db_ldap/ld_fld.c
index 2c06727..b886d85 100644
--- a/modules/db_ldap/ld_fld.c
+++ b/modules/db_ldap/ld_fld.c
@@ -41,6 +41,7 @@
#include "../../db/db_drv.h"
#include "../../mem/mem.h"
#include "../../dprint.h"
+#include "../../ut.h"
#include <stdint.h>
#include <string.h>
@@ -53,7 +54,7 @@
static void ld_fld_free(db_fld_t* fld, struct ld_fld* payload)
{
db_drv_free(&payload->gen);
- if (payload->values) ldap_value_free(payload->values);
+ if (payload->values) ldap_value_free_len(payload->values);
payload->values = NULL;
pkg_free(payload);
}
@@ -97,48 +98,88 @@ int ld_resolve_fld(db_fld_t* fld, struct ld_config* cfg)
}
+static inline int ldap_int2db_int(int* dst, str* src)
+{
+ if (str2sint(src, dst) != 0) {
+ ERR("ldap: Error while converting value '%.*s' to integer\n",
+ src->len, ZSW(src->s));
+ return -1;
+ }
+ return 0;
+}
+
+
+static inline int ldap_bit2db_int(int* dst, str* src)
+{
+ int i, v;
+
+ if (src->len > 32) {
+ WARN("ldap: bitString '%.*s'B is longer than 32 bits, truncating\n",
+ src->len, ZSW(src->s));
+ }
+ v = 0;
+ for(i = 0; i < src->len; i++) {
+ v <<= 1;
+ v += src->s[i] - '0';
+ }
+ *dst = v;
+ return 0;
+}
+
+
int ld_ldap2fld(db_fld_t* fld, LDAP* ldap, LDAPMessage* msg)
{
int i;
struct ld_fld* lfld;
+ str tmp;
if (fld == NULL || msg == NULL) return 0;
for(i = 0; !DB_FLD_EMPTY(fld) && !DB_FLD_LAST(fld[i]); i++) {
lfld = DB_GET_PAYLOAD(fld + i);
- if (lfld->values) ldap_value_free(lfld->values);
- lfld->values = ldap_get_values(ldap, msg, lfld->attr.s);
+ if (lfld->values) ldap_value_free_len(lfld->values);
+ lfld->values = ldap_get_values_len(ldap, msg, lfld->attr.s);
- if (lfld->values == NULL) {
- /* FIXME: Test for errno value here */
- ERR("ldap: Error in ldap_get_values\n");
- return -1;
- }
-
- if (lfld->values[0] == NULL) {
+ if (lfld->values == NULL || lfld->values[0] == NULL) {
fld[i].flags |= DB_NULL;
continue;
}
if (lfld->values[1] != NULL) {
- ERR("ldap: Multivalue attributes not yet supported\n");
+ ERR("ldap: Multivalue attributes not yet supported: %.*s\n",
+ lfld->attr.len, lfld->attr.s);
return -1;
}
switch(fld[i].type) {
- case DB_STR:
- fld[i].v.cstr = lfld->values[0];
+ case DB_CSTR:
+ fld[i].v.cstr = lfld->values[0]->bv_val;
break;
- case DB_CSTR:
- fld[i].v.lstr.s = lfld->values[0];
- fld[i].v.lstr.len = strlen(lfld->values[0]);
+ case DB_STR:
+ case DB_BLOB:
+ fld[i].v.lstr.s = lfld->values[0]->bv_val;
+ fld[i].v.lstr.len = lfld->values[0]->bv_len;
break;
case DB_INT:
- fld[i].v.int4 = 33;
- break;
+ case DB_BITMAP:
+ tmp.s = lfld->values[0]->bv_val;
+ tmp.len = lfld->values[0]->bv_len;
+
+ if (tmp.s[0] == '\'' &&
+ tmp.s[tmp.len - 1] == 'B' &&
+ tmp.s[tmp.len - 2] == '\'') {
+
+ tmp.s++;
+ tmp.len -= 3;
+ return ldap_bit2db_int(&fld[i].v.int4, &tmp);
+ } else {
+ return ldap_int2db_int(&fld[i].v.int4, &tmp);
+ }
+ break;
+
default:
ERR("ldap: Unsupported field type: %d\n", fld[i].type);
return -1;
diff --git a/modules/db_ldap/ld_fld.h b/modules/db_ldap/ld_fld.h
index 404f501..6994ace 100644
--- a/modules/db_ldap/ld_fld.h
+++ b/modules/db_ldap/ld_fld.h
@@ -48,7 +48,7 @@
struct ld_fld {
db_drv_t gen;
str attr; /**< Name of corresponding LDAP attribute */
- char** values; /**< Values retrieved from the LDAP result */
+ struct berval** values; /**< Values retrieved from the LDAP result */
};
diff --git a/modules/db_ldap/todo.txt b/modules/db_ldap/todo.txt
index 6c75a58..7e9c544 100644
--- a/modules/db_ldap/todo.txt
+++ b/modules/db_ldap/todo.txt
@@ -8,6 +8,4 @@
* Proper handling of NULL values
* use the asynchronous functions of the api instead of synchronous
* Support for multi-value attributes (they should be broken up into rows)
-* Handle the value in LDAP_RES_SEARCH_RESULT somehow intelligently (it
- may indicate a failure)