From owner-freebsd-bugs Tue Feb 12 12:41:22 2002 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 5784637B47F for ; Tue, 12 Feb 2002 12:40:07 -0800 (PST) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.6/8.11.6) id g1CKe4q04980; Tue, 12 Feb 2002 12:40:04 -0800 (PST) (envelope-from gnats) Date: Tue, 12 Feb 2002 12:40:04 -0800 (PST) Message-Id: <200202122040.g1CKe4q04980@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: Fernando Schapachnik Subject: Re: bin/23944: Patch for ftpd to add a cd after the chroot. Reply-To: Fernando Schapachnik Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org The following reply was made to PR bin/23944; it has been noted by GNATS. From: Fernando Schapachnik To: freebsd-gnats-submit@FreeBSD.org Cc: Subject: Re: bin/23944: Patch for ftpd to add a cd after the chroot. Date: Tue, 12 Feb 2002 17:08:05 -0300 --0F1p//8PRICkK4MW Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit Hi, Here it is an updated version of the patch against 4.5-RELEASE. I'd like to see it come into the main tree. Regards. Fernando P. Schapachnik Gerente de tecnología de red y sistemas de información VIA NET.WORKS ARGENTINA S.A. fschapachnik@vianetworks.com.ar Tel.: (54-11) 4323-3381 --0F1p//8PRICkK4MW Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="ftpd.patch-4.5" --- ftpd.c.orig Tue Dec 18 15:35:55 2001 +++ ftpd.c Tue Feb 12 16:51:22 2002 @@ -140,6 +140,7 @@ int anon_only = 0; /* Only anonymous ftp allowed */ int guest; int dochroot; +char *cd_dir= NULL, *chroot_dir= NULL; int stats; int statfd = -1; int type; @@ -191,6 +192,9 @@ char *pid_file = NULL; +/* WARNING: FTP_CHROOT_SEPARATOR *MUST* end in / */ +#define FTP_CHROOT_SEPARATOR "/./" + /* * Limit number of pathnames that glob can return. * A limit of 0 indicates the number of pathnames is unlimited. @@ -261,6 +265,7 @@ static char *sgetsave __P((char *)); static void reapchild __P((int)); static void logxfer __P((char *, long, long)); +static void get_chroot_and_cd_dirs __P((char *, char **, char **)); static char * curdir() @@ -1056,6 +1061,14 @@ logged_in = 0; guest = 0; dochroot = 0; + if (chroot_dir!=NULL) { + free(chroot_dir); + chroot_dir= NULL; + } + if (cd_dir!=NULL) { + free(cd_dir); + cd_dir= NULL; + } } #if !defined(NOPAM) @@ -1320,7 +1333,8 @@ goto bad; } } else if (dochroot) { - if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) { + get_chroot_and_cd_dirs(pw->pw_dir, &chroot_dir, &cd_dir); + if (chroot(chroot_dir) < 0 || chdir(cd_dir) < 0) { reply(550, "Can't change root."); goto bad; } @@ -2841,5 +2855,53 @@ ctime(&now)+4, ident, remotehost, path, name, size, now - start + (now == start)); write(statfd, buf, strlen(buf)); + } +} + +/* + * Make a pointer to the chroot dir and another to the cd dir. + * The first is all the path up to the first FTP_CHROOT_SEPARATOR. + * The later is the remaining chars, not including the FTP_CHROOT_SEPARATOR, + * but prepending a '/', if FTP_CHROOT_SEPARATOR is found. + * Otherwise, return user_home_dir as chroot_dir and "/" as cd_dir. + */ +static void +get_chroot_and_cd_dirs(user_home_dir, chroot_dir, cd_dir) + char *user_home_dir; + char **chroot_dir; + char **cd_dir; +{ + char *p; + int len= strlen(user_home_dir); + + /* Make a pointer to first character of string FTP_CHROOT_SEPARATOR + inside user_home_dir. */ + p = (char *) strstr(user_home_dir, FTP_CHROOT_SEPARATOR); + if (p == NULL) { + /* + * There is not FTP_CHROOT_SEPARATOR string inside + * user_home_dir. Return user_home_dir as chroot_dir, + * and "/" as cd_dir. + */ + if ((*chroot_dir = (char *) strdup(user_home_dir)) == NULL) + fatal("Ran out of memory."); + if ((*cd_dir = (char *) strdup("/")) == NULL) + fatal("Ran out of memory."); + } else { + /* + * Use strlen(user_home_dir) as maximun length for + * both cd_dir and chroot_dir, as both are substrings of + * user_home_dir. + */ + if ((*chroot_dir = malloc(len)) == NULL) + fatal("Ran out of memory."); + if ((*cd_dir = malloc(len)) == NULL) + fatal("Ran out of memory."); + (void) strncpy(*chroot_dir, user_home_dir, len-strlen(p)); + *(*chroot_dir+(len-strlen(p)))= '\0'; + /* Skip FTP_CHROOT_SEPARATOR (except the last /). */ + p += strlen(FTP_CHROOT_SEPARATOR)-1; + (void) strncpy(*cd_dir, p, strlen(p)); + *(*cd_dir+strlen(p))= '\0'; } } --- ftpd.8.orig Tue Dec 18 15:35:55 2001 +++ ftpd.8 Tue Feb 12 16:51:22 2002 @@ -321,13 +321,14 @@ or the user is a member of a group with a group entry in this file, i.e. one prefixed with .Ql \&@ , -the session's root will be changed to the user's login directory by +the session's root will be changed to the user's login directory (up to the first /./) by .Xr chroot 2 as for an .Dq anonymous or .Dq ftp account (see next item). +The user is placed into the directory that remainds after stripping the former from the user's login directory. This facility may also be triggered by enabling the boolean "ftp-chroot" capability in .Xr login.conf 5 . --- ftpcmd.y.orig Tue Feb 12 16:59:03 2002 +++ ftpcmd.y Tue Feb 12 17:00:30 2002 @@ -94,6 +94,8 @@ extern int noepsv; extern int noretr; extern int noguestretr; +extern int dochroot; +extern char *cd_dir, *chroot_dir; off_t restart_point; @@ -525,7 +527,9 @@ if ($2) { if (guest) cwd("/"); - else + else if (dochroot) { + cwd(cd_dir); + } else cwd(pw->pw_dir); } } --0F1p//8PRICkK4MW-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message