Import bind 9.5.2 vendor sources.
[dragonfly.git] / contrib / bind-9.5.2 / 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.4 2005/04/27 04:56:29 sra 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  * void pw_close(struct irs_pw *this)
109  *
110  */
111
112 static void
113 pw_close(struct irs_pw *this) {
114         struct pvt *pvt = (struct pvt *)this->private;
115
116         pw_minimize(this);
117
118         free_passwd(&pvt->passwd);
119
120         memput(pvt, sizeof *pvt);
121         memput(this, sizeof *this);
122 }
123
124 /*%
125  * struct passwd * pw_next(struct irs_pw *this)
126  *
127  */
128
129 static struct passwd *
130 pw_next(struct irs_pw *this) {
131         struct pvt *pvt = (struct pvt *)this->private;
132         struct passwd *pw = &pvt->passwd;
133         char *body;
134         size_t bodylen;
135         int code;
136         char text[256];
137
138         if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
139                 return (NULL);
140         }
141
142         if (irs_irp_send_command(pvt->girpdata, "getpwent") != 0) {
143                 return (NULL);
144         }
145
146         if (irs_irp_get_full_response(pvt->girpdata, &code,
147                                       text, sizeof text,
148                                       &body, &bodylen) != 0) {
149                 return (NULL);
150         }
151
152         if (code == IRPD_GETUSER_OK) {
153                 free_passwd(pw);
154                 if (irp_unmarshall_pw(pw, body) != 0) {
155                         pw = NULL;
156                 }
157         } else {
158                 pw = NULL;
159         }
160
161         if (body != NULL) {
162                 memput(body, bodylen);
163         }
164
165         return (pw);
166 }
167
168 /*%
169  * struct passwd * pw_byname(struct irs_pw *this, const char *name)
170  *
171  */
172
173 static struct passwd *
174 pw_byname(struct irs_pw *this, const char *name) {
175         struct pvt *pvt = (struct pvt *)this->private;
176         struct passwd *pw = &pvt->passwd;
177         char *body = NULL;
178         char text[256];
179         size_t bodylen;
180         int code;
181
182         if (pw->pw_name != NULL && strcmp(name, pw->pw_name) == 0) {
183                 return (pw);
184         }
185
186         if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
187                 return (NULL);
188         }
189
190         if (irs_irp_send_command(pvt->girpdata, "getpwnam %s", name) != 0) {
191                 return (NULL);
192         }
193
194         if (irs_irp_get_full_response(pvt->girpdata, &code,
195                                       text, sizeof text,
196                                       &body, &bodylen) != 0) {
197                 return (NULL);
198         }
199
200         if (code == IRPD_GETUSER_OK) {
201                 free_passwd(pw);
202                 if (irp_unmarshall_pw(pw, body) != 0) {
203                         pw = NULL;
204                 }
205         } else {
206                 pw = NULL;
207         }
208
209         if (body != NULL) {
210                 memput(body, bodylen);
211         }
212
213         return (pw);
214 }
215
216 /*%
217  * struct passwd * pw_byuid(struct irs_pw *this, uid_t uid)
218  *
219  */
220
221 static struct passwd *
222 pw_byuid(struct irs_pw *this, uid_t uid) {
223         struct pvt *pvt = (struct pvt *)this->private;
224         char *body;
225         char text[256];
226         size_t bodylen;
227         int code;
228         struct passwd *pw = &pvt->passwd;
229
230         if (pw->pw_name != NULL && pw->pw_uid == uid) {
231                 return (pw);
232         }
233
234         if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
235                 return (NULL);
236         }
237
238         if (irs_irp_send_command(pvt->girpdata, "getpwuid %d", uid) != 0) {
239                 return (NULL);
240         }
241
242         if (irs_irp_get_full_response(pvt->girpdata, &code,
243                                       text, sizeof text,
244                                       &body, &bodylen) != 0) {
245                 return (NULL);
246         }
247
248         if (code == IRPD_GETUSER_OK) {
249                 free_passwd(pw);
250                 if (irp_unmarshall_pw(pw, body) != 0) {
251                         pw = NULL;
252                 }
253         } else {
254                 pw = NULL;
255         }
256
257         if (body != NULL) {
258                 memput(body, bodylen);
259         }
260
261         return (pw);
262 }
263
264 /*%
265  * void pw_rewind(struct irs_pw *this)
266  *
267  */
268
269 static void
270 pw_rewind(struct irs_pw *this) {
271         struct pvt *pvt = (struct pvt *)this->private;
272         char text[256];
273         int code;
274
275         if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
276                 return;
277         }
278
279         if (irs_irp_send_command(pvt->girpdata, "setpwent") != 0) {
280                 return;
281         }
282
283         code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
284         if (code != IRPD_GETUSER_SETOK) {
285                 if (irp_log_errors) {
286                         syslog(LOG_WARNING, "setpwent failed: %s", text);
287                 }
288         }
289
290         return;
291 }
292
293 /*%
294  * void pw_minimize(struct irs_pw *this)
295  *
296  */
297
298 static void
299 pw_minimize(struct irs_pw *this) {
300         struct pvt *pvt = (struct pvt *)this->private;
301
302         irs_irp_disconnect(pvt->girpdata);
303 }
304
305
306 /* Private. */
307
308 /*%
309  *      Deallocate all the memory irp_unmarshall_pw allocated.
310  *
311  */
312
313 static void
314 free_passwd(struct passwd *pw) {
315         if (pw == NULL)
316                 return;
317
318         if (pw->pw_name != NULL)
319                 free(pw->pw_name);
320
321         if (pw->pw_passwd != NULL)
322                 free(pw->pw_passwd);
323
324 #ifdef HAVE_PW_CLASS
325         if (pw->pw_class != NULL)
326                 free(pw->pw_class);
327 #endif
328
329         if (pw->pw_gecos != NULL)
330                 free(pw->pw_gecos);
331
332         if (pw->pw_dir != NULL)
333                 free(pw->pw_dir);
334
335         if (pw->pw_shell != NULL)
336                 free(pw->pw_shell);
337 }
338
339 #endif /* WANT_IRS_PW */
340 /*! \file */