11553Srgrimes/*
21553Srgrimes * Copyright (c) 1988, 1993, 1994
31553Srgrimes *	The Regents of the University of California.  All rights reserved.
41553Srgrimes *
51553Srgrimes * Redistribution and use in source and binary forms, with or without
61553Srgrimes * modification, are permitted provided that the following conditions
71553Srgrimes * are met:
81553Srgrimes * 1. Redistributions of source code must retain the above copyright
91553Srgrimes *    notice, this list of conditions and the following disclaimer.
101553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111553Srgrimes *    notice, this list of conditions and the following disclaimer in the
121553Srgrimes *    documentation and/or other materials provided with the distribution.
131553Srgrimes * 3. All advertising materials mentioning features or use of this software
141553Srgrimes *    must display the following acknowledgement:
151553Srgrimes *	This product includes software developed by the University of
161553Srgrimes *	California, Berkeley and its contributors.
171553Srgrimes * 4. Neither the name of the University nor the names of its contributors
181553Srgrimes *    may be used to endorse or promote products derived from this software
191553Srgrimes *    without specific prior written permission.
201553Srgrimes *
211553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241553Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2815733Sjoerg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2950479Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3015733Sjoerg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311553Srgrimes * SUCH DAMAGE.
321553Srgrimes */
3379537Sru
341553Srgrimes#ifndef lint
351553Srgrimesstatic const char copyright[] =
361553Srgrimes"@(#) Copyright (c) 1988, 1993, 1994\n\
371553Srgrimes	The Regents of the University of California.  All rights reserved.\n";
3868965Sru#endif /* not lint */
391553Srgrimes
401553Srgrimes#ifndef lint
411553Srgrimes#if 0
421553Srgrimesstatic char sccsid[] = "@(#)passwd.c	8.3 (Berkeley) 4/2/94";
4353956Sache#endif
441553Srgrimesstatic const char rcsid[] =
451553Srgrimes  "$FreeBSD$";
4661913Swollman#endif /* not lint */
4715733Sjoerg
481553Srgrimes#include <sys/types.h>
4962177Swollman
501553Srgrimes#include <err.h>
511553Srgrimes#include <errno.h>
521553Srgrimes#include <libutil.h>
5395127Scharnier#include <stdio.h>
5495127Scharnier#include <stdlib.h>
5595127Scharnier#include <string.h>
56131500Sru#include <unistd.h>
57131500Sru
581553Srgrimes#ifdef YP
591553Srgrimes#include <pwd.h>
6057673Ssheldonh#include <pw_yp.h>
6157673Ssheldonh#include <rpcsvc/yp.h>
621553Srgrimesint __use_yp = 0;
6362177Swollmanint yp_errno = YP_TRUE;
6462177Swollmanextern int yp_passwd( char * );
6562177Swollman#endif
661553Srgrimes
671553Srgrimes#include "extern.h"
6862177Swollman
6962177Swollmanstatic void usage(void);
7062177Swollman
7162177Swollmanint use_local_passwd = 0;
7262177Swollman
731553Srgrimesint
741553Srgrimesmain(argc, argv)
751553Srgrimes	int argc;
761553Srgrimes	char **argv;
771553Srgrimes{
781553Srgrimes	int ch;
791553Srgrimes	char *uname;
801553Srgrimes
8162177Swollman#ifdef YP
8262177Swollman#define OPTIONS "d:h:lysfo"
8362177Swollman#else
8462177Swollman#define OPTIONS "l"
8562177Swollman#endif
8662177Swollman
8762177Swollman#ifdef YP
8862177Swollman	int res = 0;
8962177Swollman
9062177Swollman	if (strstr(argv[0], "yppasswd")) __use_yp = 1;
9162177Swollman#endif
9262177Swollman
9362177Swollman	while ((ch = getopt(argc, argv, OPTIONS)) != -1) {
9462177Swollman		switch (ch) {
9562177Swollman		case 'l':		/* change local password file */
9662177Swollman			use_local_passwd = 1;
9762177Swollman			break;
9862177Swollman#ifdef	YP
991553Srgrimes		case 'y':			/* Change NIS password */
1001553Srgrimes			__use_yp = 1;
1011553Srgrimes			break;
1021553Srgrimes		case 'd':			/* Specify NIS domain. */
1031553Srgrimes#ifdef PARANOID
10462177Swollman			if (!getuid()) {
10562177Swollman#endif
10662177Swollman				yp_domain = optarg;
10762177Swollman				if (yp_server == NULL)
10862177Swollman					yp_server = "localhost";
1091553Srgrimes#ifdef PARANOID
1101553Srgrimes			} else {
1111553Srgrimes				warnx("only the super-user may use the -d flag");
1121553Srgrimes			}
1131553Srgrimes#endif
1141553Srgrimes			break;
1151553Srgrimes		case 'h':			/* Specify NIS server. */
1161553Srgrimes#ifdef PARANOID
1171553Srgrimes			if (!getuid()) {
118131500Sru#endif
119131500Sru				yp_server = optarg;
1201553Srgrimes#ifdef PARANOID
1211553Srgrimes			} else {
1221553Srgrimes				warnx("only the super-user may use the -h flag");
1231553Srgrimes			}
1241553Srgrimes#endif
1251553Srgrimes			break;
1261553Srgrimes		case 'o':
1271553Srgrimes			force_old++;
1281553Srgrimes			break;
1291553Srgrimes#endif
1301553Srgrimes		default:
1311553Srgrimes		case '?':
1321553Srgrimes			usage();
1331553Srgrimes		}
134131500Sru	}
135131500Sru
1361553Srgrimes	argc -= optind;
1371553Srgrimes	argv += optind;
1381553Srgrimes
139131531Sru	if ((uname = getlogin()) == NULL)
1401553Srgrimes		err(1, "getlogin");
141131500Sru
142131500Sru	switch(argc) {
1431553Srgrimes	case 0:
1441553Srgrimes		break;
1451553Srgrimes	case 1:
1461553Srgrimes		uname = argv[0];
1471553Srgrimes		break;
1481553Srgrimes	default:
1491553Srgrimes		usage();
1501553Srgrimes	}
151131500Sru
152131500Sru#ifdef YP
1531553Srgrimes	/*
1541553Srgrimes	 * If NIS is turned on in the password database, use it, else punt.
1551553Srgrimes	 */
1561553Srgrimes	res = use_yp(uname, 0, 0);
157131531Sru	if (res == USER_YP_ONLY) {
158131531Sru		if (!use_local_passwd) {
1591553Srgrimes			exit(yp_passwd(uname));
1601553Srgrimes		} else {
1611553Srgrimes			/*
1621553Srgrimes			 * Reject -l flag if NIS is turned on and the user
16357673Ssheldonh			 * doesn't exist in the local password database.
16457673Ssheldonh			 */
1651553Srgrimes			errx(1, "unknown local user: %s", uname);
1661553Srgrimes		}
1671553Srgrimes	} else if (res == USER_LOCAL_ONLY) {
16871102Sru		/*
16971102Sru		 * Reject -y flag if user only exists locally.
1701553Srgrimes		 */
1711553Srgrimes		if (__use_yp)
1721553Srgrimes			errx(1, "unknown NIS user: %s", uname);
1731553Srgrimes	} else if (res == USER_YP_AND_LOCAL) {
174131531Sru		if (!use_local_passwd && (yp_in_pw_file || __use_yp))
1751553Srgrimes			exit(yp_passwd(uname));
1761553Srgrimes	}
1771553Srgrimes#endif
1781553Srgrimes
1791553Srgrimes	exit(local_passwd(uname));
1801553Srgrimes}
1811553Srgrimes
182131500Srustatic void
183131500Sruusage()
1841553Srgrimes{
1851553Srgrimes
1861553Srgrimes#ifdef	YP
1871553Srgrimes	(void)fprintf(stderr,
1881553Srgrimes		"usage: passwd [-l] [-y] [-o] [-d domain [-h host]] [user]\n");
189131531Sru#else
1901553Srgrimes	(void)fprintf(stderr, "usage: passwd [-l] user\n");
1911553Srgrimes#endif
1921553Srgrimes	exit(1);
1931553Srgrimes}
1941553Srgrimes