4 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (c) 1996-1999 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: dns_gr.c,v 1.4 2005/04/27 04:56:21 sra Exp";
26 * dns_gr.c --- this file contains the functions for accessing
27 * group information from Hesiod.
30 #include "port_before.h"
33 static int __bind_irs_gr_unneeded
;
36 #include <sys/param.h>
37 #include <sys/types.h>
45 #include <sys/types.h>
46 #include <netinet/in.h>
47 #include <arpa/nameser.h>
50 #include <isc/memcluster.h>
54 #include "port_after.h"
64 * This is our private accessor data. It has a shared hesiod context.
68 * Need space to store the entries read from the group file.
69 * The members list also needs space per member, and the
70 * strings making up the user names must be allocated
71 * somewhere. Rather than doing lots of small allocations,
72 * we keep one buffer and resize it as needed.
75 size_t nmemb
; /*%< Malloc'd max index of gr_mem[]. */
82 static struct group
* gr_next(struct irs_gr
*);
83 static struct group
* gr_byname(struct irs_gr
*, const char *);
84 static struct group
* gr_bygid(struct irs_gr
*, gid_t
);
85 static void gr_rewind(struct irs_gr
*);
86 static void gr_close(struct irs_gr
*);
87 static int gr_list(struct irs_gr
*, const char *,
88 gid_t
, gid_t
*, int *);
89 static void gr_minimize(struct irs_gr
*);
90 static struct __res_state
* gr_res_get(struct irs_gr
*);
91 static void gr_res_set(struct irs_gr
*,
95 static struct group
* get_hes_group(struct irs_gr
*this,
102 irs_dns_gr(struct irs_acc
*this) {
103 struct dns_p
*dns
= (struct dns_p
*)this->private;
107 if (!dns
|| !dns
->hes_ctx
) {
111 if (!(pvt
= memget(sizeof *pvt
))) {
115 memset(pvt
, 0, sizeof *pvt
);
117 if (!(gr
= memget(sizeof *gr
))) {
118 memput(pvt
, sizeof *pvt
);
122 memset(gr
, 0x5e, sizeof *gr
);
125 gr
->byname
= gr_byname
;
126 gr
->bygid
= gr_bygid
;
127 gr
->rewind
= gr_rewind
;
128 gr
->close
= gr_close
;
130 gr
->minimize
= gr_minimize
;
131 gr
->res_get
= gr_res_get
;
132 gr
->res_set
= gr_res_set
;
139 gr_close(struct irs_gr
*this) {
140 struct pvt
*pvt
= (struct pvt
*)this->private;
142 if (pvt
->group
.gr_mem
)
143 free(pvt
->group
.gr_mem
);
146 memput(pvt
, sizeof *pvt
);
147 memput(this, sizeof *this);
150 static struct group
*
151 gr_next(struct irs_gr
*this) {
158 static struct group
*
159 gr_byname(struct irs_gr
*this, const char *name
) {
160 return (get_hes_group(this, name
, "group"));
163 static struct group
*
164 gr_bygid(struct irs_gr
*this, gid_t gid
) {
167 sprintf(name
, "%ld", (long)gid
);
168 return (get_hes_group(this, name
, "gid"));
172 gr_rewind(struct irs_gr
*this) {
180 gr_list(struct irs_gr
*this, const char *name
,
181 gid_t basegid
, gid_t
*groups
, int *ngroups
)
189 /* There's some way to do this in Hesiod. */
194 gr_minimize(struct irs_gr
*this) {
202 static struct group
*
203 get_hes_group(struct irs_gr
*this, const char *name
, const char *type
) {
204 struct pvt
*pvt
= (struct pvt
*)this->private;
205 char **hes_list
, *cp
, **new;
206 size_t num_members
= 0;
209 hes_list
= hesiod_resolve(pvt
->dns
->hes_ctx
, name
, type
);
214 * Copy the returned hesiod string into storage space.
218 pvt
->membuf
= strdup(*hes_list
);
219 hesiod_free_list(pvt
->dns
->hes_ctx
, hes_list
);
222 pvt
->group
.gr_name
= cp
;
223 if (!(cp
= strchr(cp
, ':')))
227 pvt
->group
.gr_passwd
= cp
;
228 if (!(cp
= strchr(cp
, ':')))
233 t
= strtoul(cp
, NULL
, 10);
236 pvt
->group
.gr_gid
= (gid_t
) t
;
237 if (!(cp
= strchr(cp
, ':')))
242 * Parse the members out.
245 if (num_members
+1 >= pvt
->nmemb
|| pvt
->group
.gr_mem
== NULL
) {
247 new = realloc(pvt
->group
.gr_mem
,
248 pvt
->nmemb
* sizeof(char *));
251 pvt
->group
.gr_mem
= new;
253 pvt
->group
.gr_mem
[num_members
++] = cp
;
254 if (!(cp
= strchr(cp
, ',')))
258 if (!pvt
->group
.gr_mem
) {
259 pvt
->group
.gr_mem
= malloc(sizeof(char*));
260 if (!pvt
->group
.gr_mem
)
263 pvt
->group
.gr_mem
[num_members
] = NULL
;
265 return (&pvt
->group
);
268 if (pvt
->group
.gr_mem
) {
269 free(pvt
->group
.gr_mem
);
270 pvt
->group
.gr_mem
= NULL
;
279 static struct __res_state
*
280 gr_res_get(struct irs_gr
*this) {
281 struct pvt
*pvt
= (struct pvt
*)this->private;
282 struct dns_p
*dns
= pvt
->dns
;
284 return (__hesiod_res_get(dns
->hes_ctx
));
288 gr_res_set(struct irs_gr
*this, struct __res_state
* res
,
289 void (*free_res
)(void *)) {
290 struct pvt
*pvt
= (struct pvt
*)this->private;
291 struct dns_p
*dns
= pvt
->dns
;
293 __hesiod_res_set(dns
->hes_ctx
, res
, free_res
);
296 #endif /* WANT_IRS_GR */