?? vpgsql.c
字號:
/* * $Id: vpgsql.c,v 1.20.2.3 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 */#include <pwd.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <string.h>#include <time.h>#include <errno.h>#include <libpq-fe.h> /* required pgsql front-end headers */#include "config.h"#include "vpopmail.h"#include "vauth.h"#include "vlimits.h"#include "vpgsql.h"/* pgsql has no built-in replication, yet. #ifdef PGSQL_REPLICATION static PGconn *pgc_read; #else #define pgc_read pgc_update #endif #ifdef PGSQL_REPLICATION static int read_open = 0; #else #define read_open update_open #endif #ifdef PGSQL_REPLICATION static PGresult *res_read = NULL; #else #define res_read res_update #endif*//* read-only and read-write connections to be implemented later...static PGconn *pgc_update;static PGconn *pgc_read;static PGconn *pgc_read_getall;*/static PGconn *pgc; /* pointer to pgsql connection */static int is_open = 0;#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 VALIASPGresult *pgvalias = NULL;void vcreate_valias_table();#endif#ifdef ENABLE_AUTH_LOGGINGvoid vcreate_lastauth_table();#endif/* pgsql BEGIN TRANSACTION ********/int pg_begin(void){ PGresult *pgres; pgres=PQexec(pgc, "BEGIN"); if( !pgres || PQresultStatus(pgres)!=PGRES_COMMAND_OK ) { fprintf(stderr, "pg_begin: %s\n", PQerrorMessage(pgc)); if (pgres) PQclear (pgres); return -1; } PQclear(pgres); return 0;} /* pgsql END TRANSACTION ********/int pg_end(void){ PGresult *pgres; pgres=PQexec(pgc, "END"); if( !pgres || PQresultStatus(pgres)!=PGRES_COMMAND_OK ) { fprintf(stderr, "pg_end: %s\n", PQerrorMessage(pgc)); if (pgres) PQclear (pgres); return -1; } PQclear(pgres); return 0;} /*** Open a connection to pgsql ***/int vauth_open(){ if ( is_open != 0 ) return(0); is_open = 1; verrori = 0; /* Try to connect to the pgserver with the specified database. */ pgc = PQconnectdb(PG_CONNECT); if( PQstatus(pgc) == CONNECTION_BAD) { fprintf(stderr, "vauth_open: can't connect: %s\n", PQerrorMessage(pgc)); return VA_NO_AUTH_CONNECTION; } return(0);}int vauth_create_table (char *table, char *layout, int showerror){ int err; PGresult *pgres; char SqlBufCreate[SQL_BUF_SIZE]; if ( err = vauth_open()) return (err); snprintf(SqlBufCreate, SQL_BUF_SIZE, "CREATE TABLE %s ( %s )", table, layout); pgres=PQexec(pgc, SqlBufCreate); if (!pgres || PQresultStatus(pgres)!=PGRES_COMMAND_OK) { err = -1; if (showerror) fprintf (stderr, "vpgsql: error creating table '%s': %s\n", table, PQerrorMessage(pgc)); } else err = 0; if (pgres) PQclear (pgres); return err;}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 (PGSQL_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; PGresult *pgres; if ( (err=vauth_open()) != 0 ) return(err); vset_default_domain( domain ); strncpy( quota, "NOQUOTA", 30 );#ifndef MANY_DOMAINS domstr = vauth_munch_domain( domain );#else domstr = PGSQL_DEFAULT_TABLE;#endif if ( domain == NULL || domain[0] == 0 ) { domstr = PGSQL_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(! ( pgres=PQexec(pgc,SqlBufUpdate) )|| PQresultStatus(pgres)!=PGRES_COMMAND_OK ) { fprintf(stderr, "vauth_adduser: %s\npgsql: %s\n", SqlBufUpdate, PQerrorMessage(pgc)); } if( pgres ) PQclear(pgres); return(0);}struct vqpasswd *vauth_getpw(char *user, char *domain){ char in_domain[156]; char *domstr; static struct vqpasswd vpw; int err; PGresult *pgres; verrori = 0; if ( (err=vauth_open()) != 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 = PGSQL_DEFAULT_TABLE; #endif if ( domstr == NULL || domstr[0] == 0 ) { domstr = PGSQL_LARGE_USERS_TABLE; } qnprintf(SqlBufRead, SQL_BUF_SIZE, USER_SELECT, domstr, user#ifdef MANY_DOMAINS ,in_domain#endif ); pgres=PQexec(pgc, SqlBufRead); if ( ! pgres || PQresultStatus(pgres)!=PGRES_TUPLES_OK) {#ifdef DEBUG fprintf(stderr, "vauth_getpw: failed select: %s : %s\n", SqlBufRead, PQerrorMessage(pgc));#endif if( pgres ) PQclear(pgres); return NULL; } if ( PQntuples(pgres) <= 0 ) { /* rows count */ PQclear(pgres); 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; strncpy(vpw.pw_name,PQgetvalue( pgres, 0, 0 ),SMALL_BUFF); strncpy(vpw.pw_passwd,PQgetvalue( pgres, 0, 1 ),SMALL_BUFF); vpw.pw_uid = atoi(PQgetvalue( pgres, 0, 2 )); vpw.pw_gid = atoi(PQgetvalue( pgres, 0, 3 )); strncpy(vpw.pw_gecos,PQgetvalue( pgres, 0, 4 ),SMALL_BUFF); strncpy(vpw.pw_dir,PQgetvalue( pgres, 0, 5 ),SMALL_BUFF); strncpy(vpw.pw_shell, PQgetvalue( pgres, 0, 6 ),SMALL_BUFF);#ifdef CLEAR_PASS if ( PQgetvalue( pgres, 0, 7 ) != 0 ) strncpy(vpw.pw_clear_passwd, PQgetvalue( pgres, 0, 7 ),SMALL_BUFF);#endif vlimits_setflags (&vpw, in_domain); return(&vpw);}int vauth_deldomain( char *domain ){ PGresult *pgres; char *tmpstr; int err; if ( (err=vauth_open()) != 0 ) return(err); vset_default_domain( domain );#ifndef MANY_DOMAINS tmpstr = vauth_munch_domain( domain ); snprintf( SqlBufUpdate, SQL_BUF_SIZE, "drop table %s", tmpstr);#else tmpstr = PGSQL_DEFAULT_TABLE; qnprintf(SqlBufUpdate,SQL_BUF_SIZE, "delete from %s where pw_domain = '%s'", tmpstr, domain );#endif pgres=PQexec(pgc, SqlBufUpdate); if( !pgres || PQresultStatus(pgres)!=PGRES_COMMAND_OK){ fprintf(stderr,"vauth_deldomain: pgsql query: %s", PQerrorMessage(pgc)); if(pgres) PQclear(pgres); return(-1); } if(pgres) PQclear(pgres);#ifdef VALIAS valias_delete_domain( domain);#endif#ifdef ENABLE_AUTH_LOGGING qnprintf( SqlBufUpdate, SQL_BUF_SIZE, "delete from lastauth where domain = '%s'", domain ); pgres=PQexec(pgc, SqlBufUpdate); if( !pgres || PQresultStatus(pgres)!=PGRES_COMMAND_OK) { return(-1); } if(pgres) PQclear(pgres);#endif return(0);}int vauth_deluser( char *user, char *domain ){ PGresult *pgres; char *tmpstr; int err = 0; if ( (err=vauth_open()) != 0 ) return(err); vset_default_domain( domain );#ifndef MANY_DOMAINS if ( domain == NULL || domain[0] == 0 ) { tmpstr = PGSQL_LARGE_USERS_TABLE; } else { tmpstr = vauth_munch_domain( domain ); }#else tmpstr = PGSQL_DEFAULT_TABLE;#endif qnprintf( SqlBufUpdate, SQL_BUF_SIZE, DELETE_USER, tmpstr, user#ifdef MANY_DOMAINS , domain#endif ); pgres=PQexec(pgc, SqlBufUpdate); if( !pgres || PQresultStatus(pgres)!=PGRES_COMMAND_OK ) { err = -1; } if( pgres ) PQclear(pgres);#ifdef ENABLE_AUTH_LOGGING qnprintf( SqlBufUpdate, SQL_BUF_SIZE, "delete from lastauth where user = '%s' and domain = '%s'", user, domain ); pgres=PQexec(pgc, SqlBufUpdate); if( !pgres || PQresultStatus(pgres)!=PGRES_COMMAND_OK ) { err = -1; } if( pgres ) PQclear(pgres);#endif return(err);}int vauth_setquota( char *username, char *domain, char *quota){ PGresult *pgres; char *tmpstr; int err; if ( strlen(username) > MAX_PW_NAME ) return(VA_USER_NAME_TOO_LONG);#ifdef USERS_BIG_DIR if ( strlen(username) == 1 ) return(VA_ILLEGAL_USERNAME);#endif if ( strlen(domain) > MAX_PW_DOMAIN ) return(VA_DOMAIN_NAME_TOO_LONG); if ( strlen(quota) > MAX_PW_QUOTA ) return(VA_QUOTA_TOO_LONG); if ( (err=vauth_open()) != 0 ) return(err); vset_default_domain( domain );#ifndef MANY_DOMAINS tmpstr = vauth_munch_domain( domain );#else tmpstr = PGSQL_DEFAULT_TABLE; #endif qnprintf( SqlBufUpdate, SQL_BUF_SIZE, SETQUOTA, tmpstr, quota, username#ifdef MANY_DOMAINS , domain#endif ); pgres = PQexec(pgc, SqlBufUpdate); if( !pgres || PQresultStatus(pgres)!=PGRES_COMMAND_OK ) { fprintf(stderr, "vauth_setquota: query failed: %s\n", PQerrorMessage(pgc)); if( pgres ) PQclear(pgres); return(-1); } if( pgres ) PQclear(pgres); return(0);}struct vqpasswd *vauth_getall(char *domain, int first, int sortit){ static PGresult *pgres=NULL; /* ntuples - number of tuples ctuple - current tuple */ static unsigned ntuples=0, ctuple=0; char *domstr = NULL; static struct vqpasswd vpw; int err; vset_default_domain( domain );#ifdef MANY_DOMAINS domstr = PGSQL_DEFAULT_TABLE; #else domstr = vauth_munch_domain( domain );#endif if ( first == 1 ) { if ( (err=vauth_open()) != 0 ) return(NULL); qnprintf(SqlBufRead, SQL_BUF_SIZE, GETALL, domstr#ifdef MANY_DOMAINS ,domain#endif ); if ( sortit == 1 ) { strncat( SqlBufRead, " order by pw_name", SQL_BUF_SIZE); } if ( pgres ) { /* reset state if we had previous result */ PQclear(pgres); // clear previous result pgres=NULL; ntuples=ctuple=0; } pgres = PQexec(pgc, SqlBufRead); if( !pgres || PQresultStatus(pgres) != PGRES_TUPLES_OK ) { fprintf(stderr, "vauth_getall:query failed[5]: %s\n", PQerrorMessage(pgc)); if( pgres ) { PQclear(pgres); pgres=NULL; } return (NULL); } ntuples = PQntuples( pgres ); } if ( ctuple == ntuples ) { PQclear(pgres); pgres=NULL; ctuple=ntuples=0; return NULL; }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -