pw_yp.c revision 1.2 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.2 1993/08/01 18:17:53 mycroft 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 (void)fprintf(stderr, "%s: can't get local NIS domain. Reason: %s\n", progname, yperr_string(r));
74 return(0);
75 }
76
77 /*
78 * Find the host for the passwd map; it should be running
79 * the daemon.
80 */
81 if ((r = yp_master(domain, "passwd.byname", &master)) != 0) {
82 (void)fprintf(stderr, "%s: can't find the master NIS server. Reason: %s\n", progname, yperr_string(r));
83 return(0);
84 }
85
86 /*
87 * Ask the portmapper for the port of the daemon.
88 */
89 if ((rpcport = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, IPPROTO_UDP)) == 0) {
90 (void)fprintf(stderr, "%s: master NIS server not running yppasswd daemon.\n\tCan't change password.\n", progname);
91 return(0);
92 }
93
94 /*
95 * Be sure the port is priviledged
96 */
97 if (rpcport >= IPPORT_RESERVED) {
98 (void)fprintf(stderr, "%s: yppasswd daemon running on an invalid port.\n", progname);
99 return(0);
100 }
101
102 /* prompt for old password */
103 yppasswd.oldpass = "none";
104 if (uid)
105 yppasswd.oldpass = getpass("Old password:");
106 if (!yppasswd.oldpass) {
107 (void)fprintf(stderr, "Cancelled.\n");
108 return(0);
109 }
110
111 /* tell rpc.yppasswdd */
112 yppasswd.newpw.pw_name = pw->pw_name;
113 yppasswd.newpw.pw_passwd= pw->pw_passwd;
114 yppasswd.newpw.pw_uid = pw->pw_uid;
115 yppasswd.newpw.pw_gid = pw->pw_gid;
116 yppasswd.newpw.pw_gecos = pw->pw_gecos;
117 yppasswd.newpw.pw_dir = pw->pw_dir;
118 yppasswd.newpw.pw_shell = pw->pw_shell;
119
120 client = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp");
121 if (client==NULL) {
122 fprintf(stderr, "can't contact yppasswdd on %s: Reason: %s\n",
123 master, yperr_string(YPERR_YPBIND));
124 return(0);
125 }
126 client->cl_auth = authunix_create_default();
127 tv.tv_sec = 2;
128 tv.tv_usec = 0;
129 r = clnt_call(client, YPPASSWDPROC_UPDATE,
130 xdr_yppasswd, &yppasswd, xdr_int, &status, tv);
131 if (r) {
132 fprintf(stderr, "%s: rpc to yppasswdd failed.\n");
133 return(0);
134 }
135 else if (status) {
136 printf("Couldn't change NIS password information.\n");
137 return(0);
138 }
139 else
140 printf("The NIS password information has been changed on %s, the master NIS passwd server.\n", master);
141
142 return(1);
143 }
144
145 static char *
146 pwskip(register char *p)
147 {
148 while (*p && *p != ':' && *p != '\n')
149 ++p;
150 if (*p)
151 *p++ = 0;
152 return (p);
153 }
154
155 static struct passwd *
156 interpret(struct passwd *pwent, char *line)
157 {
158 register char *p = line;
159 register int c;
160
161 pwent->pw_passwd = "*";
162 pwent->pw_uid = 0;
163 pwent->pw_gid = 0;
164 pwent->pw_gecos = "";
165 pwent->pw_dir = "";
166 pwent->pw_shell = "";
167 pwent->pw_change = 0;
168 pwent->pw_expire = 0;
169 pwent->pw_class = "";
170
171 /* line without colon separators is no good, so ignore it */
172 if(!strchr(p,':'))
173 return(NULL);
174
175 pwent->pw_name = p;
176 p = pwskip(p);
177 pwent->pw_passwd = p;
178 p = pwskip(p);
179 pwent->pw_uid = (uid_t)strtoul(p, NULL, 10);
180 p = pwskip(p);
181 pwent->pw_gid = (gid_t)strtoul(p, NULL, 10);
182 p = pwskip(p);
183 pwent->pw_gecos = p;
184 p = pwskip(p);
185 pwent->pw_dir = p;
186 p = pwskip(p);
187 pwent->pw_shell = p;
188 while (*p && *p != '\n')
189 p++;
190 *p = '\0';
191 return (pwent);
192 }
193
194 struct passwd *
195 ypgetpwnam(nam)
196 char *nam;
197 {
198 static struct passwd pwent;
199 static char line[1024];
200 char *val;
201 int reason, vallen;
202
203 /*
204 * Get local domain
205 */
206 if (!domain && (reason = yp_get_default_domain(&domain))) {
207 (void)fprintf(stderr, "%s: can't get local NIS domain. Reason: %s\n", progname, yperr_string(reason));
208 exit(1);
209 }
210
211 reason = yp_match(domain, "passwd.byname", nam, strlen(nam),
212 &val, &vallen);
213 switch(reason) {
214 case 0:
215 break;
216 default:
217 return (NULL);
218 break;
219 }
220 val[vallen] = '\0';
221 strcpy(line, val);
222 free(val);
223
224 return(interpret(&pwent, line));
225 }
226
227 struct passwd *
228 ypgetpwuid(uid)
229 uid_t uid;
230 {
231 static struct passwd pwent;
232 static char line[1024];
233 char *val;
234 int reason, vallen;
235 char namebuf[16];
236
237 if (!domain && (reason = yp_get_default_domain(&domain))) {
238 (void)fprintf(stderr, "%s: can't get local NIS domain. Reason: %s\n", progname, yperr_string(reason));
239 exit(1);
240 }
241
242 sprintf(namebuf, "%d", uid);
243 reason = yp_match(domain, "passwd.byuid", namebuf, strlen(namebuf),
244 &val, &vallen);
245 switch(reason) {
246 case 0:
247 break;
248 default:
249 return (NULL);
250 break;
251 }
252 val[vallen] = '\0';
253 strcpy(line, val);
254 free(val);
255
256 return(interpret(&pwent, line));
257 }
258
259 #endif /* YP */
260