This commit was generated by cvs2svn to compensate for changes in r10768,

which included commits to RCS files with non-trunk default branches.
This commit is contained in:
gibbs 1995-09-15 06:13:43 +00:00
commit 6669165a88
7 changed files with 884 additions and 0 deletions

View File

@ -0,0 +1,12 @@
# @(#)Makefile 8.1 (Berkeley) 6/4/93
PROG= rkinitd
SRCS= ${RKINITOBJDIR}/rkinit_err.h rkinitd.c util.c rpc.c krb.c
CFLAGS+=-I${KRBOBJDIR} -I${RKINITOBJDIR}
DPADD= ${LIBKRB} ${LIBDES}
LDADD= -L${RKINITOBJDIR} -lrkinit -L${KRBOBJDIR} -lkrb \
-L${DESOBJDIR} -ldes
MAN8= rkinitd.8
.include <bsd.prog.mk>

View File

@ -0,0 +1,388 @@
/*
* $Id: krb.c,v 1.1 1993/07/29 22:45:19 dglo Exp gibbs $
* $Source: /usr/src/eBones/rkinitd/RCS/krb.c,v $
* $Author: dglo $
*
* This file contains all of the kerberos part of rkinitd.
*/
#if !defined(lint) && !defined(SABER) && !defined(LOCORE) && defined(RCS_HDRS)
static char *rcsid = "$Id: krb.c,v 1.1 1993/07/29 22:45:19 dglo Exp gibbs $";
#endif /* lint || SABER || LOCORE || RCS_HDRS */
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <syslog.h>
#include <netinet/in.h>
#include <setjmp.h>
#include <string.h>
#include <unistd.h>
#include <pwd.h>
#include <krb.h>
#include <des.h>
#include <rkinit.h>
#include <rkinit_private.h>
#include <rkinit_err.h>
#include "rkinitd.h"
#define FAILURE (!RKINIT_SUCCESS)
extern int errno;
static char errbuf[BUFSIZ];
typedef struct {
jmp_buf env;
} rkinitd_intkt_info;
#if defined(_AIX) && defined(_IBMR2)
#include <sys/id.h>
/*
* The RIOS has bizzarre ideas about changing uids around. They are
* such that the seteuid and setruid calls here fail. For this reason
* we are replacing the seteuid and setruid calls.
*
* The bizzarre ideas are as follows:
*
* The effective ID may be changed only to the current real or
* saved IDs.
*
* The saved uid may be set only if the real and effective
* uids are being set to the same value.
*
* The real uid may be set only if the effective
* uid is being set to the same value.
*/
#ifdef __STDC__
static int setruid(uid_t ruid)
#else
static int setruid(ruid)
uid_t ruid;
#endif /* __STDC__ */
{
uid_t euid;
euid = geteuid();
if (setuidx(ID_REAL | ID_EFFECTIVE, ruid) == -1)
return (-1);
return (setuidx(ID_EFFECTIVE, euid));
}
#ifdef __STDC__
static int seteuid(uid_t euid)
#else
static int seteuid(euid)
uid_t euid;
#endif /* __STDC__ */
{
uid_t ruid;
ruid = getuid();
if (setuidx(ID_SAVED | ID_REAL | ID_EFFECTIVE, euid) == -1)
return (-1);
return (setruid(ruid));
}
#ifdef __STDC__
static int setreuid(uid_t ruid, uid_t euid)
#else
static int setreuid(ruid, euid)
uid_t ruid;
uid_t euid;
#endif /* __STDC__ */
{
if (seteuid(euid) == -1)
return (-1);
return (setruid(ruid));
}
#ifdef __STDC__
static int setuid(uid_t uid)
#else
static int setuid(uid)
uid_t uid;
#endif /* __STDC__ */
{
return (setreuid(uid, uid));
}
#endif /* RIOS */
#ifdef __STDC__
static void this_phost(char *host, int hostlen)
#else
static void this_phost(host, hostlen)
char *host;
int hostlen;
#endif /* __STDC__ */
{
char this_host[MAXHOSTNAMELEN + 1];
BCLEAR(this_host);
if (gethostname(this_host, sizeof(this_host)) < 0) {
sprintf(errbuf, "gethostname: %s", sys_errlist[errno]);
rkinit_errmsg(errbuf);
error();
exit(1);
}
strncpy(host, krb_get_phost(this_host), hostlen - 1);
}
#ifdef __STDC__
static int decrypt_tkt(char *user, char *instance, char *realm, char *arg,
int (*key_proc)(), KTEXT *cipp)
#else
static int decrypt_tkt(user, instance, realm, arg, key_proc, cipp)
char *user;
char *instance;
char *realm;
char *arg;
int (*key_proc)();
KTEXT *cipp;
#endif /* __STDC__ */
{
MSG_DAT msg_data; /* Message data containing decrypted data */
KTEXT_ST auth; /* Authenticator */
AUTH_DAT auth_dat; /* Authentication data */
KTEXT cip = *cipp;
MSG_DAT scip;
int status = 0;
des_cblock key;
des_key_schedule sched;
char phost[MAXHOSTNAMELEN + 1];
struct sockaddr_in caddr; /* client internet address */
struct sockaddr_in saddr; /* server internet address */
rkinitd_intkt_info *rii = (rkinitd_intkt_info *)arg;
u_char enc_data[MAX_KTXT_LEN];
SBCLEAR(auth);
SBCLEAR(auth_dat);
SBCLEAR(scip);
BCLEAR(enc_data);
scip.app_data = enc_data;
/*
* Exchange with the client our response from the KDC (ticket encrypted
* in user's private key) for the same ticket encrypted in our
* (not yet known) session key.
*/
rpc_exchange_tkt(cip, &scip);
/*
* Get the authenticator
*/
SBCLEAR(auth);
rpc_getauth(&auth, &caddr, &saddr);
/*
* Decode authenticator and extract session key. The first zero
* means we don't care what host this comes from. This needs to
* be done with euid of root so that /etc/srvtab can be read.
*/
BCLEAR(phost);
this_phost(phost, sizeof(phost));
/*
* This function has to use longjmp to return to the caller
* because the kerberos library routine that calls it doesn't
* pay attention to the return value it gives. That means that
* if any of these routines failed, the error returned to the client
* would be "password incorrect".
*/
if ((status = krb_rd_req(&auth, KEY, phost, caddr.sin_addr.s_addr,
&auth_dat, KEYFILE))) {
sprintf(errbuf, "krb_rd_req: %s", krb_err_txt[status]);
rkinit_errmsg(errbuf);
longjmp(rii->env, status);
}
bcopy(auth_dat.session, key, sizeof(key));
if (des_key_sched(&key, sched)) {
sprintf(errbuf, "Error in des_key_sched");
rkinit_errmsg(errbuf);
longjmp(rii->env, RKINIT_DES);
}
/* Decrypt the data. */
if ((status =
krb_rd_priv((u_char *)scip.app_data, scip.app_length,
sched, key, &caddr, &saddr, &msg_data)) == KSUCCESS) {
cip->length = msg_data.app_length;
bcopy(msg_data.app_data, cip->dat, msg_data.app_length);
cip->dat[cip->length] = 0;
}
else {
sprintf(errbuf, "krb_rd_priv: %s", krb_err_txt[status]);
rkinit_errmsg(errbuf);
longjmp(rii->env, status);
}
return(status);
}
#ifdef __STDC__
static int validate_user(char *aname, char *inst, char *realm,
char *username, char *errmsg)
#else
static int validate_user(aname, inst, realm, username, errmsg)
char *aname;
char *inst;
char *realm;
char *username;
char *errmsg;
#endif /* __STDC__ */
{
struct passwd *pwnam; /* For access_check and uid */
AUTH_DAT auth_dat;
int kstatus = KSUCCESS;
SBCLEAR(auth_dat);
if ((pwnam = getpwnam(username)) == NULL) {
sprintf(errmsg, "%s does not exist on the remote host.", username);
return(FAILURE);
}
strcpy(auth_dat.pname, aname);
strcpy(auth_dat.pinst, inst);
strcpy(auth_dat.prealm, realm);
if (seteuid(pwnam->pw_uid) < 0) {
sprintf(errmsg, "Failure setting euid to %d: %s\n", pwnam->pw_uid,
sys_errlist[errno]);
strcpy(errbuf, errmsg);
error();
return(FAILURE);
}
kstatus = kuserok(&auth_dat, username);
if (seteuid(0) < 0) {
sprintf(errmsg, "Failure setting euid to 0: %s\n",
sys_errlist[errno]);
strcpy(errbuf, errmsg);
error();
return(FAILURE);
}
if (kstatus != KSUCCESS) {
sprintf(errmsg, "%s has not allowed you to log in with", username);
if (strlen(auth_dat.pinst))
sprintf(errmsg, "%s %s.%s", errmsg, auth_dat.pname,
auth_dat.pinst);
else
sprintf(errmsg, "%s %s", errmsg, auth_dat.pname);
sprintf(errmsg, "%s@%s tickets.", errmsg, auth_dat.prealm);
return(FAILURE);
}
/*
* Set real uid to owner of ticket file. The library takes care
* of making the appropriate change.
*/
if (setruid(pwnam->pw_uid) < 0) {
sprintf(errmsg, "Failure setting ruid to %d: %s\n", pwnam->pw_uid,
sys_errlist[errno]);
strcpy(errbuf, errmsg);
error();
return(FAILURE);
}
return(RKINIT_SUCCESS);
}
#ifdef __STDC__
int get_tickets(int version)
#else
int get_tickets(version)
int version;
#endif /* __STDC__ */
{
rkinit_info info;
AUTH_DAT auth_dat;
int status;
char errmsg[BUFSIZ]; /* error message for client */
rkinitd_intkt_info rii;
SBCLEAR(info);
SBCLEAR(auth_dat);
BCLEAR(errmsg);
SBCLEAR(rii);
rpc_get_rkinit_info(&info);
/*
* The validate_user routine makes sure that the principal in question
* is allowed to log in as username, and if so, does a setuid(localuid).
* If there is an access violation or an error in setting the uid,
* an error is returned and the string errmsg is initialized with
* an error message that will be sent back to the client.
*/
if ((status = validate_user(info.aname, info.inst, info.realm,
info.username, errmsg)) != RKINIT_SUCCESS) {
rpc_send_error(errmsg);
exit(0);
}
else
rpc_send_success();
/*
* If the name of a ticket file was specified, set it; otherwise,
* just use the default.
*/
if (strlen(info.tktfilename))
krb_set_tkt_string(info.tktfilename);
/*
* Call internal kerberos library routine so that we can supply
* our own ticket decryption routine.
*/
/*
* We need a setjmp here because krb_get_in_tkt ignores the
* return value of decrypt_tkt. Thus if we want any of its
* return values to reach the client, we have to jump out of
* the routine.
*/
if (setjmp(rii.env) == 0) {
if ((status = krb_get_in_tkt(info.aname, info.inst, info.realm,
info.sname, info.sinst, info.lifetime,
NULL, decrypt_tkt, (char *)&rii))) {
strcpy(errmsg, krb_err_txt[status]);
rpc_send_error(errmsg);
}
else
rpc_send_success();
}
else
rpc_send_error(errbuf);
return(RKINIT_SUCCESS);
}

