/* * vsybase.c * part of the vpopmail package * * Copyright (C) 1999,2001 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 #include #include #include #include #include #include #include #include #include "config.h" #include "vpopmail.h" #include "vauth.h" #include "vsybase.h" static int is_open = 0; static LOGINREC *login; static DBPROCESS *dbproc; #define SQL_BUF_SIZE 600 static char SqlBuf[SQL_BUF_SIZE]; static char SqlBuf1[SQL_BUF_SIZE]; #define SMALL_BUFF 200 char IUser[SMALL_BUFF]; char IPass[SMALL_BUFF]; char IGecos[SMALL_BUFF]; char IDir[SMALL_BUFF]; char IShell[SMALL_BUFF]; void vcreate_relay_table(); int err_handler(dbproc, severity, dberr, oserr, dberrstr, oserrstr) DBPROCESS *dbproc; int severity; int dberr; int oserr; char *dberrstr; char *oserrstr; { if ((dbproc == NULL) || (DBDEAD(dbproc))) { return(INT_EXIT); } else { return(INT_CANCEL); } } int msg_handler(dbproc, msgno, msgstate, severity, msgtext, srvname, procname, line) DBPROCESS *dbproc; DBINT msgno; int msgstate; int severity; char *msgtext; char *srvname; char *procname; DBUSMALLINT line; { return(0); } int vauth_open() { if ( is_open == 1 ) return(0); is_open = 1; if ( dbinit() == FAIL ) return(-1); dberrhandle(err_handler); dbmsghandle(msg_handler); login=dblogin(); DBSETLUSER(login, SYBASE_USER); DBSETLPWD(login, SYBASE_PASSWD); DBSETLAPP(login, SYBASE_APP); dbproc = dbopen(login,SYBASE_SERVER); if ( dbuse(dbproc, SYBASE_DATABASE) == FAIL ) { dbcancel(dbproc); sprintf( SqlBuf, "create database %s", SYBASE_DATABASE ); dbcmd(dbproc, SqlBuf); dbsqlexec(dbproc); while(dbresults(dbproc) != NO_MORE_RESULTS) continue; dbuse(dbproc, SYBASE_DATABASE); } return(0); } int vauth_adddomain( char *domain ) { return(vauth_adddomain_size( domain, SITE_SIZE )); } int vauth_adddomain_size( char *domain, int site_size ) { char *tmpstr = NULL; vauth_open(); vset_default_domain( domain ); if ( site_size == LARGE_SITE ) { tmpstr = vauth_munch_domain( domain ); sprintf( SqlBuf1, "create table %s ( %s )", tmpstr, LARGE_TABLE_LAYOUT ); } else { sprintf( SqlBuf1, "create table %s ( %s )", SYBASE_DEFAULT_TABLE, SMALL_TABLE_LAYOUT); } dbcmd(dbproc, SqlBuf1); dbsqlexec(dbproc); while(dbresults(dbproc) != NO_MORE_RESULTS) continue; return(0); } int vauth_adduser(char *user, char *domain, char *pass, char *gecos, char *dir, int apop ) { return(vauth_adduser_size(user, domain, pass, gecos, dir, apop, SITE_SIZE )); } int vauth_adduser_size(char *user, char *domain, char *pass, char *gecos, char *dir, int apop, int site_size ) { char *domstr; int pop; char dom_dir[156]; int uid, gid; char dirbuf[200]; char quota[30]; vauth_open(); vset_default_domain( domain ); #ifdef HARD_QUOTA sprintf( quota, "%d", HARD_QUOTA ); #else strncpy( quota, "NOQUOTA", 30 ); #endif if ( apop == 0 ) { pop = 1; } else { pop = 2; } domstr = vauth_munch_domain( domain ); if ( site_size == LARGE_SITE && (domain == NULL || domain[0] == 0) ) { domstr = SYBASE_LARGE_USERS_TABLE; } if ( strlen(domain) <= 0 ) { if ( strlen(dir) > 0 ) { sprintf(dirbuf, "%s/users/%s/%s", VPOPMAILDIR, dir, user); } else { sprintf(dirbuf, "%s/users/%s", VPOPMAILDIR, user); } } else { vget_assign(domain, dom_dir, 156, &uid, &gid ); if ( strlen(dir) > 0 ) { sprintf(dirbuf,"%s/%s/%s", dom_dir,dir,user); } else { sprintf(dirbuf, "%s/%s", dom_dir, user); } } if ( site_size == LARGE_SITE ) { sprintf( SqlBuf, LARGE_INSERT, domstr, user, pass, pop, gecos, dirbuf, quota); } else { sprintf( SqlBuf, SMALL_INSERT, SYBASE_DEFAULT_TABLE, user, domain, pass, pop, gecos, dirbuf, quota); } dbcmd(dbproc, SqlBuf); if ( dbsqlexec(dbproc) == FAIL || dbresults(dbproc)== FAIL ) { if ( site_size == LARGE_SITE ) { vauth_adddomain_size( SYBASE_LARGE_USERS_TABLE, LARGE_SITE ); dbcmd(dbproc, SqlBuf); if ( dbsqlexec(dbproc)==FAIL || dbresults(dbproc)== FAIL ) { fprintf(stderr, "sybase adduser failed\n"); return(-1); } dbcancel(dbproc); } else { fprintf(stderr, "sybase adduser failed\n"); return(-1); } } dbcancel(dbproc); return(0); } struct vqpasswd *vauth_getpw(char *user, char *domain) { return(vauth_getpw_size( user, domain, SITE_SIZE )); } struct vqpasswd *vauth_getpw_size(char *user, char *domain, int site_size) { char *in_domain; char *domstr; int mem_size; static struct vqpasswd pwent; lowerit(user); lowerit(domain); mem_size = strlen(domain)+1; in_domain = calloc(mem_size, sizeof(char)); strncpy(in_domain, domain, mem_size); vauth_open(); vset_default_domain( in_domain ); domstr = vauth_munch_domain( in_domain ); if ( domstr == NULL || domstr[0] == 0 ) { domstr = SYBASE_LARGE_USERS_TABLE; } if ( site_size == LARGE_SITE ) { sprintf(SqlBuf, LARGE_SELECT, domstr, user); } else { sprintf(SqlBuf, SMALL_SELECT, SYBASE_DEFAULT_TABLE, user, in_domain); } free(in_domain); dbcmd(dbproc, SqlBuf); if ( dbsqlexec(dbproc) == FAIL || dbresults(dbproc)== FAIL ) { printf("vsql_getpw: failed select\n"); return(NULL); } pwent.pw_name = IUser; pwent.pw_passwd = IPass; pwent.pw_gecos = IGecos; pwent.pw_dir = IDir; pwent.pw_shell = IShell; dbbind(dbproc, 1, NTBSTRINGBIND, (DBINT)0, (BYTE *)pwent.pw_name); dbbind(dbproc, 2, NTBSTRINGBIND, (DBINT)0, (BYTE *)pwent.pw_passwd); dbbind(dbproc, 3, INTBIND, (DBINT)0, (BYTE *)&pwent.pw_uid); dbbind(dbproc, 4, INTBIND, (DBINT)0, (BYTE *)&pwent.pw_gid); dbbind(dbproc, 5, NTBSTRINGBIND, (DBINT)0, (BYTE *)pwent.pw_gecos); dbbind(dbproc, 6, NTBSTRINGBIND, (DBINT)0, (BYTE *)pwent.pw_dir); dbbind(dbproc, 7, NTBSTRINGBIND, (DBINT)0, (BYTE *)pwent.pw_shell); mem_size = 0; while( dbnextrow(dbproc) != NO_MORE_ROWS ) { ++mem_size; } dbcancel(dbproc); if ( mem_size == 0 ) return(NULL); return(&pwent); } int vauth_deldomain( char *domain ) { return(vauth_deldomain_size( domain, SITE_SIZE )); } int vauth_deldomain_size( char *domain, int site_size ) { char *tmpstr; vauth_open(); vset_default_domain( domain ); tmpstr = vauth_munch_domain( domain ); if ( site_size == LARGE_SITE ) { sprintf( SqlBuf, "drop table %s", tmpstr); } else { sprintf( SqlBuf, "delete from %s where pw_domain = '%s'", SYBASE_DEFAULT_TABLE, domain ); } dbcmd(dbproc, SqlBuf); if ( dbsqlexec(dbproc) == FAIL || dbresults(dbproc)== FAIL ) { return(-1); } dbcancel(dbproc); return(0); } int vauth_deluser( char *user, char *domain ) { return(vauth_deluser_size( user, domain, SITE_SIZE)); } int vauth_deluser_size( char *user, char *domain, int site_size ) { char *tmpstr; vauth_open(); vset_default_domain( domain ); if ( site_size == LARGE_SITE ) { if ( domain == NULL || domain[0] == 0 ) { tmpstr = SYBASE_LARGE_USERS_TABLE; } else { tmpstr = vauth_munch_domain( domain ); } sprintf( SqlBuf, "delete from %s where pw_name = '%s'", tmpstr, user ); } else { sprintf( SqlBuf, "delete from %s where pw_name = '%s' and pw_domain = '%s'", SYBASE_DEFAULT_TABLE, user, domain ); } dbcmd(dbproc, SqlBuf); if ( dbsqlexec(dbproc) == FAIL || dbresults(dbproc)== FAIL ) { fprintf(stderr, "sybase query\n"); return(-1); } dbcancel(dbproc); return(0); } int vauth_setquota( char *user, char *domain, char *quota) { return(vauth_setquota_size( user, domain, quota, SITE_SIZE)); } int vauth_setquota_size( char *user, char *domain, char *quota, int site_size) { char *tmpstr; vauth_open(); vset_default_domain( domain ); if ( site_size == LARGE_SITE ) { tmpstr = vauth_munch_domain( domain ); sprintf( SqlBuf, "update %s set pw_shell = '%s' where pw_name = '%s'", tmpstr, quota, user ); } else { sprintf( SqlBuf, "update %s set pw_shell = '%s' where pw_name = '%s' and pw_domain = '%s'", SYBASE_DEFAULT_TABLE, quota, user, domain ); } dbcmd(dbproc, SqlBuf); if ( dbsqlexec(dbproc) == FAIL || dbresults(dbproc)== FAIL ) { fprintf(stderr, "sybase query\n"); return(-1); } dbcancel(dbproc); return(0); } int vauth_vpasswd( char *user, char *domain, char *pass, int apop ) { return(vauth_vpasswd_size( user, domain, pass, apop, SITE_SIZE )); } int vauth_vpasswd_size( char *user, char *domain, char *pass, int apop, int site_size ) { char *tmpstr; uid_t uid; gid_t gid; uid_t myuid; myuid = geteuid(); vget_assign(domain,NULL,156,&uid,&gid); if (myuid != 0 && myuid != uid ) { return(VA_BAD_UID); } vauth_open(); vset_default_domain( domain ); if ( site_size == LARGE_SITE ) { tmpstr = vauth_munch_domain( domain ); sprintf( SqlBuf, "update %s set pw_passwd = '%s' where pw_name = '%s'", tmpstr, pass, user ); } else { sprintf( SqlBuf, "update %s set pw_passwd = '%s' where pw_name = '%s' and pw_domain = '%s'", SYBASE_DEFAULT_TABLE, pass, user, domain ); } dbcmd(dbproc, SqlBuf); if ( dbsqlexec(dbproc) == FAIL || dbresults(dbproc)== FAIL ) { fprintf(stderr, "sybase query\n"); return(-1); } dbcancel(dbproc); return(0); } void vauth_end_getall() { } struct vqpasswd *vauth_getall(char *domain, int first, int sortit) { return(vauth_getall_size(domain, first, sortit, SITE_SIZE)); } struct vqpasswd *vauth_getall_size(char *domain, int first, int sortit, int site_size) { char *domstr = NULL; static struct vqpasswd pwent; static int more = 0; vset_default_domain( domain ); if ( site_size == LARGE_SITE ) { domstr = vauth_munch_domain( domain ); } if ( first == 1 ) { vauth_open(); if ( site_size == LARGE_SITE ) { sprintf(SqlBuf, LARGE_GETALL, domstr); } else { sprintf(SqlBuf, SMALL_GETALL, SYBASE_DEFAULT_TABLE, domain); } if ( sortit == 1 ) { strcat( SqlBuf, " order by pw_name"); } dbcmd(dbproc, SqlBuf); if ( dbsqlexec(dbproc) == FAIL || dbresults(dbproc)== FAIL ) { printf("vsql_getpw: failed select\n"); return(NULL); } } else if ( more == 0 ) { return(NULL); } pwent.pw_name = IUser; pwent.pw_passwd = IPass; pwent.pw_gecos = IGecos; pwent.pw_dir = IDir; pwent.pw_shell = IShell; if ( dbnextrow(dbproc) != NO_MORE_ROWS ) { strncpy(pwent.pw_name,(char *)dbretdata(dbproc,1),SMALL_BUFF); strncpy(pwent.pw_passwd,(char *)dbretdata(dbproc,2),SMALL_BUFF); pwent.pw_uid = atoi(dbretdata(dbproc,3)); pwent.pw_gid = atoi(dbretdata(dbproc,4)); strncpy(pwent.pw_gecos,dbretdata(dbproc,5),SMALL_BUFF); strncpy(pwent.pw_dir,dbretdata(dbproc,6),SMALL_BUFF); strncpy(pwent.pw_shell, dbretdata(dbproc,7),SMALL_BUFF); more = 1; return(&pwent); } more = 0; dbcancel(dbproc); return(NULL); } char *vauth_munch_domain( char *domain ) { int i; static char tmpbuf[50]; if ( domain == NULL || domain[0] == 0 ) return(domain); for(i=0;domain[i]!=0;++i){ tmpbuf[i] = domain[i]; if ( domain[i] == '.' || domain[i] == '-' ) { tmpbuf[i] = SYBASE_DOT_CHAR; } } tmpbuf[i] = 0; return(tmpbuf); } int vauth_setpw( struct vqpasswd *inpw, char *domain ) { return(vauth_setpw_size( inpw, domain, SITE_SIZE)); } int vauth_setpw_size( struct vqpasswd *inpw, char *domain, int site_size) { char *tmpstr; uid_t myuid; uid_t uid; gid_t gid; myuid = geteuid(); if ( myuid != VPOPMAIL && myuid != 0 ) return(VA_BAD_UID); vauth_open(); vset_default_domain( domain ); if ( site_size == LARGE_SITE ) { tmpstr = vauth_munch_domain( domain ); sprintf( SqlBuf, LARGE_SETPW, tmpstr, inpw->pw_passwd, inpw->pw_uid, inpw->pw_gid, inpw->pw_gecos, inpw->pw_dir, inpw->pw_shell, inpw->pw_name ); } else { sprintf( SqlBuf, SMALL_SETPW, SYBASE_DEFAULT_TABLE, inpw->pw_passwd, inpw->pw_uid, inpw->pw_gid, inpw->pw_gecos, inpw->pw_dir, inpw->pw_shell, inpw->pw_name, domain); } dbcmd(dbproc, SqlBuf); if ( dbsqlexec(dbproc) == FAIL || dbresults(dbproc)== FAIL ) { fprintf(stderr, "sybase query\n"); return(-1); } dbcancel(dbproc); #ifdef SQWEBMAIL_PASS tmpstr = vget_assign(domain, NULL, 156, &uid, &gid ); vsqwebmail_pass( inpw->pw_dir, inpw->pw_passwd, uid, gid); #endif return(0); } void vclear_open_smtp(time_t clear_minutes, time_t mytime) { /* time_t delete_time; int err; if ( (err=vauth_open()) != 0 ) exit(0); delete_time = mytime - clear_minutes; sprintf( SqlBuf, "delete from relay where timestamp <= %d", (int)delete_time); if (mysql_query(&mysql,SqlBuf)) { vcreate_relay_table(); return; } */ } int vmkpasswd( char *domain ) { return(0); } void vclose() { if ( is_open == 1 ) { is_open = 0; dbclose(proc); } } #ifdef IP_ALIAS_DOMAINS int vget_ip_map( char *ip, char *domain, int domain_size) { if ( ip == NULL || strlen(ip) <= 0 ) return(0); return(0); } int vadd_ip_map( char *ip, char *domain) { return(0); } int vdel_ip_map( char *ip, char *domain) { return(0); } int vshow_ip_map( int first, char *ip, char *domain); { return(0); } #endif