xref: /openbsd/usr.bin/passwd/passwd.c (revision db3296cf)
1 /*	$OpenBSD: passwd.c,v 1.17 2003/07/10 00:06:51 david Exp $	*/
2 
3 /*
4  * Copyright (c) 1988 The Regents of the University of California.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31 
32 #ifndef lint
33 char copyright[] =
34 "@(#) Copyright (c) 1988 The Regents of the University of California.\n\
35  All rights reserved.\n";
36 #endif /* not lint */
37 
38 #ifndef lint
39 /*static const char sccsid[] = "from: @(#)passwd.c	5.5 (Berkeley) 7/6/91";*/
40 static const char rcsid[] = "$OpenBSD: passwd.c,v 1.17 2003/07/10 00:06:51 david Exp $";
41 #endif /* not lint */
42 
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <unistd.h>
47 #include <err.h>
48 #ifdef KERBEROS
49 #include <kerberosIV/krb.h>
50 #endif
51 
52 /*
53  * Note on configuration:
54  *      Generally one would not use both Kerberos and YP
55  *      to maintain passwords.
56  *
57  */
58 
59 int use_kerberos;
60 int use_yp;
61 
62 #ifdef YP
63 int force_yp;
64 #endif
65 
66 extern int local_passwd(char *, int);
67 extern int yp_passwd(char *);
68 extern int krb_passwd(int, char **);
69 extern int krb5_passwd(int, char **);
70 extern int _yp_check(char **);
71 void usage(int retval);
72 
73 int
74 main(int argc, char **argv)
75 {
76 	extern int optind;
77 	char *username;
78 	int ch;
79 #ifdef	YP
80 	int status = 0;
81 #endif
82 
83 #if defined(KERBEROS) || defined(KERBEROS5)
84 	extern char realm[];
85 
86 	if (krb_get_lrealm(realm,1) == KSUCCESS)
87 		use_kerberos = 1;
88 #endif
89 #ifdef	YP
90 	use_yp = _yp_check(NULL);
91 #endif
92 
93 	/* Process args and options */
94 	while ((ch = getopt(argc, argv, "lykK")) != -1)
95 		switch (ch) {
96 		case 'l':		/* change local password file */
97 			use_kerberos = 0;
98 			use_yp = 0;
99 			break;
100 		case 'k':		/* change Kerberos password */
101 #if defined(KERBEROS)
102 			use_kerberos = 1;
103 			use_yp = 0;
104 			exit(krb_passwd(argc, argv));
105 			break;
106 #else
107 			fprintf(stderr, "passwd: Kerberos not compiled in\n");
108 			exit(1);
109 #endif
110 		case 'K':
111 #ifdef KRB5
112 			/* Skip programname and '-K' option */
113 			argc -= 2;
114 			argv += 2;
115 			exit(krb5_passwd(argc, argv));
116 #else
117 			errx(1, "KerberosV support not enabled");
118 			break;
119 #endif
120 		case 'y':		/* change YP password */
121 #ifdef	YP
122 			if (!use_yp) {
123 				fprintf(stderr, "passwd: YP not in use.\n");
124 				exit(1);
125 			}
126 			use_kerberos = 0;
127 			use_yp = 1;
128 			force_yp = 1;
129 			break;
130 #else
131 			fprintf(stderr, "passwd: YP not compiled in\n");
132 			exit(1);
133 #endif
134 		default:
135 			usage(1);
136 		}
137 
138 	argc -= optind;
139 	argv += optind;
140 
141 	username = getlogin();
142 	if (username == NULL) {
143 		fprintf(stderr, "passwd: who are you ??\n");
144 		exit(1);
145 	}
146 
147 	switch (argc) {
148 	case 0:
149 		break;
150 	case 1:
151 #if defined(KERBEROS) || defined(KERBEROS5)
152 		if (use_kerberos && strcmp(argv[0], username)) {
153 			(void)fprintf(stderr, "passwd: %s\n\t%s\n%s\n",
154 			    "to change another user's Kerberos password, do",
155 			    "\"passwd -k -u <user>\";",
156 			    "to change a user's local passwd, use \"passwd -l <user>\"");
157 			exit(1);
158 		}
159 #endif
160 		username = argv[0];
161 		break;
162 	default:
163 		usage(1);
164 	}
165 
166 #if defined(KERBEROS) || defined(KERBEROS5)
167 	if (use_kerberos)
168 		exit(krb_passwd(argc, argv));
169 #endif
170 
171 #ifdef	YP
172 	if (force_yp || ((status = local_passwd(username, 0)) && use_yp))
173 		exit(yp_passwd(username));
174 	exit(status);
175 #endif
176 	exit(local_passwd(username, 0));
177 }
178 
179 void
180 usage(int retval)
181 {
182 	fprintf(stderr, "usage: passwd [-l] [-y] [-k [-n name] [-i instance] "
183 	    "[-r realm] [-u username[.instance][@realm]] [user]\n");
184 	exit(retval);
185 }
186