passwd.c revision 40102
1/*
2 * Copyright (c) 1988, 1993, 1994
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static const char copyright[] =
36"@(#) Copyright (c) 1988, 1993, 1994\n\
37	The Regents of the University of California.  All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41#if 0
42static char sccsid[] = "@(#)passwd.c	8.3 (Berkeley) 4/2/94";
43#endif
44static const char rcsid[] =
45	"$Id: passwd.c,v 1.14 1998/03/23 14:14:24 bde Exp $";
46#endif /* not lint */
47
48#include <sys/types.h>
49
50#include <err.h>
51#include <errno.h>
52#include <libutil.h>
53#include <stdio.h>
54#include <stdlib.h>
55#include <string.h>
56#include <unistd.h>
57
58#ifdef YP
59#include <pwd.h>
60#include <pw_yp.h>
61#include <rpcsvc/yp.h>
62int __use_yp = 0;
63int yp_errno = YP_TRUE;
64extern int yp_passwd	__P(( char * ));
65#endif
66
67#ifdef KERBEROS
68#include "krb.h"
69#endif
70
71#include "extern.h"
72
73static void usage __P((void));
74
75int use_local_passwd = 0;
76
77int
78main(argc, argv)
79	int argc;
80	char **argv;
81{
82	int ch;
83	char *uname;
84#ifdef KERBEROS
85	char *iflag = 0, *rflag = 0, *uflag = 0;
86	char *k;
87#endif
88
89#ifdef YP
90#ifdef KERBEROS
91	char realm[REALM_SZ];
92#define OPTIONS "d:h:lysfoi:r:u:"
93#else
94#define OPTIONS "d:h:lysfo"
95#endif
96#else
97#ifdef KERBEROS
98	char realm[REALM_SZ];
99#define OPTIONS "li:r:u:"
100#else
101#define OPTIONS "l"
102#endif
103#endif
104
105#ifdef YP
106	int res = 0;
107
108	if (strstr(argv[0], "yppasswd")) __use_yp = 1;
109#endif
110
111	while ((ch = getopt(argc, argv, OPTIONS)) != -1) {
112		switch (ch) {
113		case 'l':		/* change local password file */
114			use_local_passwd = 1;
115			break;
116#ifdef KERBEROS
117		case 'i':
118			iflag = optarg;
119			break;
120		case 'r':
121			rflag = optarg;
122			break;
123		case 'u':
124			uflag = optarg;
125			break;
126#endif /* KERBEROS */
127#ifdef	YP
128		case 'y':			/* Change NIS password */
129			__use_yp = 1;
130			break;
131		case 'd':			/* Specify NIS domain. */
132#ifdef PARANOID
133			if (!getuid()) {
134#endif
135				yp_domain = optarg;
136				if (yp_server == NULL)
137					yp_server = "localhost";
138#ifdef PARANOID
139			} else {
140				warnx("only the super-user may use the -d flag");
141			}
142#endif
143			break;
144		case 'h':			/* Specify NIS server. */
145#ifdef PARANOID
146			if (!getuid()) {
147#endif
148				yp_server = optarg;
149#ifdef PARANOID
150			} else {
151				warnx("only the super-user may use the -h flag");
152			}
153#endif
154			break;
155		case 'o':
156			force_old++;
157			break;
158#endif
159		default:
160		case '?':
161			usage();
162		}
163	}
164
165	argc -= optind;
166	argv += optind;
167
168	if ((uname = getlogin()) == NULL)
169		err(1, "getlogin");
170
171	switch(argc) {
172	case 0:
173		break;
174	case 1:
175		uname = argv[0];
176		break;
177	default:
178		usage();
179	}
180
181#ifdef YP
182	/*
183	 * If NIS is turned on in the password database, use it, else punt.
184	 */
185#ifdef KERBEROS
186	if (__use_yp || (iflag == NULL && rflag == NULL && uflag == NULL)) {
187#endif
188		res = use_yp(uname, 0, 0);
189		if (res == USER_YP_ONLY) {
190			if (!use_local_passwd) {
191				exit(yp_passwd(uname));
192			} else {
193			/*
194			 * Reject -l flag if NIS is turned on and the user
195			 * doesn't exist in the local password database.
196			 */
197				errx(1, "unknown local user: %s", uname);
198			}
199		} else if (res == USER_LOCAL_ONLY) {
200			/*
201			 * Reject -y flag if user only exists locally.
202			 */
203			if (__use_yp)
204				errx(1, "unknown NIS user: %s", uname);
205		} else if (res == USER_YP_AND_LOCAL) {
206			if (!use_local_passwd && (yp_in_pw_file || __use_yp))
207				exit(yp_passwd(uname));
208		}
209#ifdef KERBEROS
210	}
211#endif
212#endif
213
214	if (!use_local_passwd) {
215#ifdef	KERBEROS
216		k = auth_getval("auth_list");
217		if (k && strstr(k, "kerberos"))
218		if(krb_get_lrealm(realm, 0) == KSUCCESS) {
219			fprintf(stderr, "realm %s\n", realm);
220			exit(krb_passwd(argv[0], iflag, rflag, uflag));
221		}
222#endif
223	}
224	exit(local_passwd(uname));
225}
226
227static void
228usage()
229{
230
231#ifdef	YP
232#ifdef	KERBEROS
233	fprintf(stderr, "%s\n%s\n",
234		"usage: passwd [-l] [-i instance] [-r realm] [-u fullname]",
235		"       passwd [-l] [-y] [-o] [-d domain [-h host]] [user]");
236#else
237	(void)fprintf(stderr,
238		"usage: passwd [-l] [-y] [-o] [-d domain [-h host]] [user]\n");
239#endif
240#else
241#ifdef	KERBEROS
242	fprintf(stderr,
243		"usage: passwd [-l] [-i instance] [-r realm] [-u fullname] [user]\n");
244#else
245	(void)fprintf(stderr, "usage: passwd user\n");
246#endif
247#endif
248	exit(1);
249}
250