diff -ruN vsftpd-2.0.5/main.c vsftpd-2.0.5.group/main.c --- vsftpd-2.0.5/main.c 2006-07-03 14:26:08.000000000 +0200 +++ vsftpd-2.0.5.group/main.c 2007-05-04 17:42:04.000000000 +0200 @@ -46,8 +46,8 @@ 0, 1, INIT_MYSTR, 0, 0, /* Session state */ 0, - /* Userids */ - -1, -1, -1, + /* Userids / Gids */ + -1, -1, -1, -1, -1, -1, /* Pre-chroot() cache */ INIT_MYSTR, INIT_MYSTR, INIT_MYSTR, INIT_MYSTR, 1, /* Logging */ @@ -306,6 +306,7 @@ tunable_ftp_username); } p_sess->anon_ftp_uid = vsf_sysutil_user_getuid(p_user); + p_sess->anon_ftp_gid = vsf_sysutil_user_getgid(p_user); } if (tunable_guest_enable) { @@ -317,17 +318,26 @@ tunable_guest_username); } p_sess->guest_user_uid = vsf_sysutil_user_getuid(p_user); + p_sess->guest_user_gid = vsf_sysutil_user_getgid(p_user); } if (tunable_chown_uploads) { const struct vsf_sysutil_user* p_user = vsf_sysutil_getpwnam(tunable_chown_username); + const struct vsf_sysutil_group* p_group = + vsf_sysutil_getgrnam(tunable_chown_groupname); if (p_user == 0) { die2("vsftpd: cannot locate user specified in 'chown_username':", tunable_chown_username); } + if (p_group == 0) + { + die2("vsftpd: cannot locate user specified in 'chown_groupname':", + tunable_chown_groupname); + } p_sess->anon_upload_chown_uid = vsf_sysutil_user_getuid(p_user); + p_sess->anon_upload_chown_gid = vsf_sysutil_group_getgid(p_group); } } diff -ruN vsftpd-2.0.5/parseconf.c vsftpd-2.0.5.group/parseconf.c --- vsftpd-2.0.5/parseconf.c 2007-05-04 17:33:51.000000000 +0200 +++ vsftpd-2.0.5.group/parseconf.c 2007-05-04 16:22:27.000000000 +0200 @@ -142,6 +142,7 @@ { "secure_chroot_dir", &tunable_secure_chroot_dir }, { "ftp_username", &tunable_ftp_username }, { "chown_username", &tunable_chown_username }, + { "chown_groupname", &tunable_chown_groupname }, { "xferlog_file", &tunable_xferlog_file }, { "vsftpd_log_file", &tunable_vsftpd_log_file }, { "message_file", &tunable_message_file }, diff -ruN vsftpd-2.0.5/privops.c vsftpd-2.0.5.group/privops.c --- vsftpd-2.0.5/privops.c 2007-05-04 17:33:51.000000000 +0200 +++ vsftpd-2.0.5.group/privops.c 2007-05-04 16:54:54.000000000 +0200 @@ -54,9 +54,11 @@ { static struct vsf_sysutil_statbuf* s_p_statbuf; vsf_sysutil_fstat(fd, &s_p_statbuf); - /* Do nothing if it is already owned by the desired user. */ - if (vsf_sysutil_statbuf_get_uid(s_p_statbuf) == - p_sess->anon_upload_chown_uid) + /* Do nothing if it is already owned by the desired user/group. */ + if ((vsf_sysutil_statbuf_get_uid(s_p_statbuf) == + p_sess->anon_upload_chown_uid) && + (vsf_sysutil_statbuf_get_gid(s_p_statbuf) == + p_sess->anon_upload_chown_gid)) { return; } @@ -64,9 +66,12 @@ * the the anonymous ftp user */ if (p_sess->anon_upload_chown_uid == -1 || + p_sess->anon_upload_chown_gid == -1 || !vsf_sysutil_statbuf_is_regfile(s_p_statbuf) || (vsf_sysutil_statbuf_get_uid(s_p_statbuf) != p_sess->anon_ftp_uid && - vsf_sysutil_statbuf_get_uid(s_p_statbuf) != p_sess->guest_user_uid)) + vsf_sysutil_statbuf_get_uid(s_p_statbuf) != p_sess->guest_user_uid) || + (vsf_sysutil_statbuf_get_gid(s_p_statbuf) != p_sess->anon_ftp_gid && + vsf_sysutil_statbuf_get_gid(s_p_statbuf) != p_sess->guest_user_gid)) { die("invalid fd in cmd_process_chown"); } @@ -74,7 +79,7 @@ * otherwise a compromise of the FTP user will lead to compromise of * the "anon_upload_chown_uid" user (think chmod +s). */ - vsf_sysutil_fchown(fd, p_sess->anon_upload_chown_uid, -1); + vsf_sysutil_fchown(fd, p_sess->anon_upload_chown_uid, p_sess->anon_upload_chown_gid); } enum EVSFPrivopLoginResult Les fichiers vsftpd-2.0.5/.privops.c.swp et vsftpd-2.0.5.group/.privops.c.swp sont différents. diff -ruN vsftpd-2.0.5/session.h vsftpd-2.0.5.group/session.h --- vsftpd-2.0.5/session.h 2006-07-02 02:34:48.000000000 +0200 +++ vsftpd-2.0.5.group/session.h 2007-05-04 16:54:24.000000000 +0200 @@ -48,8 +48,11 @@ /* Details of userids which are interesting to us */ int anon_ftp_uid; + int anon_ftp_gid; int guest_user_uid; + int guest_user_gid; int anon_upload_chown_uid; + int anon_upload_chown_gid; /* Things we need to cache before we chroot() */ struct mystr banned_email_str; diff -ruN vsftpd-2.0.5/sysutil.c vsftpd-2.0.5.group/sysutil.c --- vsftpd-2.0.5/sysutil.c 2007-05-04 17:33:51.000000000 +0200 +++ vsftpd-2.0.5.group/sysutil.c 2007-05-04 16:55:21.000000000 +0200 @@ -2226,6 +2226,12 @@ return (struct vsf_sysutil_user*) getpwnam(p_user); } +struct vsf_sysutil_group* +vsf_sysutil_getgrnam(const char* p_group) +{ + return (struct vsf_sysutil_group*) getgrnam(p_group); +} + const char* vsf_sysutil_user_getname(const struct vsf_sysutil_user* p_user) { @@ -2254,6 +2260,13 @@ return p_passwd->pw_gid; } +int +vsf_sysutil_group_getgid(const struct vsf_sysutil_group* p_group) +{ + const struct group* p_grp = (const struct group*) p_group; + return p_grp->gr_gid; +} + struct vsf_sysutil_group* vsf_sysutil_getgrgid(const int gid) { Les fichiers vsftpd-2.0.5/.sysutil.c.swp et vsftpd-2.0.5.group/.sysutil.c.swp sont différents. diff -ruN vsftpd-2.0.5/sysutil.h vsftpd-2.0.5.group/sysutil.h --- vsftpd-2.0.5/sysutil.h 2007-05-04 17:33:51.000000000 +0200 +++ vsftpd-2.0.5.group/sysutil.h 2007-05-04 17:02:00.000000000 +0200 @@ -283,8 +283,10 @@ const struct vsf_sysutil_user* p_user); int vsf_sysutil_user_getuid(const struct vsf_sysutil_user* p_user); int vsf_sysutil_user_getgid(const struct vsf_sysutil_user* p_user); +int vsf_sysutil_group_getgid(const struct vsf_sysutil_group* p_group); struct vsf_sysutil_group* vsf_sysutil_getgrgid(const int gid); +struct vsf_sysutil_group* vsf_sysutil_getgrnam(const char* p_group); const char* vsf_sysutil_group_getname(const struct vsf_sysutil_group* p_group); /* More random things */ diff -ruN vsftpd-2.0.5/tunables.c vsftpd-2.0.5.group/tunables.c --- vsftpd-2.0.5/tunables.c 2007-05-04 17:33:51.000000000 +0200 +++ vsftpd-2.0.5.group/tunables.c 2007-05-04 16:23:57.000000000 +0200 @@ -98,6 +98,7 @@ const char* tunable_secure_chroot_dir = "/usr/share/empty"; const char* tunable_ftp_username = "ftp"; const char* tunable_chown_username = "root"; +const char* tunable_chown_groupname = "root"; const char* tunable_xferlog_file = "/var/log/xferlog"; const char* tunable_vsftpd_log_file = "/var/log/vsftpd.log"; const char* tunable_message_file = ".message"; diff -ruN vsftpd-2.0.5/tunables.h vsftpd-2.0.5.group/tunables.h --- vsftpd-2.0.5/tunables.h 2006-07-02 01:07:00.000000000 +0200 +++ vsftpd-2.0.5.group/tunables.h 2007-05-04 16:22:38.000000000 +0200 @@ -93,6 +93,7 @@ extern const char* tunable_secure_chroot_dir; extern const char* tunable_ftp_username; extern const char* tunable_chown_username; +extern const char* tunable_chown_groupname; extern const char* tunable_xferlog_file; extern const char* tunable_vsftpd_log_file; extern const char* tunable_message_file; diff -ruN vsftpd-2.0.5/vsftpd.conf vsftpd-2.0.5.group/vsftpd.conf --- vsftpd-2.0.5/vsftpd.conf 2007-05-04 17:33:57.000000000 +0200 +++ vsftpd-2.0.5.group/vsftpd.conf 2007-05-04 16:24:21.000000000 +0200 @@ -45,6 +45,7 @@ # recommended! #chown_uploads=YES #chown_username=whoever +#chown_groupname=whoever # # You may override where the log file goes if you like. The default is shown # below. diff -ruN vsftpd-2.0.5/vsftpd.conf.5 vsftpd-2.0.5.group/vsftpd.conf.5 --- vsftpd-2.0.5/vsftpd.conf.5 2007-05-04 17:33:51.000000000 +0200 +++ vsftpd-2.0.5.group/vsftpd.conf.5 2007-05-04 16:23:06.000000000 +0200 @@ -710,6 +710,14 @@ Default: root .TP +.B chown_groupname +This is the name of the group who is given ownership of anonymously uploaded +files. This option is only relevant if another option, +.BR chown_uploads , +is set. + +Default: root +.TP .B chroot_list_file The option is the name of a file containing a list of local users which will be placed in a chroot() jail in their home directory. This option is