View | Details | Raw Unified | Return to bug 23944
Collapse All | Expand All

(-)ftpd.c (-1 / +53 lines)
Lines 185-190 Link Here
185
185
186
char	*pid_file = NULL;
186
char	*pid_file = NULL;
187
187
188
/* WARNING: FTP_CHROOT_SEPARATOR *MUST* end in / */
189
#define FTP_CHROOT_SEPARATOR	"/./"
190
188
/*
191
/*
189
 * Timeout intervals for retrying connections
192
 * Timeout intervals for retrying connections
190
 * to hosts that don't accept PORT cmds.  This
193
 * to hosts that don't accept PORT cmds.  This
Lines 248-253 Link Here
248
static char	*sgetsave __P((char *));
251
static char	*sgetsave __P((char *));
249
static void	 reapchild __P((int));
252
static void	 reapchild __P((int));
250
static void      logxfer __P((char *, long, long));
253
static void      logxfer __P((char *, long, long));
254
static void      get_chroot_and_cd_dirs __P((char *, char **, char **));
251
255
252
static char *
256
static char *
253
curdir()
257
curdir()
Lines 1168-1173 Link Here
1168
{
1172
{
1169
	int rval;
1173
	int rval;
1170
	FILE *fd;
1174
	FILE *fd;
1175
	char *cd_dir, *chroot_dir;
1171
#ifdef	LOGIN_CAP
1176
#ifdef	LOGIN_CAP
1172
	login_cap_t *lc = NULL;
1177
	login_cap_t *lc = NULL;
1173
#endif
1178
#endif
Lines 1291-1300 Link Here
1291
			goto bad;
1296
			goto bad;
1292
		}
1297
		}
1293
	} else if (dochroot) {
1298
	} else if (dochroot) {
1294
		if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) {
1299
		get_chroot_and_cd_dirs(pw->pw_dir, &chroot_dir, &cd_dir);
1300
		if (chroot(chroot_dir) < 0 || chdir(cd_dir) < 0) {
1301
			free(chroot_dir);
1302
			free(cd_dir);
1295
			reply(550, "Can't change root.");
1303
			reply(550, "Can't change root.");
1296
			goto bad;
1304
			goto bad;
1297
		}
1305
		}
1306
		free(chroot_dir);
1307
		free(cd_dir);
1298
	} else if (chdir(pw->pw_dir) < 0) {
1308
	} else if (chdir(pw->pw_dir) < 0) {
1299
		if (chdir("/") < 0) {
1309
		if (chdir("/") < 0) {
1300
			reply(530, "User %s: can't change directory to %s.",
1310
			reply(530, "User %s: can't change directory to %s.",
Lines 2789-2793 Link Here
2789
			ctime(&now)+4, ident, remotehost,
2799
			ctime(&now)+4, ident, remotehost,
2790
			path, name, size, now - start + (now == start));
2800
			path, name, size, now - start + (now == start));
2791
		write(statfd, buf, strlen(buf));
2801
		write(statfd, buf, strlen(buf));
2802
	}
2803
}
2804
2805
/*
2806
 * Make a pointer to the chroot dir and another to the cd dir.
2807
 * The first is all the path up to the first FTP_CHROOT_SEPARATOR.
2808
 * The later is the remaining chars, not including the FTP_CHROOT_SEPARATOR,
2809
 * but prepending a '/'.
2810
 */
2811
static void
2812
get_chroot_and_cd_dirs(user_home_dir, chroot_dir, cd_dir)
2813
	char *user_home_dir;
2814
	char **chroot_dir;
2815
	char **cd_dir;
2816
{
2817
	char *p;
2818
2819
	/* Make a pointer to first character of string FTP_CHROOT_SEPARATOR
2820
	   inside user_home_dir. */
2821
	p = (char *) strstr(user_home_dir, FTP_CHROOT_SEPARATOR);
2822
	if (p == NULL) {
2823
		 /*
2824
		  * There is not FTP_CHROOT_SEPARATOR string inside
2825
		  * user_home_dir. Return user_home_dir as chroot_dir,
2826
		  * and "/" as cd_dir.
2827
		  */
2828
		 *chroot_dir = (char *) strdup(user_home_dir);
2829
		 *cd_dir = (char *) strdup("/");
2830
	} else {
2831
		 /*
2832
		  * Use strlen(user_home_dir) as maximun length for
2833
		  * both cd_dir and chroot_dir, as both are substrings of
2834
		  * user_home_dir.
2835
		  */
2836
		 if ((*chroot_dir = malloc(strlen(user_home_dir))) == NULL)
2837
			fatal("Ran out of memory.");
2838
		 if ((*cd_dir = malloc(strlen(user_home_dir))) == NULL)
2839
			fatal("Ran out of memory.");
2840
		 (void) strncpy(*chroot_dir, user_home_dir, p-user_home_dir);
2841
		 /* Skip FTP_CHROOT_SEPARATOR (except the last /). */
2842
		 p += strlen(FTP_CHROOT_SEPARATOR)-1;
2843
		 (void) strncpy(*cd_dir, p, strlen(p));
2792
	}
2844
	}
2793
}
2845
}
(-)ftpd.8 (-1 / +2 lines)
Lines 298-310 Link Here
298
or the user is a member of a group with a group entry in this file,
298
or the user is a member of a group with a group entry in this file,
299
i.e. one prefixed with
299
i.e. one prefixed with
300
.Ql \&@ ,
300
.Ql \&@ ,
301
the session's root will be changed to the user's login directory by
301
the session's root will be changed to the user's login directory (up to the first /./) by
302
.Xr chroot 2
302
.Xr chroot 2
303
as for an
303
as for an
304
.Dq anonymous
304
.Dq anonymous
305
or
305
or
306
.Dq ftp
306
.Dq ftp
307
account (see next item).
307
account (see next item).
308
The user is placed into the directory that remainds after stripping the former from the user's login directory.
308
This facility may also be triggered by enabling the boolean "ftp-chroot"
309
This facility may also be triggered by enabling the boolean "ftp-chroot"
309
capability in
310
capability in
310
.Xr login.conf 5 .
311
.Xr login.conf 5 .

Return to bug 23944