?? vmysql.c
字號:
/* * $Id: vmysql.c,v 1.15.2.2 2004/06/26 02:20:56 tomcollins Exp $ * Copyright (C) 1999-2003 Inter7 Internet Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* TODOAdd error result for "unable to read vpopmail.mysql" and return it*/ #include <pwd.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <string.h>#include <time.h>#include <mysql.h>#include "config.h"#include "vpopmail.h"#include "vauth.h"#include "vlimits.h"#include "vmysql.h"static MYSQL mysql_update;static MYSQL mysql_read_getall;#ifdef MYSQL_REPLICATIONstatic MYSQL mysql_read;#else#define mysql_read mysql_update#endifstatic int update_open = 0;static int read_getall_open = 0;#ifdef MYSQL_REPLICATIONstatic int read_open = 0;#else#define read_open update_open#endifstatic MYSQL_RES *res_update = NULL;static MYSQL_RES *res_read_getall = NULL;#ifdef MYSQL_REPLICATIONstatic MYSQL_RES *res_read = NULL;#else#define res_read res_update#endifstatic MYSQL_ROW row;static MYSQL_ROW row_getall;#define SQL_BUF_SIZE 2048static char SqlBufRead[SQL_BUF_SIZE];static char SqlBufUpdate[SQL_BUF_SIZE];#define SMALL_BUFF 200char IUser[SMALL_BUFF];char IPass[SMALL_BUFF];char IGecos[SMALL_BUFF];char IDir[SMALL_BUFF];char IShell[SMALL_BUFF];char IClearPass[SMALL_BUFF];void vcreate_dir_control(char *domain);void vcreate_vlog_table();#ifdef POP_AUTH_OPEN_RELAYvoid vcreate_relay_table();#endif#ifdef VALIASvoid vcreate_valias_table();#endif#ifdef ENABLE_AUTH_LOGGINGvoid vcreate_lastauth_table();#endif/* * get mysql connection info */int load_connection_info() { FILE *fp; char conn_info[256]; char config[256]; int eof; static int loaded = 0; char *port; char delimiters[] = "|\n"; char *conf_read, *conf_update; if (loaded) return 0; loaded = 1; sprintf(config, "%s/etc/%s", VPOPMAILDIR, "vpopmail.mysql"); fp = fopen(config, "r"); if (fp == NULL) { fprintf(stderr, "vmysql: can't read settings from %s\n", config); return(VA_NO_AUTH_CONNECTION); } /* skip comments and blank lines */ do { eof = (fgets (conn_info, sizeof(conn_info), fp) == NULL); } while (!eof && ((*conn_info == '#') || (*conn_info == '\n'))); if (eof) { /* no valid data read, return error */ fprintf(stderr, "vmysql: no valid settings in %s\n", config); return(VA_NO_AUTH_CONNECTION); } conf_read = strdup(conn_info); MYSQL_READ_SERVER = strtok(conf_read, delimiters); if (MYSQL_READ_SERVER == NULL) return VA_PARSE_ERROR; port = strtok(NULL, delimiters); if (port == NULL) return VA_PARSE_ERROR; MYSQL_READ_PORT = atoi(port); MYSQL_READ_USER = strtok(NULL, delimiters); if (MYSQL_READ_USER == NULL) return VA_PARSE_ERROR; MYSQL_READ_PASSWD = strtok(NULL, delimiters); if (MYSQL_READ_PASSWD == NULL) return VA_PARSE_ERROR; MYSQL_READ_DATABASE = strtok(NULL, delimiters); if (MYSQL_READ_DATABASE == NULL) return VA_PARSE_ERROR; /* skip comments and blank lines */ do { eof = (fgets (conn_info, sizeof(conn_info), fp) == NULL); } while (!eof && ((*conn_info == '#') || (*conn_info == '\n'))); if (eof) { /* re-use read-only settings for update */ MYSQL_UPDATE_SERVER = MYSQL_READ_SERVER; MYSQL_UPDATE_PORT = MYSQL_READ_PORT; MYSQL_UPDATE_USER = MYSQL_READ_USER; MYSQL_UPDATE_PASSWD = MYSQL_READ_PASSWD; MYSQL_UPDATE_DATABASE = MYSQL_READ_DATABASE; } else { conf_update = strdup(conn_info); MYSQL_UPDATE_SERVER = strtok(conf_update, delimiters); if (MYSQL_UPDATE_SERVER == NULL) return VA_PARSE_ERROR; port = strtok(NULL, delimiters); if (port == NULL) return VA_PARSE_ERROR; MYSQL_UPDATE_PORT = atoi(port); MYSQL_UPDATE_USER = strtok(NULL, delimiters); if (MYSQL_UPDATE_USER == NULL) return VA_PARSE_ERROR; MYSQL_UPDATE_PASSWD = strtok(NULL, delimiters); if (MYSQL_UPDATE_PASSWD == NULL) return VA_PARSE_ERROR; MYSQL_UPDATE_DATABASE = strtok(NULL, delimiters); if (MYSQL_UPDATE_DATABASE == NULL) return VA_PARSE_ERROR; }/* useful debugging info fprintf(stderr, "read settings: server:%s port:%d user:%s pw:%s db:%s\n", MYSQL_READ_SERVER, MYSQL_READ_PORT, MYSQL_READ_USER, MYSQL_READ_PASSWD, MYSQL_READ_DATABASE); fprintf(stderr, "update settings: server:%s port:%d user:%s pw:%s db:%s\n", MYSQL_UPDATE_SERVER, MYSQL_UPDATE_PORT, MYSQL_UPDATE_USER, MYSQL_UPDATE_PASSWD, MYSQL_UPDATE_DATABASE); */ return 0;}/* * Open a connection to mysql for updates */int vauth_open_update(){ unsigned int timeout = 2; if ( update_open != 0 ) return(0); update_open = 1; verrori = load_connection_info(); if (verrori) return -1; mysql_init(&mysql_update); mysql_options(&mysql_update, MYSQL_OPT_CONNECT_TIMEOUT, (char *)&timeout); /* Try to connect to the mysql update server */ if (!(mysql_real_connect(&mysql_update, MYSQL_UPDATE_SERVER, MYSQL_UPDATE_USER, MYSQL_UPDATE_PASSWD, NULL, MYSQL_UPDATE_PORT, NULL, 0))) { /* if we can not connect, report a error and return */ verrori = VA_NO_AUTH_CONNECTION; return(VA_NO_AUTH_CONNECTION); } /* set the database we use */ if (mysql_select_db(&mysql_update, MYSQL_UPDATE_DATABASE)) { /* we were able to connect, so create the database */ snprintf( SqlBufUpdate, SQL_BUF_SIZE, "create database %s", MYSQL_UPDATE_DATABASE ); if (mysql_query(&mysql_update,SqlBufUpdate)) { /* we could not create the database * so report the error and return */ fprintf(stderr, "vmysql: couldn't create database '%s': %s\n", MYSQL_UPDATE_DATABASE, mysql_error(&mysql_update)); return(-1); } /* set the database (we just created)*/ if (mysql_select_db(&mysql_update, MYSQL_UPDATE_DATABASE)) { fprintf(stderr, "could not enter (just created) %s database\n", MYSQL_UPDATE_DATABASE); return(-1); } } return(0);}#ifdef MYSQL_REPLICATION/* * Open a connection to the database for read-only queries */int vauth_open_read(){ /* if we are already connected, just return */ if ( read_open != 0 ) return(0); read_open = 1; /* connect to mysql and set the database */ verrori = load_connection_info(); if (verrori) return -1; mysql_init(&mysql_read); if (!(mysql_real_connect(&mysql_read, MYSQL_READ_SERVER, MYSQL_READ_USER, MYSQL_READ_PASSWD, MYSQL_READ_DATABASE, MYSQL_READ_PORT, NULL, 0))) { /* we could not connect, at least try the update server */ if (!(mysql_real_connect(&mysql_read, MYSQL_UPDATE_SERVER, MYSQL_UPDATE_USER, MYSQL_UPDATE_PASSWD, MYSQL_UPDATE_DATABASE, MYSQL_READ_PORT, NULL, 0))) { verrori = VA_NO_AUTH_CONNECTION; return( VA_NO_AUTH_CONNECTION ); } } /* return success */ return(0);}#else#define vauth_open_read vauth_open_update#endif/* * Open a connection to the database for read-only queries */int vauth_open_read_getall(){ /* if we are already connected, just return */ if ( read_getall_open != 0 ) return(0); read_getall_open = 1; /* connect to mysql and set the database */ verrori = load_connection_info(); if (verrori) return -1; mysql_init(&mysql_read_getall); if (!(mysql_real_connect(&mysql_read_getall, MYSQL_READ_SERVER, MYSQL_READ_USER, MYSQL_READ_PASSWD, MYSQL_READ_DATABASE, MYSQL_READ_PORT, NULL, 0))) { /* we could not connect, at least try the update server */ if (!(mysql_real_connect(&mysql_read_getall, MYSQL_UPDATE_SERVER, MYSQL_UPDATE_USER, MYSQL_UPDATE_PASSWD, MYSQL_UPDATE_DATABASE, MYSQL_UPDATE_PORT, NULL, 0))) { verrori = VA_NO_AUTH_CONNECTION; return(-1); } return(-1); } /* return success */ return(0);}int vauth_create_table (char *table, char *layout, int showerror){ int err; char SqlBufCreate[SQL_BUF_SIZE]; if ((err = vauth_open_update()) != 0) return (err); snprintf (SqlBufCreate, SQL_BUF_SIZE, "CREATE TABLE %s ( %s )", table, layout); if (mysql_query (&mysql_update, SqlBufCreate)) { if (showerror) fprintf (stderr, "vmysql: error creating table '%s': %s\n", table, mysql_error(&mysql_update)); return -1; } else { return 0; }} int vauth_adddomain( char *domain ){#ifndef MANY_DOMAINS vset_default_domain( domain ); return (vauth_create_table (vauth_munch_domain( domain ), TABLE_LAYOUT, 1));#else /* if creation fails, don't show an error */ vauth_create_table (MYSQL_DEFAULT_TABLE, TABLE_LAYOUT, 0); return (0);#endif}int vauth_adduser(char *user, char *domain, char *pass, char *gecos, char *dir, int apop ){ char *domstr; char dom_dir[156]; uid_t uid; gid_t gid; char dirbuf[200]; char quota[30]; char Crypted[100]; int err; if ( (err=vauth_open_update()) != 0 ) return(err); vset_default_domain( domain ); strncpy( quota, "NOQUOTA", 30 );#ifndef MANY_DOMAINS domstr = vauth_munch_domain( domain );#else domstr = MYSQL_DEFAULT_TABLE;#endif if ( domain == NULL || domain[0] == 0 ) { domstr = MYSQL_LARGE_USERS_TABLE; } if ( strlen(domain) <= 0 ) { if ( strlen(dir) > 0 ) { snprintf(dirbuf, SQL_BUF_SIZE, "%s/users/%s/%s", VPOPMAILDIR, dir, user); } else { snprintf(dirbuf, SQL_BUF_SIZE, "%s/users/%s", VPOPMAILDIR, user); } } else { vget_assign(domain, dom_dir, 156, &uid, &gid ); if ( strlen(dir) > 0 ) { snprintf(dirbuf,SQL_BUF_SIZE, "%s/%s/%s", dom_dir, dir, user); } else { snprintf(dirbuf, SQL_BUF_SIZE, "%s/%s", dom_dir, user); } } if ( pass[0] != 0 ) { mkpasswd3(pass,Crypted, 100); } else { Crypted[0] = 0; } qnprintf( SqlBufUpdate, SQL_BUF_SIZE, INSERT, domstr, user, #ifdef MANY_DOMAINS domain,#endif Crypted, apop, gecos, dirbuf, quota#ifdef CLEAR_PASS, pass#endif); if (mysql_query(&mysql_update,SqlBufUpdate)) { fprintf(stderr, "vmysql: sql error[2]: %s\n", mysql_error(&mysql_update)); return(-1); } return(0);}struct vqpasswd *vauth_getpw(char *user, char *domain){ char *domstr; static struct vqpasswd vpw; static char in_domain[156]; int err; uid_t myuid; uid_t uid; vget_assign(domain,NULL,0,&uid,&gid); myuid = geteuid(); if ( myuid != 0 && myuid != uid ) return(NULL); verrori = 0; if ( (err=vauth_open_read()) != 0 ) { verrori = err; return(NULL); } lowerit(user); lowerit(domain); snprintf (in_domain, sizeof(in_domain), "%s", domain); vset_default_domain( in_domain );#ifndef MANY_DOMAINS domstr = vauth_munch_domain( in_domain );#else domstr = MYSQL_DEFAULT_TABLE; #endif if ( domstr == NULL || domstr[0] == 0 ) domstr = MYSQL_LARGE_USERS_TABLE; qnprintf(SqlBufRead, SQL_BUF_SIZE, USER_SELECT, domstr, user#ifdef MANY_DOMAINS, in_domain#endif); if (mysql_query(&mysql_read,SqlBufRead)) { fprintf(stderr, "vmysql: sql error[3]: %s\n", mysql_error(&mysql_read)); return(NULL); } if (!(res_read = mysql_store_result(&mysql_read))) { fprintf(stderr, "vmysql: store result failed 1\n"); return(NULL); } if ( mysql_num_rows(res_read) == 0 ) { mysql_free_result(res_read); return(NULL); } memset(IUser, 0, sizeof(IUser)); memset(IPass, 0, sizeof(IPass)); memset(IGecos, 0, sizeof(IGecos)); memset(IDir, 0, sizeof(IDir)); memset(IShell, 0, sizeof(IShell)); memset(IClearPass, 0, sizeof(IClearPass)); vpw.pw_name = IUser; vpw.pw_passwd = IPass; vpw.pw_gecos = IGecos; vpw.pw_dir = IDir; vpw.pw_shell = IShell; vpw.pw_clear_passwd = IClearPass; if((row = mysql_fetch_row(res_read))) { strncpy(vpw.pw_name,row[0],SMALL_BUFF); if ( row[1] != 0 ) strncpy(vpw.pw_passwd,row[1],SMALL_BUFF); if ( row[2] != 0 ) vpw.pw_uid = atoi(row[2]); if ( row[3] != 0 ) vpw.pw_gid = atoi(row[3]); if ( row[4] != 0 ) strncpy(vpw.pw_gecos,row[4],SMALL_BUFF); if ( row[5] != 0 ) strncpy(vpw.pw_dir,row[5],SMALL_BUFF); if ( row[6] != 0 ) strncpy(vpw.pw_shell, row[6],SMALL_BUFF);#ifdef CLEAR_PASS if ( row[7] != 0 ) strncpy(vpw.pw_clear_passwd, row[7],SMALL_BUFF);#endif } else { mysql_free_result(res_read); return(NULL); } mysql_free_result(res_read); vlimits_setflags (&vpw, in_domain); return(&vpw);}/* del a domain from the auth backend * - drop the domain's table, or del all users from users table * - delete domain's entries from lastauth table * - delete domain's limit's entries */int vauth_deldomain( char *domain ){ char *tmpstr; int err; if ( (err=vauth_open_update()) != 0 ) return(err); vset_default_domain( domain );#ifndef MANY_DOMAINS /* convert the domain name to the table name (eg convert . to _ ) */ tmpstr = vauth_munch_domain( domain ); snprintf( SqlBufUpdate, SQL_BUF_SIZE, "drop table %s", tmpstr);#else tmpstr = MYSQL_DEFAULT_TABLE; qnprintf( SqlBufUpdate, SQL_BUF_SIZE, "delete from %s where pw_domain = '%s'", tmpstr, domain );#endif if (mysql_query(&mysql_update,SqlBufUpdate)) { return(-1); }
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -