Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 373 lines (335 sloc) 14.023 kb
ac2936d @gstrauss prep for public release
authored
1 /*
2 * nss_mcdb - common routines to query mcdb of nsswitch.conf databases
3 *
4 * Copyright (c) 2010, Glue Logic LLC. All rights reserved. code()gluelogic.com
5 *
6 * This file is part of mcdb.
7 *
8 * mcdb is free software: you can redistribute it and/or modify it under
9 * the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation, either version 2.1 of the License, or
11 * (at your option) any later version.
12 *
13 * mcdb is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with mcdb. If not, see <http://www.gnu.org/licenses/>.
20 */
21
7a8f2ec @gstrauss create nss_mcdb.h (extract from nss_mcdb.c)
authored
22 #include "nss_mcdb.h"
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
23
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored
27 #include <unistd.h>
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
28 #include <errno.h>
29 #include <stdbool.h>
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored
30 #include <stdint.h>
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
31 #include <stdlib.h>
32 #include <string.h>
33
34 #ifdef _THREAD_SAFE
35 #include <pthread.h> /* pthread_mutex_t, pthread_mutex_{lock,unlock}() */
36 #else
37 #define pthread_mutex_lock(mutexp) 0
38 #define pthread_mutex_unlock(mutexp) (void)0
39 #endif
40
a3a871d @gstrauss doc: add references to 'man' pages
authored
41 /*
42 * man nsswitch.conf
43 * /etc/nsswitch.conf
ecf7731 @gstrauss rewrite nss_mcdb* based on prototypes in The GNU C Library documentation
authored
44 * /lib/libnss_XXXXX.so.2, e.g. /lib/libnss_files.so.2
a3a871d @gstrauss doc: add references to 'man' pages
authored
45 * rpm -qil nss_db nss_ldap
ecf7731 @gstrauss rewrite nss_mcdb* based on prototypes in The GNU C Library documentation
authored
46 * The GNU C Library (manual)
4f5afcc @gstrauss minor doc update
authored
47 * http://www.gnu.org/s/libc/manual/html_node/Name-Service-Switch.html
48 * http://www.gnu.org/s/libc/manual/html_node/NSS-Module-Function-Internals.html
ecf7731 @gstrauss rewrite nss_mcdb* based on prototypes in The GNU C Library documentation
authored
49 * 28.4.2 Internals of the NSS Module Functions
a3a871d @gstrauss doc: add references to 'man' pages
authored
50 */
51
116e0d2 @gstrauss - rework thread-safe interfaces
authored
52 /* Note various thread-safety optimizations are taken below since these routines
53 * retain mmap of mcdb files once opened. Since the mcdb files are not munmap'd
54 * there are no race conditions having to do with opening and closing the mcdb.
55 * (Opening each mcdb is protect by a mutex.)
56 *
57 * shadow.mcdb is kept mmap'd, like all other mcdb. If this is an issue, then
58 * modify setspent(), endspent(), and getspnam() to use custom routines instead
59 * of the generic routines. The shadow routines would then mcdb_mmap_create(),
60 * use mcdb, and mcdb_mmap_destroy() every getspnam() or {set,get,end}spent().
61 * (and -would not- use the static storage (e.g. no use of _nss_mcdb_mmap_st[]))
62 */
63
406c67c @gstrauss nss_mcdb.c
authored
64 /* compile-time setting for security
116e0d2 @gstrauss - rework thread-safe interfaces
authored
65 * /etc/mcdb/ is recommended so that .mcdb are on same partition as flat files
66 * (implies that if flat files visible, then likely so are .mcdb equivalents) */
406c67c @gstrauss nss_mcdb.c
authored
67 #ifndef NSS_MCDB_DBPATH
68 #define NSS_MCDB_DBPATH "/etc/mcdb/"
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
69 #endif
70
a7f6ba9 @gstrauss add symbol aliases with "hidden" DSO visibility
authored
71 /* NOTE: path to db must match up to enum nss_dbtype index
72 * (static two-dimensional array instead of ptrs to reduce num DSO relocations)
73 * (+14 for longest name, e.g. "protocols.mcdb") */
74 static const char
75 _nss_dbnames[NSS_DBTYPE_SENTINEL][sizeof(NSS_MCDB_DBPATH)+14] = {
116e0d2 @gstrauss - rework thread-safe interfaces
authored
76 NSS_MCDB_DBPATH"aliases.mcdb",
77 NSS_MCDB_DBPATH"ethers.mcdb",
78 NSS_MCDB_DBPATH"group.mcdb",
79 NSS_MCDB_DBPATH"hosts.mcdb",
80 NSS_MCDB_DBPATH"netgroup.mcdb",
81 NSS_MCDB_DBPATH"networks.mcdb",
82 NSS_MCDB_DBPATH"passwd.mcdb",
83 NSS_MCDB_DBPATH"protocols.mcdb",
84 NSS_MCDB_DBPATH"publickey.mcdb",
85 NSS_MCDB_DBPATH"rpc.mcdb",
86 NSS_MCDB_DBPATH"services.mcdb",
87 NSS_MCDB_DBPATH"shadow.mcdb"
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
88 };
89
a7f6ba9 @gstrauss add symbol aliases with "hidden" DSO visibility
authored
90 #define _nss_num_dbs NSS_DBTYPE_SENTINEL
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored
91
8dc21f1 @gstrauss better encapsulation of access to static variables
authored
92 static struct mcdb_mmap _nss_mcdb_mmap_st[_nss_num_dbs];
93 static struct mcdb_mmap *_nss_mcdb_mmap[_nss_num_dbs];
94
95 /* set*ent(), get*ent(), end*ent() are not thread-safe */
96 /* (use thread-local storage of static struct mcdb array to increase safety) */
97
98 static __thread struct mcdb _nss_mcdb_st[_nss_num_dbs];
99
a17d095 @gstrauss nss_mcdb - register atexit() to cleanup open nss mcdb if -D_FORTIFY_SOUR...
authored
100 #ifdef _FORTIFY_SOURCE
101 static void _nss_mcdb_atexit(void)
102 {
103 struct mcdb_mmap * restrict map;
104 for (uintptr_t i = 0; i < _nss_num_dbs; ++i) {
105 map = &_nss_mcdb_mmap_st[i];
6336e94 @gstrauss some addtl sanity checks detect incorrect API use
authored
106 if (map->ptr || map->fname)
a7f6ba9 @gstrauss add symbol aliases with "hidden" DSO visibility
authored
107 mcdb_mmap_destroy_h(map);
a17d095 @gstrauss nss_mcdb - register atexit() to cleanup open nss mcdb if -D_FORTIFY_SOUR...
authored
108 }
109 }
110 #endif
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored
111
116e0d2 @gstrauss - rework thread-safe interfaces
authored
112 /* custom free for mcdb_mmap_* routines to not free initial static storage */
d5df439 @gstrauss enable/disable inlining selectively for those routine that will remain
authored
113 static void
116e0d2 @gstrauss - rework thread-safe interfaces
authored
114 _nss_mcdb_mmap_fn_free(void * const v)
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
115 {
116e0d2 @gstrauss - rework thread-safe interfaces
authored
116 /* do not free initial static storage */
117 if ( v >=(void *)&_nss_mcdb_mmap_st[0]
118 && v < (void *)&_nss_mcdb_mmap_st[_nss_num_dbs] )
119 return;
120
121 /* otherwise free() allocated memory */
122 free(v);
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
123 }
124
125 static bool __attribute_noinline__
126 _nss_mcdb_db_openshared(const enum nss_dbtype dbtype)
127 __attribute_cold__ __attribute_warn_unused_result__;
128 static bool __attribute_noinline__
129 _nss_mcdb_db_openshared(const enum nss_dbtype dbtype)
130 {
131 #ifdef _THREAD_SAFE
8dc21f1 @gstrauss better encapsulation of access to static variables
authored
132 static pthread_mutex_t _nss_mcdb_global_mutex = PTHREAD_MUTEX_INITIALIZER;
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
133 #endif
8dc21f1 @gstrauss better encapsulation of access to static variables
authored
134 struct mcdb_mmap * const restrict map = &_nss_mcdb_mmap_st[dbtype];
116e0d2 @gstrauss - rework thread-safe interfaces
authored
135 bool rc;
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
136
8dc21f1 @gstrauss better encapsulation of access to static variables
authored
137 if (pthread_mutex_lock(&_nss_mcdb_global_mutex) != 0)
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
138 return false;
1c94d91 @gstrauss nss_mcdb.c - add __builtin_expect() compiler hint in a couple specific p...
authored
139 if (__builtin_expect( _nss_mcdb_mmap[dbtype] != 0, false)) {
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
140 /* init'ed by another thread while waiting for mutex */
8dc21f1 @gstrauss better encapsulation of access to static variables
authored
141 pthread_mutex_unlock(&_nss_mcdb_global_mutex);
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
142 return true;
143 }
144
a17d095 @gstrauss nss_mcdb - register atexit() to cleanup open nss mcdb if -D_FORTIFY_SOUR...
authored
145 #ifdef _FORTIFY_SOURCE
146 { static bool atexit_once = true;
147 if (atexit_once) { atexit_once = false; atexit(_nss_mcdb_atexit); } }
148 #endif
149
116e0d2 @gstrauss - rework thread-safe interfaces
authored
150 /* pass full path in fname instead of separate dirname and basename
151 * (not using openat(), fstatat() where someone might close dfd on us)
152 * use static storage for initial struct mcdb_mmap for each dbtype
153 * and therefore pass custom _nss_mcdb_mmap_fn_free() to not free statics */
a7f6ba9 @gstrauss add symbol aliases with "hidden" DSO visibility
authored
154 if ((rc = (NULL != mcdb_mmap_create_h(map, NULL, _nss_dbnames[dbtype],
155 malloc, _nss_mcdb_mmap_fn_free)))) {
116e0d2 @gstrauss - rework thread-safe interfaces
authored
156 /*(ought to be preceded by StoreStore memory barrier)*/
157 _nss_mcdb_mmap[dbtype] = map;
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
158 }
159
8dc21f1 @gstrauss better encapsulation of access to static variables
authored
160 pthread_mutex_unlock(&_nss_mcdb_global_mutex);
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
161 return rc;
162 }
163
38a0578 @gstrauss make set*ent(), get*ent(), end*ent() work
authored
164 /* Flag to skip mcdb stat() check for protocols, rpc, services databases.
165 * Default: enabled
166 * (similar to set*ent(int stayopen) flag in glibc for netdb databases)
8dc21f1 @gstrauss better encapsulation of access to static variables
authored
167 * (protocols, rpc, services are unlikely to change frequently in most configs)
38a0578 @gstrauss make set*ent(), get*ent(), end*ent() work
authored
168 * (hosts and networks database lookups differ: they perform mcdb stat() check)
d35a146 @gstrauss nss_mcdb_acct*
authored
169 * (future: might provide accessor routine to enable/disable)
170 * (FreeBSD provides setpassent() and setgroupent() API with stayopen flag) */
8dc21f1 @gstrauss better encapsulation of access to static variables
authored
171 static bool _nss_mcdb_stayopen = true;
172
173 /* release shared mcdb_mmap */
116e0d2 @gstrauss - rework thread-safe interfaces
authored
174 #define _nss_mcdb_db_relshared(map,flags) \
a7f6ba9 @gstrauss add symbol aliases with "hidden" DSO visibility
authored
175 mcdb_mmap_thread_registration_h(&(map),(flags))
8dc21f1 @gstrauss better encapsulation of access to static variables
authored
176
177 /* get shared mcdb_mmap */
33175f9 @gstrauss clang supports most gcc __attribute__, __builtin_*
authored
178 static struct mcdb_mmap * __attribute_regparm__((2))
35abc99 @gstrauss modify mcdb_register_access() to take an enum of flags to control behavi...
authored
179 _nss_mcdb_db_getshared(const enum nss_dbtype dbtype,
116e0d2 @gstrauss - rework thread-safe interfaces
authored
180 const enum mcdb_flags mcdb_flags)
936cbe4 @gstrauss compile with clang; fix warnings and errors
authored
181 __attribute_warn_unused_result__;
33175f9 @gstrauss clang supports most gcc __attribute__, __builtin_*
authored
182 static struct mcdb_mmap * __attribute_regparm__((2))
35abc99 @gstrauss modify mcdb_register_access() to take an enum of flags to control behavi...
authored
183 _nss_mcdb_db_getshared(const enum nss_dbtype dbtype,
116e0d2 @gstrauss - rework thread-safe interfaces
authored
184 const enum mcdb_flags mcdb_flags)
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
185 {
8dc21f1 @gstrauss better encapsulation of access to static variables
authored
186 /* reuse set*ent(),get*ent(),end*end() session if open in current thread */
187 if (_nss_mcdb_st[dbtype].map != NULL)
188 return _nss_mcdb_st[dbtype].map;
189
190 /* check if db is open and up-to-date, or else open db
191 * (continue with open database if failure refreshing) */
192 if (__builtin_expect(_nss_mcdb_mmap[dbtype] != 0, true)) {
193 /* protocols, rpc, services unlikely to change often in most configs
3389f4c @gstrauss AIX LAM netdb, Solaris NSS read-only using mcdb
authored
194 * Therefore, skip stat() check if configured (default skips stat())
195 * (Implication: must restart nscd if any of these three files change)*/
8dc21f1 @gstrauss better encapsulation of access to static variables
authored
196 switch (dbtype) {
197 case NSS_DBTYPE_PROTOCOLS:
198 case NSS_DBTYPE_RPC:
199 case NSS_DBTYPE_SERVICES: if (_nss_mcdb_stayopen) break;
a7f6ba9 @gstrauss add symbol aliases with "hidden" DSO visibility
authored
200 default:
201 /*(void)mcdb_mmap_refresh_threadsafe(&_nss_mcdb_mmap[dbtype]);*/
202 (void)(__builtin_expect(
203 mcdb_mmap_refresh_check_h(_nss_mcdb_mmap[dbtype]), true)
204 || __builtin_expect(
205 mcdb_mmap_reopen_threadsafe_h(&_nss_mcdb_mmap[dbtype]), true));
206 break;
8dc21f1 @gstrauss better encapsulation of access to static variables
authored
207 }
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
208 }
8dc21f1 @gstrauss better encapsulation of access to static variables
authored
209 else if (!_nss_mcdb_db_openshared(dbtype))
210 return NULL;
211
a7f6ba9 @gstrauss add symbol aliases with "hidden" DSO visibility
authored
212 return mcdb_mmap_thread_registration_h(&_nss_mcdb_mmap[dbtype], mcdb_flags)
8dc21f1 @gstrauss better encapsulation of access to static variables
authored
213 ? _nss_mcdb_mmap[dbtype]
7a2bdb9 @gstrauss more consistent setting of errno
authored
214 : NULL; /* (fails if obtaining mutex fails, i.e. EAGAIN) */
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
215 }
216
a7f6ba9 @gstrauss add symbol aliases with "hidden" DSO visibility
authored
217 INTERNAL nss_status_t __attribute_noinline__ /*(skip _nss_mcdb_getent inline)*/
e73ac45 @gstrauss nss_mcdb - pass stayopen flag for netdb set*ent()
authored
218 nss_mcdb_setent(const enum nss_dbtype dbtype,
219 const int stayopen __attribute_unused__)
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
220 {
8dc21f1 @gstrauss better encapsulation of access to static variables
authored
221 struct mcdb * const restrict m = &_nss_mcdb_st[dbtype];
116e0d2 @gstrauss - rework thread-safe interfaces
authored
222 const enum mcdb_flags mcdb_flags = MCDB_REGISTER_USE_INCR;
35abc99 @gstrauss modify mcdb_register_access() to take an enum of flags to control behavi...
authored
223 if (m->map != NULL
224 || (m->map = _nss_mcdb_db_getshared(dbtype, mcdb_flags)) != NULL) {
65ded13 @gstrauss mcdb iterator interface
authored
225 m->hpos = (uintptr_t)(m->map->ptr + MCDB_HEADER_SZ);
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
226 return NSS_STATUS_SUCCESS;
227 }
228 return NSS_STATUS_UNAVAIL;
229 }
230
a7f6ba9 @gstrauss add symbol aliases with "hidden" DSO visibility
authored
231 INTERNAL nss_status_t
7718ee5 @gstrauss rename routines and structs with prefix matching filename containing cod...
authored
232 nss_mcdb_endent(const enum nss_dbtype dbtype)
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
233 {
8dc21f1 @gstrauss better encapsulation of access to static variables
authored
234 struct mcdb * const restrict m = &_nss_mcdb_st[dbtype];
e428dc2 @gstrauss minor fixes
authored
235 struct mcdb_mmap *map = m->map;
116e0d2 @gstrauss - rework thread-safe interfaces
authored
236 const enum mcdb_flags mcdb_flags =
237 MCDB_REGISTER_USE_DECR | MCDB_REGISTER_MUNMAP_SKIP;
e428dc2 @gstrauss minor fixes
authored
238 m->map = NULL; /* set thread-local ptr NULL even though munmap skipped */
239 return (map == NULL || _nss_mcdb_db_relshared(map, mcdb_flags))
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
240 ? NSS_STATUS_SUCCESS
7a2bdb9 @gstrauss more consistent setting of errno
authored
241 : NSS_STATUS_UNAVAIL; /* (fails if obtaining mutex fails, i.e. EAGAIN) */
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
242 }
243
8dc21f1 @gstrauss better encapsulation of access to static variables
authored
244 /* mcdb get*ent() walks db returning successive keys with '=' tag char */
a7f6ba9 @gstrauss add symbol aliases with "hidden" DSO visibility
authored
245 INTERNAL nss_status_t
7718ee5 @gstrauss rename routines and structs with prefix matching filename containing cod...
authored
246 nss_mcdb_getent(const enum nss_dbtype dbtype,
65ded13 @gstrauss mcdb iterator interface
authored
247 const struct nss_mcdb_vinfo * const restrict v)
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
248 {
65ded13 @gstrauss mcdb iterator interface
authored
249 struct mcdb_iter iter;
e73ac45 @gstrauss nss_mcdb - pass stayopen flag for netdb set*ent()
authored
250 struct mcdb * const m = &_nss_mcdb_st[dbtype];
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored
251 if (__builtin_expect(m->map == NULL, false)
e73ac45 @gstrauss nss_mcdb - pass stayopen flag for netdb set*ent()
authored
252 && nss_mcdb_setent(dbtype,0) != NSS_STATUS_SUCCESS) {
7718ee5 @gstrauss rename routines and structs with prefix matching filename containing cod...
authored
253 *v->errnop = errno;
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
254 return NSS_STATUS_UNAVAIL;
ecf7731 @gstrauss rewrite nss_mcdb* based on prototypes in The GNU C Library documentation
authored
255 }
a7f6ba9 @gstrauss add symbol aliases with "hidden" DSO visibility
authored
256 mcdb_iter_init_h(&iter, m);
65ded13 @gstrauss mcdb iterator interface
authored
257 iter.ptr = (unsigned char *)m->hpos;
a7f6ba9 @gstrauss add symbol aliases with "hidden" DSO visibility
authored
258 while (mcdb_iter_h(&iter)) {
65ded13 @gstrauss mcdb iterator interface
authored
259 if (mcdb_iter_keyptr(&iter)[0] == (unsigned char)'=') {
260 m->hpos = (uintptr_t)iter.ptr;
261 /* valid data for mcdb_datapos() mcdb_datalen() mcdb_dataptr() */
262 m->dpos = mcdb_iter_datapos(&iter);
263 m->dlen = mcdb_iter_datalen(&iter);
7718ee5 @gstrauss rename routines and structs with prefix matching filename containing cod...
authored
264 return v->decode(m, v);
65ded13 @gstrauss mcdb iterator interface
authored
265 }
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
266 }
65ded13 @gstrauss mcdb iterator interface
authored
267 m->hpos = (uintptr_t)iter.ptr;
7718ee5 @gstrauss rename routines and structs with prefix matching filename containing cod...
authored
268 *v->errnop = errno = ENOENT;
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored
269 return NSS_STATUS_NOTFOUND;
270 }
271
e73ac45 @gstrauss nss_mcdb - pass stayopen flag for netdb set*ent()
authored
272 #if 0 /* implemented, but not enabling by default; often used only with NIS+ */
273 INTERNAL nss_status_t
274 nss_mcdb_getentstart(const enum nss_dbtype dbtype,
275 const struct nss_mcdb_vinfo * const restrict v)
276 {
277 struct mcdb * const m = &_nss_mcdb_st[dbtype];
278 if (__builtin_expect( nss_mcdb_setent(dbtype,0) != NSS_STATUS_SUCCESS, 0)) {
279 *v->errnop = errno;
280 return NSS_STATUS_UNAVAIL;
281 }
282 /* query for key; subsequent calls to nss_mcdb_getentnext() reuse keyptr */
283 if ( __builtin_expect( mcdb_findtagstart_h(m,v->key,v->klen,v->tagc), 1)
284 && __builtin_expect( mcdb_findtagnext_h(m,v->key,v->klen,v->tagc), 1))
285 return NSS_STATUS_SUCCESS;
286 *v->errnop = errno = ENOENT;
287 return NSS_STATUS_NOTFOUND;
288 }
289
290 INTERNAL nss_status_t
291 nss_mcdb_getentnext(const enum nss_dbtype dbtype,
292 const struct nss_mcdb_vinfo * const restrict v)
293 {
294 struct mcdb * const restrict m = &_nss_mcdb_st[dbtype];
295 if (__builtin_expect(m->map == NULL, false)) { /* db must already be open */
296 *v->errnop = errno;
297 return NSS_STATUS_UNAVAIL;
298 }
299 if (m->loop != 0) { /* prior search must have succeeded */
300 nss_status_t status = v->decode(m, v); /* decode previous found entry */
301 if (status != NSS_STATUS_SUCCESS)
302 return status;
303 /*(safe to use keyptr since mcdb is held open during getent iteration)*/
304 status = mcdb_findtagnext_h(m, (char *)mcdb_keyptr(m),
305 mcdb_keylen(m), v->tagc);
306 /*(ignore status until next call; m->loop == 0 if not found)*/
307 return NSS_STATUS_SUCCESS;
308 }
309 *v->errnop = errno = ENOENT;
310 return NSS_STATUS_NOTFOUND;
311 }
312 #endif
313
a7f6ba9 @gstrauss add symbol aliases with "hidden" DSO visibility
authored
314 INTERNAL nss_status_t
7718ee5 @gstrauss rename routines and structs with prefix matching filename containing cod...
authored
315 nss_mcdb_get_generic(const enum nss_dbtype dbtype,
316 const struct nss_mcdb_vinfo * const restrict v)
faf374e @gstrauss continue working on nss_mcdb
authored
317 {
318 struct mcdb m;
52f0225 @gstrauss portability:
authored
319 nss_status_t status;
116e0d2 @gstrauss - rework thread-safe interfaces
authored
320 const enum mcdb_flags mcdb_flags_lock =
321 MCDB_REGISTER_USE_INCR | MCDB_REGISTER_MUTEX_LOCK_HOLD;
faf374e @gstrauss continue working on nss_mcdb
authored
322
35abc99 @gstrauss modify mcdb_register_access() to take an enum of flags to control behavi...
authored
323 /* Queries to mcdb are quick, so attempt to reduce locking overhead.
324 * Set mcdb_flags to get and release mcdb_global_mutex once instead of
325 * grab/release mutex to register, then grab/release mutex to unregister */
326
327 m.map = _nss_mcdb_db_getshared(dbtype, mcdb_flags_lock);
ecf7731 @gstrauss rewrite nss_mcdb* based on prototypes in The GNU C Library documentation
authored
328 if (__builtin_expect(m.map == NULL, false)) {
7718ee5 @gstrauss rename routines and structs with prefix matching filename containing cod...
authored
329 *v->errnop = errno;
faf374e @gstrauss continue working on nss_mcdb
authored
330 return NSS_STATUS_UNAVAIL;
ecf7731 @gstrauss rewrite nss_mcdb* based on prototypes in The GNU C Library documentation
authored
331 }
faf374e @gstrauss continue working on nss_mcdb
authored
332
a7f6ba9 @gstrauss add symbol aliases with "hidden" DSO visibility
authored
333 if ( __builtin_expect( mcdb_findtagstart_h(&m,v->key,v->klen,v->tagc), 1)
334 && __builtin_expect( mcdb_findtagnext_h(&m,v->key,v->klen,v->tagc), 1))
7718ee5 @gstrauss rename routines and structs with prefix matching filename containing cod...
authored
335 status = v->decode(&m, v);
7a2bdb9 @gstrauss more consistent setting of errno
authored
336 else {
337 status = NSS_STATUS_NOTFOUND;
7718ee5 @gstrauss rename routines and structs with prefix matching filename containing cod...
authored
338 *v->errnop = errno = ENOENT;
7a2bdb9 @gstrauss more consistent setting of errno
authored
339 }
faf374e @gstrauss continue working on nss_mcdb
authored
340
35abc99 @gstrauss modify mcdb_register_access() to take an enum of flags to control behavi...
authored
341 /* set*ent(),get*ent(),end*end() session not open/reused in current thread*/
342 if (_nss_mcdb_st[dbtype].map == NULL) {
116e0d2 @gstrauss - rework thread-safe interfaces
authored
343 const enum mcdb_flags mcdb_flags_unlock =
344 MCDB_REGISTER_USE_DECR
35abc99 @gstrauss modify mcdb_register_access() to take an enum of flags to control behavi...
authored
345 | MCDB_REGISTER_MUNMAP_SKIP
346 | MCDB_REGISTER_MUTEX_UNLOCK_HOLD;
347 _nss_mcdb_db_relshared(m.map, mcdb_flags_unlock);
348 }
349
faf374e @gstrauss continue working on nss_mcdb
authored
350 return status;
351 }
352
a7f6ba9 @gstrauss add symbol aliases with "hidden" DSO visibility
authored
353 INTERNAL nss_status_t
11efc64 @gstrauss (part 2)
authored
354 nss_mcdb_buf_decode(struct mcdb * const restrict m,
355 const struct nss_mcdb_vinfo * const restrict v)
7a8f2ec @gstrauss create nss_mcdb.h (extract from nss_mcdb.c)
authored
356 { /* generic; simply copy data into target buffer and NIL terminate string */
357 const size_t dlen = mcdb_datalen(m);
7718ee5 @gstrauss rename routines and structs with prefix matching filename containing cod...
authored
358 if (dlen < v->bufsz) {
359 memcpy(v->buf, mcdb_dataptr(m), dlen);
360 v->buf[dlen] = '\0';
7a8f2ec @gstrauss create nss_mcdb.h (extract from nss_mcdb.c)
authored
361 return NSS_STATUS_SUCCESS;
362 }
7718ee5 @gstrauss rename routines and structs with prefix matching filename containing cod...
authored
363 *v->errnop = errno = ERANGE;
7a8f2ec @gstrauss create nss_mcdb.h (extract from nss_mcdb.c)
authored
364 return NSS_STATUS_TRYAGAIN;
365 }
f78a730 @gstrauss add nss_mcdb_refresh_check() interface so that callers that set*ent()
authored
366
367 bool
368 nss_mcdb_refresh_check(const enum nss_dbtype dbtype)
369 {
370 return (0 <= dbtype && dbtype < NSS_DBTYPE_SENTINEL)
a7f6ba9 @gstrauss add symbol aliases with "hidden" DSO visibility
authored
371 && mcdb_mmap_refresh_check_h(&_nss_mcdb_mmap_st[dbtype]);
f78a730 @gstrauss add nss_mcdb_refresh_check() interface so that callers that set*ent()
authored
372 }
Something went wrong with that request. Please try again.