diff -c -N -r sendmail-8.9.3/src/Makefile.m4 sendmail+mysql/src/Makefile.m4 *** sendmail-8.9.3/src/Makefile.m4 Sat Jan 23 18:51:41 1999 --- sendmail+mysql/src/Makefile.m4 Mon Jul 19 12:28:07 1999 *************** *** 32,38 **** # see also conf.h for additional compilation flags # include directories ! INCDIRS=confINCDIRS # loader options LDOPTS= ifdef(`confLDOPTS', `confLDOPTS') --- 32,38 ---- # see also conf.h for additional compilation flags # include directories ! INCDIRS=confINCDIRS -I/usr/local/include/mysql # loader options LDOPTS= ifdef(`confLDOPTS', `confLDOPTS') *************** *** 42,48 **** # libraries required on your system # delete -l44bsd if you are not running BIND 4.9.x ! LIBS= ifdef(`confLIBS', `confLIBS') # location of sendmail binary (usually /usr/sbin or /usr/lib) BINDIR= ${DESTDIR}ifdef(`confMBINDIR', `confMBINDIR', `/usr/sbin') --- 42,48 ---- # libraries required on your system # delete -l44bsd if you are not running BIND 4.9.x ! LIBS= -lmysqlclient ifdef(`confLIBS', `confLIBS') # location of sendmail binary (usually /usr/sbin or /usr/lib) BINDIR= ${DESTDIR}ifdef(`confMBINDIR', `confMBINDIR', `/usr/sbin') *************** *** 72,78 **** daemon.o deliver.o domain.o envelope.o err.o headers.o macro.o \ main.o map.o mci.o mime.o parseaddr.o queue.o readcf.o recipient.o \ safefile.o savemail.o snprintf.o srvrsmtp.o stab.o stats.o \ ! sysexits.o trace.o udb.o usersmtp.o util.o version.o ${OBJADD} LINKS= ifdef(`confLINKS', `confLINKS', `${UBINDIR}/newaliases \ --- 72,79 ---- daemon.o deliver.o domain.o envelope.o err.o headers.o macro.o \ main.o map.o mci.o mime.o parseaddr.o queue.o readcf.o recipient.o \ safefile.o savemail.o snprintf.o srvrsmtp.o stab.o stats.o \ ! sysexits.o trace.o udb.o usersmtp.o util.o version.o \ ! mysql_sendmail.o ${OBJADD} LINKS= ifdef(`confLINKS', `confLINKS', `${UBINDIR}/newaliases \ diff -c -N -r sendmail-8.9.3/src/mysql_sendmail.c sendmail+mysql/src/mysql_sendmail.c *** sendmail-8.9.3/src/mysql_sendmail.c Tue Jul 20 01:29:38 1999 --- sendmail+mysql/src/mysql_sendmail.c Tue Jul 20 00:58:59 1999 *************** *** 0 **** --- 1,239 ---- + #include + #include + #include + #include + #include "mysql_sendmail.h" + #include "sendmail.h" + + #define CONF_FILE "/etc/sendmail_mysql.conf" + #define BUF_SIZE 128 + + MYSQL mysql; + MYSQL_RES *result; + my_ulonglong num_rows; + my_ulonglong num_fields; + char *mysql_alias; + MYSQL_ROW field; + MAP *map; + char *name; + struct mysql_sendmail_struct *mysqlconf; + struct mysql_sendmail_struct *mysqlpwd; + + char *get_mysql_alias(char *mysql_name) + { + + char queryBuf[256]; + + mysql_init(&mysql); + mysqlconf=get_mysql_conf(); + if(mysqlconf == NULL) + { + sm_syslog(LOG_INFO, NOQID,"Error reading config file"); + return NULL; + } + if(!mysql_real_connect(&mysql,mysqlconf->mysql_host,mysqlconf->mysql_user,mysqlconf->mysql_passwd,mysqlconf->mysql_database,0,NULL,0)) + { + sm_syslog(LOG_INFO, NOQID, + "Connection to MySQL server failed(%s)",mysql_error(&mysql)); + mysql_close(&mysql); + return NULL; + } + snprintf(queryBuf, sizeof(queryBuf), "select alias from %s where address = \'%s\'",mysqlconf->mysql_alias_table,mysql_name); + #ifdef MYSQL_VERBOSE + + sm_syslog(LOG_INFO, NOQID,"Looking up %s in alias table\n",mysql_name); + + #endif + mysql_query(&mysql,queryBuf); + result=mysql_store_result(&mysql); + if(result == NULL) + { + #ifdef MYSQL_VERBOSE + + sm_syslog(LOG_INFO, NOQID,"Error sending query to server\n"); + + #endif + mysql_free_result(result); + mysql_close(&mysql); + return NULL; + } + num_rows=mysql_num_rows(result); + if(num_rows == 0) + { + #ifdef MYSQL_VERBOSE + + sm_syslog(LOG_INFO, NOQID,"Not found...\n"); + + #endif + mysql_free_result(result); + mysql_close(&mysql); + return NULL; + } + field = mysql_fetch_row(result); + mysql_alias = field[0]; + #ifdef MYSQL_VERBOSE + + sm_syslog(LOG_INFO, NOQID,"Found, aliased to: %s\n",mysql_alias); + + #endif + mysql_free_result(result); + mysql_close(&mysql); + return mysql_alias; + } + + + struct mysql_sendmail_struct *get_mysql_conf() { + static struct mysql_sendmail_struct mss; + static char host[BUF_SIZE], user[BUF_SIZE], password[BUF_SIZE], + database[BUF_SIZE], user_table[BUF_SIZE], + alias_table[BUF_SIZE], map_table[BUF_SIZE]; + char buf[256]; + char *name, *value; + int pos; + char *delim = "\n \t"; + FILE *conf; + + mss.mysql_host = NULL; + mss.mysql_user = NULL; + mss.mysql_passwd = NULL; + mss.mysql_database = NULL; + mss.mysql_user_table = NULL; + mss.mysql_map_table = NULL; + + if(!(conf = fopen(CONF_FILE, "r"))) + /* Could not open config file */ + return NULL; + while(fgets(buf, 256, conf)) { + for(pos=0; strchr(delim+1, buf[pos]) && buf[pos]; pos++) + ; + name = buf+pos; + if(*name=='#' || *name=='\n' || *name==0) + continue; + for(; !strchr(delim, buf[pos]) && buf[pos]; pos++) + ; + buf[pos] = 0; + if(!*name) continue; + for(pos++; strchr(delim+1, buf[pos]) && buf[pos]; pos++) + ; + value = buf+pos; + for(; !strchr(delim, buf[pos]) && buf[pos]; pos++) + ; + buf[pos] = 0; + if(!*value) continue; + switch(name[5]) { + case 'H': + if(!strcmp(name, "MysqlHost")) { + strncpy(host, value, BUF_SIZE); + mss.mysql_host = host; + } + break; + case 'U': + if(!strcmp(name, "MysqlUsername")) { + strncpy(user, value, BUF_SIZE); + mss.mysql_user = user; + } else if(!strcmp(name, "MysqlUserTable")) { + strncpy(user_table, value, BUF_SIZE); + mss.mysql_user_table = user_table; + } + break; + case 'D': + if(!strcmp(name, "MysqlDatabase")) { + strncpy(database, value, BUF_SIZE); + mss.mysql_database = database; + } + break; + case 'M': + if(!strcmp(name, "MysqlMapTable")){ + strncpy(map_table, value, BUF_SIZE); + mss.mysql_map_table = map_table; + } + break; + case 'A': + if(!strcmp(name, "MysqlAliasTable")) { + strncpy(alias_table, value, BUF_SIZE); + mss.mysql_alias_table = alias_table; + } + break; + case 'P': + if(!strcmp(name, "MysqlPassword")) { + strncpy(password, value, BUF_SIZE); + mss.mysql_passwd = password; + } + break; + } + } + fclose(conf); + if(mss.mysql_host && mss.mysql_user && mss.mysql_passwd && + mss.mysql_database && mss.mysql_user_table && + mss.mysql_alias_table && mss.mysql_map_table) + { + return &mss; + } + return NULL; + } + + + struct passwd * get_mysql_pwd(char * user_name) + { + + char queryBuf[256]; + + static struct passwd pw; + mysql_init(&mysql); + mysqlpwd = get_mysql_conf(); + if(mysqlconf == NULL) + { + sm_syslog(LOG_INFO, NOQID,"Error reading config file"); + return NULL; + } + if(!mysql_real_connect(&mysql,mysqlpwd->mysql_host,mysqlpwd->mysql_user,mysqlpwd->mysql_passwd,mysqlpwd->mysql_database,0,NULL,0)) + { + sm_syslog(LOG_INFO, NOQID, + "Connection to MySQL server(%s) failed\n",mysql_error(&mysql)); + mysql_close(&mysql); + return NULL; + } + snprintf(queryBuf, sizeof(queryBuf), "select * from %s where username = \'%s\'",mysqlpwd->mysql_user_table,user_name); + #ifdef MYSQL_VERBOSE + + sm_syslog(LOG_INFO, NOQID,"Looking up %s in user table\n",user_name); + + #endif + mysql_query(&mysql, queryBuf); + if((result=mysql_store_result(&mysql)) == NULL) + { + mysql_close(&mysql); + return NULL; + } + num_rows=mysql_num_rows(result); + num_fields=mysql_num_fields(result); + if(num_rows == 0) + { + #ifdef MYSQL_VERBOSE + sm_syslog(LOG_INFO, NOQID,"Not found...\n"); + #endif + mysql_free_result(result); + mysql_close(&mysql); + return NULL; + } + + field=mysql_fetch_row(result); + #ifdef MYSQL_VERBOSE + + sm_syslog(LOG_INFO, NOQID,"Found,local user: %s\n",user_name); + + #endif + + pw.pw_name = field[0]; + pw.pw_passwd = field[1]; + pw.pw_uid = atoi(field[2]); + pw.pw_gid = atoi(field[3]); + if((pw.pw_gecos = field[4]) == NULL) + pw.pw_gecos = ",,,"; + pw.pw_dir = field[5]; + if((pw.pw_shell = field[6]) == NULL) + pw.pw_shell == "/bin/noshell"; + mysql_free_result(result); + mysql_close(&mysql); + return &pw; + } diff -c -N -r sendmail-8.9.3/src/mysql_sendmail.h sendmail+mysql/src/mysql_sendmail.h *** sendmail-8.9.3/src/mysql_sendmail.h Tue Jul 20 01:29:38 1999 --- sendmail+mysql/src/mysql_sendmail.h Tue Jul 20 00:48:55 1999 *************** *** 0 **** --- 1,23 ---- + #include + #include + + struct mysql_sendmail_struct + { + char *mysql_host; + char *mysql_user; + char *mysql_passwd; + char *mysql_database; + char *mysql_user_table; + char *mysql_alias_table; + char *mysql_map_table; + }; + + struct passwd *get_mysql_pwd(char *user_name); + struct passwd *get_mysql_uid(int user_id); + char *get_mysql_alias(char *mysql_name); + struct mysql_sendmail_struct *get_mysql_conf(); + char *mysql_map_dequote(char *); + static struct passwd pw; + typedef struct mysql_sendmail_struct MYSQL_MAP_STRUCT; + + #define EX_NOTFOUND EX_NOHOST diff -c -N -r sendmail-8.9.3/src/alias.c sendmail+mysql/src/alias.c *** sendmail-8.9.3/src/alias.c Tue Dec 29 12:42:25 1998 --- sendmail+mysql/src/alias.c Mon Jul 19 12:27:25 1999 *************** *** 11,16 **** --- 11,17 ---- */ # include "sendmail.h" + # include "mysql_sendmail.h" #ifndef lint static char sccsid[] = "@(#)alias.c 8.96 (Berkeley) 12/18/1998"; *************** *** 85,90 **** --- 86,99 ---- e->e_message = newstr("alias database unavailable"); return; } + p = get_mysql_alias(a->q_user); + if (stat == EX_TEMPFAIL || stat == EX_UNAVAILABLE) + { + a->q_flags |= QQUEUEUP; + if (e->e_message == NULL) + e->e_message = newstr("alias database unavailable"); + return; + } if (p == NULL) return; *************** *** 129,134 **** --- 138,144 ---- (void) strcat(obuf, a->q_user); owner = aliaslookup(obuf, &stat, e); if (owner == NULL) + if((owner = get_mysql_alias(obuf)) == NULL) return; /* reflect owner into envelope sender */ *************** *** 184,191 **** /* special case POstMastER -- always use lower case */ if (strcasecmp(name, "postmaster") == 0) name = "postmaster"; - return (*map->map_class->map_lookup)(map, name, NULL, pstat); } /* ** SETALIAS -- set up an alias map --- 194,201 ---- /* special case POstMastER -- always use lower case */ if (strcasecmp(name, "postmaster") == 0) name = "postmaster"; return (*map->map_class->map_lookup)(map, name, NULL, pstat); + } /* ** SETALIAS -- set up an alias map diff -c -N -r sendmail-8.9.3/src/conf.c sendmail+mysql/src/conf.c *** sendmail-8.9.3/src/conf.c Tue Jan 26 19:15:52 1999 --- sendmail+mysql/src/conf.c Mon Jul 19 12:27:25 1999 *************** *** 485,490 **** --- 485,493 ---- syslog_map_parseargs, null_map_open, null_map_close, syslog_map_lookup, null_map_store); #endif + MAPDEF("mysql", NULL, 0, + mysql_map_parseargs, mysql_map_open, mysql_map_close, + mysql_map_lookup, null_map_store); } #undef MAPDEF diff -c -N -r sendmail-8.9.3/src/map.c sendmail+mysql/src/map.c *** sendmail-8.9.3/src/map.c Tue Feb 2 15:10:21 1999 --- sendmail+mysql/src/map.c Tue Jul 20 00:57:07 1999 *************** *** 5207,5209 **** --- 5207,5529 ---- return regex_map_rewrite(map, "", (size_t)0, av); } #endif /* MAP_REGEX */ + + /* ########## MySQL MAP #################### */ + + #include + #include + #include + #include + #include "mysql_sendmail.h" + + MYSQL mysql; + MYSQL_RES *sql_result; + my_ulonglong num_rows; + MYSQL_ROW field; + my_ulonglong num_fields; + char *result; + + static MYSQL_MAP_STRUCT *mysqlmap; + + bool mysql_map_parseargs(map,args) + MAP *map; + char *args; + + { + + char *result; + register char *p = args; + register int done; + + mysqlmap = (MYSQL_MAP_STRUCT *) xalloc(sizeof(MYSQL_MAP_STRUCT)); + + + mysqlmap = get_mysql_conf(); + // return FALSE; + map->map_mflags |= MF_TRY0NULL | MF_TRY1NULL; + for (;;) + { + while (isascii(*p) && isspace(*p)) + p++; + if (*p != '-') + break; + switch (*++p) + { + case 'N': + map->map_mflags |= MF_INCLNULL; + map->map_mflags &= ~MF_TRY0NULL; + break; + + case 'O': + map->map_mflags &= ~MF_TRY1NULL; + break; + + case 'o': + + map->map_mflags |= MF_OPTIONAL; + break; + + case 'f': + map->map_mflags |= MF_NOFOLDCASE; + break; + + case 'm': + map->map_mflags |= MF_MATCHONLY; + break; + + case 'A': + map->map_mflags |= MF_APPEND; + break; + + case 'q': + map->map_mflags |= MF_KEEPQUOTES; + break; + + case 't': + map->map_mflags |= MF_NODEFER; + break; + + case 'a': + map->map_app = ++p; + break; + case 'T': + map->map_tapp = ++p; + break; + + case 'H': /* mysql host */ + while (isascii(*++p) && isspace(*p)) + continue; + map->map_domain = p; + mysqlmap->mysql_host = p; + break; + + case 'D': /* mysql database */ + while (isascii(*++p) && isspace(*p)) + continue; + mysqlmap->mysql_database = p; + break; + + + case 'M': /* mysql map table */ + while (isascii(*++p) && isspace(*p)) + continue; + mysqlmap->mysql_map_table = p; + break; + + case 'P': /* mysql passwd */ + while (isascii(*++p) && isspace(*p)) + continue; + mysqlmap->mysql_passwd = p; + break; + + case 'U': /* mysql username */ + while (isascii(*++p) && isspace(*p)) + continue; + mysqlmap->mysql_user = p; + break; + + } + /* need to account for quoted strings here arggg... */ + done = isascii(*p) && isspace(*p); + while (*p != '\0' && !done) + { + if (*p == '"') + { + while (*++p != '"' && *p != '\0') + { + continue; + } + if (*p != '\0') + p++; + } + else + { + p++; + } + done = isascii(*p) && isspace(*p); + } + + if (*p != '\0') + *p++ = '\0'; + } + if (map->map_app != NULL) + map->map_app = newstr(mysql_map_dequote(map->map_app)); + if (map->map_tapp != NULL) + map->map_tapp = newstr(mysql_map_dequote(map->map_tapp)); + if (map->map_domain != NULL) + map->map_domain = newstr(mysql_map_dequote(map->map_domain)); + + + if (mysqlmap->mysql_host == NULL) + { + syserr("MySQL map: -h for host is required"); + return FALSE; + } + else { + mysqlmap->mysql_host = newstr(mysql_map_dequote(mysqlmap->mysql_host)); + } + if (mysqlmap->mysql_user == NULL) + { + syserr("MySQL map: -x for username is required"); + return FALSE; + } + else { + mysqlmap->mysql_user = newstr(mysql_map_dequote(mysqlmap->mysql_user)); + } + if (mysqlmap->mysql_passwd == NULL) + { + syserr("MySQL map: -p for password is required"); + return FALSE; + } + else { + mysqlmap->mysql_passwd = newstr(mysql_map_dequote(mysqlmap->mysql_passwd)); + } + if (mysqlmap->mysql_database == NULL) + { + syserr("MySQL map: -b for database name is required"); + return FALSE; + } + else { + mysqlmap->mysql_database = newstr(mysql_map_dequote(mysqlmap->mysql_database)); + } + if (mysqlmap->mysql_map_table == NULL) + { + syserr("MySQL map: -d for domainalias table is required"); + return FALSE; + } + else { + mysqlmap->mysql_map_table = newstr(mysql_map_dequote(mysqlmap->mysql_map_table)); + } + + map->map_db1 = (ARBPTR_T) mysqlmap; + return TRUE; + } + + mysql_map_open(map, mode) + MAP *map; + int mode; + { + int *statp; + + mysqlmap = (MYSQL_MAP_STRUCT *) map->map_db1; + mysql_init(&mysql); + if(!mysql_real_connect(&mysql,mysqlmap->mysql_host,mysqlmap->mysql_user,mysqlmap->mysql_passwd,mysqlmap->mysql_database,0,NULL,0)) + { + sm_syslog(LOG_INFO, NOQID, + "Connection to MySQL server failed(%s)",mysql_error(&mysql)); + mysql_close(&mysql); + return FALSE; + } + if (tTd(38, 2)) + printf("mysql_map_open(%s, %d)\n", map->map_mname,mode); + #ifdef MYSQL_VERBOSE + + sm_syslog(LOG_INFO, NOQID, + "Connecting to MySQL server(%s)",mysqlmap->mysql_host); + + #endif + + mode &= O_ACCMODE; + if (mode != O_RDONLY) + { + return FALSE; + } + return TRUE; + + } + char *mysql_map_lookup(map, name, av, statp) + MAP *map; + char *name; + char **av; + int *statp; + + { + char keybuf[MAXNAME + 1]; + int name_len; + char queryBuf[256]; + + if (tTd(38, 20)) + printf("mysql_map_lookup(%s, %s)\n", map->map_mname, name); + + mysqlmap = (MYSQL_MAP_STRUCT *) map->map_db1; + name_len = strlen(name); + if (name_len > MAXNAME) + name_len = MAXNAME; + strncpy(keybuf, name, name_len); + keybuf[name_len] = '\0'; + + mysqlmap = (MYSQL_MAP_STRUCT *) map->map_db1; + + #ifdef MYSQL_VERBOSE + + sm_syslog(LOG_INFO, NOQID,"Looking up %s in domainalias table\n",keybuf); + + #endif + snprintf(queryBuf, sizeof(queryBuf), "select domainalias from %s where address = \'%s\'",mysqlmap->mysql_map_table,keybuf); + mysql_query(&mysql, queryBuf); + if((sql_result=mysql_store_result(&mysql)) == NULL) + { + mysql_close(&mysql); + return NULL; + } + num_rows=mysql_num_rows(sql_result); + if(num_rows == 0) + { + #ifdef MYSQL_VERBOSE + + sm_syslog(LOG_INFO, NOQID,"Not found...\n"); + + #endif + result = NULL; + *statp = EX_NOTFOUND; + goto exit; + } + field=mysql_fetch_row(sql_result); + result = field[0]; + *statp = EX_OK; + #ifdef MYSQL_VERBOSE + + sm_syslog(LOG_INFO, NOQID,"Found, rewriting to: %s", field[0]); + + #endif + exit: return result; + mysql_map_close(map); + + } + + int mysql_map_close(map) + { + #ifdef MYSQL_VERBOSE + + sm_syslog(LOG_INFO, NOQID,"Disconnecting from MySQL server"); + + #endif + mysql_free_result(sql_result); + mysql_close(&mysql); + } + + char * + mysql_map_dequote(str) + char *str; + { + char *p; + char *start; + p = str; + + if (*p == '"') + { + start = ++p; + } + else + { + return(str); + } + while (*p != '"' && *p != '\0') + { + p++; + } + if (*p != '\0') + *p = '\0'; + return start; + } + diff -c -N -r sendmail-8.9.3/src/recipient.c sendmail+mysql/src/recipient.c *** sendmail-8.9.3/src/recipient.c Sat Jan 23 19:34:33 1999 --- sendmail+mysql/src/recipient.c Mon Jul 19 12:27:25 1999 *************** *** 16,22 **** # include "sendmail.h" # include ! /* ** SENDTOLIST -- Designate a send list. ** --- 16,22 ---- # include "sendmail.h" # include ! #include "mysql_sendmail.h" /* ** SENDTOLIST -- Designate a send list. ** *************** *** 497,508 **** /* warning -- finduser may trash buf */ pw = finduser(buf, &fuzzy); if (pw == NULL || strlen(pw->pw_name) > MAXNAME) ! { ! a->q_flags |= QBADADDR; ! a->q_status = "5.1.1"; ! giveresponse(EX_NOUSER, m, NULL, a->q_alias, ! (time_t) 0, e); ! } else { char nbuf[MAXNAME + 1]; --- 497,508 ---- /* warning -- finduser may trash buf */ pw = finduser(buf, &fuzzy); if (pw == NULL || strlen(pw->pw_name) > MAXNAME) ! { ! a->q_flags |= QBADADDR; ! a->q_status = "5.1.1"; ! giveresponse(EX_NOUSER, m, NULL, a->q_alias, ! (time_t) 0, e); ! } else { char nbuf[MAXNAME + 1]; *************** *** 685,697 **** #endif /* look up this login name using fast path */ ! if ((pw = sm_getpwnam(name)) != NULL) ! { ! if (tTd(29, 4)) ! printf("found (non-fuzzy)\n"); ! return (pw); ! } ! /* try mapping it to lower case */ tryagain = FALSE; for (p = name; *p != '\0'; p++) --- 685,695 ---- #endif /* look up this login name using fast path */ ! if(((pw = sm_getpwnam(name)) != NULL)||((pw = get_mysql_pwd(name)) !=NULL)) ! { ! if (tTd(29, 4)) ! printf("found (non-fuzzy)\n"); ! } return (pw); /* try mapping it to lower case */ tryagain = FALSE; for (p = name; *p != '\0'; p++) *************** *** 702,708 **** tryagain = TRUE; } } ! if (tryagain && (pw = sm_getpwnam(name)) != NULL) { if (tTd(29, 4)) printf("found (lower case)\n"); --- 700,706 ---- tryagain = TRUE; } } ! if (tryagain && (pw = sm_getpwnam(name)) && get_mysql_pwd(name) != NULL) { if (tTd(29, 4)) printf("found (lower case)\n"); diff -c -N -r sendmail-8.9.3/src/version.c sendmail+mysql/src/version.c *** sendmail-8.9.3/src/version.c Thu Feb 4 19:38:46 1999 --- sendmail+mysql/src/version.c Mon Jul 19 12:44:45 1999 *************** *** 14,17 **** static char sccsid[] = "@(#)version.c 8.9.3.1 (Berkeley) 2/4/1999"; #endif /* not lint */ ! char Version[] = "8.9.3"; --- 14,17 ---- static char sccsid[] = "@(#)version.c 8.9.3.1 (Berkeley) 2/4/1999"; #endif /* not lint */ ! char Version[] = "8.9.3-MySQL-0.13"; diff -c -N -r sendmail-8.9.3/sendmail_mysql.conf sendmail+mysql/sendmail_mysql.conf