1 /* $NetBSD: irp_pw.c,v 1.1.1.2 2012/09/09 16:07:51 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 *
irs_irp_pw(struct irs_acc * this)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
pw_close(struct irs_pw * this)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 *
pw_next(struct irs_pw * this)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 *
pw_byname(struct irs_pw * this,const char * name)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 *
pw_byuid(struct irs_pw * this,uid_t uid)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
pw_rewind(struct irs_pw * this)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
pw_minimize(struct irs_pw * this)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
free_passwd(struct passwd * pw)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