4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
24 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
33 #include <sys/param.h>
38 #include <rpcsvc/nfs_prot.h>
39 #include "automount.h"
42 * Each name service is represented by a ns_info structure.
45 char *ns_name
; /* service name */
46 void (*ns_init
)(); /* initialization routine */
47 int (*ns_getmapent
)(); /* get map entry given key */
48 int (*ns_loadmaster
)(); /* load master map */
49 int (*ns_loaddirect
)(); /* load direct map */
50 int (*ns_getmapkeys
)(); /* readdir */
53 static struct ns_info ns_info
[] = {
55 "files", init_files
, getmapent_files
,
56 loadmaster_files
, loaddirect_files
,
59 "ldap", init_ldap
, getmapent_ldap
,
60 loadmaster_ldap
, loaddirect_ldap
,
63 "nis", init_nis
, getmapent_nis
,
64 loadmaster_nis
, loaddirect_nis
,
67 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
70 static struct ns_info
*get_next_ns(struct __nsw_lookup
**, int);
73 ns_setup(char **stack
, char ***stkptr
)
77 for (nsp
= ns_info
; nsp
->ns_name
; nsp
++) {
78 nsp
->ns_init(stack
, stkptr
);
82 static struct ns_info
*
83 get_next_ns(curr_ns
, curr_nserr
)
84 struct __nsw_lookup
**curr_ns
;
87 static struct __nsw_switchconfig
*conf
= NULL
;
88 enum __nsw_parse_err pserr
;
89 struct __nsw_lookup
*lkp
;
93 /* __nsw_getconfig() is protected by a lock */
94 conf
= __nsw_getconfig("automount", &pserr
);
100 if (*curr_ns
== NULL
)
105 /* __NSW_ACTION is MT-Safe */
106 if (__NSW_ACTION(lkp
, curr_nserr
) == __NSW_RETURN
)
111 for (; lkp
; lkp
= lkp
->next
) {
112 for (nsp
= ns_info
; nsp
->ns_name
; nsp
++) {
113 if (strcmp(lkp
->service_name
, nsp
->ns_name
) == 0) {
119 * Note: if we get here then we've found
120 * an unsupported name service.
128 getmapent(key
, mapname
, ml
, stack
, stkptr
, iswildcard
, isrestricted
)
131 char **stack
, ***stkptr
;
135 struct __nsw_lookup
*curr_ns
= NULL
;
136 int ns_err
= __NSW_SUCCESS
;
139 if (strcmp(mapname
, "-hosts") == 0) {
140 (void) strcpy(ml
->linebuf
, "-hosts");
141 return (__NSW_SUCCESS
);
144 if (*mapname
== '/') /* must be a file */
145 return (getmapent_files(key
, mapname
, ml
, stack
, stkptr
,
146 iswildcard
, isrestricted
));
148 while ((nsp
= get_next_ns(&curr_ns
, ns_err
)) != NULL
) {
149 ns_err
= nsp
->ns_getmapent(key
, mapname
, ml
, stack
, stkptr
,
150 iswildcard
, isrestricted
);
151 if (ns_err
== __NSW_SUCCESS
)
152 return (__NSW_SUCCESS
);
155 return (__NSW_UNAVAIL
);
159 loadmaster_map(mapname
, defopts
, stack
, stkptr
)
160 char *mapname
, *defopts
;
161 char **stack
, ***stkptr
;
163 struct __nsw_lookup
*curr_ns
= NULL
;
164 int ns_err
= __NSW_SUCCESS
;
167 if (*mapname
== '/') /* must be a file */
168 return (loadmaster_files(mapname
, defopts
, stack
, stkptr
));
170 while ((nsp
= get_next_ns(&curr_ns
, ns_err
)) != NULL
) {
171 ns_err
= nsp
->ns_loadmaster(mapname
, defopts
, stack
, stkptr
);
172 if (ns_err
== __NSW_SUCCESS
)
173 return (__NSW_SUCCESS
);
176 return (__NSW_UNAVAIL
);
180 loaddirect_map(mapname
, localmap
, defopts
, stack
, stkptr
)
181 char *mapname
, *localmap
, *defopts
;
182 char **stack
, ***stkptr
;
184 struct __nsw_lookup
*curr_ns
= NULL
;
185 int ns_err
= __NSW_SUCCESS
;
188 if (*mapname
== '/') /* must be a file */
189 return (loaddirect_files(mapname
, localmap
, defopts
,
192 while ((nsp
= get_next_ns(&curr_ns
, ns_err
)) != NULL
) {
193 ns_err
= nsp
->ns_loaddirect(mapname
, localmap
, defopts
, stack
,
195 if (ns_err
== __NSW_SUCCESS
)
196 return (__NSW_SUCCESS
);
199 return (__NSW_UNAVAIL
);
203 gethostkeys(mapname
, list
, error
, cache_time
)
205 struct dir_entry
**list
;
210 int bufferlen
= 1000;
211 struct dir_entry
*last
= NULL
;
215 *cache_time
= RDDIR_CACHE_TIME
* 2;
218 trace_prt(1, "gethostkeys called\n");
221 syslog(LOG_ERR
, "gethostkeys: sethostent failed");
223 return (__NSW_UNAVAIL
);
226 buffer
= (char *)malloc(bufferlen
);
227 if (buffer
== NULL
) {
228 syslog(LOG_ERR
, "gethostkeys: malloc of buffer failed");
230 return (__NSW_UNAVAIL
);
233 while (gethostent_r(&ent
, buffer
, bufferlen
, error
)) {
237 if (add_dir_entry(ent
.h_name
, list
, &last
)) {
241 if (ent
.h_aliases
== NULL
)
242 goto done
; /* no aliases */
243 for (p
= ent
.h_aliases
; *p
!= 0; p
++) {
244 if (strcmp(*p
, ent
.h_name
) != 0) {
246 * add alias only if different
247 * from canonical name
249 if (add_dir_entry(*p
, list
, &last
)) {
255 assert(last
!= NULL
);
257 done
: if (*list
!= NULL
) {
259 * list of entries found
265 return (__NSW_SUCCESS
);
269 * enumerate all entries in the map in the various name services.
272 getmapkeys(mapname
, list
, error
, cache_time
, stack
, stkptr
, uid
)
274 struct dir_entry
**list
;
277 char **stack
, ***stkptr
;
281 struct __nsw_lookup
*curr_ns
= NULL
;
282 int ns_err
= __NSW_SUCCESS
;
286 if (*mapname
== '/') /* must be a file */
287 return (getmapkeys_files(mapname
, list
, error
, cache_time
,
289 if (strcmp(mapname
, "-hosts") == 0) {
290 return (gethostkeys(mapname
, list
, error
, cache_time
));
293 while ((nsp
= get_next_ns(&curr_ns
, ns_err
)) != NULL
) {
294 ns_err
= nsp
->ns_getmapkeys(mapname
, list
, error
,
295 cache_time
, stack
, stkptr
);
298 * return success if listing was successful
299 * for at least one name service
305 * XXX force next name service
307 if (ns_err
!= __NSW_UNAVAIL
)
308 ns_err
= __NSW_NOTFOUND
;
312 * if succeeded at least once, return error=0
317 return (success
? __NSW_SUCCESS
: __NSW_NOTFOUND
);