Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 Feb 2002 12:40:04 -0800 (PST)
From:      Fernando Schapachnik <fschapachnik@vianetworks.com.ar>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: bin/23944: Patch for ftpd to add a cd after the chroot.
Message-ID:  <200202122040.g1CKe4q04980@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/23944; it has been noted by GNATS.

From: Fernando Schapachnik <fschapachnik@vianetworks.com.ar>
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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200202122040.g1CKe4q04980>