summaryrefslogtreecommitdiffstats
path: root/libexec
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
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')
-rw-r--r--libexec/ftpd/Makefile12
-rw-r--r--libexec/ftpd/ftpd.c160
-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
-rw-r--r--libexec/rshd/Makefile14
-rw-r--r--libexec/rshd/rshd.c205
8 files changed, 388 insertions, 326 deletions
diff --git a/libexec/ftpd/Makefile b/libexec/ftpd/Makefile
index bd5453f..ad5d142 100644
--- a/libexec/ftpd/Makefile
+++ b/libexec/ftpd/Makefile
@@ -17,13 +17,11 @@ LSDIR= ../../bin/ls
SRCS+= ls.c cmp.c print.c stat_flags.c util.c
CFLAGS+=-DINTERNAL_LS -Dmain=ls_main -I${.CURDIR}/${LSDIR}
-.if exists(${DESTDIR}/usr/lib/libkrb.a) && defined(MAKE_KERBEROS4)
-.PATH: ${.CURDIR}/../../lib/libpam/modules/pam_kerberosIV
-SRCS+= klogin.c
-LDADD+= -lkrb -ldes -lcom_err
-DPADD+= ${LIBKRB} ${LIBDES} ${LIBCOM_ERR}
-CFLAGS+=-DKERBEROS
-DISTRIBUTION= krb
+.if defined(NOPAM)
+CFLAGS+=-DNOPAM
+.else
+DPADD+= ${LIBPAM}
+LDADD+= ${MINUSLPAM}
.endif
.include <bsd.prog.mk>
diff --git a/libexec/ftpd/ftpd.c b/libexec/ftpd/ftpd.c
index 52321ef..0f9d20c 100644
--- a/libexec/ftpd/ftpd.c
+++ b/libexec/ftpd/ftpd.c
@@ -94,6 +94,10 @@ static const char rcsid[] =
#include <skey.h>
#endif
+#if !defined(NOPAM)
+#include <security/pam_appl.h>
+#endif
+
#include "pathnames.h"
#include "extern.h"
@@ -168,19 +172,13 @@ char *ident = NULL;
static char ttyline[20];
char *tty = ttyline; /* for klogin */
-#ifdef KERBEROS
-int klogin __P((struct passwd *, char *, char *, char *));
+#if !defined(NOPAM)
+static int auth_pam __P((struct passwd**, const char*));
#endif
struct in_addr bind_address;
char *pid_file = NULL;
-#if defined(KERBEROS)
-int notickets = 1;
-int noticketsdontcomplain = 1;
-char *krbtkfile_env = NULL;
-#endif
-
/*
* Timeout intervals for retrying connections
* to hosts that don't accept PORT cmds. This
@@ -914,6 +912,132 @@ end_login()
dochroot = 0;
}
+#if !defined(NOPAM)
+
+/*
+ * the following code is stolen from imap-uw PAM authentication module and
+ * login.c
+ */
+#define COPY_STRING(s) (s ? strdup(s) : NULL)
+
+struct cred_t {
+ const char *uname; /* user name */
+ const char *pass; /* password */
+};
+typedef struct cred_t cred_t;
+
+static int
+auth_conv(int num_msg, const struct pam_message **msg,
+ struct pam_response **resp, void *appdata)
+{
+ int i;
+ cred_t *cred = (cred_t *) appdata;
+ struct pam_response *reply =
+ malloc(sizeof(struct pam_response) * num_msg);
+
+ for (i = 0; i < num_msg; i++) {
+ switch (msg[i]->msg_style) {
+ case PAM_PROMPT_ECHO_ON: /* assume want user name */
+ reply[i].resp_retcode = PAM_SUCCESS;
+ reply[i].resp = COPY_STRING(cred->uname);
+ /* PAM frees resp. */
+ break;
+ case PAM_PROMPT_ECHO_OFF: /* assume want password */
+ reply[i].resp_retcode = PAM_SUCCESS;
+ reply[i].resp = COPY_STRING(cred->pass);
+ /* PAM frees resp. */
+ break;
+ case PAM_TEXT_INFO:
+ case PAM_ERROR_MSG:
+ reply[i].resp_retcode = PAM_SUCCESS;
+ reply[i].resp = NULL;
+ break;
+ default: /* unknown message style */
+ free(reply);
+ return PAM_CONV_ERR;
+ }
+ }
+
+ *resp = reply;
+ return PAM_SUCCESS;
+}
+
+/*
+ * 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.
+ */
+static int
+auth_pam(struct passwd **ppw, const char *pass)
+{
+ pam_handle_t *pamh = NULL;
+ const char *tmpl_user;
+ const void *item;
+ int rval;
+ int e;
+ cred_t auth_cred = { (*ppw)->pw_name, pass };
+ struct pam_conv conv = { &auth_conv, &auth_cred };
+
+ e = pam_start("ftpd", (*ppw)->pw_name, &conv, &pamh);
+ if (e != PAM_SUCCESS) {
+ syslog(LOG_ERR, "pam_start: %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((*ppw)->pw_name, tmpl_user) != 0)
+ *ppw = 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;
+}
+
+#endif /* !defined(NOPAM) */
+
void
pass(passwd)
char *passwd;
@@ -934,9 +1058,9 @@ pass(passwd)
rval = 1; /* failure below */
goto skip;
}
-#if defined(KERBEROS)
- rval = klogin(pw, "", hostname, passwd);
- if (rval == 0)
+#if !defined(NOPAM)
+ rval = auth_pam(&pw, passwd);
+ if (rval >= 0)
goto skip;
#endif
#ifdef SKEY
@@ -953,7 +1077,7 @@ pass(passwd)
skip:
/*
* If rval == 1, the user failed the authentication check
- * above. If rval == 0, either Kerberos or local authentication
+ * above. If rval == 0, either PAM or local authentication
* succeeded.
*/
if (rval) {
@@ -1085,14 +1209,14 @@ skip:
if (thishost != firsthost)
snprintf(proctitle, sizeof(proctitle),
"%s: anonymous(%s)/%.*s", remotehost, hostname,
- sizeof(proctitle) - sizeof(remotehost) -
- sizeof(": anonymous/"), passwd);
+ (int)(sizeof(proctitle) - sizeof(remotehost) -
+ sizeof(": anonymous/")), passwd);
else
#endif
snprintf(proctitle, sizeof(proctitle),
"%s: anonymous/%.*s", remotehost,
- sizeof(proctitle) - sizeof(remotehost) -
- sizeof(": anonymous/"), passwd);
+ (int)(sizeof(proctitle) - sizeof(remotehost) -
+ sizeof(": anonymous/")), passwd);
setproctitle("%s", proctitle);
#endif /* SETPROCTITLE */
if (logging)
@@ -1937,10 +2061,6 @@ dologout(status)
if (logged_in) {
(void) seteuid((uid_t)0);
ftpd_logwtmp(ttyline, "", "");
-#if defined(KERBEROS)
- if (!notickets && krbtkfile_env)
- unlink(krbtkfile_env);
-#endif
}
/* beware of flushing buffers after a SIGPIPE */
_exit(status);
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 "]");
}
diff --git a/libexec/rshd/Makefile b/libexec/rshd/Makefile
index cf3acf3..2005122 100644
--- a/libexec/rshd/Makefile
+++ b/libexec/rshd/Makefile
@@ -5,11 +5,13 @@ PROG= rshd
SRCS= rshd.c
MAN8= rshd.8
-.if exists(${DESTDIR}${LIBDIR}/libkrb.a) && defined(MAKE_KERBEROS4)
-CFLAGS+=-DKERBEROS -DCRYPT
-DPADD= ${LIBKRB} ${LIBDES} ${LIBCRYPT} ${LIBCOM_ERR}
-LDADD= -lkrb -ldes -lcrypt -lcom_err
-DISTRIBUTION= krb
+.if defined(NOPAM)
+CFLAGS+= -DNO_PAM
+.else
+#CFLAGS+= -DCRYPT
+SRCS+= auth_pam.c
+DPADD+= ${LIBPAM}
+LDADD+= ${MINUSLPAM}
.endif
# For login_cap handling
@@ -18,3 +20,5 @@ DPADD+= ${LIBUTIL}
LDADD+= -lutil
.include <bsd.prog.mk>
+
+.PATH: ${.CURDIR}/../rlogind
diff --git a/libexec/rshd/rshd.c b/libexec/rshd/rshd.c
index c2afeb5..8533644 100644
--- a/libexec/rshd/rshd.c
+++ b/libexec/rshd/rshd.c
@@ -84,6 +84,9 @@ int keepalive = 1;
int log_success; /* If TRUE, log all successful accesses */
int sent_null;
int no_delay;
+#ifdef CRYPT
+int doencrypt = 0;
+#endif
void doit __P((struct sockaddr_in *));
void error __P((const char *, ...));
@@ -92,20 +95,12 @@ int local_domain __P((char *));
char *topdomain __P((char *));
void usage __P((void));
-#ifdef KERBEROS
-#include <des.h>
-#include <krb.h>
-#define VERSION_SIZE 9
-#define SECURE_MESSAGE "This rsh session is using DES encryption for all transmissions.\r\n"
-#define OPTIONS "alnkvxDL"
-char authbuf[sizeof(AUTH_DAT)];
-char tickbuf[sizeof(KTEXT_ST)];
-int doencrypt, use_kerberos, vacuous;
-Key_schedule schedule;
-#else
-#define OPTIONS "alnDL"
+#ifndef NO_PAM
+extern int auth_pam __P((char *));
#endif
+#define OPTIONS "alnDL"
+
int
main(argc, argv)
int argc;
@@ -130,21 +125,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 'D':
no_delay = 1;
break;
@@ -160,18 +145,12 @@ main(argc, argv)
argc -= optind;
argv += optind;
-#ifdef KERBEROS
- if (use_kerberos && vacuous) {
- syslog(LOG_ERR, "only one of -k and -v allowed");
- exit(2);
- }
#ifdef CRYPT
- if (doencrypt && !use_kerberos) {
+ if (doencrypt) {
syslog(LOG_ERR, "-k is required for -x");
exit(2);
}
#endif
-#endif
fromlen = sizeof (from);
if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
@@ -217,23 +196,15 @@ doit(fromp)
char *cp, sig, buf[BUFSIZ];
char cmdbuf[NCARGS+1], locuser[16], remuser[16];
char fromhost[MAXHOSTNAMELEN];
+ int retval;
+#ifdef CRYPT
+ int rc;
+ int pv1[2], pv2[2];
+#endif
#ifdef LOGIN_CAP
login_cap_t *lc;
#endif
-#ifdef KERBEROS
- AUTH_DAT *kdata = (AUTH_DAT *) NULL;
- KTEXT ticket = (KTEXT) NULL;
- char instance[INST_SZ], version[VERSION_SIZE];
- struct sockaddr_in fromaddr;
- int rc;
- long authopts;
- int pv1[2], pv2[2];
- fd_set wready, writeto;
-
- fromaddr = *fromp;
-#endif
-
(void) signal(SIGINT, SIG_DFL);
(void) signal(SIGQUIT, SIG_DFL);
(void) signal(SIGTERM, SIG_DFL);
@@ -280,17 +251,14 @@ doit(fromp)
}
#endif
-#ifdef KERBEROS
- if (!use_kerberos)
-#endif
- if (fromp->sin_port >= IPPORT_RESERVED ||
- fromp->sin_port < IPPORT_RESERVED/2) {
- syslog(LOG_NOTICE|LOG_AUTH,
- "connection from %s on illegal port %u",
- inet_ntoa(fromp->sin_addr),
- fromp->sin_port);
- exit(1);
- }
+ if (fromp->sin_port >= IPPORT_RESERVED ||
+ fromp->sin_port < IPPORT_RESERVED/2) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ "connection from %s on illegal port %u",
+ inet_ntoa(fromp->sin_addr),
+ fromp->sin_port);
+ exit(1);
+ }
(void) alarm(60);
port = 0;
@@ -316,17 +284,14 @@ doit(fromp)
syslog(LOG_ERR, "can't get stderr port: %m");
exit(1);
}
-#ifdef KERBEROS
- if (!use_kerberos)
-#endif
- if (port >= IPPORT_RESERVED ||
- port < IPPORT_RESERVED/2) {
- syslog(LOG_NOTICE|LOG_AUTH,
- "2nd socket from %s on unreserved port %u",
- inet_ntoa(fromp->sin_addr),
- port);
- exit(1);
- }
+ if (port >= IPPORT_RESERVED ||
+ port < IPPORT_RESERVED/2) {
+ syslog(LOG_NOTICE|LOG_AUTH,
+ "2nd socket from %s on unreserved port %u",
+ inet_ntoa(fromp->sin_addr),
+ port);
+ exit(1);
+ }
fromp->sin_port = htons(port);
if (connect(s, (struct sockaddr *)fromp, sizeof (*fromp)) < 0) {
syslog(LOG_INFO, "connect second port %d: %m", port);
@@ -334,60 +299,29 @@ doit(fromp)
}
}
-#ifdef KERBEROS
- if (vacuous) {
- error("rshd: remote host requires Kerberos authentication\n");
- exit(1);
- }
-#endif
-
-#ifdef notdef
- /* from inetd, socket is already on 0, 1, 2 */
- dup2(f, 0);
- dup2(f, 1);
- dup2(f, 2);
-#endif
errorstr = NULL;
realhostname(fromhost, sizeof(fromhost) - 1, &fromp->sin_addr);
fromhost[sizeof(fromhost) - 1] = '\0';
-#ifdef KERBEROS
- if (use_kerberos) {
- kdata = (AUTH_DAT *) authbuf;
- ticket = (KTEXT) tickbuf;
- authopts = 0L;
- strcpy(instance, "*");
- version[VERSION_SIZE - 1] = '\0';
#ifdef CRYPT
- if (doencrypt) {
- struct sockaddr_in local_addr;
- rc = sizeof(local_addr);
- if (getsockname(0, (struct sockaddr *)&local_addr,
- &rc) < 0) {
- syslog(LOG_ERR, "getsockname: %m");
- error("rlogind: getsockname: %m");
- exit(1);
- }
- authopts = KOPT_DO_MUTUAL;
- rc = krb_recvauth(authopts, 0, ticket,
- "rcmd", instance, &fromaddr,
- &local_addr, kdata, "", schedule,
- version);
- des_set_key(&kdata->session, schedule);
- } else
-#endif
- rc = krb_recvauth(authopts, 0, ticket, "rcmd",
- instance, &fromaddr,
- (struct sockaddr_in *) 0,
- kdata, "", NULL, version);
- if (rc != KSUCCESS) {
- error("Kerberos authentication failure: %s\n",
- krb_err_txt[rc]);
+ if (doencrypt) {
+ struct sockaddr_in local_addr;
+ rc = sizeof(local_addr);
+ if (getsockname(0, (struct sockaddr *)&local_addr,
+ &rc) < 0) {
+ syslog(LOG_ERR, "getsockname: %m");
+ error("rlogind: getsockname: %m");
exit(1);
}
- } else
+ authopts = KOPT_DO_MUTUAL;
+ rc = krb_recvauth(authopts, 0, ticket,
+ "rcmd", instance, &fromaddr,
+ &local_addr, kdata, "", schedule,
+ version);
+ des_set_key(&kdata->session, schedule);
+ }
#endif
- getstr(remuser, sizeof(remuser), "remuser");
+ getstr(remuser, sizeof(remuser), "remuser");
getstr(locuser, sizeof(locuser), "locuser");
getstr(cmdbuf, sizeof(cmdbuf), "command");
@@ -427,19 +361,20 @@ doit(fromp)
pwd->pw_dir = "/";
}
-#ifdef KERBEROS
- if (use_kerberos) {
- if (pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0') {
- if (kuserok(kdata, locuser) != 0) {
- syslog(LOG_INFO|LOG_AUTH,
- "Kerberos rsh denied to %s.%s@%s",
- kdata->pname, kdata->pinst, kdata->prealm);
- error("Login incorrect.\n");
- exit(1);
- }
+#ifndef NO_PAM
+ retval = auth_pam(locuser);
+
+ if (retval) {
+ if (retval == -1) {
+ syslog(LOG_ERR,"PAM authentication failed");
}
- } else
-#endif
+ else {
+ syslog(LOG_ERR,
+ "User %s failed PAM authentication", locuser);
+ exit(1);
+ }
+ }
+#endif
if (errorstr ||
(pwd->pw_expire && time(NULL) >= pwd->pw_expire) ||
@@ -502,7 +437,6 @@ fail:
exit(1);
}
#ifdef CRYPT
-#ifdef KERBEROS
if (doencrypt) {
if (pipe(pv1) < 0) {
error("Can't make 2nd pipe.\n");
@@ -514,7 +448,6 @@ fail:
}
}
#endif
-#endif
pid = fork();
if (pid == -1) {
error("Can't fork; try again.\n");
@@ -522,7 +455,6 @@ fail:
}
if (pid) {
#ifdef CRYPT
-#ifdef KERBEROS
if (doencrypt) {
static char msg[] = SECURE_MESSAGE;
(void) close(pv1[1]);
@@ -532,7 +464,6 @@ fail:
} else
#endif
-#endif
{
(void) close(0);
(void) close(1);
@@ -548,7 +479,6 @@ fail:
else
nfd = s;
#ifdef CRYPT
-#ifdef KERBEROS
if (doencrypt) {
FD_ZERO(&writeto);
FD_SET(pv2[0], &writeto);
@@ -558,7 +488,6 @@ fail:
nfd = MAX(nfd, pv1[0]);
} else
#endif
-#endif
ioctl(pv[0], FIONBIO, (char *)&one);
/* should set s nbio! */
@@ -566,7 +495,6 @@ fail:
do {
ready = readfrom;
#ifdef CRYPT
-#ifdef KERBEROS
if (doencrypt) {
wready = writeto;
if (select(nfd, &ready,
@@ -575,20 +503,17 @@ fail:
break;
} else
#endif
-#endif
if (select(nfd, &ready, (fd_set *)0,
(fd_set *)0, (struct timeval *)0) < 0)
break;
if (FD_ISSET(s, &ready)) {
int ret;
#ifdef CRYPT
-#ifdef KERBEROS
if (doencrypt)
ret = des_enc_read(s, &sig, 1,
schedule, &kdata->session);
else
#endif
-#endif
ret = read(s, &sig, 1);
if (ret <= 0)
FD_CLR(s, &readfrom);
@@ -603,20 +528,17 @@ fail:
FD_CLR(pv[0], &readfrom);
} else {
#ifdef CRYPT
-#ifdef KERBEROS
if (doencrypt)
(void)
des_enc_write(s, buf, cc,
schedule, &kdata->session);
else
#endif
-#endif
(void)
write(s, buf, cc);
}
}
#ifdef CRYPT
-#ifdef KERBEROS
if (doencrypt && FD_ISSET(pv1[0], &ready)) {
errno = 0;
cc = read(pv1[0], buf, sizeof(buf));
@@ -641,14 +563,11 @@ fail:
(void) write(pv2[0], buf, cc);
}
#endif
-#endif
} while (FD_ISSET(s, &readfrom) ||
#ifdef CRYPT
-#ifdef KERBEROS
(doencrypt && FD_ISSET(pv1[0], &readfrom)) ||
#endif
-#endif
FD_ISSET(pv[0], &readfrom));
exit(0);
}
@@ -656,7 +575,6 @@ fail:
(void) close(s);
(void) close(pv[0]);
#ifdef CRYPT
-#ifdef KERBEROS
if (doencrypt) {
close(pv1[0]); close(pv2[0]);
dup2(pv1[1], 1);
@@ -665,7 +583,6 @@ fail:
close(pv2[1]);
}
#endif
-#endif
dup2(pv[1], 2);
close(pv[1]);
}
@@ -694,14 +611,6 @@ fail:
#endif
endpwent();
if (log_success || pwd->pw_uid == 0) {
-#ifdef KERBEROS
- if (use_kerberos)
- syslog(LOG_INFO|LOG_AUTH,
- "Kerberos shell from %s.%s@%s on %s as %s, cmd='%.80s'",
- kdata->pname, kdata->pinst, kdata->prealm,
- fromhost, locuser, cmdbuf);
- else
-#endif
syslog(LOG_INFO|LOG_AUTH, "%s@%s as %s: cmd='%.80s'",
remuser, fromhost, locuser, cmdbuf);
}
OpenPOWER on IntegriCloud