Module: sip-router Branch: janakj/ldap Commit: 6bbe8456d8ddf3e999d16d694d58719fe41b5121 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=6bbe8456...
Author: Gergely Kovacs gergo@iptel.org Committer: Gergely Kovacs gergo@iptel.org Date: Wed Jun 4 21:43:27 2008 +0000
simple user authentication mechanism added
---
modules/db_ldap/ld_con.c | 25 +++--- modules/db_ldap/ld_uri.c | 194 ++++++++++++++++++++++++++++++++++++++++------ modules/db_ldap/ld_uri.h | 8 +- 3 files changed, 187 insertions(+), 40 deletions(-)
diff --git a/modules/db_ldap/ld_con.c b/modules/db_ldap/ld_con.c index 32a0db9..21df896 100644 --- a/modules/db_ldap/ld_con.c +++ b/modules/db_ldap/ld_con.c @@ -23,10 +23,10 @@ */
/** \addtogroup ldap - * @{ + * @{ */
-/** \file +/** \file * Functions related to connections to LDAP servers. */
@@ -62,12 +62,12 @@ static void ld_con_free(db_con_t* con, struct ld_con* payload) * to it in the connection pool */ if (db_pool_remove((db_pool_entry_t*)payload) == 0) return; - + db_pool_entry_free(&payload->gen); if (payload->con) { ret = ldap_unbind_ext_s(payload->con, NULL, NULL); if (ret != LDAP_SUCCESS) { - ERR("ldap: Error while unbinding from %s: %s\n", + ERR("ldap: Error while unbinding from %s: %s\n", luri->uri, ldap_err2string(ret)); } } @@ -129,10 +129,10 @@ int ld_con_connect(db_con_t* con) struct ld_con* lcon; struct ld_uri* luri; int ret, version = 3; - + lcon = DB_GET_PAYLOAD(con); luri = DB_GET_PAYLOAD(con->uri); - + /* Do not reconnect already connected connections */ if (lcon->flags & LD_CONNECTED) return 0;
@@ -141,7 +141,7 @@ int ld_con_connect(db_con_t* con) if (lcon->con) { ret = ldap_unbind_ext_s(lcon->con, NULL, NULL); if (ret != LDAP_SUCCESS) { - ERR("ldap: Error while unbinding from %s: %s\n", + ERR("ldap: Error while unbinding from %s: %s\n", luri->uri, ldap_err2string(ret)); } } @@ -155,15 +155,14 @@ int ld_con_connect(db_con_t* con)
ret = ldap_set_option(lcon->con, LDAP_OPT_PROTOCOL_VERSION, &version); if (ret != LDAP_OPT_SUCCESS) { - ERR("ldap: Error while setting protocol version 3: %s\n", + ERR("ldap: Error while setting protocol version 3: %s\n", ldap_err2string(ret)); goto error; }
- /* FIXME: Currently only anonymous binds are supported */ - ret = ldap_simple_bind_s(lcon->con, NULL, NULL); + ret = ldap_simple_bind_s(lcon->con, luri->username, luri->password); if (ret != LDAP_SUCCESS) { - ERR("ldap: Bind to %s failed: %s\n", + ERR("ldap: Bind to %s failed: %s\n", luri->uri, ldap_err2string(ret)); goto error; } @@ -176,7 +175,7 @@ int ld_con_connect(db_con_t* con) if (lcon->con) { ret = ldap_unbind_ext_s(lcon->con, NULL, NULL); if (ret) { - ERR("ldap: Error while unbinding from %s: %s\n", + ERR("ldap: Error while unbinding from %s: %s\n", luri->uri, ldap_err2string(ret)); } } @@ -201,7 +200,7 @@ void ld_con_disconnect(db_con_t* con) if (lcon->con) { ret = ldap_unbind_ext_s(lcon->con, NULL, NULL); if (ret) { - ERR("ldap: Error while unbinding from %s: %s\n", + ERR("ldap: Error while unbinding from %s: %s\n", luri->uri, ldap_err2string(ret)); } } diff --git a/modules/db_ldap/ld_uri.c b/modules/db_ldap/ld_uri.c index 2911b28..ee36918 100644 --- a/modules/db_ldap/ld_uri.c +++ b/modules/db_ldap/ld_uri.c @@ -1,5 +1,5 @@ -/* - * $Id$ +/* + * $Id$ * * LDAP Database Driver for SER * @@ -18,15 +18,15 @@ * details. * * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., + * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */
/** \addtogroup ldap - * @{ + * @{ */
-/** \file +/** \file * The implementation of parser parsing ldap:.. URIs. */
@@ -39,7 +39,7 @@
/** compare s1 & s2 with a function f (which should return 0 if ==); * s1 & s2 can be null - * return 0 if match, 1 if not + * return 0 if match, 1 if not */ #define cmpstr(s1, s2, f) \ ((s1)!=(s2)) && ((s1)==0 || (s2)==0 || (f)((s1), (s2))!=0) @@ -63,18 +63,178 @@ static unsigned char ld_uri_cmp(db_uri_t* uri1, db_uri_t* uri2) luri2 = DB_GET_PAYLOAD(uri2);
if (luri1->ldap_url->lud_port != luri2->ldap_url->lud_port) return 0; - if (cmpstr(luri1->ldap_url->lud_host, - luri2->ldap_url->lud_host, strcasecmp)) + if (cmpstr(luri1->ldap_url->lud_host, + luri2->ldap_url->lud_host, strcasecmp)) return 0; return 1; }
+/** Duplicate a string + */ +static int dupl_string(char** dst, const char* begin, const char* end) +{ + if (*dst) pkg_free(*dst); + + *dst = pkg_malloc(end - begin + 1); + if ((*dst) == NULL) { + return -1; + } + + memcpy(*dst, begin, end - begin); + (*dst)[end - begin] = '\0'; + return 0; +} + +/* + * Parse ldap URI of form + * //[username[:password]@]hostname[:port] + * + * Returns 0 if parsing was successful and -1 otherwise + */ +int parse_ldap_uri(struct ld_uri* res, str* scheme, str* uri) +{ +#define SHORTEST_DB_URL "a" +#define SHORTEST_DB_URL_LEN (sizeof(SHORTEST_DB_URL) - 1) + + enum state { + ST_BEGIN, /* First state */ + ST_SECTTITLE, /* Config section title */ + ST_SLASH2, /* Second slash */ + ST_USER_HOST, /* Username or hostname */ + ST_PASS_PORT, /* Password or port part */ + ST_HOST_PORT /* Hostname and port part */ + }; + enum state st; + int i, ldapurllen; + const char* begin; + const char* ldapbegin; + char* prev_token; + + prev_token = 0; + + if (!res || !scheme || !uri) { + goto err; + } + + if (uri->len < SHORTEST_DB_URL_LEN) { + goto err; + } + + st = ST_BEGIN; + ldapbegin = begin = uri->s; + + for(i = 0; i < uri->len; i++) { + switch(st) { + case ST_BEGIN: + switch(uri->s[i]) { + case '/': + st = ST_SLASH2; + break; + + default: + st = ST_SECTTITLE; + } + break; + + case ST_SECTTITLE: + break; + + case ST_SLASH2: + switch(uri->s[i]) { + case '/': + st = ST_USER_HOST; + ldapbegin = begin = uri->s + i + 1; + break; + + default: + goto err; + } + break; + + case ST_USER_HOST: + switch(uri->s[i]) { + case '@': + st = ST_HOST_PORT; + if (dupl_string(&res->username, begin, uri->s + i) < 0) goto err; + ldapbegin = begin = uri->s + i + 1; + break; + + case ':': + st = ST_PASS_PORT; + if (dupl_string(&prev_token, begin, uri->s + i) < 0) goto err; + begin = uri->s + i + 1; + break; + } + break; + + case ST_PASS_PORT: + switch(uri->s[i]) { + case '@': + st = ST_HOST_PORT; + res->username = prev_token; + if (dupl_string(&res->password, begin, uri->s + i) < 0) goto err; + ldapbegin = begin = uri->s + i + 1; + break; + } + break; + + case ST_HOST_PORT: + break; + } + } + + switch(st) { + case ST_PASS_PORT: + case ST_USER_HOST: + case ST_HOST_PORT: + ldapurllen = uri->len - (int)(ldapbegin - uri->s); + // +3 for the '://' ldap url snippet + res->uri = pkg_malloc(scheme->len + 3 + ldapurllen + 1); + if (res->uri== NULL) { + ERR("ldap: No memory left\n"); + goto err; + } + memcpy(res->uri, scheme->s, scheme->len); + res->uri[scheme->len] = ':'; + res->uri[scheme->len + 1] = '/'; + res->uri[scheme->len + 2] = '/'; + memcpy(res->uri + scheme->len + 3, ldapbegin, ldapurllen); + res->uri[scheme->len + 3 + ldapurllen] = '\0'; + + if (ldap_url_parse(res->uri, &res->ldap_url) != 0) { + ERR("ldap: Error while parsing URL '%s'\n", res->uri); + goto err; + } + break; + case ST_SECTTITLE: + /* haven't supported yet */ + default: + goto err; + } + + return 0; + + err: + if (prev_token) pkg_free(prev_token); + if (res == NULL) return -1; + if (res->username) { + pkg_free(res->username); + res->username = NULL; + } + if (res->password) { + pkg_free(res->password); + res->password = NULL; + } + return -1; +}
static void ld_uri_free(db_uri_t* uri, struct ld_uri* payload) { if (payload == NULL) return; if (payload->ldap_url) ldap_free_urldesc(payload->ldap_url); if (payload->uri) pkg_free(payload->uri); + if (payload->username) pkg_free(payload->username); + if (payload->password) pkg_free(payload->password); db_drv_free(&payload->drv); pkg_free(payload); } @@ -91,21 +251,7 @@ int ld_uri(db_uri_t* uri) } memset(luri, '\0', sizeof(struct ld_uri)); if (db_drv_init(&luri->drv, ld_uri_free) < 0) goto error; - - luri->uri = pkg_malloc(uri->scheme.len + 1 + uri->body.len + 1); - if (luri->uri== NULL) { - ERR("ldap: No memory left\n"); - goto error; - } - memcpy(luri->uri, uri->scheme.s, uri->scheme.len); - luri->uri[uri->scheme.len] = ':'; - memcpy(luri->uri + uri->scheme.len + 1, uri->body.s, uri->body.len); - luri->uri[uri->scheme.len + 1 + uri->body.len] = '\0'; - - if (ldap_url_parse(luri->uri, &luri->ldap_url) != 0) { - ERR("ldap: Error while parsing URL '%s'\n", luri->uri); - goto error; - } + if (parse_ldap_uri(luri, &uri->scheme, &uri->body) < 0) goto error;
DB_SET_PAYLOAD(uri, luri); uri->cmp = ld_uri_cmp; @@ -118,7 +264,7 @@ int ld_uri(db_uri_t* uri) db_drv_free(&luri->drv); pkg_free(luri); } - return -1; + return -1; }
diff --git a/modules/db_ldap/ld_uri.h b/modules/db_ldap/ld_uri.h index d6886c0..f125767 100644 --- a/modules/db_ldap/ld_uri.h +++ b/modules/db_ldap/ld_uri.h @@ -26,10 +26,10 @@ #define _LD_URI_H
/** \addtogroup ldap - * @{ + * @{ */
-/** \file +/** \file * The functions parsing and interpreting ldap: URIs. */
@@ -41,11 +41,13 @@
/** LDAP driver specific payload to attach to db_uri structures. * This is the LDAP specific structure that will be attached - * to generic db_uri structures in the database API in SER. The + * to generic db_uri structures in the database API in SER. The * structure contains parsed elements of the ldap: URI. */ struct ld_uri { db_drv_t drv; + char* username; + char* password; char* uri; /**< The whole URI, including scheme */ LDAPURLDesc* ldap_url; /**< URI parsed by the ldap client library */ };