--- vchkpw.c.orig Tue Sep 30 05:33:51 2003 +++ vchkpw.c Tue Sep 30 05:33:10 2003 @@ -151,7 +151,7 @@ /* Change to the users Maildir directory */ if (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, LOG_LINE_SIZE, "vchkpw: autocreate dir errno %d %s %s@%s:%s", errno, pw_dir, TheUser, TheDomain, IpAddr); --- vdelivermail.c.orig Tue Sep 30 04:38:11 2003 +++ vdelivermail.c Tue Sep 30 05:33:35 2003 @@ -51,6 +51,7 @@ struct vqpasswd *vpw; off_t message_size = 0; char bounce[AUTH_SIZE]; +char folder[AUTH_SIZE]; int CurrentQuotaSizeFd; #ifdef QMAIL_EXT @@ -162,14 +163,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; - /* exit with temporary error */ - vexit(111); + if (argc != 3) { + printf("vdelivermail: invalid syntax in .qmail-default file\n"); + + /* 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 ) { @@ -201,6 +209,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 @@ -398,6 +407,7 @@ int inject = 0; FILE *fs; char tmp_file[256]; + struct stat mystatbuf; /* check if the email is looping to this user */ if ( is_looping( address ) == 1 ) { @@ -444,6 +454,24 @@ } } + /* 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(); @@ -891,7 +919,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 Tue Sep 30 04:38:23 2003 +++ vpopmail.c Tue Sep 30 05:32:29 2003 @@ -2006,7 +2006,7 @@ return(0); } -int vmake_maildir(char *domain, char *dir ) +int vmake_maildir(char *domain, char *dir, char folder ) { char tmpbuf[156]; char tmpbuf2[156]; @@ -2039,8 +2039,10 @@ /* create the Maildir */ if ( chdir(dir) != 0 ) return(-1); - if (mkdir("Maildir",VPOPMAIL_DIR_MODE) == -1) return(-1); - if (chdir("Maildir") == -1) 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) return(-1); if (mkdir("new",VPOPMAIL_DIR_MODE) == -1) return(-1); if (mkdir("tmp",VPOPMAIL_DIR_MODE) == -1) return(-1); @@ -2381,6 +2383,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 Tue Sep 30 04:38:27 2003 +++ vpopmail.h Tue Sep 30 05:38:45 2003 @@ -80,7 +80,7 @@ #define VA_ALIAS_LINE_TOO_LONG -32 #define VA_NULL_POINTER -33 #define VA_INVALID_EMAIL_CHAR -34 - +#define VA_INVALID_FOLDER_NAME -35 /* gid flags */ #define NO_PASSWD_CHNG 0x01 @@ -144,7 +144,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(); @@ -158,6 +158,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); #ifdef APOP