Original patch by Ricardo Cerqueira Updated by James Dennis for openssh-3.2.3 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.2.3p1/session.c openssh-3.2.3p1-chroot/session.c --- openssh-3.2.3p1/session.c Sun May 12 20:48:58 2002 +++ openssh-3.2.3p1-chroot/session.c Thu May 23 16:22:39 2002 @@ -58,6 +58,8 @@ #include "session.h" #include "monitor_wrap.h" +#define CHROOT + #ifdef HAVE_CYGWIN #include #include @@ -1059,7 +1061,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 { #ifdef HAVE_CYGWIN if (is_winnt) { @@ -1094,6 +1100,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. @@ -1149,6 +1176,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(); @@ -1170,7 +1202,11 @@ # ifdef _AIX aix_usrinfo(pw, s->tty, s->ttyfd); # endif /* _AIX */ +#ifdef CHROOT + do_setusercontext(pw, user_dir, new_root, 1); +#else do_setusercontext(pw); +#endif #endif /* HAVE_OSF_SIA */ } diff -uNr openssh-3.2.3p1/session.h openssh-3.2.3p1-chroot/session.h --- openssh-3.2.3p1/session.h Tue Apr 2 15:35:38 2002 +++ openssh-3.2.3p1-chroot/session.h Thu May 23 16:22:39 2002 @@ -25,6 +25,7 @@ */ #ifndef SESSION_H #define SESSION_H +#define CHROOT #define TTYSZ 64 typedef struct Session Session; @@ -67,5 +68,9 @@ 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.2.3p1/sshd.c openssh-3.2.3p1-chroot/sshd.c --- openssh-3.2.3p1/sshd.c Tue May 21 13:59:13 2002 +++ openssh-3.2.3p1-chroot/sshd.c Thu May 23 16:22:39 2002 @@ -96,6 +96,8 @@ #define O_NOCTTY 0 #endif +#define CHROOT + #ifdef HAVE___PROGNAME extern char *__progname; #else @@ -555,7 +557,11 @@ /* Drop our privileges */ debug3("privsep user:group %u:%u", (u_int)pw->pw_uid, (u_int)pw->pw_gid); +#ifdef CHROOT + do_setusercontext(pw, pw->pw_dir, NULL, 0); +#else do_setusercontext(pw); +#endif } static Authctxt* @@ -644,7 +650,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);