xref: /netbsd/external/bsd/libbind/dist/irs/irp_pw.c (revision 6550d01e)
1 /*	$NetBSD: irp_pw.c,v 1.1.1.1 2009/04/12 15:33:36 christos Exp $	*/
2 
3 /*
4  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5  * Portions Copyright (c) 1996 by Internet Software Consortium.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #if defined(LIBC_SCCS) && !defined(lint)
21 static const char rcsid[] = "Id: irp_pw.c,v 1.4 2005/04/27 04:56:29 sra Exp";
22 #endif /* LIBC_SCCS and not lint */
23 
24 /* Extern */
25 
26 #include "port_before.h"
27 
28 #ifndef WANT_IRS_PW
29 static int __bind_irs_pw_unneeded;
30 #else
31 
32 #include <syslog.h>
33 #include <sys/param.h>
34 
35 #include <db.h>
36 #include <errno.h>
37 #include <fcntl.h>
38 #include <limits.h>
39 #include <pwd.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <syslog.h>
43 #include <utmp.h>
44 #include <unistd.h>
45 
46 #include <irs.h>
47 #include <irp.h>
48 #include <isc/memcluster.h>
49 #include <isc/irpmarshall.h>
50 
51 #include "port_after.h"
52 
53 #include "irs_p.h"
54 #include "irp_p.h"
55 
56 
57 /* Types */
58 
59 struct	pvt {
60 	struct irp_p   *girpdata; /*%< global IRP data */
61 	int		warned;
62 	struct passwd	passwd;		/*%< password structure */
63 };
64 
65 /* Forward */
66 
67 static void			pw_close(struct irs_pw *);
68 static struct passwd *		pw_next(struct irs_pw *);
69 static struct passwd *		pw_byname(struct irs_pw *, const char *);
70 static struct passwd *		pw_byuid(struct irs_pw *, uid_t);
71 static void			pw_rewind(struct irs_pw *);
72 static void			pw_minimize(struct irs_pw *);
73 
74 static void			free_passwd(struct passwd *pw);
75 
76 /* Public */
77 struct irs_pw *
78 irs_irp_pw(struct irs_acc *this) {
79 	struct irs_pw *pw;
80 	struct pvt *pvt;
81 
82 	if (!(pw = memget(sizeof *pw))) {
83 		errno = ENOMEM;
84 		return (NULL);
85 	}
86 	memset(pw, 0, sizeof *pw);
87 
88 	if (!(pvt = memget(sizeof *pvt))) {
89 		memput(pw, sizeof *pw);
90 		errno = ENOMEM;
91 		return (NULL);
92 	}
93 	memset(pvt, 0, sizeof *pvt);
94 	pvt->girpdata = this->private;
95 
96 	pw->private = pvt;
97 	pw->close = pw_close;
98 	pw->next = pw_next;
99 	pw->byname = pw_byname;
100 	pw->byuid = pw_byuid;
101 	pw->rewind = pw_rewind;
102 	pw->minimize = pw_minimize;
103 
104 	return (pw);
105 }
106 
107 /* Methods */
108 
109 /*%
110  * void pw_close(struct irs_pw *this)
111  *
112  */
113 
114 static void
115 pw_close(struct irs_pw *this) {
116 	struct pvt *pvt = (struct pvt *)this->private;
117 
118 	pw_minimize(this);
119 
120 	free_passwd(&pvt->passwd);
121 
122 	memput(pvt, sizeof *pvt);
123 	memput(this, sizeof *this);
124 }
125 
126 /*%
127  * struct passwd * pw_next(struct irs_pw *this)
128  *
129  */
130 
131 static struct passwd *
132 pw_next(struct irs_pw *this) {
133 	struct pvt *pvt = (struct pvt *)this->private;
134 	struct passwd *pw = &pvt->passwd;
135 	char *body;
136 	size_t bodylen;
137 	int code;
138 	char text[256];
139 
140 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
141 		return (NULL);
142 	}
143 
144 	if (irs_irp_send_command(pvt->girpdata, "getpwent") != 0) {
145 		return (NULL);
146 	}
147 
148 	if (irs_irp_get_full_response(pvt->girpdata, &code,
149 				      text, sizeof text,
150 				      &body, &bodylen) != 0) {
151 		return (NULL);
152 	}
153 
154 	if (code == IRPD_GETUSER_OK) {
155 		free_passwd(pw);
156 		if (irp_unmarshall_pw(pw, body) != 0) {
157 			pw = NULL;
158 		}
159 	} else {
160 		pw = NULL;
161 	}
162 
163 	if (body != NULL) {
164 		memput(body, bodylen);
165 	}
166 
167 	return (pw);
168 }
169 
170 /*%
171  * struct passwd * pw_byname(struct irs_pw *this, const char *name)
172  *
173  */
174 
175 static struct passwd *
176 pw_byname(struct irs_pw *this, const char *name) {
177 	struct pvt *pvt = (struct pvt *)this->private;
178 	struct passwd *pw = &pvt->passwd;
179 	char *body = NULL;
180 	char text[256];
181 	size_t bodylen;
182 	int code;
183 
184 	if (pw->pw_name != NULL && strcmp(name, pw->pw_name) == 0) {
185 		return (pw);
186 	}
187 
188 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
189 		return (NULL);
190 	}
191 
192 	if (irs_irp_send_command(pvt->girpdata, "getpwnam %s", name) != 0) {
193 		return (NULL);
194 	}
195 
196 	if (irs_irp_get_full_response(pvt->girpdata, &code,
197 				      text, sizeof text,
198 				      &body, &bodylen) != 0) {
199 		return (NULL);
200 	}
201 
202 	if (code == IRPD_GETUSER_OK) {
203 		free_passwd(pw);
204 		if (irp_unmarshall_pw(pw, body) != 0) {
205 			pw = NULL;
206 		}
207 	} else {
208 		pw = NULL;
209 	}
210 
211 	if (body != NULL) {
212 		memput(body, bodylen);
213 	}
214 
215 	return (pw);
216 }
217 
218 /*%
219  * struct passwd * pw_byuid(struct irs_pw *this, uid_t uid)
220  *
221  */
222 
223 static struct passwd *
224 pw_byuid(struct irs_pw *this, uid_t uid) {
225 	struct pvt *pvt = (struct pvt *)this->private;
226 	char *body;
227 	char text[256];
228 	size_t bodylen;
229 	int code;
230 	struct passwd *pw = &pvt->passwd;
231 
232 	if (pw->pw_name != NULL && pw->pw_uid == uid) {
233 		return (pw);
234 	}
235 
236 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
237 		return (NULL);
238 	}
239 
240 	if (irs_irp_send_command(pvt->girpdata, "getpwuid %d", uid) != 0) {
241 		return (NULL);
242 	}
243 
244 	if (irs_irp_get_full_response(pvt->girpdata, &code,
245 				      text, sizeof text,
246 				      &body, &bodylen) != 0) {
247 		return (NULL);
248 	}
249 
250 	if (code == IRPD_GETUSER_OK) {
251 		free_passwd(pw);
252 		if (irp_unmarshall_pw(pw, body) != 0) {
253 			pw = NULL;
254 		}
255 	} else {
256 		pw = NULL;
257 	}
258 
259 	if (body != NULL) {
260 		memput(body, bodylen);
261 	}
262 
263 	return (pw);
264 }
265 
266 /*%
267  * void pw_rewind(struct irs_pw *this)
268  *
269  */
270 
271 static void
272 pw_rewind(struct irs_pw *this) {
273 	struct pvt *pvt = (struct pvt *)this->private;
274 	char text[256];
275 	int code;
276 
277 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
278 		return;
279 	}
280 
281 	if (irs_irp_send_command(pvt->girpdata, "setpwent") != 0) {
282 		return;
283 	}
284 
285 	code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
286 	if (code != IRPD_GETUSER_SETOK) {
287 		if (irp_log_errors) {
288 			syslog(LOG_WARNING, "setpwent failed: %s", text);
289 		}
290 	}
291 
292 	return;
293 }
294 
295 /*%
296  * void pw_minimize(struct irs_pw *this)
297  *
298  */
299 
300 static void
301 pw_minimize(struct irs_pw *this) {
302 	struct pvt *pvt = (struct pvt *)this->private;
303 
304 	irs_irp_disconnect(pvt->girpdata);
305 }
306 
307 
308 /* Private. */
309 
310 /*%
311  *	Deallocate all the memory irp_unmarshall_pw allocated.
312  *
313  */
314 
315 static void
316 free_passwd(struct passwd *pw) {
317 	if (pw == NULL)
318 		return;
319 
320 	if (pw->pw_name != NULL)
321 		free(pw->pw_name);
322 
323 	if (pw->pw_passwd != NULL)
324 		free(pw->pw_passwd);
325 
326 #ifdef HAVE_PW_CLASS
327 	if (pw->pw_class != NULL)
328 		free(pw->pw_class);
329 #endif
330 
331 	if (pw->pw_gecos != NULL)
332 		free(pw->pw_gecos);
333 
334 	if (pw->pw_dir != NULL)
335 		free(pw->pw_dir);
336 
337 	if (pw->pw_shell != NULL)
338 		free(pw->pw_shell);
339 }
340 
341 #endif /* WANT_IRS_PW */
342 /*! \file */
343