2 * Copyright (c) 2005 Michael Bushkov <bushman@rsu.ru>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * $FreeBSD: src/usr.sbin/nscd/agents/group.c,v 1.3 2008/10/23 00:15:00 delphij Exp $
29 #include <sys/param.h>
30 #include <sys/types.h>
39 static int group_marshal_func(struct group
*, char *, size_t *);
40 static int group_lookup_func(const char *, size_t, char **, size_t *);
41 static void *group_mp_init_func(void);
42 static int group_mp_lookup_func(char **, size_t *, void *);
43 static void group_mp_destroy_func(void *);
46 group_marshal_func(struct group
*grp
, char *buffer
, size_t *buffer_size
)
49 size_t desired_size
, size
, mem_size
;
52 TRACE_IN(group_marshal_func
);
53 desired_size
= ALIGNBYTES
+ sizeof(struct group
) + sizeof(char *);
55 if (grp
->gr_name
!= NULL
)
56 desired_size
+= strlen(grp
->gr_name
) + 1;
57 if (grp
->gr_passwd
!= NULL
)
58 desired_size
+= strlen(grp
->gr_passwd
) + 1;
60 if (grp
->gr_mem
!= NULL
) {
62 for (mem
= grp
->gr_mem
; *mem
; ++mem
) {
63 desired_size
+= strlen(*mem
) + 1;
67 desired_size
+= ALIGNBYTES
+ (mem_size
+ 1) * sizeof(char *);
70 if ((desired_size
> *buffer_size
) || (buffer
== NULL
)) {
71 *buffer_size
= desired_size
;
72 TRACE_OUT(group_marshal_func
);
76 memcpy(&new_grp
, grp
, sizeof(struct group
));
77 memset(buffer
, 0, desired_size
);
79 *buffer_size
= desired_size
;
80 p
= buffer
+ sizeof(struct group
) + sizeof(char *);
81 memcpy(buffer
+ sizeof(struct group
), &p
, sizeof(char *));
84 if (new_grp
.gr_name
!= NULL
) {
85 size
= strlen(new_grp
.gr_name
);
86 memcpy(p
, new_grp
.gr_name
, size
);
91 if (new_grp
.gr_passwd
!= NULL
) {
92 size
= strlen(new_grp
.gr_passwd
);
93 memcpy(p
, new_grp
.gr_passwd
, size
);
94 new_grp
.gr_passwd
= p
;
98 if (new_grp
.gr_mem
!= NULL
) {
100 memcpy(p
, new_grp
.gr_mem
, sizeof(char *) * mem_size
);
101 new_grp
.gr_mem
= (char **)p
;
102 p
+= sizeof(char *) * (mem_size
+ 1);
104 for (mem
= new_grp
.gr_mem
; *mem
; ++mem
) {
106 memcpy(p
, *mem
, size
);
112 memcpy(buffer
, &new_grp
, sizeof(struct group
));
113 TRACE_OUT(group_marshal_func
);
118 group_lookup_func(const char *key
, size_t key_size
, char **buffer
,
121 enum nss_lookup_type lookup_type
;
126 struct group
*result
;
128 TRACE_IN(group_lookup_func
);
129 assert(buffer
!= NULL
);
130 assert(buffer_size
!= NULL
);
132 if (key_size
< sizeof(enum nss_lookup_type
)) {
133 TRACE_OUT(group_lookup_func
);
136 memcpy(&lookup_type
, key
, sizeof(enum nss_lookup_type
));
138 switch (lookup_type
) {
140 size
= key_size
- sizeof(enum nss_lookup_type
) + 1;
141 name
= (char *)calloc(1, size
);
142 assert(name
!= NULL
);
143 memcpy(name
, key
+ sizeof(enum nss_lookup_type
), size
- 1);
146 if (key_size
< sizeof(enum nss_lookup_type
) +
148 TRACE_OUT(passwd_lookup_func
);
152 memcpy(&gid
, key
+ sizeof(enum nss_lookup_type
), sizeof(gid_t
));
155 TRACE_OUT(group_lookup_func
);
159 switch (lookup_type
) {
162 result
= getgrnam(name
);
166 result
= getgrgid(gid
);
169 /* SHOULD NOT BE REACHED */
173 if (result
!= NULL
) {
174 group_marshal_func(result
, NULL
, buffer_size
);
175 *buffer
= (char *)malloc(*buffer_size
);
176 assert(*buffer
!= NULL
);
177 group_marshal_func(result
, *buffer
, buffer_size
);
180 TRACE_OUT(group_lookup_func
);
181 return (result
== NULL
? NS_NOTFOUND
: NS_SUCCESS
);
185 group_mp_init_func(void)
187 TRACE_IN(group_mp_init_func
);
189 TRACE_OUT(group_mp_init_func
);
195 group_mp_lookup_func(char **buffer
, size_t *buffer_size
, void *mdata
)
197 struct group
*result
;
199 TRACE_IN(group_mp_lookup_func
);
201 if (result
!= NULL
) {
202 group_marshal_func(result
, NULL
, buffer_size
);
203 *buffer
= (char *)malloc(*buffer_size
);
204 assert(*buffer
!= NULL
);
205 group_marshal_func(result
, *buffer
, buffer_size
);
208 TRACE_OUT(group_mp_lookup_func
);
209 return (result
== NULL
? NS_NOTFOUND
: NS_SUCCESS
);
213 group_mp_destroy_func(void *mdata
)
215 TRACE_IN(group_mp_destroy_func
);
216 TRACE_OUT(group_mp_destroy_func
);
220 init_group_agent(void)
222 struct common_agent
*retval
;
224 TRACE_IN(init_group_agent
);
225 retval
= (struct common_agent
*)calloc(1, sizeof(struct common_agent
));
226 assert(retval
!= NULL
);
228 retval
->parent
.name
= strdup("group");
229 assert(retval
->parent
.name
!= NULL
);
231 retval
->parent
.type
= COMMON_AGENT
;
232 retval
->lookup_func
= group_lookup_func
;
234 TRACE_OUT(init_group_agent
);
235 return ((struct agent
*)retval
);
239 init_group_mp_agent(void)
241 struct multipart_agent
*retval
;
243 TRACE_IN(init_group_mp_agent
);
244 retval
= (struct multipart_agent
*)calloc(1,
245 sizeof(struct multipart_agent
));
246 assert(retval
!= NULL
);
248 retval
->parent
.name
= strdup("group");
249 retval
->parent
.type
= MULTIPART_AGENT
;
250 retval
->mp_init_func
= group_mp_init_func
;
251 retval
->mp_lookup_func
= group_mp_lookup_func
;
252 retval
->mp_destroy_func
= group_mp_destroy_func
;
253 assert(retval
->parent
.name
!= NULL
);
255 TRACE_OUT(init_group_mp_agent
);
256 return ((struct agent
*)retval
);