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