From 4bab3e9801469e2d88851d72d45356d2b65cc16a Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Tue, 16 Aug 2005 19:00:44 +0000 Subject: [PATCH] STABLE14-sgistuff-missing-files-20050816 FIXES 20766 these were overzealously killed (by me) fix (cherry picked from commit 68f5f09832ae0b9207951df717a4e33910d9a147) --- src/sgistuff/Makefile.in | 14 +- src/sgistuff/herror.c | 69 +++++ src/sgistuff/rcmd.c | 600 +++++++++++++++++++++++++++++++++++++++ src/sgistuff/ta-rauth.c | 203 +++++++++++++ 4 files changed, 879 insertions(+), 7 deletions(-) create mode 100644 src/sgistuff/herror.c create mode 100644 src/sgistuff/rcmd.c create mode 100644 src/sgistuff/ta-rauth.c diff --git a/src/sgistuff/Makefile.in b/src/sgistuff/Makefile.in index 88e95bfc6..2f96069fa 100644 --- a/src/sgistuff/Makefile.in +++ b/src/sgistuff/Makefile.in @@ -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 index 000000000..bd47f45ff --- /dev/null +++ b/src/sgistuff/herror.c @@ -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 +#include + +RCSID + ("$Header$"); + +#ifndef AFS_DARWIN_ENV +#include +#include + +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 index 000000000..a27d7a495 --- /dev/null +++ b/src/sgistuff/rcmd.c @@ -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 +#include + +RCSID + ("$Header$"); + +#ifdef aiws /*AIX*/ +#include +#define MAXHOSTNAMELEN 64 /* use BSD's, not sys/param's */ +#define MAXPATHLEN 1024 /* from BSD */ +#include /* for SIOCSPGRP */ +#endif +#include +#include +#include +#include +#include +#include +#ifdef AFS_SUN5_ENV +#include +#endif +#include /* select() prototype */ +#include /* fd_set on older platforms */ +#include /* struct timeval, select() prototype */ +#ifndef FD_SET +# include /* fd_set on newer platforms */ +#endif +#include +#include +#include +#include +#include +#include +#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 +# 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 +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 + 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 + * +@ - group allowed + * -@ - group disallowed + * - - host 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 index 000000000..700c7dac6 --- /dev/null +++ b/src/sgistuff/ta-rauth.c @@ -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 +#include + +RCSID + ("$Header$"); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#if defined(AIX) +#include +#else /* defined(AIX) */ +#include +#endif /* defined(AIX) */ +#include +#include +#include + + +#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; +} -- 2.39.5