Module: sip-router
Branch: janakj/ldap
Commit: 5055f48ce7f0a00ed9a5ecdb63732b84fb9a3457
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=5055f48…
Author: Jan Janak <jan(a)iptel.org>
Committer: Jan Janak <jan(a)iptel.org>
Date: Mon May 12 16:13:10 2008 +0000
- Support for generalized time attributes
- Support for double/float fields
- Support for bitmap fields
- todo list items augmented with more info
---
modules/db_ldap/ld_fld.c | 113 ++++++++++++++++++++++++++++++++++++-----
modules/db_ldap/standards.txt | 2 +
modules/db_ldap/todo.txt | 77 ++++++++++++++++++++++++----
3 files changed, 168 insertions(+), 24 deletions(-)
diff --git a/modules/db_ldap/ld_fld.c b/modules/db_ldap/ld_fld.c
index b886d85..f9d2c95 100644
--- a/modules/db_ldap/ld_fld.c
+++ b/modules/db_ldap/ld_fld.c
@@ -36,6 +36,10 @@
#define LDAP_DEPRECATED 1
+#define _XOPEN_SOURCE 4 /* bsd */
+#define _XOPEN_SOURCE_EXTENDED 1 /* solaris */
+#define _SVID_SOURCE 1 /* timegm */
+
#include "ld_fld.h"
#include "../../db/db_drv.h"
@@ -43,8 +47,12 @@
#include "../../dprint.h"
#include "../../ut.h"
+#include <stdlib.h>
+#include <strings.h>
#include <stdint.h>
#include <string.h>
+#include <time.h> /* strptime, XOPEN issue must be >= 4 */
+
/** Frees memory used by a ld_fld structure.
* This function frees all memory used by a ld_fld structure
@@ -127,11 +135,63 @@ static inline int ldap_bit2db_int(int* dst, str* src)
}
+/* Convert time_t structure to Generalized Time */
+static inline int db_datetime2ldap_gentime(str* dst, time_t src)
+{
+ /*
+ struct tm* t;
+
+ t = gmtime(&_time);
+ return strftime(result, res_len, "%Y%m%d%H%M%S", t);
+ */
+ return -1;
+}
+
+
+static inline int ldap_gentime2db_datetime(time_t* dst, str* src)
+{
+ struct tm time;
+
+ if (src->len < 12) return -1;
+
+ /* It is necessary to zero tm structure first */
+ memset(&time, '\0', sizeof(struct tm));
+ strptime(src->s, "%Y%m%d%H%M%S", &time);
+
+ /* Daylight saving information got lost in the database
+ * so let timegm to guess it. This eliminates the bug when
+ * contacts reloaded from the database have different time
+ * of expiration by one hour when daylight saving is used
+ */
+ time.tm_isdst = -1;
+#ifdef HAVE_TIMEGM
+ *dst = timegm(&time);
+#else
+ *dst = _timegm(&time);
+#endif /* HAVE_TIMEGM */
+ return 0;
+}
+
+
+static inline int ldap_str2db_double(double* dst, char* src)
+{
+ *dst = atof(src);
+ return 0;
+}
+
+
+static inline int ldap_str2db_float(float* dst, char* src)
+{
+ *dst = (float)atof(src);
+ return 0;
+}
+
+
int ld_ldap2fld(db_fld_t* fld, LDAP* ldap, LDAPMessage* msg)
{
int i;
struct ld_fld* lfld;
- str tmp;
+ str v;
if (fld == NULL || msg == NULL) return 0;
for(i = 0; !DB_FLD_EMPTY(fld) && !DB_FLD_LAST(fld[i]); i++) {
@@ -151,32 +211,57 @@ int ld_ldap2fld(db_fld_t* fld, LDAP* ldap, LDAPMessage* msg)
return -1;
}
+ v.s = lfld->values[0]->bv_val;
+ v.len = lfld->values[0]->bv_len;
+
switch(fld[i].type) {
case DB_CSTR:
- fld[i].v.cstr = lfld->values[0]->bv_val;
+ fld[i].v.cstr = v.s;
break;
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;
+ fld[i].v.lstr.s = v.s;
+ fld[i].v.lstr.len = v.len;
break;
case DB_INT:
case DB_BITMAP:
- tmp.s = lfld->values[0]->bv_val;
- tmp.len = lfld->values[0]->bv_len;
+ if (v.s[0] == '\'' &&
+ v.s[v.len - 1] == 'B' &&
+ v.s[v.len - 2] == '\'') {
+
+ v.s++;
+ v.len -= 3;
+ return ldap_bit2db_int(&fld[i].v.int4, &v);
+ } else {
+ return ldap_int2db_int(&fld[i].v.int4, &v);
+ }
+ break;
+ case DB_DATETIME:
+ if (ldap_gentime2db_datetime(&fld[i].v.time, &v) != 0) {
+ ERR("ldap: Error while converting LDAP time value '%.*s'\n",
+ v.len, ZSW(v.s));
+ return -1;
+ }
+ break;
- if (tmp.s[0] == '\'' &&
- tmp.s[tmp.len - 1] == 'B' &&
- tmp.s[tmp.len - 2] == '\'') {
+ case DB_FLOAT:
+ /* We know that the ldap library zero-terminated v.s */
+ if (ldap_str2db_float(&fld[i].v.flt, v.s) != 0) {
+ ERR("ldap: Error while converting '%.*s' to float\n",
+ v.len, ZSW(v.s));
+ return -1;
+ }
+ break;
- tmp.s++;
- tmp.len -= 3;
- return ldap_bit2db_int(&fld[i].v.int4, &tmp);
- } else {
- return ldap_int2db_int(&fld[i].v.int4, &tmp);
+ case DB_DOUBLE:
+ /* We know that the ldap library zero-terminated v.s */
+ if (ldap_str2db_double(&fld[i].v.dbl, v.s) != 0) {
+ ERR("ldap: Error while converting '%.*s' to double\n",
+ v.len, ZSW(v.s));
+ return -1;
}
break;
diff --git a/modules/db_ldap/standards.txt b/modules/db_ldap/standards.txt
index 77d9d2c..e24244d 100644
--- a/modules/db_ldap/standards.txt
+++ b/modules/db_ldap/standards.txt
@@ -23,3 +23,5 @@ RFC4530: LDAP entryUUID Operational Attribute
directory. Such identifiers can be used to identify the object even
when the dn of the object changes. Unfortunately the entryUUID attribute
cannot by modified by the user and thus it is not directly usable for us.
+
+RFC2252 LDAPv3: Attribute Syntax Definitions
diff --git a/modules/db_ldap/todo.txt b/modules/db_ldap/todo.txt
index 7e9c544..14fb139 100644
--- a/modules/db_ldap/todo.txt
+++ b/modules/db_ldap/todo.txt
@@ -1,11 +1,68 @@
-* Support for authentication
-* Support for SSL
-* Copy all data from the configuration structures into db api structures
- (right now we only store pointers)
-* Implement < and > operators properly
-* Implement support for other than str parameters
-* Escape values of parameters injected into the search filter
-* 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)
+* Authentication Support
+
+ The driver supports no authentication method at the moment, we should
+ include support for simple authentication at least, but better SASL.
+ This will take a change in the URI parser because the one provided
+ by libldap (which we use to parse the URI right now) does not support
+ embedded usernames and passwords in the URI.
+* TLS/SSL Support
+
+ The driver should support encrypted connections to LDAP servers and some
+ level of certificate validation. Currently there are no options or
+ parameters to configure SSL/TLS certificates and keys to use.
+
+* Copy Data from Config Data Structure
+
+ The driver maintains an internal data structure that gets initialized
+ from the supplied configuration file. The structure contains things like
+ search filters and field mapping tables. The LDAP specific extension
+ structures make a shallow copy of strings from the configuration
+ data structure, they should rather copy the whole string so that they
+ do not depend on the config structure.
+
+* Implement Support For < And > Operators
+
+ The LDAP search filter syntax (RFC4515) does not support < and >
+ operators, only <= and >=. Currently the ldap driver simply uses <= instead
+ of < and >= instead of >. We need a better implementation of this.
+
+* Implement Support For Other Than str Parameters
+
+* Escape Values of Parameters Injected Into the Search Filter
+
+ see RFC4515 for description of escaping.
+
+* Proper handling of NULL Values in Parameter.
+
+ Is it correct that parameters with NULL values are represented as
+ paramName= in the filter?
+
+* Use Asynchronous API Functions Instead of Synchronous
+
+ This would be useful when we have support for multiple database drivers
+ within one database context, then we could initiate multiple searches
+ simultaneously without being blocked waiting for the result.
+
+* Support For Multi-Value Attributes
+
+ The module should support multi-value attributes. Objects containing
+ attributes with multi-values should be returned as multiple records,
+ each record containing one value of the multi-value attribute. Currently
+ the module will report an error if it encounters a multi-value attribute.
+
+* Support For Time Zones in Generalized Times
+
+ The time conversion functions ignore time zones in GeneralizedTime
+ attributes, this should be fixed.
+
+* Handle Fractions of Seconds in Generalized Time
+
+ There is no need to account fractions of seconds because we store time
+ internally as time_t, but the parses should be able to skip fractions
+ of seconds gracefully.
+
+* Eliminate Use of All libldap Functions Marked as Deprecated
+
+ We should eliminate the use of all functions that are marked as deprecated
+ in the header field and remove LDAP_DEPRECATED define from all files.