pw_yp.c revision 1.3 1 /*
2 * Copyright (c) 1988 The Regents of the University of California.
3 * 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 #ifndef lint
34 /*static char sccsid[] = "from: @(#)pw_yp.c 1.0 2/2/93";*/
35 static char rcsid[] = "$Id: pw_yp.c,v 1.3 1994/06/29 21:40:21 deraadt Exp $";
36 #endif /* not lint */
37
38 #ifdef YP
39
40 #include <stdio.h>
41 #include <string.h>
42 #include <netdb.h>
43 #include <time.h>
44 #include <pwd.h>
45 #include <errno.h>
46 #include <rpc/rpc.h>
47 #include <rpcsvc/yp_prot.h>
48 #include <rpcsvc/ypclnt.h>
49 #define passwd yp_passwd_rec
50 #include <rpcsvc/yppasswd.h>
51 #undef passwd
52
53 extern char *progname;
54
55 static char *domain;
56
57 pw_yp(pw, uid)
58 struct passwd *pw;
59 uid_t uid;
60 {
61 char *master;
62 char *pp;
63 int r, rpcport, status;
64 struct yppasswd yppasswd;
65 struct timeval tv;
66 CLIENT *client;
67 extern char *getpass();
68
69 /*
70 * Get local domain
71 */
72 if (!domain && (r = yp_get_default_domain(&domain))) {
73 fprintf(stderr, "%s: can't get local YP domain. Reason: %s\n",
74 progname, yperr_string(r));
75 return(0);
76 }
77
78 /*
79 * Find the host for the passwd map; it should be running
80 * the daemon.
81 */
82 if ((r = yp_master(domain, "passwd.byname", &master)) != 0) {
83 fprintf(stderr,
84 "%s: can't find the master YP server. Reason: %s\n",
85 progname, yperr_string(r));
86 return(0);
87 }
88
89 /*
90 * Ask the portmapper for the port of the daemon.
91 */
92 if ((rpcport = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE,
93 IPPROTO_UDP)) == 0) {
94 fprintf(stderr,
95 "%s: master YP server not running yppasswd daemon.\n",
96 progname);
97 fprintf(stderr, "\tCan't change password.\n");
98 return(0);
99 }
100
101 /*
102 * Be sure the port is priviledged
103 */
104 if (rpcport >= IPPORT_RESERVED) {
105 (void)fprintf(stderr,
106 "%s: yppasswd daemon running on an invalid port.\n",
107 progname);
108 return(0);
109 }
110
111 /* prompt for old password */
112 bzero(&yppasswd, sizeof yppasswd);
113 yppasswd.oldpass = "none";
114 if (uid)
115 yppasswd.oldpass = getpass("Old password:");
116 if (!yppasswd.oldpass) {
117 (void)fprintf(stderr, "Cancelled.\n");
118 return(0);
119 }
120
121 /* tell rpc.yppasswdd */
122 yppasswd.newpw.pw_name = pw->pw_name;
123 yppasswd.newpw.pw_passwd= pw->pw_passwd;
124 yppasswd.newpw.pw_uid = pw->pw_uid;
125 yppasswd.newpw.pw_gid = pw->pw_gid;
126 yppasswd.newpw.pw_gecos = pw->pw_gecos;
127 yppasswd.newpw.pw_dir = pw->pw_dir;
128 yppasswd.newpw.pw_shell = pw->pw_shell;
129
130 client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp");
131 if (client==NULL) {
132 fprintf(stderr, "can't contact yppasswdd on %s: Reason: %s\n",
133 master, yperr_string(YPERR_YPBIND));
134 return(0);
135 }
136 client->cl_auth = authunix_create_default();
137 tv.tv_sec = 5;
138 tv.tv_usec = 0;
139 r = clnt_call(client, YPPASSWDPROC_UPDATE,
140 xdr_yppasswd, &yppasswd, xdr_int, &status, tv);
141 if (r) {
142 fprintf(stderr, "%s: rpc to yppasswdd failed. %d\n", progname, r);
143 return(0);
144 } else if (status) {
145 printf("Couldn't change YP password information.\n");
146 return(0);
147 }
148 printf("The YP password information has been changed on %s, the master YP passwd server.\n", master);
149
150 return(1);
151 }
152
153 static char *
154 pwskip(p)
155 register char *p;
156 {
157 while (*p && *p != ':' && *p != '\n')
158 ++p;
159 if (*p)
160 *p++ = 0;
161 return (p);
162 }
163
164 static struct passwd *
165 interpret(pwent, line)
166 struct passwd *pwent;
167 char *line;
168 {
169 register char *p = line;
170 register int c;
171
172 pwent->pw_passwd = "*";
173 pwent->pw_uid = 0;
174 pwent->pw_gid = 0;
175 pwent->pw_gecos = "";
176 pwent->pw_dir = "";
177 pwent->pw_shell = "";
178 pwent->pw_change = 0;
179 pwent->pw_expire = 0;
180 pwent->pw_class = "";
181
182 /* line without colon separators is no good, so ignore it */
183 if(!strchr(p,':'))
184 return(NULL);
185
186 pwent->pw_name = p;
187 p = pwskip(p);
188 pwent->pw_passwd = p;
189 p = pwskip(p);
190 pwent->pw_uid = (uid_t)strtoul(p, NULL, 10);
191 p = pwskip(p);
192 pwent->pw_gid = (gid_t)strtoul(p, NULL, 10);
193 p = pwskip(p);
194 pwent->pw_gecos = p;
195 p = pwskip(p);
196 pwent->pw_dir = p;
197 p = pwskip(p);
198 pwent->pw_shell = p;
199 while (*p && *p != '\n')
200 p++;
201 *p = '\0';
202 return (pwent);
203 }
204
205 struct passwd *
206 ypgetpwnam(nam)
207 char *nam;
208 {
209 static struct passwd pwent;
210 static char line[1024];
211 char *val;
212 int reason, vallen;
213
214 /*
215 * Get local domain
216 */
217 if (!domain && (reason = yp_get_default_domain(&domain))) {
218 fprintf(stderr, "%s: can't get local YP domain. Reason: %s\n",
219 progname, yperr_string(reason));
220 exit(1);
221 }
222
223 reason = yp_match(domain, "passwd.byname", nam, strlen(nam),
224 &val, &vallen);
225 switch(reason) {
226 case 0:
227 break;
228 default:
229 return (NULL);
230 break;
231 }
232 val[vallen] = '\0';
233 strcpy(line, val);
234 free(val);
235
236 return(interpret(&pwent, line));
237 }
238
239 struct passwd *
240 ypgetpwuid(uid)
241 uid_t uid;
242 {
243 static struct passwd pwent;
244 static char line[1024];
245 char *val;
246 int reason, vallen;
247 char namebuf[16];
248
249 if (!domain && (reason = yp_get_default_domain(&domain))) {
250 fprintf(stderr, "%s: can't get local YP domain. Reason: %s\n",
251 progname, yperr_string(reason));
252 exit(1);
253 }
254
255 sprintf(namebuf, "%d", uid);
256 reason = yp_match(domain, "passwd.byuid", namebuf, strlen(namebuf),
257 &val, &vallen);
258 switch(reason) {
259 case 0:
260 break;
261 default:
262 return (NULL);
263 break;
264 }
265 val[vallen] = '\0';
266 strcpy(line, val);
267 free(val);
268
269 return(interpret(&pwent, line));
270 }
271
272 #endif /* YP */
273