diff options
Diffstat (limited to 'usr.bin/passwd')
-rw-r--r-- | usr.bin/passwd/Makefile | 79 | ||||
-rw-r--r-- | usr.bin/passwd/extern.h | 38 | ||||
-rw-r--r-- | usr.bin/passwd/kpasswd_proto.h | 54 | ||||
-rw-r--r-- | usr.bin/passwd/krb_passwd.c | 319 | ||||
-rw-r--r-- | usr.bin/passwd/local_passwd.c | 225 | ||||
-rw-r--r-- | usr.bin/passwd/passwd.1 | 210 | ||||
-rw-r--r-- | usr.bin/passwd/passwd.c | 243 | ||||
-rw-r--r-- | usr.bin/passwd/yp_passwd.c | 188 |
8 files changed, 1356 insertions, 0 deletions
diff --git a/usr.bin/passwd/Makefile b/usr.bin/passwd/Makefile new file mode 100644 index 0000000..49c303c --- /dev/null +++ b/usr.bin/passwd/Makefile @@ -0,0 +1,79 @@ +# From: @(#)Makefile 8.3 (Berkeley) 4/2/94 +# $Id: Makefile,v 1.23 1997/02/22 19:56:34 peter Exp $ + +PROG= passwd +SRCS= local_passwd.c yppasswd_private_xdr.c yppasswd_comm.c yp_passwd.c \ + passwd.c pw_copy.c pw_util.c pw_yp.c + +DPADD= ${LIBCRYPT} ${LIBRPCSVC} ${LIBUTIL} +LDADD= -lcrypt -lrpcsvc -lutil +.PATH: ${.CURDIR}/../../usr.bin/chpass ${.CURDIR}/../../usr.sbin/vipw \ + ${.CURDIR}/../rlogin ${.CURDIR}/../../libexec/ypxfr \ + ${.CURDIR}/../../usr.sbin/rpc.yppasswdd + +CFLAGS+= -DLOGIN_CAP -DCRYPT -DYP -I. -I${.CURDIR} \ + -I${.CURDIR}/../../usr.sbin/vipw \ + -I${.CURDIR}/../../usr.bin/chpass \ + -I${.CURDIR}/../../libexec/ypxfr \ + -I${.CURDIR}/../../usr.sbin/rpc.yppasswdd \ + -Dyp_error=warnx -DLOGGING + +SRCS+= ypxfr_misc.c yp_clnt.c yppasswd_clnt.c + +CLEANFILES= yp.h yp_clnt.c yppasswd.h yppasswd_clnt.c \ + yppasswd_private.h 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} yppasswd.h + ${RPCGEN} -l -o ${.TARGET} ${RPCSRC_PW} + +yppasswd_private.h: ${RPCSRC_PRIV} + ${RPCGEN} -h -o ${.TARGET} ${RPCSRC_PRIV} + +yppasswd_private_xdr.c: ${RPCSRC_PRIV} yppasswd_private.h + ${RPCGEN} -c -o ${.TARGET} ${RPCSRC_PRIV} + +BINOWN= root +BINMODE=4555 +MAN1=passwd.1 +LINKS=${BINDIR}/passwd ${BINDIR}/yppasswd +MLINKS=passwd.1 yppasswd.1 + +.if exists(${DESTDIR}/usr/lib/libkrb.a) && (defined(MAKE_EBONES)) +SRCS+= kpasswd.c +.PATH: ${.CURDIR}/../../usr.bin/chpass ${.CURDIR}/../../usr.sbin/vipw \ + ${.CURDIR}/../../usr.bin/rlogin ${.CURDIR}/../../usr.bin/passwd \ + ${.CURDIR}/../../eBones/usr.bin/passwd + +CFLAGS+= -DKERBEROS \ + -I${.CURDIR}/../../eBones/include \ + -I${.CURDIR}/../../eBones/lib/libkadm +# XXX not defined: ${LIBKADM}, ${LIBCOM_ERR} +DPADD= ${LIBKADM} ${LIBKRB} ${LIBDES} ${LIBCRYPT} ${LIBRPCSVC} ${LIBCOM_ERR} ${LIBUTIL} +LDADD= -lkadm -lkrb -ldes -lcrypt -lrpcsvc -lcom_err -lutil +DISTRIBUTION= krb +.endif + +beforeinstall: +.for i in passwd yppasswd + [ ! -e ${DESTDIR}${BINDIR}/$i ] || \ + chflags noschg ${DESTDIR}${BINDIR}/$i +.endfor + +afterinstall: + chflags schg ${DESTDIR}${BINDIR}/passwd + +.include <bsd.prog.mk> diff --git a/usr.bin/passwd/extern.h b/usr.bin/passwd/extern.h new file mode 100644 index 0000000..7a4bd12 --- /dev/null +++ b/usr.bin/passwd/extern.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 1994 + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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. + * + * From: @(#)extern.h 8.1 (Berkeley) 4/2/94 + * $Id$ + */ + +int krb_passwd __P((char *, char *, char *, char *)); +int local_passwd __P((char *)); diff --git a/usr.bin/passwd/kpasswd_proto.h b/usr.bin/passwd/kpasswd_proto.h new file mode 100644 index 0000000..465d4c7 --- /dev/null +++ b/usr.bin/passwd/kpasswd_proto.h @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 1989, 1993 + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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. + * + * @(#)kpasswd_proto.h 8.1 (Berkeley) 6/6/93 + */ + +/* + * kpasswd_proto + * + * definitions for the kpasswd "protocol" + * (We hope this to be temporary until a real admin protocol is worked out.) + */ + +struct kpasswd_data { + des_cblock random_key; + char secure_msg[_PASSWORD_LEN]; +}; + +struct update_data { + char pw[_PASSWORD_LEN]; + char secure_msg[_PASSWORD_LEN]; +}; +#define SERVICE "kpasswd" +#define SECURE_STRING \ + "Kerberos password update program -- 12/9/88 UC Berkeley" diff --git a/usr.bin/passwd/krb_passwd.c b/usr.bin/passwd/krb_passwd.c new file mode 100644 index 0000000..d4a0f15 --- /dev/null +++ b/usr.bin/passwd/krb_passwd.c @@ -0,0 +1,319 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)krb_passwd.c 8.3 (Berkeley) 4/2/94"; +#endif /* not lint */ + +#ifdef KERBEROS + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <netinet/in.h> +#include <kerberosIV/des.h> +#include <kerberosIV/krb.h> + +#include <err.h> +#include <errno.h> +#include <netdb.h> +#include <pwd.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "kpasswd_proto.h" + +#include "extern.h" + +#define PROTO "tcp" + +static void send_update __P((int, char *, char *)); +static void recv_ack __P((int)); +static void cleanup __P((void)); +static void finish __P((void)); + +static struct timeval timeout = { CLIENT_KRB_TIMEOUT, 0 }; +static struct kpasswd_data proto_data; +static des_cblock okey; +static Key_schedule osched; +static KTEXT_ST ticket; +static Key_schedule random_schedule; +static long authopts; +static char realm[REALM_SZ], krbhst[MAX_HSTNM]; +static int sock; + +int +krb_passwd() +{ + struct servent *se; + struct hostent *host; + struct sockaddr_in sin; + CREDENTIALS cred; + fd_set readfds; + int rval; + char pass[_PASSWORD_LEN], password[_PASSWORD_LEN]; + static void finish(); + + static struct rlimit rl = { 0, 0 }; + + (void)signal(SIGHUP, SIG_IGN); + (void)signal(SIGINT, SIG_IGN); + (void)signal(SIGTSTP, SIG_IGN); + + if (setrlimit(RLIMIT_CORE, &rl) < 0) { + warn("setrlimit"); + return (1); + } + + if ((se = getservbyname(SERVICE, PROTO)) == NULL) { + warnx("couldn't find entry for service %s/%s", + SERVICE, PROTO); + return (1); + } + + if ((rval = krb_get_lrealm(realm,1)) != KSUCCESS) { + warnx("couldn't get local Kerberos realm: %s", + krb_err_txt[rval]); + return (1); + } + + if ((rval = krb_get_krbhst(krbhst, realm, 1)) != KSUCCESS) { + warnx("couldn't get Kerberos host: %s", + krb_err_txt[rval]); + return (1); + } + + if ((host = gethostbyname(krbhst)) == NULL) { + warnx("couldn't get host entry for krb host %s", + krbhst); + return (1); + } + + sin.sin_family = host->h_addrtype; + memmove((char *) &sin.sin_addr, host->h_addr, host->h_length); + sin.sin_port = se->s_port; + + if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + warn("socket"); + return (1); + } + + if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) < 0) { + warn("connect"); + (void)close(sock); + return (1); + } + + rval = krb_sendauth( + authopts, /* NOT mutual */ + sock, + &ticket, /* (filled in) */ + SERVICE, + krbhst, /* instance (krbhst) */ + realm, /* dest realm */ + (u_long) getpid(), /* checksum */ + NULL, /* msg data */ + NULL, /* credentials */ + NULL, /* schedule */ + NULL, /* local addr */ + NULL, /* foreign addr */ + "KPWDV0.1" + ); + + if (rval != KSUCCESS) { + warnx("Kerberos sendauth error: %s", krb_err_txt[rval]); + return (1); + } + + krb_get_cred("krbtgt", realm, realm, &cred); + + (void)printf("Changing Kerberos password for %s.%s@%s.\n", + cred.pname, cred.pinst, realm); + + if (des_read_pw_string(pass, + sizeof(pass)-1, "Old Kerberos password:", 0)) { + warnx("error reading old Kerberos password"); + return (1); + } + + (void)des_string_to_key(pass, okey); + (void)des_key_sched(okey, osched); + (void)des_set_key(okey, osched); + + /* wait on the verification string */ + + FD_ZERO(&readfds); + FD_SET(sock, &readfds); + + rval = + select(sock + 1, &readfds, (fd_set *) 0, (fd_set *) 0, &timeout); + + if ((rval < 1) || !FD_ISSET(sock, &readfds)) { + if(rval == 0) { + warnx("timed out (aborted)"); + cleanup(); + return (1); + } + warnx("select failed (aborted)"); + cleanup(); + return (1); + } + + /* read verification string */ + + if (des_read(sock, &proto_data, sizeof(proto_data)) != + sizeof(proto_data)) { + warnx("couldn't read verification string (aborted)"); + cleanup(); + return (1); + } + + (void)signal(SIGHUP, finish); + (void)signal(SIGINT, finish); + + if (strcmp(SECURE_STRING, proto_data.secure_msg) != 0) { + cleanup(); + /* don't complain loud if user just hit return */ + if (pass == NULL || (!*pass)) + return (0); + (void)fprintf(stderr, "Sorry\n"); + return (1); + } + + (void)des_key_sched(proto_data.random_key, random_schedule); + (void)des_set_key(proto_data.random_key, random_schedule); + (void)memset(pass, 0, sizeof(pass)); + + if (des_read_pw_string(pass, + sizeof(pass)-1, "New Kerberos password:", 0)) { + warnx("error reading new Kerberos password (aborted)"); + cleanup(); + return (1); + } + + if (des_read_pw_string(password, + sizeof(password)-1, "Retype new Kerberos password:", 0)) { + warnx("error reading new Kerberos password (aborted)"); + cleanup(); + return (1); + } + + if (strcmp(password, pass) != 0) { + warnx("password mismatch (aborted)"); + cleanup(); + return (1); + } + + if (strlen(pass) == 0) + (void)printf("using NULL password\n"); + + send_update(sock, password, SECURE_STRING); + + /* wait for ACK */ + + FD_ZERO(&readfds); + FD_SET(sock, &readfds); + + rval = + select(sock + 1, &readfds, (fd_set *) 0, (fd_set *) 0, &timeout); + if ((rval < 1) || !FD_ISSET(sock, &readfds)) { + if(rval == 0) { + warnx("timed out reading ACK (aborted)"); + cleanup(); + exit(1); + } + warnx("select failed (aborted)"); + cleanup(); + exit(1); + } + recv_ack(sock); + cleanup(); + return (0); +} + +static void +send_update(dest, pwd, str) + int dest; + char *pwd, *str; +{ + static struct update_data ud; + + (void)strncpy(ud.secure_msg, str, _PASSWORD_LEN); + (void)strncpy(ud.pw, pwd, sizeof(ud.pw)); + if (des_write(dest, &ud, sizeof(ud)) != sizeof(ud)) { + warnx("couldn't write pw update (abort)"); + memset((char *)&ud, 0, sizeof(ud)); + cleanup(); + exit(1); + } +} + +static void +recv_ack(remote) + int remote; +{ + int cc; + char buf[BUFSIZ]; + + cc = des_read(remote, buf, sizeof(buf)); + if (cc <= 0) { + warnx("error reading acknowledgement (aborted)"); + cleanup(); + exit(1); + } + (void)printf("%s", buf); +} + +static void +cleanup() +{ + + (void)memset((char *)&proto_data, 0, sizeof(proto_data)); + (void)memset((char *)okey, 0, sizeof(okey)); + (void)memset((char *)osched, 0, sizeof(osched)); + (void)memset((char *)random_schedule, 0, sizeof(random_schedule)); +} + +static void +finish() +{ + + (void)close(sock); + exit(1); +} + +#endif /* KERBEROS */ diff --git a/usr.bin/passwd/local_passwd.c b/usr.bin/passwd/local_passwd.c new file mode 100644 index 0000000..5e8a4bc --- /dev/null +++ b/usr.bin/passwd/local_passwd.c @@ -0,0 +1,225 @@ +/*- + * Copyright (c) 1990, 1993, 1994 + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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. + * + * $Id: local_passwd.c,v 1.17 1997/05/10 19:02:38 davidn Exp $ + */ + +#ifndef lint +static const char sccsid[] = "@(#)local_passwd.c 8.3 (Berkeley) 4/2/94"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/time.h> + +#include <ctype.h> +#include <err.h> +#include <errno.h> +#include <pwd.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include <pw_copy.h> +#include <pw_util.h> +#ifdef YP +#include <pw_yp.h> +#endif + +#ifdef LOGGING +#include <syslog.h> +#endif + +#ifdef LOGIN_CAP +#ifdef AUTH_NONE /* multiple defs :-( */ +#undef AUTH_NONE +#endif +#include <login_cap.h> +#endif + +#include "extern.h" + +static uid_t uid; +int randinit; + +char *tempname; + +static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +void +to64(s, v, n) + char *s; + long v; + int n; +{ + while (--n >= 0) { + *s++ = itoa64[v&0x3f]; + v >>= 6; + } +} + +char * +getnewpasswd(pw, nis) + struct passwd *pw; + int nis; +{ + int tries, min_length = 6; + char *p, *t; +#ifdef LOGIN_CAP + login_cap_t * lc; +#endif + char buf[_PASSWORD_LEN+1], salt[10]; + struct timeval tv; + + if (!nis) + (void)printf("Changing local password for %s.\n", pw->pw_name); + + if (uid && pw->pw_passwd[0] && + strcmp(crypt(getpass("Old password:"), pw->pw_passwd), + pw->pw_passwd)) { + errno = EACCES; + pw_error(NULL, 1, 1); + } + +#ifdef LOGIN_CAP + /* + * Determine minimum password length and next password change date. + * Note that even for NIS passwords, login_cap is still used. + */ + if ((lc = login_getpwclass(pw)) != NULL) { + time_t period; + + /* minpasswordlen capablity */ + min_length = (int)login_getcapnum(lc, "minpasswordlen", + min_length, min_length); + /* passwordperiod capability */ + period = login_getcaptime(lc, "passwordperiod", 0, 0); + if (period > (time_t)0) { + pw->pw_change = time(NULL) + period; + } + login_close(lc); + } +#endif + + for (buf[0] = '\0', tries = 0;;) { + p = getpass("New password:"); + if (!*p) { + (void)printf("Password unchanged.\n"); + pw_error(NULL, 0, 0); + } + if (strlen(p) < min_length && (uid != 0 || ++tries < 2)) { + (void)printf("Please enter a password at least %d characters in length.\n", min_length); + continue; + } + for (t = p; *t && islower(*t); ++t); + if (!*t && (uid != 0 || ++tries < 2)) { + (void)printf("Please don't use an all-lower case password.\nUnusual capitalization, control characters or digits are suggested.\n"); + continue; + } + (void)strcpy(buf, p); + if (!strcmp(buf, getpass("Retype new password:"))) + break; + (void)printf("Mismatch; try again, EOF to quit.\n"); + } + /* grab a random printable character that isn't a colon */ + if (!randinit) { + randinit = 1; + srandomdev(); + } +#ifdef NEWSALT + salt[0] = _PASSWORD_EFMT1; + to64(&salt[1], (long)(29 * 25), 4); + to64(&salt[5], random(), 4); + salt[9] = '\0'; +#else + /* Make a good size salt for algoritms that can use it. */ + gettimeofday(&tv,0); + if (strncmp(pw->pw_passwd, "$1$", 3)) { + /* DES Salt */ + to64(&salt[0], random(), 3); + to64(&salt[3], tv.tv_usec, 3); + to64(&salt[6], tv.tv_sec, 2); + salt[8] = '\0'; + } + else { + /* MD5 Salt */ + strncpy(&salt[0], "$1$", 3); + to64(&salt[3], random(), 3); + to64(&salt[6], tv.tv_usec, 3); + salt[8] = '\0'; + } +#endif + return (crypt(buf, salt)); +} + +int +local_passwd(uname) + char *uname; +{ + struct passwd *pw; + int pfd, tfd; + + if (!(pw = getpwnam(uname))) + errx(1, "unknown user %s", uname); + +#ifdef YP + /* Use the right password information. */ + pw = (struct passwd *)&local_password; +#endif + uid = getuid(); + if (uid && uid != pw->pw_uid) + errx(1, "%s", strerror(EACCES)); + + pw_init(); + pfd = pw_lock(); + tfd = pw_tmp(); + + /* + * Get the new password. Reset passwd change time to zero by + * default. If the user has a valid login class (or the default + * fallback exists), then the next password change date is set + * by getnewpasswd() according to the "passwordperiod" capability + * if one has been specified. + */ + pw->pw_change = 0; + pw->pw_passwd = getnewpasswd(pw, 0); + pw_copy(pfd, tfd, pw); + + if (!pw_mkdb(uname)) + pw_error((char *)NULL, 0, 1); +#ifdef LOGGING + syslog(LOG_DEBUG, "user %s changed their local password\n", uname); +#endif + return (0); +} diff --git a/usr.bin/passwd/passwd.1 b/usr.bin/passwd/passwd.1 new file mode 100644 index 0000000..a595bfa --- /dev/null +++ b/usr.bin/passwd/passwd.1 @@ -0,0 +1,210 @@ +.\" Copyright (c) 1990, 1993 +.\" 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. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. 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. +.\" +.\" @(#)passwd.1 8.1 (Berkeley) 6/6/93 +.\" +.Dd June 6, 1993 +.Dt PASSWD 1 +.Os BSD 4 +.Sh NAME +.Nm passwd, yppasswd +.Nd modify a user's password +.Sh SYNOPSIS +.Nm passwd +.Op Fl l +.Op Ar user +.Nm yppasswd +.Op Fl l +.Op Fl y +.Op Fl d Ar domain +.Op Fl s Ar host +.Op Fl o +.Sh DESCRIPTION +.Nm Passwd +changes the user's local, Kerberos, or NIS password. First, the user is prompted for their +current password. +If the current password is correctly typed, a new password is +requested. +The new password must be entered twice to avoid typing errors. +.Pp +The new password should be at least six characters long (which +may be overridden using the +.Xr login.cap 5 +"minpasswordlen" setting for a user's login class) and not purely alphabetic. +Its total length must be less than +.Dv _PASSWORD_LEN +(currently 128 characters). +Numbers, upper case letters and meta characters +are encouraged. +.Pp +Once the password has been verified, +.Nm passwd +communicates the new password information to +the Kerberos authenticating host. +.Bl -tag -width flag +.It Fl l +This option causes the password to be updated only in the local +password file, and not with the Kerberos database. +When changing only the local password, +.Xr pwd_mkdb 8 +is used to update the password databases. +.Pp +.El +When changing local or NIS password, the next password change date +is set according to "passwordperiod" capability in the user's +login class. +.Pp +To change another user's Kerberos password, one must first +run +.Xr kinit 1 +followed by +.Xr passwd 1 . +The super-user is not required to provide a user's current password +if only the local password is modified. +.Sh NIS INTERACTION +.Nm Passwd +has built-in support for NIS. If a user exists in the NIS password +database but does not exist locally, +.Nm passwd +automatically switches into ``yppasswd'' mode. If the specified +user does not exist in either the local password database of the +NIS password maps, +.Nm passwd +returns an error. +.Pp +When changing an NIS password, unprivileged users are required to provide +their old password for authentication (the +.Xr rpc.yppasswdd 8 +daemon requires the original password before +it will allow any changes to the NIS password maps). +This restriction applies even to the +super-user, with one important exception: the password authentication is +bypassed for the super-user on the NIS master server. This means that +the super-user on the NIS master server can make unrestricted changes to +anyone's NIS password. The super-user on NIS client systems and NIS slave +servers still needs to provide a password before the update will be processed. +.Pp +The following additional options are supported for use with NIS: +.Bl -tag -width flag +.It Fl y +The +.Fl y +flag overrides +.Nm passwd 's +checking heuristics and forces +it into NIS mode. +.It Fl l +When NIS is enabled, the +.Fl l +flag can be used to force +.Nm passwd +into ``local only'' mode. This flag can be used to change the entry +for a local user when an NIS user exists when the same login name. +For example, you will sometimes find entries for system ``placeholder'' +users such as +.Pa bin +or +.Pa daemon +in both the NIS password maps and the local user database. By +default, +.Nm passwd +will try to change the NIS password. The +.Fl l +flag can be used to change the local password instead. +.It Fl d Ar domain +Specify what domain to use when changing an NIS password. By default, +.Nm passwd +assumes that the system default domain should be used. This flag is +primarily for use by the superuser on the NIS master server: a single +NIS server can support multiple domains. It is also possible that the +domainname on the NIS master may not be set (it is not necessary for +an NIS server to also be a client) in which case the +.Nm passwd +command needs to be told what domain to operate on. +.It Fl s Ar host +Specify the name of an NIS server. This option, in conjunction +with the +.Fl d +option, can be used to change an NIS password on a non-local NIS +server. When a domain is specified with the +.Fl d +option and +.Nm passwd +is unable to determine the name of the NIS master server (possibly because +the local domainname isn't set), the name of the NIS master is assumed to +be ``localhost''. This can be overriden with the +.Fl s +flag. The specified hostname need not be the name of an NIS master: the +name of the NIS master for a given map can be determined by querying any +NIS server (master or slave) in a domain, so specifying the name of a +slave server will work equally well. +.Pp +.It Fl o +Do not automatically override the password authentication checks for the +super-user on the NIS master server; assume 'old' mode instead. This +flag is of limited practical use but is useful for testing. +.El +.Sh FILES +.Bl -tag -width /etc/master.passwd -compact +.It Pa /etc/master.passwd +The user database +.It Pa /etc/passwd +A Version 7 format password file +.It Pa /etc/passwd.XXXXXX +Temporary copy of the password file +.It Pa /etc/login.conf +Login class capabilities database +.El +.Sh SEE ALSO +.Xr chpass 1 , +.Xr kerberos 1 , +.Xr kinit 1 , +.Xr login 1 , +.Xr login.conf 5 , +.Xr passwd 5 , +.Xr kpasswdd 8 , +.Xr pwd_mkdb 8 , +.Xr vipw 8 +.Rs +.%A Robert Morris +.%A Ken Thompson +.%T "UNIX password security" +.Re +.Sh NOTES +The +.Xr yppasswd 1 +command is really only a link to +.Nm passwd . +.Sh HISTORY +A +.Nm passwd +command appeared in +.At v6 . diff --git a/usr.bin/passwd/passwd.c b/usr.bin/passwd/passwd.c new file mode 100644 index 0000000..46562c6 --- /dev/null +++ b/usr.bin/passwd/passwd.c @@ -0,0 +1,243 @@ +/* + * Copyright (c) 1988, 1993, 1994 + * 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. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. 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. + * + * $id$ + * + */ + +#ifndef lint +static const char copyright[] = +"@(#) Copyright (c) 1988, 1993, 1994\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static const char sccsid[] = "From: @(#)passwd.c 8.3 (Berkeley) 4/2/94"; +static const char rcsid[] = + "$Id: passwd.c,v 1.11 1997/02/22 19:56:35 peter Exp $"; +#endif /* not lint */ + +#include <err.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +#ifdef YP +#include <pwd.h> +#include <pw_yp.h> +#include <rpcsvc/yp.h> +int __use_yp = 0; +int yp_errno = YP_TRUE; +extern int yp_passwd __P(( char * )); +#endif + +#ifdef KERBEROS +#include "krb.h" +#endif + +#include "extern.h" + +void usage __P((void)); + +int use_local_passwd = 0; + +int +main(argc, argv) + int argc; + char **argv; +{ + int ch; + char *uname; + char *iflag = 0, *rflag = 0, *uflag = 0; + +#ifdef YP +#ifdef KERBEROS + char realm[REALM_SZ]; +#define OPTIONS "d:h:lysfoi:r:u:" +#else +#define OPTIONS "d:h:lysfo" +#endif +#else +#ifdef KERBEROS + char realm[REALM_SZ]; +#define OPTIONS "li:r:u:" +#else +#define OPTIONS "l" +#endif +#endif + +#ifdef YP + int res = 0; + + if (strstr(argv[0], "yppasswd")) __use_yp = 1; +#endif + + while ((ch = getopt(argc, argv, OPTIONS)) != -1) { + switch (ch) { + case 'l': /* change local password file */ + use_local_passwd = 1; + break; +#ifdef KERBEROS + case 'i': + iflag = optarg; + break; + case 'r': + rflag = optarg; + break; + case 'u': + uflag = optarg; + break; +#endif /* KERBEROS */ +#ifdef YP + case 'y': /* Change NIS password */ + __use_yp = 1; + break; + case 'd': /* Specify NIS domain. */ +#ifdef PARANOID + if (!getuid()) { +#endif + yp_domain = optarg; + if (yp_server == NULL) + yp_server = "localhost"; +#ifdef PARANOID + } else { + warnx("Only the super-user may use the -d flag."); + } +#endif + break; + case 'h': /* Specify NIS server. */ +#ifdef PARANOID + if (!getuid()) { +#endif + yp_server = optarg; +#ifdef PARANOID + } else { + warnx("Only the super-user may use the -h flag."); + } +#endif + break; + case 'o': + force_old++; + break; +#endif + default: + case '?': + usage(); + } + } + + argc -= optind; + argv += optind; + + if ((uname = getlogin()) == NULL) + err(1, "getlogin"); + + switch(argc) { + case 0: + break; + case 1: + uname = argv[0]; + break; + default: + usage(); + } + +#ifdef YP + /* + * If NIS is turned on in the password database, use it, else punt. + */ +#ifdef KERBEROS + if (__use_yp || (iflag == NULL && rflag == NULL && uflag == NULL)) { +#endif + res = use_yp(uname, 0, 0); + if (res == USER_YP_ONLY) { + if (!use_local_passwd) { + exit(yp_passwd(uname)); + } else { + /* + * Reject -l flag if NIS is turned on and the user + * doesn't exist in the local password database. + */ + errx(1, "unknown local user: %s.", uname); + } + } else if (res == USER_LOCAL_ONLY) { + /* + * Reject -y flag if user only exists locally. + */ + if (__use_yp) + errx(1, "unknown NIS user: %s.", uname); + } else if (res == USER_YP_AND_LOCAL) { + if (!use_local_passwd && (yp_in_pw_file || __use_yp)) + exit(yp_passwd(uname)); + } +#ifdef KERBEROS + } +#endif +#endif + + if (!use_local_passwd) { +#ifdef KERBEROS + if(krb_get_lrealm(realm, 0) == KSUCCESS) { + fprintf(stderr, "realm %s\n", realm); + exit(krb_passwd(argv[0], iflag, rflag, uflag)); + } +#endif + } + exit(local_passwd(uname)); +} + +void +usage() +{ + +#ifdef YP +#ifdef KERBEROS + fprintf(stderr, + "usage: passwd [-l] [-i instance] [-r realm] [-u fullname]\n"); + fprintf(stderr, + " [-l] [-y] [-o] [-d domain [-h host]] [user]\n"); +#else + (void)fprintf(stderr, "usage: passwd [-l] [-y] [-o] [-d domain \ +[-h host]] [user] \n"); +#endif +#else +#ifdef KERBEROS + fprintf(stderr, + "usage: passwd [-l] [-i instance] [-r realm] [-u fullname] [user]\n"); +#else + (void)fprintf(stderr, "usage: passwd user\n"); +#endif +#endif + exit(1); +} diff --git a/usr.bin/passwd/yp_passwd.c b/usr.bin/passwd/yp_passwd.c new file mode 100644 index 0000000..3eab43a --- /dev/null +++ b/usr.bin/passwd/yp_passwd.c @@ -0,0 +1,188 @@ +/* + * 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> + * 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. The name of the author may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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 <netdb.h> +#include <time.h> +#include <sys/types.h> +#include <pwd.h> +#include <errno.h> +#include <unistd.h> +#include <limits.h> +#include <rpc/rpc.h> +#include <rpcsvc/yp_prot.h> +#include <rpcsvc/ypclnt.h> +#include <rpcsvc/yppasswd.h> +#include <pw_yp.h> +#include "yppasswd_comm.h" + +extern char *getnewpasswd __P(( struct passwd * , int )); + +int +yp_passwd(char *user) +{ + struct timeval timeout; + struct yppasswd yppasswd; + struct master_yppasswd master_yppasswd; + struct passwd *pw; + CLIENT *clnt; + struct rpc_err err; + char *master; + int *status = NULL; + uid_t uid; + + _use_yp = 1; + + uid = getuid(); + + if ((master = get_yp_master(1)) == NULL) { + warnx("failed to find NIS master server"); + return(1); + } + + /* + * 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 */ + pw = (struct passwd *)&yp_password; + + if (pw->pw_uid != uid && uid != 0) { + warnx("Only the super-user may change account information \ +for other users"); + return(1); + } + + pw->pw_change = 0; + + /* Initialize password information */ + if (suser_override) { + master_yppasswd.newpw.pw_passwd = strdup(pw->pw_passwd); + master_yppasswd.newpw.pw_name = strdup(pw->pw_name); + master_yppasswd.newpw.pw_uid = pw->pw_uid; + master_yppasswd.newpw.pw_gid = pw->pw_gid; + master_yppasswd.newpw.pw_expire = pw->pw_expire; + master_yppasswd.newpw.pw_change = pw->pw_change; + master_yppasswd.newpw.pw_fields = pw->pw_fields; + master_yppasswd.newpw.pw_gecos = strdup(pw->pw_gecos); + master_yppasswd.newpw.pw_dir = strdup(pw->pw_dir); + master_yppasswd.newpw.pw_shell = strdup(pw->pw_shell); + master_yppasswd.newpw.pw_class = pw->pw_class != NULL ? + strdup(pw->pw_class) : ""; + master_yppasswd.oldpass = ""; + master_yppasswd.domain = yp_domain; + } else { + yppasswd.newpw.pw_passwd = strdup(pw->pw_passwd); + yppasswd.newpw.pw_name = strdup(pw->pw_name); + yppasswd.newpw.pw_uid = pw->pw_uid; + yppasswd.newpw.pw_gid = pw->pw_gid; + yppasswd.newpw.pw_gecos = strdup(pw->pw_gecos); + yppasswd.newpw.pw_dir = strdup(pw->pw_dir); + yppasswd.newpw.pw_shell = strdup(pw->pw_shell); + yppasswd.oldpass = ""; + } + + if (suser_override) + printf("Changing NIS password for %s on %s in domain %s.\n", + pw->pw_name, master, yp_domain); + else + printf("Changing NIS password for %s on %s.\n", + pw->pw_name, master); + + /* Get old password */ + + if(pw->pw_passwd[0] && !suser_override) { + yppasswd.oldpass = strdup(getpass("Old Password: ")); + if (strcmp(crypt(yppasswd.oldpass, pw->pw_passwd), + pw->pw_passwd)) { + errx(1, "Sorry."); + } + + } + + if (suser_override) { + if ((master_yppasswd.newpw.pw_passwd = getnewpasswd(pw, 1)) == NULL) + return(1); + } else { + if ((yppasswd.newpw.pw_passwd = getnewpasswd(pw, 1)) == NULL) + return(1); + } + + if (suser_override) { + if (senddat(&master_yppasswd)) { + warnx("failed to send request to rpc.yppasswdd"); + return(1); + } + status = getresp(); + } else { + if ((clnt = clnt_create(master, YPPASSWDPROG, + YPPASSWDVERS, "udp")) == NULL) { + warnx("failed to contact rpc.yppasswdd on host %s: %s", + master, clnt_spcreateerror("")); + return(1); + } + /* + * 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(); + + status = yppasswdproc_update_1(&yppasswd, clnt); + clnt_geterr(clnt, &err); + + auth_destroy(clnt->cl_auth); + clnt_destroy(clnt); + } + + if ((!suser_override && err.re_status != RPC_SUCCESS) || + status == NULL || *status) { + errx(1, "Failed to change NIS password: %s", + (err.re_status != RPC_SUCCESS && !suser_override) ? + clnt_sperrno(err.re_status) : + "rpc.yppasswdd returned error status"); + } + + printf("\nNIS password has%s been changed on %s.\n", + ((err.re_status != RPC_SUCCESS && !suser_override) + || status == NULL || *status) ? + " not" : "", master); + + return ((err.re_status || status == NULL || *status)); +} +#endif /* YP */ |