Skip to content
Newer
Older
100644 1143 lines (1020 sloc) 46.8 KB
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
1 /* fstatat(), openat() */
2 #define _ATFILE_SOURCE
3 /* _BSD_SOURCE or _SVID_SOURCE needed for struct rpcent on Linux */
4 #define _BSD_SOURCE
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
5
6 #include "mcdb.h"
7 #include "mcdb_uint32.h"
8 #include "mcdb_attribute.h"
9
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <fcntl.h>
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
13 #include <unistd.h>
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
14 #include <errno.h>
15 #include <stdbool.h>
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
16 #include <stdint.h>
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
17 #include <stdlib.h>
18 #include <string.h>
19 #include <stdio.h>
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
20 #include <nss.h> /* NSS_STATUS_{TRYAGAIN,UNAVAIL,NOTFOUND,SUCCESS,RETURN} */
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
21
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
22 #include <pwd.h>
23 #include <grp.h>
24 #include <netdb.h>
25 #include <sys/socket.h> /* AF_INET */
26 #include <aliases.h>
27 #include <shadow.h>
28 #include <netinet/ether.h>
29
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
30 #ifdef _THREAD_SAFE
31 #include <pthread.h> /* pthread_mutex_t, pthread_mutex_{lock,unlock}() */
32 #else
33 #define pthread_mutex_lock(mutexp) 0
34 #define pthread_mutex_unlock(mutexp) (void)0
35 #endif
36
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
37 #ifndef O_CLOEXEC
38 #define O_CLOEXEC 0
39 #endif
40
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
41 enum nss_dbtype {
42 NSS_DBTYPE_ALIASES = 0,
43 NSS_DBTYPE_ETHERS,
44 NSS_DBTYPE_GROUP,
45 NSS_DBTYPE_HOSTS,
46 NSS_DBTYPE_NETGROUP,
47 NSS_DBTYPE_NETWORKS,
48 NSS_DBTYPE_PASSWD,
49 NSS_DBTYPE_PROTOCOLS,
50 NSS_DBTYPE_PUBLICKEY,
51 NSS_DBTYPE_RPC,
52 NSS_DBTYPE_SERVICES,
53 NSS_DBTYPE_SHADOW
54 };
55
56 /* compile-time setting for security */
57 #ifndef NSS_DBPATH
58 #define NSS_DBPATH "/var/db/"
59 #endif
60
61 /* path to db must match up to enum nss_dbtype index */
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
62 /* NOTE: string must fit into map->fname array (i.e. currently 64 bytes) */
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
63 static const char * const restrict nss_dbnames[] = {
64 "aliases.mcdb",
65 "ethers.mcdb",
66 "group.mcdb",
67 "hosts.mcdb",
68 "netgroup.mcdb",
69 "networks.mcdb",
70 "passwd.mcdb",
71 "protocols.mcdb",
72 "publickey.mcdb",
73 "rpc.mcdb",
74 "services.mcdb",
75 "shadow.mcdb"
76 };
77
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
78
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
79 static struct mcdb_mmap nss_mcdb_mmap_st[sizeof(nss_dbnames)/sizeof(char *)];
80 static struct mcdb_mmap *nss_mcdb_mmap[sizeof(nss_dbnames)/sizeof(char *)];
81
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
82
83 union _nss_ent {
84 struct passwd * restrict passwd;
85 struct group * restrict group;
86 struct hostent * restrict hostent;
87 struct netent * restrict netent;
88 struct protoent * restrict protoent;
89 struct rpcent * restrict rpcent;
90 struct servent * restrict servent;
91 struct aliasent * restrict aliasent;
92 struct spwd * restrict spwd;
93 struct ether_addr * restrict ether_addr;
94 uintptr_t NA;
95 };
96
97 union _nss_entp {
98 struct passwd ** restrict passwd;
99 struct group ** restrict group;
100 struct hostent ** restrict hostent;
101 struct netent ** restrict netent;
102 struct protoent ** restrict protoent;
103 struct rpcent ** restrict rpcent;
104 struct servent ** restrict servent;
105 struct aliasent ** restrict aliasent;
106 struct spwd ** restrict spwd;
107 struct ether_addr ** restrict ether_addr;
108 uintptr_t NA;
109 };
110
111 struct _nss_kinfo {
112 const char * restrict key;
113 size_t klen;
114 unsigned char tagc;
115 };
116
117 struct _nss_vinfo {
118 /* fail ERANGE if insufficient buf space supplied */
119 enum nss_status (*decode)(struct mcdb * restrict,
120 const struct _nss_kinfo * restrict,
121 const struct _nss_vinfo * restrict);
122 union _nss_ent u;
123 char * restrict buf;
124 size_t buflen;
125 union _nss_entp p;
126 };
127
128
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
129 /* custom free for mcdb_mmap_create() to not free initial static storage */
130 static void __attribute_noinline__
131 nss_mcdb_mmap_free(void * const v)
132 {
133 struct mcdb_mmap * const m = v;
134 if (&nss_mcdb_mmap_st[sizeof(nss_mcdb_mmap_st)/sizeof(struct mcdb_mmap)]<=m
135 || m < &nss_mcdb_mmap_st[0])
136 free(v);
137 }
138
139 /* (similar to mcdb_mmap_create() but mutex-protected, shared dir fd,
140 * and use static storage for initial struct mcdb_mmap for each dbtype)
141 */
142 static bool __attribute_noinline__
143 _nss_mcdb_db_openshared(const enum nss_dbtype dbtype)
144 __attribute_cold__ __attribute_warn_unused_result__;
145 static bool __attribute_noinline__
146 _nss_mcdb_db_openshared(const enum nss_dbtype dbtype)
147 {
148 #ifdef _THREAD_SAFE
149 static pthread_mutex_t nss_mcdb_global_mutex = PTHREAD_MUTEX_INITIALIZER;
150 #endif
151 static int dfd = -1;
152 struct mcdb_mmap * const restrict map = &nss_mcdb_mmap_st[dbtype];
153 int fd;
154 bool rc = false;
155
156 if (pthread_mutex_lock(&nss_mcdb_global_mutex) != 0)
157 return false;
158
159 if (nss_mcdb_mmap[dbtype] != 0) {
160 /* init'ed by another thread while waiting for mutex */
161 pthread_mutex_unlock(&nss_mcdb_global_mutex);
162 return true;
163 }
164
165 map->fn_malloc = malloc;
166 map->fn_free = nss_mcdb_mmap_free;
167
168 #if defined(__linux) || defined(__sun)
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
169 if (__builtin_expect(dfd <= STDERR_FILENO, false)) {
170 if ((dfd = open(NSS_DBPATH, O_RDONLY | O_CLOEXEC, 0)) > STDERR_FILENO) {
171 #if O_CLOEXEC == 0
172 (void) fcntl(dfd, F_SETFD, FD_CLOEXEC);
173 #endif
174 }
175 else {
176 if (dfd != -1) /* caller must have open STDIN, STDOUT, STDERR */
177 while (close(dfd) != 0 && errno == EINTR)
178 ;
179 pthread_mutex_unlock(&nss_mcdb_global_mutex);
180 return false;
181 }
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
182 }
183 /* assert(sizeof(map->fname) > strlen(nss_dbnames[dbtype])); */
184 memcpy(map->fname, nss_dbnames[dbtype], strlen(nss_dbnames[dbtype])+1);
185 #else
186 if (snprintf(map->fname, sizeof(map->fname), "%s%s",
187 NSS_DBPATH, nss_dbnames[dbtype]) >= sizeof(map->fname)) {
188 pthread_mutex_unlock(&nss_mcdb_global_mutex);
189 return false;
190 }
191 #endif
192
193 #if defined(__linux) || defined(__sun)
194 if ((fd = openat((map->dfd=dfd), map->fname, O_RDONLY|O_NONBLOCK, 0)) != -1)
195 #else
196 if ((fd = open(map->fname, O_RDONLY|O_NONBLOCK, 0)) != -1)
197 #endif
198 {
199 rc = mcdb_mmap_init(map, fd);
200 while (close(fd) != 0 && errno == EINTR) /* close fd once mmap'ed */
201 ;
202 if (rc) /*(ought to be preceded by StoreStore memory barrier)*/
203 nss_mcdb_mmap[dbtype] = map;
204 }
205
206 pthread_mutex_unlock(&nss_mcdb_global_mutex);
207 return rc;
208 }
209
210 static struct mcdb_mmap * __attribute_noinline__
211 _nss_mcdb_db_getshared(const enum nss_dbtype dbtype)
212 __attribute_nonnull__ __attribute_warn_unused_result__;
213 static struct mcdb_mmap * __attribute_noinline__
214 _nss_mcdb_db_getshared(const enum nss_dbtype dbtype)
215 {
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
216 /* GPS: should we be doing stat() of mcdb to see if it has changed? */
217 /* Is gettimeofday() much less expensive than stat()? If so, we might
218 * implement something like a 15 second cache */
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
219 if (__builtin_expect(nss_mcdb_mmap[dbtype] != 0, true)
220 || _nss_mcdb_db_openshared(dbtype)) {
221 if (mcdb_register(nss_mcdb_mmap[dbtype]))
222 return nss_mcdb_mmap[dbtype];
223 }
224 return NULL;
225 }
226
227 static enum nss_status
228 _nss_mcdb_setent(struct mcdb * const restrict m, const enum nss_dbtype dbtype)
229 __attribute_nonnull__;
230 static enum nss_status
231 _nss_mcdb_setent(struct mcdb * const restrict m, const enum nss_dbtype dbtype)
232 {
233 if (m->map != NULL || (m->map = _nss_mcdb_db_getshared(dbtype)) != NULL) {
234 m->hpos = 0;
235 return NSS_STATUS_SUCCESS;
236 }
237 return NSS_STATUS_UNAVAIL;
238 }
239
240 static enum nss_status
241 _nss_mcdb_endent(struct mcdb * const restrict m)
242 __attribute_nonnull__;
243 static enum nss_status
244 _nss_mcdb_endent(struct mcdb * const restrict m)
245 {
246 return (m->map == NULL || mcdb_unregister(m->map))
247 ? NSS_STATUS_SUCCESS
248 : NSS_STATUS_TRYAGAIN; /* (fails only if obtaining mutex fails) */
249 }
250
251 static enum nss_status
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
252 _nss_mcdb_getent(struct mcdb * const restrict m, const enum nss_dbtype dbtype,
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
253 const struct _nss_vinfo * const restrict vinfo)
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
254 __attribute_nonnull__ __attribute_warn_unused_result__;
255 static enum nss_status
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
256 _nss_mcdb_getent(struct mcdb * const restrict m, const enum nss_dbtype dbtype,
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
257 const struct _nss_vinfo * const restrict vinfo)
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
258 {
259 unsigned char *map;
260 uint32_t eod;
261 uint32_t klen;
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
262 if (__builtin_expect(m->map == NULL, false)
263 && _nss_mcdb_setent(m, dbtype) != NSS_STATUS_SUCCESS)
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
264 return NSS_STATUS_UNAVAIL;
265 map = m->map->ptr;
266 eod = mcdb_uint32_unpack_bigendian_aligned_macro(map) - 7;
267 while (m->hpos < eod) {
268 unsigned char * const restrict p = map + m->hpos;
269 klen = mcdb_uint32_unpack_bigendian_macro(p);
270 m->dlen = mcdb_uint32_unpack_bigendian_macro(p+4);
271 m->hpos = (m->dpos = (m->kpos = m->hpos + 8) + klen) + m->dlen;
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
272 if (p[8+klen] == (unsigned char)'=')
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
273 /* valid data in mcdb_datapos() mcdb_datalen() mcdb_dataptr() */
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
274 return vinfo->decode(m, NULL, vinfo);
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
275 }
276 return NSS_STATUS_NOTFOUND;
277 }
278
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
279 static enum nss_status
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
280 _nss_files_get_generic(const enum nss_dbtype dbtype,
281 const struct _nss_kinfo * const restrict kinfo,
282 const struct _nss_vinfo * const restrict vinfo)
283 __attribute_nonnull__ __attribute_warn_unused_result__;
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
284 static enum nss_status
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
285 _nss_files_get_generic(const enum nss_dbtype dbtype,
286 const struct _nss_kinfo * const restrict kinfo,
287 const struct _nss_vinfo * const restrict vinfo)
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
288 {
289 struct mcdb m;
290 enum nss_status status = NSS_STATUS_NOTFOUND;
291
292 m.map = _nss_mcdb_db_getshared(dbtype);
293 if (__builtin_expect(m.map == NULL, false))
294 return NSS_STATUS_UNAVAIL;
295
296 if ( mcdb_findtagstart(&m, kinfo->key, kinfo->klen, kinfo->tagc)
297 && mcdb_findtagnext(&m, kinfo->key, kinfo->klen, kinfo->tagc) )
298 status = vinfo->decode(&m, kinfo, vinfo);
299
300 mcdb_unregister(m.map);
301 return status;
302 }
303
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
304
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
305 /* _nss_files_setaliasent() _nss_files_endaliasent() */
306 /* _nss_files_setetherent() _nss_files_endetherent() */
307 /* _nss_files_setgrent() _nss_files_endgrent() */
308 /* _nss_files_sethostent() _nss_files_endhostent() */
309 /* _nss_files_setnetgrent() _nss_files_endnetgrent() */
310 /* _nss_files_setnetent() _nss_files_endnetent() */
311 /* _nss_files_setpwent() _nss_files_endpwent() */
312 /* _nss_files_setprotoent() _nss_files_endprotoent() */
313 /* _nss_files_setrpcent() _nss_files_endrpcent() */
314 /* _nss_files_setservent() _nss_files_endservent() */
315 /* _nss_files_setspent() _nss_files_endspent() */
316
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
317 /* set*ent(), get*ent(), end*ent() are not thread-safe */
318 /* (use thread-local storage of static struct mcdb array to increase safety) */
319
320 static __thread struct mcdb nss_mcdb_st[sizeof(nss_dbnames)/sizeof(char *)];
321
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
322 #define _nss_files_xxxNAMEent(name, dbtype) \
323 \
324 void _nss_files_set##name##ent(void) \
325 { _nss_mcdb_setent(&nss_mcdb_st[(dbtype)], (dbtype)); } \
326 \
327 void _nss_files_end##name##ent(void) \
328 { _nss_mcdb_endent(&nss_mcdb_st[(dbtype)]); }
329
330
331 _nss_files_xxxNAMEent(alias, NSS_DBTYPE_ALIASES)
332 _nss_files_xxxNAMEent(ether, NSS_DBTYPE_ETHERS)
333 _nss_files_xxxNAMEent(gr, NSS_DBTYPE_GROUP)
334 _nss_files_xxxNAMEent(host, NSS_DBTYPE_HOSTS)
335 _nss_files_xxxNAMEent(netgr, NSS_DBTYPE_NETGROUP)
336 _nss_files_xxxNAMEent(net, NSS_DBTYPE_NETWORKS)
337 _nss_files_xxxNAMEent(pw, NSS_DBTYPE_PASSWD)
338 _nss_files_xxxNAMEent(proto, NSS_DBTYPE_PROTOCOLS)
339 _nss_files_xxxNAMEent(rpc, NSS_DBTYPE_RPC)
340 _nss_files_xxxNAMEent(serv, NSS_DBTYPE_SERVICES)
341 _nss_files_xxxNAMEent(sp, NSS_DBTYPE_SHADOW)
342
343
344
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
345 static enum nss_status
346 _nss_files_decode_buf(struct mcdb * restrict,
347 const struct _nss_kinfo * restrict,
348 const struct _nss_vinfo * restrict)
349 __attribute_nonnull__ __attribute_warn_unused_result__;
350 static enum nss_status
351 _nss_files_decode_buf(struct mcdb * const restrict m,
352 const struct _nss_kinfo * const restrict kinfo
353 __attribute_unused__,
354 const struct _nss_vinfo * const restrict vinfo)
355 { /* generic; simply copy data into target buffer and NIL terminate string */
356 const size_t dlen = mcdb_datalen(m);
357 if (vinfo->buflen > dlen) {
358 memcpy(vinfo->buf, mcdb_dataptr(m), dlen);
359 vinfo->buf[dlen] = '\0';
360 return NSS_STATUS_SUCCESS;
361 }
362 return NSS_STATUS_TRYAGAIN;
363 }
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
364
365 /* GPS: these all should be static (once we define them) */
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
366
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
367 enum nss_status
368 _nss_files_decode_passwd(struct mcdb * restrict,
369 const struct _nss_kinfo * restrict,
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
370 const struct _nss_vinfo * restrict)
371 __attribute_nonnull__ __attribute_warn_unused_result__;
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
372 enum nss_status
373 _nss_files_decode_group(struct mcdb * restrict,
374 const struct _nss_kinfo * restrict,
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
375 const struct _nss_vinfo * restrict)
376 __attribute_nonnull__ __attribute_warn_unused_result__;
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
377 enum nss_status
378 _nss_files_decode_hostent(struct mcdb * restrict,
379 const struct _nss_kinfo * restrict,
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
380 const struct _nss_vinfo * restrict)
381 __attribute_nonnull__ __attribute_warn_unused_result__;
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
382 enum nss_status
383 _nss_files_decode_netent(struct mcdb * restrict,
384 const struct _nss_kinfo * restrict,
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
385 const struct _nss_vinfo * restrict)
386 __attribute_nonnull__ __attribute_warn_unused_result__;
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
387 enum nss_status
388 _nss_files_decode_protoent(struct mcdb * restrict,
389 const struct _nss_kinfo * restrict,
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
390 const struct _nss_vinfo * restrict)
391 __attribute_nonnull__ __attribute_warn_unused_result__;
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
392 enum nss_status
393 _nss_files_decode_rpcent(struct mcdb * restrict,
394 const struct _nss_kinfo * restrict,
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
395 const struct _nss_vinfo * restrict)
396 __attribute_nonnull__ __attribute_warn_unused_result__;
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
397 enum nss_status
398 _nss_files_decode_servent(struct mcdb * restrict,
399 const struct _nss_kinfo * restrict,
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
400 const struct _nss_vinfo * restrict)
401 __attribute_nonnull__ __attribute_warn_unused_result__;
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
402 enum nss_status
403 _nss_files_decode_aliasent(struct mcdb * restrict,
404 const struct _nss_kinfo * restrict,
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
405 const struct _nss_vinfo * restrict)
406 __attribute_nonnull__ __attribute_warn_unused_result__;
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
407 enum nss_status
408 _nss_files_decode_spwd(struct mcdb * restrict,
409 const struct _nss_kinfo * restrict,
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
410 const struct _nss_vinfo * restrict)
411 __attribute_nonnull__ __attribute_warn_unused_result__;
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
412 enum nss_status
413 _nss_files_decode_ether_addr(struct mcdb * restrict,
414 const struct _nss_kinfo * restrict,
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
415 const struct _nss_vinfo * restrict)
416 __attribute_nonnull__ __attribute_warn_unused_result__;
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
417 /* TODO: decode into struct ether_addr and hostname; both in buf (!) */
418
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
419
420 enum nss_status
421 _nss_files_getpwent_r(struct passwd * const restrict pwbuf,
422 char * const restrict buf, const size_t buflen,
423 struct passwd ** const restrict pwbufp)
424 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
425 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_passwd,
426 .u = { .passwd = pwbuf },
427 .buf = buf,
428 .buflen = buflen,
429 .p = { .passwd = pwbufp } };
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
430 return _nss_mcdb_getent(&nss_mcdb_st[NSS_DBTYPE_PASSWD],
431 NSS_DBTYPE_PASSWD, &vinfo);
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
432 }
433
434 enum nss_status
435 _nss_files_getpwnam_r(const char * const restrict name,
436 struct passwd * const restrict pwbuf,
437 char * const restrict buf, const size_t buflen,
438 struct passwd ** const restrict pwbufp)
439 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
440 const struct _nss_kinfo kinfo = { .key = name,
441 .klen = strlen(name),
442 .tagc = (unsigned char)'=' };
443 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_passwd,
444 .u = { .passwd = pwbuf },
445 .buf = buf,
446 .buflen = buflen,
447 .p = { .passwd = pwbufp } };
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
448 return _nss_files_get_generic(NSS_DBTYPE_PASSWD, &kinfo, &vinfo);
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
449 }
450
451 enum nss_status
452 _nss_files_getpwuid_r(const uid_t uid,
453 struct passwd * const restrict pwbuf,
454 char * const restrict buf, const size_t buflen,
455 struct passwd ** const restrict pwbufp)
456 {
457 char hexstr[8];
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
458 const struct _nss_kinfo kinfo = { .key = hexstr,
459 .klen = sizeof(hexstr),
460 .tagc = (unsigned char)'x' };
461 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_passwd,
462 .u = { .passwd = pwbuf },
463 .buf = buf,
464 .buflen = buflen,
465 .p = { .passwd = pwbufp } };
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
466 uint32_to_ascii8uphex((uint32_t)uid, hexstr);/* TODO take from cdbauthz.c */
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
467 return _nss_files_get_generic(NSS_DBTYPE_PASSWD, &kinfo, &vinfo);
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
468 }
469
470
471 enum nss_status
472 _nss_files_getgrent_r(struct group * const restrict grbuf,
473 char * const restrict buf, const size_t buflen,
474 struct group ** const restrict grbufp)
475 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
476 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_group,
477 .u = { .group = grbuf },
478 .buf = buf,
479 .buflen = buflen,
480 .p = { .group = grbufp } };
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
481 return _nss_mcdb_getent(&nss_mcdb_st[NSS_DBTYPE_GROUP],
482 NSS_DBTYPE_GROUP, &vinfo);
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
483 }
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
484
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
485 enum nss_status
486 _nss_files_getgrnam_r(const char * const restrict name,
487 struct group * const restrict grbuf,
488 char * const restrict buf, const size_t buflen,
489 struct group ** const restrict grbufp)
490 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
491 const struct _nss_kinfo kinfo = { .key = name,
492 .klen = strlen(name),
493 .tagc = (unsigned char)'=' };
494 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_group,
495 .u = { .group = grbuf },
496 .buf = buf,
497 .buflen = buflen,
498 .p = { .group = grbufp } };
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
499 return _nss_files_get_generic(NSS_DBTYPE_GROUP, &kinfo, &vinfo);
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
500 }
501
502 enum nss_status
503 _nss_files_getgrgid_r(const gid_t gid,
504 struct group * const restrict grbuf,
505 char * const restrict buf, const size_t buflen,
506 struct group ** const restrict grbufp)
507 {
508 char hexstr[8];
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
509 const struct _nss_kinfo kinfo = { .key = hexstr,
510 .klen = sizeof(hexstr),
511 .tagc = (unsigned char)'x' };
512 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_group,
513 .u = { .group = grbuf },
514 .buf = buf,
515 .buflen = buflen,
516 .p = { .group = grbufp } };
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
517 uint32_to_ascii8uphex((uint32_t)gid, hexstr);/* TODO take from cdbauthz.c */
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
518 return _nss_files_get_generic(NSS_DBTYPE_GROUP, &kinfo, &vinfo);
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
519 }
520
521
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
522 /* GPS: TODO check for each get*ent if buflen is size_t or int
523 * and document if we choose to use size_t anyway */
524 /* GPS: some sethostent() calls have a 'stayopen' parameter.
525 * Is nss looking for this? Check */
526 /* GPS: document which routines are POSIX-1.2001 and which are GNU extensions */
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
527 /* GPS: make sure to fill in h_errnop on error */
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
528 /* GPS: if buffer sizes are not large enough, man page says return ERANGE ? */
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
529
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
530 static enum nss_status
531 fill_h_errnop(enum nss_status status, int * const restrict h_errnop)
532 {
533 switch (status) {
534 case NSS_STATUS_TRYAGAIN: *h_errnop = TRY_AGAIN; break;
535 case NSS_STATUS_UNAVAIL: *h_errnop = NO_RECOVERY; break;
536 case NSS_STATUS_NOTFOUND: *h_errnop = HOST_NOT_FOUND; break;
537 case NSS_STATUS_SUCCESS: break;
538 case NSS_STATUS_RETURN: *h_errnop = TRY_AGAIN; break;
539 }
540 return status;
541 }
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
542
543 enum nss_status
544 _nss_files_gethostent_r(struct hostent * const restrict hostbuf,
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
545 char * const restrict buf, const size_t buflen,
546 struct hostent ** const restrict hostbufp,
547 int * const restrict h_errnop)
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
548 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
549 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_hostent,
550 .u = { .hostent = hostbuf },
551 .buf = buf,
552 .buflen = buflen,
553 .p = { .hostent = hostbufp } };
554 const enum nss_status status =
555 _nss_mcdb_getent(&nss_mcdb_st[NSS_DBTYPE_HOSTS],
556 NSS_DBTYPE_HOSTS, &vinfo);
557 return (status == NSS_STATUS_SUCCESS)
558 ? NSS_STATUS_SUCCESS
559 : fill_h_errnop(status, h_errnop);
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
560 }
561
562 /* GPS: TODO
563 * POSIX.1-2001 marks gethostbyaddr() and gethostbyname() obsolescent.
564 * See getaddrinfo(), getnameinfo(), gai_strerror() and see if we can implement
565 * the parsing and lookups according to those interfaces.
566 */
567
568 /* ??? (struct hostent *) */
569 enum nss_status
570 _nss_files_gethostbyname2_r(const char * const restrict name, const int type,
571 struct hostent * const restrict hostbuf,
572 char * const restrict buf, const size_t buflen,
573 struct hostent ** const restrict hostbufp,
574 int * const restrict h_errnop)
575 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
576 const enum nss_status status;
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
577 struct mcdb m;
578 size_t nlen;
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
579 /* GPS: if the name is already an address, fill the struct and return.
580 * GPS: FIXME: should we look for HOSTALIASES environment variable
581 * and parse that? Do other get* types look for environment overrides? Check.
582 * GPS: if the name does *not* end in '.' and HOSTALIASES is set, look there
583 * first and there here? Yech. HOSTALIASES is not documented in SuSv6.
584 if (0 && getenv("HOSTALIASES") != NULL)
585 return NSS_STATUS_NOTFOUND;
586 */
587 /* GPS: look for unadorned name, then current
588 * domain and then parent domain appended. Yech. */
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
589 m.map = _nss_mcdb_db_getshared(NSS_DBTYPE_HOSTS);
590 if (__builtin_expect(m.map == NULL, false))
591 return NSS_STATUS_UNAVAIL;
592 nlen = strlen(name);
593 /* GPS: FIXME: must parse name str and see if it is already an address */
594 if ( mcdb_findtagstart(&m, name, nlen, (unsigned char)'=')
595 && mcdb_findtagnext(&m, name, nlen, (unsigned char)'=') ) {
596 /* GPS: FIXME: check type match: mcdb_findtagnext() until match */
597
598 /* TODO: decode into struct hostent */
599 /* fail ERANGE only if insufficient buffer space supplied */
600
601 mcdb_unregister(m.map);
602 return NSS_STATUS_SUCCESS;
603 }
604 mcdb_unregister(m.map);
605 return NSS_STATUS_NOTFOUND;
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
606
607 return (status == NSS_STATUS_SUCCESS)
608 ? NSS_STATUS_SUCCESS
609 : fill_h_errnop(status, h_errnop);
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
610 }
611
612 enum nss_status
613 _nss_files_gethostbyname_r(const char * const restrict name,
614 struct hostent * const restrict hostbuf,
615 char * const restrict buf, const size_t buflen,
616 struct hostent ** const restrict hostbufp,
617 int * const restrict h_errnop)
618 {
619 return _nss_files_gethostbyname2_r(name, AF_INET, hostbuf,
620 buf, buflen, hostbufp, h_errnop);
621 }
622
623 /* ??? (struct hostent *) */
624 enum nss_status
625 _nss_files_gethostbyaddr_r(const void * const restrict addr,
626 const socklen_t len, const int type,
627 struct hostent * const restrict hostbuf,
628 char * const restrict buf, const size_t buflen,
629 struct hostent ** const restrict hostbufp,
630 int * const restrict h_errnop)
631 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
632 const enum nss_status status;
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
633 struct mcdb m;
634 char hexstr[8];
635 m.map = _nss_mcdb_db_getshared(NSS_DBTYPE_HOSTS);
636 if (__builtin_expect(m.map == NULL, false))
637 return NSS_STATUS_UNAVAIL;
638 /* GPS: FIXME: do we need 16 char buffer for addr? */
639 uint32_to_ascii8uphex((uint32_t)len, hexstr); /* TODO from cdbauthz.c */
640 if ( mcdb_findtagstart(&m, hexstr, sizeof(hexstr), (unsigned char)'x')
641 && mcdb_findtagnext(&m, hexstr, sizeof(hexstr), (unsigned char)'x') ) {
642 /* GPS: FIXME: check addr,len,type match: mcdb_findtagnext() until match */
643
644 /* TODO: decode into struct hostent */
645 /* fail ERANGE only if insufficient buffer space supplied */
646
647 mcdb_unregister(m.map);
648 return NSS_STATUS_SUCCESS;
649 }
650 mcdb_unregister(m.map);
651 return NSS_STATUS_NOTFOUND;
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
652
653 return (status == NSS_STATUS_SUCCESS)
654 ? NSS_STATUS_SUCCESS
655 : fill_h_errnop(status, h_errnop);
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
656 }
657
658
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
659 /* GPS: should we also provide an efficient innetgr()? */
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
660 enum nss_status
661 _nss_files_getnetgrent_r(char ** const restrict host,
662 char ** const restrict user,
663 char ** const restrict domain,
664 char * const restrict buf, const size_t buflen)
665 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
666 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_buf,
667 .u = { .NA = 0 },
668 .buf = buf,
669 .buflen = buflen,
670 .p = { .NA = 0 } };
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
671 const enum nss_status status =
672 _nss_mcdb_getent(&nss_mcdb_st[NSS_DBTYPE_NETGROUP],
673 NSS_DBTYPE_NETGROUP, &vinfo);
674 if (status == NSS_STATUS_SUCCESS) {
675 *host = buf;
676 *user = (char *)memchr(buf, '\0', buflen) + 1;
677 *domain = (char *)memchr(*user, '\0', buflen - (*user - buf)) + 1;
678 }
679 return status;
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
680 }
681
682
683 enum nss_status
684 _nss_files_getnetent_r(struct netent * const restrict netbuf,
685 char * const restrict buf, const size_t buflen,
686 struct netent ** const restrict netbufp)
687 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
688 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_netent,
689 .u = { .netent = netbuf },
690 .buf = buf,
691 .buflen = buflen,
692 .p = { .netent = netbufp } };
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
693 return _nss_mcdb_getent(&nss_mcdb_st[NSS_DBTYPE_NETWORKS],
694 NSS_DBTYPE_NETWORKS, &vinfo);
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
695 }
696
697 enum nss_status
698 _nss_files_getnetbyname_r(const char * const restrict name,
699 struct netent * const restrict netbuf,
700 char * const restrict buf, const size_t buflen,
701 struct netent ** const restrict netbufp)
702 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
703 const struct _nss_kinfo kinfo = { .key = name,
704 .klen = strlen(name),
705 .tagc = (unsigned char)'=' };
706 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_netent,
707 .u = { .netent = netbuf },
708 .buf = buf,
709 .buflen = buflen,
710 .p = { .netent = netbufp } };
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
711 return _nss_files_get_generic(NSS_DBTYPE_NETWORKS, &kinfo, &vinfo);
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
712 }
713
714 enum nss_status
715 _nss_files_getnetbyaddr_r(const long net, const int type,
716 struct netent * const restrict netbuf,
717 char * const restrict buf, const size_t buflen,
718 struct netent ** const restrict netbufp)
719 {
720 char hexstr[8];
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
721 const struct _nss_kinfo kinfo = { .key = hexstr,
722 .klen = sizeof(hexstr),
723 .tagc = (unsigned char)'x' };
724 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_netent,
725 .u = { .netent = netbuf },
726 .buf = buf,
727 .buflen = buflen,
728 .p = { .netent = netbufp } };
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
729 /* GPS: FIXME: do we need 16 char buffer for 'long'? longer to encode type? */
730 /* or pass type in buf to decoding routine? */
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
731 uint32_to_ascii8uphex((uint32_t)net, hexstr); /* TODO from cdbauthz.c */
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
732 return _nss_files_get_generic(NSS_DBTYPE_NETWORKS, &kinfo, &vinfo);
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
733 }
734
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
735
736 enum nss_status
737 _nss_files_getprotoent_r(struct protoent * const restrict protobuf,
738 char * const restrict buf, const size_t buflen,
739 struct protoent ** const restrict protobufp)
740 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
741 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_protoent,
742 .u = { .protoent = protobuf },
743 .buf = buf,
744 .buflen = buflen,
745 .p = { .protoent = protobufp } };
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
746 return _nss_mcdb_getent(&nss_mcdb_st[NSS_DBTYPE_PROTOCOLS],
747 NSS_DBTYPE_PROTOCOLS, &vinfo);
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
748 }
749
750 enum nss_status
751 _nss_files_getprotobyname_r(const char * const restrict name,
752 struct protoent * const restrict protobuf,
753 char * const restrict buf, const size_t buflen,
754 struct protoent ** const restrict protobufp)
755 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
756 const struct _nss_kinfo kinfo = { .key = name,
757 .klen = strlen(name),
758 .tagc = (unsigned char)'=' };
759 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_protoent,
760 .u = { .protoent = protobuf },
761 .buf = buf,
762 .buflen = buflen,
763 .p = { .protoent = protobufp } };
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
764 return _nss_files_get_generic(NSS_DBTYPE_PROTOCOLS, &kinfo, &vinfo);
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
765 }
766
767 enum nss_status
768 _nss_files_getprotobynumber_r(const int proto,
769 struct protoent * const restrict protobuf,
770 char * const restrict buf, const size_t buflen,
771 struct protoent ** const restrict protobufp)
772 {
773 char hexstr[8];
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
774 const struct _nss_kinfo kinfo = { .key = hexstr,
775 .klen = sizeof(hexstr),
776 .tagc = (unsigned char)'x' };
777 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_protoent,
778 .u = { .protoent = protobuf },
779 .buf = buf,
780 .buflen = buflen,
781 .p = { .protoent = protobufp } };
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
782 uint32_to_ascii8uphex((uint32_t)proto, hexstr); /* TODO from cdbauthz.c */
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
783 return _nss_files_get_generic(NSS_DBTYPE_PROTOCOLS, &kinfo, &vinfo);
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
784 }
785
786
787 enum nss_status
788 _nss_files_getrpcent_r(struct rpcent * const restrict rpcbuf,
789 char * const restrict buf, const size_t buflen,
790 struct rpcent ** const restrict rpcbufp)
791 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
792 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_rpcent,
793 .u = { .rpcent = rpcbuf },
794 .buf = buf,
795 .buflen = buflen,
796 .p = { .rpcent = rpcbufp } };
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
797 return _nss_mcdb_getent(&nss_mcdb_st[NSS_DBTYPE_RPC],
798 NSS_DBTYPE_RPC, &vinfo);
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
799 }
800
801 enum nss_status
802 _nss_files_getrpcbyname_r(const char * const restrict name,
803 struct rpcent * const restrict rpcbuf,
804 char * const restrict buf, const size_t buflen,
805 struct rpcent ** const restrict rpcbufp)
806 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
807 const struct _nss_kinfo kinfo = { .key = name,
808 .klen = strlen(name),
809 .tagc = (unsigned char)'=' };
810 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_rpcent,
811 .u = { .rpcent = rpcbuf },
812 .buf = buf,
813 .buflen = buflen,
814 .p = { .rpcent = rpcbufp } };
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
815 return _nss_files_get_generic(NSS_DBTYPE_RPC, &kinfo, &vinfo);
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
816 }
817
818 enum nss_status
819 _nss_files_getrpcbynumber_r(const int number,
820 struct rpcent * const restrict rpcbuf,
821 char * const restrict buf, const size_t buflen,
822 struct rpcent ** const restrict rpcbufp)
823 {
824 char hexstr[8];
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
825 const struct _nss_kinfo kinfo = { .key = hexstr,
826 .klen = sizeof(hexstr),
827 .tagc = (unsigned char)'x' };
828 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_rpcent,
829 .u = { .rpcent = rpcbuf },
830 .buf = buf,
831 .buflen = buflen,
832 .p = { .rpcent = rpcbufp } };
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
833 uint32_to_ascii8uphex((uint32_t)number, hexstr); /* TODO from cdbauthz.c */
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
834 return _nss_files_get_generic(NSS_DBTYPE_RPC, &kinfo, &vinfo);
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
835 }
836
837
838 enum nss_status
839 _nss_files_getservent_r(struct servent * const restrict servbuf,
840 char * const restrict buf, const size_t buflen,
841 struct servent ** const restrict servbufp)
842 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
843 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_servent,
844 .u = { .servent = servbuf },
845 .buf = buf,
846 .buflen = buflen,
847 .p = { .servent = servbufp } };
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
848 return _nss_mcdb_getent(&nss_mcdb_st[NSS_DBTYPE_SERVICES],
849 NSS_DBTYPE_SERVICES, &vinfo);
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
850 }
851
852 enum nss_status
853 _nss_files_getservbyname_r(const char * const restrict name,
854 const char * const restrict proto,
855 struct servent * const restrict servbuf,
856 char * const restrict buf, const size_t buflen,
857 struct servent ** const restrict servbufp)
858 {
859 struct mcdb m;
860 size_t nlen;
861 m.map = _nss_mcdb_db_getshared(NSS_DBTYPE_SERVICES);
862 if (__builtin_expect(m.map == NULL, false))
863 return NSS_STATUS_UNAVAIL;
864 nlen = strlen(name);
865 if ( mcdb_findtagstart(&m, name, nlen, (unsigned char)'=')
866 && mcdb_findtagnext(&m, name, nlen, (unsigned char)'=') ) {
867 /* GPS: FIXME: check proto != NULL and mcdb_findtagnext() until match */
868
869 /* TODO: decode into struct servent */
870 /* fail ERANGE only if insufficient buffer space supplied */
871
872 mcdb_unregister(m.map);
873 return NSS_STATUS_SUCCESS;
874 }
875 mcdb_unregister(m.map);
876 return NSS_STATUS_NOTFOUND;
877 }
878
879 enum nss_status
880 _nss_files_getservbyport_r(const int port, const char * const restrict proto,
881 struct servent * const restrict servbuf,
882 char * const restrict buf, const size_t buflen,
883 struct servent ** const restrict servbufp)
884 {
885 struct mcdb m;
886 char hexstr[8];
887 m.map = _nss_mcdb_db_getshared(NSS_DBTYPE_SERVICES);
888 if (__builtin_expect(m.map == NULL, false))
889 return NSS_STATUS_UNAVAIL;
890 uint32_to_ascii8uphex((uint32_t)port, hexstr); /* TODO from cdbauthz.c */
891 if ( mcdb_findtagstart(&m, hexstr, sizeof(hexstr), (unsigned char)'x')
892 && mcdb_findtagnext(&m, hexstr, sizeof(hexstr), (unsigned char)'x') ) {
893 /* GPS: FIXME: check proto != NULL and mcdb_findtagnext() until match */
894
895 /* TODO: decode into struct servent */
896 /* fail ERANGE only if insufficient buffer space supplied */
897
898 mcdb_unregister(m.map);
899 return NSS_STATUS_SUCCESS;
900 }
901 mcdb_unregister(m.map);
902 return NSS_STATUS_NOTFOUND;
903 }
904
905
906 enum nss_status
907 _nss_files_getaliasent_r(struct aliasent * const restrict aliasbuf,
908 char * const restrict buf, const size_t buflen,
909 struct aliasent ** const restrict aliasbufp)
910 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
911 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_aliasent,
912 .u = { .aliasent = aliasbuf },
913 .buf = buf,
914 .buflen = buflen,
915 .p = { .aliasent = aliasbufp } };
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
916 return _nss_mcdb_getent(&nss_mcdb_st[NSS_DBTYPE_ALIASES],
917 NSS_DBTYPE_ALIASES, &vinfo);
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
918 }
919
920 enum nss_status
921 _nss_files_getaliasbyname_r(const char * const restrict name,
922 struct aliasent * const restrict aliasbuf,
923 char * const restrict buf, const size_t buflen,
924 struct aliasent ** const restrict aliasbufp)
925 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
926 const struct _nss_kinfo kinfo = { .key = name,
927 .klen = strlen(name),
928 .tagc = (unsigned char)'=' };
929 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_aliasent,
930 .u = { .aliasent = aliasbuf },
931 .buf = buf,
932 .buflen = buflen,
933 .p = { .aliasent = aliasbufp } };
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
934 return _nss_files_get_generic(NSS_DBTYPE_ALIASES, &kinfo, &vinfo);
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
935 }
936
937
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
938 enum nss_status
939 _nss_files_getspent_r(struct spwd * const restrict spbuf,
940 char * const restrict buf, const size_t buflen,
941 struct spwd ** const restrict spbufp)
942 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
943 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_spwd,
944 .u = { .spwd = spbuf },
945 .buf = buf,
946 .buflen = buflen,
947 .p = { .spwd = spbufp } };
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
948 return _nss_mcdb_getent(&nss_mcdb_st[NSS_DBTYPE_SHADOW],
949 NSS_DBTYPE_SHADOW, &vinfo);
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
950 }
951
952 enum nss_status
953 _nss_files_getspnam_r(const char * const restrict name,
954 struct spwd * const restrict spbuf,
955 char * const restrict buf, const size_t buflen,
956 struct spwd ** const restrict spbufp)
957 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
958 const struct _nss_kinfo kinfo = { .key = name,
959 .klen = strlen(name),
960 .tagc = (unsigned char)'=' };
961 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_spwd,
962 .u = { .spwd = spbuf },
963 .buf = buf,
964 .buflen = buflen,
965 .p = { .spwd = spbufp } };
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
966 return _nss_files_get_generic(NSS_DBTYPE_SHADOW, &kinfo, &vinfo);
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
967 }
968
969
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
970 /* ??? (what is prototype for _nss_files_getpublickey()) ??? */
971 /* ??? (what is prototype for _nss_files_getsecretkey()) ??? (different db?) */
972 enum nss_status
973 _nss_files_getpublickey(const char * const restrict name,
974 char * const restrict buf, const size_t buflen)
975 {
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
976 const struct _nss_kinfo kinfo = { .key = name,
977 .klen = strlen(name),
978 .tagc = (unsigned char)'=' };
979 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_buf,
980 .u = { .NA = 0 },
981 .buf = buf,
982 .buflen = buflen,
983 .p = { .NA = 0 } };
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
984 return _nss_files_get_generic(NSS_DBTYPE_PUBLICKEY, &kinfo, &vinfo);
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
985 }
986
987
988 enum nss_status
989 _nss_files_getetherent_r(struct ether_addr * const restrict etherbuf,
990 char * const restrict buf, const size_t buflen,
991 struct ether_addr ** const restrict etherbufp)
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
992 { /* man ether_line() */
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
993 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_ether_addr,
994 .u = { .ether_addr = etherbuf },
995 .buf = buf,
996 .buflen = buflen,
997 .p = { .ether_addr = etherbufp } };
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
998 return _nss_mcdb_getent(&nss_mcdb_st[NSS_DBTYPE_ETHERS],
999 NSS_DBTYPE_ETHERS, &vinfo);
1000 }
1001
1002 enum nss_status
1003 _nss_files_gethostton_r(const char * const restrict name,
1004 struct ether_addr * const restrict etherbuf)
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
1005 { /* man ether_hostton() */
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
1006 const struct _nss_kinfo kinfo = { .key = name,
1007 .klen = strlen(name),
1008 .tagc = (unsigned char)'=' };
1009 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_ether_addr,
1010 .u = { .ether_addr = etherbuf },
1011 .buf = NULL,
1012 .buflen = 0,
1013 .p = { .NA = 0 } };
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
1014 return _nss_files_get_generic(NSS_DBTYPE_ETHERS, &kinfo, &vinfo);
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
1015 }
1016
1017 enum nss_status
1018 _nss_files_getntohost_r(struct ether_addr * const restrict ether,
1019 char * const restrict buf, const size_t buflen)
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
1020 { /* man ether_ntohost() */
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
1021 char hexstr[8];
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
1022 const struct _nss_kinfo kinfo = { .key = hexstr,
1023 .klen = sizeof(hexstr),
1024 .tagc = (unsigned char)'x' };
1025 const struct _nss_vinfo vinfo = { .decode = _nss_files_decode_buf,
1026 .u = { .NA = 0 },
1027 .buf = buf,
1028 .buflen = buflen,
1029 .p = { .NA = 0 } };
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
1030 /* GPS: FIXME convert ether_addr into hex; TODO need 12 chars for 48 bits */
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
1031 uint32_to_ascii8uphex((uint32_t)ether, hexstr); /* TODO from cdbauthz.c */
c18fd64 @gstrauss continue nss_mcdb implementation
authored May 20, 2010
1032 return _nss_files_get_generic(NSS_DBTYPE_ETHERS, &kinfo, &vinfo);
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
1033 }
1034
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
1035
1036
1037
1038 /* GPS: should have companion routine to _nss_mcdb_db_getshared() which turns
1039 * around and calls mcdb_unregister(m.map), named _nss_mcdb_db_releaseshare()
1040 * or something similar */
1041 /* GPS: if any refcnt were increased, elimination of thread local storage will
1042 * leak that reference and the count will not go to zero
1043 * ==> While with less potential efficiency, perhaps we should mmap per thread.
1044 * No, because the maps would not be cleaned up at thread close.
1045 * Is there an _nss_free_held_resources() routine?
1046 */
1047 /* GPS: if every call to getgrnam() and others has to obtain a lock to increment
1048 * and then decrement refcnt, then that's expensive. Probably want to use
1049 * atomic increment and decrement instead, if possible. Probably not possible.
1050 * Perhaps create a set of _unlocked routines that bypass updating refcnt.
1051 * ==> lookups might take lock, lookup, decode, unlock mutex
1052 * instead of lock, register, unlock, lookup, decode, lock, unregister, unlock
1053 * Create a routine that can be called at synchronization points?
1054 * (to say "clear everything that might otherwise be lost; no current usage")
1055 */
1056 /* TODO create an atexit() routine to walk static maps and munmap recursively
1057 * (might only do if compiled with -D_FORTIFY_SOURCE or something so that we
1058 * free() memory allocated to demonstrate lack of leaking)
1059 */
1060 /* TODO might make all *getent have '=' string and set tagc == '=' */
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
1061 /* TODO might static struct mcdb for each database type
1062 * and for first use, not bother malloc a new structure
1063 * That would lead to race conditions in threaded program.
1064 * unless also protected by a mutex.
1065 */
3ee3625 @gstrauss set FD_CLOEXEC on directory file descriptor
authored May 17, 2010
1066 /* GPS: verify what nss passes in and what it wants as exit values
1067 * It probably always wants enum nss_status
1068 */
1069
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
1070
1071
1072
1073
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
1074 /* GPS: FIXME FIXME FIXME
1075 * mcdb_unregister() calls down to mcdb_mmap_free() if there are no other
1076 * references. mcdb_mmap_free() calls mcdb_mmap_unmap() which will set
1077 * map->ptr to be NULL. We either need to detect this to reopen mmap on
1078 * every usage, or we need to provide a persistence mechanism which checks
1079 * if map needs to be reopened. (Yes, add a stat()) */
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
1080
1081
1082
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
1083 /* GPS: TODO
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
1084 To save some code size, use dispatch table for parse functions?
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
1085 ==> (i.e. have all get*ent() call generic function which parses through
1086 dispatch table)
1087 Might see if we can use dipatch table for other
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
1088 similar types, but not all have similar prototype. Consolidate into
1089 single arg container struct that can be passed as void through to the
1090 parsing. However, the matching still needs to be separate, so it might
1091 not be worth it for other types.
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
1092 */
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
1093
1094
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
1095 #if 0
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
1096
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
1097 To avoid conflicts, prepend *all* types with a char indicating type
1098 (Do not trust user input that might otherwise match a different type)
1a9f9f2 @gstrauss continue implementing nss_mcdb
authored May 17, 2010
1099
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
1100 _nss_files_parse_etherent
1101 _nss_files_parse_grent@@GLIBC_PRIVATE
1102 _nss_files_parse_netent
1103 _nss_files_parse_protoent
1104 _nss_files_parse_pwent@@GLIBC_PRIVATE
1105 _nss_files_parse_rpcent
1106 _nss_files_parse_servent
1107 _nss_files_parse_spent@@GLIBC_PRIVATE
1108
1109 _nss_netgroup_parseline
1110
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
1111
1112 GPS: create a generic routine which all the others call
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
1113 _nss_files_get_generic()
1114 encapsulates getting the shared pointer to mcdb and then unregistering it.
1115 Might also look up in table whether or not to encode the void * key
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
1116 into uppercase hex key. Might make it uint32_t n[2]; for 64 bits
1117 or uint32_t n[4] for 128 bits
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
1118 Might make a routine through which all hex (num) lookups go which takes
1119 key and number of octets (in multiples of 4) to convert to hex,
1120 and constructs _nss_kinfo and then calls _nss_files_get_generic().
1121 (Use switch() and fall through calling ascii8uphex)
1122 (If we're not inlining ascii8uphex(), then probably not worth the effort)
1123 qtype for query-type (lookup by number or by string)
1124 (convert number to uppercase hex)
1125 (might make part of _nss_kinfo)
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
1126 In the parent routines which call the generic, it is their responsibility
1127 to encode multiple info, potentially from structs, into a "key", if, say
1128 a struct ether_addr needs to be made into a number, or port and type
1129 need to be encoded together. Might have to put the number types into
1130 128-bit hex if we want to be generic.
1131
1132 For routines that let you specify port and proto, if proto is NULL, then
1133 have an entry in mcdb configured specifically for that query type when
1134 when creating the mcdb. e.g. a -1 proto means tcp (if present) otherwise
1135 a whatever types are there.
1136
9f14346 @gstrauss use union in struct _nss_vinfo for stricter type safety
authored May 22, 2010
1137 Currently we are passing kinfo through to decode routines to enable further
1138 lookups. If we do not need it, and if we include key info in each entry in
1139 mcdb, then do not pass kinfo and maybe reorder list so that vinfo is in the
1140 same register slot that is passed through.
faf374e @gstrauss continue working on nss_mcdb
authored May 20, 2010
1141
1938e68 @gstrauss nss_mcdb.c - work in progress for name server switch (nss) plugin
authored May 16, 2010
1142 #endif
Something went wrong with that request. Please try again.