Module: sip-router
Branch: janakj/ldap
Commit: 6bbe8456d8ddf3e999d16d694d58719fe41b5121
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=6bbe845…
Author: Gergely Kovacs <gergo(a)iptel.org>
Committer: Gergely Kovacs <gergo(a)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 */
};