From d18b50bbf45afd7a208bc308baee465fb558a431 Mon Sep 17 00:00:00 2001 From: tv Date: Fri, 21 Nov 1997 20:28:33 +0000 Subject: [PATCH] Added test to allow fallback to local password database if YP passwd map is not found. Fixes both PRs 4142 and 4557 (4558). Still fails properly if user is in YP and not in local database. Man page fixed to reflect current logic behind falling back, changed since YP was made default some time ago. --- usr.bin/passwd/passwd.1 | 6 +++--- usr.bin/passwd/yp_passwd.c | 41 ++++++++++++++++++++++++-------------- 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/usr.bin/passwd/passwd.1 b/usr.bin/passwd/passwd.1 index c781a52c6f3c..5790d7f97bf7 100644 --- a/usr.bin/passwd/passwd.1 +++ b/usr.bin/passwd/passwd.1 @@ -1,4 +1,4 @@ -.\" $NetBSD: passwd.1,v 1.10 1997/11/11 14:40:17 mrg Exp $ +.\" $NetBSD: passwd.1,v 1.11 1997/11/21 20:28:33 tv Exp $ .\" .\" Copyright (c) 1990, 1993 .\" The Regents of the University of California. All rights reserved. @@ -82,8 +82,8 @@ flag. .El .Pp This is the behavior if no flags are specified: -If the password is not in the local password database, then -an attempt is made to use the YP database. +If the password is not in the YP database, then +an attempt is made to use the local password database. The super-user is not required to provide a user's current password if only the local password is modified. .Sh FILES diff --git a/usr.bin/passwd/yp_passwd.c b/usr.bin/passwd/yp_passwd.c index d1c244f3f2ea..ef0f1b26c41b 100644 --- a/usr.bin/passwd/yp_passwd.c +++ b/usr.bin/passwd/yp_passwd.c @@ -1,4 +1,4 @@ -/* $NetBSD: yp_passwd.c,v 1.15 1997/10/19 12:30:07 lukem Exp $ */ +/* $NetBSD: yp_passwd.c,v 1.16 1997/11/21 20:28:35 tv Exp $ */ /* * Copyright (c) 1988, 1990, 1993, 1994 @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "from: @(#)local_passwd.c 8.3 (Berkeley) 4/2/94"; #else -__RCSID("$NetBSD: yp_passwd.c,v 1.15 1997/10/19 12:30:07 lukem Exp $"); +__RCSID("$NetBSD: yp_passwd.c,v 1.16 1997/11/21 20:28:35 tv Exp $"); #endif #endif /* not lint */ @@ -77,6 +77,7 @@ static char *getnewpasswd __P((struct passwd *, char **)); static struct passwd *interpret __P((struct passwd *, char *)); static struct passwd *ypgetpwnam __P((char *)); static void pw_error __P((char *, int, int)); +static void test_local __P((char *)); static uid_t uid; char *domain; @@ -91,6 +92,21 @@ pw_error(name, err, eval) errx(eval, "YP passwd database unchanged"); } +static void +test_local(username) + char *username; +{ + /* + * Something failed recoverably stating that the YP system couldn't + * find this user. Look for a local passwd entry, and change that + * if and only if we weren't run as yppasswd or with the -y option. + * This function does not return if a local entry is found. + */ + if (yppwd == 0 && yflag == 0) + if ((getpwnam(username) != NULL) && !local_passwd(username)) + exit(0); +} + int yp_passwd(username) char *username; @@ -115,25 +131,18 @@ yp_passwd(username) * Find the host for the passwd map; it should be running * the daemon. */ - if ((r = yp_master(domain, "passwd.byname", &master)) != 0) + if ((r = yp_master(domain, "passwd.byname", &master)) != 0) { + test_local(username); errx(1, "can't find the master YP server. Reason: %s", yperr_string(r)); + } /* * Ask the portmapper for the port of the daemon. */ if ((rpcport = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, IPPROTO_UDP)) == 0) { - /* - * Master server isn't running rpc.yppasswdd. Check to see - * if there's a local passwd entry, and if there is, use - * it iff: - * - we were not invoked as "yppasswd" - * - we were not passed "-y", and defaulted to YP - */ - if (yppwd == 0 && yflag == 0) - if (getpwnam(username) != NULL) - exit(local_passwd(username)); + test_local(username); errx(1, "master YP server not running yppasswd daemon.\n\t%s\n", "Can't change password."); } @@ -145,8 +154,10 @@ yp_passwd(username) errx(1, "yppasswd daemon is on an invalid port."); /* Get user's login identity */ - if (!(pw = ypgetpwnam(username))) + if (!(pw = ypgetpwnam(username))) { + test_local(username); errx(1, "unknown user %s", username); + } if (uid && uid != pw->pw_uid) errx(1, "you may only change your own password: %s", @@ -162,7 +173,7 @@ yp_passwd(username) 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",