View File

@ -0,0 +1,42 @@
.\"
.\" $Header: /local/cvsfiles/kerberos/src/appl/rkinit/man/rkinitd.8,v 1.1 1991/12/03 23:21:32 eichin Exp $
.\" $Source: /local/cvsfiles/kerberos/src/appl/rkinit/man/rkinitd.8,v $
.\" $Author: eichin $
.\"
.\"
.TH RKINITD 8 "November 12, 1989"
.UC 4
.SH NAME
rkinitd \- server for
.I rkinit,
a remote kerberos ticket establishment utility
.SH SYNOPSIS
.B rkinitd
.SH DESCRIPTION
.I rkinitd
is the server for
.I rkinit.
See
.IR rkinit (1)
for information about
.I rkinit.
.I rkinitd
is started from inetd and must be run as root or be installed
setuid(root) as it needs to be able to read /etc/athena/srvtab and
change its uid to create tickets.
.I rkinitd
times out in 60 seconds if the transaction is not completed.
.I rkinitd
must be running on a machine that is registered for rlogin
service; that is, the host must have a srvtab containing an rcmd.<host>
key where <host> is the value returned by the
.IR krb_get_phost (3)
kerberos library call.
.SH SEE ALSO
rkinit(1), inetd(8), kerberos(1), kerberos(3)
.SH AUTHOR
Emanuel Jay Berkenbilt (MIT-Project Athena)

