]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
STABLE14-sgistuff-missing-files-20050816
authorDerrick Brashear <shadow@dementia.org>
Tue, 16 Aug 2005 19:00:44 +0000 (19:00 +0000)
committerDerrick Brashear <shadow@dementia.org>
Tue, 16 Aug 2005 19:00:44 +0000 (19:00 +0000)
FIXES 20766

these were overzealously killed (by me)

fix

(cherry picked from commit 68f5f09832ae0b9207951df717a4e33910d9a147)

src/sgistuff/Makefile.in
src/sgistuff/herror.c [new file with mode: 0644]
src/sgistuff/rcmd.c [new file with mode: 0644]
src/sgistuff/ta-rauth.c [new file with mode: 0644]

index 88e95bfc6a8495f8716c7f7def161e1f94964d75..2f96069facf6616f3e7fbd7b19093634946dd00b 100644 (file)
@@ -26,7 +26,7 @@ KAFSLIBS=${TOP_LIBDIR}/libkauth.krb.a ${TOP_LIBDIR}/libprot.a ${LIBDIR}/libubik.
          ${TOP_LIBDIR}/libauth.krb.a ${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/libsys.a \
          ${TOP_LIBDIR}/libdes.a ${LIBDIR}/librx.a ${LIBDIR}/liblwp.a \
           ${TOP_LIBDIR}/libcmd.a ${TOP_LIBDIR}/libcom_err.a ${TOP_LIBDIR}/util.a
-AUTHFILES=../inetd/ta-rauth.o ../rsh/rcmd.o ../rsh/herror.o
+AUTHFILES=ta-rauth.o rcmd.o herror.o
 AUTHLIBS=afsauthlib.so afskauthlib.so
 TARGETS=$(AUTHLIBS) 
 
@@ -43,14 +43,14 @@ afsauthlib.so: sgi_auth.o ${AFSLIBS} ${AUTHFILES}
 afskauthlib.so: sgi_auth.o ${KAFSLIBS} ${AUTHFILES}
        $(LD) ${LDFLAGS} -shared -all -o afskauthlib.so sgi_auth.o $(KAFSLIBS) ${AUTHFILES}
 
-../inetd/ta-rauth.o: ../inetd/ta-rauth.c
-       (cd ../inetd ; $(MAKE) ta-rauth.o )
+ta-rauth.o: ta-rauth.c
+       ${CC} ${CFLAGS} -c ta-rauth.c
 
-../rsh/rcmd.o: ../rsh/rcmd.c
-       (cd ../rsh ; $(MAKE) rcmd.o )
+rcmd.o: rcmd.c
+       ${CC} ${CFLAGS} -c rcmd.c
 
-../rsh/herror.o: ../rsh/herror.c
-       (cd ../rsh ; $(MAKE) herror.o )
+herror.o: herror.c
+       ${CC} ${CFLAGS} -c herror.c
 
 sgi_auth.o: sgi_auth.c
        ${CC} ${CFLAGS} -c sgi_auth.c
diff --git a/src/sgistuff/herror.c b/src/sgistuff/herror.c
new file mode 100644 (file)
index 0000000..bd47f45
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1987 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <afsconfig.h>
+#include <afs/param.h>
+
+RCSID
+    ("$Header$");
+
+#ifndef AFS_DARWIN_ENV
+#include <sys/types.h>
+#include <sys/uio.h>
+
+char *h_errlist[] = {
+    "Error 0",
+    "Unknown host",            /* 1 HOST_NOT_FOUND */
+    "Host name lookup failure",        /* 2 TRY_AGAIN */
+    "Unknown server error",    /* 3 NO_RECOVERY */
+    "No address associated with name", /* 4 NO_ADDRESS */
+};
+int h_nerr = { sizeof(h_errlist) / sizeof(h_errlist[0]) };
+
+#if defined(AFS_SUN_ENV)
+int h_errno;
+#else
+extern int h_errno;
+#endif
+
+/*
+ * herror --
+ *     print the error indicated by the h_errno value.
+ */
+herror(s)
+     char *s;
+{
+    struct iovec iov[4];
+    register struct iovec *v = iov;
+
+    if (s && *s) {
+       v->iov_base = s;
+       v->iov_len = strlen(s);
+       v++;
+       v->iov_base = ": ";
+       v->iov_len = 2;
+       v++;
+    }
+    v->iov_base =
+       (u_int) h_errno < h_nerr ? h_errlist[h_errno] : "Unknown error";
+    v->iov_len = strlen(v->iov_base);
+    v++;
+    v->iov_base = "\n";
+    v->iov_len = 1;
+    writev(2, iov, (v - iov) + 1);
+}
+#endif
diff --git a/src/sgistuff/rcmd.c b/src/sgistuff/rcmd.c
new file mode 100644 (file)
index 0000000..a27d7a4
--- /dev/null
@@ -0,0 +1,600 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <afsconfig.h>
+#include <afs/param.h>
+
+RCSID
+    ("$Header$");
+
+#ifdef aiws /*AIX*/
+#include <sys/types.h>
+#define MAXHOSTNAMELEN 64      /* use BSD's, not sys/param's */
+#define MAXPATHLEN     1024    /* from BSD */
+#include <sys/ioctl.h>         /* for SIOCSPGRP */
+#endif
+#include <stdio.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <sys/param.h>
+#include <limits.h>
+#include <sys/file.h>
+#ifdef AFS_SUN5_ENV
+#include <fcntl.h>
+#endif
+#include <unistd.h>            /* select() prototype */
+#include <sys/types.h>         /* fd_set on older platforms */
+#include <sys/time.h>          /* struct timeval, select() prototype */
+#ifndef        FD_SET
+# include <sys/select.h>       /* fd_set on newer platforms */
+#endif
+#include <sys/signal.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <errno.h>
+#if defined(AFS_HPUX_ENV)
+/* HPUX uses a different call to set[res][gu]ids: */
+#define seteuid(newEuid)       setresuid(-1, (newEuid), -1)
+#define setegid(newEgid)       setresgid(-1, (newEgid), -1)
+#endif /* defined(AFS_HPUX_ENV) */
+#ifdef TCP_DEBUG
+#include <sys/syslog.h>
+#      define  DPRINTF(args)   dprintf args
+dprintf(args)
+     char *args;
+{
+    char **argv;
+    char buf[BUFSIZ];
+    static char prefix[] = "rcmd: ";
+
+    argv = &args;
+    vsprintf(buf, argv[0], &argv[1]);
+    syslog(LOG_DEBUG, "%s %s\n", prefix, buf);
+}
+#else
+#      define  DPRINTF(args)
+#endif
+#include <syslog.h>
+static _checkhost();
+
+#ifdef AFS_HPUX102_ENV
+int
+rmcd(ahost, rport, locuser, remuser, cmd, fd2p)
+     char **ahost;
+     int rport;
+     const char *locuser, *remuser, *cmd;
+     int *fd2p;
+#else
+#ifdef AFS_AIX32_ENV
+rcmd(ahost, rport, locuser, remuser, cmd, fd2p, retry)
+     int retry;
+#else
+rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
+#endif
+     char **ahost;
+     u_short rport;
+#if defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+     const char *locuser, *remuser, *cmd;
+#else
+     char *locuser, *remuser, *cmd;
+#endif
+     int *fd2p;
+#endif
+{
+    int s, timo = 1, pid;
+    sigset_t oldset;
+    sigset_t sigBlock;
+    int someSignals[100];
+    struct servent *sp, *getservbyport();
+    struct sockaddr_in sin, from;
+    char c;
+    int lport = IPPORT_RESERVED - 1;
+    struct hostent *hp;
+    fd_set reads;
+
+    memset((char *)someSignals, 0, sizeof(someSignals));
+    someSignals[0] = 1 << (SIGURG - 1);
+    sigBlock = *((sigset_t *) someSignals);
+
+    pid = getpid();
+    hp = gethostbyname(*ahost);        /* CAUTION: this uses global static */
+    /* storage.  ANY OTHER CALLS to gethostbyname (including from within
+     * syslog, eg) will trash the contents of hp. BE CAREFUL! */
+    if (hp == 0) {
+       herror(*ahost);
+       return (-1);
+    }
+    *ahost = hp->h_name;
+    /* was: syslog(LOG_ERR, "rcmd: host=%s, rport=%d, luser=%s,ruser=%s,cmd=%s,fd2p=%s\n", *ahost,rport,locuser,remuser,cmd,fd2p) 
+     * but that trashes hp... */
+    sigprocmask(SIG_BLOCK, &sigBlock, &oldset);
+    for (;;) {
+       s = rresvport(&lport);
+       if (s < 0) {
+           if (errno == EAGAIN)
+               fprintf(stderr, "socket: All ports in use\n");
+           else
+               perror("rcmd: socket");
+           sigprocmask(SIG_SETMASK, &oldset, (sigset_t *) 0);
+           return (-1);
+       }
+#ifdef AFS_AIX32_ENV
+#ifndef aiws
+       fcntl(s, F_SETOWN, pid);
+#else
+       /* since AIX has no F_SETOWN, we just do the ioctl */
+       (void)ioctl(s, SIOCSPGRP, &pid);
+#endif
+#else
+#if !defined(AFS_AIX_ENV) && !defined(AFS_HPUX_ENV)
+       fcntl(s, F_SETOWN, pid);
+#endif /* !defined(AIX) */
+#endif
+       sin.sin_family = hp->h_addrtype;
+#ifdef AFS_OSF_ENV
+       memcpy((caddr_t) & sin.sin_addr, hp->h_addr_list[0], hp->h_length);
+#else
+       memcpy((caddr_t) & sin.sin_addr, hp->h_addr, hp->h_length);
+#endif
+       sin.sin_port = rport;
+       /* attempt to remote authenticate first... */
+       sp = getservbyport((int)rport, "tcp");
+       if (sp) {
+           int ok = 0;
+
+           switch (ta_rauth(s, sp->s_name, sin.sin_addr)) {
+           case 0:
+#ifndef        AFS_SGI_ENV
+               fprintf(stderr, "No remote authentication\n");
+#endif
+               close(s);
+               s = rresvport(&lport);
+               if (s < 0) {
+                   if (errno == EAGAIN)
+                       fprintf(stderr, "socket: All ports in use\n");
+                   else
+                       perror("rcmd: socket");
+                   sigprocmask(SIG_SETMASK, &oldset, (sigset_t *) 0);
+                   return (-1);
+               }
+#if !defined(AFS_AIX_ENV) && !defined(AFS_HPUX_ENV)
+               fcntl(s, F_SETOWN, pid);
+#endif /* !defined(AIX) */
+               break;
+           case 1:
+               ok = 1;
+               break;
+           case -1:
+               fprintf(stderr, "Login incorrect.");
+               exit(1);
+               break;
+           case -2:
+               fprintf(stderr, "internal failure, ta_rauth\n");
+               exit(errno);
+               break;
+           case -3:
+               fprintf(stderr, "Cannot connect to remote machine\n");
+               exit(errno);
+               break;
+           }
+
+           if (ok) {
+               break;          /* from for loop */
+           }
+       }
+       if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
+           break;
+       (void)close(s);
+       if (errno == EADDRINUSE) {
+           lport--;
+           continue;
+       }
+       if (errno == ECONNREFUSED && timo <= 16) {
+#ifdef AFS_AIX32_ENV
+           if (!retry) {
+               return (-2);
+           }
+#endif
+           sleep(timo);
+           timo *= 2;
+           continue;
+       }
+       if (hp->h_addr_list[1] != NULL) {
+           int oerrno = errno;
+
+           fprintf(stderr, "connect to address %s: ",
+                   inet_ntoa(sin.sin_addr));
+           errno = oerrno;
+           perror(0);
+           hp->h_addr_list++;
+           memcpy((caddr_t) & sin.sin_addr, hp->h_addr_list[0],
+                  hp->h_length);
+           fprintf(stderr, "Trying %s...\n", inet_ntoa(sin.sin_addr));
+           continue;
+       }
+       perror(hp->h_name);
+       sigprocmask(SIG_SETMASK, &oldset, (sigset_t *) 0);
+       return (-1);
+    }
+    lport--;
+    if (fd2p == 0) {
+       write(s, "", 1);
+       lport = 0;
+    } else {
+       char num[8];
+       int s2 = rresvport(&lport), s3;
+       int len = sizeof(from);
+       int maxfd = -1;
+
+       if (s2 < 0)
+           goto bad;
+       listen(s2, 1);
+       (void)sprintf(num, "%d", lport);
+       if (write(s, num, strlen(num) + 1) != strlen(num) + 1) {
+           perror("write: setting up stderr");
+           (void)close(s2);
+           goto bad;
+       }
+       FD_ZERO(&reads);
+       FD_SET(s, &reads);
+       if (maxfd < s)
+           maxfd = s;
+       FD_SET(s2, &reads);
+       if (maxfd < s2)
+           maxfd = s2;
+       errno = 0;
+       if (select(maxfd + 1, &reads, 0, 0, 0) < 1 || !FD_ISSET(s2, &reads)) {
+           if (errno != 0)
+               perror("select: setting up stderr");
+           else
+               fprintf(stderr,
+                       "select: protocol failure in circuit setup.\n");
+           (void)close(s2);
+           goto bad;
+       }
+       s3 = accept(s2, (struct sockaddr *)&from, &len);
+       (void)close(s2);
+       if (s3 < 0) {
+           perror("accept");
+           lport = 0;
+           goto bad;
+       }
+       *fd2p = s3;
+       from.sin_port = ntohs((u_short) from.sin_port);
+       if (from.sin_family != AF_INET || from.sin_port >= IPPORT_RESERVED
+           || from.sin_port < IPPORT_RESERVED / 2) {
+           fprintf(stderr, "socket: protocol failure in circuit setup.\n");
+           goto bad2;
+       }
+    }
+    (void)write(s, locuser, strlen(locuser) + 1);
+    (void)write(s, remuser, strlen(remuser) + 1);
+    (void)write(s, cmd, strlen(cmd) + 1);
+    errno = 0;
+    if (read(s, &c, 1) < 0) {
+       perror(*ahost);
+       goto bad2;
+    }
+    if (c != 0) {
+#ifdef AFS_OSF_ENV
+       /*
+        *   Two different protocols seem to be used;
+        *   one prepends a "message" byte with a "small"
+        *   number; the other one just sends the message
+        */
+       if (isalnum(c))
+           (void)write(2, &c, 1);
+
+#endif
+       while (read(s, &c, 1) == 1) {
+           (void)write(2, &c, 1);
+           if (c == '\n')
+               break;
+       }
+       goto bad2;
+    }
+    sigprocmask(SIG_SETMASK, &oldset, (sigset_t *) 0);
+    return (s);
+  bad2:
+    if (lport)
+       (void)close(*fd2p);
+  bad:
+    (void)close(s);
+    sigprocmask(SIG_SETMASK, &oldset, (sigset_t *) 0);
+    return (-1);
+}
+
+#ifndef AFS_AIX32_ENV
+rresvport(alport)
+     int *alport;
+{
+    struct sockaddr_in sin;
+    int s;
+
+    sin.sin_family = AF_INET;
+    sin.sin_addr.s_addr = INADDR_ANY;
+    s = socket(AF_INET, SOCK_STREAM, 0);
+    if (s < 0)
+       return (-1);
+    for (;;) {
+       sin.sin_port = htons((u_short) * alport);
+       if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
+           return (s);
+       if (errno != EADDRINUSE) {
+           (void)close(s);
+           return (-1);
+       }
+       (*alport)--;
+       if (*alport == IPPORT_RESERVED / 2) {
+           (void)close(s);
+           errno = EAGAIN;     /* close */
+           return (-1);
+       }
+    }
+}
+#endif
+
+int _check_rhosts_file = 1;
+
+#if defined(AFS_HPUX102_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
+ruserok(rhost, superuser, ruser, luser)
+     const char *rhost;
+     int superuser;
+     const char *ruser, *luser;
+#else
+ruserok(rhost, superuser, ruser, luser)
+     int superuser;
+     char *rhost;
+     char *ruser, *luser;
+#endif
+{
+    FILE *hostf;
+    char fhost[MAXHOSTNAMELEN];
+    int first = 1;
+    register char *sp, *p;
+    int baselen = -1;
+    int suid, sgid;
+    int group_list_size = -1;
+    gid_t groups[NGROUPS_MAX];
+    sp = rhost;
+    p = fhost;
+    while (*sp) {
+       if (*sp == '.') {
+           if (baselen == -1)
+               baselen = sp - rhost;
+           *p++ = *sp++;
+       } else {
+           *p++ = isupper(*sp) ? tolower(*sp++) : *sp++;
+       }
+    }
+    *p = '\0';
+    hostf = superuser ? (FILE *) 0 : fopen("/etc/hosts.equiv", "r");
+  again:
+    if (hostf) {
+       if (!_validuser(hostf, fhost, luser, ruser, baselen)) {
+           (void)fclose(hostf);
+#ifdef AFS_OSF_ENV
+           if (first == 0) {
+               (void)seteuid(suid);
+               (void)setegid(sgid);
+               if (group_list_size >= 0)
+                   (void)setgroups(group_list_size, groups);
+           }
+#endif
+           return (0);
+       }
+       (void)fclose(hostf);
+    }
+    if (first == 1 && (_check_rhosts_file || superuser)) {
+       struct stat sbuf;
+       struct passwd *pwd, *getpwnam();
+       char pbuf[MAXPATHLEN];
+
+       first = 0;
+       suid = geteuid();
+       sgid = getegid();
+       group_list_size = getgroups(NGROUPS_MAX, groups);
+       if ((pwd = getpwnam(luser)) == NULL)
+           return (-1);
+       if (setegid(pwd->pw_gid) >= 0)
+           (void)initgroups(luser, pwd->pw_gid);
+       (void)seteuid(pwd->pw_uid);
+       (void)strcpy(pbuf, pwd->pw_dir);
+       (void)strcat(pbuf, "/.rhosts");
+       if ((hostf = fopen(pbuf, "r")) == NULL)
+           goto bad;
+       /*
+        * if owned by someone other than user or root or if
+        * writeable by anyone but the owner, quit
+        */
+       if (fstat(fileno(hostf), &sbuf) || sbuf.st_uid
+           && sbuf.st_uid != pwd->pw_uid || sbuf.st_mode & 022) {
+           fclose(hostf);
+           goto bad;
+       }
+       goto again;
+    }
+  bad:
+    if (first == 0) {
+       (void)seteuid(suid);
+       (void)setegid(sgid);
+       if (group_list_size >= 0)
+           (void)setgroups(group_list_size, groups);
+    }
+    return (-1);
+}
+
+/* don't make static, used by lpd(8) */
+_validuser(hostf, rhost, luser, ruser, baselen)
+     char *rhost, *luser, *ruser;
+     FILE *hostf;
+     int baselen;
+{
+    char *user;
+    char ahost[MAXHOSTNAMELEN * 4];
+    register char *p;
+#ifdef AFS_AIX32_ENV
+#include <arpa/nameser.h>
+    int hostmatch, usermatch;
+    char domain[MAXDNAME], *dp;
+
+    dp = NULL;
+    if (getdomainname(domain, sizeof(domain)) == 0)
+       dp = domain;
+#endif
+    while (fgets(ahost, sizeof(ahost), hostf)) {
+#ifdef AFS_AIX32_ENV
+       hostmatch = usermatch = 0;
+       p = ahost;
+       if (*p == '#' || *p == '\n')    /* ignore comments and blanks */
+           continue;
+       while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
+           p++;
+       if (*p == ' ' || *p == '\t') {
+           *p++ = '\0';
+           while (*p == ' ' || *p == '\t')
+               p++;
+           user = p;
+           while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
+               p++;
+       } else
+           user = p;
+       *p = '\0';
+       /*
+        *  + - anything goes
+        *  +@<name> - group <name> allowed
+        *  -@<name> - group <name> disallowed
+        *  -<name> - host <name> disallowed
+        */
+       if (ahost[0] == '+' && ahost[1] == 0)
+           hostmatch = 1;
+       else if (ahost[0] == '+' && ahost[1] == '@')
+           hostmatch = innetgr(ahost + 2, rhost, NULL, dp);
+       else if (ahost[0] == '-' && ahost[1] == '@') {
+           if (innetgr(ahost + 2, rhost, NULL, dp))
+               return (-1);
+       } else if (ahost[0] == '-') {
+           if (_checkhost(rhost, ahost + 1, baselen))
+               return (-1);
+       } else
+           hostmatch = _checkhost(rhost, ahost, baselen);
+       if (user[0]) {
+           if (user[0] == '+' && user[1] == 0)
+               usermatch = 1;
+           else if (user[0] == '+' && user[1] == '@')
+               usermatch = innetgr(user + 2, NULL, ruser, dp);
+           else if (user[0] == '-' && user[1] == '@') {
+               if (hostmatch && innetgr(user + 2, NULL, ruser, dp))
+                   return (-1);
+           } else if (user[0] == '-') {
+               if (hostmatch && !strcmp(user + 1, ruser))
+                   return (-1);
+           } else
+               usermatch = !strcmp(user, ruser);
+       } else
+           usermatch = !strcmp(ruser, luser);
+       if (hostmatch && usermatch)
+           return (0);
+#else
+       p = ahost;
+       while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
+           *p = isupper(*p) ? tolower(*p) : *p;
+           p++;
+       }
+       if (*p == ' ' || *p == '\t') {
+           *p++ = '\0';
+           while (*p == ' ' || *p == '\t')
+               p++;
+           user = p;
+           while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0')
+               p++;
+       } else
+           user = p;
+       *p = '\0';
+       if (_checkhost(rhost, ahost, baselen)
+           && !strcmp(ruser, *user ? user : luser)) {
+           return (0);
+       }
+#endif
+    }
+    return (-1);
+}
+
+static
+_checkhost(rhost, lhost, len)
+     char *rhost, *lhost;
+     int len;
+{
+    static char ldomain[MAXHOSTNAMELEN + 1];
+    static char *domainp = NULL;
+    static int nodomain = 0;
+    register char *cp;
+
+#ifdef AFS_AIX32_ENV
+    struct hostent *hp;
+    long addr;
+
+    /*
+     * check for ip address and do a lookup to convert to hostname
+     */
+    if (isinet_addr(lhost) && (addr = inet_addr(lhost)) != -1
+       && (hp = gethostbyaddr(&addr, sizeof(addr), AF_INET)))
+       lhost = hp->h_name;
+
+#endif
+    if (len == -1) {
+#ifdef AFS_AIX32_ENV
+       /* see if hostname from file has a domain name */
+       for (cp = lhost; *cp; ++cp) {
+           if (*cp == '.') {
+               len = cp - lhost;
+               break;
+           }
+       }
+#endif
+       return (!strcmp(rhost, lhost));
+    }
+    if (strncmp(rhost, lhost, len))
+       return (0);
+    if (!strcmp(rhost, lhost))
+       return (1);
+#ifdef AFS_AIX32_ENV
+    if (*(lhost + len) != '\0' && *(rhost + len) != '\0')
+#else
+    if (*(lhost + len) != '\0')
+#endif
+       return (0);
+    if (nodomain)
+       return (0);
+    if (!domainp) {
+       if (gethostname(ldomain, sizeof(ldomain)) == -1) {
+           nodomain = 1;
+           return (0);
+       }
+       ldomain[MAXHOSTNAMELEN] = '\0';
+       if ((domainp = strchr(ldomain, '.')) == (char *)NULL) {
+           nodomain = 1;
+           return (0);
+       }
+       for (cp = ++domainp; *cp; ++cp)
+           if (isupper(*cp))
+               *cp = tolower(*cp);
+    }
+    return (!strcmp(domainp, rhost + len + 1));
+}
diff --git a/src/sgistuff/ta-rauth.c b/src/sgistuff/ta-rauth.c
new file mode 100644 (file)
index 0000000..700c7da
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ * 
+ * This software has been released under the terms of the IBM Public
+ * License.  For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+/*
+ * This code is used for application programs who want to transfer a
+ * token from the local system to the remote system.
+ */
+#include <afsconfig.h>
+#include <afs/param.h>
+
+RCSID
+    ("$Header$");
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+
+#include <afs/auth.h>
+#include <afs/cellconfig.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#include <signal.h>
+#include <strings.h>
+#if defined(AIX)
+#include <sys/syslog.h>
+#else /* defined(AIX) */
+#include <syslog.h>
+#endif /* defined(AIX) */
+#include <errno.h>
+#include <pwd.h>
+#include <afs/afsutil.h>
+
+
+#ifndef RAUTH_PORT
+#define RAUTH_PORT (601)
+#endif
+
+ /* ta_rauth provides a single entry point into the remote */
+ /* authentication scheme.  This allows us to simply pass the service */
+ /* name; this routine will in turn obtain whatever remote */
+ /* authentication information necessary and will negotiate with the */
+ /* remote connection.  There are three possible return codes: */
+ /*  (0) There is no remote authentication system; continue without */
+ /*      any authentication. */
+ /*  (1) Remote authentication was negotiated successfully */
+ /*  (-1) Remote authentication failed (but did exist) */
+ /*  (-2) The call could not complete due to internal failure */
+ /*  (-3) The remote connection failed */
+ /* Note that raddr is in *network* byte order! */
+
+int ta_debug = 0;
+
+int
+ta_rauth(s, svc_name, raddr)
+     int s;
+     char *svc_name;
+     struct in_addr raddr;
+{
+    char localName[64];
+    int code;
+    struct afsconf_dir *tdir;
+    struct ktc_principal tserver;
+    struct ktc_token token;
+    struct sockaddr_in name;
+
+    /* extract the token */
+
+    tdir = afsconf_Open(AFSDIR_CLIENT_ETC_DIRPATH);
+    if (!tdir) {
+       if (ta_debug) {
+           syslog(LOG_ERR, "ta_rauth: afsconf_Open failed\n");
+       }
+       return (-2);
+    }
+    code = afsconf_GetLocalCell(tdir, localName, sizeof(localName));
+    if (code) {
+       if (ta_debug) {
+           syslog(LOG_ERR, "ta_rauth: afsconf_GetLocalCell failed\n");
+       }
+       return (-2);
+    }
+    afsconf_Close(tdir);
+
+    strcpy(tserver.cell, localName);
+    strcpy(tserver.name, "afs");
+
+    code = ktc_GetToken(&tserver, &token, sizeof(token), NULL);
+    if (code) {
+       syslog(LOG_WARNING, "ta_rauth: no tokens available");
+       return 0;               /* try port without authentication */
+    }
+
+    name.sin_family = AF_INET;
+    name.sin_port = htons(RAUTH_PORT);
+    name.sin_addr = raddr;
+    if (connect(s, (struct sockaddr *)&name, sizeof(name)) == -1) {
+       extern int errno;
+
+       if (ta_debug) {
+           syslog(LOG_ERR,
+                  "ta_rauth(%s): connect call to (%d:%d) failed=%d\n",
+                  svc_name, raddr.s_addr, htons(RAUTH_PORT), errno);
+           perror("socket");
+       }
+       switch (errno) {
+#ifdef AFS_AIX_ENV
+           /* On conn failure aix doesn't return any error! */
+       case 0:
+#endif
+       case ECONNREFUSED:
+           return 0;
+       case ETIMEDOUT:
+       case ENETUNREACH:
+           return -3;
+       default:
+           return -2;
+       }
+    }
+
+    if (outtoken(s, &token, svc_name, localName) == 0) {
+       char result;
+
+       if (read(s, &result, 1) != 1) {
+           syslog(LOG_ERR, "Invalid return from remote authenticator\n");
+           exit(1);
+       }
+       if (result == '0')      /* remote authentication denied */
+           return -1;
+       else                    /* remote authentication allowed */
+           return 1;
+    }
+
+    return (-2);
+}
+
+/*
+ * outtoken:
+ *
+ * This routine writes a token on the specified file handle;
+ * The output format for a token is:
+ *
+ *   Field #    Contents         description
+ *    (0)       Service requested char[]
+ *    (1)       Version #        unsigned integer (< 2^32)
+ *    (2)       startTime        unsigned afs_int32 (< 2^32)
+ *    (3)       endTime          unsigned afs_int32 (< 2^32)
+ *    (4)       sessionKey       char[8]
+ *    (5)       kvno             short (< 2^16)
+ *    (6)       ticketLen        unsigned integer (< 2^32)
+ *    (7)       ticket           char[MAXKTCTICKETLEN]
+ *
+ *  All fields are comma separated except (4) and (5) because (4) is fixed
+ *  length; since field (7) is variable length, it is presumed to
+ *  begin after the ',' and to be ticketLen afs_int32.
+ */
+outtoken(s, token, svc, localName)
+     int s;
+     struct ktc_token *token;
+     char *svc, *localName;
+{
+    char buf[1024], *bp;
+    int count;
+
+    /* (0) - (3) */
+    sprintf(buf, "%s,%d,%s,%ld,%ld,", svc, 2, localName, token->startTime,
+           token->endTime);
+
+    /* (4) sessionKey */
+    bp = buf + strlen(buf);
+    memcpy(bp, &token->sessionKey, 8);
+    bp += 8;
+
+    /* (5) - (6) */
+    sprintf(bp, "%u,%u,", token->kvno, token->ticketLen);
+
+    /* (7) ticket */
+    bp += strlen(bp);
+    memcpy(bp, token->ticket, token->ticketLen);
+    bp += token->ticketLen;
+
+    if ((count = write(s, buf, (int)(bp - buf))) == -1) {
+       perror("outtoken write");
+       exit(1);
+    }
+    if (ta_debug) {
+       fprintf(stderr, "sent buffer %s\n", buf);
+    }
+    return 0;
+}