3 messages in net.sourceforge.lists.courier-maildrop[maildropl] [PATCH]mysql & ldap auto ...
FromSent OnAttachments
Chris MastersOct 5, 2003 1:29 pm 
Devin RubiaOct 6, 2003 8:37 am 
Erik BourgetOct 6, 2003 9:21 am 
Actions with this message:
Paste this link in email or IM:
Paste this link in email or IM:
Atom feed for this thread
Paste this URL into your reader:
Subject:[maildropl] [PATCH]mysql & ldap auto failover and timeoutActions...
From:Chris Masters (roti@yahoo.com)
Date:Oct 5, 2003 1:29:43 pm
List:net.sourceforge.lists.courier-maildrop

Hi all,

I needed fault tolrance in my system, so I've had to write a patch to auto failover through a list of hosts for both mysql and ldap.

Just use the following in maildropmysql.config (or maildropldap.config):

hostname 192.168.0.1,192.168.0.2

I've done this by using a comma-seperated list of hosts and alarm signals for timeouts. It works really well.

It will attempt to connect to the first source (ldap/mysql) and if there is no response (within 5 seconds) it will try the next until a reponse or all have been tried.

This patch incorporates the changes I made in my last patch (a week or 2 ago), so it must be used with that.

If I'm using diff wrong please let me know (I'm using it on Solaris).

Hope this will stop someone getting up in the night,

Enjoy, Chris

__________________________________ Do you Yahoo!? The New Yahoo! Shopping - with improved product search http://shopping.yahoo.com

*** mdldap.c.old Sun Jun 9 15:26:19 2002 --- mdldap.c Fri Oct 3 15:31:59 2003 *************** *** 1,5 **** --- 1,6 ---- #include <stdio.h> #include <stdlib.h> + #include <signal.h> #include <string.h> #include <sys/time.h>

*************** *** 9,17 **** #include <lber.h> #include <ldap.h>