View File

@ -0,0 +1,137 @@
/*
* $Id: rkinitd.c,v 1.1 1993/12/10 18:54:19 dglo Exp gibbs $
* $Source: /usr/src/eBones/rkinitd/RCS/rkinitd.c,v $
* $Author: dglo $
*
* This is the main source file for rkinit
*/
#if !defined(lint) && !defined(SABER) && !defined(LOCORE) && defined(RCS_HDRS)
static char *rcsid = "$Id: rkinitd.c,v 1.1 1993/12/10 18:54:19 dglo Exp gibbs $";
#endif /* lint || SABER || LOCORE || RCS_HDRS */
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <strings.h>
#include <signal.h>
#include <sys/time.h>
#include <pwd.h>
#include <unistd.h>
#include <krb.h>
#include <des.h>
#include <syslog.h>
#include <rkinit.h>
#include <rkinit_err.h>
#include <rkinit_private.h>
#include "rkinitd.h"
extern int errno;
static int inetd = TRUE; /* True if we were started by inetd */
#ifdef __STDC__
static void usage(void)
#else
static void usage()
#endif /* __STDC__ */
{
syslog(LOG_ERR, "rkinitd usage: rkinitd [-notimeout]\n");
exit(1);
}
#ifdef __STDC__
void error(void)
#else
void error()
#endif /* __STDC__ */
{
char errbuf[BUFSIZ];
strcpy(errbuf, rkinit_errmsg(0));
if (strlen(errbuf)) {
if (inetd)
syslog(LOG_ERR, "rkinitd: %s", errbuf);
else
fprintf(stderr, "rkinitd: %s\n", errbuf);
}
}
int
#ifdef __STDC__
main(int argc, char *argv[])
#else
main(argc, argv)
int argc;
char *argv[];
#endif /* __STDC__ */
{
int version; /* Version of the transaction */
int notimeout = FALSE; /* Should we not timeout? */
static char *envinit[1]; /* Empty environment */
extern char **environ; /* This process's environment */
int status = 0; /* General error code */
/*
* Clear the environment so that this process does not inherit
* kerberos ticket variable information from the person who started
* the process (if a person started it...).
*/
environ = envinit;
/* Initialize com_err error table */
init_rkin_err_tbl();
#ifdef DEBUG
/* This only works if the library was compiled with DEBUG defined */
rki_i_am_server();
#endif /* DEBUG */
/*
* Make sure that we are running as root or can arrange to be
* running as root. We need both to be able to read /etc/srvtab
* and to be able to change uid to create tickets.
*/
(void) setuid(0);
if (getuid() != 0) {
syslog(LOG_ERR, "rkinitd: not running as root.\n");
exit(1);
}
/* Determine whether to time out */
if (argc == 2) {
if (strcmp(argv[1], "-notimeout"))
usage();
else
notimeout = TRUE;
}
else if (argc != 1)
usage();
inetd = setup_rpc(notimeout);
if ((status = choose_version(&version) != RKINIT_SUCCESS)) {
error();
exit(1);
}
if ((status = get_tickets(version) != RKINIT_SUCCESS)) {
error();
exit(1);
}
exit(0);
}

