--- vchkpw.c.orig Thu Feb 5 16:18:03 2004 +++ vchkpw.c Thu Feb 5 16:18:26 2004 @@ -226,7 +226,7 @@ */ if (ConnType != SMTP_CONN && chdir(pw_dir) == -1) { if ( vpw!=NULL) { - if ( vmake_maildir(TheDomain, vpw->pw_dir )!= VA_SUCCESS ) { + if ( vmake_maildir(TheDomain, vpw->pw_dir, 0 )!= VA_SUCCESS ) { snprintf(LogLine, sizeof(LogLine), "%s: autocreate dir errno %d %s %s@%s:%s", VchkpwLogName, errno, pw_dir, TheUser, TheDomain, IpAddr); --- vdelivermail.c.orig Thu Feb 5 16:18:50 2004 +++ vdelivermail.c Thu Feb 5 16:22:50 2004 @@ -52,6 +52,7 @@ struct vqpasswd *vpw; off_t message_size = 0; char bounce[AUTH_SIZE]; +char folder[AUTH_SIZE]; int CurrentQuotaSizeFd; #ifdef QMAIL_EXT @@ -170,14 +171,21 @@ char *tmpstr; int i; - if (argc != 3) { - printf("vdelivermail: invalid syntax in .qmail-default file\n"); + if (argc == 4) { + /* has folder parameter */ + strncpy(folder, argv[3], sizeof(folder)); + } else { + *folder = NULL; + + if (argc != 3) { + printf("vdelivermail: invalid syntax in .qmail-default file\n"); - /* exit with temporary error */ - vexit(111); + /* exit with temporary error */ + vexit(111); + } } - /* get the last parameter in the .qmail-default file */ + /* get third parameter in the .qmail-default file */ strncpy(bounce, argv[2], sizeof(bounce)); if ((tmpstr=getenv("EXT")) == NULL ) { @@ -209,6 +217,7 @@ if ( is_username_valid(TheUser) != 0 ) vexit(100); if ( is_domain_valid(TheDomain) != 0 ) vexit(100); + if ( is_folder_valid(folder) != 0 ) vexit(100); strncpy(TheUserFull, TheUser, AUTH_SIZE); #ifdef QMAIL_EXT @@ -443,6 +452,7 @@ int inject = 0; FILE *fs; char tmp_file[256]; + struct stat mystatbuf; /* This is a comment, ignore it */ if ( *address == '#' ) return(0); @@ -531,6 +541,24 @@ } #endif + /* folder delivery */ + if ( *folder != NULL ) { + /* foldernames start with '.', so if not specified we have to add it */ + if ( *folder == 46 ) { + snprintf(TheDir, AUTH_SIZE, "%s%s/", TheDir, folder); + } else { + snprintf(TheDir, AUTH_SIZE, "%s.%s/", TheDir, folder); + } + + /* check if the directory exists and create if needed */ + if ( stat(address, &mystatbuf ) == -1 ) { + if ( vmake_maildir(TheDomain, address, 1 )!= VA_SUCCESS ) { + printf("Auto re-creation of folder failed. vpopmail (#5.9.9)\n"); + vexit(100); + } + } + } + /* Format the email file name */ gethostname(hostname,sizeof(hostname)); pid=getpid(); @@ -988,7 +1016,7 @@ /* check if the directory exists and create if needed */ if ( stat(vpw->pw_dir, &mystatbuf ) == -1 ) { - if ( vmake_maildir(TheDomain, vpw->pw_dir )!= VA_SUCCESS ) { + if ( vmake_maildir(TheDomain, vpw->pw_dir, 0 )!= VA_SUCCESS ) { printf("Auto re-creation of maildir failed. vpopmail (#5.9.9)\n"); vexit(100); } --- vpopmail.c.orig Thu Feb 5 16:18:56 2004 +++ vpopmail.c Thu Feb 5 16:25:58 2004 @@ -2330,7 +2330,7 @@ * vmake_maildir(TheDomain, vpw->pw_dir) */ -int vmake_maildir(char *domain, char *dir ) +int vmake_maildir(char *domain, char *dir, char folder ) { char tmpbuf[MAX_BUFF]; char calling_dir[MAX_BUFF]; @@ -2379,6 +2379,10 @@ /* now create the Maildir */ if (mkdir("Maildir",VPOPMAIL_DIR_MODE) == -1) { chdir(calling_dir); return(-1); } if (chdir("Maildir") == -1) { chdir(calling_dir); return(-1); } + if (folder == 0) { + if (mkdir("Maildir",VPOPMAIL_DIR_MODE) == -1) return(-1); + if (chdir("Maildir") == -1) return(-1); + } if (mkdir("cur",VPOPMAIL_DIR_MODE) == -1) { chdir(calling_dir); return(-1); } if (mkdir("new",VPOPMAIL_DIR_MODE) == -1) { chdir(calling_dir); return(-1); } if (mkdir("tmp",VPOPMAIL_DIR_MODE) == -1) { chdir(calling_dir); return(-1); } @@ -2894,6 +2898,29 @@ ++user; } else { return(VA_ILLEGAL_USERNAME); + } + } + return(0); +} + +int is_folder_valid( char *folder ) +{ + while(*folder != 0) { + /* at this stage, allowed chars are: + ' ', '&' (for extended chars) + '-', '.' + '@', '0'-'9' + 'A'-'Z', 'a'-'z' + maybe more have to been allowed + */ + if ( (*folder == 32) || (*folder == 38) || + (*folder == 45) || (*folder == 46) || + (*folder >= 48 && *folder <= 57) || + (*folder >= 64 && *folder <= 90) || + (*folder >= 97 && *folder <= 122) ) { + ++folder; + } else { + return(VA_INVALID_FOLDER_NAME); } } return(0); --- vpopmail.h.orig Thu Feb 5 16:18:59 2004 +++ vpopmail.h Thu Feb 5 16:26:54 2004 @@ -82,6 +82,7 @@ #define VA_INVALID_EMAIL_CHAR -34 #define VA_PARSE_ERROR -35 #define VA_CANNOT_READ_LIMITS -36 +#define VA_INVALID_FOLDER_NAME -99 /* gid flags */ #define NO_PASSWD_CHNG 0x01 @@ -148,7 +149,7 @@ int vget_real_domain(char *domain, int len ); char *vget_assign(char *domain, char *dir, int dir_len, uid_t *uid, gid_t *gid); struct vqpasswd *vauth_user(char *user, char *domain, char *password, char *apop); -int vmake_maildir(char *domain, char *dir); +int vmake_maildir(char *domain, char *dir, char folder); int vsqwebmail_pass( char *dir, char *crypted, uid_t uid, gid_t gid ); int open_smtp_relay(); unsigned long tcprules_open(); @@ -163,6 +164,7 @@ int vvalidchar( char inchar ); int is_username_valid( char *user ); int is_domain_valid( char *domain ); +int is_folder_valid( char *folder ); int vaddaliasdomain( char *alias_domain, char *real_domain); char *format_maildirquota(const char *q); char *date_header();