diff options
author | markm <markm@FreeBSD.org> | 1999-09-19 22:05:32 +0000 |
---|---|---|
committer | markm <markm@FreeBSD.org> | 1999-09-19 22:05:32 +0000 |
commit | 0b2fe68756570c146bda89ff69a3d209aac9f8be (patch) | |
tree | 8d4295813f9b149f83950d8b50c74d07c35aa987 /libexec | |
parent | fc84b1a733b5c4774a2dcd8035e4f71948716a55 (diff) | |
download | FreeBSD-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/Makefile | 12 | ||||
-rw-r--r-- | libexec/ftpd/ftpd.c | 160 | ||||
-rw-r--r-- | libexec/rlogind/Makefile | 17 | ||||
-rw-r--r-- | libexec/rlogind/auth_pam.c | 142 | ||||
-rw-r--r-- | libexec/rlogind/pathnames.h | 2 | ||||
-rw-r--r-- | libexec/rlogind/rlogind.c | 162 | ||||
-rw-r--r-- | libexec/rshd/Makefile | 14 | ||||
-rw-r--r-- | libexec/rshd/rshd.c | 205 |
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); } |