From cb34385453717065a4bbfd9fae971b76c186df1e Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Sun, 29 Mar 1998 17:03:23 +0000 Subject: Update. 1998-03-29 16:50 Ulrich Drepper * config.make.in (ldd-rewrite-script): New variable. * configure.in: Substitute ldd-rewrite-script. * elf/Makefile: Rewrite rules to generate ldd script. * elf/ldd.bash.in: Allow handling of non-ELF binaries. * elf/ldd.sh.in: Likewise. * sysdeps/unix/sysv/linux/Makefile: Remove rule to install lddlibc4. * sysdeps/unix/sysv/linux/configure.in: Define ldd_rewrite_script to point to sed script for libc4 handling insertion for ix86, m68, SPARC. * sysdeps/unix/sysv/linux/i386/Makefile: Add rule to install lddlibc4. 1998-03-26 15:20 Zack Weinberg * inet/rcmd.c (iruserok): Remain setuid to the local user while .rhosts is actually read, to make .rhosts-over-NFS work (PR libc/524). Use iruserfopen() for security checks on both hosts.equiv and .rhosts. General cleanup. (iruserfopen): New function, performs careful checking on hosts.equiv/.rhosts files. Disallows all the old forbidden stuff plus hard links to files. 1998-03-29 09:26 Ulrich Drepper * setjmp/tst-setjmp.c: Don't test __setjmp, test _setjmp instead. 1998-03-29 02:02 H.J. Lu * sysdeps/i386/i486/bits/string.h: Fix typos. * nss/nsswitch.c (__nss_lookup): Fix the bogus checking for "adjusted for next function". 1998-03-28 00:13 H.J. Lu * sysdeps/unix/sysv/linux/alpha/readdir.c (__readdir64): New strong alias. * sysdeps/unix/sysv/linux/alpha/syscalls.list (socket): Added. * libc.map (__ieee_get_fp_control, __ieee_set_fp_control): Added. Used by libm.so on alpha. 1998-03-28 Thorsten Kukuk * intl/bindtextdom.c [_LIBC]: Define strdup only if not yet defined. 1998-03-27 07:29 H.J. Lu * Makerules (object-suffixes-for-rules): Add .oS only for building shared library. Add ranlib rule for nonshared library. (rmobjs): Fix typo. * Makeconfig (libtype.oS, CFLAGS-.oS, CPPFLAGS-.oS): Moved into for shared library only. (CPPFLAGS-.oS): Add -DPIC. (libtypes): Use $(object-suffixes-for-rules) instead of $(object-suffixes). 1998-03-28 Ulrich Drepper * sysdeps/unix/sysv/linux/Makefile (inhibit-stdio_lim): Compile and install lddlibc4. 1998-03-28 09:13 Zack Weinberg * iconvdata/gap.pl: Gobble rest of line with a scalar, not a hash. * iconvdata/gaptab.pl: Likewise. --- inet/rcmd.c | 168 ++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 94 insertions(+), 74 deletions(-) (limited to 'inet') diff --git a/inet/rcmd.c b/inet/rcmd.c index d496a7a8fa..05bd1d5e8b 100644 --- a/inet/rcmd.c +++ b/inet/rcmd.c @@ -287,6 +287,49 @@ ruserok(rhost, superuser, ruser, luser) return -1; } +/* Extremely paranoid file open function. */ +static FILE * +iruserfopen (char *file, uid_t okuser) +{ + struct stat st; + char *cp = NULL; + FILE *res = NULL; + + /* If not a regular file, if owned by someone other than user or + root, if writeable by anyone but the owner, or if hardlinked + anywhere, quit. */ + cp = NULL; + if (__lxstat (_STAT_VER, file, &st)) + cp = _("lstat failed"); + else if (!S_ISREG (st.st_mode)) + cp = _("not regular file"); + else + { + res = fopen (file, "r"); + if (!res) + cp = _("cannot open"); + else if (__fxstat (_STAT_VER, fileno (res), &st) < 0) + cp = _("fstat failed"); + else if (st.st_uid && st.st_uid != okuser) + cp = _("bad owner"); + else if (st.st_mode & (S_IWGRP|S_IWOTH)) + cp = _("writeable by other than owner"); + else if (st.st_nlink > 1) + cp = _("hard linked somewhere"); + } + + /* If there were any problems, quit. */ + if (cp != NULL) + { + __rcmd_errstr = cp; + if (res) + fclose (res); + return NULL; + } + + return res; +} + /* * New .rhosts strategy: We are passed an ip address. We spin through * hosts.equiv and .rhosts looking for a match. When the .rhosts only @@ -297,83 +340,60 @@ ruserok(rhost, superuser, ruser, luser) * Returns 0 if ok, -1 if not ok. */ int -iruserok(raddr, superuser, ruser, luser) - u_int32_t raddr; - int superuser; - const char *ruser, *luser; +iruserok (raddr, superuser, ruser, luser) + u_int32_t raddr; + int superuser; + const char *ruser, *luser; { - register char *cp; - struct stat sbuf; - struct passwd pwdbuf, *pwd; - FILE *hostf; - int first; - - first = 1; - hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "r"); -again: - if (hostf) { - if (__ivaliduser(hostf, raddr, luser, ruser) == 0) { - (void)fclose(hostf); - return 0; - } - (void)fclose(hostf); - } - if (first == 1 && (__check_rhosts_file || superuser)) { - char *pbuf; - size_t dirlen; - size_t buflen = __sysconf (_SC_GETPW_R_SIZE_MAX); - char *buffer = __alloca (buflen); - - first = 0; - if (__getpwnam_r (luser, &pwdbuf, buffer, buflen, &pwd) < 0) - return -1; + FILE *hostf; + int isbad; - dirlen = strlen (pwd->pw_dir); - pbuf = alloca (dirlen + sizeof "/.rhosts"); - __mempcpy (__mempcpy (pbuf, pwd->pw_dir, dirlen), - "/.rhosts", sizeof "/.rhosts"); - - /* - * Change effective uid while opening .rhosts. If root and - * reading an NFS mounted file system, can't read files that - * are protected read/write owner only. - */ - if (__access (pbuf, R_OK) != 0) - hostf = NULL; - else - { - uid_t uid = geteuid (); - seteuid (pwd->pw_uid); - hostf = fopen (pbuf, "r"); - seteuid (uid); - } - - if (hostf == NULL) - return -1; - /* - * If not a regular file, or is owned by someone other than - * user or root or if writeable by anyone but the owner, quit. - */ - cp = NULL; - if (lstat(pbuf, &sbuf) < 0) - cp = _(".rhosts lstat failed"); - else if (!S_ISREG(sbuf.st_mode)) - cp = _(".rhosts not regular file"); - else if (fstat(fileno(hostf), &sbuf) < 0) - cp = _(".rhosts fstat failed"); - else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) - cp = _("bad .rhosts owner"); - else if (sbuf.st_mode & (S_IWGRP|S_IWOTH)) - cp = _(".rhosts writeable by other than owner"); - /* If there were any problems, quit. */ - if (cp) { - __rcmd_errstr = cp; - (void)fclose(hostf); - return -1; - } - goto again; - } + if (!superuser) + hostf = iruserfopen (_PATH_HEQUIV, 0); + + if (hostf) + { + isbad = __ivaliduser (hostf, raddr, luser, ruser); + fclose (hostf); + + if (!isbad) + return 0; + } + + if (__check_rhosts_file || superuser) + { + char *pbuf; + struct passwd pwdbuf, *pwd; + size_t dirlen; + size_t buflen = __sysconf (_SC_GETPW_R_SIZE_MAX); + char *buffer = __alloca (buflen); + uid_t uid; + + if (__getpwnam_r (luser, &pwdbuf, buffer, buflen, &pwd)) return -1; + + dirlen = strlen (pwd->pw_dir); + pbuf = alloca (dirlen + sizeof "/.rhosts"); + __mempcpy (__mempcpy (pbuf, pwd->pw_dir, dirlen), + "/.rhosts", sizeof "/.rhosts"); + + /* Change effective uid while reading .rhosts. If root and + reading an NFS mounted file system, can't read files that + are protected read/write owner only. */ + uid = geteuid (); + seteuid (pwd->pw_uid); + hostf = iruserfopen (pbuf, pwd->pw_uid); + + if (hostf != NULL) + { + isbad = __ivaliduser (hostf, raddr, luser, ruser); + fclose (hostf); + } + + seteuid (uid); + return isbad; + } + return -1; } /* -- cgit 1.4.1