Original patch by Ricardo Cerqueira Updated by James Dennis for openssh-3.4 A patch to cause sshd to chroot when it encounters the magic token '/./' in a users home directory. The directory portion before the token is the directory to chroot() to, the portion after the token is the user's home directory relative to the new root. Patch source using: patch -p0 < /path/to/patch ================================================================================ diff -uNr openssh-3.4p1/session.c openssh-3.4p1-chroot/session.c --- openssh-3.4p1/session.c Wed Jun 26 08:51:06 2002 +++ openssh-3.4p1-chroot/session.c Sat Jun 29 03:42:24 2002 @@ -58,6 +58,8 @@ #include "session.h" #include "monitor_wrap.h" +#define CHROOT + #ifdef HAVE_CYGWIN #include #include @@ -1157,7 +1159,11 @@ /* Set login name, uid, gid, and groups. */ void +#ifdef CHROOT +do_setusercontext(struct passwd *pw, char *user_dir, char *new_root, int dochroot) +#else do_setusercontext(struct passwd *pw) +#endif { char tty='\0'; @@ -1197,6 +1203,27 @@ exit(1); } endgrent(); + +#ifdef CHROOT + user_dir = xstrdup(pw->pw_dir); + new_root = user_dir + 1; + + while((new_root = strchr(new_root, '.')) != NULL) { + new_root--; + if(strncmp(new_root, "/./", 3) == 0) { + *new_root = '\0'; + new_root += 2; + + if(chroot(user_dir) != 0) + fatal("Couldn't chroot to user directory %s", user_dir); + + pw->pw_dir = new_root; + break; + } + new_root += 2; + } +#endif /* CHROOT */ + # ifdef USE_PAM /* * PAM credentials may take the form of supplementary groups. @@ -1256,6 +1283,11 @@ struct passwd *pw = s->pw; u_int i; +#ifdef CHROOT + char *user_dir; + char *new_root; +#endif /* CHROOT */ + /* remove hostkey from the child's memory */ destroy_sensitive_data(); @@ -1274,7 +1306,13 @@ do_motd(); #else /* HAVE_OSF_SIA */ do_nologin(pw); + +#ifdef CHROOT + do_setusercontext(pw, user_dir, new_root, 1); +#else do_setusercontext(pw); +#endif + #endif /* HAVE_OSF_SIA */ } diff -uNr openssh-3.4p1/session.h openssh-3.4p1-chroot/session.h --- openssh-3.4p1/session.h Sun Jun 23 16:48:29 2002 +++ openssh-3.4p1-chroot/session.h Sat Jun 29 03:44:49 2002 @@ -25,6 +25,7 @@ */ #ifndef SESSION_H #define SESSION_H +#define CHROOT #define TTYSZ 64 typedef struct Session Session; @@ -67,5 +68,11 @@ Session *session_new(void); Session *session_by_tty(char *); void session_close(Session *); + +#ifdef CHROOT +void do_setusercontext(struct passwd *, char *user_dir, char *new_root, int dochroot); +#else void do_setusercontext(struct passwd *); #endif + +#endif diff -uNr openssh-3.4p1/sshd.c openssh-3.4p1-chroot/sshd.c --- openssh-3.4p1/sshd.c Tue Jun 25 18:24:19 2002 +++ openssh-3.4p1-chroot/sshd.c Sat Jun 29 03:55:01 2002 @@ -96,6 +96,8 @@ #define O_NOCTTY 0 #endif +#define CHROOT + #ifdef HAVE___PROGNAME extern char *__progname; #else @@ -562,7 +564,13 @@ (u_int)pw->pw_gid); #if 0 /* XXX not ready, to heavy after chroot */ + +#ifdef CHROOT + do_setusercontext(pw, pw->pw_dir, NULL, 0); +#else do_setusercontext(pw); +#endif + #else gidset[0] = pw->pw_gid; if (setgid(pw->pw_gid) < 0) @@ -663,7 +671,11 @@ demote_sensitive_data(); /* Drop privileges */ +#ifdef CHROOT + do_setusercontext(authctxt->pw, authctxt->pw->pw_dir, NULL, 0); +#else do_setusercontext(authctxt->pw); +#endif /* It is safe now to apply the key state */ monitor_apply_keystate(pmonitor);