diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2015-11-26 19:01:48 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2015-11-26 19:01:48 +0000 |
commit | fd42d389364f410db18dfe948d807b16249c13e7 (patch) | |
tree | 827a62fc25b288c40680691c2901c3e5f7a09134 | |
parent | d80e3ad219a437ddb3ae12eae6ac4a8d13ca1dd9 (diff) |
Delete YP password related code. As a result, these can also be
pledged. Keep an eye out for regressions, because they could be
uncomfortable.
ok beck semarie
-rw-r--r-- | libexec/login_chpass/Makefile | 15 | ||||
-rw-r--r-- | libexec/login_chpass/login_chpass.c | 158 | ||||
-rw-r--r-- | usr.bin/chpass/Makefile | 11 | ||||
-rw-r--r-- | usr.bin/chpass/chpass.1 | 19 | ||||
-rw-r--r-- | usr.bin/chpass/chpass.c | 86 | ||||
-rw-r--r-- | usr.bin/chpass/chpass.h | 8 | ||||
-rw-r--r-- | usr.bin/chpass/pw_yp.c | 290 | ||||
-rw-r--r-- | usr.bin/passwd/Makefile | 7 | ||||
-rw-r--r-- | usr.bin/passwd/local_passwd.c | 18 | ||||
-rw-r--r-- | usr.bin/passwd/passwd.1 | 25 | ||||
-rw-r--r-- | usr.bin/passwd/passwd.c | 60 | ||||
-rw-r--r-- | usr.bin/passwd/pwd_check.c | 8 | ||||
-rw-r--r-- | usr.bin/passwd/yp_passwd.c | 341 |
13 files changed, 61 insertions, 985 deletions
diff --git a/libexec/login_chpass/Makefile b/libexec/login_chpass/Makefile index c4dfdfa11a3..703f5a4f413 100644 --- a/libexec/login_chpass/Makefile +++ b/libexec/login_chpass/Makefile @@ -1,23 +1,12 @@ -# $OpenBSD: Makefile,v 1.8 2015/10/22 12:32:33 tedu Exp $ +# $OpenBSD: Makefile,v 1.9 2015/11/26 19:01:47 deraadt Exp $ +.PATH: ${.CURDIR}/../../usr.bin/passwd PROG= login_chpass SRCS= login_chpass.c MAN= login_chpass.8 - -.PATH: ${.CURDIR}/../../usr.bin/passwd - -.include <bsd.own.mk> # For YP - CFLAGS+=-Wall -.if (${YP:L} == "yes") -CFLAGS+=-DYP -SRCS+= yp_passwd.c pwd_check.c -DPADD+= ${LIBRPCSVC} ${LIBUTIL} -LDADD+= -lrpcsvc -lutil -.endif - BINOWN= root BINGRP= auth BINMODE=4555 diff --git a/libexec/login_chpass/login_chpass.c b/libexec/login_chpass/login_chpass.c index 4da3e8b928e..4afe266d6f7 100644 --- a/libexec/login_chpass/login_chpass.c +++ b/libexec/login_chpass/login_chpass.c @@ -1,4 +1,4 @@ -/* $OpenBSD: login_chpass.c,v 1.19 2015/10/25 08:39:26 ajacoutot Exp $ */ +/* $OpenBSD: login_chpass.c,v 1.20 2015/11/26 19:01:47 deraadt Exp $ */ /*- * Copyright (c) 1995,1996 Berkeley Software Design, Inc. All rights reserved. @@ -51,38 +51,15 @@ #include <unistd.h> #include <login_cap.h> -#ifdef YP -# include <netdb.h> -# include <rpc/rpc.h> -# include <rpcsvc/yp_prot.h> -# include <rpcsvc/ypclnt.h> -# define passwd yp_passwd_rec -# include <rpcsvc/yppasswd.h> -# undef passwd -#endif - #define _PATH_LOGIN_LCHPASS "/usr/libexec/auth/login_lchpass" #define BACK_CHANNEL 3 -#ifdef YP -struct iovec iov[2] = { { BI_SILENT, sizeof(BI_SILENT) - 1 }, { "\n", 1 } }; - -int _yp_check(char **); -char *ypgetnewpasswd(struct passwd *, char **); -struct passwd *ypgetpwnam(char *); -void kbintr(int); -#endif - void local_chpass(char **); -void yp_chpass(char *); int main(int argc, char *argv[]) { -#ifdef YP - char *username; -#endif struct rlimit rl; int c; @@ -92,6 +69,9 @@ main(int argc, char *argv[]) (void)setpriority(PRIO_PROCESS, 0, 0); + if (pledge("stdio exec", NULL) == -1) + err(1, "pledge"); + openlog("login", LOG_ODELAY, LOG_AUTH); while ((c = getopt(argc, argv, "s:v:")) != -1) @@ -113,19 +93,12 @@ main(int argc, char *argv[]) case 2: /* class is not used */ case 1: -#ifdef YP - username = argv[optind]; -#endif break; default: syslog(LOG_ERR, "usage error"); exit(1); } -#ifdef YP - if (_yp_check(NULL)) - yp_chpass(username); -#endif local_chpass(argv); /* NOTREACHED */ exit(0); @@ -141,126 +114,3 @@ local_chpass(char *argv[]) syslog(LOG_ERR, "%s: %m", _PATH_LOGIN_LCHPASS); exit(1); } - -#ifdef YP -void -yp_chpass(char *username) -{ - char *master; - int r, rpcport, status; - struct yppasswd yppasswd; - struct passwd *pw; - struct timeval tv; - CLIENT *client; - extern char *domain; - - (void)signal(SIGINT, kbintr); - (void)signal(SIGQUIT, kbintr); - - if ((r = yp_get_default_domain(&domain)) != 0) { - warnx("can't get local YP domain. Reason: %s", yperr_string(r)); - exit(1); - } - - /* - * Find the host for the passwd map; it should be running - * the daemon. - */ - if ((r = yp_master(domain, "passwd.byname", &master)) != 0) { - warnx("can't find the master YP server. Reason: %s", - yperr_string(r)); - exit(1); - } - - /* Ask the portmapper for the port of the daemon. */ - if ((rpcport = getrpcport(master, YPPASSWDPROG, - YPPASSWDPROC_UPDATE, IPPROTO_UDP)) == 0) { - warnx("master YP server not running yppasswd daemon."); - warnx("Can't change password."); - exit(1); - } - - if (rpcport >= IPPORT_RESERVED) { - warnx("yppasswd daemon is on an invalid port."); - exit(1); - } - - /* If user doesn't exist, just prompt for old password and exit. */ - pw = ypgetpwnam(username); - if (pw) { - if (pw->pw_uid == 0) { - syslog(LOG_ERR, "attempted root password change"); - pw = NULL; - } else if (*pw->pw_passwd == '\0') { - syslog(LOG_ERR, "%s attempting to add password", - username); - pw = NULL; - } - } - if (pw == NULL) { - char *p; - /* no such user, but fake to thwart timing attack */ - if ((p = getpass("Old password:")) != NULL) { - crypt_checkpass(p, NULL); - explicit_bzero(p, strlen(p)); - } - warnx("YP passwd database unchanged."); - exit(1); - } - - /* prompt for new password */ - yppasswd.newpw.pw_passwd = ypgetnewpasswd(pw, &yppasswd.oldpass); - - /* tell rpc.yppasswdd */ - yppasswd.newpw.pw_name = pw->pw_name; - yppasswd.newpw.pw_uid = pw->pw_uid; - yppasswd.newpw.pw_gid = pw->pw_gid; - yppasswd.newpw.pw_gecos = pw->pw_gecos; - yppasswd.newpw.pw_dir = pw->pw_dir; - yppasswd.newpw.pw_shell = pw->pw_shell; - - client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp"); - if (client == NULL) { - warnx("cannot contact yppasswdd on %s: Reason: %s", - master, yperr_string(YPERR_YPBIND)); - free(yppasswd.newpw.pw_passwd); - exit(1); - } - client->cl_auth = authunix_create_default(); - tv.tv_sec = 2; - tv.tv_usec = 0; - r = clnt_call(client, YPPASSWDPROC_UPDATE, - xdr_yppasswd, &yppasswd, xdr_int, &status, tv); - if (r) - warnx("rpc to yppasswdd failed."); - else if (status) { - printf("Couldn't change YP password.\n"); - free(yppasswd.newpw.pw_passwd); - exit(1); - } - printf("The YP password has been changed on %s, the master YP passwd server.\n", - master); - free(yppasswd.newpw.pw_passwd); - (void)writev(BACK_CHANNEL, iov, 2); - exit(0); -} - -/* ARGSUSED */ -void -kbintr(int signo) -{ - char msg[] = "YP passwd database unchanged.\n"; - struct iovec iv[3]; - extern char *__progname; - - iv[0].iov_base = __progname; - iv[0].iov_len = strlen(__progname); - iv[1].iov_base = ": "; - iv[1].iov_len = 2; - iv[2].iov_base = msg; - iv[2].iov_len = sizeof(msg) - 1; - writev(STDERR_FILENO, iv, 3); - - _exit(1); -} -#endif diff --git a/usr.bin/chpass/Makefile b/usr.bin/chpass/Makefile index 59ed17061f8..5c8530047c3 100644 --- a/usr.bin/chpass/Makefile +++ b/usr.bin/chpass/Makefile @@ -1,20 +1,17 @@ -# $OpenBSD: Makefile,v 1.13 2015/09/14 07:19:41 guenther Exp $ +# $OpenBSD: Makefile,v 1.14 2015/11/26 19:01:47 deraadt Exp $ .include <bsd.own.mk> PROG= chpass -SRCS= chpass.c edit.c field.c pw_yp.c table.c util.c getpwent.c +SRCS= chpass.c edit.c field.c table.c util.c getpwent.c BINOWN= root BINMODE=4555 .PATH: ${.CURDIR}/../../lib/libc/gen LINKS= ${BINDIR}/chpass ${BINDIR}/chfn ${BINDIR}/chpass ${BINDIR}/chsh MLINKS= chpass.1 chfn.1 chpass.1 chsh.1 CFLAGS+=-I${.CURDIR}/../../lib/libc/include -.if (${YP:L} == "yes") -CFLAGS+=-DYP -I${.CURDIR}/../../lib/libc/yp -.endif -DPADD+= ${LIBRPCSVC} ${LIBUTIL} -LDADD+= -lrpcsvc -lutil +DPADD+= ${LIBUTIL} +LDADD+= -lutil .include <bsd.prog.mk> diff --git a/usr.bin/chpass/chpass.1 b/usr.bin/chpass/chpass.1 index 56b204fbf41..a46737380c4 100644 --- a/usr.bin/chpass/chpass.1 +++ b/usr.bin/chpass/chpass.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: chpass.1,v 1.40 2014/11/15 14:41:01 bentley Exp $ +.\" $OpenBSD: chpass.1,v 1.41 2015/11/26 19:01:47 deraadt Exp $ .\" $NetBSD: chpass.1,v 1.7 1996/05/15 21:50:40 jtc Exp $ .\" .\" Copyright (c) 1988, 1990, 1993 @@ -30,7 +30,7 @@ .\" .\" @(#)chpass.1 8.2 (Berkeley) 12/30/93 .\" -.Dd $Mdocdate: November 15 2014 $ +.Dd $Mdocdate: November 26 2015 $ .Dt CHPASS 1 .Os .Sh NAME @@ -40,11 +40,9 @@ .Nd add or change user database information .Sh SYNOPSIS .Nm chpass -.Op Fl ly .Op Fl s Ar newshell .Op Ar user .Nm chpass -.Op Fl l .Fl a Ar list .Sh DESCRIPTION .Nm chpass @@ -56,9 +54,6 @@ The information is formatted and supplied to an editor for changes. .Pp Only the information that the user is allowed to change is displayed. .Pp -If YP is enabled change requests are first tried in the local database, -and then in the YP database, if there was no entry to change locally. -.Pp .Nm chfn and .Nm chsh @@ -76,19 +71,9 @@ This argument must be a colon .Pq Sq \&: separated list of all the user database fields, although they may be empty. -This operation is not supported in YP environments; only local additions -can be performed which requires the -.Fl l -flag to be specified. -.It Fl l -In environments where YP is enabled, always alter local information as -opposed to information in YP. .It Fl s Ar newshell Attempts to change the user's shell to .Ar newshell . -.It Fl y -In environments where YP is enabled, always change the YP entry, even if this -is a modification request and there is a local entry for the specified user. .El .Pp Possible display items are as follows: diff --git a/usr.bin/chpass/chpass.c b/usr.bin/chpass/chpass.c index 9914bd095d9..4e47a82b441 100644 --- a/usr.bin/chpass/chpass.c +++ b/usr.bin/chpass/chpass.c @@ -1,4 +1,4 @@ -/* $OpenBSD: chpass.c,v 1.42 2015/11/18 19:26:45 tedu Exp $ */ +/* $OpenBSD: chpass.c,v 1.43 2015/11/26 19:01:47 deraadt Exp $ */ /* $NetBSD: chpass.c,v 1.8 1996/05/15 21:50:43 jtc Exp $ */ /*- @@ -53,10 +53,6 @@ extern char *__progname; enum { NEWSH, LOADENTRY, EDITENTRY } op; uid_t uid; -#ifdef YP -int use_yp; -int force_yp = 0; -#endif void baduser(void); void kbintr(int); @@ -70,9 +66,6 @@ main(int argc, char *argv[]) char *tz, *arg = NULL; sigset_t fullset; -#ifdef YP - use_yp = _yp_check(NULL); -#endif /* We need to use the system timezone for date conversions. */ if ((tz = getenv("TZ")) != NULL) { unsetenv("TZ"); @@ -81,7 +74,7 @@ main(int argc, char *argv[]) } op = EDITENTRY; - while ((ch = getopt(argc, argv, "a:s:ly")) != -1) + while ((ch = getopt(argc, argv, "a:s:")) != -1) switch(ch) { case 'a': op = LOADENTRY; @@ -91,18 +84,6 @@ main(int argc, char *argv[]) op = NEWSH; arg = optarg; break; -#ifdef YP - case 'l': - use_yp = 0; - break; - case 'y': - if (!use_yp) { - warnx("YP not in use."); - usage(); - } - force_yp = 1; - break; -#endif case '?': default: usage(); @@ -110,33 +91,17 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; -#ifdef YP - if (op == LOADENTRY && use_yp) - errx(1, "cannot load using YP, use -l to load local."); -#endif uid = getuid(); if (op == EDITENTRY || op == NEWSH) switch(argc) { case 0: pw = getpwuid_shadow(uid); -#ifdef YP - if (pw && !force_yp) - use_yp = 0; - else if (use_yp) - pw = ypgetpwuid(uid); -#endif /* YP */ if (!pw) errx(1, "unknown user: uid %u", uid); break; case 1: pw = getpwnam_shadow(*argv); -#ifdef YP - if (pw && !force_yp) - use_yp = 0; - else if (use_yp) - pw = ypgetpwnam(*argv); -#endif /* YP */ if (!pw) errx(1, "unknown user: %s", *argv); if (uid && uid != pw->pw_uid) @@ -170,6 +135,11 @@ main(int argc, char *argv[]) if (dfd == -1) pw_error(tempname, 1, 1); display(tempname, dfd, pw); + + if (pledge("stdio rpath wpath cpath id proc exec", + NULL) == -1) + err(1, "pledge"); + edit_status = edit(tempname, pw); close(dfd); unlink(tempname); @@ -188,6 +158,10 @@ main(int argc, char *argv[]) } if (op == NEWSH) { + if (pledge("stdio rpath wpath cpath id proc exec", + NULL) == -1) + err(1, "pledge"); + /* protect p_shell -- it thinks NULL is /bin/sh */ if (!arg[0]) usage(); @@ -201,6 +175,9 @@ main(int argc, char *argv[]) sigdelset(&fullset, SIGINT); sigprocmask(SIG_BLOCK, &fullset, NULL); + if (pledge("stdio rpath wpath cpath proc exec", NULL) == -1) + err(1, "pledge"); + /* Get the passwd lock file and open the passwd file for reading. */ pw_init(); for (i = 1; (tfd = pw_lock(0)) == -1; i++) { @@ -219,28 +196,15 @@ main(int argc, char *argv[]) if (pfd == -1) pw_error(_PATH_MASTERPASSWD, 1, 1); -#ifdef YP - if (use_yp) { - if (pw_yp(pw, uid)) - pw_error(NULL, 0, 1); - else { - pw_abort(); - exit(0); - } - } else -#endif /* YP */ - { - /* Copy the passwd file to the lock file, updating pw. */ - pw_copy(pfd, tfd, pw, opw); - - /* If username changed we need to rebuild the entire db. */ - arg = !strcmp(opw->pw_name, pw->pw_name) ? pw->pw_name : NULL; + /* Copy the passwd file to the lock file, updating pw. */ + pw_copy(pfd, tfd, pw, opw); - /* Now finish the passwd file update. */ - if (pw_mkdb(arg, 0) == -1) - pw_error(NULL, 0, 1); - } + /* If username changed we need to rebuild the entire db. */ + arg = !strcmp(opw->pw_name, pw->pw_name) ? pw->pw_name : NULL; + /* Now finish the passwd file update. */ + if (pw_mkdb(arg, 0) == -1) + pw_error(NULL, 0, 1); exit(0); } @@ -276,15 +240,7 @@ void usage(void) { -#ifdef YP - (void)fprintf(stderr, - "usage: %s [-l%s] [-s newshell] [user]\n", - __progname, use_yp ? "y" : ""); - (void)fprintf(stderr, - " %s [-l] -a list\n", __progname); -#else (void)fprintf(stderr, "usage: %s [-s newshell] [user]\n", __progname); (void)fprintf(stderr, " %s -a list\n", __progname); -#endif exit(1); } diff --git a/usr.bin/chpass/chpass.h b/usr.bin/chpass/chpass.h index 833f73552f8..0d7d3ccc687 100644 --- a/usr.bin/chpass/chpass.h +++ b/usr.bin/chpass/chpass.h @@ -1,4 +1,4 @@ -/* $OpenBSD: chpass.h,v 1.10 2009/03/05 20:53:13 millert Exp $ */ +/* $OpenBSD: chpass.h,v 1.11 2015/11/26 19:01:47 deraadt Exp $ */ /* $NetBSD: chpass.h,v 1.4 1996/05/15 21:50:44 jtc Exp $ */ /* @@ -73,9 +73,3 @@ int p_shell(char *, struct passwd *, ENTRY *); int p_uid(char *, struct passwd *, ENTRY *); char *ttoa(char *, size_t, time_t); int verify(char *, struct passwd *); -struct passwd - *ypgetpwnam(char *); -struct passwd - *ypgetpwuid(uid_t uid); -int _yp_check(char **); -int pw_yp(struct passwd *, uid_t); diff --git a/usr.bin/chpass/pw_yp.c b/usr.bin/chpass/pw_yp.c deleted file mode 100644 index b8764fbc456..00000000000 --- a/usr.bin/chpass/pw_yp.c +++ /dev/null @@ -1,290 +0,0 @@ -/* $OpenBSD: pw_yp.c,v 1.23 2009/10/27 23:59:36 deraadt Exp $ */ -/* $NetBSD: pw_yp.c,v 1.5 1995/03/26 04:55:33 glass Exp $ */ - -/* - * Copyright (c) 1988 The Regents of the University of California. - * 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. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - */ - -#ifdef YP - -#include <stdio.h> -#include <string.h> -#include <netdb.h> -#include <time.h> -#include <pwd.h> -#include <err.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <rpc/rpc.h> -#include <rpcsvc/yp_prot.h> -#include <rpcsvc/ypclnt.h> -#define passwd yp_passwd_rec -#include <rpcsvc/yppasswd.h> -#undef passwd -#include "chpass.h" - -extern char *__progname; - -static char *domain; - -int -pw_yp(struct passwd *pw, uid_t uid) -{ - char uidbuf[20], gidbuf[20], *master, *p; - int r, rpcport, status, alen; - struct yppasswd yppasswd; - struct timeval tv; - CLIENT *client; - - /* - * Get local domain - */ - if (!domain && (r = yp_get_default_domain(&domain))) { - fprintf(stderr, "%s: can't get local YP domain. Reason: %s\n", - __progname, yperr_string(r)); - return(0); - } - - /* - * Find the host for the passwd map; it should be running - * the daemon. - */ - if ((r = yp_master(domain, "passwd.byname", &master)) != 0) { - fprintf(stderr, - "%s: can't find the master YP server. Reason: %s\n", - __progname, yperr_string(r)); - return(0); - } - - /* - * Ask the portmapper for the port of the daemon. - */ - if ((rpcport = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, - IPPROTO_UDP)) == 0) { - fprintf(stderr, - "%s: master YP server not running yppasswd daemon.\n", - __progname); - fprintf(stderr, "\tCan't change password.\n"); - return(0); - } - - /* - * Be sure the port is privileged - */ - if (rpcport >= IPPORT_RESERVED) { - (void)fprintf(stderr, - "%s: yppasswd daemon running on an invalid port.\n", - __progname); - return(0); - } - - /* prompt for old password */ - bzero(&yppasswd, sizeof yppasswd); - yppasswd.oldpass = "none"; - yppasswd.oldpass = getpass("Old password:"); - if (!yppasswd.oldpass) { - (void)fprintf(stderr, "Cancelled.\n"); - return(0); - } - - for (alen = 0, p = pw->pw_gecos; *p; p++) - if (*p == '&') - alen = alen + strlen(pw->pw_name) - 1; - (void)snprintf(uidbuf, sizeof uidbuf, "%u", pw->pw_uid); - (void)snprintf(gidbuf, sizeof gidbuf, "%u", pw->pw_gid); - - if (strlen(pw->pw_name) + 1 + strlen(pw->pw_passwd) + 1 + - strlen(uidbuf) + 1 + strlen(gidbuf) + 1 + - strlen(pw->pw_gecos) + alen + 1 + strlen(pw->pw_dir) + 1 + - strlen(pw->pw_shell) >= 1023) { - warnx("entries too long"); - return (0); - } - - /* tell rpc.yppasswdd */ - yppasswd.newpw.pw_name = pw->pw_name; - yppasswd.newpw.pw_passwd= pw->pw_passwd; - yppasswd.newpw.pw_uid = pw->pw_uid; - yppasswd.newpw.pw_gid = pw->pw_gid; - yppasswd.newpw.pw_gecos = pw->pw_gecos; - yppasswd.newpw.pw_dir = pw->pw_dir; - yppasswd.newpw.pw_shell = pw->pw_shell; - - client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp"); - if (client==NULL) { - fprintf(stderr, "can't contact yppasswdd on %s: Reason: %s\n", - master, yperr_string(YPERR_YPBIND)); - return(1); - } - client->cl_auth = authunix_create_default(); - tv.tv_sec = 5; - tv.tv_usec = 0; - r = clnt_call(client, YPPASSWDPROC_UPDATE, - xdr_yppasswd, &yppasswd, xdr_int, &status, tv); - if (r) { - fprintf(stderr, "%s: rpc to yppasswdd failed. %d\n", - __progname, r); - clnt_destroy(client); - return(1); - } else if (status) { - printf("Couldn't change YP password information.\n"); - clnt_destroy(client); - return(1); - } - printf("The YP password information has been changed on %s, the master YP passwd server.\n", master); - - clnt_destroy(client); - return(0); -} - -static char * -pwskip(char *p) -{ - while (*p && *p != ':' && *p != '\n') - ++p; - if (*p) - *p++ = 0; - return (p); -} - -static struct passwd * -interpret(struct passwd *pwent, char *line, const int secure) -{ - char *p = line; - - pwent->pw_passwd = "*"; - pwent->pw_uid = 0; - pwent->pw_gid = 0; - pwent->pw_gecos = ""; - pwent->pw_dir = ""; - pwent->pw_shell = ""; - pwent->pw_change = 0; - pwent->pw_expire = 0; - pwent->pw_class = ""; - - /* line without colon separators is no good, so ignore it */ - if (!strchr(p,':')) - return(NULL); - - pwent->pw_name = p; - p = pwskip(p); - pwent->pw_passwd = p; - p = pwskip(p); - pwent->pw_uid = (uid_t)strtoul(p, NULL, 10); - p = pwskip(p); - pwent->pw_gid = (gid_t)strtoul(p, NULL, 10); - p = pwskip(p); - if (secure == 1) { - pwent->pw_class = p; - p = pwskip(p); - pwent->pw_change = (time_t)strtoul(p, NULL, 10); - p = pwskip(p); - pwent->pw_expire = (time_t)strtoul(p, NULL, 10); - p = pwskip(p); - } - pwent->pw_gecos = p; - p = pwskip(p); - pwent->pw_dir = p; - p = pwskip(p); - pwent->pw_shell = p; - while (*p && *p != '\n') - p++; - *p = '\0'; - return (pwent); -} - -static char *__yplin; - -struct passwd * -ypgetpwnam(char *nam) -{ - static struct passwd pwent; - int reason, vallen, secure = 0; - char *val; - - /* - * Get local domain - */ - if (!domain && (reason = yp_get_default_domain(&domain))) { - fprintf(stderr, "%s: can't get local YP domain. Reason: %s\n", - __progname, yperr_string(reason)); - exit(1); - } - - if (!yp_match(domain, "master.passwd.byname", nam, strlen(nam), - &val, &vallen)) - secure = 1; - else if (yp_match(domain, "passwd.byname", nam, strlen(nam), - &val, &vallen)) - return (NULL); - - val[vallen] = '\0'; - if (__yplin) - free(__yplin); - if (!(__yplin = malloc(vallen + 1))) - err(1, NULL); - strlcpy(__yplin, val, vallen + 1); - free(val); - - return(interpret(&pwent, __yplin, secure)); -} - -struct passwd * -ypgetpwuid(uid_t uid) -{ - static struct passwd pwent; - int reason, vallen, secure = 0; - char namebuf[16], *val; - - if (!domain && (reason = yp_get_default_domain(&domain))) { - fprintf(stderr, "%s: can't get local YP domain. Reason: %s\n", - __progname, yperr_string(reason)); - exit(1); - } - - snprintf(namebuf, sizeof namebuf, "%u", (u_int)uid); - if (!yp_match(domain, "master.passwd.byuid", namebuf, strlen(namebuf), - &val, &vallen)) - secure = 1; - else if (yp_match(domain, "passwd.byuid", namebuf, strlen(namebuf), - &val, &vallen)) - return (NULL); - - val[vallen] = '\0'; - if (__yplin) - free(__yplin); - if (!(__yplin = malloc(vallen + 1))) - err(1, NULL); - strlcpy(__yplin, val, vallen + 1); - free(val); - - return(interpret(&pwent, __yplin, secure)); -} - -#endif /* YP */ diff --git a/usr.bin/passwd/Makefile b/usr.bin/passwd/Makefile index 8f27be6df99..e1168b760d8 100644 --- a/usr.bin/passwd/Makefile +++ b/usr.bin/passwd/Makefile @@ -1,9 +1,9 @@ -# $OpenBSD: Makefile,v 1.40 2015/09/14 07:19:41 guenther Exp $ +# $OpenBSD: Makefile,v 1.41 2015/11/26 19:01:47 deraadt Exp $ .include <bsd.own.mk> PROG= passwd -SRCS= local_passwd.c yp_passwd.c passwd.c getpwent.c \ +SRCS= local_passwd.c passwd.c getpwent.c \ pwd_check.c .PATH: ${.CURDIR}/../../lib/libc/gen DPADD+= ${LIBRPCSVC} ${LIBUTIL} @@ -11,9 +11,6 @@ LDADD+= -lrpcsvc -lutil CFLAGS+= -I${.CURDIR} CFLAGS+=-I${.CURDIR}/../../lib/libc/include -.if (${YP:L} == "yes") -CFLAGS+=-DYP -I${.CURDIR}/../../lib/libc/yp -.endif BINMODE=4555 BINOWN=root diff --git a/usr.bin/passwd/local_passwd.c b/usr.bin/passwd/local_passwd.c index 02b173e41e5..2c9f4b69c58 100644 --- a/usr.bin/passwd/local_passwd.c +++ b/usr.bin/passwd/local_passwd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: local_passwd.c,v 1.45 2015/10/25 08:39:26 ajacoutot Exp $ */ +/* $OpenBSD: local_passwd.c,v 1.46 2015/11/26 19:01:47 deraadt Exp $ */ /*- * Copyright (c) 1990 The Regents of the University of California. @@ -66,13 +66,13 @@ local_passwd(char *uname, int authenticated) int pwflags = _PASSWORD_OMITV7; if (!(pw = getpwnam(uname))) { -#ifdef YP - extern int use_yp; - if (!use_yp) -#endif warnx("unknown user %s.", uname); return(1); } + + if (pledge("stdio rpath wpath cpath getpw tty id proc exec", NULL) == -1) + err(1, "pledge"); + if ((opw = pw_dup(pw)) == NULL) { warn(NULL); return(1); @@ -93,6 +93,9 @@ local_passwd(char *uname, int authenticated) /* Get the new password. */ pw->pw_passwd = getnewpasswd(pw, lc, authenticated); + if (pledge("stdio rpath wpath cpath getpw id proc exec", NULL) == -1) + err(1, "pledge"); + /* Reset password change time based on login.conf. */ period = (time_t)login_getcaptime(lc, "passwordtime", (quad_t)0, (quad_t)0); @@ -115,6 +118,9 @@ local_passwd(char *uname, int authenticated) sigdelset(&fullset, SIGINT); sigprocmask(SIG_BLOCK, &fullset, NULL); + if (pledge("stdio rpath wpath cpath proc exec", NULL) == -1) + err(1, "pledge"); + /* Get a lock on the passwd file and open it. */ pw_init(); for (i = 1; (tfd = pw_lock(0)) == -1; i++) { @@ -155,7 +161,7 @@ getnewpasswd(struct passwd *pw, login_cap_t *lc, int authenticated) savequit = signal(SIGQUIT, kbintr); if (!authenticated) { - (void)printf("Changing local password for %s.\n", pw->pw_name); + (void)printf("Changing password for %s.\n", pw->pw_name); if (uid != 0 && pw->pw_passwd[0] != '\0') { p = getpass("Old password:"); if (p == NULL || *p == '\0') { diff --git a/usr.bin/passwd/passwd.1 b/usr.bin/passwd/passwd.1 index 72ce56fad01..0fb67cf23ee 100644 --- a/usr.bin/passwd/passwd.1 +++ b/usr.bin/passwd/passwd.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: passwd.1,v 1.43 2015/07/27 17:28:39 sobrado Exp $ +.\" $OpenBSD: passwd.1,v 1.44 2015/11/26 19:01:47 deraadt Exp $ .\" .\" Copyright (c) 1990 The Regents of the University of California. .\" All rights reserved. @@ -29,7 +29,7 @@ .\" .\" from: @(#)passwd.1 6.11 (Berkeley) 7/24/91 .\" -.Dd $Mdocdate: July 27 2015 $ +.Dd $Mdocdate: November 26 2015 $ .Dt PASSWD 1 .Os .Sh NAME @@ -37,11 +37,10 @@ .Nd modify a user's password .Sh SYNOPSIS .Nm passwd -.Op Fl l | y .Op Ar user .Sh DESCRIPTION .Nm -changes the user's local or YP password. +changes the user's password. If no .Ar user is specified, the user's login name is used (see @@ -64,24 +63,6 @@ checking program via the variable in .Xr login.conf 5 . .Pp -The options are as follows: -.Bl -tag -width Ds -.It Fl l -Causes the password to be updated only in the local password file. -When changing only the local password, -.Xr pwd_mkdb 8 -is used to update the password databases. -.It Fl y -Forces the YP password database entry to be changed, even if -the user has an entry in the local database. -The -.Xr rpc.yppasswdd 8 -daemon should be running on the YP master server. -.El -.Pp -If no flags are specified and the password is not in the local password -database, then an attempt is made to use the YP database. -.Pp The superuser is not required to provide a user's current password if only the local password is modified. .Pp diff --git a/usr.bin/passwd/passwd.c b/usr.bin/passwd/passwd.c index 9f789e08e72..c13afd76e81 100644 --- a/usr.bin/passwd/passwd.c +++ b/usr.bin/passwd/passwd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: passwd.c,v 1.26 2014/05/19 15:05:13 tedu Exp $ */ +/* $OpenBSD: passwd.c,v 1.27 2015/11/26 19:01:47 deraadt Exp $ */ /* * Copyright (c) 1988 The Regents of the University of California. @@ -34,26 +34,8 @@ #include <string.h> #include <unistd.h> #include <err.h> -#include <rpcsvc/ypclnt.h> - -/* - * Note on configuration: - * Generally one would not use both Kerberos and YP - * to maintain passwords. - * - */ - -int use_kerberos; -int use_yp; - -#ifdef YP -int force_yp; -#endif extern int local_passwd(char *, int); -extern int yp_passwd(char *); -extern int krb5_passwd(int, char **); -extern int _yp_check(char **); void usage(int retval); int @@ -62,40 +44,10 @@ main(int argc, char **argv) extern int optind; char *username; int ch; -#ifdef YP - int status = 0; -#endif -#ifdef YP - use_yp = _yp_check(NULL); - if (use_yp) { - char *dom; - - yp_get_default_domain(&dom); - yp_unbind(dom); - } -#endif /* Process args and options */ - while ((ch = getopt(argc, argv, "ly")) != -1) + while ((ch = getopt(argc, argv, "")) != -1) switch (ch) { - case 'l': /* change local password file */ - use_kerberos = 0; - use_yp = 0; - break; - case 'y': /* change YP password */ -#ifdef YP - if (!use_yp) { - fprintf(stderr, "passwd: YP not in use.\n"); - exit(1); - } - use_kerberos = 0; - use_yp = 1; - force_yp = 1; - break; -#else - fprintf(stderr, "passwd: YP not compiled in\n"); - exit(1); -#endif default: usage(1); } @@ -119,18 +71,12 @@ main(int argc, char **argv) usage(1); } -#ifdef YP - if (force_yp || ((status = local_passwd(username, 0)) && use_yp)) - exit(yp_passwd(username)); - exit(status); -#else exit(local_passwd(username, 0)); -#endif } void usage(int retval) { - fprintf(stderr, "usage: passwd [-l | -y] [user]\n"); + fprintf(stderr, "usage: passwd [user]\n"); exit(retval); } diff --git a/usr.bin/passwd/pwd_check.c b/usr.bin/passwd/pwd_check.c index 290cba0b99a..88f41057ac3 100644 --- a/usr.bin/passwd/pwd_check.c +++ b/usr.bin/passwd/pwd_check.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pwd_check.c,v 1.13 2013/03/02 09:07:37 ajacoutot Exp $ */ +/* $OpenBSD: pwd_check.c,v 1.14 2015/11/26 19:01:47 deraadt Exp $ */ /* * Copyright 2000 Niels Provos <provos@citi.umich.edu> @@ -134,6 +134,9 @@ pwd_check(login_cap_t *lc, char *password) } if (checker == NULL) { + if (pledge("stdio", NULL) == -1) + err(1, "pledge"); + for (i = 0; i < sizeof(patterns) / sizeof(*patterns); i++) { if (regcomp(&rgx, patterns[i].match, patterns[i].flags) != 0) @@ -149,6 +152,9 @@ pwd_check(login_cap_t *lc, char *password) exit(0); } + if (pledge("stdio exec", NULL) == -1) + err(1, "pledge"); + /* Otherwise, pass control to checker program */ argp[2] = checker; if (dup2(pipefds[0], STDIN_FILENO) == -1) { diff --git a/usr.bin/passwd/yp_passwd.c b/usr.bin/passwd/yp_passwd.c deleted file mode 100644 index d155e92120f..00000000000 --- a/usr.bin/passwd/yp_passwd.c +++ /dev/null @@ -1,341 +0,0 @@ -/* $OpenBSD: yp_passwd.c,v 1.37 2015/10/25 08:39:26 ajacoutot Exp $ */ - -/* - * Copyright (c) 1988 The Regents of the University of California. - * 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. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - */ - -#ifdef YP - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <netdb.h> -#include <time.h> -#include <pwd.h> -#include <err.h> -#include <signal.h> -#include <errno.h> -#include <ctype.h> -#include <login_cap.h> -#include <rpc/rpc.h> -#include <rpcsvc/yp_prot.h> -#include <rpcsvc/ypclnt.h> -#define passwd yp_passwd_rec -#include <rpcsvc/yppasswd.h> -#undef passwd - -#ifndef _PASSWORD_LEN -#define _PASSWORD_LEN PASS_MAX -#endif - -extern int pwd_check(login_cap_t *, char *); -extern int pwd_gettries(login_cap_t *); -extern void kbintr(int); -int yp_passwd(char *); - -char *ypgetnewpasswd(struct passwd *, login_cap_t *, char **); -struct passwd *ypgetpwnam(char *, int); -struct passwd *interpret(struct passwd *, char *, int); - -char *domain; - -static int -pw_error(char *name, int error, int eval) -{ - if (error) { - if (name) - warn("%s", name); - else - warn(NULL); - } - - warnx("YP passwd database: unchanged."); - exit(eval); -} - -int -yp_passwd(char *username) -{ - struct yppasswd yppwd; - int r, rpcport, status, secure=0; - struct passwd *pw; - struct timeval tv; - login_cap_t *lc; - CLIENT *client; - char *master; - uid_t uid; - - /* - * Get local domain - */ - if ((r = yp_get_default_domain(&domain)) != 0) { - warnx("can't get local YP domain. Reason: %s", - yperr_string(r)); - return (1); - } - - /* - * Find the host for the passwd map; it should be running - * the daemon. - */ - if ((r = yp_master(domain, "master.passwd.byname", &master)) == 0) { - secure=1; - } else if ((r = yp_master(domain, "passwd.byname", &master)) != 0) { - warnx("can't find the master YP server. Reason: %s", - yperr_string(r)); - return (1); - } - - /* - * Ask the portmapper for the port of the daemon. - */ - if ((rpcport = getrpcport(master, YPPASSWDPROG, - YPPASSWDPROC_UPDATE, IPPROTO_UDP)) == 0) { - warnx("master YP server not running yppasswd daemon."); - warnx("Can't change password."); - return (1); - } - - /* - * Be sure the port is privileged - */ - if (rpcport >= IPPORT_RESERVED) { - warnx("yppasswd daemon is on an invalid port."); - return (1); - } - - /* Get user's login identity */ - if (!(pw = ypgetpwnam(username, secure))) { - warnx("unknown user %s.", username); - return (1); - } - if ((lc = login_getclass(pw->pw_class)) == NULL) { - warnx("unable to get login class for user %s.", username); - return (1); - } - - uid = getuid(); - if (uid && uid != pw->pw_uid) { - warnx("you may only change your own password: %s", - strerror(EACCES)); - return (1); - } - - /* prompt for new password */ - yppwd.newpw.pw_passwd = ypgetnewpasswd(pw, lc, &yppwd.oldpass); - - /* tell rpc.yppasswdd */ - yppwd.newpw.pw_name = pw->pw_name; - yppwd.newpw.pw_uid = pw->pw_uid; - yppwd.newpw.pw_gid = pw->pw_gid; - yppwd.newpw.pw_gecos = pw->pw_gecos; - yppwd.newpw.pw_dir = pw->pw_dir; - yppwd.newpw.pw_shell = pw->pw_shell; - - client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp"); - if (client==NULL) { - warnx("cannot contact yppasswdd on %s: Reason: %s", - master, yperr_string(YPERR_YPBIND)); - free(yppwd.newpw.pw_passwd); - return (YPERR_YPBIND); - } - client->cl_auth = authunix_create_default(); - tv.tv_sec = 2; - tv.tv_usec = 0; - r = clnt_call(client, YPPASSWDPROC_UPDATE, - xdr_yppasswd, &yppwd, xdr_int, &status, tv); - if (r) { - printf("rpc to yppasswdd failed.\n"); - free(yppwd.newpw.pw_passwd); - return (1); - } else if (status) { - printf("Couldn't change YP password.\n"); - free(yppwd.newpw.pw_passwd); - return (1); - } else { - printf("The YP password has been changed on %s, " - "the master YP passwd server.\n", master); - free(yppwd.newpw.pw_passwd); - return (0); - } -} - -char * -ypgetnewpasswd(struct passwd *pw, login_cap_t *lc, char **old_pass) -{ - char buf[1024], hash[_PASSWORD_LEN]; - sig_t saveint, savequit; - int tries, pwd_tries; - char *p, *pref; - - saveint = signal(SIGINT, kbintr); - savequit = signal(SIGQUIT, kbintr); - - printf("Changing YP password for %s.\n", pw->pw_name); - if (old_pass) { - *old_pass = NULL; - - if (pw->pw_passwd[0]) { - p = getpass("Old password:"); - if (p == NULL || - strcmp(crypt(p, pw->pw_passwd), pw->pw_passwd)) { - errno = EACCES; - pw_error(NULL, 1, 1); - } - } else - p = ""; - *old_pass = strdup(p); - if (*old_pass == NULL) - pw_error(NULL, 1, 1); - } - - pwd_tries = pwd_gettries(lc); - - for (buf[0] = '\0', tries = 0;;) { - p = getpass("New password:"); - if (p == NULL || *p == '\0') - pw_error(NULL, 0, p == NULL ? 1 : 0); - if (strcmp(p, "s/key") == 0) { - printf("That password collides with a system feature. " - "Choose another.\n"); - continue; - } - if ((tries++ < pwd_tries || pwd_tries == 0) - && pwd_check(lc, p) == 0) - continue; - strlcpy(buf, p, sizeof buf); - p = getpass("Retype new password:"); - if (p != NULL && strcmp(buf, p) == 0) - break; - (void)printf("Mismatch; try again, EOF to quit.\n"); - } - - (void)signal(SIGINT, saveint); - (void)signal(SIGQUIT, savequit); - - pref = login_getcapstr(lc, "localcipher", NULL, NULL); - if (crypt_newhash(buf, pref, hash, sizeof(hash)) == -1) { - (void)printf("Couldn't generate hash.\n"); - pw_error(NULL, 0, 0); - } - free(pref); - p = strdup(hash); - if (p == NULL) - pw_error(NULL, 1, 1); - - return (p); -} - -static char * -pwskip(char *p) -{ - while (*p && *p != ':' && *p != '\n') - ++p; - if (*p) - *p++ = 0; - return (p); -} - -struct passwd * -interpret(struct passwd *pwent, char *line, int secure) -{ - char *p = line; - - pwent->pw_passwd = "*"; - pwent->pw_uid = 0; - pwent->pw_gid = 0; - pwent->pw_gecos = ""; - pwent->pw_dir = ""; - pwent->pw_shell = ""; - pwent->pw_change = 0; - pwent->pw_expire = 0; - pwent->pw_class = ""; - - /* line without colon separators is no good, so ignore it */ - if (!strchr(p, ':')) - return (NULL); - - pwent->pw_name = p; - p = pwskip(p); - pwent->pw_passwd = p; - p = pwskip(p); - pwent->pw_uid = (uid_t)strtoul(p, NULL, 10); - p = pwskip(p); - pwent->pw_gid = (gid_t)strtoul(p, NULL, 10); - p = pwskip(p); - if ( secure == 1 ) { - pwent->pw_class = p; - p = pwskip(p); - pwent->pw_change = (time_t)strtoul(p, NULL, 10); - p = pwskip(p); - pwent->pw_expire = (time_t)strtoul(p, NULL, 10); - p = pwskip(p); - } - pwent->pw_gecos = p; - p = pwskip(p); - pwent->pw_dir = p; - p = pwskip(p); - pwent->pw_shell = p; - while (*p && *p != '\n') - p++; - *p = '\0'; - return (pwent); -} - -static char *__yplin; - -struct passwd * -ypgetpwnam(char *nam, int secure) -{ - static struct passwd pwent; - int reason, vallen; - char *val; - - reason = yp_match(domain, - secure ? "master.passwd.byname" : "passwd.byname", - nam, strlen(nam), &val, &vallen); - switch (reason) { - case 0: - break; - default: - return (NULL); - } - val[vallen] = '\0'; - if (__yplin) - free(__yplin); - __yplin = malloc(vallen + 1); - if (__yplin == NULL) - pw_error(NULL, 1, 1); - strlcpy(__yplin, val, vallen + 1); - free(val); - - return (interpret(&pwent, __yplin, secure)); -} - -#endif /* YP */ |