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/passwd.c,v 1.3 2008/10/23 00:15:00 delphij Exp $
29 #include <sys/types.h>
38 static int passwd_marshal_func(struct passwd
*, char *, size_t *);
39 static int passwd_lookup_func(const char *, size_t, char **, size_t *);
40 static void *passwd_mp_init_func(void);
41 static int passwd_mp_lookup_func(char **, size_t *, void *);
42 static void passwd_mp_destroy_func(void *mdata
);
45 passwd_marshal_func(struct passwd
*pwd
, char *buffer
, size_t *buffer_size
)
48 struct passwd new_pwd
;
49 size_t desired_size
, size
;
51 TRACE_IN(passwd_marshal_func
);
52 desired_size
= sizeof(struct passwd
) + sizeof(char *) +
53 strlen(pwd
->pw_name
) + 1;
54 if (pwd
->pw_passwd
!= NULL
)
55 desired_size
+= strlen(pwd
->pw_passwd
) + 1;
56 if (pwd
->pw_class
!= NULL
)
57 desired_size
+= strlen(pwd
->pw_class
) + 1;
58 if (pwd
->pw_gecos
!= NULL
)
59 desired_size
+= strlen(pwd
->pw_gecos
) + 1;
60 if (pwd
->pw_dir
!= NULL
)
61 desired_size
+= strlen(pwd
->pw_dir
) + 1;
62 if (pwd
->pw_shell
!= NULL
)
63 desired_size
+= strlen(pwd
->pw_shell
) + 1;
65 if ((*buffer_size
< desired_size
) || (buffer
== NULL
)) {
66 *buffer_size
= desired_size
;
67 TRACE_OUT(passwd_marshal_func
);
71 memcpy(&new_pwd
, pwd
, sizeof(struct passwd
));
72 memset(buffer
, 0, desired_size
);
74 *buffer_size
= desired_size
;
75 p
= buffer
+ sizeof(struct passwd
) + sizeof(char *);
76 memcpy(buffer
+ sizeof(struct passwd
), &p
, sizeof(char *));
78 if (new_pwd
.pw_name
!= NULL
) {
79 size
= strlen(new_pwd
.pw_name
);
80 memcpy(p
, new_pwd
.pw_name
, size
);
85 if (new_pwd
.pw_passwd
!= NULL
) {
86 size
= strlen(new_pwd
.pw_passwd
);
87 memcpy(p
, new_pwd
.pw_passwd
, size
);
88 new_pwd
.pw_passwd
= p
;
92 if (new_pwd
.pw_class
!= NULL
) {
93 size
= strlen(new_pwd
.pw_class
);
94 memcpy(p
, new_pwd
.pw_class
, size
);
99 if (new_pwd
.pw_gecos
!= NULL
) {
100 size
= strlen(new_pwd
.pw_gecos
);
101 memcpy(p
, new_pwd
.pw_gecos
, size
);
102 new_pwd
.pw_gecos
= p
;
106 if (new_pwd
.pw_dir
!= NULL
) {
107 size
= strlen(new_pwd
.pw_dir
);
108 memcpy(p
, new_pwd
.pw_dir
, size
);
113 if (new_pwd
.pw_shell
!= NULL
) {
114 size
= strlen(new_pwd
.pw_shell
);
115 memcpy(p
, new_pwd
.pw_shell
, size
);
116 new_pwd
.pw_shell
= p
;
120 memcpy(buffer
, &new_pwd
, sizeof(struct passwd
));
121 TRACE_OUT(passwd_marshal_func
);
126 passwd_lookup_func(const char *key
, size_t key_size
, char **buffer
,
129 enum nss_lookup_type lookup_type
;
134 struct passwd
*result
;
136 TRACE_IN(passwd_lookup_func
);
137 assert(buffer
!= NULL
);
138 assert(buffer_size
!= NULL
);
140 if (key_size
< sizeof(enum nss_lookup_type
)) {
141 TRACE_OUT(passwd_lookup_func
);
144 memcpy(&lookup_type
, key
, sizeof(enum nss_lookup_type
));
146 switch (lookup_type
) {
148 size
= key_size
- sizeof(enum nss_lookup_type
) + 1;
149 login
= (char *)calloc(1, size
);
150 assert(login
!= NULL
);
151 memcpy(login
, key
+ sizeof(enum nss_lookup_type
), size
- 1);
154 if (key_size
< sizeof(enum nss_lookup_type
) +
156 TRACE_OUT(passwd_lookup_func
);
160 memcpy(&uid
, key
+ sizeof(enum nss_lookup_type
), sizeof(uid_t
));
163 TRACE_OUT(passwd_lookup_func
);
167 switch (lookup_type
) {
169 result
= getpwnam(login
);
173 result
= getpwuid(uid
);
176 /* SHOULD NOT BE REACHED */
180 if (result
!= NULL
) {
181 passwd_marshal_func(result
, NULL
, buffer_size
);
182 *buffer
= (char *)malloc(*buffer_size
);
183 assert(*buffer
!= NULL
);
184 passwd_marshal_func(result
, *buffer
, buffer_size
);
187 TRACE_OUT(passwd_lookup_func
);
188 return (result
== NULL
? NS_NOTFOUND
: NS_SUCCESS
);
192 passwd_mp_init_func(void)
194 TRACE_IN(passwd_mp_init_func
);
196 TRACE_OUT(passwd_mp_init_func
);
202 passwd_mp_lookup_func(char **buffer
, size_t *buffer_size
, void *mdata
)
204 struct passwd
*result
;
206 TRACE_IN(passwd_mp_lookup_func
);
208 if (result
!= NULL
) {
209 passwd_marshal_func(result
, NULL
, buffer_size
);
210 *buffer
= (char *)malloc(*buffer_size
);
211 assert(*buffer
!= NULL
);
212 passwd_marshal_func(result
, *buffer
, buffer_size
);
215 TRACE_OUT(passwd_mp_lookup_func
);
216 return (result
== NULL
? NS_NOTFOUND
: NS_SUCCESS
);
220 passwd_mp_destroy_func(void *mdata
)
222 TRACE_IN(passwd_mp_destroy_func
);
223 TRACE_OUT(passwd_mp_destroy_func
);
227 init_passwd_agent(void)
229 struct common_agent
*retval
;
231 TRACE_IN(init_passwd_agent
);
232 retval
= (struct common_agent
*)calloc(1, sizeof(struct common_agent
));
233 assert(retval
!= NULL
);
235 retval
->parent
.name
= strdup("passwd");
236 assert(retval
->parent
.name
!= NULL
);
238 retval
->parent
.type
= COMMON_AGENT
;
239 retval
->lookup_func
= passwd_lookup_func
;
241 TRACE_OUT(init_passwd_agent
);
242 return ((struct agent
*)retval
);
246 init_passwd_mp_agent(void)
248 struct multipart_agent
*retval
;
250 TRACE_IN(init_passwd_mp_agent
);
251 retval
= (struct multipart_agent
*)calloc(1,
252 sizeof(struct multipart_agent
));
253 assert(retval
!= NULL
);
255 retval
->parent
.name
= strdup("passwd");
256 retval
->parent
.type
= MULTIPART_AGENT
;
257 retval
->mp_init_func
= passwd_mp_init_func
;
258 retval
->mp_lookup_func
= passwd_mp_lookup_func
;
259 retval
->mp_destroy_func
= passwd_mp_destroy_func
;
260 assert(retval
->parent
.name
!= NULL
);
262 TRACE_OUT(init_passwd_mp_agent
);
263 return ((struct agent
*)retval
);