summaryrefslogtreecommitdiffstats
path: root/lib/libpam
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2002-04-15 02:34:43 +0000
committerdes <des@FreeBSD.org>2002-04-15 02:34:43 +0000
commitee50be8376898250d5bf96e16315915377098c69 (patch)
tree8fdad9c4a51508750170d2067e3134dff672234d /lib/libpam
parent812186605687a58b20d2b464b1a528455d4bade0 (diff)
downloadFreeBSD-src-ee50be8376898250d5bf96e16315915377098c69.zip
FreeBSD-src-ee50be8376898250d5bf96e16315915377098c69.tar.gz
Dike out most of the NIS code and replace it with calls to libypclnt.
Rework pam_sm_chauthtok() so it (mostly?) works. The standard pw stuff still needs to move into a library somewhere. Sponsored by: DARPA, NAI Labs
Diffstat (limited to 'lib/libpam')
-rw-r--r--lib/libpam/modules/pam_unix/Makefile45
-rw-r--r--lib/libpam/modules/pam_unix/pam_unix.c319
2 files changed, 79 insertions, 285 deletions
diff --git a/lib/libpam/modules/pam_unix/Makefile b/lib/libpam/modules/pam_unix/Makefile
index 883d16c..3c23f90 100644
--- a/lib/libpam/modules/pam_unix/Makefile
+++ b/lib/libpam/modules/pam_unix/Makefile
@@ -25,54 +25,17 @@
# $FreeBSD$
LIB= pam_unix
-SRCS= pam_unix.c pw_copy.c pw_yp.c pw_util.c ypxfr_misc.c ${GENSRCS}
-CFLAGS+= -DYP -Dyp_error=warnx \
+SRCS= pam_unix.c pw_copy.c pw_util.c
+CFLAGS+= -DYP \
-I. \
- -I${.CURDIR}/../../../../libexec/ypxfr \
-I${.CURDIR}/../../../../usr.sbin/vipw \
-I${.CURDIR}/../../../../usr.bin/chpass \
-I${.CURDIR}/../../../../lib/libc/gen
-DPADD= ${LIBUTIL} ${LIBCRYPT} ${LIBRPCSVC}
-LDADD= -lutil -lcrypt -lrpcsvc
+DPADD= ${LIBUTIL} ${LIBCRYPT} ${LIBYPCLNT}
+LDADD= -lutil -lcrypt -lypclnt
MAN= pam_unix.8
-GENSRCS=yp.h yp_clnt.c yppasswd.h yppasswd_clnt.c \
- yppasswd_private.h yppasswd_private_clnt.c yppasswd_private_xdr.c
-
-RPCGEN= rpcgen -C
-RPCSRC= ${DESTDIR}/usr/include/rpcsvc/yp.x
-RPCSRC_PW= ${DESTDIR}/usr/include/rpcsvc/yppasswd.x
-RPCSRC_PRIV= ${.CURDIR}/../../../../usr.sbin/rpc.yppasswdd/yppasswd_private.x
-
-yp.h: ${RPCSRC}
- ${RPCGEN} -h -o ${.TARGET} ${RPCSRC}
-
-yp_clnt.c: ${RPCSRC} yp.h
- ${RPCGEN} -l -o ${.TARGET} ${RPCSRC}
-
-yppasswd.h: ${RPCSRC_PW}
- ${RPCGEN} -h -o ${.TARGET} ${RPCSRC_PW}
-
-yppasswd_clnt.c: ${RPCSRC_PW}
- ${RPCGEN} -l -o ${.TARGET} ${RPCSRC_PW}
-
-yppasswd_private.h: ${RPCSRC_PRIV}
- ${RPCGEN} -h -o ${.TARGET} ${RPCSRC_PRIV}
-
-yppasswd_private_xdr.c: ${RPCSRC_PRIV}
- ${RPCGEN} -c -o ${.TARGET} ${RPCSRC_PRIV}
-
-yppasswd_private_clnt.c: ${RPCSRC_PRIV}
- ${RPCGEN} -l -o ${.TARGET} ${RPCSRC_PRIV}
-
-
-yppasswd_private.h: ${RPCSRC_PRIV}
- ${RPCGEN} -h -o ${.TARGET} ${RPCSRC_PRIV}
-
-CLEANFILES= ${GENSRCS}
-
.include <bsd.lib.mk>
.PATH: ${.CURDIR}/../../../../usr.bin/chpass
.PATH: ${.CURDIR}/../../../../usr.sbin/vipw
-.PATH: ${.CURDIR}/../../../../libexec/ypxfr
diff --git a/lib/libpam/modules/pam_unix/pam_unix.c b/lib/libpam/modules/pam_unix/pam_unix.c
index 29f22d9..5c1125c 100644
--- a/lib/libpam/modules/pam_unix/pam_unix.c
+++ b/lib/libpam/modules/pam_unix/pam_unix.c
@@ -43,13 +43,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/in.h>
#include <arpa/inet.h>
-#ifdef YP
-#include <rpc/rpc.h>
-#include <rpcsvc/yp_prot.h>
-#include <rpcsvc/ypclnt.h>
-#include <rpcsvc/yppasswd.h>
-#endif
-
#include <login_cap.h>
#include <netdb.h>
#include <pwd.h>
@@ -63,8 +56,7 @@ __FBSDID("$FreeBSD$");
#include <pw_util.h>
#ifdef YP
-#include <pw_yp.h>
-#include "yppasswd_private.h"
+#include <ypclnt.h>
#endif
#define PAM_SM_AUTH
@@ -82,7 +74,6 @@ __FBSDID("$FreeBSD$");
static void makesalt(char []);
static char password_hash[] = PASSWORD_HASH;
-static char colon[] = ":";
enum {
PAM_OPT_AUTH_AS_SELF = PAM_OPT_STD_MAX,
@@ -99,16 +90,7 @@ static struct opttab other_options[] = {
{ NULL, 0 }
};
-#ifdef YP
-int pam_use_yp = 0;
-int yp_errno = YP_TRUE;
-#endif
-
char *tempname = NULL;
-static int local_passwd(const char *user, const char *pass);
-#ifdef YP
-static int yp_passwd(const char *user, const char *pass);
-#endif
/*
* authentication management
@@ -300,11 +282,17 @@ PAM_EXTERN int
pam_sm_chauthtok(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
+#ifdef YP
+ struct ypclnt *ypclnt;
+ const char *yp_domain, *yp_server;
+#endif
struct options options;
+ char salt[SALTSIZE + 1];
+ login_cap_t * lc;
struct passwd *pwd;
- const char *user, *pass, *new_pass;
- char *encrypted, *usrdup;
- int retval, res;
+ const char *user, *old_pass, *new_pass;
+ char *encrypted;
+ int pfd, tfd, retval;
pam_std_option(&options, other_options, argc, argv);
@@ -332,36 +320,21 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags,
* by not prompting for a password?
* XXX check PAM_DISALLOW_NULL_AUTHTOK
*/
- PAM_LOG("Got password");
- return (PAM_SUCCESS);
- }
- else {
+ old_pass = "";
+ } else {
retval = pam_get_authtok(pamh,
- PAM_OLDAUTHTOK, &pass, NULL);
+ PAM_OLDAUTHTOK, &old_pass, NULL);
if (retval != PAM_SUCCESS)
return (retval);
- PAM_LOG("Got password");
- }
- encrypted = crypt(pass, pwd->pw_passwd);
- if (pass[0] == '\0' && pwd->pw_passwd[0] != '\0')
- encrypted = colon;
-
- if (strcmp(encrypted, pwd->pw_passwd) != 0) {
- pam_set_item(pamh, PAM_OLDAUTHTOK, NULL);
- return (PAM_AUTH_ERR);
}
-
- return (PAM_SUCCESS);
- }
- else if (flags & PAM_UPDATE_AUTHTOK) {
- PAM_LOG("UPDATE round; checking user password");
-
- retval = pam_get_authtok(pamh, PAM_OLDAUTHTOK, &pass, NULL);
- if (retval != PAM_SUCCESS)
- return (retval);
-
PAM_LOG("Got old password");
+ /* always encrypt first */
+ encrypted = crypt(old_pass, pwd->pw_passwd);
+ if ((old_pass[0] == '\0' && pwd->pw_passwd[0] != '\0') ||
+ strcmp(encrypted, pwd->pw_passwd) != 0)
+ return (PAM_PERM_DENIED);
+ /* get new password */
for (;;) {
retval = pam_get_authtok(pamh,
PAM_AUTHTOK, &new_pass, NULL);
@@ -369,51 +342,68 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags,
break;
pam_error(pamh, "Mismatch; try again, EOF to quit.");
}
-
- if (retval != PAM_SUCCESS) {
+ PAM_LOG("Got new password");
+ if (retval != PAM_SUCCESS)
PAM_VERBOSE_ERROR("Unable to get new password");
- return (PAM_PERM_DENIED);
- }
+ return (retval);
+ }
+ else if (flags & PAM_UPDATE_AUTHTOK) {
+ PAM_LOG("UPDATE round");
- PAM_LOG("Got new password: %s", new_pass);
+ retval = pam_get_item(pamh,
+ PAM_OLDAUTHTOK, (const void **)&old_pass);
+ if (retval != PAM_SUCCESS)
+ return (retval);
+ PAM_LOG("Got old password");
+ retval = pam_get_item(pamh,
+ PAM_AUTHTOK, (const void **)&new_pass);
+ if (retval != PAM_SUCCESS)
+ return (retval);
+ PAM_LOG("Got new password");
+
+ pwd->pw_change = 0;
+ lc = login_getclass(NULL);
+ if (login_setcryptfmt(lc, password_hash, NULL) == NULL)
+ openpam_log(PAM_LOG_ERROR,
+ "can't set password cipher, relying on default");
+ login_close(lc);
+ makesalt(salt);
+ pwd->pw_passwd = crypt(new_pass, salt);
+ retval = PAM_SUCCESS;
#ifdef YP
- /* If NIS is set in the passwd database, use it */
- if ((usrdup = strdup(user)) == NULL)
- return (PAM_BUF_ERR);
- res = use_yp(usrdup, 0, 0);
- free(usrdup);
- if (res == USER_YP_ONLY) {
- if (!pam_test_option(&options, PAM_OPT_LOCAL_PASS,
- NULL))
- retval = yp_passwd(user, new_pass);
- else {
- /* Reject 'local' flag if NIS is on and the user
- * is not local
- */
- retval = PAM_PERM_DENIED;
- PAM_LOG("Unknown local user: %s", user);
- }
- }
- else if (res == USER_LOCAL_ONLY) {
- if (!pam_test_option(&options, PAM_OPT_NIS_PASS, NULL))
- retval = local_passwd(user, new_pass);
- else {
- /* Reject 'nis' flag if user is only local */
- retval = PAM_PERM_DENIED;
- PAM_LOG("Unknown NIS user: %s", user);
+ switch (pwd->pw_fields & _PWF_SOURCE) {
+ case _PWF_FILES:
+#endif
+ pfd = pw_lock();
+ tfd = pw_tmp();
+ pw_copy(pfd, tfd, pwd, NULL);
+ if (!pw_mkdb(user))
+ retval = PAM_SERVICE_ERR;
+#ifdef YP
+ break;
+ case _PWF_NIS:
+ yp_domain = yp_server = NULL;
+ (void)pam_get_data(pamh,
+ "yp_domain", (const void **)&yp_domain);
+ (void)pam_get_data(pamh,
+ "yp_server", (const void **)&yp_server);
+ ypclnt = ypclnt_new(yp_domain,
+ "passwd.byname", yp_server);
+ if (ypclnt == NULL)
+ return (PAM_BUF_ERR);
+ if (ypclnt_connect(ypclnt) == -1 ||
+ ypclnt_passwd(ypclnt, pwd, old_pass) == -1) {
+ openpam_log(PAM_LOG_ERROR, "%s", ypclnt->error);
+ retval = PAM_SERVICE_ERR;
}
+ ypclnt_free(ypclnt);
+ break;
+ default:
+ openpam_log(PAM_LOG_ERROR, "unsupported source 0x%x",
+ pwd->pw_fields & _PWF_SOURCE);
+ retval = PAM_SERVICE_ERR;
}
- else if (res == USER_YP_AND_LOCAL) {
- if (pam_test_option(&options, PAM_OPT_NIS_PASS, NULL))
- retval = yp_passwd(user, new_pass);
- else
- retval = local_passwd(user, new_pass);
- }
- else
- retval = PAM_SERVICE_ERR; /* Bad juju */
-#else
- retval = local_passwd(user, new_pass);
#endif
}
else {
@@ -439,165 +429,6 @@ to64(char *s, long v, int n)
}
}
-static int
-local_passwd(const char *user, const char *pass)
-{
- login_cap_t * lc;
- struct passwd *pwd;
- int pfd, tfd;
- const char *crypt_type;
- char salt[SALTSIZE + 1];
-
- pwd = getpwnam(user);
- if (pwd == NULL)
- return(PAM_SERVICE_ERR); /* Really bad things */
-
-#ifdef YP
- pwd = (struct passwd *)&local_password;
-#endif
- pw_init();
-
- pwd->pw_change = 0;
- lc = login_getclass(NULL);
- crypt_type = login_getcapstr(lc, "passwd_format",
- password_hash, password_hash);
- if (login_setcryptfmt(lc, crypt_type, NULL) == NULL)
- syslog(LOG_ERR, "cannot set password cipher");
- login_close(lc);
- makesalt(salt);
- pwd->pw_passwd = crypt(pass, salt);
-
- pfd = pw_lock();
- tfd = pw_tmp();
- pw_copy(pfd, tfd, pwd, NULL);
-
- if (!pw_mkdb(user))
- pw_error((char *)NULL, 0, 1);
-
- return (PAM_SUCCESS);
-}
-
-#ifdef YP
-/* Stolen from src/usr.bin/passwd/yp_passwd.c, carrying copyrights of:
- * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca>
- * Copyright (c) 1994 Olaf Kirch <okir@monad.swb.de>
- * Copyright (c) 1995 Bill Paul <wpaul@ctr.columbia.edu>
- */
-int
-yp_passwd(const char *user __unused, const char *pass)
-{
- struct yppasswd yppwd;
- struct master_yppasswd master_yppwd;
- struct passwd *pwd;
- struct rpc_err err;
- CLIENT *clnt;
- login_cap_t *lc;
- int *status;
- uid_t uid;
- char *master, sockname[] = YP_SOCKNAME, salt[SALTSIZE + 1];
-
- _use_yp = 1;
-
- uid = getuid();
-
- master = get_yp_master(1);
- if (master == NULL)
- return (PAM_SERVICE_ERR); /* Major disaster */
-
- /*
- * It is presumed that by the time we get here, use_yp()
- * has been called and that we have verified that the user
- * actually exists. This being the case, the yp_password
- * stucture has already been filled in for us.
- */
-
- /* Use the correct password */
- pwd = (struct passwd *)&yp_password;
-
- pwd->pw_change = 0;
-
- /* Initialize password information */
- if (suser_override) {
- master_yppwd.newpw.pw_passwd = strdup(pwd->pw_passwd);
- master_yppwd.newpw.pw_name = strdup(pwd->pw_name);
- master_yppwd.newpw.pw_uid = pwd->pw_uid;
- master_yppwd.newpw.pw_gid = pwd->pw_gid;
- master_yppwd.newpw.pw_expire = pwd->pw_expire;
- master_yppwd.newpw.pw_change = pwd->pw_change;
- master_yppwd.newpw.pw_fields = pwd->pw_fields;
- master_yppwd.newpw.pw_gecos = strdup(pwd->pw_gecos);
- master_yppwd.newpw.pw_dir = strdup(pwd->pw_dir);
- master_yppwd.newpw.pw_shell = strdup(pwd->pw_shell);
- master_yppwd.newpw.pw_class = pwd->pw_class != NULL ?
- strdup(pwd->pw_class) : strdup("");
- master_yppwd.oldpass = strdup("");
- master_yppwd.domain = yp_domain;
- } else {
- yppwd.newpw.pw_passwd = strdup(pwd->pw_passwd);
- yppwd.newpw.pw_name = strdup(pwd->pw_name);
- yppwd.newpw.pw_uid = pwd->pw_uid;
- yppwd.newpw.pw_gid = pwd->pw_gid;
- yppwd.newpw.pw_gecos = strdup(pwd->pw_gecos);
- yppwd.newpw.pw_dir = strdup(pwd->pw_dir);
- yppwd.newpw.pw_shell = strdup(pwd->pw_shell);
- yppwd.oldpass = strdup("");
- }
-
- if (login_setcryptfmt(lc, "md5", NULL) == NULL)
- syslog(LOG_ERR, "cannot set password cipher");
- login_close(lc);
-
- makesalt(salt);
- if (suser_override)
- master_yppwd.newpw.pw_passwd = crypt(pass, salt);
- else
- yppwd.newpw.pw_passwd = crypt(pass, salt);
-
- if (suser_override) {
- if ((clnt = clnt_create(sockname, MASTER_YPPASSWDPROG,
- MASTER_YPPASSWDVERS, "unix")) == NULL) {
- syslog(LOG_ERR,
- "Cannot contact rpc.yppasswdd on host %s: %s",
- master, clnt_spcreateerror(""));
- return (PAM_SERVICE_ERR);
- }
- }
- else {
- if ((clnt = clnt_create(master, YPPASSWDPROG,
- YPPASSWDVERS, "udp")) == NULL) {
- syslog(LOG_ERR,
- "Cannot contact rpc.yppasswdd on host %s: %s",
- master, clnt_spcreateerror(""));
- return (PAM_SERVICE_ERR);
- }
- }
- /*
- * The yppasswd.x file said `unix authentication required',
- * so I added it. This is the only reason it is in here.
- * My yppasswdd doesn't use it, but maybe some others out there
- * do. --okir
- */
- clnt->cl_auth = authunix_create_default();
-
- if (suser_override)
- status = yppasswdproc_update_master_1(&master_yppwd, clnt);
- else
- status = yppasswdproc_update_1(&yppwd, clnt);
-
- clnt_geterr(clnt, &err);
-
- auth_destroy(clnt->cl_auth);
- clnt_destroy(clnt);
-
- if (err.re_status != RPC_SUCCESS || status == NULL || *status)
- return (PAM_SERVICE_ERR);
-
- if (err.re_status || status == NULL || *status)
- return (PAM_SERVICE_ERR);
- return (PAM_SUCCESS);
-}
-#endif /* YP */
-
/* Salt suitable for traditional DES and MD5 */
void
makesalt(char salt[SALTSIZE])
OpenPOWER on IntegriCloud