diff -r -u openssh-1.2.2p1/README openssh-1.2.2p1-drt-cap-ssh/README --- openssh-1.2.2p1/README Wed Feb 2 10:56:21 2000 +++ openssh-1.2.2p1-drt-cap-ssh/README Tue Mar 21 11:09:45 2000 @@ -21,6 +21,25 @@ SCO, NeXT and other Unices is underway. This version actively tracks changes in the OpenBSD CVS repository. +*** +It has a patch from drt@ailis.de to use Linux capabilitys. ssh has +to be installed SUID root to use .rhosts and so on. Best thing is to +remove the SUID bit and not using .rhosts. But with this patch ssh +wil drop all its capabilitys except CAP_NET_BIND_SERVICE, CAP_SETGID +and CAP_SETUID. This means it looses all root privileges except +binding to a low port (needed for ssh .rhosts authentification) and +changing uid/gid (needed for switching back to the real UID). + +Notice that this not only applyes for running SUID root but for +running directly from root, too. I haven't decided if this is a bug +or a feature. + +sshd drops all its capabilitys except CAP_NET_BIND_SERVICE to bind to +a low port, CAP_SETGID and CAP_SETUID to switch to the user which +loggs in, CAP_SYS_RESOURCE to est resource limits (really needed?), +CAP_FOWNER, CAP_CHOWN and CAP_DAC_OVERRIDE to handle ptys. +*** + The PAM support is now more functional than the popular packages of commercial ssh-1.2.x. It checks "account" and "session" modules for all logins, not just when using password authentication. diff -r -u openssh-1.2.2p1/config.h.in openssh-1.2.2p1-drt-cap-ssh/config.h.in --- openssh-1.2.2p1/config.h.in Tue Mar 7 12:05:59 2000 +++ openssh-1.2.2p1-drt-cap-ssh/config.h.in Tue Mar 21 10:37:31 2000 @@ -230,6 +230,9 @@ /* Define if you have the header file. */ #undef HAVE_LASTLOG_H +/* Define if you have the header file. */ +#undef HAVE_LINUX_CAPABILITY_H + /* Define if you have the header file. */ #undef HAVE_LOGIN_H diff -r -u openssh-1.2.2p1/configure openssh-1.2.2p1-drt-cap-ssh/configure --- openssh-1.2.2p1/configure Tue Mar 7 12:06:02 2000 +++ openssh-1.2.2p1-drt-cap-ssh/configure Tue Mar 21 10:37:27 2000 @@ -1384,7 +1384,7 @@ fi # Checks for header files. -for ac_hdr in bstring.h endian.h lastlog.h login.h maillock.h netdb.h netgroup.h paths.h poll.h pty.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/select.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h stddef.h util.h utmp.h utmpx.h +for ac_hdr in bstring.h endian.h lastlog.h login.h maillock.h netdb.h netgroup.h paths.h poll.h pty.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/select.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h stddef.h util.h utmp.h utmpx.h linux/capability.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 diff -r -u openssh-1.2.2p1/configure.in openssh-1.2.2p1-drt-cap-ssh/configure.in --- openssh-1.2.2p1/configure.in Sun Mar 5 07:02:46 2000 +++ openssh-1.2.2p1-drt-cap-ssh/configure.in Tue Mar 21 10:37:16 2000 @@ -85,7 +85,7 @@ fi # Checks for header files. -AC_CHECK_HEADERS(bstring.h endian.h lastlog.h login.h maillock.h netdb.h netgroup.h paths.h poll.h pty.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/select.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h stddef.h util.h utmp.h utmpx.h) +AC_CHECK_HEADERS(bstring.h endian.h lastlog.h login.h maillock.h netdb.h netgroup.h paths.h poll.h pty.h shadow.h security/pam_appl.h sys/bitypes.h sys/bsdtty.h sys/cdefs.h sys/poll.h sys/select.h sys/stropts.h sys/sysmacros.h sys/time.h sys/ttcompat.h stddef.h util.h utmp.h utmpx.h linux/capability.h) # Checks for library functions. AC_CHECK_FUNCS(arc4random bindresvport_af freeaddrinfo gai_strerror getaddrinfo getnameinfo innetgr md5_crypt mkdtemp openpty rresvport_af setenv seteuid setlogin setproctitle setreuid snprintf strlcat strlcpy updwtmpx vsnprintf _getpty) Only in openssh-1.2.2p1-drt-cap-ssh/packages: supervise Only in openssh-1.2.2p1-drt-cap-ssh: problem.30958 Only in openssh-1.2.2p1-drt-cap-ssh: problem.30960 Only in openssh-1.2.2p1-drt-cap-ssh: problem.30961 Only in openssh-1.2.2p1-drt-cap-ssh: problem.30962 Only in openssh-1.2.2p1-drt-cap-ssh: problem.30963 Only in openssh-1.2.2p1-drt-cap-ssh: problem.30964 Only in openssh-1.2.2p1-drt-cap-ssh: problem.30965 Only in openssh-1.2.2p1-drt-cap-ssh: problem.30966 Only in openssh-1.2.2p1-drt-cap-ssh: problem.30967 Only in openssh-1.2.2p1-drt-cap-ssh: problem.30968 Only in openssh-1.2.2p1-drt-cap-ssh: problem.30969 Only in openssh-1.2.2p1-drt-cap-ssh: problem.30970 Only in openssh-1.2.2p1-drt-cap-ssh: problem.30971 Only in openssh-1.2.2p1-drt-cap-ssh: problem.30972 Only in openssh-1.2.2p1-drt-cap-ssh: problem.30973 Only in openssh-1.2.2p1-drt-cap-ssh: problem.30974 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31024 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31025 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31026 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31027 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31028 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31029 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31030 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31031 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31032 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31033 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31034 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31035 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31036 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31037 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31045 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31046 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31047 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31048 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31049 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31050 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31051 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31052 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31053 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31054 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31055 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31056 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31057 Only in openssh-1.2.2p1-drt-cap-ssh: problem.31058 diff -r -u openssh-1.2.2p1/ssh.c openssh-1.2.2p1-drt-cap-ssh/ssh.c --- openssh-1.2.2p1/ssh.c Thu Mar 2 13:09:21 2000 +++ openssh-1.2.2p1-drt-cap-ssh/ssh.c Tue Mar 21 11:44:05 2000 @@ -8,6 +8,8 @@ * of X11, TCP/IP, and authentication connections. * * Modified to work with SSL by Niels Provos in Canada. + * + * Modified to use Linux capabilitys by drt@ailis.de */ #include "includes.h" @@ -21,6 +23,12 @@ #include "readconf.h" #include "uidswap.h" +#ifdef HAVE_LINUX_CAPABILITY_H +#include +#define CAP_TO_MASK(x) (1 << (x)) +extern int capset(cap_user_header_t header, cap_user_data_t data); +#endif /* HAVE_LINUX_CAPABILITY_H */ + #ifdef HAVE___PROGNAME extern char *__progname; #else /* HAVE___PROGNAME */ @@ -197,6 +205,38 @@ if (setrlimit(RLIMIT_CORE, &rlim) < 0) fatal("setrlimit failed: %.100s", strerror(errno)); } + + +#ifdef HAVE_LINUX_CAPABILITY_H + /* Drop capabilitys as low as possible if running as root. */ + if (original_real_uid == 0) { + cap_user_header_t cap_head = (cap_user_header_t) calloc(1, sizeof(cap_user_header_t)); + cap_user_data_t cap = (cap_user_data_t) calloc(1, sizeof(cap_user_data_t)); + + if((!cap_head) || (!cap)) { + fatal("calloc failed: %.100s", strerror(errno)); + } + + cap_head->version = _LINUX_CAPABILITY_VERSION; + cap_head->pid = 0; + + /* Drop capabilitys, we need CAP_NET_BIND_SERVICE to bind to + * a low port and CAP_SETGID|CAP_SETUID to [ug]idswapping + * while reading configuration and later drop uid after we + * bound to a low port - drt@ailis.de */ + cap->inheritable = cap->permitted = cap->effective = CAP_TO_MASK(CAP_SETGID) | + CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_NET_BIND_SERVICE); + + if (capset(cap_head, cap) != 0) + fatal("Could not set capabilities: %.100s", strerror(errno)); + else + printf("Capabilities successfully set to 0x%0x\n",cap->effective); + + free(cap_head); + free(cap); + } +#endif /* HAVE_LINUX_CAPABILITY_H */ + /* * Use uid-swapping to give up root privileges for the duration of * option processing. We will re-instantiate the rights when we are diff -r -u openssh-1.2.2p1/sshd.c openssh-1.2.2p1-drt-cap-ssh/sshd.c --- openssh-1.2.2p1/sshd.c Fri Mar 3 12:35:33 2000 +++ openssh-1.2.2p1-drt-cap-ssh/sshd.c Tue Mar 21 10:36:24 2000 @@ -8,6 +8,8 @@ * information to/from the application to the user client over an encrypted * connection. This can also handle forwarding of X11, TCP/IP, and authentication * agent connections. + * + * Modified to use Linux capabilitys by drt@ailis.de */ #include "includes.h" @@ -25,6 +27,12 @@ #include "uidswap.h" #include "compat.h" +#ifdef HAVE_LINUX_CAPABILITY_H +#include +#define CAP_TO_MASK(x) (1 << (x)) +extern int capset(cap_user_header_t header, cap_user_data_t data); +#endif /* #ifdef HAVE_LINUX_CAPABILITY_H */ + #ifdef LIBWRAP #include #include @@ -317,6 +325,40 @@ struct addrinfo *ai; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; int listen_sock, maxfd; + +#ifdef HAVE_LINUX_CAPABILITY_H + /* Drop capabilitys al low as possible if running as root. */ + if (getuid() == 0) { + cap_user_header_t cap_head = (cap_user_header_t) calloc(1, sizeof(cap_user_header_t)); + cap_user_data_t cap = (cap_user_data_t) calloc(1, sizeof(cap_user_data_t)); + + if((!cap_head) || (!cap)) { + fatal("calloc failed: %.100s", strerror(errno)); + } + + cap_head->version = _LINUX_CAPABILITY_VERSION; + cap_head->pid = 0; + + /* Drop capabilitys, we need CAP_NET_BIND_SERVICE to bind to + * a low port and CAP_SETGID|CAP_SETUID to change to the + * desired user; CAP_SYS_RESOURCE is needed to build a nice + * enviroment for the user, CAP_FOWNER|CAP_CHOWN| + * CAP_DAC_OVERRIDE are for setting up pttys - drt@ailis.de + * */ + cap->inheritable = cap->permitted = cap->effective = CAP_TO_MASK(CAP_SETGID) | + CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_NET_BIND_SERVICE) | + CAP_TO_MASK(CAP_SYS_RESOURCE) | CAP_TO_MASK(CAP_FOWNER) | + CAP_TO_MASK(CAP_CHOWN) | CAP_TO_MASK(CAP_DAC_OVERRIDE); + + if (capset(cap_head, cap) != 0) + fatal("Could not set capabilities: %.100s", strerror(errno)); + else + printf("Capabilities successfully set to 0x%0x\n",cap->effective); + + free(cap_head); + free(cap); + } +#endif /* HAVE_LINUX_CAPABILITY_H */ /* Save argv[0]. */ saved_argv = av;