Subject: Re: rpc.yppasswdd problems
To: Martti Kuparinen <martti.kuparinen@iki.fi>
From: Manuel Bouyer <bouyer@antioche.eu.org>
List: netbsd-help
Date: 06/10/2002 22:26:13
--82I3+IH0IqGh5yIs
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
On Mon, Jun 10, 2002 at 12:31:17PM +0300, Martti Kuparinen wrote:
> Hi!
>
> I'm having problems with my NIS server. Users can authenticate just fine
> against this server (1.6_BETA1) but nobody can change the passwords, not
> even root. And to make things more difficult to debug, there's nothing
> in the logs to help. The only thing in the logs is this line in
> /var/log/authlog:
>
> Jun 10 11:20:16 server rpcbind: connect from x.x.x.x to getport/addr(yppasswdd)
>
> server:~> passwd
> Changing YP password for martti.
> Old password:
> New password:
> Retype new password:
> Couldn't change YP password.
>
> server:~> ypcat passwd
> martti:*:1000:1000:Martti Kuparinen:/home/martti:/bin/bash
> [...]
>
> server:~> ls -l /var/yp/etc
> total 4
> -rw-r--r-- 1 root wheel 153 May 17 11:22 group
> -rw-r--r-- 1 root wheel 108 May 17 11:22 hosts
> -rw------- 1 root wheel 601 May 17 09:37 master.passwd
> -rw-r--r-- 1 root wheel 435 May 17 09:37 passwd
>
> server:~> cat /etc/rc.conf
> sshd=YES
> wscons=YES
> rpcbind=YES
> ypbind=YES
> ypserv=YES
> yppasswdd=YES yppasswdd_flags="-d /var/yp"
Yes, I ran into this too. rpc.yppasswdd uses getpwnam() to get the
user's passwd entry. This is wrong if the server isn't running NIS and
the NIS passwd file isn't /etc/master.passwd.
I fixed this problem in the attached patch. This is for 1.6.
Should be commited soon unless I get objections (I'm going to post this
to tech-userlevel)
--
Manuel Bouyer <bouyer@antioche.eu.org>
--
--82I3+IH0IqGh5yIs
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="yppasswdd.diff"
Index: yppasswdd_mkpw.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/rpc.yppasswdd/yppasswdd_mkpw.c,v
retrieving revision 1.9
diff -u -r1.9 yppasswdd_mkpw.c
--- yppasswdd_mkpw.c 2001/08/18 19:35:32 1.9
+++ yppasswdd_mkpw.c 2002/06/10 20:24:30
@@ -68,9 +68,11 @@
void
make_passwd(yppasswd *argp, struct svc_req *rqstp, SVCXPRT *transp)
{
- struct passwd *pw;
+ struct passwd pw;
int pfd, tfd;
char mpwd[MAXPATHLEN];
+ char buf[8192]; /* from libutil */
+ FILE *fpw;
#define REPLY(val) do { \
int res = (val); \
@@ -91,12 +93,30 @@
}
handling_request = 1;
- pw = getpwnam(argp->newpw.pw_name);
- if (!pw)
+ (void)strlcpy(mpwd, pw_getprefix(), sizeof(mpwd));
+ (void)strlcat(mpwd, _PATH_MASTERPASSWD, sizeof(mpwd));
+ fpw = fopen(mpwd, "r");
+ if (fpw == NULL) {
+ warnx("%s", mpwd);
RETURN(1);
-
- if (*pw->pw_passwd &&
- strcmp(crypt(argp->oldpass, pw->pw_passwd), pw->pw_passwd) != 0)
+ }
+ for(;;) {
+ if (fgets(buf, sizeof(buf), fpw) == NULL) {
+ if (feof(fpw))
+ warnx("%s: %s not found", mpwd,
+ argp->newpw.pw_name);
+ else
+ warnx("%s: %s", mpwd, strerror(errno));
+ RETURN(1);
+ }
+ if (pw_scan(buf, &pw, NULL) == 0)
+ continue;
+ if (strncmp(argp->newpw.pw_name, pw.pw_name, MAXLOGNAME) == 0)
+ break;
+ }
+ fclose(fpw);
+ if (*pw.pw_passwd &&
+ strcmp(crypt(argp->oldpass, pw.pw_passwd), pw.pw_passwd) != 0)
RETURN(1);
pw_init();
@@ -105,8 +125,6 @@
warnx("the passwd file is busy.");
RETURN(1);
}
- (void)strlcpy(mpwd, pw_getprefix(), sizeof(mpwd));
- (void)strlcat(mpwd, _PATH_MASTERPASSWD, sizeof(mpwd));
pfd = open(mpwd, O_RDONLY, 0);
if (pfd < 0) {
pw_abort();
@@ -120,17 +138,17 @@
* class and reset the timer.
*/
if (!nopw) {
- pw->pw_passwd = argp->newpw.pw_passwd;
- pw->pw_change = 0;
+ pw.pw_passwd = argp->newpw.pw_passwd;
+ pw.pw_change = 0;
}
if (!nogecos)
- pw->pw_gecos = argp->newpw.pw_gecos;
+ pw.pw_gecos = argp->newpw.pw_gecos;
if (!noshell)
- pw->pw_shell = argp->newpw.pw_shell;
+ pw.pw_shell = argp->newpw.pw_shell;
- pw_copy(pfd, tfd, pw, NULL);
+ pw_copy(pfd, tfd, &pw, NULL);
- if (pw_mkdb(pw->pw_name, 0) < 0) {
+ if (pw_mkdb(pw.pw_name, 0) < 0) {
warnx("pw_mkdb failed");
pw_abort();
RETURN(1);
--82I3+IH0IqGh5yIs--