|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1983 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char Xsccsid[] = "derived from @(#)rcmd.c 5.17 (Berkeley) 6/27/88"; ! 22: static char sccsid[] = "@(#)kcmd.c 5.6 (Berkeley) 6/1/90"; ! 23: #endif /* not lint */ ! 24: ! 25: /* ! 26: * $Source: /mit/kerberos/src/appl/bsd/RCS/kcmd.c,v $ ! 27: * $Header: kcmd.c,v 4.16 89/05/17 10:54:31 jtkohl Exp $ ! 28: * ! 29: * static char *rcsid_kcmd_c = ! 30: * "$Header: kcmd.c,v 4.16 89/05/17 10:54:31 jtkohl Exp $"; ! 31: */ ! 32: ! 33: #include <sys/param.h> ! 34: #include <sys/file.h> ! 35: #include <sys/signal.h> ! 36: #include <sys/socket.h> ! 37: #include <sys/stat.h> ! 38: ! 39: #include <netinet/in.h> ! 40: ! 41: #include <netdb.h> ! 42: #include <errno.h> ! 43: #include <kerberosIV/des.h> ! 44: #include <kerberosIV/krb.h> ! 45: #include <kerberosIV/kparse.h> ! 46: #include <pwd.h> ! 47: #include <stdio.h> ! 48: #include <ctype.h> ! 49: ! 50: #ifndef MAXHOSTNAMELEN ! 51: #define MAXHOSTNAMELEN 64 ! 52: #endif ! 53: ! 54: extern errno; ! 55: char *index(), *malloc(), *krb_realmofhost(); ! 56: ! 57: #define START_PORT 5120 /* arbitrary */ ! 58: ! 59: kcmd(sock, ahost, rport, locuser, remuser, cmd, fd2p, ticket, service, realm, ! 60: cred, schedule, msg_data, laddr, faddr, authopts) ! 61: int *sock; ! 62: char **ahost; ! 63: u_short rport; ! 64: char *locuser, *remuser, *cmd; ! 65: int *fd2p; ! 66: KTEXT ticket; ! 67: char *service; ! 68: char *realm; ! 69: CREDENTIALS *cred; ! 70: Key_schedule schedule; ! 71: MSG_DAT *msg_data; ! 72: struct sockaddr_in *laddr, *faddr; ! 73: long authopts; ! 74: { ! 75: int s, timo = 1, pid; ! 76: long oldmask; ! 77: struct sockaddr_in sin, from; ! 78: char c; ! 79: #ifdef ATHENA_COMPAT ! 80: int lport = IPPORT_RESERVED - 1; ! 81: #else ! 82: int lport = START_PORT; ! 83: #endif ATHENA_COMPAT ! 84: struct hostent *hp; ! 85: int rc; ! 86: char *host_save; ! 87: int status; ! 88: ! 89: pid = getpid(); ! 90: hp = gethostbyname(*ahost); ! 91: if (hp == 0) { ! 92: /* fprintf(stderr, "%s: unknown host\n", *ahost); */ ! 93: return (-1); ! 94: } ! 95: ! 96: host_save = malloc(strlen(hp->h_name) + 1); ! 97: strcpy(host_save, hp->h_name); ! 98: *ahost = host_save; ! 99: ! 100: /* If realm is null, look up from table */ ! 101: if ((realm == NULL) || (realm[0] == '\0')) { ! 102: realm = krb_realmofhost(host_save); ! 103: } ! 104: ! 105: oldmask = sigblock(sigmask(SIGURG)); ! 106: for (;;) { ! 107: s = getport(&lport); ! 108: if (s < 0) { ! 109: if (errno == EAGAIN) ! 110: fprintf(stderr, ! 111: "kcmd(socket): All ports in use\n"); ! 112: else ! 113: perror("kcmd: socket"); ! 114: sigsetmask(oldmask); ! 115: return (-1); ! 116: } ! 117: fcntl(s, F_SETOWN, pid); ! 118: sin.sin_family = hp->h_addrtype; ! 119: #if defined(ultrix) || defined(sun) ! 120: bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length); ! 121: #else ! 122: bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, hp->h_length); ! 123: #endif /* defined(ultrix) || defined(sun) */ ! 124: sin.sin_port = rport; ! 125: if (connect(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0) ! 126: break; ! 127: (void) close(s); ! 128: if (errno == EADDRINUSE) { ! 129: lport--; ! 130: continue; ! 131: } ! 132: /* ! 133: * don't wait very long for Kerberos rcmd. ! 134: */ ! 135: if (errno == ECONNREFUSED && timo <= 4) { ! 136: /* sleep(timo); don't wait at all here */ ! 137: timo *= 2; ! 138: continue; ! 139: } ! 140: #if !(defined(ultrix) || defined(sun)) ! 141: if (hp->h_addr_list[1] != NULL) { ! 142: int oerrno = errno; ! 143: ! 144: fprintf(stderr, ! 145: "kcmd: connect to address %s: ", ! 146: inet_ntoa(sin.sin_addr)); ! 147: errno = oerrno; ! 148: perror(0); ! 149: hp->h_addr_list++; ! 150: bcopy(hp->h_addr_list[0], (caddr_t)&sin.sin_addr, ! 151: hp->h_length); ! 152: fprintf(stderr, "Trying %s...\n", ! 153: inet_ntoa(sin.sin_addr)); ! 154: continue; ! 155: } ! 156: #endif /* !(defined(ultrix) || defined(sun)) */ ! 157: if (errno != ECONNREFUSED) ! 158: perror(hp->h_name); ! 159: sigsetmask(oldmask); ! 160: return (-1); ! 161: } ! 162: lport--; ! 163: if (fd2p == 0) { ! 164: write(s, "", 1); ! 165: lport = 0; ! 166: } else { ! 167: char num[8]; ! 168: int s2 = getport(&lport), s3; ! 169: int len = sizeof (from); ! 170: ! 171: if (s2 < 0) { ! 172: status = -1; ! 173: goto bad; ! 174: } ! 175: listen(s2, 1); ! 176: (void) sprintf(num, "%d", lport); ! 177: if (write(s, num, strlen(num)+1) != strlen(num)+1) { ! 178: perror("kcmd(write): setting up stderr"); ! 179: (void) close(s2); ! 180: status = -1; ! 181: goto bad; ! 182: } ! 183: s3 = accept(s2, (struct sockaddr *)&from, &len); ! 184: (void) close(s2); ! 185: if (s3 < 0) { ! 186: perror("kcmd:accept"); ! 187: lport = 0; ! 188: status = -1; ! 189: goto bad; ! 190: } ! 191: *fd2p = s3; ! 192: from.sin_port = ntohs((u_short)from.sin_port); ! 193: if (from.sin_family != AF_INET || ! 194: from.sin_port >= IPPORT_RESERVED) { ! 195: fprintf(stderr, ! 196: "kcmd(socket): protocol failure in circuit setup.\n"); ! 197: goto bad2; ! 198: } ! 199: } ! 200: /* ! 201: * Kerberos-authenticated service. Don't have to send locuser, ! 202: * since its already in the ticket, and we'll extract it on ! 203: * the other side. ! 204: */ ! 205: /* (void) write(s, locuser, strlen(locuser)+1); */ ! 206: ! 207: /* set up the needed stuff for mutual auth, but only if necessary */ ! 208: if (authopts & KOPT_DO_MUTUAL) { ! 209: int sin_len; ! 210: *faddr = sin; ! 211: ! 212: sin_len = sizeof (struct sockaddr_in); ! 213: if (getsockname(s, (struct sockaddr *)laddr, &sin_len) < 0) { ! 214: perror("kcmd(getsockname)"); ! 215: status = -1; ! 216: goto bad2; ! 217: } ! 218: } ! 219: if ((status = krb_sendauth(authopts, s, ticket, service, *ahost, ! 220: realm, (unsigned long) getpid(), msg_data, ! 221: cred, schedule, ! 222: laddr, ! 223: faddr, ! 224: "KCMDV0.1")) != KSUCCESS) ! 225: goto bad2; ! 226: ! 227: (void) write(s, remuser, strlen(remuser)+1); ! 228: (void) write(s, cmd, strlen(cmd)+1); ! 229: ! 230: if ((rc=read(s, &c, 1)) != 1) { ! 231: if (rc==-1) { ! 232: perror(*ahost); ! 233: } else { ! 234: fprintf(stderr,"kcmd: bad connection with remote host\n"); ! 235: } ! 236: status = -1; ! 237: goto bad2; ! 238: } ! 239: if (c != 0) { ! 240: while (read(s, &c, 1) == 1) { ! 241: (void) write(2, &c, 1); ! 242: if (c == '\n') ! 243: break; ! 244: } ! 245: status = -1; ! 246: goto bad2; ! 247: } ! 248: sigsetmask(oldmask); ! 249: *sock = s; ! 250: return (KSUCCESS); ! 251: bad2: ! 252: if (lport) ! 253: (void) close(*fd2p); ! 254: bad: ! 255: (void) close(s); ! 256: sigsetmask(oldmask); ! 257: return (status); ! 258: } ! 259: ! 260: getport(alport) ! 261: int *alport; ! 262: { ! 263: struct sockaddr_in sin; ! 264: int s; ! 265: ! 266: sin.sin_family = AF_INET; ! 267: sin.sin_addr.s_addr = INADDR_ANY; ! 268: s = socket(AF_INET, SOCK_STREAM, 0); ! 269: if (s < 0) ! 270: return (-1); ! 271: for (;;) { ! 272: sin.sin_port = htons((u_short)*alport); ! 273: if (bind(s, (struct sockaddr *)&sin, sizeof (sin)) >= 0) ! 274: return (s); ! 275: if (errno != EADDRINUSE) { ! 276: (void) close(s); ! 277: return (-1); ! 278: } ! 279: (*alport)--; ! 280: #ifdef ATHENA_COMPAT ! 281: if (*alport == IPPORT_RESERVED/2) { ! 282: #else ! 283: if (*alport == IPPORT_RESERVED) { ! 284: #endif ATHENA_COMPAT ! 285: (void) close(s); ! 286: errno = EAGAIN; /* close */ ! 287: return (-1); ! 288: } ! 289: } ! 290: } ! 291:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.