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