Home | History | Annotate | Line # | Download | only in passwd
yp_passwd.c revision 1.36.2.1
      1  1.36.2.1      yamt /*	$NetBSD: yp_passwd.c,v 1.36.2.1 2012/04/17 00:09:38 yamt Exp $	*/
      2       1.9   thorpej 
      3       1.1    brezak /*
      4      1.11       tls  * Copyright (c) 1988, 1990, 1993, 1994
      5      1.11       tls  *	The Regents of the University of California.  All rights reserved.
      6       1.1    brezak  *
      7       1.1    brezak  * Redistribution and use in source and binary forms, with or without
      8       1.1    brezak  * modification, are permitted provided that the following conditions
      9       1.1    brezak  * are met:
     10       1.1    brezak  * 1. Redistributions of source code must retain the above copyright
     11       1.1    brezak  *    notice, this list of conditions and the following disclaimer.
     12       1.1    brezak  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.1    brezak  *    notice, this list of conditions and the following disclaimer in the
     14       1.1    brezak  *    documentation and/or other materials provided with the distribution.
     15      1.27       agc  * 3. Neither the name of the University nor the names of its contributors
     16       1.1    brezak  *    may be used to endorse or promote products derived from this software
     17       1.1    brezak  *    without specific prior written permission.
     18       1.1    brezak  *
     19       1.1    brezak  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20       1.1    brezak  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21       1.1    brezak  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22       1.1    brezak  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23       1.1    brezak  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24       1.1    brezak  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25       1.1    brezak  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26       1.1    brezak  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27       1.1    brezak  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28       1.1    brezak  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29       1.1    brezak  * SUCH DAMAGE.
     30       1.1    brezak  */
     31       1.9   thorpej 
     32      1.15     lukem #include <sys/cdefs.h>
     33       1.1    brezak #ifndef lint
     34       1.9   thorpej #if 0
     35      1.11       tls static char sccsid[] = "from:  @(#)local_passwd.c    8.3 (Berkeley) 4/2/94";
     36       1.9   thorpej #else
     37  1.36.2.1      yamt __RCSID("$NetBSD: yp_passwd.c,v 1.36.2.1 2012/04/17 00:09:38 yamt Exp $");
     38       1.9   thorpej #endif
     39       1.1    brezak #endif /* not lint */
     40       1.1    brezak 
     41       1.1    brezak #ifdef	YP
     42       1.1    brezak 
     43      1.15     lukem #include <ctype.h>
     44       1.9   thorpej #include <err.h>
     45      1.15     lukem #include <errno.h>
     46      1.15     lukem #include <netdb.h>
     47      1.15     lukem #include <pwd.h>
     48       1.1    brezak #include <stdio.h>
     49      1.15     lukem #include <stdlib.h>
     50       1.1    brezak #include <string.h>
     51       1.1    brezak #include <time.h>
     52      1.15     lukem #include <unistd.h>
     53      1.30  christos #include <limits.h>
     54      1.30  christos #include <util.h>
     55      1.15     lukem 
     56       1.1    brezak #include <rpc/rpc.h>
     57       1.1    brezak #include <rpcsvc/yp_prot.h>
     58       1.1    brezak #include <rpcsvc/ypclnt.h>
     59      1.15     lukem 
     60      1.15     lukem #include "extern.h"
     61      1.15     lukem 
     62       1.1    brezak #define passwd yp_passwd_rec
     63       1.1    brezak #include <rpcsvc/yppasswd.h>
     64       1.1    brezak #undef passwd
     65       1.4   deraadt 
     66       1.1    brezak #ifndef _PASSWORD_LEN
     67       1.1    brezak #define _PASSWORD_LEN PASS_MAX
     68       1.1    brezak #endif
     69       1.9   thorpej 
     70       1.1    brezak static uid_t uid;
     71      1.31   thorpej static char *domain;
     72       1.1    brezak 
     73      1.36     joerg __dead static void
     74      1.33     lukem pwerror(const char *name, int show_err, int eval)
     75       1.4   deraadt {
     76      1.17       mrg 
     77      1.33     lukem 	if (show_err)
     78      1.18       mrg 		warn("%s", name);
     79      1.31   thorpej 	errx(eval, "NIS passwd database unchanged");
     80      1.31   thorpej }
     81      1.31   thorpej 
     82      1.31   thorpej static char *
     83      1.31   thorpej getnewpasswd(struct passwd *pw, char **old_pass)
     84      1.31   thorpej {
     85      1.31   thorpej 	int tries;
     86      1.33     lukem 	const char *p, *t;
     87      1.33     lukem 	char *result;
     88      1.35  christos 	static char buf[_PASSWORD_LEN + 1];
     89      1.35  christos 	char salt[_PASSWORD_LEN + 1];
     90      1.31   thorpej 	char option[LINE_MAX], *key, *opt;
     91      1.31   thorpej 
     92      1.31   thorpej 	(void)printf("Changing NIS password for %s.\n", pw->pw_name);
     93      1.31   thorpej 
     94      1.31   thorpej 	if (old_pass) {
     95      1.31   thorpej 		*old_pass = NULL;
     96      1.31   thorpej 
     97      1.31   thorpej 		if (pw->pw_passwd[0]) {
     98      1.31   thorpej 			if (strcmp(crypt(p = getpass("Old password:"),
     99      1.35  christos 			    pw->pw_passwd),  pw->pw_passwd)) {
    100      1.31   thorpej 				(void)printf("Sorry.\n");
    101      1.31   thorpej 				pwerror(NULL, 0, 1);
    102      1.31   thorpej 			}
    103      1.31   thorpej 		} else {
    104      1.31   thorpej 			p = "";
    105      1.31   thorpej 		}
    106      1.31   thorpej 
    107      1.31   thorpej 		*old_pass = strdup(p);
    108      1.31   thorpej 		if (!*old_pass) {
    109      1.31   thorpej 			(void)printf("not enough core.\n");
    110      1.31   thorpej 			pwerror(NULL, 0, 1);
    111      1.31   thorpej 		}
    112      1.31   thorpej 	}
    113      1.31   thorpej 	for (buf[0] = '\0', tries = 0;;) {
    114      1.31   thorpej 		p = getpass("New password:");
    115      1.31   thorpej 		if (!*p) {
    116      1.31   thorpej 			(void)printf("Password unchanged.\n");
    117      1.31   thorpej 			pwerror(NULL, 0, 0);
    118      1.31   thorpej 		}
    119      1.31   thorpej 		if (strlen(p) <= 5 && ++tries < 2) {
    120      1.31   thorpej 			(void)printf("Please enter a longer password.\n");
    121      1.31   thorpej 			continue;
    122      1.31   thorpej 		}
    123      1.31   thorpej 		for (t = p; *t && islower((unsigned char)*t); ++t);
    124      1.31   thorpej 		if (!*t && ++tries < 2) {
    125      1.31   thorpej 			(void)printf("Please don't use an all-lower case "
    126      1.35  christos 			    "password.\nUnusual capitalization, "
    127      1.35  christos 			    "control characters or digits are "
    128      1.35  christos 			    "suggested.\n");
    129      1.31   thorpej 			continue;
    130      1.31   thorpej 		}
    131      1.31   thorpej 		(void)strlcpy(buf, p, sizeof(buf));
    132      1.31   thorpej 		if (!strcmp(buf, getpass("Retype new password:")))
    133      1.31   thorpej 			break;
    134      1.31   thorpej 		(void)printf("Mismatch; try again, EOF to quit.\n");
    135      1.31   thorpej 	}
    136      1.31   thorpej 
    137      1.31   thorpej 	pw_getpwconf(option, sizeof(option), pw, "ypcipher");
    138      1.31   thorpej 	opt = option;
    139      1.31   thorpej 	key = strsep(&opt, ",");
    140      1.31   thorpej 	if (pw_gensalt(salt, _PASSWORD_LEN, key, opt) == -1) {
    141      1.31   thorpej 		warn("Couldn't generate salt");
    142      1.31   thorpej 		pwerror(NULL, 0, 0);
    143      1.31   thorpej 	}
    144      1.33     lukem 	result = strdup(crypt(buf, salt));
    145      1.33     lukem 	if (!result) {
    146      1.31   thorpej 		(void)printf("not enough core.\n");
    147      1.31   thorpej 		pwerror(NULL, 0, 0);
    148      1.31   thorpej 	}
    149      1.35  christos 	return result;
    150      1.31   thorpej }
    151      1.31   thorpej 
    152      1.32  christos static void
    153      1.32  christos makeypp(struct yppasswd *ypp, struct passwd *pw)
    154      1.32  christos {
    155      1.32  christos 	/* prompt for new password */
    156      1.32  christos 	ypp->newpw.pw_passwd = getnewpasswd(pw, &ypp->oldpass);
    157      1.32  christos 
    158      1.32  christos 	/* tell rpc.yppasswdd */
    159      1.32  christos 	ypp->newpw.pw_name	= estrdup(pw->pw_name);
    160      1.32  christos 	ypp->newpw.pw_uid 	= pw->pw_uid;
    161      1.32  christos 	ypp->newpw.pw_gid	= pw->pw_gid;
    162      1.32  christos 	ypp->newpw.pw_gecos	= estrdup(pw->pw_gecos);
    163      1.32  christos 	ypp->newpw.pw_dir	= estrdup(pw->pw_dir);
    164      1.32  christos 	ypp->newpw.pw_shell	= estrdup(pw->pw_shell);
    165      1.32  christos }
    166      1.32  christos 
    167      1.31   thorpej static int
    168      1.32  christos ypgetpwnam(const char *nam, struct passwd *pwd)
    169      1.31   thorpej {
    170      1.31   thorpej 	char *val;
    171      1.34  christos 	int reason, vallen, namlen = (int)strlen(nam);
    172      1.35  christos 	int flags;
    173      1.35  christos 	int ok;
    174      1.31   thorpej 
    175      1.35  christos 	flags = ok = 0;
    176      1.31   thorpej 	val = NULL;
    177      1.34  christos 	reason = yp_match(domain, "master.passwd.byname", nam, namlen,
    178      1.35  christos 	    &val, &vallen);
    179      1.34  christos 	if (reason == YPERR_MAP) {
    180      1.34  christos 		reason = yp_match(domain, "passwd.byname", nam, namlen,
    181      1.35  christos 		    &val, &vallen);
    182      1.34  christos 		flags = _PASSWORD_OLDFMT;
    183      1.34  christos 	}
    184      1.32  christos 	if (reason != 0)
    185      1.32  christos 		goto out;
    186      1.32  christos 
    187      1.32  christos 	if (pw_scan(val, pwd, &flags) == 0)
    188      1.32  christos 		goto out;
    189      1.32  christos 
    190      1.32  christos 	ok = 1;
    191      1.34  christos 	val = NULL;	/* Don't free the memory, it is still in use */
    192      1.32  christos out:
    193      1.32  christos 	if (val)
    194      1.32  christos 		free(val);
    195      1.32  christos 	return ok;
    196      1.31   thorpej }
    197      1.31   thorpej 
    198      1.31   thorpej #ifdef USE_PAM
    199      1.31   thorpej 
    200      1.31   thorpej void
    201      1.31   thorpej pwyp_usage(const char *prefix)
    202      1.31   thorpej {
    203      1.31   thorpej 
    204      1.35  christos 	(void)fprintf(stderr, "%s %s [-d nis | -y] [user]\n",
    205      1.31   thorpej 	    prefix, getprogname());
    206      1.31   thorpej }
    207      1.31   thorpej 
    208      1.31   thorpej void
    209      1.31   thorpej pwyp_argv0_usage(const char *prefix)
    210      1.31   thorpej {
    211      1.31   thorpej 
    212      1.35  christos 	(void)fprintf(stderr, "%s %s [user]\n",
    213      1.31   thorpej 	    prefix, getprogname());
    214      1.31   thorpej }
    215      1.31   thorpej 
    216      1.31   thorpej void
    217      1.31   thorpej pwyp_process(const char *username, int argc, char **argv)
    218      1.31   thorpej {
    219      1.31   thorpej 	char *master;
    220      1.31   thorpej 	int ch, r, rpcport, status;
    221      1.35  christos 	enum clnt_stat yr;
    222      1.32  christos 	struct yppasswd ypp;
    223      1.34  christos 	struct passwd pwb, pwb2, *pw;
    224      1.32  christos 	char pwbuf[1024];
    225      1.31   thorpej 	struct timeval tv;
    226      1.31   thorpej 	CLIENT *client;
    227      1.31   thorpej 
    228      1.31   thorpej 	while ((ch = getopt(argc, argv, "y")) != -1) {
    229      1.31   thorpej 		switch (ch) {
    230      1.31   thorpej 		case 'y':
    231      1.31   thorpej 			/*
    232      1.31   thorpej 			 * Abosrb the -y that may have gotten us here.
    233      1.31   thorpej 			 */
    234      1.31   thorpej 			break;
    235      1.31   thorpej 
    236      1.31   thorpej 		default:
    237      1.31   thorpej 			usage();
    238      1.31   thorpej 			/* NOTREACHED */
    239      1.31   thorpej 		}
    240      1.31   thorpej 	}
    241      1.31   thorpej 
    242      1.31   thorpej 	argc -= optind;
    243      1.31   thorpej 	argv += optind;
    244      1.31   thorpej 
    245      1.31   thorpej 	switch (argc) {
    246      1.31   thorpej 	case 0:
    247      1.31   thorpej 		/* username already provided */
    248      1.31   thorpej 		break;
    249      1.31   thorpej 	case 1:
    250      1.31   thorpej 		username = argv[0];
    251      1.31   thorpej 		break;
    252      1.31   thorpej 	default:
    253      1.31   thorpej 		usage();
    254      1.35  christos 		/*NOTREACHED*/
    255      1.31   thorpej 	}
    256      1.31   thorpej 
    257      1.31   thorpej 	if (_yp_check(NULL) == 0) {
    258      1.31   thorpej 		/* can't use YP. */
    259      1.35  christos 		errx(EXIT_FAILURE, "NIS not in use.");
    260      1.31   thorpej 	}
    261      1.31   thorpej 
    262      1.31   thorpej 	uid = getuid();
    263      1.31   thorpej 
    264      1.31   thorpej 	/*
    265      1.31   thorpej 	 * Get local domain
    266      1.31   thorpej 	 */
    267      1.31   thorpej 	if ((r = yp_get_default_domain(&domain)) != 0)
    268      1.35  christos 		errx(EXIT_FAILURE, "Can't get local NIS domain (%s)",
    269      1.31   thorpej 		    yperr_string(r));
    270      1.31   thorpej 
    271      1.31   thorpej 	/*
    272      1.31   thorpej 	 * Find the host for the passwd map; it should be running
    273      1.31   thorpej 	 * the daemon.
    274      1.31   thorpej 	 */
    275      1.31   thorpej 	if ((r = yp_master(domain, "passwd.byname", &master)) != 0)
    276      1.35  christos 		errx(EXIT_FAILURE, "Can't find the master NIS server (%s)",
    277      1.31   thorpej 		    yperr_string(r));
    278      1.31   thorpej 
    279      1.31   thorpej 	/*
    280      1.31   thorpej 	 * Ask the portmapper for the port of the daemon.
    281      1.31   thorpej 	 */
    282      1.31   thorpej 	if ((rpcport = getrpcport(master, YPPASSWDPROG,
    283      1.31   thorpej 	    YPPASSWDPROC_UPDATE, IPPROTO_UDP)) == 0)
    284      1.35  christos 		errx(EXIT_FAILURE, "Master NIS server not running yppasswd "
    285      1.35  christos 		    "daemon");
    286      1.31   thorpej 
    287      1.31   thorpej 	/*
    288      1.31   thorpej 	 * Be sure the port is privileged
    289      1.31   thorpej 	 */
    290      1.31   thorpej 	if (rpcport >= IPPORT_RESERVED)
    291      1.35  christos 		errx(EXIT_FAILURE, "Yppasswd daemon is on an invalid port");
    292      1.31   thorpej 
    293      1.31   thorpej 	/* Bail out if this is a local (non-yp) user, */
    294      1.31   thorpej 	/* then get user's login identity */
    295      1.34  christos 	if (!ypgetpwnam(username, &pwb) ||
    296      1.34  christos 	    getpwnam_r(username, &pwb2, pwbuf, sizeof(pwbuf), &pw) ||
    297      1.32  christos 	    pw == NULL)
    298      1.35  christos 		errx(EXIT_FAILURE, "NIS unknown user %s", username);
    299      1.31   thorpej 
    300      1.35  christos 	if (uid && uid != pwb.pw_uid) {
    301      1.35  christos 		errno = EACCES;
    302      1.35  christos 		err(EXIT_FAILURE, "You may only change your own password");
    303      1.35  christos 	}
    304      1.31   thorpej 
    305      1.34  christos 	makeypp(&ypp, &pwb);
    306      1.31   thorpej 
    307      1.31   thorpej 	client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp");
    308      1.31   thorpej 	if (client == NULL)
    309      1.35  christos 		errx(EXIT_FAILURE, "Cannot contact yppasswdd on %s (%s)",
    310      1.31   thorpej 		    master, yperr_string(YPERR_YPBIND));
    311      1.31   thorpej 
    312      1.31   thorpej 	client->cl_auth = authunix_create_default();
    313      1.31   thorpej 	tv.tv_sec = 2;
    314      1.31   thorpej 	tv.tv_usec = 0;
    315      1.35  christos 	yr = clnt_call(client, YPPASSWDPROC_UPDATE,
    316      1.32  christos 	    xdr_yppasswd, &ypp, xdr_int, &status, tv);
    317      1.35  christos 	if (yr != RPC_SUCCESS)
    318      1.35  christos 		errx(EXIT_FAILURE, "RPC to yppasswdd failed (%s)",
    319      1.35  christos 		    clnt_sperrno(yr));
    320      1.31   thorpej 	else if (status)
    321      1.31   thorpej 		printf("Couldn't change NIS password.\n");
    322      1.31   thorpej 	else
    323      1.31   thorpej 		printf("The NIS password has been changed on %s, %s\n",
    324      1.31   thorpej 		    master, "the master NIS passwd server.");
    325       1.4   deraadt }
    326       1.4   deraadt 
    327      1.31   thorpej #else /* ! USE_PAM */
    328      1.31   thorpej 
    329      1.31   thorpej static	int yflag;
    330      1.31   thorpej 
    331      1.22     aidan int
    332  1.36.2.1      yamt yp_init(const char *progname)
    333      1.22     aidan {
    334      1.22     aidan 	int yppwd;
    335      1.22     aidan 
    336      1.22     aidan 	if (strcmp(progname, "yppasswd") == 0) {
    337      1.22     aidan 		yppwd = 1;
    338      1.22     aidan 	} else
    339      1.22     aidan 		yppwd = 0;
    340      1.22     aidan 	yflag = 0;
    341      1.22     aidan 	if (_yp_check(NULL) == 0) {
    342      1.22     aidan 		/* can't use YP. */
    343      1.22     aidan 		if (yppwd)
    344      1.35  christos 			errx(EXIT_FAILURE, "NIS not in use");
    345      1.35  christos 		return -1;
    346      1.22     aidan 	}
    347      1.35  christos 	return 0;
    348      1.22     aidan }
    349      1.22     aidan 
    350      1.22     aidan int
    351      1.35  christos yp_arg(char ch, const char *arg)
    352      1.22     aidan {
    353      1.22     aidan 	switch (ch) {
    354      1.22     aidan 	case 'y':
    355      1.22     aidan 		yflag = 1;
    356      1.22     aidan 		break;
    357      1.22     aidan 	default:
    358      1.35  christos 		return 0;
    359      1.22     aidan 	}
    360      1.35  christos 	return 1;
    361      1.22     aidan }
    362      1.22     aidan 
    363      1.22     aidan int
    364      1.35  christos yp_arg_end(void)
    365      1.16        tv {
    366      1.22     aidan 	if (yflag)
    367      1.35  christos 		return PW_USE_FORCE;
    368      1.35  christos 	return PW_USE;
    369      1.22     aidan }
    370      1.17       mrg 
    371      1.22     aidan void
    372      1.35  christos yp_end(void)
    373      1.22     aidan {
    374      1.22     aidan 	/* NOOP */
    375      1.16        tv }
    376      1.16        tv 
    377       1.9   thorpej int
    378      1.35  christos yp_chpw(const char *username)
    379       1.1    brezak {
    380       1.4   deraadt 	char *master;
    381       1.4   deraadt 	int r, rpcport, status;
    382      1.35  christos 	enum clnt_stat yr;
    383      1.32  christos 	struct yppasswd ypp;
    384      1.32  christos 	struct passwd *pw, pwb;
    385      1.32  christos 	char pwbuf[1024];
    386       1.1    brezak 	struct timeval tv;
    387       1.1    brezak 	CLIENT *client;
    388      1.21       mjl 
    389       1.4   deraadt 	uid = getuid();
    390       1.4   deraadt 
    391       1.4   deraadt 	/*
    392       1.4   deraadt 	 * Get local domain
    393       1.4   deraadt 	 */
    394      1.22     aidan 	if ((r = yp_get_default_domain(&domain)) != 0)
    395      1.35  christos 		errx(EXIT_FAILURE, "can't get local NIS domain.  Reason: %s",
    396       1.9   thorpej 		    yperr_string(r));
    397       1.4   deraadt 
    398       1.4   deraadt 	/*
    399       1.4   deraadt 	 * Find the host for the passwd map; it should be running
    400       1.4   deraadt 	 * the daemon.
    401       1.4   deraadt 	 */
    402      1.16        tv 	if ((r = yp_master(domain, "passwd.byname", &master)) != 0) {
    403      1.31   thorpej 		warnx("can't find the master NIS server.  Reason: %s",
    404       1.9   thorpej 		    yperr_string(r));
    405      1.22     aidan 		/* continuation */
    406      1.35  christos 		return -1;
    407      1.16        tv 	}
    408       1.1    brezak 
    409       1.4   deraadt 	/*
    410       1.4   deraadt 	 * Ask the portmapper for the port of the daemon.
    411       1.4   deraadt 	 */
    412       1.4   deraadt 	if ((rpcport = getrpcport(master, YPPASSWDPROG,
    413      1.10   thorpej 	    YPPASSWDPROC_UPDATE, IPPROTO_UDP)) == 0) {
    414      1.35  christos 		warnx("Master NIS server not running yppasswd daemon");
    415      1.22     aidan 		/* continuation */
    416      1.35  christos 		return -1;
    417      1.10   thorpej 	}
    418       1.1    brezak 
    419       1.4   deraadt 	/*
    420      1.20    simonb 	 * Be sure the port is privileged
    421       1.4   deraadt 	 */
    422       1.9   thorpej 	if (rpcport >= IPPORT_RESERVED)
    423      1.35  christos 		errx(EXIT_FAILURE, "Yppasswd daemon is on an invalid port");
    424       1.4   deraadt 
    425      1.21       mjl 	/* Bail out if this is a local (non-yp) user, */
    426      1.21       mjl 	/* then get user's login identity */
    427      1.32  christos 	if (!ypgetpwnam(username, pw = &pwb) ||
    428      1.32  christos 	    getpwnam_r(username, &pwb, pwbuf, sizeof(pwbuf), &pw) ||
    429      1.32  christos 	    pw == NULL) {
    430      1.31   thorpej 		warnx("NIS unknown user %s", username);
    431      1.22     aidan 		/* continuation */
    432      1.35  christos 		return -1;
    433      1.16        tv 	}
    434       1.9   thorpej 
    435      1.35  christos 	if (uid && uid != pw->pw_uid) {
    436      1.35  christos 		errno = EACCES;
    437      1.35  christos 		err(EXIT_FAILURE, "You may only change your own password");
    438      1.35  christos 	}
    439       1.1    brezak 
    440      1.32  christos 	makeypp(&ypp, pw);
    441      1.16        tv 
    442       1.4   deraadt 	client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp");
    443      1.17       mrg 	if (client == NULL) {
    444      1.35  christos 		warnx("Cannot contact yppasswdd on %s (%s)",
    445       1.5   deraadt 		    master, yperr_string(YPERR_YPBIND));
    446      1.35  christos 		return YPERR_YPBIND;
    447       1.4   deraadt 	}
    448       1.9   thorpej 
    449       1.4   deraadt 	client->cl_auth = authunix_create_default();
    450       1.4   deraadt 	tv.tv_sec = 2;
    451       1.4   deraadt 	tv.tv_usec = 0;
    452      1.35  christos 	yr = clnt_call(client, YPPASSWDPROC_UPDATE,
    453      1.32  christos 	    xdr_yppasswd, &ypp, xdr_int, &status, tv);
    454      1.35  christos 	if (yr != RPC_SUCCESS)
    455      1.35  christos 		errx(EXIT_FAILURE, "RPC to yppasswdd failed (%s)",
    456      1.35  christos 		    clnt_sperrno(yr));
    457       1.4   deraadt 	else if (status)
    458      1.31   thorpej 		printf("Couldn't change NIS password.\n");
    459       1.4   deraadt 	else
    460      1.31   thorpej 		printf("The NIS password has been changed on %s, %s\n",
    461      1.31   thorpej 		    master, "the master NIS passwd server.");
    462      1.35  christos 	return 0;
    463       1.1    brezak }
    464       1.1    brezak 
    465      1.31   thorpej #endif /* USE_PAM */
    466       1.1    brezak 
    467       1.1    brezak #endif	/* YP */
    468