diff --git a/include/unistd.h b/include/unistd.h index 029171187f93..3289776c4785 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -1,4 +1,4 @@ -/* $NetBSD: unistd.h,v 1.26 1995/11/22 23:07:19 cgd Exp $ */ +/* $NetBSD: unistd.h,v 1.27 1996/05/28 02:07:32 mrg Exp $ */ /*- * Copyright (c) 1991 The Regents of the University of California. @@ -127,7 +127,7 @@ char *getpass __P((const char *)); char *getusershell __P((void)); char *getwd __P((char *)); /* obsoleted by getcwd() */ int initgroups __P((const char *, int)); -int iruserok __P((u_long, int, const char *, const char *)); +int iruserok __P((u_int32_t, int, const char *, const char *)); int mknod __P((const char *, mode_t, dev_t)); int mkstemp __P((char *)); char *mktemp __P((char *)); diff --git a/lib/libc/net/rcmd.3 b/lib/libc/net/rcmd.3 index 4db847c39220..135c74376abd 100644 --- a/lib/libc/net/rcmd.3 +++ b/lib/libc/net/rcmd.3 @@ -1,4 +1,4 @@ -.\" $NetBSD: rcmd.3,v 1.8 1995/02/25 06:20:52 cgd Exp $ +.\" $NetBSD: rcmd.3,v 1.9 1996/05/28 02:07:39 mrg Exp $ .\" .\" Copyright (c) 1983, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -49,7 +49,7 @@ .Ft int .Fn rresvport "int *port" .Ft int -.Fn iruserok "u_long raddr" "int superuser" "const char *ruser" "const char *luser" +.Fn iruserok "u_int32_t raddr" "int superuser" "const char *ruser" "const char *luser" .Ft int .Fn ruserok "const char *rhost" "int superuser" "const char *ruser" "const char *luser" .Sh DESCRIPTION diff --git a/lib/libc/net/rcmd.c b/lib/libc/net/rcmd.c index cfd43bc03067..750ef9c7a51d 100644 --- a/lib/libc/net/rcmd.c +++ b/lib/libc/net/rcmd.c @@ -1,4 +1,4 @@ -/* $NetBSD: rcmd.c,v 1.13 1995/11/16 08:35:33 pk Exp $ */ +/* $NetBSD: rcmd.c,v 1.14 1996/05/28 02:07:44 mrg Exp $ */ /* * Copyright (c) 1983, 1993, 1994 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94"; #else -static char *rcsid = "$NetBSD: rcmd.c,v 1.13 1995/11/16 08:35:33 pk Exp $"; +static char *rcsid = "$NetBSD: rcmd.c,v 1.14 1996/05/28 02:07:44 mrg Exp $"; #endif #endif /* LIBC_SCCS and not lint */ @@ -57,9 +57,11 @@ static char *rcsid = "$NetBSD: rcmd.c,v 1.13 1995/11/16 08:35:33 pk Exp $"; #include #include #include +#include -int __ivaliduser __P((FILE *, u_long, const char *, const char *)); -static int __icheckhost __P((u_long, const char *)); +int __ivaliduser __P((FILE *, u_int32_t, const char *, const char *)); +static int __icheckhost __P((u_int32_t, const char *)); +static char *__gethostloop __P((u_int32_t)); int rcmd(ahost, rport, locuser, remuser, cmd, fd2p) @@ -71,7 +73,7 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p) struct hostent *hp; struct sockaddr_in sin, from; fd_set reads; - long oldmask; + int oldmask; pid_t pid; int s, lport, timo; char c; @@ -253,7 +255,7 @@ ruserok(rhost, superuser, ruser, luser) char **ap; int i; #define MAXADDRS 35 - u_long addrs[MAXADDRS + 1]; + u_int32_t addrs[MAXADDRS + 1]; if ((hp = gethostbyname(rhost)) == NULL) return (-1); @@ -278,7 +280,7 @@ ruserok(rhost, superuser, ruser, luser) */ int iruserok(raddr, superuser, ruser, luser) - u_long raddr; + u_int32_t raddr; int superuser; const char *ruser, *luser; { @@ -354,7 +356,7 @@ again: int __ivaliduser(hostf, raddr, luser, ruser) FILE *hostf; - u_long raddr; + u_int32_t raddr; const char *luser, *ruser; { register char *user, *p; @@ -362,8 +364,8 @@ __ivaliduser(hostf, raddr, luser, ruser) char buf[MAXHOSTNAMELEN + 128]; /* host + login */ const char *auser, *ahost; int hostok, userok; - char rhost[MAXHOSTNAMELEN]; - struct hostent *hp; + char *rhost = NULL; + int firsttime = 1; char domain[MAXHOSTNAMELEN]; getdomainname(domain, sizeof(domain)); @@ -372,7 +374,8 @@ __ivaliduser(hostf, raddr, luser, ruser) p = buf; /* Skip lines that are too long. */ if (strchr(p, '\n') == NULL) { - while ((ch = getc(hostf)) != '\n' && ch != EOF); + while ((ch = getc(hostf)) != '\n' && ch != EOF) + ; continue; } while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') { @@ -397,13 +400,6 @@ __ivaliduser(hostf, raddr, luser, ruser) auser = *user ? user : luser; ahost = buf; - if ((hp = gethostbyaddr((char *) &raddr, - sizeof(raddr), AF_INET)) == NULL) { - return -1; - } - (void) strncpy(rhost, hp->h_name, sizeof(rhost)); - rhost[sizeof(rhost) - 1] = '\0'; - if (ahost[0] == '+') switch (ahost[1]) { case '\0': @@ -411,8 +407,15 @@ __ivaliduser(hostf, raddr, luser, ruser) break; case '@': - hostok = innetgr(&ahost[2], rhost, NULL, - domain); + if (firsttime) { + rhost = __gethostloop(raddr); + firsttime = 0; + } + if (rhost) + hostok = innetgr(&ahost[2], rhost, + NULL, domain); + else + hostok = 0; break; default: @@ -426,8 +429,15 @@ __ivaliduser(hostf, raddr, luser, ruser) break; case '@': - hostok = -innetgr(&ahost[2], rhost, NULL, - domain); + if (firsttime) { + rhost = __gethostloop(raddr); + firsttime = 0; + } + if (rhost) + hostok = -innetgr(&ahost[2], rhost, + NULL, domain); + else + hostok = 0; break; default: @@ -446,7 +456,7 @@ __ivaliduser(hostf, raddr, luser, ruser) case '@': userok = innetgr(&auser[2], NULL, ruser, - domain); + domain); break; default: @@ -461,7 +471,7 @@ __ivaliduser(hostf, raddr, luser, ruser) case '@': userok = -innetgr(&auser[2], NULL, ruser, - domain); + domain); break; default: @@ -491,15 +501,15 @@ __ivaliduser(hostf, raddr, luser, ruser) */ static int __icheckhost(raddr, lhost) - u_long raddr; + u_int32_t raddr; const char *lhost; { register struct hostent *hp; - register u_long laddr; + register u_int32_t laddr; register char **pp; /* Try for raw ip address first. */ - if (isdigit(*lhost) && (long)(laddr = inet_addr(lhost)) != -1) + if (isdigit(*lhost) && (int32_t)(laddr = inet_addr(lhost)) != -1) return (raddr == laddr); /* Better be a hostname. */ @@ -508,9 +518,50 @@ __icheckhost(raddr, lhost) /* Spin through ip addresses. */ for (pp = hp->h_addr_list; *pp; ++pp) - if (!bcmp(&raddr, *pp, sizeof(u_long))) + if (!bcmp(&raddr, *pp, sizeof(u_int32_t))) return (1); /* No match. */ return (0); } + +/* + * Return the hostname associated with the supplied address. + * Do a reverse lookup as well for security. If a loop cannot + * be found, pack the result of inet_ntoa() into the string. + */ +static char * +__gethostloop(raddr) + u_int32_t raddr; +{ + static char remotehost[MAXHOSTNAMELEN]; + struct hostent *hp; + struct in_addr in; + + hp = gethostbyaddr((char *) &raddr, sizeof(raddr), AF_INET); + if (hp == NULL) + return (NULL); + + /* + * Look up the name and check that the supplied + * address is in the list + */ + strncpy(remotehost, hp->h_name, sizeof(remotehost) - 1); + remotehost[sizeof(remotehost) - 1] = '\0'; + hp = gethostbyname(remotehost); + if (hp == NULL) + return (NULL); + + for (; hp->h_addr_list[0] != NULL; hp->h_addr_list++) + if (!bcmp(hp->h_addr_list[0], (caddr_t)&raddr, sizeof(raddr))) + return (remotehost); + + /* + * either the DNS adminstrator has made a configuration + * mistake, or someone has attempted to spoof us + */ + in.s_addr = raddr; + syslog(LOG_NOTICE, "rcmd: address %s not listed for host %s", + inet_ntoa(in), hp->h_name); + return (NULL); +}