[297] in Kerberos-V5-bugs
appl-bsd.patch
daemon@ATHENA.MIT.EDU (Marc Horowitz)
Fri Feb 26 17:55:30 1993
To: krb5-bugs@MIT.EDU
Date: Fri, 26 Feb 1993 17:51:20 -0500
From: Marc Horowitz <marc@Aktis.COM>
** Complete reworking of bsd stuff. In production use at GZA on Sun's
and NeXT's
./appl/bsd/Imakefile
./appl/bsd/kcmd.c
./appl/bsd/krcp.c
./appl/bsd/krlogin.c
./appl/bsd/krlogind.c
./appl/bsd/krsh.c
./appl/bsd/krshd.c
./appl/bsd/login.c
./appl/bsd/logutil.c
Significant changes in general:
updated to use new krb5_sname_to_principal function
Many portability and code fixes.
Imakefile:
added -DLOGIN_PROGRAM to compilation of login.krb5
krlogind.c:
added standalone debugging mode, port can be specified
added #define CRYPT by default
added cpp symbol LOGIN_PROGRAM so the path to login.krb5 can
be passed in
don't vhangup() in debug mode
added setsid() call in the right place for POSIX and sun
changed the way krlogind and login.krb5 work together.
Info is no longer passed in-band.
krsh.c:
added cpp symbol RLOGIN_PROGRAM so the path to the berkeley
rlogin can be passed in.
krshd.c:
(changes relative to krb5-bugs [0244])
added standalone debugging mode, port can be specified
*** ./appl/bsd/Imakefile.old 1992/11/25 15:08:11
--- ./appl/bsd/Imakefile 1992/12/09 14:58:27
***************
*** 29,35 ****
#else
LOCAL_LIBRARIES = $(KLIB)
#endif
! DEFINES = $(APPL_BSD_DEF)
CLIENTSRCS= krcp.c krlogin.c krsh.c kcmd.c logutil.c
CLIENTOBJS= krcp.o krlogin.o krsh.o kcmd.o logutil.o
--- 29,35 ----
#else
LOCAL_LIBRARIES = $(KLIB)
#endif
! DEFINES = $(APPL_BSD_DEF) -DLOGIN_PROGRAM=\"$(SERVER_BINDIR)/login.krb5\"
CLIENTSRCS= krcp.c krlogin.c krsh.c kcmd.c logutil.c
CLIENTOBJS= krcp.o krlogin.o krsh.o kcmd.o logutil.o
***************
*** 45,53 ****
SRCS= $(CLIENTSRCS) $(SERVERSRCS)
#ifdef CrayArchitecture
! all:: rsh rcp rlogin krshd
#else
! all:: rsh rcp rlogin krshd krlogind
#endif
NormalProgramTarget(rsh,krsh.o kcmd.o,$(DEPLIBS),$(LOCAL_LIBRARIES),)
--- 45,53 ----
SRCS= $(CLIENTSRCS) $(SERVERSRCS)
#ifdef CrayArchitecture
! all:: rsh rcp rlogin krshd login.krb5
#else
! all:: rsh rcp rlogin krshd login.krb5 krlogind
#endif
NormalProgramTarget(rsh,krsh.o kcmd.o,$(DEPLIBS),$(LOCAL_LIBRARIES),)
***************
*** 61,66 ****
--- 61,70 ----
NormalProgramTarget(krshd,krshd.o kcmd.o logutil.o,$(DEPLIBS),$(LOCAL_LIBRARIES),)
Krb5InstallServerProgram(krshd)
+
+ /* The only thing login.krb5 needs from libkrb is setenv. sigh. */
+ NormalProgramTarget(login.krb5,login.o logutil.o,$(DEPLIBS),$(LOCAL_LIBRARIES),)
+ InstallProgram(login.krb5,$(SERVER_BINDIR))
#ifndef CrayArchitecture
NormalProgramTarget(krlogind,krlogind.o logutil.o kcmd.o,$(DEPLIBS),$(LOCAL_LIBRARIES),)
*** ./appl/bsd/krsh.c.old 1992/12/07 15:19:32
--- ./appl/bsd/krsh.c 1992/12/09 14:55:33
***************
*** 77,85 ****
--- 77,89 ----
char *krb_realm = (char *)0;
void try_normal();
#define UCB_RSH "/usr/ucb/rsh"
+ #ifndef RLOGIN_PROGRAM
#define RLOGIN_PROGRAM "/nfs/kerberos/bin/sun3/rlogin"
+ #endif
#else /* KERBEROS */
+ #ifndef RLOGIN_PROGRAM
#define RLOGIN_PROGRAM "/usr/ucb/rlogin"
+ #endif
#endif /* KERBEROS */
#define mask(s) (1 << ((s) - 1))
*** ./appl/bsd/kcmd.c.old 1992/12/07 13:54:58
--- ./appl/bsd/kcmd.c 1992/12/09 15:32:52
***************
*** 136,147 ****
fprintf(stderr,"kcmd: no memory\n");
return(-1);
}
! if ((realm == NULL) || (realm[0] == '\0')) {
! krb5_sname_to_principal(host_save,service,1,&ret_cred->server);
! }
! else {
! sprintf(tmpstr,"%s/%s@%s",service,host_save,realm);
! krb5_parse_name(tmpstr,&ret_cred->server);
}
#ifdef sgi
oldmask = sigignore(sigmask(SIGURG));
--- 136,152 ----
fprintf(stderr,"kcmd: no memory\n");
return(-1);
}
! krb5_sname_to_principal(host_save,service,KRB5_NT_SRV_HST,
! &ret_cred->server);
! if (realm && *realm) {
! char *copyrealm;
! krb5_data rdata;
!
! rdata.length = strlen(realm);
! rdata.data = (char *) malloc(rdata.length+1);
! strcpy(rdata.data, realm);
!
! krb5_princ_set_realm(ret_cred->server, &rdata);
}
#ifdef sgi
oldmask = sigignore(sigmask(SIGURG));
*** ./appl/bsd/krshd.c.old 1992/09/29 14:45:38
--- ./appl/bsd/krshd.c 1992/12/09 15:06:36
***************
*** 153,161 ****
#include <com_err.h>
! #define ARGSTR "rRkK?"
#else /* !KERBEROS */
! #define ARGSTR "rR?"
char *strsave();
#endif /* KERBEROS */
--- 153,161 ----
#include <com_err.h>
! #define ARGSTR "rRkKD:?"
#else /* !KERBEROS */
! #define ARGSTR "rRD:?"
char *strsave();
#endif /* KERBEROS */
***************
*** 172,178 ****
#endif /* CRAY */
int errno;
! char *index(), *rindex(), *strncat();
/*VARARGS1*/
int error();
--- 172,184 ----
#endif /* CRAY */
int errno;
! char *strncat();
! #ifndef index
! char *index();
! #endif
! #ifndef rindex
! char *rindex();
! #endif
/*VARARGS1*/
int error();
***************
*** 191,196 ****
--- 197,204 ----
extern char *optarg;
char *options, ch;
int i;
+ int fd;
+ int debug_port = 0;
#ifdef CRAY
secflag = sysconf(_SC_CRAY_SECURE_SYS);
***************
*** 241,246 ****
--- 249,257 ----
if (must_pass_one)
must_pass_one = 0;
break;
+ case 'D':
+ debug_port = atoi(optarg);
+ break;
#ifdef KERBEROS
case 'k':
must_pass_one = 1; /* If just 'k', any one check must succeed */
***************
*** 261,272 ****
argv += optind;
fromlen = sizeof (from);
! if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
! fprintf(stderr, "%s: ", progname);
! perror("getpeername");
! _exit(1);
}
! if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
sizeof (on)) < 0)
syslog(LOG_WARNING,
"setsockopt (SO_KEEPALIVE): %m");
--- 272,319 ----
argv += optind;
fromlen = sizeof (from);
!
! if (debug_port) {
! int s;
! struct sockaddr_in sin;
!
! if ((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) {
! fprintf(stderr, "Error in socket: %s\n", strerror(errno));
! exit(2);
! }
!
! bzero((char *) &sin,sizeof(sin));
! sin.sin_family = AF_INET;
! sin.sin_port = htons(debug_port);
! sin.sin_addr.s_addr = INADDR_ANY;
!
! if ((bind(s, (struct sockaddr *) &sin, sizeof(sin))) < 0) {
! fprintf(stderr, "Error in bind: %s\n", strerror(errno));
! exit(2);
! }
!
! if ((listen(s, 5)) < 0) {
! fprintf(stderr, "Error in listen: %s\n", strerror(errno));
! exit(2);
! }
!
! if ((fd = accept(s, &from, &fromlen)) < 0) {
! fprintf(stderr, "Error in accept: %s\n", strerror(errno));
! exit(2);
! }
!
! close(s);
! } else {
! if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
! fprintf(stderr, "%s: ", progname);
! perror("getpeername");
! _exit(1);
! }
!
! fd = 0;
}
!
! if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&on,
sizeof (on)) < 0)
syslog(LOG_WARNING,
"setsockopt (SO_KEEPALIVE): %m");
***************
*** 273,283 ****
#if defined(BSD) && BSD >= 43
linger.l_onoff = 1;
linger.l_linger = 60; /* XXX */
! if (setsockopt(0, SOL_SOCKET, SO_LINGER, (char *)&linger,
sizeof (linger)) < 0)
syslog(LOG_WARNING , "setsockopt (SO_LINGER): %m");
#endif
! doit(dup(0), &from);
}
#ifdef CRAY
--- 320,332 ----
#if defined(BSD) && BSD >= 43
linger.l_onoff = 1;
linger.l_linger = 60; /* XXX */
! if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *)&linger,
sizeof (linger)) < 0)
syslog(LOG_WARNING , "setsockopt (SO_LINGER): %m");
#endif
! doit(dup(fd), &from);
!
!
}
#ifdef CRAY
***************
*** 318,324 ****
#endif /* CRAY */
#endif /* KERBEROS */
! char **environ;
char ttyn[12]; /* Line string for wtmp entries */
#if defined (alliant) /* Alliant compiler complains of too many
--- 367,373 ----
#endif /* CRAY */
#endif /* KERBEROS */
! extern char **environ;
char ttyn[12]; /* Line string for wtmp entries */
#if defined (alliant) /* Alliant compiler complains of too many
***************
*** 535,552 ****
peeraddr.addrtype = fromp->sin_family;
peeraddr.length = SIZEOF_INADDR;
peeraddr.contents = (krb5_octet *)&fromp->sin_addr;
! strcpy(srv_name, "host/");
! gethostname(def_host, 100);
! strcat(srv_name, def_host);
! if (status = krb5_parse_name(srv_name, &server)) {
syslog(LOG_ERR, "parse server name %s: %s", "host",
error_message(status));
exit(1);
}
! krb5_princ_type(server) = KRB5_NT_SRV_HST;
! krb5_init_ets();
!
if (status = krb5_recvauth(&f,
"KCMDV0.1",
server,
--- 584,599 ----
peeraddr.addrtype = fromp->sin_family;
peeraddr.length = SIZEOF_INADDR;
peeraddr.contents = (krb5_octet *)&fromp->sin_addr;
!
! krb5_init_ets();
! if (status = krb5_sname_to_principal(NULL,"host",KRB5_NT_SRV_HST,
! &server)) {
syslog(LOG_ERR, "parse server name %s: %s", "host",
error_message(status));
exit(1);
}
!
if (status = krb5_recvauth(&f,
"KCMDV0.1",
server,
***************
*** 572,578 ****
error("Error no memory\n");
exit(1);
}
! getstr(remuser, sizeof(locuser), "remuser");
}
/* These two reads will be used in the next release to obtain
--- 619,625 ----
error("Error no memory\n");
exit(1);
}
! getstr(f, remuser, sizeof(locuser), "remuser");
}
/* These two reads will be used in the next release to obtain
***************
*** 597,606 ****
}
#else
! getstr(remuser, sizeof(remuser), "remuser");
#endif /* KERBEROS */
! getstr(locuser, sizeof(locuser), "locuser");
! getstr(cmdbuf, sizeof(cmdbuf), "command");
#ifdef KERBEROS
if (!(remuser = malloc(sizeof(locuser) + 1))){
--- 644,653 ----
}
#else
! getstr(f, remuser, sizeof(remuser), "remuser");
#endif /* KERBEROS */
! getstr(f, locuser, sizeof(locuser), "locuser");
! getstr(f, cmdbuf, sizeof(cmdbuf), "command");
#ifdef KERBEROS
if (!(remuser = malloc(sizeof(locuser) + 1))){
***************
*** 607,613 ****
error("Error no memory\n");
exit(1);
}
! getstr(remuser, sizeof(locuser), "remuser");
#endif
#ifdef CRAY
--- 654,660 ----
error("Error no memory\n");
exit(1);
}
! getstr(f, remuser, sizeof(locuser), "remuser");
#endif
#ifdef CRAY
***************
*** 1083,1089 ****
! getstr(buf, cnt, err)
char *buf;
int cnt;
char *err;
--- 1130,1137 ----
! getstr(fd, buf, cnt, err)
! int fd;
char *buf;
int cnt;
char *err;
***************
*** 1091,1097 ****
char c;
do {
! if (read(0, &c, 1) != 1)
exit(1);
*buf++ = c;
if (--cnt == 0) {
--- 1139,1145 ----
char c;
do {
! if (read(fd, &c, 1) != 1)
exit(1);
*buf++ = c;
if (--cnt == 0) {
*** ./appl/bsd/login.c.old 1993/02/26 22:20:55
--- ./appl/bsd/login.c 1993/02/26 22:21:20
***************
*** 6,12 ****
#ifndef lint
static char rcsid_login_c[] = "$Id$";
! #endif lint
/*
* Copyright (c) 1980, 1987, 1988 The Regents of the University of California.
--- 6,12 ----
#ifndef lint
static char rcsid_login_c[] = "$Id$";
! #endif /* lint */
/*
* Copyright (c) 1980, 1987, 1988 The Regents of the University of California.
***************
*** 27,33 ****
#ifndef lint
char copyright[] =
! "@(#) Copyright (c) 1980, 1987, 1988 The Regents of the University of California.\n\
All rights reserved.\n";
#endif /* not lint */
--- 27,33 ----
#ifndef lint
char copyright[] =
! "@(#) Copyright (c) 1980, 1987, 1988 The Regents of the University of California.\n\
All rights reserved.\n";
#endif /* not lint */
***************
*** 35,63 ****
static char sccsid[] = "@(#)login.c 5.25 (Berkeley) 1/6/89";
#endif /* not lint */
! #define KERBEROS
!
! /*
! * login -f name (for pre-authenticated login)
! * login name (for non-authenticated/non-authorized login)
! */
!
! #define VFS
! #define BYPASS_ROOT_CHK
!
#include <sys/param.h>
! #ifndef VFS
#include <sys/quota.h>
! #endif VFS
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/file.h>
#include <sys/ioctl.h>
!
#include <utmp.h>
#include <signal.h>
#include <lastlog.h>
#include <errno.h>
#ifndef NOTTYENT
#include <ttyent.h>
--- 35,74 ----
static char sccsid[] = "@(#)login.c 5.25 (Berkeley) 1/6/89";
#endif /* not lint */
! /*
! * login [ name ]
! * login -r hostname (for rlogind)
! * login -h hostname (for telnetd, etc.)
! * login -f name (for pre-authenticated login: datakit, xterm, etc.)
! * login -e name (for pre-authenticated encrypted, must do term
! * negotiation)
! * ifdef KERBEROS
! * login -k hostname (for Kerberos rlogind with password access)
! * login -K hostname (for Kerberos rlogind with restricted access)
! * endif KERBEROS
! *
! * only one of: -r -f -e -k -K
! * only one of: -r -h -k -K
! */
!
! #include <sys/types.h>
#include <sys/param.h>
! #ifdef OQUOTA
#include <sys/quota.h>
! #endif
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/file.h>
#include <sys/ioctl.h>
!
#include <utmp.h>
#include <signal.h>
+
+ #if !defined(_AIX)
#include <lastlog.h>
+ #endif
+
#include <errno.h>
#ifndef NOTTYENT
#include <ttyent.h>
***************
*** 68,86 ****
#include <setjmp.h>
#include <stdio.h>
#include <strings.h>
!
#ifdef UIDGID_T
! uid_t getuid();
#define uid_type uid_t
#define gid_type gid_t
#else
! int getuid();
#define uid_type int
#define gid_type int
#endif /* UIDGID_T */
!
#define TTYGRPNAME "tty" /* name of group to own ttys */
!
#define MOTDFILE "/etc/motd"
#define MAILDIR "/usr/spool/mail"
#define NOLOGIN "/etc/nologin"
--- 79,127 ----
#include <setjmp.h>
#include <stdio.h>
#include <strings.h>
! #ifdef KERBEROS
! #include <krb.h>
! #include <netdb.h>
! #include <netinet/in.h>
! #ifdef BIND_HACK
! #include <arpa/nameser.h>
! #include <arpa/resolv.h>
! #endif /* BIND_HACK */
! #endif /* KERBEROS */
!
! #ifdef POSIX
! #include <stdlib.h>
! #include <termios.h>
! #ifdef _AIX
! #include <termio.h>
! #endif
! #endif
!
! #ifdef _IBMR2
! #include <usersec.h>
! #include <sys/id.h>
! #endif
!
! #if defined(_AIX)
! #define PRIO_OFFSET 20
! #else
! #define PRIO_OFFSET 0
! #endif
!
#ifdef UIDGID_T
! uid_t getuid();
#define uid_type uid_t
#define gid_type gid_t
#else
! int getuid();
#define uid_type int
#define gid_type int
#endif /* UIDGID_T */
!
! #define SETPAG
!
#define TTYGRPNAME "tty" /* name of group to own ttys */
!
#define MOTDFILE "/etc/motd"
#define MAILDIR "/usr/spool/mail"
#define NOLOGIN "/etc/nologin"
***************
*** 87,123 ****
#define HUSHLOGIN ".hushlogin"
#define LASTLOG "/usr/adm/lastlog"
#define BSHELL "/bin/sh"
!
! #ifdef VFS
#define QUOTAWARN "/usr/ucb/quota" /* warn user about quotas */
! #endif VFS
!
#define UT_HOSTSIZE sizeof(((struct utmp *)0)->ut_host)
#define UT_NAMESIZE sizeof(((struct utmp *)0)->ut_name)
!
/*
* This bounds the time given to login. Not a define so it can
* be patched on machines where it's too small.
*/
! int timeout = 300;
struct passwd *pwd;
! char term[64], *hostname, *username = NULL;
struct sgttyb sgttyb;
struct tchars tc = {
! CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK
! };
struct ltchars ltc = {
! CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT
! };
extern int errno;
char *getenv();
! int putenv();
! void setenv();
void dofork();
#ifdef POSIX
typedef void sigtype;
--- 128,193 ----
#define HUSHLOGIN ".hushlogin"
#define LASTLOG "/usr/adm/lastlog"
#define BSHELL "/bin/sh"
!
! #if !defined(OQUOTA) && !defined(QUOTAWARN)
#define QUOTAWARN "/usr/ucb/quota" /* warn user about quotas */
! #endif
!
! #define PROTOTYPE_DIR "/usr/athena/lib/prototype_tmpuser"
! #define TEMP_DIR_PERM 0711
!
! #define NOATTACH "/etc/noattach"
! #define NOCREATE "/etc/nocreate"
! #define NOREMOTE "/etc/noremote"
! #define REGISTER "/usr/etc/go_register"
! #define GET_MOTD "/bin/athena/get_message"
!
#define UT_HOSTSIZE sizeof(((struct utmp *)0)->ut_host)
#define UT_NAMESIZE sizeof(((struct utmp *)0)->ut_name)
!
! #define MAXENVIRON 32
!
/*
* This bounds the time given to login. Not a define so it can
* be patched on machines where it's too small.
*/
! int timeout = 300;
struct passwd *pwd;
! char term[64], *hostname, *username;
+ #ifndef POSIX
struct sgttyb sgttyb;
struct tchars tc = {
! CINTR, CQUIT, CSTART, CSTOP, CEOT, CBRK
! };
struct ltchars ltc = {
! CSUSP, CDSUSP, CRPRNT, CFLUSH, CWERASE, CLNEXT
! };
! #endif
extern int errno;
+ #ifdef KERBEROS
+ #define KRB_ENVIRON "KRBTKFILE" /* Ticket file environment variable */
+ #define KRB_TK_DIR "/tmp/tkt_" /* Where to put the ticket */
+ #define MAXPWSIZE 128 /* Biggest string accepted for Kerberos
+ passsword */
+
+ extern char *krb_err_txt[]; /* From libkrb */
+
+ AUTH_DAT *kdata = (AUTH_DAT *) NULL;
+ KTEXT ticket = (KTEXT) NULL;
+ char tkfile[MAXPATHLEN];
+ int krbflag = 0; /* set if tickets have been obtained */
+ #ifdef SETPAG
+ int pagflag = 0; /* true if setpag() has been called */
+ #endif
+
char *getenv();
! char *strsave();
void dofork();
+ #endif /* KERBEROS */
#ifdef POSIX
typedef void sigtype;
***************
*** 125,684 ****
typedef int sigtype;
#endif /* POSIX */
! #ifdef CRAY
! char user[32] = "LOGNAME=";
! #include <tmpdir.h>
! char tmpdir[64] = "TMPDIR=";
! #else
! char user[20] = "USER=";
! #endif
!
! char homedir[64] = "HOME=";
! char shell[64] = "SHELL=";
#ifdef KERBEROS
! char *envinit[] =
! #ifdef CRAY
! {homedir, shell, PATH, user, "TZ=GMT0", tmpdir, 0};
! #define TZENV 4
! #define TMPDIRENV 5
! char *getenv();
! extern
! #else
! {homedir, shell, "PATH=:/usr/ucb:/bin:/usr/bin:/usr/bin/kerberos",
! user, 0};
! #endif /* CRAY */
! #else /* !KERBEROS */
! char *envinit[] =
! #ifdef CRAY
! {homedir, shell, PATH, user, "TZ=GMT0", tmpdir, 0};
! #define TZENV 4
! #define TMPDIRENV 5
! char *getenv();
! extern
! #else
! {homedir, shell, "PATH=:/usr/ucb:/bin:/usr/bin:/usr/bin/kerberos",
! user, 0};
! #endif /* CRAY */
#endif /* KERBEROS */
! char **environ;
! main(argc, argv)
! int argc;
! char **argv;
! {
! extern int optind;
! extern char *optarg;
! struct group *gr;
! register int ch;
! register char *p;
! int fflag, pflag, cnt;
! int quietlog, ioctlval;
! sigtype timedout();
! char *domain, *salt, *ttyn, *tty;
! char tbuf[MAXPATHLEN + 2];
! char *ttyname(), *stypeof(), *crypt(), *getpass();
! time_t time();
! off_t lseek();
! int passwd_req = 1, preserve_env = 0;
!
! (void)signal(SIGALRM, timedout);
! (void)alarm((u_int)timeout);
! (void)signal(SIGQUIT, SIG_IGN);
! (void)signal(SIGINT, SIG_IGN);
! (void)setpriority(PRIO_PROCESS, 0, 0);
! #ifndef VFS
! (void)quota(Q_SETUID, 0, 0, 0);
! #endif VFS
!
! (void)gethostname(tbuf, sizeof(tbuf));
! domain = index(tbuf, '.');
!
! passwd_req = 1;
! while ((ch = getopt(argc, argv, "fp")) != EOF)
! switch (ch) {
! case 'f':
! passwd_req = 0;
! break;
! case 'p':
! preserve_env = 1;
! break;
! case '?':
! default:
! fprintf(stderr, "usage: login [-fp] [username]\n");
! exit(1);
! break;
! }
! argc -= optind;
! argv += optind;
! if (*argv)
! hostname = *argv;
!
! ioctlval = 0;
! (void)ioctl(0, TIOCLSET, (char *)&ioctlval);
! (void)ioctl(0, TIOCNXCL, (char *)0);
! (void)fcntl(0, F_SETFL, ioctlval);
! (void)ioctl(0, TIOCGETP, (char *)&sgttyb);
!
! doremotelogin();
!
! /*
! * If talking to an rlogin process, propagate the terminal type and
! * baud rate across the network.
! */
! doremoteterm(&sgttyb);
! sgttyb.sg_erase = CERASE;
! sgttyb.sg_kill = CKILL;
! (void)ioctl(0, TIOCSLTC, (char *)<c);
! (void)ioctl(0, TIOCSETC, (char *)&tc);
! (void)ioctl(0, TIOCSETP, (char *)&sgttyb);
!
! for (cnt = getdtablesize(); cnt > 2; cnt--)
! (void) close(cnt);
!
! ttyn = ttyname(0);
! if (ttyn == NULL || *ttyn == '\0')
! ttyn = "/dev/tty??";
! if (tty = rindex(ttyn, '/'))
! ++tty;
! else
! tty = ttyn;
!
! #ifndef LOG_ODELAY /* 4.2 syslog ... */
! openlog("login", 0);
! #else
! openlog("login", LOG_ODELAY, LOG_AUTH);
! #endif /* 4.2 syslog */
!
! for (cnt = 0;; username = NULL) {
ioctlval = 0;
! (void)ioctl(0, TIOCSETD, (char *)&ioctlval);
!
! if (username == NULL)
! getloginname();
!
! if (pwd = getpwnam(username))
! salt = pwd->pw_passwd;
! else
! salt = "xx";
!
! /* if user not super-user, check for disabled logins */
! if (pwd == NULL || pwd->pw_uid)
! checknologin();
!
/*
! * Disallow automatic login to root; if not invoked by
! * root, disallow if the uid's differ.
*/
! if (!passwd_req && pwd) {
! int uid = (int) getuid();
!
! passwd_req = (uid && uid != pwd->pw_uid)
! #ifndef BYPASS_ROOT_CHK
! || (pwd->pw_uid == 0);
#else
! ;
#endif
}
!
/*
! * If no remote login authentication and a password exists
! * for this user, prompt for one and verify it.
*/
! if (!passwd_req || pwd && !*pwd->pw_passwd)
! break;
!
! (void) setpriority(PRIO_PROCESS, 0, -4);
! p = crypt(getpass("Password:"), salt);
! (void) setpriority(PRIO_PROCESS, 0, 0);
! if (pwd && !strcmp(p, pwd->pw_passwd))
! break;
!
! printf("Login incorrect\n");
! if (++cnt >= 5) {
! if (hostname)
! syslog(LOG_ERR,
! "REPEATED LOGIN FAILURES ON %s FROM %.*s, %.*s",
! tty, UT_HOSTSIZE, hostname, UT_NAMESIZE,
! username);
! else
! syslog(LOG_ERR,
! "REPEATED LOGIN FAILURES ON %s, %.*s",
! tty, UT_NAMESIZE, username);
! (void)ioctl(0, TIOCHPCL, (char *)0);
! sleepexit(1);
}
! }
!
! /* committed to login -- turn off timeout */
! (void)alarm((u_int)0);
!
! /*
! * If valid so far and root is logging in, see if root logins on
! * this terminal are permitted.
! */
! #ifndef BYPASS_ROOT_CHK
! if (pwd->pw_uid == 0 && !rootterm(tty)) {
! if (hostname)
! syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s FROM %.*s",
! tty, UT_HOSTSIZE, hostname);
! else
! syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s", tty);
! printf("Login incorrect\n");
! sleepexit(1);
! }
#endif
!
! #ifndef VFS
! if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) {
! switch(errno) {
! case EUSERS:
! fprintf(stderr,
! "Too many users logged on already.\nTry again later.\n");
! break;
! case EPROCLIM:
! fprintf(stderr,
! "You have too many processes running.\n");
! break;
! default:
! perror("quota (Q_SETUID)");
}
! sleepexit(0);
! }
! #endif /* !VFS */
!
! if (chdir(pwd->pw_dir) < 0) {
! printf("No directory %s!\n", pwd->pw_dir);
! if (chdir("/"))
! exit(0);
! pwd->pw_dir = "/";
! printf("Logging in with home = \"/\".\n");
! }
!
! /* nothing else left to fail -- really log in */
! {
! struct utmp utmp;
!
! (void)time(&utmp.ut_time);
! (void) strncpy(utmp.ut_name, username, sizeof(utmp.ut_name));
! if (hostname)
! (void) strncpy(utmp.ut_host, hostname,
! sizeof(utmp.ut_host));
! else
! bzero(utmp.ut_host, sizeof(utmp.ut_host));
! (void) strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line));
! login(&utmp);
! }
!
! quietlog = access(HUSHLOGIN, F_OK) == 0;
! dolastlog(quietlog, tty);
!
! {
! static struct winsize win = { 0, 0, 0, 0 };
!
! (void)ioctl(0, TIOCSWINSZ, (char *)&win);
! }
!
! (void)chown(ttyn, pwd->pw_uid,
! (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
!
! (void)chmod(ttyn, 0620);
!
! (void)setgid((gid_type) pwd->pw_gid);
!
! (void) initgroups(username, pwd->pw_gid);
!
! #ifndef VFS
! quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0);
#endif
! (void)setuid((uid_type) pwd->pw_uid);
!
! if (*pwd->pw_shell == '\0')
! pwd->pw_shell = BSHELL;
! /* turn on new line discipline for the csh */
! else if (!strcmp(pwd->pw_shell, "/bin/csh")) {
! ioctlval = NTTYDISC;
! (void)ioctl(0, TIOCSETD, (char *)&ioctlval);
! }
! /* Destroy old environment unless requested. */
! if (!preserve_env)
! environ = envinit;
!
! setenv("HOME", pwd->pw_dir);
! setenv("SHELL", pwd->pw_shell);
! if (term[0] == '\0')
! (void) strncpy(term, stypeof(tty), sizeof(term));
! setenv("TERM", term);
! setenv("USER", pwd->pw_name);
! setenv("PATH", "/usr/ucb:/bin:/usr/bin:");
!
! if (tty[sizeof("tty")-1] == 'd')
! syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
!
! if (!quietlog) {
! struct stat st;
! motd();
! (void)sprintf(tbuf, "%s/%s", MAILDIR, pwd->pw_name);
! if (stat(tbuf, &st) == 0 && st.st_size != 0)
! printf("You have %smail.\n",
! (st.st_mtime > st.st_atime) ? "new " : "");
! }
!
! #ifdef VFS
! if (! access( QUOTAWARN, X_OK)) (void) system(QUOTAWARN);
! #endif VFS
! (void)signal(SIGALRM, SIG_DFL);
! (void)signal(SIGQUIT, SIG_DFL);
! (void)signal(SIGINT, SIG_DFL);
! (void)signal(SIGTSTP, SIG_IGN);
!
! tbuf[0] = '-';
! (void) strcpy(tbuf + 1, (p = rindex(pwd->pw_shell, '/')) ?
! p + 1 : pwd->pw_shell);
! execlp(pwd->pw_shell, tbuf, 0);
! fprintf(stderr, "login: no shell: ");
! perror(pwd->pw_shell);
! exit(0);
! }
getloginname()
{
! register int ch;
! register char *p;
! static char nbuf[UT_NAMESIZE + 1];
!
! for (;;) {
! printf("login: ");
! for (p = nbuf; (ch = getchar()) != '\n'; ) {
! if (ch == EOF)
! exit(0);
! if (p < nbuf + UT_NAMESIZE)
! *p++ = ch;
! }
! if (p > nbuf)
! if (nbuf[0] == '-')
! fprintf(stderr,
! "login names may not start with '-'.\n");
! else {
! *p = '\0';
! username = nbuf;
! break;
! }
! }
}
-
-
sigtype
! timedout()
{
! fprintf(stderr, "Login timed out after %d seconds\n", timeout);
! exit(0);
}
-
-
#ifdef NOTTYENT
! int root_tty_security = 0;
#endif
rootterm(tty)
! char *tty;
{
#ifdef NOTTYENT
! return(root_tty_security);
#else
! struct ttyent *t;
!
! return((t = getttynam(tty)) && t->ty_status&TTY_SECURE);
! #endif NOTTYENT
! }
!
jmp_buf motdinterrupt;
motd()
{
! register int fd, nchars;
! sigtype (*oldint)(), sigint();
! char tbuf[8192];
!
! if ((fd = open(MOTDFILE, O_RDONLY, 0)) < 0)
! return;
! oldint = (sigtype (*)()) signal(SIGINT, sigint);
! if (setjmp(motdinterrupt) == 0)
! while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
! (void)write(fileno(stdout), tbuf, nchars);
! (void)signal(SIGINT, oldint);
! (void)close(fd);
}
-
-
sigtype
! sigint()
{
! longjmp(motdinterrupt, 1);
}
-
-
checknologin()
{
! register int fd, nchars;
! char tbuf[8192];
!
! if ((fd = open(NOLOGIN, O_RDONLY, 0)) >= 0) {
! while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
! (void)write(fileno(stdout), tbuf, nchars);
! sleepexit(0);
! }
! }
!
dolastlog(quiet, tty)
! int quiet;
! char *tty;
{
! struct lastlog ll;
! int fd;
!
! if ((fd = open(LASTLOG, O_RDWR, 0)) >= 0) {
! (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
! if (!quiet) {
! if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
! ll.ll_time != 0) {
! printf("Last login: %.*s ",
! 24-5, (char *)ctime(&ll.ll_time));
! if (*ll.ll_host != '\0')
! printf("from %.*s\n",
! sizeof(ll.ll_host), ll.ll_host);
else
! printf("on %.*s\n",
! sizeof(ll.ll_line), ll.ll_line);
! }
! (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
}
! (void)time(&ll.ll_time);
! (void) strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
! if (hostname)
! (void) strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
! else
! (void) bzero(ll.ll_host, sizeof(ll.ll_host));
! (void)write(fd, (char *)&ll, sizeof(ll));
! (void)close(fd);
! }
}
-
-
#undef UNKNOWN
#define UNKNOWN "su"
! char *stypeof(ttyid)
! char *ttyid;
{
#ifdef NOTTYENT
! return(UNKNOWN);
#else
! struct ttyent *t;
!
! return(ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
#endif
}
! getstr(buf, cnt, err)
! char *buf, *err;
! int cnt;
{
! char ch;
!
! do {
! if (read(0, &ch, sizeof(ch)) != sizeof(ch))
! exit(1);
! if (--cnt < 0) {
! fprintf(stderr, "%s too long\r\n", err);
! sleepexit(1);
}
! *buf++ = ch;
! } while (ch);
! }
! doremotelogin()
! {
! static char lusername[UT_NAMESIZE+1];
! char rusername[UT_NAMESIZE+1];
!
! getstr(rusername, sizeof(rusername), "remuser");
! getstr(lusername, sizeof(lusername), "locuser");
! if (username == NULL)
! username = lusername;
! getstr(term, sizeof(term), "Terminal type");
}
!
char *speeds[] = {
! "0", "50", "75", "110", "134", "150", "200", "300", "600",
! "1200", "1800", "2400", "4800", "9600", "19200", "38400",
};
#define NSPEEDS (sizeof(speeds) / sizeof(speeds[0]))
doremoteterm(tp)
! struct sgttyb *tp;
{
! register char *cp = index(term, '/'), **cpp;
! char *speed;
!
! if (cp) {
! *cp++ = '\0';
! speed = cp;
! cp = index(speed, '/');
! if (cp)
! *cp++ = '\0';
! for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++)
! if (strcmp(*cpp, speed) == 0) {
! tp->sg_ispeed = tp->sg_ospeed = cpp-speeds;
! break;
! }
! }
! tp->sg_flags = ECHO|CRMOD|ANYP|XTABS;
! }
!
sleepexit(eval)
! int eval;
{
! sleep((u_int)5);
! exit(eval);
}
! void setenv(var, value)
! char *var, *value;
! {
! char *env_str;
! int retval, str_size = strlen(var) + strlen(value) + strlen("=") + 1;
!
! env_str = (char *) malloc(str_size);
! strcpy(env_str, var);
! strcat(env_str, "=");
! strcat(env_str, value);
! env_str[str_size-1] = '\0';
!
! if (retval = putenv(env_str)) {
! syslog(LOG_ERR, "Not enough memory\n");
! exit(1);
}
}
--- 195,1243 ----
typedef int sigtype;
#endif /* POSIX */
! #define EXCL_AUTH_TEST if (rflag || kflag || Kflag || eflag) { \
! fprintf(stderr, \
! "login: only one of -r, -k, -K, -e, and -f allowed.\n"); \
! exit(1);\
! }
!
! #define EXCL_HOST_TEST if (rflag || kflag || Kflag || hflag) { \
! fprintf(stderr, \
! "login: only one of -r, -k, -K, and -h allowed.\n"); \
! exit(1);\
! }
!
! main(argc, argv)
! int argc;
! char **argv;
! {
! extern int optind;
! extern char *optarg, **environ;
! struct group *gr;
! register int ch, i;
! register char *p;
! int fflag, hflag, pflag, rflag, cnt;
! int kflag, Kflag, eflag;
! int quietlog, passwd_req, ioctlval;
! sigtype timedout();
! char *domain, *salt, **envinit, *ttyn, *tty, *ktty;
! char tbuf[MAXPATHLEN + 2];
! char *ttyname(), *stypeof(), *crypt(), *getpass();
! time_t time(), login_time;
! off_t lseek();
! #ifdef POSIX
! struct termios tc;
! #endif
!
! (void)signal(SIGALRM, timedout);
! (void)alarm((u_int)timeout);
! (void)signal(SIGQUIT, SIG_IGN);
! (void)signal(SIGINT, SIG_IGN);
! (void)setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
! #ifdef OQUOTA
! (void)quota(Q_SETUID, 0, 0, 0);
! #endif
+ /*
+ * -p is used by getty to tell login not to destroy the environment
+ * -r is used by rlogind to cause the autologin protocol;
+ * -f is used to skip a second login authentication
+ * -e is used to skip a second login authentication, but allows
+ * login as root.
+ * -h is used by other servers to pass the name of the
+ * remote host to login so that it may be placed in utmp and wtmp
+ * -k is used by klogind to cause the Kerberos autologin protocol;
+ * -K is used by klogind to cause the Kerberos autologin protocol with
+ * restricted access.;
+ */
+ (void)gethostname(tbuf, sizeof(tbuf));
+ domain = index(tbuf, '.');
+ fflag = hflag = pflag = rflag = kflag = Kflag = eflag = 0;
+ passwd_req = 1;
+ while ((ch = getopt(argc, argv, "feh:pr:k:K:")) != EOF)
+ switch (ch) {
+ case 'f':
+ EXCL_AUTH_TEST;
+ fflag = 1;
+ break;
+ case 'h':
+ EXCL_HOST_TEST;
+ if (getuid()) {
+ fprintf(stderr,
+ "login: -h for super-user only.\n");
+ exit(1);
+ }
+ hflag = 1;
+ if (domain && (p = index(optarg, '.')) &&
+ strcmp(p, domain) == 0)
+ *p = 0;
+ hostname = optarg;
+ break;
+ case 'p':
+ pflag = 1;
+ break;
+ case 'r':
+ EXCL_AUTH_TEST;
+ EXCL_HOST_TEST;
+ if (getuid()) {
+ fprintf(stderr,
+ "login: -r for super-user only.\n");
+ exit(1);
+ }
+ /* "-r hostname" must be last args */
+ if (optind != argc) {
+ fprintf(stderr, "Syntax error.\n");
+ exit(1);
+ }
+ rflag = 1;
+ passwd_req = (doremotelogin(optarg) == -1);
+ if (domain && (p = index(optarg, '.')) &&
+ !strcmp(p, domain))
+ *p = '\0';
+ hostname = optarg;
+ break;
#ifdef KERBEROS
! case 'k':
! case 'K':
! EXCL_AUTH_TEST;
! EXCL_HOST_TEST;
! if (getuid()) {
! fprintf(stderr,
! "login: -%c for super-user only.\n", ch);
! exit(1);
! }
! /* "-k hostname" must be last args */
! if (optind != argc) {
! fprintf(stderr, "Syntax error.\n");
! exit(1);
! }
! if (ch == 'K')
! Kflag = 1;
! else
! kflag = 1;
! passwd_req = (do_krb_login(optarg,
! Kflag ? 1 : 0) == -1);
! if (domain && (p = index(optarg, '.')) &&
! !strcmp(p, domain))
! *p = '\0';
! hostname = optarg;
! break;
#endif /* KERBEROS */
! case 'e':
! EXCL_AUTH_TEST;
! if (getuid()) {
! fprintf(stderr,
! "login: -e for super-user only.\n");
! exit(1);
! }
! eflag = 1;
! passwd_req = 0;
! break;
! case '?':
! default:
! fprintf(stderr, "usage: login [-fp] [username]\n");
! exit(1);
! }
! argc -= optind;
! argv += optind;
! if (*argv)
! username = *argv;
! #if !defined(_AIX)
ioctlval = 0;
! (void)ioctl(0, TIOCLSET, (char *)&ioctlval);
! (void)ioctl(0, TIOCNXCL, (char *)0);
! (void)fcntl(0, F_SETFL, ioctlval);
! #endif
! #ifdef POSIX
! (void)tcgetattr(0, &tc);
! #else
! (void)ioctl(0, TIOCGETP, (char *)&sgttyb);
! #endif
!
/*
! * If talking to an rlogin process, propagate the terminal type and
! * baud rate across the network.
*/
! if (eflag)
! lgetstr(term, sizeof(term), "Terminal type");
! #ifdef POSIX
! if (rflag || kflag || Kflag || eflag)
! doremoteterm(&tc);
! tc.c_cc[VMIN] = 1;
! tc.c_cc[VTIME] = 0;
! tc.c_cc[VERASE] = CERASE;
! tc.c_cc[VKILL] = CKILL;
! tc.c_cc[VEOF] = CEOF;
! tc.c_cc[VINTR] = CINTR;
! tc.c_cc[VQUIT] = CQUIT;
! tc.c_cc[VSTART] = CSTART;
! tc.c_cc[VSTOP] = CSTOP;
! tc.c_cc[VEOL] = CNUL;
! /* The following are common extensions to POSIX */
! #ifdef VEOL2
! tc.c_cc[VEOL2] = CNUL;
! #endif
! #ifdef VSUSP
! tc.c_cc[VSUSP] = CSUSP;
! #endif
! #ifdef VDSUSP
! tc.c_cc[VDSUSP] = CDSUSP;
! #endif
! #ifdef VLNEXT
! tc.c_cc[VLNEXT] = CLNEXT;
! #endif
! #ifdef VREPRINT
! tc.c_cc[VREPRINT] = CRPRNT;
! #endif
! #ifdef VDISCRD
! tc.c_cc[VDISCRD] = CFLUSH;
! #endif
! #ifdef VWERSE
! tc.c_cc[VWERSE] = CWERASE;
! #endif
! tcsetattr(0, TCSANOW, &tc);
#else
! if (rflag || kflag || Kflag || eflag)
! doremoteterm(&sgttyb);
! sgttyb.sg_erase = CERASE;
! sgttyb.sg_kill = CKILL;
! (void)ioctl(0, TIOCSLTC, (char *)<c);
! (void)ioctl(0, TIOCSETC, (char *)&tc);
! (void)ioctl(0, TIOCSETP, (char *)&sgttyb);
! #endif
!
! for (cnt = getdtablesize(); cnt > 2; cnt--)
! (void) close(cnt);
!
! ttyn = ttyname(0);
! if (ttyn == NULL || *ttyn == '\0')
! ttyn = "/dev/tty??";
!
! /* This allows for tty names of the form /dev/pts/4 as well */
! if ((tty = index(ttyn, '/')) && (tty = index(tty+1, '/')))
! ++tty;
! else
! tty = ttyn;
!
! /* For kerberos tickets, extract only the last part of the ttyname */
! if (ktty = rindex(tty, '/'))
! ++ktty;
! else
! ktty = tty;
!
! #ifndef LOG_ODELAY /* 4.2 syslog ... */
! openlog("login", 0);
! #else
! openlog("login", LOG_ODELAY, LOG_AUTH);
! #endif /* 4.2 syslog */
!
! for (cnt = 0;; username = NULL) {
! #ifdef KERBEROS
! char pp[9], pp2[MAXPWSIZE], *namep;
! int krbval;
! char realm[REALM_SZ];
! int kpass_ok,lpass_ok;
! #ifdef NOENCRYPTION
! #define read_long_pw_string placebo_read_pw_string
! #else
! #define read_long_pw_string des_read_pw_string
#endif
+ int read_long_pw_string();
+ #endif
+ #if !defined(_IBMR2)
+ ioctlval = 0;
+ (void)ioctl(0, TIOCSETD, (char *)&ioctlval);
+ #endif
+
+ if (username == NULL) {
+ fflag = 0;
+ getloginname();
+ }
+
+ if (pwd = getpwnam(username))
+ salt = pwd->pw_passwd;
+ else
+ salt = "xx";
+
+ /* if user not super-user, check for disabled logins */
+ if (pwd == NULL || pwd->pw_uid)
+ checknologin();
+
+ /*
+ * Disallow automatic login to root; if not invoked by
+ * root, disallow if the uid's differ.
+ */
+ if (fflag && pwd) {
+ int uid = (int) getuid();
+
+ passwd_req = pwd->pw_uid == 0 ||
+ (uid && uid != pwd->pw_uid);
+ }
+
+ /*
+ * If no remote login authentication and a password exists
+ * for this user, prompt for one and verify it.
+ */
+ if (!passwd_req || pwd && !*pwd->pw_passwd)
+ break;
+
+ #ifdef KERBEROS
+ kpass_ok = 0;
+ lpass_ok = 0;
+
+ (void) setpriority(PRIO_PROCESS, 0, -4 + PRIO_OFFSET);
+ if (read_long_pw_string(pp2, sizeof(pp2)-1, "Password: ", 0)) {
+ /* reading password failed... */
+ (void) setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
+ goto bad_login;
+ }
+ if (!pwd) /* avoid doing useless work */
+ goto bad_login;
+
+ /* Modifications for Kerberos authentication -- asp */
+ (void) strncpy(pp, pp2, sizeof(pp));
+ pp[8]='\0';
+ namep = crypt(pp, pwd->pw_passwd);
+ bzero (pp, sizeof(pp)); /* To the best of my recollection, Senator... */
+ lpass_ok = !strcmp (namep, pwd->pw_passwd);
+
+ if (pwd->pw_uid != 0) { /* Don't get tickets for root */
+
+ if (krb_get_lrealm(realm, 1) != KSUCCESS) {
+ (void) strncpy(realm, KRB_REALM, sizeof(realm));
+ }
+ #ifdef BIND_HACK
+ /* Set name server timeout to be reasonable,
+ so that people don't take 5 minutes to
+ log in. Can you say abstraction violation? */
+ _res.retrans = 1;
+ #endif
+ #if 0 /* XXX krb5 has defaults; don't do this. */
+ /* Set up the ticket file environment variable */
+ strncpy(tkfile, KRB_TK_DIR, sizeof(tkfile));
+ strncat(tkfile, ktty,
+ sizeof(tkfile) - strlen(tkfile) - 1);
+ (void) setenv(KRB_ENVIRON, tkfile, 1);
+ krb_set_tkt_string(tkfile);
+ #endif
+
+ #ifdef _IBMR2
+ krbval = setuidx(ID_REAL|ID_EFFECTIVE, pwd->pw_uid);
+ #else
+ krbval = setreuid(pwd->pw_uid, -1);
+ #endif
+ if (krbval) {
+ /* can't set ruid to user! */
+ krbval = -1;
+ fprintf(stderr,
+ "login: Can't set ruid for ticket file.\n");
+ } else
+ krbval = krb_get_pw_in_tkt(username, "",
+ realm, "krbtgt",
+ realm,
+ DEFAULT_TKT_LIFE, pp2);
+ bzero (pp2, sizeof(pp2));
+ (void) setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
+ switch (krbval) {
+ case INTK_OK:
+ kpass_ok = 1;
+ krbflag = 1;
+ break;
+
+ /* These errors should be silent */
+ /* So the Kerberos database can't be probed */
+ case KDC_NULL_KEY:
+ case KDC_PR_UNKNOWN:
+ case INTK_BADPW:
+ case KDC_PR_N_UNIQUE:
+ case -1:
+ break;
+ /* These should be printed but are not fatal */
+ case INTK_W_NOTALL:
+ krbflag = 1;
+ kpass_ok = 1;
+ fprintf(stderr, "Kerberos error: %s\n",
+ krb_err_txt[krbval]);
+ break;
+ default:
+ fprintf(stderr, "Kerberos error: %s\n",
+ krb_err_txt[krbval]);
+ break;
+ }
+ } else {
+ (void) bzero (pp2, sizeof(pp2));
+ (void) setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
+ }
+
+ /* Policy: If local password is good, user is good.
+ We really can't trust the Kerberos password,
+ because somebody on the net could spoof the
+ Kerberos server (not easy, but possible).
+ Some sites might want to use it anyways, in
+ which case they should change this line
+ to:
+ if (kpass_ok)
+ */
+ if (lpass_ok)
+ break;
+ bad_login:
+ if (krbflag)
+ dest_tkt(); /* clean up tickets if login fails */
+ #else
+ (void) setpriority(PRIO_PROCESS, 0, -4 + PRIO_OFFSET);
+ p = crypt(getpass("password:"), salt);
+ (void) setpriority(PRIO_PROCESS, 0, 0 + PRIO_OFFSET);
+ if (pwd && !strcmp(p, pwd->pw_passwd))
+ break;
+ #endif /* KERBEROS */
+
+ printf("Login incorrect\n");
+ if (++cnt >= 5) {
+ if (hostname)
+ syslog(LOG_ERR,
+ "REPEATED LOGIN FAILURES ON %s FROM %.*s, %.*s",
+ tty, UT_HOSTSIZE, hostname, UT_NAMESIZE,
+ username);
+ else
+ syslog(LOG_ERR,
+ "REPEATED LOGIN FAILURES ON %s, %.*s",
+ tty, UT_NAMESIZE, username);
+ (void)ioctl(0, TIOCHPCL, (char *)0);
+ sleepexit(1);
+ }
}
!
! /* committed to login -- turn off timeout */
! (void)alarm((u_int)0);
!
/*
! * If valid so far and root is logging in, see if root logins on
! * this terminal are permitted.
! *
! * We allow authenticated remote root logins (except -r style)
*/
! if (pwd->pw_uid == 0 && !rootterm(tty) && (passwd_req || rflag)) {
! if (hostname)
! syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s FROM %.*s",
! tty, UT_HOSTSIZE, hostname);
! else
! syslog(LOG_ERR, "ROOT LOGIN REFUSED ON %s", tty);
! printf("Login incorrect\n");
! sleepexit(1);
}
!
! #ifdef OQUOTA
! if (quota(Q_SETUID, pwd->pw_uid, 0, 0) < 0 && errno != EINVAL) {
! switch(errno) {
! case EUSERS:
! fprintf(stderr,
! "Too many users logged on already.\nTry again later.\n");
! break;
! case EPROCLIM:
! fprintf(stderr,
! "You have too many processes running.\n");
! break;
! default:
! perror("quota (Q_SETUID)");
! }
! sleepexit(0);
! }
#endif
!
! if (chdir(pwd->pw_dir) < 0) {
! printf("No directory %s!\n", pwd->pw_dir);
! if (chdir("/"))
! exit(0);
! pwd->pw_dir = "/";
! printf("Logging in with home = \"/\".\n");
}
!
! /* nothing else left to fail -- really log in */
! {
! struct utmp utmp;
!
! bzero((char *)&utmp, sizeof(utmp));
! login_time = time(&utmp.ut_time);
! (void) strncpy(utmp.ut_name, username, sizeof(utmp.ut_name));
! if (hostname)
! (void) strncpy(utmp.ut_host, hostname,
! sizeof(utmp.ut_host));
! else
! bzero(utmp.ut_host, sizeof(utmp.ut_host));
! (void) strncpy(utmp.ut_line, tty, sizeof(utmp.ut_line));
! login(&utmp);
! }
!
! quietlog = access(HUSHLOGIN, F_OK) == 0;
! dolastlog(quietlog, tty);
!
! if (!hflag && !rflag && !kflag && !Kflag && !eflag) { /* XXX */
! static struct winsize win = { 0, 0, 0, 0 };
!
! (void)ioctl(0, TIOCSWINSZ, (char *)&win);
! }
!
! (void)chown(ttyn, pwd->pw_uid,
! (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
! #ifdef KERBEROS
! if(krbflag)
! (void) chown(getenv(KRB_ENVIRON), pwd->pw_uid, pwd->pw_gid);
#endif
! (void)chmod(ttyn, 0620);
! #ifdef KERBEROS
! #ifdef SETPAG
! if (pwd->pw_uid) {
! /* Only reset the pag for non-root users. */
! /* This allows root to become anything. */
! pagflag = 1;
! setpag();
! }
! #endif
! /* Fork so that we can call kdestroy */
! dofork();
! #endif /* KERBEROS */
! (void)setgid((gid_type) pwd->pw_gid);
! (void) initgroups(username, pwd->pw_gid);
!
! #ifdef OQUOTA
! quota(Q_DOWARN, pwd->pw_uid, (dev_t)-1, 0);
! #endif
! /* This call MUST succeed */
! #ifdef _IBMR2
! setuidx(ID_LOGIN, pwd->pw_uid);
! #endif
! if(setuid((uid_type) pwd->pw_uid) < 0) {
! perror("setuid");
! sleepexit(1);
! }
!
! if (*pwd->pw_shell == '\0')
! pwd->pw_shell = BSHELL;
! /* turn on new line discipline for the csh */
! else if (!strcmp(pwd->pw_shell, "/bin/csh")) {
! #if !defined(_IBMR2)
! ioctlval = NTTYDISC;
! (void)ioctl(0, TIOCSETD, (char *)&ioctlval);
! #endif
! }
!
! /* destroy environment unless user has requested preservation */
! envinit = (char **)malloc(MAXENVIRON * sizeof(char *));
! if (envinit == 0) {
! fprintf(stderr, "Can't malloc empty environment.\n");
! sleepexit(1);
! }
! if (!pflag)
! environ = envinit;
!
! i = 0;
!
! #if defined(_AIX) && defined(_IBMR2)
! {
! FILE *fp;
! if ((fp = fopen("/etc/environment", "r")) != NULL) {
! while(fgets(tbuf, sizeof(tbuf), fp)) {
! if ((tbuf[0] == '#') || (strchr(tbuf, '=') == 0))
! continue;
! for (p = tbuf; *p; p++)
! if (*p == '\n') {
! *p = '\0';
! break;
! }
! envinit[i++] = strsave(tbuf);
! }
! fclose(fp);
! }
! }
! #endif
! sprintf(tbuf,"LOGNAME=%s",pwd->pw_name);
! envinit[i++] = strsave(tbuf);
! sprintf(tbuf,"LOGIN=%s",pwd->pw_name);
! envinit[i++] = strsave(tbuf);
!
! envinit[i++] = NULL;
!
! setenv("HOME", pwd->pw_dir, 0);
! setenv("PATH", "/usr/local/krb5/bin:/usr/local/bin:/usr/bin/X11:/usr/ucb:/bin:/usr/bin:.", 0);
! setenv("USER", pwd->pw_name, 0);
! setenv("SHELL", pwd->pw_shell, 0);
!
! if (term[0] == '\0')
! (void) strncpy(term, stypeof(tty), sizeof(term));
! (void)setenv("TERM", term, 0);
! #ifdef KERBEROS
! /* tkfile[0] is only set if we got tickets above */
! if (tkfile[0])
! (void) setenv(KRB_ENVIRON, tkfile, 1);
! #endif /* KERBEROS */
!
! #if 0
! strcpy(wgfile, "/tmp/wg.XXXXXX");
! mktemp(wgfile);
! setenv("WGFILE", wgfile, 0);
! #endif
!
! if (tty[sizeof("tty")-1] == 'd')
! syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
! if (pwd->pw_uid == 0)
! if (hostname)
! #ifdef KERBEROS
! if (kdata) {
! /* @*$&@#*($)#@$ syslog doesn't handle very
! many arguments */
! char buf[BUFSIZ];
! (void) sprintf(buf,
! "ROOT LOGIN (krb) %s from %.*s, %s.%s@%s",
! tty, UT_HOSTSIZE, hostname,
! kdata->pname, kdata->pinst,
! kdata->prealm);
! syslog(LOG_NOTICE, buf);
! } else {
! #endif /* KERBEROS */
! syslog(LOG_NOTICE, "ROOT LOGIN %s FROM %.*s",
! tty, UT_HOSTSIZE, hostname);
! #ifdef KERBEROS
! }
! else
! if (kdata) {
! syslog(LOG_NOTICE,
! "ROOT LOGIN (krb) %s, %s.%s@%s",
! tty,
! kdata->pname, kdata->pinst,
! kdata->prealm);
! }
! #endif /* KERBEROS */
! else
! syslog(LOG_NOTICE, "ROOT LOGIN %s", tty);
+ if (!quietlog) {
+ struct stat st;
+ #ifdef KERBEROS
+ if (!krbflag)
+ printf("\nWarning: No Kerberos tickets obtained.\n\n");
+ #endif /* KERBEROS */
+ motd();
+ (void)sprintf(tbuf, "%s/%s", MAILDIR, pwd->pw_name);
+ if (stat(tbuf, &st) == 0 && st.st_size != 0)
+ printf("You have %smail.\n",
+ (st.st_mtime > st.st_atime) ? "new " : "");
+ }
+
+ #ifndef OQUOTA
+ if (! access( QUOTAWARN, X_OK)) (void) system(QUOTAWARN);
+ #endif
+ (void)signal(SIGALRM, SIG_DFL);
+ (void)signal(SIGQUIT, SIG_DFL);
+ (void)signal(SIGINT, SIG_DFL);
+ (void)signal(SIGTSTP, SIG_IGN);
+
+ tbuf[0] = '-';
+ (void) strcpy(tbuf + 1, (p = rindex(pwd->pw_shell, '/')) ?
+ p + 1 : pwd->pw_shell);
+ execlp(pwd->pw_shell, tbuf, 0);
+ fprintf(stderr, "login: no shell: ");
+ perror(pwd->pw_shell);
+ exit(0);
+ }
getloginname()
{
! register int ch;
! register char *p;
! static char nbuf[UT_NAMESIZE + 1];
!
! for (;;) {
! printf("login: ");
! for (p = nbuf; (ch = getchar()) != '\n'; ) {
! if (ch == EOF)
! exit(0);
! if (p < nbuf + UT_NAMESIZE)
! *p++ = ch;
! }
! if (p > nbuf)
! if (nbuf[0] == '-')
! fprintf(stderr,
! "login names may not start with '-'.\n");
! else {
! *p = '\0';
! username = nbuf;
! break;
! }
! }
}
sigtype
! timedout()
{
! fprintf(stderr, "Login timed out after %d seconds\n", timeout);
! exit(0);
}
#ifdef NOTTYENT
! int root_tty_security = 1;
#endif
rootterm(tty)
! char *tty;
{
#ifdef NOTTYENT
! return(root_tty_security);
#else
! struct ttyent *t;
! return((t = getttynam(tty)) && t->ty_status&TTY_SECURE);
! #endif /* NOTTYENT */
! }
jmp_buf motdinterrupt;
motd()
{
! register int fd, nchars;
! sigtype (*oldint)(), sigint();
! char tbuf[8192];
!
! if ((fd = open(MOTDFILE, O_RDONLY, 0)) < 0)
! return;
! oldint = signal(SIGINT, sigint);
! if (setjmp(motdinterrupt) == 0)
! while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
! (void)write(fileno(stdout), tbuf, nchars);
! (void)signal(SIGINT, oldint);
! (void)close(fd);
}
sigtype
! sigint()
{
! longjmp(motdinterrupt, 1);
}
checknologin()
{
! register int fd, nchars;
! char tbuf[8192];
+ if ((fd = open(NOLOGIN, O_RDONLY, 0)) >= 0) {
+ while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
+ (void)write(fileno(stdout), tbuf, nchars);
+ sleepexit(0);
+ }
+ }
dolastlog(quiet, tty)
! int quiet;
! char *tty;
{
! #if !defined(_AIX)
! struct lastlog ll;
! int fd;
!
! if ((fd = open(LASTLOG, O_RDWR, 0)) >= 0) {
! (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
! if (!quiet) {
! if (read(fd, (char *)&ll, sizeof(ll)) == sizeof(ll) &&
! ll.ll_time != 0) {
! printf("Last login: %.*s ",
! 24-5, (char *)ctime(&ll.ll_time));
! if (*ll.ll_host != '\0')
! printf("from %.*s\n",
! sizeof(ll.ll_host), ll.ll_host);
! else
! printf("on %.*s\n",
! sizeof(ll.ll_line), ll.ll_line);
! }
! (void)lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), L_SET);
! }
! (void)time(&ll.ll_time);
! (void) strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
! if (hostname)
! (void) strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
else
! (void) bzero(ll.ll_host, sizeof(ll.ll_host));
! (void)write(fd, (char *)&ll, sizeof(ll));
! (void)close(fd);
}
! #endif
}
#undef UNKNOWN
#define UNKNOWN "su"
! char *
! stypeof(ttyid)
! char *ttyid;
{
#ifdef NOTTYENT
! return(UNKNOWN);
#else
! struct ttyent *t;
!
! return(ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
#endif
}
+ doremotelogin(host)
+ char *host;
+ {
+ static char lusername[UT_NAMESIZE+1];
+ char rusername[UT_NAMESIZE+1];
+ lgetstr(rusername, sizeof(rusername), "Remote user");
+ lgetstr(lusername, sizeof(lusername), "Local user");
+ lgetstr(term, sizeof(term), "Terminal type");
+ username = lusername;
+ pwd = getpwnam(username);
+ if (pwd == NULL)
+ return(-1);
+ return(ruserok(host, (pwd->pw_uid == 0), rusername, username));
+ }
! #ifdef KERBEROS
! do_krb_login(host, strict)
! char *host;
! int strict;
{
! int rc;
! struct sockaddr_in sin;
! char instance[INST_SZ], version[9];
! long authoptions = 0L;
! struct hostent *hp = gethostbyname(host);
! static char lusername[UT_NAMESIZE+1];
!
! /*
! * Kerberos autologin protocol.
! */
!
! (void) bzero((char *) &sin, (int) sizeof(sin));
!
! if (hp)
! (void) bcopy (hp->h_addr, (char *)&sin.sin_addr,
! sizeof(sin.sin_addr));
! else
! sin.sin_addr.s_addr = inet_addr(host);
!
! if ((hp == NULL) && (sin.sin_addr.s_addr == -1)) {
! printf("Hostname did not resolve to an address, so Kerberos authentication failed\r\n");
! /*
! * No host addr prevents auth, so
! * punt krb and require password
! */
! if (strict) {
! goto paranoid;
! } else {
! pwd = NULL;
! return(-1);
! }
}
!
! kdata = (AUTH_DAT *)malloc( sizeof(AUTH_DAT) );
! ticket = (KTEXT) malloc(sizeof(KTEXT_ST));
+ (void) strcpy(instance, "*");
+ if (rc=krb_recvauth(authoptions, 0, ticket, "rcmd",
+ instance, &sin,
+ (struct sockaddr_in *)0,
+ kdata, "", (bit_64 *) 0, version)) {
+ printf("Kerberos rlogin failed: %s\r\n",krb_err_txt[rc]);
+ if (strict) {
+ paranoid:
+ /*
+ * Paranoid hosts, such as a Kerberos server,
+ * specify the Klogind daemon to disallow
+ * even password access here.
+ */
+ printf("Sorry, you must have Kerberos authentication to access this host.\r\n");
+ exit(1);
+ }
+ }
+ (void) lgetstr(lusername, sizeof (lusername), "Local user");
+ (void) lgetstr(term, sizeof(term), "Terminal type");
+ username = lusername;
+ if (getuid()) {
+ pwd = NULL;
+ return(-1);
+ }
+ pwd = getpwnam(lusername);
+ if (pwd == NULL) {
+ pwd = NULL;
+ return(-1);
+ }
+ /*
+ * if Kerberos login failed because of an error in krb_recvauth,
+ * return the indication of a bad attempt. User will be prompted
+ * for a password. We CAN'T check the .rhost file, because we need
+ * the remote username to do that, and the remote username is in the
+ * Kerberos ticket. This affects ONLY the case where there is
+ * Kerberos on both ends, but Kerberos fails on the server end.
+ */
+ if (rc) {
+ return(-1);
+ }
! if (rc=kuserok(kdata,lusername)) {
! printf("login: %s has not given you permission to login without a password.\r\n",lusername);
! if (strict) {
! exit(1);
! }
! return(-1);
! }
! return(0);
}
! #endif /* KERBEROS */
+ lgetstr(buf, cnt, err)
+ char *buf, *err;
+ int cnt;
+ {
+ int ocnt = cnt;
+ char *obuf = buf;
+ char ch;
+
+ do {
+ if (read(0, &ch, sizeof(ch)) != sizeof(ch))
+ exit(1);
+ if (--cnt < 0) {
+ fprintf(stderr,"%s '%.*s' too long, %d characters maximum.\r\n",
+ err, ocnt, obuf, ocnt-1);
+ sleepexit(1);
+ }
+ *buf++ = ch;
+ } while (ch);
+ }
char *speeds[] = {
! "0", "50", "75", "110", "134", "150", "200", "300", "600",
! "1200", "1800", "2400", "4800", "9600", "19200", "38400",
};
#define NSPEEDS (sizeof(speeds) / sizeof(speeds[0]))
doremoteterm(tp)
! #ifdef POSIX
! struct termios *tp;
! #else
! struct sgttyb *tp;
! #endif
{
! register char *cp = index(term, '/'), **cpp;
! char *speed;
+ if (cp) {
+ *cp++ = '\0';
+ speed = cp;
+ cp = index(speed, '/');
+ if (cp)
+ *cp++ = '\0';
+ for (cpp = speeds; cpp < &speeds[NSPEEDS]; cpp++)
+ if (strcmp(*cpp, speed) == 0) {
+ #ifdef POSIX
+ tp->c_cflag =
+ (tp->c_cflag & ~CBAUD) | (cpp-speeds);
+ #else
+ tp->sg_ispeed = tp->sg_ospeed = cpp-speeds;
+ #endif
+ break;
+ }
+ }
+ #ifdef POSIX
+ /* set all standard echo, edit, and job control options */
+ tp->c_lflag = ECHO|ECHOE|ECHOK|ICANON|ISIG;
+ tp->c_iflag |= ICRNL|BRKINT;
+ tp->c_oflag |= ONLCR|OPOST|TAB3;
+ #else /* !POSIX */
+ tp->sg_flags = ECHO|CRMOD|ANYP|XTABS;
+ #endif
+ }
sleepexit(eval)
! int eval;
{
! #ifdef KERBEROS
! if (krbflag)
! (void) dest_tkt();
! #endif /* KERBEROS */
! sleep((u_int)5);
! exit(eval);
}
+ #ifdef KERBEROS
+ /*
+ * This routine handles cleanup stuff, and the like.
+ * It exits only in the child process.
+ */
+ #include <sys/wait.h>
+ void
+ dofork()
+ {
+ int child;
+ #ifdef _IBMR2
+ update_ref_count(1);
+ #endif
+ if(!(child=fork()))
+ return; /* Child process */
! /* Setup stuff? This would be things we could do in parallel with login */
! (void) chdir("/"); /* Let's not keep the fs busy... */
! /* If we're the parent, watch the child until it dies */
! while(wait((union wait *)0) != child)
! ;
!
! /* Cleanup stuff */
! /* Run dest_tkt to destroy tickets */
! (void) dest_tkt(); /* If this fails, we lose quietly */
! #ifdef SETPAG
! if (pagflag)
! ktc_ForgetAllTokens();
! #endif
! #ifdef _IBMR2
! update_ref_count(-1);
! #endif
!
! /* Leave */
! exit(0);
! }
! #endif /* KERBEROS */
!
!
! char *strsave(s)
! char *s;
! {
! char *ret = (char *)malloc(strlen(s) + 1);
! strcpy(ret, s);
! return(ret);
! }
!
! #ifdef _IBMR2
! update_ref_count(int adj)
! {
! static char *empty = "\0";
! char *grp;
! int i;
!
! /* Update reference count on all user's temporary groups */
! setuserdb(S_READ|S_WRITE);
! if (getuserattr(username, S_GROUPS, (void *)&grp, SEC_LIST) == 0) {
! while (*grp) {
! if (getgroupattr(grp, "athena_temp", (void *)&i, SEC_INT) == 0) {
! i += adj;
! if (i > 0) {
! putgroupattr(grp, "athena_temp", (void *)i, SEC_INT);
! putgroupattr(grp, (char *)0, (void *)0, SEC_COMMIT);
! } else {
! putgroupattr(grp, S_USERS, (void *)empty, SEC_LIST);
! putgroupattr(grp, (char *)0, (void *)0, SEC_COMMIT);
! rmufile(grp, 0, GROUP_TABLE);
! }
! }
! while (*grp) grp++;
! grp++;
! }
}
+ enduserdb();
}
+ #endif
*** ./appl/bsd/krcp.c.old 1992/11/20 14:40:59
--- ./appl/bsd/krcp.c 1992/11/20 14:41:33
***************
*** 104,110 ****
#endif /* KERBEROS */
int rem;
! char *colon(), *index(), *rindex(), *strcpy();
int errs;
krb5_sigtype lostconn();
int errno;
--- 104,116 ----
#endif /* KERBEROS */
int rem;
! char *colon(), *strcpy();
! #ifndef index
! char *index();
! #endif
! #ifndef rindex
! char *rindex();
! #endif
int errs;
krb5_sigtype lostconn();
int errno;
*** ./appl/bsd/logutil.c.old 1993/02/26 22:20:55
--- ./appl/bsd/logutil.c 1993/02/26 22:21:20
***************
*** 15,178 ****
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)login.c 5.1 (Berkeley) 9/27/88";
- #endif /* LIBC_SCCS and not lint */
-
#include <sys/types.h>
#include <sys/file.h>
- #if defined (CRAY) || defined (sgi)
- #include <sys/fcntl.h>
- #define L_SET 0
- #define L_INCR 1
- #endif
#include <utmp.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/stat.h>
-
- #ifndef UTMP_FILE
- #define UTMP_FILE "/etc/utmp"
- #endif
- #ifndef WTMP_FILE
- #ifdef SYSV
- #define WTMPFILE "/etc/wtmp"
- #else
- #define WTMP_FILE "/usr/adm/wtmp"
- #endif
- #endif
-
- void login(ut)
- struct utmp *ut;
- {
- register int fd;
- int tty;
- off_t lseek();
-
- tty = ttyslot();
- if (tty > 0 && (fd = open(UTMP_FILE, O_WRONLY, 0)) >= 0) {
- (void)lseek(fd, (long)(tty * sizeof(struct utmp)), L_SET);
- (void)write(fd, (char *)ut, sizeof(struct utmp));
- (void)close(fd);
- }
- if ((fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) >= 0) {
- (void)write(fd, (char *)ut, sizeof(struct utmp));
- (void)close(fd);
- }
- }
- /*
- * Copyright (c) 1988 The 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.
- */
-
- #if defined(LIBC_SCCS) && !defined(lint)
- static char sccsid[] = "@(#)logout.c 5.1 (Berkeley) 8/31/88";
- #endif /* LIBC_SCCS and not lint */
-
logout(line)
! register char *line;
{
! register FILE *fp;
! struct utmp ut;
! int rval;
! time_t time();
!
! if (!(fp = fopen(UTMP_FILE, "r+")))
! return(0);
! rval = 1;
! while (fread((char *)&ut, sizeof(struct utmp), 1, fp) == 1) {
! if (!ut.ut_name[0] ||
! strncmp(ut.ut_line, line, sizeof(ut.ut_line)))
! continue;
! memset(ut.ut_name,0, sizeof(ut.ut_name));
! #ifndef NO_UT_HOST
! memset(ut.ut_host,0, sizeof(ut.ut_host));
! #endif
! (void)time(&ut.ut_time);
! (void)fseek(fp, (long)-sizeof(struct utmp), L_INCR);
! (void)fwrite((char *)&ut, sizeof(struct utmp), 1, fp);
! (void)fseek(fp, (long)0, L_INCR);
! rval = 0;
! }
! (void)fclose(fp);
! return(rval);
}
!
!
! /*
! * Copyright (c) 1988 The 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.
! */
!
! #if defined(LIBC_SCCS) && !defined(lint)
! static char sccsid[] = "@(#)logwtmp.c 5.2 (Berkeley) 9/20/88";
! #endif /* LIBC_SCCS and not lint */
!
! static int fd = -1;
!
! #ifndef SYSV
! logwtmp(line, name, host, keep_open)
! #else
! logwtmp(line, name, host, keep_open, logingin)
! #endif
! char *line, *name, *host;
! int keep_open;
! #ifdef SYSV
! int logingin;
! #endif
{
! struct utmp ut;
! struct stat buf;
! time_t time();
! char *strncpy();
!
! if (fd < 0 && (fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0)) < 0)
! return;
! if (!fstat(fd, &buf)) {
! (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
! (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
! #ifndef NO_UT_HOST
! (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
! #endif
! #ifdef SYSV
! (void)strncpy(ut.ut_id, (char *)ut.ut_line + 4,
! sizeof(ut.ut_id));
! ut.ut_type = logingin ? USER_PROCESS : DEAD_PROCESS;
! ut.ut_pid = getpid();
! #endif
! (void)time(&ut.ut_time);
! if (write(fd, (char *)&ut, sizeof(struct utmp)) !=
! sizeof(struct utmp))
! (void)ftruncate(fd, buf.st_size);
! }
! if ( !keep_open)
! (void)close(fd);
}
--- 15,125 ----
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <sys/types.h>
#include <sys/file.h>
#include <utmp.h>
#include <stdio.h>
+ #include <strings.h>
#include <sys/time.h>
#include <sys/stat.h>
+ #define UTMPFILE "/etc/utmp"
+ #define WTMPFILE "/usr/adm/wtmp"
+
+ void
+ login(ut)
+ struct utmp *ut;
+ {
+ register int fd;
+ struct utmp utmp;
+ int tty;
+
+ #if defined(_AIX)
+ if (!ut->ut_pid)
+ ut->ut_pid = getppid();
+ ut->ut_type = USER_PROCESS;
+ (void) strncpy(ut->ut_id, ut->ut_line, sizeof(ut->ut_id));
+
+ (void) setutent();
+ (void) bzero((char *)&utmp, sizeof(utmp));
+ (void) strncpy(utmp.ut_id, ut->ut_id, sizeof(utmp.ut_id));
+ utmp.ut_type = DEAD_PROCESS;
+ (void) getutid(&utmp);
+ (void) pututline(ut);
+ (void) endutent();
+ #else
+ tty = ttyslot();
+ if (tty > 0 && (fd = open(UTMPFILE, O_WRONLY, 0)) >= 0) {
+ (void)lseek(fd, (long)(tty * sizeof(struct utmp)), L_SET);
+ (void)write(fd, (char *)ut, sizeof(struct utmp));
+ (void)close(fd);
+ }
+ #endif
+ if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) >= 0) {
+ (void)write(fd, (char *)ut, sizeof(struct utmp));
+ (void)close(fd);
+ }
+ }
logout(line)
! register char *line;
{
! register FILE *fp;
! struct utmp ut;
! int rval;
!
! if (!(fp = fopen(UTMPFILE, "r+")))
! return(0);
! rval = 1;
! while (fread((char *)&ut, sizeof(struct utmp), 1, fp) == 1) {
! if (!ut.ut_name[0] ||
! strncmp(ut.ut_line, line, sizeof(ut.ut_line)))
! continue;
! (void)bzero(ut.ut_name, sizeof(ut.ut_name));
! (void)bzero(ut.ut_host, sizeof(ut.ut_host));
! (void)time(&ut.ut_time);
! #if defined(_AIX)
! (void)bzero(ut.ut_id, sizeof(ut.ut_id));
! ut.ut_pid = ut.ut_exit.e_exit = 0;
! ut.ut_type = EMPTY;
! #endif
! (void)fseek(fp, (long)-sizeof(struct utmp), L_INCR);
! (void)fwrite((char *)&ut, sizeof(struct utmp), 1, fp);
! (void)fseek(fp, (long)0, L_INCR);
! rval = 0;
! }
! (void)fclose(fp);
! return(rval);
}
! logwtmp(line, name, host)
! char *line, *name, *host;
{
! struct utmp ut;
! struct stat buf;
! int fd;
!
! if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0)
! return;
! if (!fstat(fd, &buf)) {
! (void)bzero((char *)&ut, sizeof(ut));
! (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line));
! (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name));
! (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host));
! (void)time(&ut.ut_time);
! #if defined(_AIX)
! if (*name) {
! if (!ut.ut_pid)
! ut.ut_pid = getpid();
! ut.ut_type = USER_PROCESS;
! } else {
! ut.ut_type = EMPTY;
! }
! #endif
! if (write(fd, (char *)&ut, sizeof(struct utmp)) !=
! sizeof(struct utmp))
! (void)ftruncate(fd, buf.st_size);
! }
! (void)close(fd);
}
*** ./appl/bsd/krlogin.c.old 1992/11/20 15:23:26
--- ./appl/bsd/krlogin.c 1992/11/20 15:23:46
***************
*** 136,142 ****
# define SIGUSR1 30
# endif /* SIGUSR1 */
! char *index(), *rindex(), *getenv(), *strcat(), *strcpy();
#ifndef convex
struct passwd *getpwuid();
#endif
--- 136,148 ----
# define SIGUSR1 30
# endif /* SIGUSR1 */
! char *getenv(), *strcat(), *strcpy();
! #ifndef index
! char *index();
! #endif
! #ifndef rindex
! char *rindex();
! #endif
#ifndef convex
struct passwd *getpwuid();
#endif
*** ./appl/bsd/krlogind.c.old 1992/11/20 15:27:32
--- ./appl/bsd/krlogind.c 1992/12/09 15:03:14
***************
*** 95,101 ****
--- 95,106 ----
*/
#define LOG_REMOTE_REALM
+
+ /* XXXX These should be in the site.def file; the Imakefile needs some
+ changes */
+
#define KERBEROS
+ #define CRYPT
#include <stdio.h>
#include <sys/types.h>
***************
*** 139,144 ****
--- 144,150 ----
#include <netdb.h>
#include <syslog.h>
#include <strings.h>
+ #include <ctype.h>
#include <sys/param.h>
#include <utmp.h>
***************
*** 180,192 ****
#endif
#endif
! #define ARGSTR "rRkKeExXpP?"
#else /* !KERBEROS */
! #define ARGSTR "rRpP?"
#define des_read read
#define des_write write
#endif /* KERBEROS */
#ifdef DO_NOT_USE_K_LOGIN
#ifdef sysvimp
#define LOGIN_PROGRAM "/bin/remlogin"
--- 186,199 ----
#endif
#endif
! #define ARGSTR "rRkKeExXpPD:?"
#else /* !KERBEROS */
! #define ARGSTR "rRpPD:?"
#define des_read read
#define des_write write
#endif /* KERBEROS */
+ #ifndef LOGIN_PROGRAM
#ifdef DO_NOT_USE_K_LOGIN
#ifdef sysvimp
#define LOGIN_PROGRAM "/bin/remlogin"
***************
*** 196,201 ****
--- 203,209 ----
#else /* DO_NOT_USE_K_LOGIN */
#define LOGIN_PROGRAM "/krb5/etc/login.krb5"
#endif
+ #endif
struct utmp wtmp;
#define NMAX sizeof(wtmp.ut_name)
***************
*** 212,218 ****
extern int errno;
int reapchild();
struct passwd *getpwnam();
! #ifndef ultrix
char *malloc();
#endif
char *progname;
--- 220,226 ----
extern int errno;
int reapchild();
struct passwd *getpwnam();
! #ifndef __STDC__
char *malloc();
#endif
char *progname;
***************
*** 228,237 ****
int argc;
char **argv;
{
! extern int opterr, optind;
int on = 1, fromlen, ch, i;
struct sockaddr_in from;
char *options;
progname = *argv;
--- 236,247 ----
int argc;
char **argv;
{
! extern int opterr, optind, optarg;
int on = 1, fromlen, ch, i;
struct sockaddr_in from;
char *options;
+ int debug_port = 0;
+ int fd;
progname = *argv;
***************
*** 267,277 ****
options[0] = '\0';
for (i = 0; (progname[i] != '\0') && (i < MAX_PROG_NAME); i++)
if (!strcmp(progname+i, "logind")) {
strcpy(options, "-");
strncat(options, progname, i);
argc = 2;
! argv[1] = options;
! argv[2] = NULL;
break;
}
if (options[0] == '\0') {
--- 277,294 ----
options[0] = '\0';
for (i = 0; (progname[i] != '\0') && (i < MAX_PROG_NAME); i++)
if (!strcmp(progname+i, "logind")) {
+ char **newargv;
+
+ newargv = (char **) malloc(sizeof(char *) * 3);
+
strcpy(options, "-");
strncat(options, progname, i);
+
+ newargv[0] = argv[0];
+ newargv[1] = options;
+ newargv[2] = NULL;
argc = 2;
! argv = newargv;
break;
}
if (options[0] == '\0') {
***************
*** 316,321 ****
--- 333,341 ----
case 'P': /* passwd is a must */
passwd_req = 1;
break;
+ case 'D':
+ debug_port = atoi(optarg);
+ break;
case '?':
default:
usage();
***************
*** 326,344 ****
argv += optind;
fromlen = sizeof (from);
! if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
! syslog(LOG_ERR,"Can't get peer name of remote host: %m");
#ifdef STDERR_FILENO
! fatal(STDERR_FILENO, "Can't get peer name of remote host", 1);
#else
! fatal(3, "Can't get peer name of remote host", 1);
#endif
!
}
! if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0)
syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
! doit(0, &from);
}
--- 346,399 ----
argv += optind;
fromlen = sizeof (from);
!
! if (debug_port) {
! int s;
! struct sockaddr_in sin;
!
! if ((s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) {
! fprintf(stderr, "Error in socket: %s\n", strerror(errno));
! exit(2);
! }
!
! bzero((char *) &sin,sizeof(sin));
! sin.sin_family = AF_INET;
! sin.sin_port = htons(debug_port);
! sin.sin_addr.s_addr = INADDR_ANY;
!
! if ((bind(s, (struct sockaddr *) &sin, sizeof(sin))) < 0) {
! fprintf(stderr, "Error in bind: %s\n", strerror(errno));
! exit(2);
! }
!
! if ((listen(s, 5)) < 0) {
! fprintf(stderr, "Error in listen: %s\n", strerror(errno));
! exit(2);
! }
!
! if ((fd = accept(s, &from, &fromlen)) < 0) {
! fprintf(stderr, "Error in accept: %s\n", strerror(errno));
! exit(2);
! }
!
! close(s);
! } else {
! if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
! syslog(LOG_ERR,"Can't get peer name of remote host: %m");
#ifdef STDERR_FILENO
! fatal(STDERR_FILENO, "Can't get peer name of remote host", 1);
#else
! fatal(3, "Can't get peer name of remote host", 1);
#endif
! }
!
! fd = 0;
}
!
! if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof (on)) < 0)
syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
! doit(fd, &from);
}
***************
*** 435,443 ****
}
#else
rusername = malloc(sizeof (lusername) + 1);
! getstr(rusername, sizeof(lusername), "remuser");
! getstr(lusername, sizeof(lusername), "locuser");
! getstr(term, sizeof(term), "Terminal type");
#endif
write(f, "", 1);
--- 490,498 ----
}
#else
rusername = malloc(sizeof (lusername) + 1);
! getstr(f, rusername, sizeof(lusername), "remuser");
! getstr(f, lusername, sizeof(lusername), "locuser");
! getstr(f, term, sizeof(term), "Terminal type");
#endif
write(f, "", 1);
***************
*** 462,474 ****
#endif
fatalperror(f, line);
#ifndef SYSV
! signal(SIGHUP, SIG_IGN);
! vhangup();
! signal(SIGHUP, SIG_DFL);
#ifdef ultrix /* Someone needs to cleanup all this and have a consistant
way of associating controlling tty to a process. */
setpgrp();
#endif
t = open(line, O_RDWR);
if (t < 0)
fatalperror(f, line);
--- 517,534 ----
#endif
fatalperror(f, line);
#ifndef SYSV
! if (f == 0) { /* if operating standalone, do not reset tty!! */
! signal(SIGHUP, SIG_IGN);
! vhangup();
! signal(SIGHUP, SIG_DFL);
! }
#ifdef ultrix /* Someone needs to cleanup all this and have a consistant
way of associating controlling tty to a process. */
setpgrp();
#endif
+ #if defined (sun) || defined (POSIX)
+ setsid();
+ #endif
t = open(line, O_RDWR);
if (t < 0)
fatalperror(f, line);
***************
*** 607,615 ****
execl(LOGIN_PROGRAM, "login", "-r", rhost_name, 0);
#else
if (passwd_req)
! execl(LOGIN_PROGRAM, "login", rhost_name,0);
else
! execl(LOGIN_PROGRAM, "login", "-f", rhost_name, 0);
#endif
fatalperror(2, LOGIN_PROGRAM, errno);
--- 667,675 ----
execl(LOGIN_PROGRAM, "login", "-r", rhost_name, 0);
#else
if (passwd_req)
! execl(LOGIN_PROGRAM, "login", "-h", rhost_name, lusername,0);
else
! execl(LOGIN_PROGRAM, "login", "-h", rhost_name, "-e", lusername, 0);
#endif
fatalperror(2, LOGIN_PROGRAM, errno);
***************
*** 660,665 ****
--- 720,727 ----
#endif
#if defined(KERBEROS)
+ #if 0 /* the code in the login I'm using only reads term. local user
+ is passed in on the command line, and remote user is not used */
/* Pass down rusername and lusername which we have
obtained from ticket and authorized by PWC_ACCESS.
Note lusername's .rhost should have entry for rusername.
***************
*** 666,671 ****
--- 728,734 ----
*/
(void) write(p, rusername, strlen(rusername) +1);
(void) write(p, lusername, strlen(lusername) +1);
+ #endif
/* stuff term info down to login */
if( write(p, term, strlen(term)+1) <= 0 ){
/*
***************
*** 945,950 ****
--- 1008,1015 ----
krb5_principal server;
char srv_name[100];
char def_host[100];
+ struct hostent *he;
+ char *ptr;
krb5_data inbuf;
if (getuid()) {
***************
*** 968,983 ****
peeraddr.length = SIZEOF_INADDR;
peeraddr.contents = (krb5_octet *)&peersin.sin_addr;
! strcpy(srv_name, "host/");
! gethostname(def_host, 100);
! strcat(srv_name, def_host);
! if (status = krb5_parse_name(srv_name, &server)) {
syslog(LOG_ERR, "parse server name %s: %s", "host",
error_message(status));
exit(1);
}
! krb5_princ_type(server) = KRB5_NT_SRV_HST;
!
if (status = krb5_recvauth(&netf,
"KCMDV0.1",
server, /* no match on server
--- 1033,1045 ----
peeraddr.length = SIZEOF_INADDR;
peeraddr.contents = (krb5_octet *)&peersin.sin_addr;
! if (status = krb5_sname_to_principal(NULL,"host",KRB5_NT_SRV_HST,
! &server)) {
syslog(LOG_ERR, "parse server name %s: %s", "host",
error_message(status));
exit(1);
}
!
if (status = krb5_recvauth(&netf,
"KCMDV0.1",
server, /* no match on server
***************
*** 1014,1023 ****
if (inbuf.length)
fatal(netf, "Forwarding is not yet supported");
! getstr(lusername, sizeof(lusername), "locuser");
! getstr(term, sizeof(term), "Terminal type");
rusername = malloc(sizeof (lusername) + 1);
! getstr(rusername, sizeof(lusername), "remuser");
failed_auth = 1;
if (ticket)
--- 1076,1085 ----
if (inbuf.length)
fatal(netf, "Forwarding is not yet supported");
! getstr(netf, lusername, sizeof(lusername), "locuser");
! getstr(netf, term, sizeof(term), "Terminal type");
rusername = malloc(sizeof (lusername) + 1);
! getstr(netf, rusername, sizeof(lusername), "remuser");
failed_auth = 1;
if (ticket)
***************
*** 1046,1055 ****
if (inbuf.length)
fatal(netf, "Forwarding is not yet supported");
! getstr(lusername, sizeof(lusername), "locuser");
! getstr(term, sizeof(term), "Terminal type");
rusername = malloc(sizeof (lusername) + 1);
! getstr(rusername, sizeof(lusername), "remuser");
/* OK we have authenticated this user - now check authorization. */
/* We must do this here since we want the same functionality as */
--- 1108,1117 ----
if (inbuf.length)
fatal(netf, "Forwarding is not yet supported");
! getstr(netf, lusername, sizeof(lusername), "locuser");
! getstr(netf, term, sizeof(term), "Terminal type");
rusername = malloc(sizeof (lusername) + 1);
! getstr(netf, rusername, sizeof(lusername), "remuser");
/* OK we have authenticated this user - now check authorization. */
/* We must do this here since we want the same functionality as */
***************
*** 1103,1120 ****
return;
}
!
!
! getstr(buf, cnt, err)
char *buf;
int cnt;
char *err;
{
-
char c;
do {
! if (read(0, &c, 1) != 1) {
exit(1);
}
if (--cnt < 0) {
--- 1165,1180 ----
return;
}
! getstr(fd, buf, cnt, err)
! int fd;
char *buf;
int cnt;
char *err;
{
char c;
do {
! if (read(fd, &c, 1) != 1) {
exit(1);
}
if (--cnt < 0) {
***************
*** 1318,1327 ****
void usage()
{
#ifdef KERBEROS
! syslog(LOG_ERR,
! "usage: klogind [-rRkKxpP] or [r/R][k/K][x/e][p/P]logind");
#else
! syslog(LOG_ERR, "usage: rlogind [-rRpP] or [r/R][p/P]logind");
#endif
}
--- 1378,1387 ----
void usage()
{
#ifdef KERBEROS
! syslog(LOG_ERR,
! "usage: klogind [-rRkKxpP] [-D port] or [r/R][k/K][x/e][p/P]logind");
#else
! syslog(LOG_ERR, "usage: rlogind [-rRpP] [-D port] or [r/R][p/P]logind");
#endif
}