*** sendmail-8.10.0.Beta12/devtools/Site/site.config.m4 Mon Apr 3 16:20:48 2000 --- sendmail-devel/devtools/Site/site.config.m4 Mon Apr 3 15:31:20 2000 *************** *** 0 **** --- 1,8 ---- + APPENDDEF(`confENVDEF', `-DMYSQL_MAP') + APPENDDEF(`confINCDIRS', `-I/usr/include -I/usr/local/mysql/include/mysql') + APPENDDEF(`confLIBDIRS', `-L/usr/local/mysql/lib/mysql/') + APPENDDEF(`confLIBS', `-lmysqlclient') + + APPENDDEF(`confSMSRCADD', `mysql_sendmail.c') + APPENDDEF(`confSMOBJADD', `mysql_sendmail.o') + *** sendmail-8.10.0.Beta12/sendmail/mysql_sendmail.h Mon Apr 3 16:20:48 2000 --- sendmail-devel/sendmail/mysql_sendmail.h Mon Apr 3 13:23:10 2000 *************** *** 0 **** --- 1,28 ---- + #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; + char *mysql_lhs_col; + char *mysql_rhs_col; + }; + + 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; + MYSQL_MAP_STRUCT *mysql_map_scanconf(); + + #define EX_NOTFOUND EX_NOHOST + #define ALIAS_LHS "address" + #define ALIAS_RHS "alias" *** sendmail-8.10.0.Beta12/sendmail/alias.c Tue Jan 18 16:55:31 2000 --- sendmail-devel/sendmail/alias.c Mon Apr 3 13:46:00 2000 *************** *** 11,16 **** --- 11,17 ---- */ #include + #include #ifndef lint static char id[] = "@(#)$Id: alias.c,v 8.139 2000/01/18 21:55:31 gshapiro Exp $"; *************** *** 110,115 **** --- 111,128 ---- return; } if (p == NULL) + { + p = get_mysql_alias(a->q_user); + if (stat == EX_TEMPFAIL || stat == EX_UNAVAILABLE) + { + a->q_flags |= QS_QUEUEUP; + if (e->e_message == NULL) + e->e_message = newstr("alias database unavailable"); + return; + } + } + + if (p == NULL) return; /* *************** *** 165,170 **** --- 178,184 ---- (void) strlcat(obuf, a->q_user, sizeof obuf); owner = aliaslookup(obuf, &status); if (owner == NULL) + if((owner = get_mysql_alias(obuf)) == NULL) return; /* reflect owner into envelope sender */ *** sendmail-8.10.0.Beta12/sendmail/conf.c Thu Jan 20 01:31:01 2000 --- sendmail-devel/sendmail/conf.c Mon Apr 3 13:23:10 2000 *************** *** 556,561 **** --- 556,566 ---- map_parseargs, null_map_open, null_map_close, bogus_map_lookup, null_map_store); } + #ifdef MYSQL_MAP + MAPDEF("mysql", NULL, 0, + mysql_map_parseargs, mysql_map_open, mysql_map_close, + mysql_map_lookup, null_map_store); + #endif } #undef MAPDEF *** sendmail-8.10.0.Beta12/sendmail_mysql.conf Mon Apr 3 16:20:48 2000 --- sendmail-devel/sendmail_mysql.conf Mon Apr 3 15:40:58 2000 *************** *** 0 **** --- 1,20 ---- + ############################################################################## + # General (can be overriden in sendmail.cf by per map options) + ############################################################################## + + MysqlHost host + MysqlUsername username + MysqlPassword password + MysqlDatabase database_name + MysqlUserTable users_table + MysqlAliasTable alias_table + MysqlMapTable default_map_table + + ############################################################################## + # For the MySQL MAP only (for alias you have to define it in + # mysql_sendmail.h before you compile) + ############################################################################## + + MysqlLHSColumn default_key_column + MysqlRHSColumn default_value_column + *** sendmail-8.10.0.Beta12/sendmail/mysql_sendmail.c Mon Apr 3 16:20:48 2000 --- sendmail-devel/sendmail/mysql_sendmail.c Mon Apr 3 13:46:32 2000 *************** *** 0 **** --- 1,300 ---- + #include + #include + #include + #include + #include + #include + + #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; + // struct mysql_sendmail_struct *mysql_class; + + 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 %s from %s where %s = \'%s\'",ALIAS_RHS,mysqlconf->mysql_alias_table,ALIAS_LHS,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) + { + sm_syslog(LOG_INFO, NOQID,"Error sending query to server\n"); + 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], + lhs[BUF_SIZE],rhs[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; + mss.mysql_rhs_col = NULL; + mss.mysql_lhs_col = 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; + #ifdef MYSQL_MAP + case 'R': + if(!strcmp(name, "MysqlRHSColumn")) { + strncpy(rhs, value, BUF_SIZE); + mss.mysql_rhs_col = rhs; + } + break; + case 'L': + if(!strcmp(name, "MysqlLHSColumn")) { + strncpy(lhs, value, BUF_SIZE); + mss.mysql_lhs_col = lhs; + } + break; + #endif + } + } + fclose(conf); + if(mss.mysql_host && mss.mysql_user && /* mss.mysql_passwd && */ + mss.mysql_database && mss.mysql_user_table && + #ifdef MYSQL_MAP + mss.mysql_lhs_col && mss.mysql_rhs_col && + #endif + 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); + 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(%s) failed\n",mysql_error(&mysql)); + mysql_close(&mysql); + return NULL; + } + snprintf(queryBuf, sizeof(queryBuf), "select * from %s where username = \'%s\'",mysqlconf->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) + { + sm_syslog(LOG_INFO, NOQID,"Error sending query to server"); + 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; + } + + void mysqlclass(class, hostname, db_name, table_name) + + int class; + const char *hostname; + const char *db_name; + const char *table_name; + { + int i; + char queryBuf[256]; + + mysql_init(&mysql); + mysqlconf = get_mysql_conf(); + if(mysqlconf == NULL) + { + syserr("Error reading config file"); + return; + } + + if(!mysql_real_connect(&mysql,hostname,mysqlconf->mysql_user,mysqlconf->mysql_passwd,db_name,0,NULL,0)) + { + syserr("Cannot connect to MySQL database server"); + return; + } + snprintf(queryBuf,sizeof(queryBuf),"select * from %s",table_name); + mysql_query(&mysql,queryBuf); + result=mysql_store_result(&mysql); + if(result == NULL) + { + syserr("Error querying MySQL server"); + return; + } + num_rows=mysql_num_rows(result); + if(num_rows == 0) + return; + for( i = 0; i < num_rows; i++) + { + field=mysql_fetch_row(result); + setclass(class, field[0]); + mysql_field_seek(result, 0); + } + } *** sendmail-8.10.0.Beta12/sendmail/readcf.c Thu Jan 13 16:47:09 2000 --- sendmail-devel/sendmail/readcf.c Mon Apr 3 13:44:33 2000 *************** *** 100,105 **** --- 100,106 ---- register char *p; long sff = SFF_OPENASROOT; struct stat statb; + char *hostname, *db_name, *table_name; char buf[MAXLINE]; char exbuf[MAXLINE]; char pvpbuf[MAXLINE + MAXATOM]; *************** *** 436,441 **** --- 437,495 ---- xla_init(&bp[1]); break; #endif /* XLA */ + + case 'Q': /* SQL class */ + mid = macid(&bp[1], &ep); + for (p = ep; isascii(*p) && isspace(*p); ) + p++; + if (p[0] == '-' && p[1] == 'o') + { + optional = TRUE; + while (*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + while (isascii(*p) && isspace(*p)) + p++; + } + else + optional = FALSE; + hostname = db_name = table_name = NULL; + while(*p) { + while(isascii(*p) && isspace(*p)) + p++; + if(*p != '-') { + syserr("mysqlclass: invalid argument, starts with a '%c' instead of a '-'", *p); + while(*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + while(isascii(*p) && isspace(*p)) + p++; + continue; + } + p++; + switch(*p) { + case 'H': + hostname = ++p; + break; + case 'D': + db_name = ++p; + break; + case 'T': + table_name = ++p; + break; + } + while(*p != '\0' && !(isascii(*p) && isspace(*p))) + p++; + if(!*p) + continue; + *p = 0; + p++; + } + + if(!hostname || !db_name || !table_name) { + syserr("mysqlclass: missing parameters"); + break; + } + mysqlclass(mid,hostname,db_name,table_name); + break; #if defined(SUN_EXTENSIONS) && defined(SUN_LOOKUP_MACRO) case 'L': /* lookup macro */ *** sendmail-8.10.0.Beta12/sendmail/map.c Tue Jan 18 14:32:30 2000 --- sendmail-devel/sendmail/map.c Mon Apr 3 13:46:47 2000 *************** *** 7048,7050 **** --- 7048,7421 ---- *statp = EX_CONFIG; return NULL; } + + /* ########## MySQL MAP #################### */ + + #include + #include + #include + #include + #include + + MYSQL mysql; + MYSQL_RES *sql_result; + my_ulonglong num_rows; + MYSQL_ROW field; + my_ulonglong num_fields; + char *result; + + MYSQL_MAP_STRUCT *mysqlmap; + + 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; + + { + MYSQL_MAP_STRUCT *mysqlmap = NULL; + 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); + if(!mysql_map_open(map)) + { + sm_syslog(LOG_INFO, NOQID,"Error connecting to server"); + mysql_close(&mysql); + *statp = EX_TEMPFAIL; + return NULL; + } + 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'; + + #ifdef MYSQL_VERBOSE + + sm_syslog(LOG_INFO, NOQID,"Looking up %s in domainalias table\n",keybuf); + + #endif + snprintf(queryBuf, sizeof(queryBuf), "select %s from %s where %s = \'%s\'",mysqlmap->mysql_rhs_col,mysqlmap->mysql_map_table,mysqlmap->mysql_lhs_col,keybuf); + mysql_query(&mysql, queryBuf); + sql_result = mysql_store_result(&mysql); + if(sql_result == NULL) + { + sm_syslog(LOG_INFO, NOQID,"Error sending query to server"); + mysql_close(&mysql); + *statp = EX_TEMPFAIL; + 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: + if(sql_result != NULL) + { + mysql_free_result(sql_result); + } + mysql_map_close(map); + + if(!result) + return NULL; + + if (bitset(MF_MATCHONLY, map->map_mflags)) + return map_rewrite(map, result, strlen(result), NULL); + else + return map_rewrite(map, result, strlen(result), av); + + // return result; + + } + + int mysql_map_close(map) + { + #ifdef MYSQL_VERBOSE + + sm_syslog(LOG_INFO, NOQID,"Disconnecting from MySQL server"); + + #endif + 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; + } + + // #endif + bool mysql_map_parseargs(map,args) + MAP *map; + char *args; + + { + + MYSQL_MAP_STRUCT *mysqlmap_conf; + char *result; + register char *p = args; + register int done; + if((mysqlmap_conf = get_mysql_conf()) == NULL) + { + + sm_syslog(LOG_INFO, NOQID,"Error reading config file"); + return FALSE; + } + mysqlmap = (MYSQL_MAP_STRUCT *) xalloc(sizeof(MYSQL_MAP_STRUCT)); + + memcpy(mysqlmap,mysqlmap_conf,sizeof(MYSQL_MAP_STRUCT)); + + 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; + + case 'L': /* mysql LHS table */ + while (isascii(*++p) && isspace(*p)) + continue; + mysqlmap->mysql_lhs_col = p; + break; + + case 'R': /* mysql RHS table */ + while (isascii(*++p) && isspace(*p)) + continue; + mysqlmap->mysql_rhs_col = 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) + mysqlmap->mysql_host = newstr(mysql_map_dequote(mysqlmap->mysql_host)); + else { + syserr("MySQL map: -H for Host is required"); + sm_syslog(LOG_INFO, NOQID,"Error getting server hostname"); + return FALSE; + } + if (mysqlmap->mysql_user != NULL) + mysqlmap->mysql_user = newstr(mysql_map_dequote(mysqlmap->mysql_user)); + else { + syserr("MySQL map: Username is required"); + sm_syslog(LOG_INFO, NOQID,"Error getting databse username"); + return FALSE; + } + // if (mysqlmap->mysql_passwd != NULL) + // mysqlmap->mysql_passwd = newstr(mysql_map_dequote(mysqlmap->mysql_passwd)); + // else { + // syserr("MySQL map: -P for Password is required"); + // sm_syslog(LOG_INFO, NOQID,"Error getting database password"); + // return FALSE; + // } + if (mysqlmap->mysql_database != NULL) + mysqlmap->mysql_database = newstr(mysql_map_dequote(mysqlmap->mysql_database)); + else { + syserr("MySQL map: -D for Database name is required"); + sm_syslog(LOG_INFO, NOQID,"Error getting database name"); + return FALSE; + } + if (mysqlmap->mysql_map_table != NULL) + mysqlmap->mysql_map_table = newstr(mysql_map_dequote(mysqlmap->mysql_map_table)); + else { + syserr("MySQL map: -M for Map table is required"); + sm_syslog(LOG_INFO, NOQID,"Error getting map table name"); + return FALSE; + } + + if (mysqlmap->mysql_lhs_col != NULL) + mysqlmap->mysql_lhs_col = newstr(mysql_map_dequote(mysqlmap->mysql_lhs_col)); + else { + syserr("MySQL map: -L for LHS column is required"); + sm_syslog(LOG_INFO, NOQID,"Error getting RHS column name"); + return FALSE; + } + + if (mysqlmap->mysql_rhs_col != NULL) + mysqlmap->mysql_rhs_col = newstr(mysql_map_dequote(mysqlmap->mysql_rhs_col)); + else { + syserr("MySQL map: -R for RHS column is required"); + sm_syslog(LOG_INFO, NOQID,"Error getting RHS column name"); + return FALSE; + } + + map->map_db1 = (ARBPTR_T) mysqlmap; + return TRUE; + } + *** sendmail-8.10.0.Beta12/sendmail/recipient.c Tue Jan 4 20:40:53 2000 --- sendmail-devel/sendmail/recipient.c Mon Apr 3 13:46:11 2000 *************** *** 16,21 **** --- 16,22 ---- #endif /* ! lint */ #include + #include static void includetimeout __P((void)); static ADDRESS *self_reference __P((ADDRESS *)); *************** *** 874,879 **** --- 875,886 ---- dprintf("found (non-fuzzy)\n"); return pw; } + else if((pw = get_mysql_pwd(name)) !=NULL) + { + if (tTd(29, 4)) + dprintf("found (non-fuzzy)\n"); + return pw; + } /* try mapping it to lower case */ tryagain = FALSE; *************** *** 892,897 **** --- 899,911 ---- *fuzzyp = TRUE; return pw; } + else if(pw = get_mysql_pwd(name) != NULL) + { + if (tTd(29, 4)) + printf("found (lower case)\n"); + *fuzzyp = TRUE; + return pw; + } #if MATCHGECOS /* see if fuzzy matching allowed */ *** sendmail-8.10.0.Beta12/mail.local/mail.local.c Fri Dec 24 20:27:21 1999 --- sendmail-devel/mail.local/mail.local.c Mon Apr 3 15:01:31 2000 *************** *** 31,36 **** --- 31,38 ---- ** work on such architectures. */ + #include + #include #include #include *************** *** 343,348 **** --- 345,355 ---- pw->pw_uid != uid)) from = (pw = getpwuid(uid)) != NULL ? pw->pw_name : "???"; + if (from == NULL && ((from = getlogin()) == NULL || + (pw = get_mysql_pwd(from)) == NULL || + pw->pw_uid != uid)) + from = (pw = get_mysql_pwd(uid)) != NULL ? pw->pw_name : "???"; + /* ** There is no way to distinguish the error status of one delivery ** from the rest of the deliveries. So, if we failed hard on one *************** *** 454,459 **** --- 461,467 ---- char *addr; { if (getpwnam(addr) == NULL) + if (get_mysql_pwd(addr) == NULL) return "550 5.1.1 user unknown"; return NULL; } *************** *** 895,923 **** ** handled in the sendmail aliases file. */ if ((pw = getpwnam(name)) == NULL) ! { ! if (ExitVal != EX_TEMPFAIL) ! ExitVal = EX_UNAVAILABLE; ! if (LMTPMode) ! { ! if (ExitVal == EX_TEMPFAIL) ! printf("451 4.3.0 cannot lookup name: %s\r\n", name); ! else ! printf("550 5.1.1 unknown name: %s\r\n", name); ! } ! else ! { ! char *errcode = NULL; ! ! if (ExitVal == EX_TEMPFAIL) ! errcode = "451 4.3.0"; ! else ! errcode = "550 5.1.1"; ! mailerr(errcode, "unknown name: %s", name); ! } ! return; ! } ! endpwent(); /* ** Keep name reasonably short to avoid buffer overruns. --- 903,932 ---- ** handled in the sendmail aliases file. */ if ((pw = getpwnam(name)) == NULL) ! if ((pw = get_mysql_pwd(name)) == NULL) ! { ! if (ExitVal != EX_TEMPFAIL) ! ExitVal = EX_UNAVAILABLE; ! if (LMTPMode) ! { ! if (ExitVal == EX_TEMPFAIL) ! printf("451 4.3.0 cannot lookup name: %s\r\n", name); ! else ! printf("550 5.1.1 unknown name: %s\r\n", name); ! } ! else ! { ! char *errcode = NULL; ! ! if (ExitVal == EX_TEMPFAIL) ! errcode = "451 4.3.0"; ! else ! errcode = "550 5.1.1"; ! mailerr(errcode, "unknown name: %s", name); ! } ! return; ! } ! endpwent(); /* ** Keep name reasonably short to avoid buffer overruns. *** sendmail-8.10.0.Beta12/mail.local/mysql_sendmail.c Mon Apr 3 16:20:48 2000 --- sendmail-devel/mail.local/mysql_sendmail.c Mon Apr 3 15:11:07 2000 *************** *** 0 **** --- 1,184 ---- + #include + #include + #include + #include + #include + + #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 *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], + lhs[BUF_SIZE],rhs[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; + mss.mysql_rhs_col = NULL; + mss.mysql_lhs_col = 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; + #ifdef MYSQL_MAP + case 'R': + if(!strcmp(name, "MysqlRHSColumn")) { + strncpy(rhs, value, BUF_SIZE); + mss.mysql_rhs_col = rhs; + } + break; + case 'L': + if(!strcmp(name, "MysqlLHSColumn")) { + strncpy(lhs, value, BUF_SIZE); + mss.mysql_lhs_col = lhs; + } + break; + #endif + } + } + fclose(conf); + if(mss.mysql_host && mss.mysql_user && /* mss.mysql_passwd && */ + mss.mysql_database && mss.mysql_user_table && + #ifdef MYSQL_MAP + mss.mysql_lhs_col && mss.mysql_rhs_col && + #endif + 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); + mysqlconf = get_mysql_conf(); + if(mysqlconf == NULL) + { + return NULL; + } + if(!mysql_real_connect(&mysql,mysqlconf->mysql_host,mysqlconf->mysql_user,mysqlconf->mysql_passwd,mysqlconf->mysql_database,0,NULL,0)) + { + mysql_close(&mysql); + return NULL; + } + snprintf(queryBuf, sizeof(queryBuf), "select * from %s where username = \'%s\'",mysqlconf->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) + { + return NULL; + } + num_rows=mysql_num_rows(result); + num_fields=mysql_num_fields(result); + if(num_rows == 0) + { + mysql_free_result(result); + mysql_close(&mysql); + return NULL; + } + + field=mysql_fetch_row(result); + + 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; + } + *** sendmail-8.10.0.Beta12/mail.local/mysql_sendmail.h Mon Apr 3 16:20:48 2000 --- sendmail-devel/mail.local/mysql_sendmail.h Mon Apr 3 15:07:07 2000 *************** *** 0 **** --- 1,28 ---- + #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; + char *mysql_lhs_col; + char *mysql_rhs_col; + }; + + 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; + MYSQL_MAP_STRUCT *mysql_map_scanconf(); + + #define EX_NOTFOUND EX_NOHOST + #define ALIAS_LHS "address" + #define ALIAS_RHS "alias"