passwd.c revision 6067
11590Srgrimes/*
21590Srgrimes * Copyright (c) 1988, 1993, 1994
31590Srgrimes *	The Regents of the University of California.  All rights reserved.
41590Srgrimes *
51590Srgrimes * Redistribution and use in source and binary forms, with or without
61590Srgrimes * modification, are permitted provided that the following conditions
71590Srgrimes * are met:
81590Srgrimes * 1. Redistributions of source code must retain the above copyright
91590Srgrimes *    notice, this list of conditions and the following disclaimer.
101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111590Srgrimes *    notice, this list of conditions and the following disclaimer in the
121590Srgrimes *    documentation and/or other materials provided with the distribution.
131590Srgrimes * 3. All advertising materials mentioning features or use of this software
141590Srgrimes *    must display the following acknowledgement:
151590Srgrimes *	This product includes software developed by the University of
161590Srgrimes *	California, Berkeley and its contributors.
171590Srgrimes * 4. Neither the name of the University nor the names of its contributors
181590Srgrimes *    may be used to endorse or promote products derived from this software
191590Srgrimes *    without specific prior written permission.
201590Srgrimes *
211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311590Srgrimes * SUCH DAMAGE.
321590Srgrimes */
331590Srgrimes
341590Srgrimes#ifndef lint
351590Srgrimesstatic char copyright[] =
361590Srgrimes"@(#) Copyright (c) 1988, 1993, 1994\n\
371590Srgrimes	The Regents of the University of California.  All rights reserved.\n";
381590Srgrimes#endif /* not lint */
391590Srgrimes
401590Srgrimes#ifndef lint
415752Swollmanstatic char sccsid[] = "From: @(#)passwd.c	8.3 (Berkeley) 4/2/94";
425752Swollmanstatic const char rcsid[] =
436067Swpaul	"$Id: passwd.c,v 1.2 1995/01/20 22:03:36 wollman Exp $";
441590Srgrimes#endif /* not lint */
451590Srgrimes
461590Srgrimes#include <err.h>
471590Srgrimes#include <errno.h>
481590Srgrimes#include <stdio.h>
491590Srgrimes#include <stdlib.h>
501590Srgrimes#include <unistd.h>
511590Srgrimes
526067Swpaul#ifdef YP
536067Swpaul#include <pwd.h>
546067Swpaul#include <limits.h>
556067Swpaul#include <db.h>
566067Swpaul#include <fcntl.h>
576067Swpaul#include <utmp.h>
586067Swpaul#include <sys/types.h>
596067Swpaul#include <sys/stat.h>
606067Swpaul#include <sys/param.h>
616067Swpaul#endif
626067Swpaul
635752Swollman#ifdef KERBEROS
645752Swollman#include "krb.h"
655752Swollman#endif
665752Swollman
671590Srgrimes#include "extern.h"
681590Srgrimes
691590Srgrimesvoid	usage __P((void));
701590Srgrimes
715752Swollmanint use_local_passwd = 0;
721590Srgrimes
736067Swpaul#ifdef YP
746067Swpaul#define PERM_SECURE (S_IRUSR|S_IWUSR)
756067Swpaulint use_yp_passwd = 0, opt_shell = 0, opt_fullname = 0;
766067Swpaulchar *prog_name;
776067SwpaulHASHINFO openinfo = {
786067Swpaul        4096,           /* bsize */
796067Swpaul        32,             /* ffactor */
806067Swpaul        256,            /* nelem */
816067Swpaul        2048 * 1024,    /* cachesize */
826067Swpaul        NULL,           /* hash */
836067Swpaul        0,              /* lorder */
846067Swpaul};
856067Swpaul#endif
866067Swpaul
871590Srgrimesint
881590Srgrimesmain(argc, argv)
891590Srgrimes	int argc;
901590Srgrimes	char **argv;
911590Srgrimes{
921590Srgrimes	int ch;
931590Srgrimes	char *uname;
945752Swollman	char *iflag = 0, *rflag = 0, *uflag = 0;
951590Srgrimes
966067Swpaul#ifdef YP
975752Swollman#ifdef KERBEROS
985752Swollman	char realm[REALM_SZ];
996067Swpaul#define OPTIONS "lysfi:r:u:"
1006067Swpaul#else
1016067Swpaul#define OPTIONS "lysf"
1026067Swpaul#endif
1036067Swpaul#else
1046067Swpaul#ifdef KERBEROS
1056067Swpaul	char realm[REALM_SZ];
1065752Swollman#define OPTIONS "li:r:u:"
1075752Swollman#else
1085752Swollman#define OPTIONS "l"
1095752Swollman#endif
1106067Swpaul#endif
1116067Swpaul
1126067Swpaul#ifdef YP
1136067Swpaul	DB *dbp;
1146067Swpaul	DBT key,data;
1156067Swpaul	char bf[UT_NAMESIZE + 2];
1166067Swpaul
1176067Swpaul	if (strstr(argv[0], (prog_name = "ypchpass")))
1186067Swpaul		use_yp_passwd = opt_shell = opt_fullname = 1;
1196067Swpaul	if (strstr(argv[0], (prog_name = "ypchsh"))) opt_shell = 1;
1206067Swpaul	if (strstr(argv[0], (prog_name = "ypchfn"))) opt_fullname = 1;
1216067Swpaul	if (strstr(argv[0], (prog_name = "yppasswd"))) use_yp_passwd = 1;
1226067Swpaul#endif
1236067Swpaul
1245752Swollman	while ((ch = getopt(argc, argv, OPTIONS)) != EOF) {
1251590Srgrimes		switch (ch) {
1261590Srgrimes		case 'l':		/* change local password file */
1275752Swollman			use_local_passwd = 1;
1281590Srgrimes			break;
1295752Swollman#ifdef KERBEROS
1305752Swollman		case 'i':
1315752Swollman			iflag = optarg;
1325752Swollman			break;
1335752Swollman		case 'r':
1345752Swollman			rflag = optarg;
1355752Swollman			break;
1365752Swollman		case 'u':
1375752Swollman			uflag = optarg;
1385752Swollman			break;
1395752Swollman#endif /* KERBEROS */
1406067Swpaul#ifdef	YP
1416067Swpaul		case 'y':			/* Change NIS password */
1426067Swpaul			use_yp_passwd = 1;
1436067Swpaul			break;
1446067Swpaul		case 's':			/* Change NIS shell field */
1456067Swpaul			opt_shell = 1;
1466067Swpaul			break;
1476067Swpaul		case 'f':			/* Change NIS GECOS field */
1486067Swpaul			opt_fullname = 1;
1496067Swpaul			break;
1506067Swpaul#endif
1511590Srgrimes		default:
1521590Srgrimes		case '?':
1531590Srgrimes			usage();
1541590Srgrimes		}
1555752Swollman	}
1561590Srgrimes
1571590Srgrimes	argc -= optind;
1581590Srgrimes	argv += optind;
1591590Srgrimes
1601590Srgrimes	if ((uname = getlogin()) == NULL)
1611590Srgrimes		err(1, "getlogin");
1621590Srgrimes
1631590Srgrimes	switch(argc) {
1641590Srgrimes	case 0:
1651590Srgrimes		break;
1661590Srgrimes	case 1:
1671590Srgrimes		uname = argv[0];
1681590Srgrimes		break;
1691590Srgrimes	default:
1701590Srgrimes		usage();
1711590Srgrimes	}
1721590Srgrimes
1736067Swpaul#ifdef YP
1746067Swpaul	/*
1756067Swpaul	 * If the user isn't in the local database file, he must
1766067Swpaul	 * be in the NIS database.
1776067Swpaul	 */
1786067Swpaul#ifdef KERBEROS
1796067Swpaul	if (!use_yp_passwd && !opt_shell && !opt_fullname &&
1806067Swpaul		iflag == NULL && rflag == NULL && uflag == NULL) {
1816067Swpaul#else
1826067Swpaul	if (!use_yp_passwd && !opt_shell && !opt_fullname) {
1836067Swpaul#endif
1846067Swpaul		if ((dbp = dbopen(_PATH_MP_DB, O_RDONLY, PERM_SECURE,
1856067Swpaul				DB_HASH, &openinfo)) == NULL)
1866067Swpaul			errx(1, "error opening database: %s.", _PATH_MP_DB);
1876067Swpaul
1886067Swpaul		bf[0] = _PW_KEYBYNAME;
1896067Swpaul		bcopy(uname, bf + 1, MIN(strlen(uname), UT_NAMESIZE));
1906067Swpaul		key.data = (u_char *)bf;
1916067Swpaul		key.size = strlen(uname) + 1;
1926067Swpaul		if ((dbp->get)(dbp,&key,&data,0))
1936067Swpaul			use_yp_passwd = 1;
1946067Swpaul		(dbp->close)(dbp);
1956067Swpaul	}
1966067Swpaul
1976067Swpaul	if (!use_local_passwd && (use_yp_passwd || opt_shell || opt_fullname))
1986067Swpaul		exit(yp_passwd(uname));
1996067Swpaul#endif
2006067Swpaul
2015752Swollman	if (!use_local_passwd) {
2021590Srgrimes#ifdef	KERBEROS
2035752Swollman		if(krb_get_lrealm(realm, 0) == KSUCCESS) {
2045752Swollman			fprintf(stderr, "realm %s\n", realm);
2055752Swollman			exit(krb_passwd(argv[0], iflag, rflag, uflag));
2065752Swollman		}
2071590Srgrimes#endif
2085752Swollman	}
2096067Swpaul#ifdef YP
2106067Swpaul	if (use_local_passwd && use_yp_passwd)
2116067Swpaul		errx(1,"unknown local user: %s.",uname);
2126067Swpaul#endif
2131590Srgrimes	exit(local_passwd(uname));
2141590Srgrimes}
2151590Srgrimes
2161590Srgrimesvoid
2171590Srgrimesusage()
2181590Srgrimes{
2191590Srgrimes
2206067Swpaul#ifdef	YP
2211590Srgrimes#ifdef	KERBEROS
2225752Swollman	fprintf(stderr,
2236067Swpaul	 "usage: passwd [-l] [-i instance] [-r realm] [-u fullname]\n");
2246067Swpaul	fprintf(stderr,
2256067Swpaul	"        [-l] [-y] [-f] [-s] [user]\n");
2266067Swpaul#else
2276067Swpaul	(void)fprintf(stderr, "usage: passwd [-y] [-f] [-s] [user] \n");
2286067Swpaul#endif
2296067Swpaul#else
2306067Swpaul#ifdef	KERBEROS
2316067Swpaul	fprintf(stderr,
2325752Swollman	 "usage: passwd [-l] [-i instance] [-r realm] [-u fullname] [user]\n");
2331590Srgrimes#else
2341590Srgrimes	(void)fprintf(stderr, "usage: passwd user\n");
2351590Srgrimes#endif
2366067Swpaul#endif
2371590Srgrimes	exit(1);
2381590Srgrimes}
239