summaryrefslogtreecommitdiffstats
path: root/libexec/rlogind
diff options
context:
space:
mode:
authormarkm <markm@FreeBSD.org>1999-09-19 22:05:32 +0000
committermarkm <markm@FreeBSD.org>1999-09-19 22:05:32 +0000
commit0b2fe68756570c146bda89ff69a3d209aac9f8be (patch)
tree8d4295813f9b149f83950d8b50c74d07c35aa987 /libexec/rlogind
parentfc84b1a733b5c4774a2dcd8035e4f71948716a55 (diff)
downloadFreeBSD-src-0b2fe68756570c146bda89ff69a3d209aac9f8be.zip
FreeBSD-src-0b2fe68756570c146bda89ff69a3d209aac9f8be.tar.gz
Fix for new Kerberos4. Make a fist cut at PAM-ising while I'm here.
Diffstat (limited to 'libexec/rlogind')
-rw-r--r--libexec/rlogind/Makefile17
-rw-r--r--libexec/rlogind/auth_pam.c142
-rw-r--r--libexec/rlogind/pathnames.h2
-rw-r--r--libexec/rlogind/rlogind.c162
4 files changed, 177 insertions, 146 deletions
diff --git a/libexec/rlogind/Makefile b/libexec/rlogind/Makefile
index ae34f30..bae4a4b 100644
--- a/libexec/rlogind/Makefile
+++ b/libexec/rlogind/Makefile
@@ -8,17 +8,12 @@ DPADD= ${LIBUTIL}
LDADD= -lutil
CFLAGS+= -Wall
-.if exists(${DESTDIR}${LIBDIR}/libkrb.a) && defined(MAKE_KERBEROS4)
-SRCS+= encrypt.c
-CFLAGS+=-DKERBEROS -DCRYPT -DHAVE_CONFIG_H \
- -I${.CURDIR}/../../kerberosIV/include \
- -I${.CURDIR}/../../crypto/kerberosIV/include \
- -I${.CURDIR}/../../crypto/kerberosIV/lib/roken \
- -I${.CURDIR}/../../crypto/kerberosIV/appl/bsd
-DPADD= ${LIBKRB} ${LIBDES} ${LIBCRYPT} ${LIBCOM_ERR)
-LDADD+= -lkrb -ldes -lcrypt -lcom_err
-DISTRIBUTION= krb
-.PATH: ${.CURDIR}/../../crypto/kerberosIV/appl/bsd
+.if defined(NOPAM)
+CFLAGS+= -DNO_PAM
+.else
+SRCS+= auth_pam.c
+DPADD+= ${LIBPAM}
+LDADD+= ${MINUSLPAM}
.endif
.include <bsd.prog.mk>
diff --git a/libexec/rlogind/auth_pam.c b/libexec/rlogind/auth_pam.c
new file mode 100644
index 0000000..e452107
--- /dev/null
+++ b/libexec/rlogind/auth_pam.c
@@ -0,0 +1,142 @@
+/*-
+ * Copyright (c) 1999 John Polstra
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <security/pam_appl.h>
+#include <security/pam_misc.h>
+#include <paths.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+/*
+ * Attempt to authenticate the user using PAM. Returns 0 if the user is
+ * authenticated, or 1 if not authenticated. If some sort of PAM system
+ * error occurs (e.g., the "/etc/pam.conf" file is missing) then this
+ * function returns -1. This can be used as an indication that we should
+ * fall back to a different authentication mechanism.
+ */
+
+int
+auth_pam(char *username)
+{
+ struct passwd *pawd;
+ pam_handle_t *pamh = NULL;
+ const char *tmpl_user;
+ const void *item;
+ int rval;
+ char *tty, *ttyn;
+ char hostname[MAXHOSTNAMELEN];
+ char tname[sizeof(_PATH_TTY) + 10];
+ int e;
+
+ static struct pam_conv conv = { misc_conv, NULL };
+
+ ttyn = ttyname(STDIN_FILENO);
+
+ if (ttyn == NULL || *ttyn == '\0') {
+ (void)snprintf(tname, sizeof(tname), "%s??", _PATH_TTY);
+ ttyn = tname;
+ }
+ if ((tty = strrchr(ttyn, '/')) != NULL)
+ ++tty;
+ else
+ tty = ttyn;
+
+ rval = gethostname(hostname, sizeof(hostname));
+
+ if (rval < 0) {
+ syslog(LOG_ERR, "auth_pam: Failed to resolve local hostname");
+ return -1;
+ }
+ if ((e = pam_start("rshd", username, &conv, &pamh)) != PAM_SUCCESS) {
+ syslog(LOG_ERR, "pam_start: %s", pam_strerror(pamh, e));
+ return -1;
+ }
+ if ((e = pam_set_item(pamh, PAM_TTY, tty)) != PAM_SUCCESS) {
+ syslog(LOG_ERR, "pam_set_item(PAM_TTY): %s",
+ pam_strerror(pamh, e));
+ return -1;
+ }
+ if (hostname != NULL &&
+ (e = pam_set_item(pamh,PAM_RHOST, hostname)) != PAM_SUCCESS) {
+ syslog(LOG_ERR, "pam_set_item(PAM_RHOST): %s",
+ pam_strerror(pamh, e));
+ return -1;
+ }
+
+ e = pam_authenticate(pamh, 0);
+
+ switch (e) {
+ case PAM_SUCCESS:
+ /*
+ * With PAM we support the concept of a "template"
+ * user. The user enters a login name which is
+ * authenticated by PAM, usually via a remote service
+ * such as RADIUS or TACACS+. If authentication
+ * succeeds, a different but related "template" name
+ * is used for setting the credentials, shell, and
+ * home directory. The name the user enters need only
+ * exist on the remote authentication server, but the
+ * template name must be present in the local password
+ * database.
+ *
+ * This is supported by two various mechanisms in the
+ * individual modules. However, from the application's
+ * point of view, the template user is always passed
+ * back as a changed value of the PAM_USER item.
+ */
+ if ((e = pam_get_item(pamh, PAM_USER, &item)) ==
+ PAM_SUCCESS) {
+ tmpl_user = (const char *) item;
+ if (strcmp(username, tmpl_user) != 0)
+ pawd = getpwnam(tmpl_user);
+ } else
+ syslog(LOG_ERR, "Couldn't get PAM_USER: %s", pam_strerror(pamh, e));
+ rval = 0;
+ break;
+
+ case PAM_AUTH_ERR:
+ case PAM_USER_UNKNOWN:
+ case PAM_MAXTRIES:
+ rval = 1;
+ break;
+
+ default:
+ syslog(LOG_ERR, "auth_pam: %s", pam_strerror(pamh, e));
+ rval = -1;
+ break;
+ }
+ if ((e = pam_end(pamh, e)) != PAM_SUCCESS) {
+ syslog(LOG_ERR, "pam_end: %s", pam_strerror(pamh, e));
+ rval = -1;
+ }
+ return rval;
+}
diff --git a/libexec/rlogind/pathnames.h b/libexec/rlogind/pathnames.h
index 5240f19..17a8f5c 100644
--- a/libexec/rlogind/pathnames.h
+++ b/libexec/rlogind/pathnames.h
@@ -31,8 +31,10 @@
* SUCH DAMAGE.
*
* @(#)pathnames.h 8.1 (Berkeley) 6/4/93
+ * $FreeBSD$
*/
#include <paths.h>
#define _PATH_LOGIN "/usr/bin/login"
+#define _PATH_RLOGIN "/usr/bin/rlogin"
diff --git a/libexec/rlogind/rlogind.c b/libexec/rlogind/rlogind.c
index a99ac7e..111a56b 100644
--- a/libexec/rlogind/rlogind.c
+++ b/libexec/rlogind/rlogind.c
@@ -80,26 +80,16 @@ static const char rcsid[] =
#include <unistd.h>
#include "pathnames.h"
+#ifndef NO_PAM
+#include <security/pam_appl.h>
+#include <security/pam_misc.h>
+#endif
+
#ifndef TIOCPKT_WINDOW
#define TIOCPKT_WINDOW 0x80
#endif
-#ifdef KERBEROS
-#include <des.h>
-#include <krb.h>
-#define SECURE_MESSAGE "This rlogin session is using DES encryption for all transmissions.\r\n"
-
-AUTH_DAT *kdata;
-KTEXT ticket;
-u_char auth_buf[sizeof(AUTH_DAT)];
-u_char tick_buf[sizeof(KTEXT_ST)];
-Key_schedule schedule;
-int doencrypt, retval, use_kerberos, vacuous;
-
-#define ARGSTR "Dalnkvx"
-#else
-#define ARGSTR "Daln"
-#endif /* KERBEROS */
+#define ARGSTR "Dalnx"
char *env[2];
#define NMAX 30
@@ -123,6 +113,10 @@ void setup_term __P((int));
int do_krb_login __P((struct sockaddr_in *));
void usage __P((void));
+#ifndef NO_PAM
+extern int auth_pam __P((char *));
+#endif
+
int
main(argc, argv)
int argc;
@@ -149,19 +143,11 @@ main(argc, argv)
case 'n':
keepalive = 0;
break;
-#ifdef KERBEROS
- case 'k':
- use_kerberos = 1;
- break;
- case 'v':
- vacuous = 1;
- break;
#ifdef CRYPT
case 'x':
doencrypt = 1;
break;
#endif
-#endif
case '?':
default:
usage();
@@ -170,12 +156,6 @@ main(argc, argv)
argc -= optind;
argv += optind;
-#ifdef KERBEROS
- if (use_kerberos && vacuous) {
- usage();
- fatal(STDERR_FILENO, "only one of -k and -v allowed", 0);
- }
-#endif
fromlen = sizeof (from);
if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
syslog(LOG_ERR,"Can't get peer name of remote host: %m");
@@ -219,27 +199,12 @@ doit(f, fromp)
if (c != 0)
exit(1);
-#ifdef KERBEROS
- if (vacuous)
- fatal(f, "Remote host requires Kerberos authentication", 0);
-#endif
alarm(0);
fromp->sin_port = ntohs((u_short)fromp->sin_port);
realhostname(hostname, sizeof(hostname) - 1, &fromp->sin_addr);
hostname[sizeof(hostname) - 1] = '\0';
-#ifdef KERBEROS
- if (use_kerberos) {
- retval = do_krb_login(fromp);
- if (retval == 0)
- authenticated++;
- else if (retval > 0)
- fatal(f, krb_err_txt[retval], 0);
- write(f, &c, 1);
- confirmed = 1; /* we sent the null! */
- } else
-#endif
{
if (fromp->sin_family != AF_INET ||
fromp->sin_port >= IPPORT_RESERVED ||
@@ -283,7 +248,6 @@ doit(f, fromp)
write(f, "", 1);
confirmed = 1; /* we sent the null! */
}
-#ifdef KERBEROS
#ifdef CRYPT
if (doencrypt)
(void) des_enc_write(f,
@@ -291,7 +255,6 @@ doit(f, fromp)
strlen(SECURE_MESSAGE),
schedule, &kdata->session);
#endif
-#endif
netf = f;
pid = forkpty(&master, line, NULL, &win);
@@ -311,14 +274,6 @@ doit(f, fromp)
fatal(STDERR_FILENO, "invalid user", 0);
}
if (authenticated) {
-#ifdef KERBEROS
- if (use_kerberos && (pwd->pw_uid == 0))
- syslog(LOG_INFO|LOG_AUTH,
- "ROOT Kerberos login from %s.%s@%s on %s\n",
- kdata->pname, kdata->pinst, kdata->prealm,
- hostname);
-#endif
-
execl(_PATH_LOGIN, "login", "-p",
"-h", hostname, "-f", lusername, (char *)NULL);
} else
@@ -328,7 +283,6 @@ doit(f, fromp)
/*NOTREACHED*/
}
#ifdef CRYPT
-#ifdef KERBEROS
/*
* If encrypted, don't turn on NBIO or the des read/write
* routines will croak.
@@ -336,7 +290,6 @@ doit(f, fromp)
if (!doencrypt)
#endif
-#endif
ioctl(f, FIONBIO, &on);
ioctl(master, FIONBIO, &on);
ioctl(master, TIOCPKT, &on);
@@ -445,13 +398,11 @@ protocol(f, p)
}
if (FD_ISSET(f, &ibits)) {
#ifdef CRYPT
-#ifdef KERBEROS
if (doencrypt)
fcc = des_enc_read(f, fibuf, sizeof(fibuf),
schedule, &kdata->session);
else
#endif
-#endif
fcc = read(f, fibuf, sizeof(fibuf));
if (fcc < 0 && errno == EWOULDBLOCK)
fcc = 0;
@@ -499,10 +450,8 @@ protocol(f, p)
else if (pibuf[0] == 0) {
pbp++, pcc--;
#ifdef CRYPT
-#ifdef KERBEROS
if (!doencrypt)
#endif
-#endif
FD_SET(f, &obits); /* try write */
} else {
if (pkcontrol(pibuf[0])) {
@@ -514,13 +463,11 @@ protocol(f, p)
}
if ((FD_ISSET(f, &obits)) && pcc > 0) {
#ifdef CRYPT
-#ifdef KERBEROS
if (doencrypt)
cc = des_enc_write(f, pbp, pcc,
schedule, &kdata->session);
else
#endif
-#endif
cc = write(f, pbp, pcc);
if (cc < 0 && errno == EWOULDBLOCK) {
/*
@@ -588,10 +535,26 @@ int
do_rlogin(dest)
struct sockaddr_in *dest;
{
+ int retval;
+
getstr(rusername, sizeof(rusername), "remuser too long");
getstr(lusername, sizeof(lusername), "locuser too long");
getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type too long");
+#ifndef NO_PAM
+ retval = auth_pam(lusername);
+
+ if (retval) {
+ if (retval == -1) {
+ syslog(LOG_ERR, "PAM authentication failed");
+ }
+ else {
+ syslog(LOG_ERR,
+ "User %s failed PAM authentication", lusername);
+ exit(1);
+ }
+ }
+#endif
pwd = getpwnam(lusername);
if (pwd == NULL)
return (-1);
@@ -660,79 +623,8 @@ setup_term(fd)
environ = env;
}
-#ifdef KERBEROS
-#define VERSION_SIZE 9
-
-/*
- * Do the remote kerberos login to the named host with the
- * given inet address
- *
- * Return 0 on valid authorization
- * Return -1 on valid authentication, no authorization
- * Return >0 for error conditions
- */
-int
-do_krb_login(dest)
- struct sockaddr_in *dest;
-{
- int rc;
- char instance[INST_SZ], version[VERSION_SIZE];
- long authopts = 0L; /* !mutual */
- struct sockaddr_in faddr;
-
- kdata = (AUTH_DAT *) auth_buf;
- ticket = (KTEXT) tick_buf;
-
- instance[0] = '*';
- instance[1] = '\0';
-
-#ifdef CRYPT
- if (doencrypt) {
- rc = sizeof(faddr);
- if (getsockname(0, (struct sockaddr *)&faddr, &rc))
- return (-1);
- authopts = KOPT_DO_MUTUAL;
- rc = krb_recvauth(
- authopts, 0,
- ticket, "rcmd",
- instance, dest, &faddr,
- kdata, "", schedule, version);
- des_set_key(&kdata->session, schedule);
-
- } else
-#endif
- rc = krb_recvauth(
- authopts, 0,
- ticket, "rcmd",
- instance, dest, (struct sockaddr_in *) 0,
- kdata, "", NULL, version);
-
- if (rc != KSUCCESS)
- return (rc);
-
- getstr(lusername, sizeof(lusername), "locuser");
- /* get the "cmd" in the rcmd protocol */
- getstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type");
-
- pwd = getpwnam(lusername);
- if (pwd == NULL)
- return (-1);
-
- /* returns nonzero for no access */
- if (kuserok(kdata, lusername) != 0)
- return (-1);
-
- return (0);
-
-}
-#endif /* KERBEROS */
-
void
usage()
{
-#ifdef KERBEROS
- syslog(LOG_ERR, "usage: rlogind [-Daln] [-k | -v]");
-#else
- syslog(LOG_ERR, "usage: rlogind [-Daln]");
-#endif
+ syslog(LOG_ERR, "usage: rlogind [-" ARGSTR "]");
}
OpenPOWER on IntegriCloud