mdldaprec *get_user_ldap(mdldapconfig *cfg,char *username) { ! LDAP *ldap; LDAPMessage *result; LDAPMessage *entry; char *tmp_filter,*filter; --- 10,21 ---- #include <lber.h> #include <ldap.h>

+ void ldap_timed_out(){} + mdldaprec *get_user_ldap(mdldapconfig *cfg,char *username) { ! struct sigaction action; ! LDAP *ldap = NULL; LDAPMessage *result; LDAPMessage *entry; char *tmp_filter,*filter; *************** *** 22,39 **** int needbind = 0; char *mail_filter; struct timeval tv;

! ldap = ldap_init(cfg->hostname,cfg->port); ! if ( !ldap ) ! return NULL;

! if ( cfg->binddn && cfg->bindpw ) ! { ! needbind = 1; ! if ( ldap_simple_bind_s(ldap,cfg->binddn,cfg->bindpw) != 0 ) ! return NULL; ! }

if ( !strcasecmp(cfg->search_method,"mail") ) { mail_filter = (char*)malloc(strlen(cfg->mail_attr)+5); --- 26,77 ---- int needbind = 0; char *mail_filter; struct timeval tv; + char *tempname = NULL; + char temphn2[64]; + int pos1 = 0,pos2 = 0,i,timeout = 5,bind_result = 0;

! //alarm timeout initialisation for databse connect ! bzero(&action, sizeof(action)); ! action.sa_handler = ldap_timed_out; ! action.sa_flags = 0; ! sigaction(SIGALRM, &action, 0);

! tempname = (char*)strdup(cfg->hostname);

+ for(i=0;i<strlen(tempname)+1;i++) + { + if(tempname[i] == ',' || tempname[i] == '\0') + { + pos2 = i; + memset(temphn2,'\0',64); + strncpy(temphn2,tempname+pos1,pos2-pos1); + pos1 = pos2+1; + + alarm(timeout); + + ldap = ldap_init(temphn2,cfg->port); + if ( !ldap ) + return NULL; + + if ( cfg->binddn && cfg->bindpw ) + { + needbind = 1; + bind_result = ldap_simple_bind_s(ldap,cfg->binddn,cfg->bindpw); + } + + alarm(0); + + if(bind_result == 0) + break; + + fprintf(stderr, "Could not connect to ldap %s\n", temphn2); + } + } + free(tempname); + + if (bind_result != 0) + return NULL; + if ( !strcasecmp(cfg->search_method,"mail") ) { mail_filter = (char*)malloc(strlen(cfg->mail_attr)+5); *************** *** 94,100 **** values=ldap_get_values(ldap,entry,cfg->maildir_attr); if ( ldap_count_values(values) > 0 ) { ! rec->maildir = strdup(values[0]); ldap_value_free(values); } else rec->maildir = NULL; --- 132,142 ---- values=ldap_get_values(ldap,entry,cfg->maildir_attr); if ( ldap_count_values(values) > 0 ) { ! rec->maildir= malloc(sizeof(char) * (strlen(values[0]) +
strlen(cfg->maildir_base_ldap) + 1)); ! strcpy(rec->maildir,cfg->maildir_base_ldap); ! strcat(rec->maildir,values[0]); ! ! //rec->maildir = strdup(values[0]); ldap_value_free(values); } else rec->maildir = NULL; *************** *** 129,135 ****

values=ldap_get_values(ldap,entry,cfg->homedirectory_attr); if ( ldap_count_values(values) > 0 ) { ! rec->homedirectory = strdup(values[0]); ldap_value_free(values); } else { rec->homedirectory = NULL; --- 171,180 ----

values=ldap_get_values(ldap,entry,cfg->homedirectory_attr); if ( ldap_count_values(values) > 0 ) { ! rec->homedirectory = malloc(sizeof(char) * (strlen(values[0]) +
strlen(cfg->maildir_base_ldap) + 1)); ! strcpy(rec->homedirectory,cfg->maildir_base_ldap); ! strcat(rec->homedirectory,values[0]); ! //rec->homedirectory = strdup(values[0]); ldap_value_free(values); } else { rec->homedirectory = NULL;

*** mdmysql.c.old Tue Dec 4 13:08:32 2001 --- mdmysql.c Fri Oct 3 14:58:26 2003 *************** *** 1,5 **** --- 1,6 ---- #include <stdio.h> #include <stdlib.h> + #include <signal.h> #include <string.h> #include <sys/time.h> #include <errno.h> *************** *** 12,19 **** --- 13,23 ----

extern int errno;

+ void timed_out(){} + mdmysqlrec *get_user_mysql(mdmysqlconfig *cfg,char *username) { + struct sigaction action; MYSQL mysql_buf, *mysql=0; MYSQL_RES *result; MYSQL_ROW row; *************** *** 22,37 **** "SELECT %s, %s, %s, %s, %s, %s, %s FROM %s WHERE %s = \"%s\" %s"; char *querybuf; unsigned int querybuf_len;

#if MYSQL_VERSION_ID >= 32200 ! mysql_init(&mysql_buf); ! mysql=mysql_real_connect(&mysql_buf, cfg->hostname, cfg->dbuser, cfg->dbpw, NULL, cfg->port, cfg->socket, 0); #else ! mysql=mysql_connect(&mysql_buf, server, userid, password); #endif

if ( !mysql ) return NULL; if (mysql_select_db(mysql, cfg->database)) --- 26,72 ---- "SELECT %s, %s, %s, %s, %s, %s, %s FROM %s WHERE %s = \"%s\" %s"; char *querybuf; unsigned int querybuf_len; + char *tempname = NULL; + char temphn2[64]; + int pos1 = 0,pos2 = 0,i,timeout = 5;

+ //alarm timeout initialisation for databse connect + bzero(&action, sizeof(action)); + action.sa_handler = timed_out; + action.sa_flags = 0; + sigaction(SIGALRM, &action, 0);

+ tempname = (char*)strdup(cfg->hostname); + + for(i=0;i<strlen(tempname)+1;i++) + { + if(tempname[i] == ',' || tempname[i] == '\0') + { + pos2 = i; + memset(temphn2,'\0',64); + strncpy(temphn2,tempname+pos1,pos2-pos1); + pos1 = pos2+1; + + alarm(timeout); + #if MYSQL_VERSION_ID >= 32200 ! ! mysql_init(&mysql_buf); ! mysql=mysql_real_connect(&mysql_buf, temphn2, cfg->dbuser, cfg->dbpw, NULL, cfg->port, cfg->socket, 0); #else ! mysql=mysql_connect(&mysql_buf, server, userid, password); #endif + alarm(0);

+ if(mysql) + break; + + fprintf(stderr, "Could not connect to database %s\n", temphn2); + } + } + free(tempname); + if ( !mysql ) return NULL; if (mysql_select_db(mysql, cfg->database)) *************** *** 92,99 **** if (errno == ERANGE) rec->uidnumber = cfg->default_uidnumber; rec->gidnumber=atoi(row[2]); if (errno == ERANGE) rec->gidnumber = cfg->default_gidnumber; ! rec->homedir=strdup(row[3]); ! rec->maildir=strdup(row[4]); rec->quota=strdup(row[5]); rec->mailstatus=strdup(row[6]);

--- 127,145 ---- if (errno == ERANGE) rec->uidnumber = cfg->default_uidnumber; rec->gidnumber=atoi(row[2]); if (errno == ERANGE) rec->gidnumber = cfg->default_gidnumber; ! ! //following lines added my cmasters 27-09-2003 for virtual base capability ! rec->homedir=malloc(sizeof(char) * (strlen(row[3]) +
strlen(cfg->maildir_base) + 1)); ! memset(rec->homedir,'\0',(strlen(row[3]) + strlen(cfg->maildir_base) + 1)); ! strcpy(rec->homedir,cfg->maildir_base); ! strcat(rec->homedir,row[3]); ! //rec->homedir=strdup(row[3]); ! rec->maildir=malloc(sizeof(char) * (strlen(row[3]) +
strlen(cfg->maildir_base) + 1)); ! memset(rec->maildir,'\0',(strlen(row[4]) + strlen(cfg->maildir_base) + 1)); ! strcpy(rec->maildir,cfg->maildir_base); ! strcat(rec->maildir,row[4]); ! //rec->maildir=strdup(row[4]); ! rec->quota=strdup(row[5]); rec->mailstatus=strdup(row[6]);