xref: /openbsd/usr.bin/passwd/passwd.c (revision 7b36286a)
1 /*	$OpenBSD: passwd.c,v 1.24 2007/09/08 18:42:36 cloder 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.24 2007/09/08 18:42:36 cloder 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 #include <rpcsvc/ypclnt.h>
49 
50 #if defined(KRB5)
51 #include <sys/stat.h>
52 #endif
53 
54 /*
55  * Note on configuration:
56  *      Generally one would not use both Kerberos and YP
57  *      to maintain passwords.
58  *
59  */
60 
61 int use_kerberos;
62 int use_yp;
63 
64 #ifdef YP
65 int force_yp;
66 #endif
67 
68 extern int local_passwd(char *, int);
69 extern int yp_passwd(char *);
70 extern int krb5_passwd(int, char **);
71 extern int _yp_check(char **);
72 void usage(int retval);
73 
74 int
75 main(int argc, char **argv)
76 {
77 	extern int optind;
78 	char *username;
79 	int ch;
80 #ifdef	YP
81 	int status = 0;
82 #endif
83 #if defined(KRB5)
84 	char *ccfile;
85 	struct stat sb;
86 
87 	if (!(ccfile = getenv("KRB5CCNAME")))
88 		if (asprintf(&ccfile, "/tmp/krb5cc_%u", (unsigned)getuid()) ==
89 		    -1)
90 			errx(1, "out of memory");
91 
92 	if ((stat(ccfile, &sb) == 0) && (sb.st_uid == getuid()))
93 		use_kerberos = 1;
94 #endif
95 #ifdef	YP
96 	use_yp = _yp_check(NULL);
97 	if (use_yp) {
98 		char *dom;
99 
100 		yp_get_default_domain(&dom);
101 		yp_unbind(dom);
102 	}
103 #endif
104 
105 	/* Process args and options */
106 	while ((ch = getopt(argc, argv, "lyK")) != -1)
107 		switch (ch) {
108 		case 'l':		/* change local password file */
109 			use_kerberos = 0;
110 			use_yp = 0;
111 			break;
112 		case 'K':
113 #if defined(KRB5)
114 			/* Skip programname and '-K' option */
115 			argc -= 2;
116 			argv += 2;
117 			exit(krb5_passwd(argc, argv));
118 #else
119 			errx(1, "KerberosV support not enabled");
120 			break;
121 #endif
122 		case 'y':		/* change YP password */
123 #ifdef	YP
124 			if (!use_yp) {
125 				fprintf(stderr, "passwd: YP not in use.\n");
126 				exit(1);
127 			}
128 			use_kerberos = 0;
129 			use_yp = 1;
130 			force_yp = 1;
131 			break;
132 #else
133 			fprintf(stderr, "passwd: YP not compiled in\n");
134 			exit(1);
135 #endif
136 		default:
137 			usage(1);
138 		}
139 
140 	argc -= optind;
141 	argv += optind;
142 
143 	username = getlogin();
144 	if (username == NULL) {
145 		fprintf(stderr, "passwd: who are you ??\n");
146 		exit(1);
147 	}
148 
149 	switch (argc) {
150 	case 0:
151 		break;
152 	case 1:
153 		username = argv[0];
154 		break;
155 	default:
156 		usage(1);
157 	}
158 
159 #if defined(KRB5)
160 	if (use_kerberos)
161 		exit(krb5_passwd(argc, argv));
162 #endif
163 #ifdef	YP
164 	if (force_yp || ((status = local_passwd(username, 0)) && use_yp))
165 		exit(yp_passwd(username));
166 	exit(status);
167 #else
168 	exit(local_passwd(username, 0));
169 #endif
170 }
171 
172 void
173 usage(int retval)
174 {
175 	fprintf(stderr, "usage: passwd [-K | -l | -y] [user]\n");
176 	exit(retval);
177 }
178