View File

@ -0,0 +1,34 @@
/*
* $Id: rkinitd.h,v 1.1 1993/12/10 19:02:10 dglo Exp gibbs $
* $Source: /usr/src/eBones/rkinitd/RCS/rkinitd.h,v $
* $Author: dglo $
*
* This header file contains function declarations for use for rkinitd
*/
#ifndef __RKINITD_H__
#define __RKINITD_H__
#if !defined(lint) && !defined(SABER) && !defined(LOCORE) && defined(RCS_HDRS)
static char *rcsid_rkinitd_h = "$Id: rkinitd.h,v 1.1 1993/12/10 19:02:10 dglo Exp gibbs $";
#endif /* lint || SABER || LOCORE || RCS_HDRS */
#ifdef __STDC__
#define RK_PROTO(x) x
#else
#define RK_PROTO(x) ()
#endif /* __STDC__ */
int get_tickets RK_PROTO((int));
void error RK_PROTO((void));
int setup_rpc RK_PROTO((int)) ;
void rpc_exchange_version_info RK_PROTO((int *, int *, int, int));
void rpc_get_rkinit_info RK_PROTO((rkinit_info *));
void rpc_send_error RK_PROTO((char *));
void rpc_send_success RK_PROTO((void));
void rpc_exchange_tkt RK_PROTO((KTEXT, MSG_DAT *));
void rpc_getauth RK_PROTO((KTEXT, struct sockaddr_in *, struct sockaddr_in *));
int choose_version RK_PROTO((int *));
#endif /* __RKINITD_H__ */

