Module: sip-router Branch: janakj/ldap Commit: 09e32928839c2be69caa0ad96a25b725b268482f URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=09e32928...
Author: Jan Janak jan@iptel.org Committer: Jan Janak jan@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)