4 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5 * Portions Copyright(c) 1996, 1998 by Internet Software Consortium.
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.
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.
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 */
26 #include "port_before.h"
29 static int __bind_irs_gr_unneeded
;
33 #include <sys/param.h>
34 #include <sys/types.h>
47 #include <isc/memcluster.h>
48 #include <isc/irpmarshall.h>
54 #include "port_after.h"
61 * Module for the getnetgrent(3) family to use when connected to a
64 * See irpd.c for justification of caching done here.
69 struct irp_p
*girpdata
; /*%< global IRP data */
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
*);
84 static void free_group(struct group
*gr
);
90 * Initialize the group sub-module.
95 irs_irp_gr(struct irs_acc
*this) {
99 if (!(gr
= memget(sizeof *gr
))) {
103 memset(gr
, 0x0, sizeof *gr
);
105 if (!(pvt
= memget(sizeof *pvt
))) {
106 memput(gr
, sizeof *gr
);
110 memset(pvt
, 0x0, sizeof *pvt
);
111 pvt
->girpdata
= this->private;
114 gr
->close
= gr_close
;
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
;
127 * Close the sub-module.
132 gr_close(struct irs_gr
*this) {
133 struct pvt
*pvt
= (struct pvt
*)this->private;
137 memput(pvt
, sizeof *pvt
);
138 memput(this, sizeof *this);
142 * Gets the next group out of the cached data and returns it.
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
;
155 if (irs_irp_connection_setup(pvt
->girpdata
, &pvt
->warned
) != 0) {
159 if (irs_irp_send_command(pvt
->girpdata
, "getgrent") != 0) {
163 if (irs_irp_get_full_response(pvt
->girpdata
, &code
,
165 &body
, &bodylen
) != 0) {
166 if (irp_log_errors
) {
167 syslog(LOG_WARNING
, "getgrent failed: %s", text
);
172 if (code
== IRPD_GETGROUP_OK
) {
174 if (irp_unmarshall_gr(gr
, body
) != 0) {
182 memput(body
, bodylen
);
189 * Gets a group by name from irpd and returns it.
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
;
203 if (gr
->gr_name
!= NULL
&& strcmp(name
, gr
->gr_name
) == 0) {
207 if (irs_irp_connection_setup(pvt
->girpdata
, &pvt
->warned
) != 0) {
211 if (irs_irp_send_command(pvt
->girpdata
, "getgrnam %s", name
) != 0)
214 if (irs_irp_get_full_response(pvt
->girpdata
, &code
,
216 &body
, &bodylen
) != 0) {
220 if (code
== IRPD_GETGROUP_OK
) {
222 if (irp_unmarshall_gr(gr
, body
) != 0) {
230 memput(body
, bodylen
);
237 * Gets a group by gid from irpd and returns it.
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
;
250 if (gr
->gr_name
!= NULL
&& (gid_t
)gr
->gr_gid
== gid
) {
254 if (irs_irp_connection_setup(pvt
->girpdata
, &pvt
->warned
) != 0) {
258 if (irs_irp_send_command(pvt
->girpdata
, "getgrgid %d", gid
) != 0)
261 if (irs_irp_get_full_response(pvt
->girpdata
, &code
,
263 &body
, &bodylen
) != 0) {
267 if (code
== IRPD_GETGROUP_OK
) {
269 if (irp_unmarshall_gr(gr
, body
) != 0) {
277 memput(body
, bodylen
);
284 * void gr_rewind(struct irs_gr *this)
289 gr_rewind(struct irs_gr
*this) {
290 struct pvt
*pvt
= (struct pvt
*)this->private;
294 if (irs_irp_connection_setup(pvt
->girpdata
, &pvt
->warned
) != 0) {
298 if (irs_irp_send_command(pvt
->girpdata
, "setgrent") != 0) {
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
);
313 * Frees up cached data and disconnects(if necessary) from the remote.
318 gr_minimize(struct irs_gr
*this) {
319 struct pvt
*pvt
= (struct pvt
*)this->private;
321 free_group(&pvt
->group
);
322 irs_irp_disconnect(pvt
->girpdata
);
328 * static void free_group(struct group *gr);
330 * Deallocate all the memory irp_unmarshall_gr allocated.
335 free_group(struct group
*gr
) {
341 if (gr
->gr_name
!= NULL
)
344 if (gr
->gr_passwd
!= NULL
)
347 for (p
= gr
->gr_mem
; p
!= NULL
&& *p
!= NULL
; p
++)
358 #endif /* WANT_IRS_GR */