pw_yp.c revision 1.5 1 /* $NetBSD: pw_yp.c,v 1.5 1995/03/26 04:55:33 glass 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. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 */
35 #ifndef lint
36 #if 0
37 static char sccsid[] = "@(#)pw_yp.c 1.0 2/2/93";
38 #else
39 static char rcsid[] = "$NetBSD: pw_yp.c,v 1.5 1995/03/26 04:55:33 glass Exp $";
40 #endif
41 #endif /* not lint */
42
43 #ifdef YP
44
45 #include <stdio.h>
46 #include <string.h>
47 #include <netdb.h>
48 #include <time.h>
49 #include <pwd.h>
50 #include <errno.h>
51 #include <rpc/rpc.h>
52 #include <rpcsvc/yp_prot.h>
53 #include <rpcsvc/ypclnt.h>
54 #define passwd yp_passwd_rec
55 #include <rpcsvc/yppasswd.h>
56 #undef passwd
57
58 extern char *progname;
59
60 static char *domain;
61
62 pw_yp(pw, uid)
63 struct passwd *pw;
64 uid_t uid;
65 {
66 char *master;
67 char *pp;
68 int r, rpcport, status;
69 struct yppasswd yppasswd;
70 struct timeval tv;
71 CLIENT *client;
72 extern char *getpass();
73
74 /*
75 * Get local domain
76 */
77 if (!domain && (r = yp_get_default_domain(&domain))) {
78 fprintf(stderr, "%s: can't get local YP domain. Reason: %s\n",
79 progname, yperr_string(r));
80 return(0);
81 }
82
83 /*
84 * Find the host for the passwd map; it should be running
85 * the daemon.
86 */
87 if ((r = yp_master(domain, "passwd.byname", &master)) != 0) {
88 fprintf(stderr,
89 "%s: can't find the master YP server. Reason: %s\n",
90 progname, yperr_string(r));
91 return(0);
92 }
93
94 /*
95 * Ask the portmapper for the port of the daemon.
96 */
97 if ((rpcport = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE,
98 IPPROTO_UDP)) == 0) {
99 fprintf(stderr,
100 "%s: master YP server not running yppasswd daemon.\n",
101 progname);
102 fprintf(stderr, "\tCan't change password.\n");
103 return(0);
104 }
105
106 /*
107 * Be sure the port is priviledged
108 */
109 if (rpcport >= IPPORT_RESERVED) {
110 (void)fprintf(stderr,
111 "%s: yppasswd daemon running on an invalid port.\n",
112 progname);
113 return(0);
114 }
115
116 /* prompt for old password */
117 bzero(&yppasswd, sizeof yppasswd);
118 yppasswd.oldpass = "none";
119 yppasswd.oldpass = getpass("Old password:");
120 if (!yppasswd.oldpass) {
121 (void)fprintf(stderr, "Cancelled.\n");
122 return(0);
123 }
124
125 /* tell rpc.yppasswdd */
126 yppasswd.newpw.pw_name = pw->pw_name;
127 yppasswd.newpw.pw_passwd= pw->pw_passwd;
128 yppasswd.newpw.pw_uid = pw->pw_uid;
129 yppasswd.newpw.pw_gid = pw->pw_gid;
130 yppasswd.newpw.pw_gecos = pw->pw_gecos;
131 yppasswd.newpw.pw_dir = pw->pw_dir;
132 yppasswd.newpw.pw_shell = pw->pw_shell;
133
134 client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp");
135 if (client==NULL) {
136 fprintf(stderr, "can't contact yppasswdd on %s: Reason: %s\n",
137 master, yperr_string(YPERR_YPBIND));
138 return(0);
139 }
140 client->cl_auth = authunix_create_default();
141 tv.tv_sec = 5;
142 tv.tv_usec = 0;
143 r = clnt_call(client, YPPASSWDPROC_UPDATE,
144 xdr_yppasswd, &yppasswd, xdr_int, &status, tv);
145 if (r) {
146 fprintf(stderr, "%s: rpc to yppasswdd failed. %d\n", progname, r);
147 return(0);
148 } else if (status) {
149 printf("Couldn't change YP password information.\n");
150 return(0);
151 }
152 printf("The YP password information has been changed on %s, the master YP passwd server.\n", master);
153
154 return(1);
155 }
156
157 static char *
158 pwskip(p)
159 register char *p;
160 {
161 while (*p && *p != ':' && *p != '\n')
162 ++p;
163 if (*p)
164 *p++ = 0;
165 return (p);
166 }
167
168 static struct passwd *
169 interpret(pwent, line)
170 struct passwd *pwent;
171 char *line;
172 {
173 register char *p = line;
174 register int c;
175
176 pwent->pw_passwd = "*";
177 pwent->pw_uid = 0;
178 pwent->pw_gid = 0;
179 pwent->pw_gecos = "";
180 pwent->pw_dir = "";
181 pwent->pw_shell = "";
182 pwent->pw_change = 0;
183 pwent->pw_expire = 0;
184 pwent->pw_class = "";
185
186 /* line without colon separators is no good, so ignore it */
187 if(!strchr(p,':'))
188 return(NULL);
189
190 pwent->pw_name = p;
191 p = pwskip(p);
192 pwent->pw_passwd = p;
193 p = pwskip(p);
194 pwent->pw_uid = (uid_t)strtoul(p, NULL, 10);
195 p = pwskip(p);
196 pwent->pw_gid = (gid_t)strtoul(p, NULL, 10);
197 p = pwskip(p);
198 pwent->pw_gecos = p;
199 p = pwskip(p);
200 pwent->pw_dir = p;
201 p = pwskip(p);
202 pwent->pw_shell = p;
203 while (*p && *p != '\n')
204 p++;
205 *p = '\0';
206 return (pwent);
207 }
208
209 struct passwd *
210 ypgetpwnam(nam)
211 char *nam;
212 {
213 static struct passwd pwent;
214 static char line[1024];
215 char *val;
216 int reason, vallen;
217
218 /*
219 * Get local domain
220 */
221 if (!domain && (reason = yp_get_default_domain(&domain))) {
222 fprintf(stderr, "%s: can't get local YP domain. Reason: %s\n",
223 progname, yperr_string(reason));
224 exit(1);
225 }
226
227 reason = yp_match(domain, "passwd.byname", nam, strlen(nam),
228 &val, &vallen);
229 switch(reason) {
230 case 0:
231 break;
232 default:
233 return (NULL);
234 break;
235 }
236 val[vallen] = '\0';
237 strcpy(line, val);
238 free(val);
239
240 return(interpret(&pwent, line));
241 }
242
243 struct passwd *
244 ypgetpwuid(uid)
245 uid_t uid;
246 {
247 static struct passwd pwent;
248 static char line[1024];
249 char *val;
250 int reason, vallen;
251 char namebuf[16];
252
253 if (!domain && (reason = yp_get_default_domain(&domain))) {
254 fprintf(stderr, "%s: can't get local YP domain. Reason: %s\n",
255 progname, yperr_string(reason));
256 exit(1);
257 }
258
259 sprintf(namebuf, "%d", uid);
260 reason = yp_match(domain, "passwd.byuid", namebuf, strlen(namebuf),
261 &val, &vallen);
262 switch(reason) {
263 case 0:
264 break;
265 default:
266 return (NULL);
267 break;
268 }
269 val[vallen] = '\0';
270 strcpy(line, val);
271 free(val);
272
273 return(interpret(&pwent, line));
274 }
275
276 #endif /* YP */
277