/* * Copyright (C) 2004 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 "config.h" #include "vpopmail.h" #include "vauth.h" #include "vlimits.h" #include "vpopmaild.msg" /* two responses */ #define RET_OK "+OK \r\n" #define RET_OK_MORE "+OK+\r\n" #define RET_ERR "-ERR " #define RET_CRLF "\r\n" #define READ_TIMEOUT 60 #define MAX_TMP_BUFF 1024 #define MAX_FILE_NAME 156 #define TOKENS " \n\t\r" #define PASS_TOKENS "\n\r" #define PARAM_TOKENS " =:\n\r" #define GECOS_TOKENS "=:\n\r" #define LIST_DOMAIN_TOKENS " :\t\n\r" const int MAXPATH = 256; char ReadBuf[MAX_TMP_BUFF]; char WriteBuf[MAX_TMP_BUFF]; char SystemBuf[MAX_TMP_BUFF]; struct vqpasswd *tmpvpw; struct vqpasswd AuthVpw; #define AUTH_SIZE 156 char TheUser[AUTH_SIZE]; char ThePass[AUTH_SIZE]; /* for C/R this is 'TheResponse' */ char TheDomain[AUTH_SIZE]; char TheDomainDir[256]; char TheUserDir[256]; char TheVpopmailDomains[256]; char TmpUser[AUTH_SIZE]; char TmpPass[AUTH_SIZE]; /* for C/R this is 'TheResponse' */ char TmpDomain[AUTH_SIZE]; #define LOGIN_FAILURES 3 // Number of login failures allowed #define LOGIN_ACTIVITY 4 // Number of commands accepted before login //int login_tries = 0; /* count invalid login attempts */ int logged_in = 0; /* 0=not logged in, 1=mailbox, 2=domain, 3=system */ int output_type = 0; /* 0=full, 1=compact, 2=silent */ int login(); int add_user(); int del_user(); int mod_user(); int user_info(); int add_domain(); int add_alias_domain(); int add_alias(); int remove_alias(); int delete_alias(); int del_domain(); int dom_info(); int mk_dir(); int rm_dir(); int list_dir(); int rm_file(); int rename_file(); int write_file(); int read_file(); int stat_file(); int list_domains(); int find_domain(); int domain_count(); int user_count(); int list_users(); int list_alias(); int list_lists(); int get_ip_map(); int add_ip_map(); int del_ip_map(); int show_ip_map(); int get_limits(); int set_limits(); int del_limits(); int get_lastauth(); int add_list(); int del_list(); int mod_list(); int get_user_size(); int get_domain_size(); int quit(); int login_help(); int help(); /* utility functions */ void send_user_info(struct vqpasswd *tmpvpw); int validate_path(char * newpath, char *path); int bkscandir(const char *dirname, struct dirent ***namelist, int (*select)(struct dirent *), int (*compar)(const void *, const void *)); int qa_sort(const void * a, const void * b); #define DEC ( int *(*)() ) typedef struct func_t { int level; /* user level required to run the command */ char *command; int (*func)(); char *help; } func_t; func_t LoginFunctions[] = { // Table contents: // Access Level, Command string, function to exec, help text // Output Type values 0 = normal 1 = compact 2 = silent 3 = exit {0, "Login", NULL, NULL}, {0, "login", login, "login user@domain password - expanded bitmaps"}, {1, "clogin", login, "login user@domain password - compact bitmapts"}, {2, "slogin", login, "login user@domain password - silent results"}, {0, "Utility", NULL, NULL}, {0, "help", login_help, "help" }, {0, "exit", quit, "quit" }, {0, "quit", quit, "quit" }, {0, "q", quit, "quit" }, {0, NULL, NULL, NULL }, }; func_t Functions[] = { // Table contents: // Access Level, Command string, function to exec, help text // Access level values 0 = none 1 = user 2 = domain 3 = system {2, "Domain", NULL, NULL}, {2, "user_info", user_info, "user_domain" }, {3, "list_domains", list_domains, "[page per_page]" }, {3, "find_domain", find_domain, "domain per-page" }, {3, "domain_count", domain_count, "" }, {3, "add_alias_domain", add_alias_domain, "domain alias" }, {3, "add_domain", add_domain, "domain postmaster-password" }, {3, "del_domain", del_domain, "domain" }, {3, "dom_info", dom_info, "domain" }, {2, "get_limits", get_limits, "domain" }, {3, "set_limits", set_limits, "domain (option lines)."}, {3, "del_limits", del_limits, "domain" }, {2, "get_domain_size", get_domain_size, "domain" }, {1, "User", NULL, NULL}, {2, "add_user", add_user, "user@domain password" }, {2, "del_user", del_user, "user@domain" }, {2, "user_count", user_count, "domain " }, {2, "list_users", list_users, "domain [page per_page]" }, {2, "list_users", list_users, "domain" }, {2, "list_lists", list_lists, "domain" }, {1, "mod_user", mod_user, "user@domain (option lines)." }, {1, "get_lastauth", get_lastauth, "user@domain" }, {1, "get_user_size", get_user_size, "user@domain" }, {2, "Alias", NULL, NULL}, {2, "add_alias", add_alias, "user@domain user@otherdomain" }, {2, "delete_alias", delete_alias, "user@domain" }, {2, "list_alias", list_alias, "domain" }, {2, "remove_alias", remove_alias, "user@domain user@otherdomain" }, {1, "File System", NULL, NULL}, {1, "mk_dir", mk_dir, "/full/path/to/dir" }, {1, "rm_dir", rm_dir, "/full/path/to/dir" }, {1, "list_dir", list_dir, "/full/path/to/dir" }, {1, "rm_file", rm_file, "/full/path/to/file" }, {1, "rename_file", rename_file, "/full/path/to/file" }, {1, "write_file", write_file, "/full/path (data lines)." }, {1, "read_file", read_file, "/full/path" }, {1, "stat_file", stat_file, "/full/path" }, {1, "IP Map", NULL, NULL}, {1, "get_ip_map", get_ip_map, "domain" }, {3, "add_ip_map", add_ip_map, "domain ip" }, {3, "del_ip_map", del_ip_map, "domain" }, {3, "show_ip_map", show_ip_map, "domain" }, {2, "Mailing List", NULL, NULL}, {2, "add_list", add_list, "domain listname (command line options)" }, {2, "del_list", del_list, "domain listname"}, {2, "mod_list", mod_list, "domain listname (command line options)" }, {0, "Utility", NULL, NULL}, {0, "exit", quit, "quit" }, {0, "quit", quit, "quit" }, {0, "q", quit, "quit" }, {0, "help", help, "help" }, {0, NULL, NULL, NULL } }; int wait_read() { struct timeval tv; fd_set rfds; /*int read_size;*/ tv.tv_sec = READ_TIMEOUT; tv.tv_usec = 0; FD_ZERO(&rfds); FD_SET(1,&rfds); memset(ReadBuf,0,sizeof(ReadBuf)); if (select(2,&rfds,(fd_set *) 0,(fd_set *)0,&tv)>=1) { fgets(ReadBuf,sizeof(ReadBuf),stdin); return(1); } return(-1); } int wait_write() { struct timeval tv; fd_set wfds; int write_size; tv.tv_sec = READ_TIMEOUT; tv.tv_usec = 0; FD_ZERO(&wfds); FD_SET(1,&wfds); if (select(2,(fd_set*)0, &wfds,(fd_set *)0,&tv)>=1) { if ( (write_size = fputs(WriteBuf,stdout) < 0) ) exit(-1); if ( fflush(stdout)!=0) exit(-2); return(write_size); } return(-1); } void show_error( int Major, int Minor ) { snprintf(WriteBuf,sizeof(WriteBuf), RET_ERR "%d.%03d %s" RET_CRLF, Major, Minor, ErrorMessages[ Major ] ); } int main(int argc, char **argv) { int read_size; char *command; int i; int found = 0; int status = 1; int failures = 0; int attempts = 0; if( vauth_open( 1 )) { show_error( ERR_CANT_OPEN_AUTH, 101 ); wait_write(); exit( -1 ); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK); wait_write(); /* authenticate first or drop connection */ while( status > 0 ) { attempts ++; if ( attempts > LOGIN_ACTIVITY ) { show_error( ERR_TOO_MANY_LOGIN, 102 ); wait_write(); exit(-1); } // Read a command read_size = wait_read(); // Read size < 0 means timeout -- fatal if ( read_size < 0 ) { show_error( ERR_RD_TIMEOUT, 103 ); wait_write(); exit(-1); } // No token implies a blank line if ((command=strtok(ReadBuf,TOKENS))==NULL) { continue; // ignore blank lines... } for(found=0,i=0; found==0 && LoginFunctions[i].command!=NULL; ++i ) { if ( ( ! strcasecmp(LoginFunctions[i].command, command) ) && ( LoginFunctions[i].func != NULL ) ) { found = 1; output_type = LoginFunctions[i].level; status = LoginFunctions[i].func(); } } if ( found == 0 ) { show_error( ERR_INVALID_COMMAND, 104 ); } if( -1 == status ) { // missing login parm status = 1; } if( -2 == status ) { // invalid login attempt failures ++; if( failures > LOGIN_FAILURES ) { // too many failures wait_write(); show_error( ERR_TOO_MANY_LOGIN, 105 ); wait_write(); vclose(); exit(-1); } // too many failures status = 1; } wait_write(); } while(1) { read_size = wait_read(); if ( read_size < 0 ) { show_error( ERR_RD_TIMEOUT, 106 ); wait_write(); vclose(); exit(-1); } if ((command=strtok(ReadBuf,TOKENS))==NULL) { continue; // ignore blank lines } for(found=0,i=0;found==0&&Functions[i].command!=NULL;++i ) { if ( ( ! strcasecmp(Functions[i].command, command) ) && ( Functions[i].func != NULL ) && ( logged_in >= Functions[i].level ) ) { found = 1; Functions[i].func(); } } if ( found == 0 ) { show_error( ERR_INVALID_COMMAND, 107 ); } wait_write(); } } int login() { char *email; char *pass; uid_t uid; gid_t gid; // return values: 0 = valid -1 = missing parm warning -2 = invalid login if ((email=strtok(NULL,TOKENS))==NULL) { show_error( ERR_EMAIL_REQD, 203 ); return(-1); } if ((pass=strtok(NULL,PASS_TOKENS))==NULL) { show_error( ERR_PASSWORD_REQD, 204 ); return(-1); } if ( parse_email( email, TheUser, TheDomain, AUTH_SIZE) != 0 ) { show_error( ERR_INVALID_LOGIN, 205 ); return(-2); } if ((tmpvpw = vauth_getpw(TheUser, TheDomain))==NULL) { show_error( ERR_INVALID_LOGIN, 206 ); return(-2); } if ( vauth_crypt(TheUser, TheDomain, pass, tmpvpw) != 0 ) { show_error( ERR_INVALID_LOGIN, 207 ); return(-2); } // snprintf(WriteBuf,sizeof(WriteBuf), RET_OK_MORE); // wait_write(); AuthVpw.pw_name = strdup(tmpvpw->pw_name); AuthVpw.pw_passwd = strdup(tmpvpw->pw_passwd); AuthVpw.pw_uid = tmpvpw->pw_uid; AuthVpw.pw_gid = tmpvpw->pw_gid; AuthVpw.pw_flags = tmpvpw->pw_flags; AuthVpw.pw_gecos = strdup(tmpvpw->pw_gecos); AuthVpw.pw_dir = strdup(tmpvpw->pw_dir); AuthVpw.pw_shell = strdup(tmpvpw->pw_shell); AuthVpw.pw_clear_passwd = strdup(tmpvpw->pw_clear_passwd); snprintf( TheUserDir, sizeof(TheUserDir), AuthVpw.pw_dir); snprintf( TheDomainDir, sizeof(TheDomainDir), vget_assign(TheDomain,NULL,0,&uid,&gid)); snprintf(TheVpopmailDomains, sizeof(TheVpopmailDomains), "%s/domains", VPOPMAILDIR); if ( AuthVpw.pw_gid & SA_ADMIN ) logged_in = 3; else if ( (AuthVpw.pw_gid & QA_ADMIN) || (strcmp("postmaster", AuthVpw.pw_name)==0) ) { AuthVpw.pw_gid |= QA_ADMIN; strcpy( TheDomainDir, vget_assign(TheDomain,NULL,0,NULL,NULL)); logged_in = 2; } else logged_in = 1; if(output_type < 2 ) { snprintf(WriteBuf,sizeof(WriteBuf), RET_OK_MORE); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "vpopmail_dir %s" RET_CRLF, VPOPMAILDIR); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "domain_dir %s" RET_CRLF, TheDomainDir); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "uid %d" RET_CRLF, uid); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "gid %d" RET_CRLF, gid); wait_write(); send_user_info(&AuthVpw); snprintf(WriteBuf, sizeof(WriteBuf), "." RET_CRLF); } else snprintf(WriteBuf,sizeof(WriteBuf), RET_OK); return(0); } int add_user() { char *email_address; char *password; int ret; if ( !(AuthVpw.pw_gid & QA_ADMIN) && !(AuthVpw.pw_gid & SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 301 ); return(-1); } if ((email_address=strtok(NULL,TOKENS))==NULL) { show_error( ERR_EMAIL_REQD, 302 ); return(-1); } if ( parse_email( email_address, TmpUser, TmpDomain, AUTH_SIZE) != 0 ) { show_error( ERR_INVALID_EMAIL, 303 ); return(-1); } if (!(AuthVpw.pw_gid&SA_ADMIN) && (AuthVpw.pw_gid&QA_ADMIN) && (strcmp(TheDomain,TmpDomain))!=0 ) { show_error( ERR_NOT_AUTH_DOMAIN, 304 ); return(-1); } if ((password=strtok(NULL,PASS_TOKENS))==NULL) { show_error( ERR_PASSWORD_REQD, 305 ); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK); if ((ret=vadduser(TmpUser, TmpDomain, password, TmpUser, USE_POP )) < 0 ) { snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0.305 %s" RET_CRLF, verror(ret)); return(-1); } return(0); } int del_user() { char *email_address; int ret; if ( !(AuthVpw.pw_gid & QA_ADMIN) && !(AuthVpw.pw_gid & SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 401 ); return(-1); } if ((email_address=strtok(NULL,TOKENS))==NULL) { show_error( ERR_EMAIL_REQD, 402 ); return(-1); } if ( parse_email( email_address, TmpUser, TmpDomain, AUTH_SIZE) != 0 ) { show_error( ERR_INVALID_EMAIL, 403 ); return(-1); } if (!(AuthVpw.pw_gid&SA_ADMIN) && (AuthVpw.pw_gid&QA_ADMIN) && (strcmp(TheDomain,TmpDomain))!=0 ) { show_error( ERR_NOT_AUTHORIZED, 404 ); return(-1); } if ((ret=vdeluser(TmpUser, TmpDomain)) != VA_SUCCESS ) { snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0,405 %s" RET_CRLF, verror(ret)); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK); return(0); } int mod_user() { char Crypted[64]; char *email_address; char *param; char *value; int ret; int is_user = 0; int can_override = 0; if ((email_address=strtok(NULL,TOKENS))==NULL) { show_error( ERR_EMAIL_REQD, 501 ); return(-1); } if ( parse_email( email_address, TmpUser, TmpDomain, AUTH_SIZE) != 0 ) { show_error( ERR_INVALID_EMAIL, 502 ); return(-1); } /* domain administrator */ if (!(AuthVpw.pw_gid&SA_ADMIN) && (AuthVpw.pw_gid&QA_ADMIN)) { /* if not their domain, reject */ if ( strcmp(TheDomain,TmpDomain)!= 0 ) { show_error( ERR_NOT_AUTH_DOMAIN, 503 ); return(-1); } /* user, not system admin */ } else if ( !(AuthVpw.pw_gid&SA_ADMIN) ) { /* set the is_user flag to decide which things they can change */ is_user = 1; /* if not their account, reject */ if ( strcmp(TheDomain,TmpDomain)!= 0 || strcmp(TheUser,TmpUser)!= 0 ) { show_error( ERR_NOT_AUTH_DOMAIN, 504 ); return(-1); } } /* else they have to be a system admin */ /* get the current user information */ if ((tmpvpw = vauth_getpw(TmpUser, TmpDomain))==NULL) { show_error( ERR_NO_USER, 505 ); while(fgets(ReadBuf,sizeof(ReadBuf),stdin)!=NULL && strcmp(ReadBuf, ".\n") != 0 ); return(-1); } if ( AuthVpw.pw_gid & SA_ADMIN || (AuthVpw.pw_gid & QA_ADMIN && AuthVpw.pw_gid & V_OVERRIDE) ) { can_override = 1; } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK); wait_write(); while(fgets(ReadBuf,sizeof(ReadBuf),stdin)!=NULL ) { if ( ReadBuf[0] == '.' ) break; if ( (param = strtok(ReadBuf,PARAM_TOKENS)) == NULL ) continue; if ( (value = strtok(NULL,PASS_TOKENS)) == NULL ) continue; /* anyone can change the comment field */ if ( strcmp(param,"comment") == 0 ) { tmpvpw->pw_gecos = strdup(value); } else if ( can_override==1 && strcmp(param,"quota") == 0 ) { tmpvpw->pw_shell = format_maildirquota(strdup(value)); update_maildirsize(TmpDomain, tmpvpw->pw_dir, tmpvpw->pw_shell); /* anyone can change encrypted password? */ } else if ( strcmp(param,"encrypted_password") == 0 ) { tmpvpw->pw_passwd = strdup(value); /* anyone can change clear text password, * must set encrypted pass too */ } else if ( strcmp(param,"clear_text_password") == 0 && !(tmpvpw->pw_flags & NO_PASSWD_CHNG) ) { tmpvpw->pw_clear_passwd = strdup(value); mkpasswd3(value,Crypted, sizeof(Crypted)); tmpvpw->pw_passwd = Crypted; /* only system admins or domain admins with override can clear all flags */ } else if ( can_override==1 && strcmp(param,"clear_all_flags") == 0 ) { tmpvpw->pw_gid = 0; } else if ( can_override==1 && strcmp(param,"no_password_change") == 0 ) { if ( atoi(value) == 1 ) tmpvpw->pw_gid |= NO_PASSWD_CHNG; else if ( atoi(value) == 0 ) tmpvpw->pw_gid &= ~NO_PASSWD_CHNG; } else if ( can_override==1 && strcmp(param,"no_pop") == 0 ) { if ( atoi(value) == 1 ) tmpvpw->pw_gid |= NO_POP; else if ( atoi(value) == 0 ) tmpvpw->pw_gid &= ~NO_POP; } else if ( can_override==1 && strcmp(param,"no_webmail") == 0 ) { if ( atoi(value) == 1 ) tmpvpw->pw_gid |= NO_WEBMAIL; else if ( atoi(value) == 0 ) tmpvpw->pw_gid &= ~NO_WEBMAIL; } else if ( can_override==1 && strcmp(param,"no_imap") == 0 ) { if ( atoi(value) == 1 ) tmpvpw->pw_gid |= NO_IMAP; else if ( atoi(value) == 0 ) tmpvpw->pw_gid &= ~NO_IMAP; } else if ( can_override==1 && strcmp(param,"bounce_mail") == 0 ) { if ( atoi(value) == 1 ) tmpvpw->pw_gid |= BOUNCE_MAIL; else if ( atoi(value) == 0 ) tmpvpw->pw_gid &= ~BOUNCE_MAIL; } else if ( can_override==1 && strcmp(param,"no_relay") == 0 ) { if ( atoi(value) == 1 ) tmpvpw->pw_gid |= NO_RELAY; else if ( atoi(value) == 0 ) tmpvpw->pw_gid &= ~NO_RELAY; } else if ( can_override==1 && strcmp(param,"no_dialup") == 0 ) { if ( atoi(value) == 1 ) tmpvpw->pw_gid |= NO_DIALUP; else if ( atoi(value) == 0 ) tmpvpw->pw_gid &= ~NO_DIALUP; } else if ( can_override==1 && strcmp(param,"user_flag_0") == 0 ) { if ( atoi(value) == 1 ) tmpvpw->pw_gid |= V_USER0; else if ( atoi(value) == 0 ) tmpvpw->pw_gid &= ~V_USER0; } else if ( can_override==1 && strcmp(param,"user_flag_1") == 0 ) { if ( atoi(value) == 1 ) tmpvpw->pw_gid |= V_USER1; else if ( atoi(value) == 0 ) tmpvpw->pw_gid &= ~V_USER1; } else if ( strcmp(param,"user_flag_2") == 0 ) { if ( atoi(value) == 1 ) tmpvpw->pw_gid |= V_USER2; else if ( atoi(value) == 0 ) tmpvpw->pw_gid &= ~V_USER2; } else if ( strcmp(param,"user_flag_3") == 0 ) { if ( atoi(value) == 1 ) tmpvpw->pw_gid |= V_USER3; else if ( atoi(value) == 0 ) tmpvpw->pw_gid &= ~V_USER3; } else if ( can_override==1 && strcmp(param,"no_smtp") == 0 ) { if ( atoi(value) == 1 ) tmpvpw->pw_gid |= NO_SMTP; else if ( atoi(value) == 0 ) tmpvpw->pw_gid &= ~NO_SMTP; } else if ( AuthVpw.pw_gid & SA_ADMIN && strcmp(param,"system_admin_privileges") == 0 ) { if ( atoi(value) == 1 ) tmpvpw->pw_gid |= SA_ADMIN; else if ( atoi(value) == 0 ) tmpvpw->pw_gid &= ~SA_ADMIN; } else if ( AuthVpw.pw_gid & SA_ADMIN && strcmp(param,"system_expert_privileges") == 0 ) { if ( atoi(value) == 1 ) tmpvpw->pw_gid |= SA_EXPERT; else if ( atoi(value) == 0 ) tmpvpw->pw_gid &= ~SA_EXPERT; } else if ( (AuthVpw.pw_gid & SA_ADMIN || AuthVpw.pw_gid & QA_ADMIN) && strcmp(param,"domain_admin_privileges") == 0 ) { if ( atoi(value) == 1 ) tmpvpw->pw_gid |= QA_ADMIN; else if ( atoi(value) == 0 ) tmpvpw->pw_gid &= ~QA_ADMIN; } else if ( AuthVpw.pw_gid & SA_ADMIN && strcmp(param,"override_domain_limits") == 0 ) { if ( atoi(value) == 1 ) tmpvpw->pw_gid |= V_OVERRIDE; else if ( atoi(value) == 0 ) tmpvpw->pw_gid &= ~V_OVERRIDE; } else if ( strcmp(param,"no_spamassassin") == 0 ) { if ( atoi(value) == 1 ) { tmpvpw->pw_gid |= NO_SPAMASSASSIN; } else if ( atoi(value) == 0 ) { tmpvpw->pw_gid &= ~NO_SPAMASSASSIN; } } else if ( strcmp(param,"delete_spam") == 0 ) { if ( atoi(value) == 1 ) { tmpvpw->pw_gid |= DELETE_SPAM; } else if ( atoi(value) == 0 ) { tmpvpw->pw_gid &= ~DELETE_SPAM; } } else if ( strcmp(param,"no_maildrop") == 0 ) { if ( atoi(value) == 1 ) { tmpvpw->pw_gid |= NO_MAILDROP; } else if ( atoi(value) == 0 ) { tmpvpw->pw_gid &= ~NO_MAILDROP; } } } if ( (ret=vauth_setpw( tmpvpw, TmpDomain )) != 0 ) { snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0.507 %s" RET_CRLF, verror(ret)); } else { snprintf(WriteBuf,sizeof(WriteBuf), RET_OK); } return(0); } int user_info() { char *email_address; if ( !(AuthVpw.pw_gid & QA_ADMIN) && !(AuthVpw.pw_gid & SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 601 ); return(-1); } if ((email_address=strtok(NULL,TOKENS))==NULL) { show_error( ERR_EMAIL_REQD, 602 ); return(-1); } if ( parse_email( email_address, TmpUser, TmpDomain, AUTH_SIZE) != 0 ) { show_error( ERR_INVALID_EMAIL, 603 ); return(-1); } if (!(AuthVpw.pw_gid&SA_ADMIN) && (AuthVpw.pw_gid&QA_ADMIN) && (strcmp(TheDomain,TmpDomain))!=0 ) { show_error( ERR_NOT_AUTH_DOMAIN, 604 ); return(-1); } if ((tmpvpw = vauth_getpw(TmpUser, TmpDomain))==NULL) { show_error( ERR_NO_USER, 605 ); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK_MORE); wait_write(); send_user_info(tmpvpw); snprintf(WriteBuf, sizeof(WriteBuf), "." RET_CRLF); return(0); } void send_user_info(struct vqpasswd *tmpvpw) { snprintf(WriteBuf,sizeof(WriteBuf),"name %s" RET_CRLF, tmpvpw->pw_name); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf),"comment %s" RET_CRLF, tmpvpw->pw_gecos); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf),"quota %s" RET_CRLF, tmpvpw->pw_shell); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf),"user_dir %s" RET_CRLF, tmpvpw->pw_dir); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf),"encrypted_password %s" RET_CRLF, tmpvpw->pw_passwd); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf),"clear_text_password %s" RET_CRLF, tmpvpw->pw_clear_passwd); wait_write(); if( output_type > 0 ) { snprintf(WriteBuf, sizeof(WriteBuf), "gidflags %i" RET_CRLF, tmpvpw->pw_gid); wait_write(); } else { if ( tmpvpw->pw_gid & NO_PASSWD_CHNG ) { snprintf(WriteBuf, sizeof(WriteBuf), "no_password_change 1" RET_CRLF); } else { snprintf(WriteBuf, sizeof(WriteBuf), "no_password_change 0" RET_CRLF); } wait_write(); if ( tmpvpw->pw_gid & NO_POP ) { snprintf(WriteBuf, sizeof(WriteBuf), "no_pop 1" RET_CRLF); } else { snprintf(WriteBuf, sizeof(WriteBuf), "no_pop 0" RET_CRLF); } wait_write(); if ( tmpvpw->pw_gid & NO_WEBMAIL ) { snprintf(WriteBuf, sizeof(WriteBuf), "no_webmail 1" RET_CRLF); } else { snprintf(WriteBuf, sizeof(WriteBuf), "no_webmail 0" RET_CRLF); } wait_write(); if ( tmpvpw->pw_gid & NO_IMAP ) { snprintf(WriteBuf, sizeof(WriteBuf), "no_imap 1" RET_CRLF); } else { snprintf(WriteBuf, sizeof(WriteBuf), "no_imap 0" RET_CRLF); } wait_write(); if ( tmpvpw->pw_gid & BOUNCE_MAIL ) { snprintf(WriteBuf, sizeof(WriteBuf), "bounce_mail 1" RET_CRLF); } else { snprintf(WriteBuf, sizeof(WriteBuf), "bounce_mail 0" RET_CRLF); } wait_write(); if ( tmpvpw->pw_gid & NO_RELAY ) { snprintf(WriteBuf, sizeof(WriteBuf), "no_relay 1" RET_CRLF); } else { snprintf(WriteBuf, sizeof(WriteBuf), "no_relay 0" RET_CRLF); } wait_write(); if ( tmpvpw->pw_gid & NO_DIALUP ) { snprintf(WriteBuf, sizeof(WriteBuf), "no_dialup 1" RET_CRLF); } else { snprintf(WriteBuf, sizeof(WriteBuf), "no_dialup 0" RET_CRLF); } wait_write(); if ( tmpvpw->pw_gid & V_USER0 ) { snprintf(WriteBuf, sizeof(WriteBuf), "user_flag_0 1" RET_CRLF); } else { snprintf(WriteBuf, sizeof(WriteBuf), "user_flag_0 0" RET_CRLF); } wait_write(); if ( tmpvpw->pw_gid & V_USER1 ) { snprintf(WriteBuf, sizeof(WriteBuf), "user_flag_1 1" RET_CRLF); } else { snprintf(WriteBuf, sizeof(WriteBuf), "user_flag_1 0" RET_CRLF); } wait_write(); if ( tmpvpw->pw_gid & V_USER2 ) { snprintf(WriteBuf, sizeof(WriteBuf), "user_flag_2 1" RET_CRLF); } else { snprintf(WriteBuf, sizeof(WriteBuf), "user_flag_2 0" RET_CRLF); } wait_write(); if ( tmpvpw->pw_gid & V_USER3 ) { snprintf(WriteBuf, sizeof(WriteBuf), "user_flag_3 1" RET_CRLF); } else { snprintf(WriteBuf, sizeof(WriteBuf), "user_flag_3 0" RET_CRLF); } wait_write(); if ( tmpvpw->pw_gid & NO_SMTP ) { snprintf(WriteBuf, sizeof(WriteBuf), "no_smtp 1" RET_CRLF); } else { snprintf(WriteBuf, sizeof(WriteBuf), "no_smtp 0" RET_CRLF); } wait_write(); if ( tmpvpw->pw_gid & QA_ADMIN ) { snprintf(WriteBuf, sizeof(WriteBuf), "domain_admin_privileges 1" RET_CRLF); } else { snprintf(WriteBuf, sizeof(WriteBuf), "domain_admin_privileges 0" RET_CRLF); } wait_write(); if ( tmpvpw->pw_gid & V_OVERRIDE ) { snprintf(WriteBuf, sizeof(WriteBuf), "override_domain_limits 1" RET_CRLF); } else { snprintf(WriteBuf, sizeof(WriteBuf), "override_domain_limits 0" RET_CRLF); } wait_write(); if ( tmpvpw->pw_gid & NO_SPAMASSASSIN ) { snprintf(WriteBuf, sizeof(WriteBuf), "no_spamassassin 1" RET_CRLF); } else { snprintf(WriteBuf, sizeof(WriteBuf), "no_spamassassin 0" RET_CRLF); } wait_write(); if ( tmpvpw->pw_gid & DELETE_SPAM ) { snprintf(WriteBuf, sizeof(WriteBuf), "delete_spam 1" RET_CRLF); } else { snprintf(WriteBuf, sizeof(WriteBuf), "delete_spam 0" RET_CRLF); } wait_write(); if ( tmpvpw->pw_gid & NO_MAILDROP ) { snprintf(WriteBuf, sizeof(WriteBuf), "no_maildrop 1" RET_CRLF); } else { snprintf(WriteBuf, sizeof(WriteBuf), "no_maildrop 0" RET_CRLF); } wait_write(); if ( tmpvpw->pw_gid & SA_ADMIN ) { snprintf(WriteBuf, sizeof(WriteBuf), "system_admin_privileges 1" RET_CRLF); } else { snprintf(WriteBuf, sizeof(WriteBuf), "system_admin_privileges 0" RET_CRLF); } wait_write(); } snprintf(WriteBuf, sizeof(WriteBuf), "." RET_CRLF); } int add_domain() { char *domain; char *password; int ret; if ( !(AuthVpw.pw_gid & SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 801 ); return(-1); } if ((domain=strtok(NULL,TOKENS))==NULL) { show_error( ERR_DOMAIN_REQD, 802 ); return(-1); } if ((password=strtok(NULL,PASS_TOKENS))==NULL) { show_error( ERR_PASSWORD_REQD, 803 ); return(-1); } if ((ret=vadddomain(domain,VPOPMAILDIR,VPOPMAILUID,VPOPMAILGID))!=VA_SUCCESS){ snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0.804 %s" RET_CRLF, verror(ret)); return(-1); } if ((ret=vadduser("postmaster",domain , password, "postmaster", USE_POP ))<0){ snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0.805 %s" RET_CRLF, verror(ret)); vdeldomain( domain ); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK); return(0); } int add_alias() { char *alias, *alias_line; char Email[256], Domain[256]; if ( !(AuthVpw.pw_gid & QA_ADMIN) && !(AuthVpw.pw_gid & SA_ADMIN)) { show_error( ERR_NOT_AUTHORIZED, 901 ); return(-1); } if ((alias=strtok(NULL,TOKENS))==NULL) { show_error( ERR_ALIAS_REQD, 902 ); return(-1); } if (parse_email(alias, Email, Domain, sizeof(Email)) != 0) { show_error( ERR_INVALID_ALIAS, 903 ); return(-1); } /* not system administrator and domain administrator - must be in their own domain */ if (!(AuthVpw.pw_gid & SA_ADMIN) && (AuthVpw.pw_gid & QA_ADMIN)) { /* if not their domain, reject */ if ( strcmp(TheDomain,Domain)!= 0 ) { show_error( ERR_NOT_AUTH_DOMAIN, 904 ); return(-1); } /* not system admin so kick them out */ } else if ( !(AuthVpw.pw_gid&SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 905 ); return(-1); } if ((alias_line=strtok(NULL, "\n"))==NULL) { show_error( ERR_ALIAS_LINE_REQD, 906 ); return(-1); } if (valias_insert(Email, Domain, alias_line) != 0) { show_error( ERR_ALIAS_INSERT_FAIL, 907 ); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK); return(0); } int remove_alias() { char *alias, *alias_line; char Email[256], Domain[256]; if ( !(AuthVpw.pw_gid & QA_ADMIN) && !(AuthVpw.pw_gid & SA_ADMIN)) { show_error( ERR_NOT_AUTHORIZED, 1001 ); return(-1); } if ((alias=strtok(NULL,TOKENS))==NULL) { show_error( ERR_ALIAS_REQD, 1002 ); return(-1); } if (parse_email(alias, Email, Domain, sizeof(Email)) != 0) { show_error( ERR_INVALID_ALIAS, 1003 ); return(-1); } /* not system administrator and domain administrator - must be in their own domain */ if (!(AuthVpw.pw_gid & SA_ADMIN) && (AuthVpw.pw_gid & QA_ADMIN)) { /* if not their domain, reject */ if ( strcmp(TheDomain,Domain)!= 0 ) { show_error( ERR_NOT_AUTH_DOMAIN, 1004 ); return(-1); } /* not system admin so kick them out */ } else if ( !(AuthVpw.pw_gid&SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 1005 ); return(-1); } if ((alias_line=strtok(NULL, "\n"))==NULL) { show_error( ERR_ALIAS_LINE_REQD, 1006 ); return(-1); } if (valias_remove(Email, Domain, alias_line) != 0) { show_error( ERR_ALIAS_REMOVE_FAIL, 1007 ); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK); return(0); } int delete_alias() { char *alias; char Email[256], Domain[256]; if ( !(AuthVpw.pw_gid & QA_ADMIN) && !(AuthVpw.pw_gid & SA_ADMIN)) { show_error( ERR_NOT_AUTHORIZED, 1101 ); return(-1); } if ((alias=strtok(NULL,TOKENS))==NULL) { show_error( ERR_ALIAS_REQD, 1102 ); return(-1); } if (parse_email(alias, Email, Domain, sizeof(Email)) != 0) { show_error( ERR_INVALID_ALIAS, 1103 ); return(-1); } /* not system administrator and domain administrator - must be in their own domain */ if (!(AuthVpw.pw_gid & SA_ADMIN) && (AuthVpw.pw_gid & QA_ADMIN)) { /* if not their domain, reject */ if ( strcmp(TheDomain,Domain)!= 0 ) { show_error( ERR_NOT_AUTH_DOMAIN, 1104 ); return(-1); } /* not system admin so kick them out */ } else if ( !(AuthVpw.pw_gid&SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 1105 ); return(-1); } if (valias_delete(Email, Domain) != 0) { show_error( ERR_ALIAS_DELETE_FAIL, 1106 ); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK); return(0); } /* * * Consider adding code from vaddaliasdomain program so it doesn't * matter which way you enter the parameters, it always does the * right thing. * */ int add_alias_domain() { char *domain; char *alias; int ret; if ( !(AuthVpw.pw_gid & SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 1201 ); return(-1); } if ((domain=strtok(NULL,TOKENS))==NULL) { show_error( ERR_DOMAIN_REQD, 1202 ); return(-1); } if ((alias=strtok(NULL,TOKENS))==NULL) { show_error( ERR_ALIAS_REQD, 1203 ); return(-1); } if ((ret=vaddaliasdomain(alias,domain))!=VA_SUCCESS){ snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0.1204 %s" RET_CRLF, verror(ret)); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK); return(0); } int del_domain() { char *domain; char *dummy=""; int ret; if ( !(AuthVpw.pw_gid & SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 1301 ); return(-1); } if ((domain=strtok(NULL,TOKENS))==NULL) { show_error( ERR_DOMAIN_REQD, 1302 ); return(-1); } if ((ret=vdeldomain(domain))!=VA_SUCCESS){ snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0.1303 %s" RET_CRLF, verror(ret)); return(-1); } /* Clear the domain info cache */ vget_assign(dummy, NULL, 0, NULL, NULL ); snprintf(WriteBuf,sizeof(WriteBuf), RET_OK); return(0); } int dom_info() { char *domain; domain_entry *entry; char *aliases[MAX_DOM_ALIAS]; int i, aliascount=0; if ( !(AuthVpw.pw_gid & SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 1401 ); return(-1); } if ((domain=strtok(NULL,TOKENS))==NULL) { show_error( ERR_DOMAIN_REQD, 1402 ); return(-1); } entry = get_domain_entries( domain ); if (entry==NULL) { // something went wrong if( verrori ) { // could not open file snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0.1403 %s" RET_CRLF, verror(verrori)); return(0); } else { // domain does not exist snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0.1404 %s" RET_CRLF, verror(VA_DOMAIN_DOES_NOT_EXIST)); return(0); } } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK_MORE); wait_write(); while( entry ) { if (strcmp(entry->domain, entry->realdomain) != 0) { aliases[aliascount++] = strdup(entry->domain); } else { snprintf(WriteBuf,sizeof(WriteBuf),"domain %s" RET_CRLF, entry->domain); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf),"path %s" RET_CRLF, entry->path); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf),"uid %i" RET_CRLF, entry->uid); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf),"gid %i" RET_CRLF, entry->gid); wait_write(); } entry = get_domain_entries(NULL); } for(i=0;i slash ) { show_error( ERR_INVALID_DIR_AT, 1504 ); return(4); } for(i=0;path[i]!='/'&&path[i]!=0&&i<256;++i) { theemail[i] = path[i]; } theemail[i] = 0; if ( parse_email( theemail, theuser, thedomain, 256) != 0 ) { show_error( ERR_INVALID_DIR_PARSE, 1505 ); return(5); } if ((myvpw = vauth_getpw(theuser, thedomain))==NULL) { show_error( ERR_INVALID_DIR_UNK, 1506 ); return(6); } /* limit domain admins to their domains */ if ( AuthVpw.pw_gid & QA_ADMIN ) { if ( strncmp(TheDomain,thedomain,strlen(TheDomain))!=0 ) { show_error( ERR_NOT_AUTH_DOMAIN, 1507 ); return(7); } /* limit users to their accounts */ } else if ( !(AuthVpw.pw_gid&SA_ADMIN) ){ if ( strcmp(TheUser, theuser) != 0 || strcmp(TheDomain, thedomain) != 0 ) { show_error( ERR_NO_USER, 1508 ); return(8); } } snprintf(newpath, MAXPATH, myvpw->pw_dir); strncat(newpath, &path[i], MAXPATH ); } else { /* may be domain name */ for(i=0;path[i]!='/'&&path[i]!=0&&i<256;++i) { thedomain[i] = path[i]; } thedomain[i] = 0; if ( vget_assign(thedomain, thedir,sizeof(thedir),NULL,NULL) == NULL ) { show_error( ERR_NOT_AUTH_DOMAIN, 1509 ); return(9); } snprintf(newpath, MAXPATH, thedir); strncat(newpath, &path[i], MAXPATH ); } } if ( AuthVpw.pw_gid & SA_ADMIN ) { if ( strncmp(TheVpopmailDomains, newpath, strlen(TheVpopmailDomains))!=0 ) { show_error( ERR_UNAUTH_DIR, 1510 ); return(10); } } else if ( AuthVpw.pw_gid & QA_ADMIN ) { if ( strncmp(TheDomainDir, newpath, strlen(TheDomainDir)) !=0 ) { show_error( ERR_UNAUTH_DIR, 1511 ); return(11); } } else { if ( strncmp(TheUserDir, newpath, strlen(TheUserDir))!=0 ) { show_error( ERR_UNAUTH_DIR, 1512 ); return(12); } } return( 0 ); } int mk_dir() { char *olddir; char dir[MAXPATH]; /* must supply directory parameter */ if ((olddir=strtok(NULL,TOKENS))==NULL) { show_error( ERR_DIR_REQD, 1601 ); return(-1); } if ( validate_path(dir, olddir) ) return(-1); /* make directory, return error */ if ( mkdir(dir,0700) < 0 ) { snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0.1602 %s" RET_CRLF, strerror(errno)); return(-1); } /* Change ownership */ if ( chown(dir,VPOPMAILUID,VPOPMAILGID) == -1 ) { snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0.1603 %s" RET_CRLF, strerror(errno)); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK); return(0); } int rm_dir() { char *olddir; char dir[MAXPATH]; /* must supply directory parameter */ if ((olddir=strtok(NULL,TOKENS))==NULL) { show_error( ERR_DIR_REQD, 1701 ); return(-1); } if ( validate_path( dir, olddir ) ) return(-1); /* recursive directory delete */ if ( vdelfiles(dir) < 0 ) { snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0.1702 %s" RET_CRLF, strerror(errno)); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK); return(0); } int list_dir() { char *olddir; char dir[MAXPATH]; DIR *mydir; struct dirent *mydirent; struct stat statbuf; /* must supply directory parameter */ if ((olddir=strtok(NULL,TOKENS))==NULL) { show_error( ERR_DIR_REQD, 1801 ); return(-1); } if ( validate_path( dir, olddir )) return(-1); if ( chdir(dir) < 0 ) { snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0.1802 %s" RET_CRLF, strerror(errno)); return(-1); } if ( (mydir = opendir(".")) == NULL ) { snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0.1803 %s" RET_CRLF, strerror(errno)); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK_MORE); wait_write(); while((mydirent=readdir(mydir))!=NULL){ /* skip the current directory and the parent directory entries */ if ( strncmp(mydirent->d_name,".", 2) ==0 || strncmp(mydirent->d_name,"..", 3)==0 ) continue; if ( lstat(mydirent->d_name,&statbuf) < 0 ) { printf("error on stat of %s\n", mydirent->d_name); exit(-1); } snprintf( WriteBuf, sizeof(WriteBuf), mydirent->d_name); if ( S_ISREG(statbuf.st_mode ) ) { strncat(WriteBuf," file", sizeof(WriteBuf)); } else if ( S_ISDIR(statbuf.st_mode ) ) { strncat(WriteBuf," dir", sizeof(WriteBuf)); } else if ( S_ISCHR(statbuf.st_mode ) ) { strncat(WriteBuf," chardev", sizeof(WriteBuf)); } else if ( S_ISBLK(statbuf.st_mode ) ) { strncat(WriteBuf," blkdev", sizeof(WriteBuf)); } else if ( S_ISFIFO(statbuf.st_mode ) ) { strncat(WriteBuf," fifo", sizeof(WriteBuf)); } else if ( S_ISLNK(statbuf.st_mode ) ) { strncat(WriteBuf," link", sizeof(WriteBuf)); } else if ( S_ISSOCK(statbuf.st_mode ) ) { strncat(WriteBuf," sock", sizeof(WriteBuf)); } else { strncat(WriteBuf," unknown", sizeof(WriteBuf)); } strncat(WriteBuf,RET_CRLF, sizeof(WriteBuf)); wait_write(); } if ( closedir(mydir) < 0 ) { /* oh well, at least we might die soon */ } snprintf(WriteBuf, sizeof(WriteBuf), "." RET_CRLF); return(0); } int rename_file() { char sourcename[MAXPATH], destname[MAXPATH]; char *source, *dest; if ((source=strtok(NULL,TOKENS))==NULL) { show_error( ERR_SOURCE_REQD, 3801 ); return(-1); } if ((dest=strtok(NULL,TOKENS))==NULL) { show_error( ERR_DEST_REQD, 3801 ); return(-1); } if ( validate_path( sourcename, source )) return(-1); if ( validate_path( destname, dest )) return(-1); if ( rename(sourcename,destname) < 0 ) { snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0.3803 %s" RET_CRLF, strerror(errno)); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK); return(0); } int rm_file() { char *oldfilename; char filename[MAXPATH]; /* must supply directory parameter */ if ((oldfilename=strtok(NULL,TOKENS))==NULL) { show_error( ERR_FNAME_REQD, 1901 ); return(-1); } if ( validate_path( filename, oldfilename )) return(-1); /* unlink filename */ if ( unlink(filename) < 0 ) { snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0.1902 %s" RET_CRLF, strerror(errno)); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK); return(0); } int write_file() { char *oldfilename; char filename[MAXPATH]; FILE *fs; static char tmpbuf[1024]; /* must supply directory parameter */ if ((oldfilename=strtok(NULL,TOKENS))==NULL) { show_error( ERR_FNAME_REQD, 2001 ); return(-1); } if ( validate_path( filename, oldfilename )) return(-1); if ( (fs=fopen(filename,"w+"))==NULL) { snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0.2002 %s" RET_CRLF, strerror(errno)); return(-1); } while( fgets(tmpbuf,sizeof(tmpbuf),stdin)!=NULL && strcmp(tmpbuf, "." RET_CRLF)!=0 && strcmp(tmpbuf, ".\n")!= 0 ) { fputs(tmpbuf,fs); } fclose(fs); snprintf(WriteBuf,sizeof(WriteBuf), RET_OK); return(0); } int read_file() { char *oldfilename; char filename[MAXPATH]; FILE *fs; static char tmpbuf[1024]; /* must supply directory parameter */ if ((oldfilename=strtok(NULL,TOKENS))==NULL) { show_error( ERR_FNAME_REQD, 2101 ); return(-1); } if ( validate_path( filename, oldfilename )) return(-1); if ( (fs=fopen(filename,"r"))==NULL) { snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0.2102 %s" RET_CRLF, strerror(errno)); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK_MORE); wait_write(); while(fgets(tmpbuf,sizeof(tmpbuf),fs)!=NULL){ if ( strcmp(tmpbuf, "." RET_CRLF) == 0 || strcmp(tmpbuf, ".\n") == 0 ) { snprintf(WriteBuf, sizeof(WriteBuf), "."); strncat(WriteBuf, tmpbuf, sizeof(WriteBuf)); } else { memcpy(WriteBuf,tmpbuf,sizeof(tmpbuf)); } wait_write(); } fclose(fs); if ( tmpbuf[0] != 0 && tmpbuf[strlen(tmpbuf)-1] != '\n' ) { snprintf(WriteBuf,sizeof(WriteBuf), RET_CRLF "." RET_CRLF); } else { snprintf(WriteBuf,sizeof(WriteBuf), "." RET_CRLF); } return(0); } int stat_file() { char *oldfilename; char filename[MAXPATH]; struct stat mystat; /* must supply directory parameter */ if ((oldfilename=strtok(NULL,TOKENS))==NULL) { show_error( ERR_FNAME_REQD, 2201 ); return(-1); } if ( validate_path( filename, oldfilename )) return(-1); if ( (stat(filename,&mystat))!=0){ snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0.2202 %s" RET_CRLF, strerror(errno)); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK_MORE); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "uid: %d\n", mystat.st_uid); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "." RET_CRLF); return(0); } int list_domains() { domain_entry *entry; char *tmpstr; int page = 0; int lines_per_page = 0; int count; int start; int end; if ( !(AuthVpw.pw_gid & SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 2301 ); return(-1); } if ((tmpstr=strtok(NULL,TOKENS))!=NULL) { page = atoi(tmpstr); if ( page < 0 ) page = 0; if ((tmpstr=strtok(NULL,TOKENS))!=NULL) { lines_per_page = atoi(tmpstr); if ( lines_per_page < 0 ) lines_per_page = 0; } } if ( page > 0 && lines_per_page > 0 ) { start = (page-1) * lines_per_page; end = page * lines_per_page; } else { start = 0; end = 0; } entry=get_domain_entries( "" ); if ( entry == NULL ) { show_error( ERR_NO_OPEN_ASSIGN, 2302 ); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK_MORE); wait_write(); count = 0; while( entry ) { if ( end>0 ) { if ( count>=start && countrealdomain, entry->domain); wait_write(); } else if ( count>=end ) { break; } } else { snprintf(WriteBuf,sizeof(WriteBuf), "%s %s" RET_CRLF, entry->realdomain, entry->domain); wait_write(); } ++count; entry=get_domain_entries(NULL); } snprintf(WriteBuf,sizeof(WriteBuf), "." RET_CRLF); return(0); } int find_domain() { domain_entry *entry; char *tmpstr; char *domain; int miss; int count; int page; int per_page; per_page = 0; if ( !(AuthVpw.pw_gid & SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 2401 ); return(-1); } if ((domain=strtok(NULL,TOKENS))==NULL) { show_error( ERR_DOMAIN_REQD, 2402 ); return(-1); } if ((tmpstr=strtok(NULL,TOKENS))!=NULL) { per_page = atoi(tmpstr); } entry=get_domain_entries( "" ); if ( entry == NULL ) { show_error( ERR_NO_OPEN_ASSIGN, 2403 ); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK_MORE); wait_write(); count = 0; miss = 1; while( entry ) { if( strcmp(domain, entry->domain)==0 ) { miss = 0; break; } count++; entry=get_domain_entries(NULL); } if( miss ) { page = 0; } else if( per_page > 0 ) { page = ( count / per_page ) + 1; } else { page = count; } snprintf(WriteBuf,sizeof(WriteBuf), "page %i" RET_CRLF, page ); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "." RET_CRLF); return(0); } int domain_count() { domain_entry *entry; int count; if ( !(AuthVpw.pw_gid & SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 2501 ); return(-1); } entry=get_domain_entries( "" ); if ( entry == NULL ) { show_error( ERR_NO_OPEN_ASSIGN, 2502 ); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK_MORE); wait_write(); count = 0; while( entry ) { ++count; entry=get_domain_entries(NULL); } snprintf(WriteBuf,sizeof(WriteBuf), "count %i" RET_CRLF, count); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "." RET_CRLF); return(0); } int user_count() { char *domain; int first; int count; if ( !(AuthVpw.pw_gid & QA_ADMIN) && !(AuthVpw.pw_gid & SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 2601 ); return(-1); } if ((domain=strtok(NULL,TOKENS))==NULL) { show_error( ERR_DOMAIN_REQD, 2602 ); return(-1); } if ( !(AuthVpw.pw_gid&SA_ADMIN) && (AuthVpw.pw_gid&QA_ADMIN) && (strcmp(TheDomain,domain))!=0 ) { show_error( ERR_NOT_AUTH_DOMAIN, 2603 ); return(-1); } if ( !(AuthVpw.pw_gid&SA_ADMIN) && (AuthVpw.pw_gid&QA_ADMIN) && (strcmp(TheDomain,domain))!=0 ) { show_error( ERR_NOT_AUTH_DOMAIN, 2604 ); return(-1); } snprintf(WriteBuf, sizeof(WriteBuf), RET_OK_MORE); wait_write(); first=1; count = 0; while((tmpvpw=vauth_getall(domain, first, 1))!=NULL) { first = 0; ++count; } snprintf(WriteBuf,sizeof(WriteBuf), "count %i" RET_CRLF, count); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "." RET_CRLF); return(0); } int list_users() { char *domain; char *tmpstr; int first; int page = 0; int lines_per_page = 0; int count; int start; int end; if ( !(AuthVpw.pw_gid & QA_ADMIN) && !(AuthVpw.pw_gid & SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 2701 ); return(-1); } if ((domain=strtok(NULL,TOKENS))==NULL) { show_error( ERR_EMAIL_REQD, 2702 ); return(-1); } if ( !(AuthVpw.pw_gid&SA_ADMIN) && (AuthVpw.pw_gid&QA_ADMIN) && (strcmp(TheDomain,domain))!=0 ) { show_error( ERR_NOT_AUTH_DOMAIN, 2703 ); return(-1); } if ((tmpstr=strtok(NULL,TOKENS))!=NULL) { page = atoi(tmpstr); if ( page < 0 ) page = 0; if ((tmpstr=strtok(NULL,TOKENS))!=NULL) { lines_per_page = atoi(tmpstr); if ( lines_per_page < 0 ) lines_per_page = 0; } } if ( page > 0 && lines_per_page > 0 ) { start = (page-1) * lines_per_page; end = page * lines_per_page; } else { start = 0; end = 0; } if ( !(AuthVpw.pw_gid&SA_ADMIN) && (AuthVpw.pw_gid&QA_ADMIN) && (strcmp(TheDomain,domain))!=0 ) { show_error( ERR_NOT_AUTH_DOMAIN, 2704 ); return(-1); } snprintf(WriteBuf, sizeof(WriteBuf), RET_OK_MORE); wait_write(); first=1; count = 0; while((tmpvpw=vauth_getall(domain, first, 1))!=NULL) { first = 0; if ( end>0 ) { if ( count>=start && count=end ) { break; } } else { send_user_info(tmpvpw); } snprintf(WriteBuf, sizeof(WriteBuf), RET_CRLF ); wait_write(); ++count; } snprintf(WriteBuf,sizeof(WriteBuf), "." RET_CRLF); return(0); } /* * * This needs to be changed to use the new valias code * */ int list_alias() { char *domain, *tmpalias; char Alias[256], Email[256], Domain[256]; if ( !(AuthVpw.pw_gid & QA_ADMIN) && !(AuthVpw.pw_gid & SA_ADMIN)) { show_error( ERR_NOT_AUTHORIZED, 2801 ); return(-1); } if ((domain=strtok(NULL,TOKENS))==NULL) { show_error( ERR_DOMAIN_REQD, 2802 ); return(-1); } memset(Alias, 0, sizeof(Alias)); memset(Domain, 0, sizeof(Domain)); memset(Email, 0, sizeof(Email)); snprintf(Email, sizeof(Email), "%s", domain); if (parse_email(Email, Alias, Domain, sizeof(Alias)) != 0) { show_error( ERR_INVALID_EMAIL, 2803 ); return(-1); } /* not system administrator and domain administrator - must be in their own domain */ if (!(AuthVpw.pw_gid & SA_ADMIN) && (AuthVpw.pw_gid & QA_ADMIN)) { /* if not their domain, reject */ if ( strcmp(TheDomain,domain)!= 0 ) { show_error( ERR_NOT_AUTH_DOMAIN, 2804 ); return(-1); } /* not system admin so kick them out */ } else if ( !(AuthVpw.pw_gid&SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 2805 ); return(-1); } /* print all aliases */ if (strstr(Email, "@") == NULL) { tmpalias = valias_select_all(Alias, Email); snprintf(WriteBuf, sizeof(WriteBuf), RET_OK_MORE); wait_write(); while (tmpalias != NULL) { snprintf(WriteBuf, sizeof(WriteBuf), "%s@%s %s" RET_CRLF, Alias, Email, tmpalias); wait_write(); tmpalias = valias_select_all_next(Alias); } /* print a single email address */ } else { tmpalias = valias_select(Alias, Domain); if (tmpalias == NULL) { snprintf(WriteBuf, sizeof(WriteBuf), RET_OK); } else { snprintf(WriteBuf, sizeof(WriteBuf), RET_OK_MORE); wait_write(); while (tmpalias != NULL) { snprintf(WriteBuf, sizeof(WriteBuf), "%s@%s %s" RET_CRLF, Alias, Domain, tmpalias); wait_write(); tmpalias = valias_select_next(Alias); } } } snprintf(WriteBuf,sizeof(WriteBuf), "." RET_CRLF); return(0); } int list_lists() { static char thedir[256]; char *domain; char *tmpstr; int page = 0; int lines_per_page = 0; int count; int start; int end; int i,j; struct dirent **namelist; struct dirent *mydirent; FILE *fs; static char tmpbuf[1024]; if ( !(AuthVpw.pw_gid & QA_ADMIN) && !(AuthVpw.pw_gid & SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 2901 ); return(-1); } if ((domain=strtok(NULL,TOKENS))==NULL) { show_error( ERR_EMAIL_REQD, 2902 ); return(-1); } if ( !(AuthVpw.pw_gid&SA_ADMIN) && (AuthVpw.pw_gid&QA_ADMIN) && (strcmp(TheDomain,domain))!=0 ) { show_error( ERR_NOT_AUTH_DOMAIN, 2903 ); return(-1); } if ( (vget_assign(domain,thedir,sizeof(thedir),NULL,NULL)) == NULL ) { show_error( ERR_NOT_AUTH_DOMAIN, 2904 ); return(-1); } if ((tmpstr=strtok(NULL,TOKENS))!=NULL) { page = atoi(tmpstr); if ( page < 0 ) page = 0; if ((tmpstr=strtok(NULL,TOKENS))!=NULL) { lines_per_page = atoi(tmpstr); if ( lines_per_page < 0 ) lines_per_page = 0; } } if ( page > 0 && lines_per_page > 0 ) { start = (page-1) * lines_per_page; end = page * lines_per_page; } else { start = 0; end = 0; } if ( chdir(thedir) < 0 ) { snprintf(WriteBuf,sizeof(WriteBuf),RET_ERR "0.2905 %s" RET_CRLF, strerror(errno)); return(-1); } snprintf(WriteBuf, sizeof(WriteBuf), RET_OK_MORE); wait_write(); j = bkscandir(".", &namelist, 0, qa_sort); count = 0; for(i=0;id_name,7)!= 0 ) continue; if ( (fs=fopen(mydirent->d_name,"r"))==NULL ) continue; fgets(tmpbuf,sizeof(tmpbuf),fs); fclose(fs); if ( strstr(tmpbuf, "ezmlm-reject") == 0 ) continue; if ( end>0 ) { if ( count>=start && countd_name); wait_write(); } else if ( count>=end ) { break; } } else { snprintf(WriteBuf,sizeof(WriteBuf), "%s" RET_CRLF, mydirent->d_name); wait_write(); } ++count; } snprintf(WriteBuf,sizeof(WriteBuf), "." RET_CRLF); return(0); } int get_ip_map() { #ifdef IP_ALIAS_DOMAINS char *ip; static char tmpdomain[256]; if ( !(AuthVpw.pw_gid & SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 3001 ); return(-1); } if ((ip=strtok(NULL,TOKENS))==NULL) { show_error( ERR_IP_REQUIRED, 3002 ); return(-1); } if ( vget_ip_map(ip,tmpdomain,sizeof(tmpdomain)) < 0 ) { snprintf(WriteBuf,sizeof(WriteBuf), RET_ERR "0.3003 error" RET_CRLF); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf),RET_OK_MORE); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf),"%s %s" RET_CRLF, ip, tmpdomain); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "." RET_CRLF); #else show_error( ERR_NOT_AVAIL, 3004 ); #endif return(0); } int add_ip_map() { #ifdef IP_ALIAS_DOMAINS char *ip; char *domain; if ( !(AuthVpw.pw_gid & SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 3101 ); return(-1); } if ((ip=strtok(NULL,TOKENS))==NULL) { show_error( ERR_IP_REQD, 3102 ); return(-1); } if ((domain=strtok(NULL,TOKENS))==NULL) { show_error( ERR_DOMAIN_REQD, 3103 ); return(-1); } if ( vget_assign(domain, NULL,0,NULL,NULL) == NULL ) { show_error( ERR_INVALID_DOMAIN, 3104 ); return(-1); } if ( vadd_ip_map(ip,domain) < 0 ) { snprintf(WriteBuf,sizeof(WriteBuf), RET_ERR "0.3105 error" RET_CRLF); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf),RET_OK); #else show_error( ERR_NOT_AVAIL, 3106 ); #endif return(0); } int del_ip_map() { #ifdef IP_ALIAS_DOMAINS char *ip; char *domain; if ( !(AuthVpw.pw_gid & SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 3201 ); return(-1); } if ((ip=strtok(NULL,TOKENS))==NULL) { show_error( ERR_IP_REQUIRED, 3202 ); return(-1); } if ((domain=strtok(NULL,TOKENS))==NULL) { show_error( ERR_DOMAIN_REQD, 3203 ); return(-1); } if ( vdel_ip_map(ip,domain) < 0 ) { snprintf(WriteBuf,sizeof(WriteBuf), RET_ERR "0.3204 error" RET_CRLF); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf),RET_OK); #else show_error( ERR_NOT_AVAIL, 3205 ); #endif return(0); } int show_ip_map() { #ifdef IP_ALIAS_DOMAINS int first; static char r_ip[256]; static char r_domain[256]; if ( !(AuthVpw.pw_gid & SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 3301 ); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK_MORE); wait_write(); first = 1; while( vshow_ip_map(first,r_ip,r_domain) > 0 ) { first = 0; snprintf(WriteBuf, sizeof(WriteBuf), "%s %s" RET_CRLF, r_ip, r_domain); wait_write(); } snprintf(WriteBuf,sizeof(WriteBuf), "." RET_CRLF); #else show_error( ERR_NOT_AVAIL, 3302 ); #endif return(0); } int get_limits() { char *domain; int ret; struct vlimits mylimits; if ( !(AuthVpw.pw_gid & SA_ADMIN) ) { show_error( ERR_NOT_AUTHORIZED, 3401 ); return(-1); } if ((domain=strtok(NULL,TOKENS))==NULL) { show_error( ERR_DOMAIN_REQD, 3402 ); return(-1); } if ((ret=vget_limits(domain,&mylimits))!=0){ show_error( ERR_NO_GET_LIMITS, 3403 ); return(-1); } snprintf(WriteBuf,sizeof(WriteBuf), RET_OK_MORE); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "max_popaccounts %d" RET_CRLF, mylimits.maxpopaccounts); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "max_aliases %d" RET_CRLF, mylimits.maxaliases); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "max_forwards %d" RET_CRLF, mylimits.maxforwards); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "max_autoresponders %d" RET_CRLF, mylimits.maxautoresponders); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "max_mailinglists %d" RET_CRLF, mylimits.maxmailinglists); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "disk_quota %d" RET_CRLF, mylimits.diskquota); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "max_msgcount %d" RET_CRLF, mylimits.maxmsgcount); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "default_quota %d" RET_CRLF, mylimits.defaultquota); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "default_maxmsgcount %d" RET_CRLF, mylimits.defaultmaxmsgcount); wait_write(); if (mylimits.disable_pop) snprintf(WriteBuf,sizeof(WriteBuf), "disable_pop 1" RET_CRLF); else snprintf(WriteBuf,sizeof(WriteBuf), "disable_pop 0" RET_CRLF); wait_write(); if (mylimits.disable_imap) snprintf(WriteBuf,sizeof(WriteBuf), "disable_imap 1" RET_CRLF); else snprintf(WriteBuf,sizeof(WriteBuf), "disable_imap 0" RET_CRLF); wait_write(); if (mylimits.disable_dialup) snprintf(WriteBuf,sizeof(WriteBuf), "disable_dialup 1" RET_CRLF); else snprintf(WriteBuf,sizeof(WriteBuf), "disable_dialup 0" RET_CRLF); wait_write(); if (mylimits.disable_passwordchanging) snprintf(WriteBuf,sizeof(WriteBuf), "disable_password_changing 1" RET_CRLF); else snprintf(WriteBuf,sizeof(WriteBuf), "disable_password_changing 0" RET_CRLF); wait_write(); if (mylimits.disable_webmail) snprintf(WriteBuf,sizeof(WriteBuf), "disable_webmail 1" RET_CRLF); else snprintf(WriteBuf,sizeof(WriteBuf), "disable_webmail 0" RET_CRLF); wait_write(); if (mylimits.disable_relay) snprintf(WriteBuf,sizeof(WriteBuf), "disable_external_relay 1" RET_CRLF); else snprintf(WriteBuf,sizeof(WriteBuf), "disable_external_relay 0" RET_CRLF); wait_write(); if (mylimits.disable_smtp) snprintf(WriteBuf,sizeof(WriteBuf), "disable_smtp 1" RET_CRLF); else snprintf(WriteBuf,sizeof(WriteBuf), "disable_smtp 0" RET_CRLF); wait_write(); if (mylimits.disable_spamassassin) snprintf(WriteBuf,sizeof(WriteBuf), "disable_spamassassin 1" RET_CRLF); else snprintf(WriteBuf,sizeof(WriteBuf), "disable_spamassassin 0" RET_CRLF); wait_write(); if (mylimits.delete_spam) snprintf(WriteBuf,sizeof(WriteBuf), "delete_spam 1" RET_CRLF); else snprintf(WriteBuf,sizeof(WriteBuf), "delete_spam 0" RET_CRLF); wait_write(); if (mylimits.disable_maildrop) snprintf(WriteBuf,sizeof(WriteBuf), "disable_maildrop 1" RET_CRLF); else snprintf(WriteBuf,sizeof(WriteBuf), "disable_maildrop 0" RET_CRLF); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "perm_account %d" RET_CRLF, mylimits.perm_account); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "perm_alias %d" RET_CRLF, mylimits.perm_alias); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "perm_forward %d" RET_CRLF, mylimits.perm_forward); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "perm_autoresponder %d" RET_CRLF, mylimits.perm_autoresponder); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "perm_maillist %d" RET_CRLF, mylimits.perm_maillist); wait_write(); snprintf(WriteBuf,sizeof(WriteBuf), "perm_quota %d" RET_CRLF, (mylimits.perm_quota) | (mylimits.perm_maillist_users<pw_dir, &bytes, &cnt)) != 0) { snprintf(WriteBuf, sizeof(WriteBuf), RET_ERR "3806 unable to fetch size of user account" RET_CRLF); return(-1); } snprintf(WriteBuf, sizeof(WriteBuf), RET_OK_MORE); wait_write(); snprintf(WriteBuf, sizeof(WriteBuf), "size %ld" RET_CRLF, bytes); wait_write(); snprintf(WriteBuf, sizeof(WriteBuf), "count %d" RET_CRLF, cnt); wait_write(); snprintf(WriteBuf, sizeof(WriteBuf), "." RET_CRLF); return(0); } int get_domain_size() { char *domain, tmpdir[256]; int ret, cnt, first; long bytes; unsigned int totalcnt; unsigned long long totalbytes; if (!(AuthVpw.pw_gid & QA_ADMIN) && !(AuthVpw.pw_gid & SA_ADMIN)) { snprintf(WriteBuf, sizeof(WriteBuf), RET_ERR "3901 not authorized" RET_CRLF); return(-1); } if ((domain = strtok(NULL, TOKENS)) == NULL) { snprintf(WriteBuf, sizeof(WriteBuf), RET_ERR "3902 domain required" RET_CRLF); return(-1); } if (!(AuthVpw.pw_gid & SA_ADMIN) && (AuthVpw.pw_gid & QA_ADMIN) && (strcmp(TheDomain, domain) != 0)) { snprintf(WriteBuf, sizeof(WriteBuf), RET_ERR "3903 not authorized for domain" RET_CRLF); return(-1); } snprintf(WriteBuf, sizeof(WriteBuf), RET_OK_MORE); wait_write(); totalbytes = 0; totalcnt = 0; first = 1; while ((tmpvpw = vauth_getall(domain, first, 0)) != NULL) { first = 0; bytes = 0; cnt = 0; snprintf(tmpdir, sizeof(tmpdir), "%s/Maildir", tmpvpw->pw_dir); if ((ret = readuserquota(tmpdir, &bytes, &cnt)) != 0) { snprintf(WriteBuf, sizeof(WriteBuf), RET_ERR "3904 unable to fetch size of user accounts '%s'" RET_CRLF, tmpvpw->pw_name); return(-1); } else { snprintf(WriteBuf, sizeof(WriteBuf), "user %s@%s" RET_CRLF, tmpvpw->pw_name, domain); wait_write(); snprintf(WriteBuf, sizeof(WriteBuf), "size %ld" RET_CRLF, bytes); wait_write(); snprintf(WriteBuf, sizeof(WriteBuf), "count %d" RET_CRLF, cnt); wait_write(); totalbytes += (unsigned long)bytes; totalcnt += (unsigned int)cnt; } } snprintf(WriteBuf, sizeof(WriteBuf), "domain %s" RET_CRLF, domain); wait_write(); snprintf(WriteBuf, sizeof(WriteBuf), "size %llu" RET_CRLF, totalbytes); wait_write(); snprintf(WriteBuf, sizeof(WriteBuf), "count %u" RET_CRLF, totalcnt); wait_write(); snprintf(WriteBuf, sizeof(WriteBuf), "." RET_CRLF); return(0); } int quit() { snprintf(WriteBuf,sizeof(WriteBuf), RET_OK); wait_write(); vclose(); exit(0); } int login_help() { int i; snprintf(WriteBuf,sizeof(WriteBuf), RET_OK_MORE); wait_write(); for(i=0;LoginFunctions[i].command!=NULL;++i ) { if( NULL == LoginFunctions[i].help ) { snprintf(WriteBuf, sizeof(WriteBuf), RET_CRLF "%s" RET_CRLF, LoginFunctions[i].command ); } else { snprintf(WriteBuf, sizeof(WriteBuf), "%s %s" RET_CRLF, LoginFunctions[i].command, LoginFunctions[i].help ); } wait_write(); } snprintf(WriteBuf,sizeof(WriteBuf), "." RET_CRLF); return(1); } int help() { int i; snprintf(WriteBuf,sizeof(WriteBuf), RET_OK_MORE); wait_write(); for(i=0;Functions[i].command!=NULL;++i ) { if( logged_in >= Functions[i].level ) { if( NULL == Functions[i].help ) { snprintf(WriteBuf, sizeof(WriteBuf), RET_CRLF "%s" RET_CRLF, Functions[i].command ); } else { snprintf(WriteBuf, sizeof(WriteBuf), "%s %s" RET_CRLF, Functions[i].command, Functions[i].help ); } wait_write(); } } snprintf(WriteBuf,sizeof(WriteBuf), "." RET_CRLF); return(1); } int bkscandir(const char *dirname, struct dirent ***namelist, int (*select)(struct dirent *), int (*compar)(const void *, const void *)) { int i; int entries; int esize; struct dirent* dp; struct dirent* dent; DIR * dirp; *namelist = NULL; entries = esize = 0; /* load the names */ if ((dirp = opendir(dirname)) == NULL) return -1; while ((dp = readdir(dirp)) != NULL) { if (select == NULL || (*select)(dp)) { if (entries >= esize) { void* mem; esize += 10; if ((mem = realloc(*namelist, esize * sizeof(struct dirent*)))==NULL) { for (i = 0; i < entries; i++) free((*namelist)[i]); free(*namelist); closedir(dirp); return -1; } *namelist = (struct dirent**)mem; } if ((dent = (struct dirent*)malloc(sizeof(struct dirent)+MAX_FILE_NAME)) == NULL) { for (i = 0; i < entries; i++) free((*namelist)[i]); free(*namelist); closedir(dirp); return -1; } memcpy(dent, dp, sizeof(*dp)+MAX_FILE_NAME); (*namelist)[entries] = dent; entries++; } } closedir(dirp); /* sort them */ if (compar) qsort((void*)*namelist, entries, sizeof(struct dirent*), compar); return entries; } int qa_sort(const void * a, const void * b) { return strcasecmp ((*(const struct dirent **) a)->d_name, (*(const struct dirent **) b)->d_name); }