View File

@ -0,0 +1,222 @@
/*
* $Id: rpc.c,v 1.1 1993/12/10 18:59:29 dglo Exp gibbs $
* $Source: /usr/src/eBones/rkinitd/RCS/rpc.c,v $
* $Author: dglo $
*
* This file contains the network parts of the rkinit server.
*/
#if !defined(lint) && !defined(SABER) && !defined(LOCORE) && defined(RCS_HDRS)
static char *rcsid = "$Id: rpc.c,v 1.1 1993/12/10 18:59:29 dglo Exp gibbs $";
#endif /* lint || SABER || LOCORE || RCS_HDRS */
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <syslog.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <rkinit.h>
#include <rkinit_err.h>
#include <rkinit_private.h>
#include "rkinitd.h"
#define RKINITD_TIMEOUT 60
extern int errno;
static int in; /* sockets */
static int out;
static char errbuf[BUFSIZ];
void error();
#ifdef __STDC__
static void timeout(int signal)
#else
static void timeout(signal)
int signal;
#endif /* __STDC__ */
{
syslog(LOG_WARNING, "rkinitd timed out.\n");
exit(1);
return;
}
/*
* This function does all the network setup for rkinitd.
* It returns true if we were started from inetd, or false if
* we were started from the commandline.
* It causes the program to exit if there is an error.
*/
#ifdef __STDC__
int setup_rpc(int notimeout)
#else
int setup_rpc(notimeout)
int notimeout; /* True if we should not timeout */
#endif /* __STDC__ */
{
struct itimerval timer; /* Time structure for timeout */
/* For now, support only inetd. */
in = 0;
out = 1;
if (! notimeout) {
SBCLEAR(timer);
/* Set up an itimer structure to send an alarm signal after timeout
seconds. */
timer.it_interval.tv_sec = RKINITD_TIMEOUT;
timer.it_interval.tv_usec = 0;
timer.it_value = timer.it_interval;
/* Start the timer. */
if (setitimer (ITIMER_REAL, &timer, (struct itimerval *)0) < 0) {
sprintf(errbuf, "setitimer: %s", sys_errlist[errno]);
rkinit_errmsg(errbuf);
error();
exit(1);
}
signal(SIGALRM, timeout);
}
return(TRUE);
}
#ifdef __STDC__
void rpc_exchange_version_info(int *c_lversion, int *c_hversion,
int s_lversion, int s_hversion)
#else
void rpc_exchange_version_info(c_lversion, c_hversion, s_lversion, s_hversion)
int *c_lversion;
int *c_hversion;
int s_lversion;
int s_hversion;
#endif /* __STDC__ */
{
u_char version_info[VERSION_INFO_SIZE];
u_int32_t length = sizeof(version_info);
if (rki_get_packet(in, MT_CVERSION, &length, (char *)version_info) !=
RKINIT_SUCCESS) {
error();
exit(1);
}
*c_lversion = version_info[0];
*c_hversion = version_info[1];
version_info[0] = s_lversion;
version_info[1] = s_hversion;
if (rki_send_packet(out, MT_SVERSION, length, (char *)version_info) !=
RKINIT_SUCCESS) {
error();
exit(1);
}
}
#ifdef __STDC__
void rpc_get_rkinit_info(rkinit_info *info)
#else
void rpc_get_rkinit_info(info)
rkinit_info *info;
#endif /* __STDC__ */
{
u_int32_t length = sizeof(rkinit_info);
if (rki_get_packet(in, MT_RKINIT_INFO, &length, (char *)info)) {
error();
exit(1);
}
info->lifetime = ntohl(info->lifetime);
}
#ifdef __STDC__
void rpc_send_error(char *errmsg)
#else
void rpc_send_error(errmsg)
char *errmsg;
#endif /* __STDC__ */
{
if (rki_send_packet(out, MT_STATUS, strlen(errmsg), errmsg)) {
error();
exit(1);
}
}
#ifdef __STDC__
void rpc_send_success(void)
#else
void rpc_send_success()
#endif /* __STDC__ */
{
if (rki_send_packet(out, MT_STATUS, 0, "")) {
error();
exit(1);
}
}
#ifdef __STDC__
void rpc_exchange_tkt(KTEXT cip, MSG_DAT *scip)
#else
void rpc_exchange_tkt(cip, scip)
KTEXT cip;
MSG_DAT *scip;
#endif /* __STDC__ */
{
u_int32_t length = MAX_KTXT_LEN;
if (rki_send_packet(out, MT_SKDC, cip->length, (char *)cip->dat)) {
error();
exit(1);
}
if (rki_get_packet(in, MT_CKDC, &length, (char *)scip->app_data)) {
error();
exit(1);
}
scip->app_length = length;
}
#ifdef __STDC__
void rpc_getauth(KTEXT auth, struct sockaddr_in *caddr,
struct sockaddr_in *saddr)
#else
void rpc_getauth(auth, caddr, saddr)
KTEXT auth;
struct sockaddr_in *caddr;
struct sockaddr_in *saddr;
#endif /* __STDC__ */
{
int addrlen = sizeof(struct sockaddr_in);
if (rki_rpc_get_ktext(in, auth, MT_AUTH)) {
error();
exit(1);
}
if (getpeername(in, (struct sockaddr *)caddr, &addrlen) < 0) {
sprintf(errbuf, "getpeername: %s", sys_errlist[errno]);
rkinit_errmsg(errbuf);
error();
exit(1);
}
if (getsockname(out, (struct sockaddr *)saddr, &addrlen) < 0) {
sprintf(errbuf, "getsockname: %s", sys_errlist[errno]);
rkinit_errmsg(errbuf);
error();
exit(1);
}
}

