On Fri, Oct 24, 2008 at 09:33:09AM +1100, Simon Horman wrote:
On Thu, Oct 23, 2008 at 01:33:09PM +0100, Simon Fraser
wrote:
Hi folks,
I'm newly subscribed to this list, and while I've searched for a mention
of this before and come up with nothing, I apologise if I'm duplicating
a report.
I'm using perdition-1.17.1 with perditiondb_ldap. Due to the nature of
our site, some users will have a mailhost configured in here, and some
will not. I am hoping to use the outgoing_server configuration option
as a default should the server return a partial response, since one of
our existing systems will break if we started adding this to all the
currently empty fields.
This works if the user had a mailhost set, but was refusing to use the
outgoing_server option if they did not, instead attempting to connect to
the person's username, treating it as a hostname. Omitting the port
works whether the server is set or not.
I have tracked down this problem to user_server_port_strn_assign in
getserver.c. This function appears to be dual-purpose, used for both
parsing the outgoing_server option in the configuration file, and also
for parsing the string returned by dbserver_get. Since these have a
slightly different format (hostname[:port] vs
username[<delimiter>hostname[:port]]), it gets confused when the string
returned from the DB doesn't contain a server. It falls through into
its configuration parsing option at the end, setting (*usp)->server to
(*usp)->user (the start of the string), and so the connection attempts
gethostbyname(username).
Hi Simon,
thanks for tracking that down. I'll try and get a fix for it shortly.
Hi Simon,
I don't have an LDAP db handy to test against, so could
you please test the following change for me to see if
it helps your problem. If not, I'll dig deeper into the problem.
--
Simon Horman
VA Linux Systems Japan K.K., Sydney, Australia Satellite Office
H:
www.vergenet.net/~horms/ W:
www.valinux.co.jp/en
Allow the ldap db to return any one or more of: username, server and port.
This is done by switching the ldap module over to use db_getsever2() instead
of db_getserver(), which allows these elements to be returned individually,
rather than as a string that then has to be broken down into its parts -
which assumes that server is always present.
Signed-off-by: Simon Horman <horms(a)verge.net.au>
Index: perdition-1.17.1/perdition/db/ldap/perditiondb_ldap.c
===================================================================
--- perdition-1.17.1.orig/perdition/db/ldap/perditiondb_ldap.c 2008-10-26
11:40:35.000000000 +0000
+++ perdition-1.17.1/perdition/db/ldap/perditiondb_ldap.c 2008-10-26 11:47:53.000000000
+0000
@@ -285,25 +285,26 @@ static int pldap_scan_exts(char **exts,
/**********************************************************************
- * dbserver_get
+ * dbserver_get2
* Read the server (value) from an LDAP directory given the user (key)
* pre: key_str: Key as a null terminated string
- * options_str: Options string.
+ * options_str: Options string.
* Ignored if NULL
* Used as the map to open otherwise
- * str_return: value is returned here
- * len_return: length of value is returned here
- * post: The str_key is looked up in the gdbm map and the
- * corresponding value is returned in str_return and len_return.
+ * user_str: string for user is returned here
+ * server_str: string for server is returned here
+ * port_str: string for port is returned here
+ * post: The str_key is looked up in the ldap database and the
+ * corresponding values are returned in user_str, server_str and
+ * port_str.
* return: 0 on success
* -1 on LDAP access error
* -2 if key cannot be found in map
* -3 on other error
**********************************************************************/
-int dbserver_get(const char *key_str,
- const char *options_str,
- char **str_return, int *len_return)
+int dbserver_get2(const char *key_str, const char *options_str,
+ char **user_str, char **server_str, char **port_str)
{
LDAPURLDesc *lud = NULL;
LDAP *connection = NULL;
@@ -322,9 +323,6 @@ int dbserver_get(const char *key_str,
extern options_t opt;
- *len_return = 0;
-
-
/* get filter string */
if (pldap_get_filter(key_str, pldap_filter, &lud) < 0) {
VANESSA_LOGGER_DEBUG("pldap_get_filter");
@@ -432,7 +430,6 @@ int dbserver_get(const char *key_str,
goto leave;
}
- *len_return = 0;
for (pstr = ldap_first_attribute(connection, mptr, &ber);
pstr != NULL;
pstr = ldap_next_attribute(connection, mptr, ber)) {
@@ -442,7 +439,6 @@ int dbserver_get(const char *key_str,
if (strcasecmp(lud->lud_attrs[count], pstr) != 0) {
continue;
}
- *len_return += strlen(*bv_val);
if (returns[count] != NULL) {
free(returns[count]);
}
@@ -465,36 +461,13 @@ int dbserver_get(const char *key_str,
ber_free(ber, 0);
ber = NULL;
- /* Add in some extra for the separators and terminating NULL */
- *len_return += 2 + strlen(opt.domain_delimiter);
-
- if ((*str_return = (char *) calloc(1, *len_return)) == NULL) {
- VANESSA_LOGGER_DEBUG_ERRNO("str_return calloc");
- status = -3;
- goto leave;
- }
-
/* Build the return string */
- if (attrcount > 0 && returns[0]) {
- strcat(*str_return, returns[0]);
- }
- if (attrcount > 1 && returns[1]) {
- if (returns[0]) {
- strcat(*str_return, opt.domain_delimiter);
- }
- strcat(*str_return, returns[1]);
- }
- if (attrcount > 2 && returns[2] && returns[1]) {
- strcat(*str_return, ":");
- strcat(*str_return, returns[2]);
- }
- for (count = 0; count < attrcount; count++) {
- if (!returns[count]) {
- continue;
- }
- free(returns[count]);
- returns[count] = NULL;
- }
+ if (returns[0])
+ user_str = &returns[0];
+ if (returns[1])
+ server_str = &returns[1];
+ if (returns[2])
+ port_str = &returns[2];
status = 0;
Index: perdition-1.17.1/perdition/getserver.c
===================================================================
--- perdition-1.17.1.orig/perdition/getserver.c 2008-10-26 11:40:35.000000000 +0000
+++ perdition-1.17.1/perdition/getserver.c 2008-10-26 11:42:48.000000000 +0000
@@ -291,9 +291,21 @@ do_getserver(
}
/* Check for an empty result */
- if(!server_str || *server_str=='\0') {
- VANESSA_LOGGER_DEBUG("dbserver_get returned empty string");
- goto fail;
+ if(dbserver_get) {
+ if(!server_str || *server_str=='\0') {
+ VANESSA_LOGGER_DEBUG("dbserver_get returned empty "
+ "string");
+ goto fail;
+ }
+ }
+ else {
+ if((!user_str || *user_str=='\0') &&
+ (!server_str || *server_str=='\0') &&
+ (!port_str || *port_str=='\0')) {
+ VANESSA_LOGGER_DEBUG("dbserver_get returned empty "
+ "string");
+ goto fail;
+ }
}
if(dbserver_get) {