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>
