xref: /netbsd/external/bsd/libbind/dist/irs/irp_gr.c (revision 6550d01e)
1 /*	$NetBSD: irp_gr.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, 1998 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_gr.c,v 1.4 2005/04/27 04:56:27 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_gr_unneeded;
30 #else
31 
32 #include <syslog.h>
33 #include <sys/param.h>
34 #include <sys/types.h>
35 
36 #include <errno.h>
37 #include <fcntl.h>
38 #include <grp.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <unistd.h>
43 #include <syslog.h>
44 
45 #include <irs.h>
46 #include <irp.h>
47 #include <isc/memcluster.h>
48 #include <isc/irpmarshall.h>
49 
50 #include "irs_p.h"
51 #include "lcl_p.h"
52 #include "irp_p.h"
53 
54 #include "port_after.h"
55 
56 
57 /* Types. */
58 
59 /*! \file
60  * \brief
61  * Module for the getnetgrent(3) family to use when connected to a
62  * remote irp daemon.
63  * \brief
64  * See irpd.c for justification of caching done here.
65  *
66  */
67 
68 struct pvt {
69 	struct irp_p   *girpdata;	/*%< global IRP data */
70 	int		warned;
71 	struct group	group;
72 };
73 
74 /* Forward. */
75 
76 static void		gr_close(struct irs_gr *);
77 static struct group *	gr_next(struct irs_gr *);
78 static struct group *	gr_byname(struct irs_gr *, const char *);
79 static struct group *	gr_bygid(struct irs_gr *, gid_t);
80 static void		gr_rewind(struct irs_gr *);
81 static void		gr_minimize(struct irs_gr *);
82 
83 /* Private */
84 static void		free_group(struct group *gr);
85 
86 
87 /* Public. */
88 
89 /*%
90  *	Initialize the group sub-module.
91  *
92  */
93 
94 struct irs_gr *
95 irs_irp_gr(struct irs_acc *this) {
96 	struct irs_gr *gr;
97 	struct pvt *pvt;
98 
99 	if (!(gr = memget(sizeof *gr))) {
100 		errno = ENOMEM;
101 		return (NULL);
102 	}
103 	memset(gr, 0x0, sizeof *gr);
104 
105 	if (!(pvt = memget(sizeof *pvt))) {
106 		memput(gr, sizeof *gr);
107 		errno = ENOMEM;
108 		return (NULL);
109 	}
110 	memset(pvt, 0x0, sizeof *pvt);
111 	pvt->girpdata = this->private;
112 
113 	gr->private = pvt;
114 	gr->close = gr_close;
115 	gr->next = gr_next;
116 	gr->byname = gr_byname;
117 	gr->bygid = gr_bygid;
118 	gr->rewind = gr_rewind;
119 	gr->list = make_group_list;
120 	gr->minimize = gr_minimize;
121 	return (gr);
122 }
123 
124 /* Methods. */
125 
126 /*%
127  *	Close the sub-module.
128  *
129  */
130 
131 static void
132 gr_close(struct irs_gr *this) {
133 	struct pvt *pvt = (struct pvt *)this->private;
134 
135 	gr_minimize(this);
136 
137 	memput(pvt, sizeof *pvt);
138 	memput(this, sizeof *this);
139 }
140 
141 /*%
142  *	Gets the next group out of the cached data and returns it.
143  *
144  */
145 
146 static struct group *
147 gr_next(struct irs_gr *this) {
148 	struct pvt *pvt = (struct pvt *)this->private;
149 	struct group *gr = &pvt->group;
150 	char *body;
151 	size_t bodylen;
152 	int code;
153 	char text[256];
154 
155 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
156 		return (NULL);
157 	}
158 
159 	if (irs_irp_send_command(pvt->girpdata, "getgrent") != 0) {
160 		return (NULL);
161 	}
162 
163 	if (irs_irp_get_full_response(pvt->girpdata, &code,
164 				      text, sizeof text,
165 				      &body, &bodylen) != 0) {
166 		if (irp_log_errors) {
167 			syslog(LOG_WARNING, "getgrent failed: %s", text);
168 		}
169 		return (NULL);
170 	}
171 
172 	if (code == IRPD_GETGROUP_OK) {
173 		free_group(gr);
174 		if (irp_unmarshall_gr(gr, body) != 0) {
175 			gr = NULL;
176 		}
177 	} else {
178 		gr = NULL;
179 	}
180 
181 	if (body != NULL) {
182 		memput(body, bodylen);
183 	}
184 
185 	return (gr);
186 }
187 
188 /*%
189  *	Gets a group by name from irpd and returns it.
190  *
191  */
192 
193 static struct group *
194 gr_byname(struct irs_gr *this, const char *name) {
195 	struct pvt *pvt = (struct pvt *)this->private;
196 	struct group *gr = &pvt->group;
197 	char *body;
198 	size_t bodylen;
199 	int code;
200 	char text[256];
201 
202 
203 	if (gr->gr_name != NULL && strcmp(name, gr->gr_name) == 0) {
204 		return (gr);
205 	}
206 
207 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
208 		return (NULL);
209 	}
210 
211 	if (irs_irp_send_command(pvt->girpdata, "getgrnam %s", name) != 0)
212 		return (NULL);
213 
214 	if (irs_irp_get_full_response(pvt->girpdata, &code,
215 				      text, sizeof text,
216 				      &body, &bodylen) != 0) {
217 		return (NULL);
218 	}
219 
220 	if (code == IRPD_GETGROUP_OK) {
221 		free_group(gr);
222 		if (irp_unmarshall_gr(gr, body) != 0) {
223 			gr = NULL;
224 		}
225 	} else {
226 		gr = NULL;
227 	}
228 
229 	if (body != NULL) {
230 		memput(body, bodylen);
231 	}
232 
233 	return (gr);
234 }
235 
236 /*%
237  *	Gets a group by gid from irpd and returns it.
238  *
239  */
240 
241 static struct group *
242 gr_bygid(struct irs_gr *this, gid_t gid) {
243 	struct pvt *pvt = (struct pvt *)this->private;
244 	struct group *gr = &pvt->group;
245 	char *body;
246 	size_t bodylen;
247 	int code;
248 	char text[256];
249 
250 	if (gr->gr_name != NULL && (gid_t)gr->gr_gid == gid) {
251 		return (gr);
252 	}
253 
254 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
255 		return (NULL);
256 	}
257 
258 	if (irs_irp_send_command(pvt->girpdata, "getgrgid %d", gid) != 0)
259 		return (NULL);
260 
261 	if (irs_irp_get_full_response(pvt->girpdata, &code,
262 				      text, sizeof text,
263 				      &body, &bodylen) != 0) {
264 		return (NULL);
265 	}
266 
267 	if (code == IRPD_GETGROUP_OK) {
268 		free_group(gr);
269 		if (irp_unmarshall_gr(gr, body) != 0) {
270 			gr = NULL;
271 		}
272 	} else {
273 		gr = NULL;
274 	}
275 
276 	if (body != NULL) {
277 		memput(body, bodylen);
278 	}
279 
280 	return (gr);
281 }
282 
283 /*%
284  * void gr_rewind(struct irs_gr *this)
285  *
286  */
287 
288 static void
289 gr_rewind(struct irs_gr *this) {
290 	struct pvt *pvt = (struct pvt *)this->private;
291 	char text[256];
292 	int code;
293 
294 	if (irs_irp_connection_setup(pvt->girpdata, &pvt->warned) != 0) {
295 		return;
296 	}
297 
298 	if (irs_irp_send_command(pvt->girpdata, "setgrent") != 0) {
299 		return;
300 	}
301 
302 	code = irs_irp_read_response(pvt->girpdata, text, sizeof text);
303 	if (code != IRPD_GETGROUP_SETOK) {
304 		if (irp_log_errors) {
305 			syslog(LOG_WARNING, "setgrent failed: %s", text);
306 		}
307 	}
308 
309 	return;
310 }
311 
312 /*%
313  *	Frees up cached data and disconnects(if necessary) from the remote.
314  *
315  */
316 
317 static void
318 gr_minimize(struct irs_gr *this) {
319 	struct pvt *pvt = (struct pvt *)this->private;
320 
321 	free_group(&pvt->group);
322 	irs_irp_disconnect(pvt->girpdata);
323 }
324 
325 /* Private. */
326 
327 /*%
328  * static void free_group(struct group *gr);
329  *
330  *	Deallocate all the memory irp_unmarshall_gr allocated.
331  *
332  */
333 
334 static void
335 free_group(struct group *gr) {
336 	char **p;
337 
338 	if (gr == NULL)
339 		return;
340 
341 	if (gr->gr_name != NULL)
342 		free(gr->gr_name);
343 
344 	if (gr->gr_passwd != NULL)
345 		free(gr->gr_passwd);
346 
347 	for (p = gr->gr_mem ; p != NULL && *p != NULL ; p++)
348 		free(*p);
349 
350 	if (gr->gr_mem)
351 		free(gr->gr_mem);
352 
353 	if (p != NULL)
354 		free(p);
355 }
356 
357 
358 #endif /* WANT_IRS_GR */
359 /*! \file */
360