View File

@ -0,0 +1,49 @@
/*
* $Id: util.c,v 1.1 1993/12/10 18:59:29 dglo Exp gibbs $
* $Source: /usr/src/eBones/rkinitd/RCS/util.c,v $
* $Author: dglo $
*
* This file contains general rkinit server utilities.
*/
#if !defined(lint) && !defined(SABER) && !defined(LOCORE) && defined(RCS_HDRS)
static char *rcsid = "$Id: util.c,v 1.1 1993/12/10 18:59:29 dglo Exp gibbs $";
#endif /* lint || SABER || LOCORE || RCS_HDRS */
#include <stdio.h>
#include <rkinit.h>
#include <rkinit_err.h>
#include <rkinit_private.h>
#include "rkinitd.h"
static char errbuf[BUFSIZ];
void rpc_exchange_version_info();
void error();
#ifdef __STDC__
int choose_version(int *version)
#else
int choose_version(version)
int *version;
#endif /* __STDC__ */
{
int c_lversion; /* lowest version number client supports */
int c_hversion; /* highest version number client supports */
int status = RKINIT_SUCCESS;
rpc_exchange_version_info(&c_lversion, &c_hversion,
RKINIT_LVERSION, RKINIT_HVERSION);
*version = min(RKINIT_HVERSION, c_hversion);
if (*version < max(RKINIT_LVERSION, c_lversion)) {
sprintf(errbuf,
"Can't run version %d client against version %d server.",
c_hversion, RKINIT_HVERSION);
rkinit_errmsg(errbuf);
return(RKINIT_VERSION);
}
return(status);
}