⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vcdb.c

📁 相当优秀的 UNIX 进程管理工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: vcdb.c,v 1.12 2004/01/07 16:06:16 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 *//********************************************************************************** $Id: vcdb.c,v 1.12 2004/01/07 16:06:16 tomcollins Exp $** Change a domain's password file to a CDB database**** Chris Johnson, July 1998********************************************************************************/#include <stdio.h>#include <stdlib.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <string.h>#include <pwd.h>#include <sys/time.h>#include <time.h>#include <utime.h>#include <sys/types.h>#include <cdbmake.h>#include "config.h"#include "vpopmail.h"#include "vauth.h"#include "vcdb.h"#include "file_lock.h"#include "vlimits.h"#define TOKENS " \n"char *dc_filename(char *domain, uid_t uid, gid_t gid);void vcdb_strip_char( char *instr );extern int cdb_seek();#define MAX_BUFF 300static char vpasswd_file[MAX_BUFF];static char vpasswd_bak_file[MAX_BUFF];static char vpasswd_cdb_file[MAX_BUFF];static char vpasswd_cdb_tmp_file[MAX_BUFF];static char vpasswd_lock_file[MAX_BUFF];static char vpasswd_dir[MAX_BUFF];static char TmpBuf1[MAX_BUFF];int make_vpasswd_cdb(char *domain){ char pwline[256]; char packbuf[8]; char *key; char *data; char *ptr; int i,j,h; int len; long unsigned keylen,datalen; uint32 pos,op; struct cdbmake cdbm; FILE *pwfile, *tmfile; char Dir[156]; uid_t uid; gid_t gid; char *tmpstr; mode_t oldmask;    /* If we don't optimize the index this time, just return */    if ( NoMakeIndex == 1 ) return(0);    if ((pwfile = fopen(vpasswd_file,"r")) == NULL) {        return(-1);    }    cdbmake_init(&cdbm);    /* temporarily set umask (no group/other access) and open temp file */    oldmask = umask(VPOPMAIL_UMASK);    tmfile = fopen(vpasswd_cdb_tmp_file,"w");    umask(oldmask);    if (tmfile == NULL) {        fprintf(stderr,"Error: could not create/open temporary file\n");        return(-1);    }    for (i=0; i < sizeof(cdbm.final); i++) {        if (putc(' ',tmfile) == EOF) {                fprintf(stderr,"Error:error writing temp file\n");            return(-1);        }    }    pos = sizeof(cdbm.final);    /* creation **/    fgets(pwline,sizeof(pwline),pwfile);    while (!feof(pwfile)) {        key = pwline; ptr = pwline;        while (*ptr != ':') { ptr++; }        *ptr = 0; data = ptr; data++;        while (*ptr != '\n') { ptr++; }        *ptr = 0;        keylen = strlen(key); datalen = strlen(data);#ifdef DEBUG        fprintf (stderr,"Got entry: keylen = %lu, key = %s\n           datalen = %lu, data = %s\n",keylen,key,datalen,data);#endif        cdbmake_pack(packbuf, (uint32)keylen);        cdbmake_pack(packbuf + 4, (uint32)datalen);        if (fwrite(packbuf,1,8,tmfile) < 8) {            fprintf(stderr,"Error: error writing temp file\n");            return(-1);        }        h = CDBMAKE_HASHSTART;        for (i=0; i < keylen; i++) {            h = cdbmake_hashadd(h,key[i]);            if (putc(key[i],tmfile) == EOF) {                fprintf (stderr,"Error: error temp file\n");                return(-1);            }        }        for (i=0; i < datalen; i++) {            if (putc(data[i],tmfile) == EOF) {                fprintf (stderr,"Error: write error temp file");                return(-1);            }        }        if (!cdbmake_add(&cdbm,h,pos,malloc)) {            fprintf(stderr, "Error: out of memory\n");            return(-1);        }        op = pos;        pos += (uint32)8;        pos += (uint32)keylen;        pos += (uint32)datalen;        if (pos < op) {            fprintf(stderr,"Error: too much data\n");            return(-1);        }        if (!cdbmake_split(&cdbm,malloc)) {            fprintf(stderr,"Error: out of memory\n");            return(-1);        }        fgets(pwline,sizeof(pwline),pwfile);        free(cdbm.split);    }    fclose(pwfile);    if (!cdbmake_split(&cdbm,malloc)) {        fprintf(stderr, "Error: out of memory\n");        return(-1);    }    for (i=0; i < 256; i++) {        len = cdbmake_throw(&cdbm,pos,i);        for (j=0; j < len; j++) {            cdbmake_pack(packbuf,cdbm.hash[j].h);            cdbmake_pack(packbuf + 4, cdbm.hash[j].p);            if (fwrite(packbuf,1,8,tmfile) < 8) {                fprintf(stderr,"Error 1: error temp file\n");                return(-1);            }            op = pos;            pos += (uint32)8;            if (pos < op) {                fprintf (stderr, "Error 12: too much data\n");                return(-1);            }        }    }    if (fflush(tmfile) == EOF) {        fprintf (stderr,"Error 20: write error temp file\n");        return(-1);    }    rewind(tmfile);    if (fwrite(cdbm.final,1,sizeof(cdbm.final),tmfile)<sizeof(cdbm.final)){        fprintf(stderr,"Error 21: write error temp file\n");        return(-1);    }    if (fflush(tmfile) == EOF) {        fprintf(stderr,"Error 22: write error temp file\n");        return(-1);    }        if (close(fileno(tmfile)) == -1) {        fprintf(stderr,"Error 24: error with close()\n");        return(-1);    }    if (rename(vpasswd_cdb_tmp_file,vpasswd_cdb_file)) {        fprintf(stderr,             "Error 25: could not rename cdb.tmp to vpasswd.cdb\n");        return(-1);    }    free(cdbm.head);    free(cdbm.split);    tmpstr = vget_assign(domain, Dir, 156, &uid, &gid );    chown(vpasswd_cdb_file, uid, gid);    chown(vpasswd_lock_file, uid, gid);    chown(vpasswd_file, uid, gid);    return 0;}struct vqpasswd *vauth_getpw(char *user, char *domain){ char in_domain[156]; static struct vqpasswd pwent; static char line[2048]; char *ptr = NULL, *uid = NULL, *gid = NULL; uid_t myuid; uid_t tuid; gid_t tgid; uint32 dlen; FILE *pwf;#ifdef FILE_LOCKING FILE *lock_fs;#endif    verrori = 0;    lowerit(user);    lowerit(domain);    vget_assign(domain,NULL,0,&tuid,&tgid);    myuid = geteuid();    if ( myuid != 0 && myuid != tuid ) {	return(NULL);    }    strncpy( in_domain, domain, sizeof(in_domain));    in_domain[sizeof(in_domain)-1] = '\0';  /* ensure NULL termination */    set_vpasswd_files( in_domain );    if ((pwf = fopen(vpasswd_cdb_file,"r")) == NULL) {#ifdef FILE_LOCKING		if ( (lock_fs = fopen(vpasswd_lock_file, "w+")) == NULL) {			return(NULL);		}		get_write_lock( lock_fs );#endif        make_vpasswd_cdb(domain);#ifdef FILE_LOCKING		unlock_lock(fileno(lock_fs), 0, SEEK_SET, 0);		fclose(lock_fs);#endif        if ((pwf = fopen(vpasswd_cdb_file,"r")) == NULL) {            return(NULL);        }    }    strncpy(line,user,sizeof(line));     strncat(line,":",sizeof(line));    ptr = line;    while (*ptr != ':') { ptr++; }    ptr++;    switch (cdb_seek(fileno(pwf),user,strlen(user),&dlen)) {        case -1:            fclose(pwf);            return NULL;        case 0:            fclose(pwf);            return NULL;    }    if (fread(ptr,sizeof(char),dlen,pwf) != dlen) {        return NULL;    }    fclose(pwf);    line[(dlen+strlen(user)+1)] = 0;    pwent.pw_name   = "";    pwent.pw_passwd = "";    pwent.pw_gecos  = "";    pwent.pw_dir    = "";    pwent.pw_shell  = "";    pwent.pw_clear_passwd  = "";    ptr = line;    pwent.pw_name    = line;    while (*ptr!=0&&*ptr != ':') { ptr++; }    if ( *ptr!=0 ){ *ptr = 0; ptr++; pwent.pw_passwd = ptr; }    while (*ptr!=0&&*ptr != ':') { ptr++; }    if ( *ptr!=0 ){ *ptr = 0; ptr++; uid = ptr; }    while (*ptr!=0&&*ptr != ':') { ptr++; }    if ( *ptr!=0 ){ *ptr = 0; ptr++; gid = ptr; }    while (*ptr!=0&&*ptr != ':') { ptr++; }    if ( *ptr!=0 ){ *ptr = 0; ptr++; pwent.pw_gecos = ptr; }    while (*ptr!=0&&*ptr != ':') { ptr++; }    if ( *ptr!=0 ){ *ptr = 0; ptr++; pwent.pw_dir = ptr; }    while (*ptr!=0&&*ptr != ':') { ptr++; }    if ( *ptr!=0 ){ *ptr = 0; ptr++; pwent.pw_shell = ptr; }    while (*ptr!=0&&*ptr != ':') { ptr++; }    if ( *ptr!=0 ){ *ptr = 0; ptr++; pwent.pw_clear_passwd = ptr; }    if (!*uid) { pwent.pw_uid = 0; } else { pwent.pw_uid = atoi(uid); }    if (!*gid) { pwent.pw_gid = 0; } else { pwent.pw_gid = atoi(gid); }    vlimits_setflags (&pwent, in_domain);#ifdef DEBUG    fprintf (stderr,"vgetpw: db: results: pw_name   = %s\n",pwent.pw_name);    fprintf (stderr,"                     pw_passwd = %s\n",pwent.pw_passwd);    fprintf (stderr,"                     pw_uid    = %d\n",pwent.pw_uid);    fprintf (stderr,"                     pw_gid    = %d\n",pwent.pw_gid);    fprintf (stderr,"                     pw_flags  = %d\n",pwent.pw_flags);    fprintf (stderr,"                     pw_gecos  = %s\n",pwent.pw_gecos);    fprintf (stderr,"                     pw_dir    = %s\n",pwent.pw_dir);    fprintf (stderr,"                     pw_shell  = %s\n",pwent.pw_shell);#endif    return(&pwent);}struct vqpasswd *vauth_getall(char *domain, int first, int sortit){ static FILE *fsv = NULL; struct vqpasswd *tmpwd;    set_vpasswd_files( domain );    if ( first == 1 ) {        if ( fsv != NULL ) fclose(fsv);        set_vpasswd_files( domain );        if ((fsv = fopen(vpasswd_file, "r")) == NULL) return(NULL);    } else if ( fsv == NULL ) {		return(NULL);	}    tmpwd = vgetent(fsv);    if ( tmpwd == NULL ) {		fclose(fsv);		fsv = NULL;	}    return(tmpwd);}void vauth_end_getall(){}void set_vpasswd_files( char *domain ){ char *tmpstr; uid_t uid; gid_t gid; char Dir[156];    vset_default_domain( domain );    tmpstr = vget_assign(domain, Dir, 156, &uid, &gid );    memset(vpasswd_dir, 0, MAX_BUFF);    memset(vpasswd_file, 0, MAX_BUFF);    memset(vpasswd_cdb_file, 0, MAX_BUFF);    memset(vpasswd_cdb_tmp_file, 0, MAX_BUFF);    memset(vpasswd_lock_file, 0, MAX_BUFF);    if ( domain == NULL || domain[0] == 0 ) {        snprintf(vpasswd_dir, MAX_BUFF, "%s/users", VPOPMAILDIR);    } else {        snprintf(vpasswd_dir, MAX_BUFF, "%s", Dir);     }    snprintf(vpasswd_file, MAX_BUFF, "%s/%s", vpasswd_dir,VPASSWD_FILE);    snprintf(vpasswd_bak_file, MAX_BUFF, "%s/%s.%d",         vpasswd_dir,VPASSWD_BAK_FILE, getpid());    snprintf(vpasswd_cdb_file, MAX_BUFF,         "%s/%s", vpasswd_dir,VPASSWD_CDB_FILE);    snprintf(vpasswd_cdb_tmp_file, MAX_BUFF,         "%s/%s",vpasswd_dir,VPASSWD_CDB_TMP_FILE);    snprintf(vpasswd_lock_file, MAX_BUFF,         "%s/%s", vpasswd_dir,VPASSWD_LOCK_FILE);}int vauth_adduser(char *user, char *domain, char *pass, char *gecos, char *dir, int apop ){ static char tmpbuf1[MAX_BUFF]; static char tmpbuf2[MAX_BUFF]; char *tmpstr; int added = 0; FILE *fs1; FILE *fs2;#ifdef FILE_LOCKING FILE *fs3;#endif    /* do not trod on the vpasswd file */    if ( strcmp( "vpasswd", user ) == 0 ) {      return( VA_ILLEGAL_USERNAME );    }    set_vpasswd_files( domain );    /* if the gecos field is null, set it to user name */    if ( gecos==0 || gecos[0]==0) gecos=user;    vcdb_strip_char( gecos );#ifdef FILE_LOCKING    fs3 = fopen(vpasswd_lock_file, "w+");    if ( get_write_lock(fs3) < 0 ) return(-2);#endif    fs1 = fopen(vpasswd_bak_file, "w+");    if ( (fs2 = fopen(vpasswd_file, "r+")) == NULL ) {    	fs2 = fopen(vpasswd_file, "w+");	}            if ( fs1 == NULL || fs2 == NULL ) {		if ( fs1 != NULL ) fclose(fs1);		if ( fs2 != NULL ) fclose(fs2);#ifdef FILE_LOCKING		unlock_lock(fileno(fs3), 0, SEEK_SET, 0);		fclose(fs3);#endif        return(-1);    }    while (fgets(tmpbuf1,MAX_BUFF,fs2)!=NULL){        strncpy(tmpbuf2, tmpbuf1, MAX_BUFF);        tmpstr = strtok(tmpbuf2,":");        if ( added == 0 && strcmp(user, tmpstr) < 0 ) {            added = 1;            vauth_adduser_line( fs1, user, pass, domain,gecos,dir, apop);        }        fputs(tmpbuf1, fs1);    }    if ( added == 0 ) {        vauth_adduser_line( fs1, user, pass, domain,gecos,dir,apop);    }    fclose(fs1);    fclose(fs2);    rename(vpasswd_bak_file, vpasswd_file);    make_vpasswd_cdb(domain);#ifdef FILE_LOCKING	unlock_lock(fileno(fs3), 0, SEEK_SET, 0);	fclose(fs3);#endif    return(0);}int vauth_adddomain( char *domain ){    return(0);}int vauth_deldomain( char *domain ){    return(0);}int vauth_deluser( char *user, char *domain ){ static char tmpbuf1[MAX_BUFF]; static char tmpbuf2[MAX_BUFF]; char *tmpstr; FILE *fs1; FILE *fs2;#ifdef FILE_LOCKING FILE *fs3;#endif    set_vpasswd_files( domain );#ifdef FILE_LOCKING	fs3 = fopen(vpasswd_lock_file, "w+");	if ( get_write_lock(fs3) < 0 ) return(-2);#endif    fs1 = fopen(vpasswd_bak_file, "w+");    if ( (fs2 = fopen(vpasswd_file, "r+")) == NULL ) {    	fs2 = fopen(vpasswd_file, "w+");	}    if ( fs1 == NULL || fs2 == NULL ) {		if ( fs1 != NULL ) fclose(fs1);		if ( fs2 != NULL ) fclose(fs2);#ifdef FILE_LOCKING		unlock_lock(fileno(fs3), 0, SEEK_SET, 0);		fclose(fs3);#endif        return(-1);    }    while (fgets(tmpbuf1,MAX_BUFF,fs2)!=NULL){        strncpy(tmpbuf2, tmpbuf1, MAX_BUFF);        tmpstr = strtok(tmpbuf2,":");                if ( strcmp(user, tmpstr) != 0) {            fputs(tmpbuf1, fs1);        }     }    fclose(fs1);    fclose(fs2);    rename(vpasswd_bak_file, vpasswd_file);    make_vpasswd_cdb(domain);#ifdef FILE_LOCKING	unlock_lock(fileno(fs3), 0, SEEK_SET, 0);	fclose(fs3);#endif    return(0);}/* Utility function to set the users quota * * Calls underlying vauth_getpw and vauth_setpw * to actually change the users information */int vauth_setquota( char *username, char *domain, char *quota){ struct vqpasswd *vpw;    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);    vpw = vauth_getpw( username, domain );    if ( vpw==NULL ) return(VA_USER_DOES_NOT_EXIST);    vpw->pw_shell = quota;    return(vauth_setpw(vpw,domain));}int vauth_setpw( struct vqpasswd *inpw, char *domain ) { static char tmpbuf1[MAX_BUFF]; static char tmpbuf2[MAX_BUFF]; char *tmpstr; FILE *fs1; FILE *fs2;#ifdef FILE_LOCKING FILE *fs3;#endif uid_t myuid; uid_t uid; gid_t gid; int ret;    ret = vcheck_vqpw(inpw, domain);    if ( ret != 0 ) return(ret);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -