diff options
author | Florian Weimer <fweimer@redhat.com> | 2021-07-07 18:33:52 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2021-07-07 18:33:52 +0200 |
commit | f9c8b11ed7726b858cd7b7cea0d3d7c5233d78cf (patch) | |
tree | 7a7ebab1e97c4fb74bd7bdf2cee773557d83bdd8 | |
parent | 6212bb67f4695962748a5981e1b9fea105af74f6 (diff) | |
download | glibc-f9c8b11ed7726b858cd7b7cea0d3d7c5233d78cf.zip glibc-f9c8b11ed7726b858cd7b7cea0d3d7c5233d78cf.tar.gz glibc-f9c8b11ed7726b858cd7b7cea0d3d7c5233d78cf.tar.bz2 |
nss: Access nss_files through direct references
This partially fixes static-only NSS support (bug 27959): The files
module no longer needs dlopen. Support for the dns module remains
to be added, and also support for disabling dlopen altogether.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
-rw-r--r-- | include/nss_files.h | 10 | ||||
-rw-r--r-- | nss/Makefile | 3 | ||||
-rw-r--r-- | nss/nss_files/files-XXX.c | 6 | ||||
-rw-r--r-- | nss/nss_files/files-alias.c | 7 | ||||
-rw-r--r-- | nss/nss_files/files-ethers.c | 2 | ||||
-rw-r--r-- | nss/nss_files/files-grp.c | 2 | ||||
-rw-r--r-- | nss/nss_files/files-hosts.c | 6 | ||||
-rw-r--r-- | nss/nss_files/files-init.c | 4 | ||||
-rw-r--r-- | nss/nss_files/files-initgroups.c | 3 | ||||
-rw-r--r-- | nss/nss_files/files-netgrp.c | 5 | ||||
-rw-r--r-- | nss/nss_files/files-network.c | 1 | ||||
-rw-r--r-- | nss/nss_files/files-proto.c | 2 | ||||
-rw-r--r-- | nss/nss_files/files-pwd.c | 2 | ||||
-rw-r--r-- | nss/nss_files/files-rpc.c | 2 | ||||
-rw-r--r-- | nss/nss_files/files-service.c | 2 | ||||
-rw-r--r-- | nss/nss_files/files-sgrp.c | 2 | ||||
-rw-r--r-- | nss/nss_files/files-spwd.c | 2 | ||||
-rw-r--r-- | nss/nss_files_functions.c | 43 | ||||
-rw-r--r-- | nss/nss_module.c | 38 | ||||
-rw-r--r-- | nss/nss_module.h | 4 |
20 files changed, 114 insertions, 32 deletions
diff --git a/include/nss_files.h b/include/nss_files.h index dd0081a..6190cac 100644 --- a/include/nss_files.h +++ b/include/nss_files.h @@ -19,6 +19,7 @@ #ifndef _NSS_FILES_H #define _NSS_FILES_H +#include <nss.h> #include <stdio.h> #if IS_IN (libc) #include <libc-lock.h> @@ -134,6 +135,15 @@ libc_hidden_proto (_nss_files_parse_servent) libc_hidden_proto (_nss_files_parse_sgent) libc_hidden_proto (_nss_files_parse_spent) +NSS_DECLARE_MODULE_FUNCTIONS (files) +#undef DEFINE_NSS_FUNCTION +#define DEFINE_NSS_FUNCTION(x) libc_hidden_proto (_nss_files_##x) +#include <nss/function.def> +#undef DEFINE_NSS_FUNCTION + +void _nss_files_init (void (*cb) (size_t, struct traced_file *)); +libc_hidden_proto (_nss_files_init) + /* Generic implementation of fget*ent_r. Reads lines from FP until EOF or a successful parse into *RESULT using PARSER. Returns 0 on success, ENOENT on EOF, ERANGE on too-small buffer. */ diff --git a/nss/Makefile b/nss/Makefile index 7259e83..63a386a 100644 --- a/nss/Makefile +++ b/nss/Makefile @@ -31,7 +31,8 @@ routines = nsswitch getnssent getnssent_r digits_dots \ compat-lookup nss_hash nss_files_fopen \ nss_readline nss_parse_line_result \ nss_fgetent_r nss_module nss_action \ - nss_action_parse nss_database nss_files_data + nss_action_parse nss_database nss_files_data \ + nss_files_functions # These are the databases that go through nss dispatch. # Caution: if you add a database here, you must add its real name diff --git a/nss/nss_files/files-XXX.c b/nss/nss_files/files-XXX.c index 91553d7..c158a89 100644 --- a/nss/nss_files/files-XXX.c +++ b/nss/nss_files/files-XXX.c @@ -91,12 +91,14 @@ CONCAT(_nss_files_set,ENTNAME) (int stayopen) { return __nss_files_data_setent (CONCAT (nss_file_, ENTNAME), DATAFILE); } +libc_hidden_def (CONCAT (_nss_files_set,ENTNAME)) enum nss_status CONCAT(_nss_files_end,ENTNAME) (void) { return __nss_files_data_endent (CONCAT (nss_file_, ENTNAME)); } +libc_hidden_def (CONCAT (_nss_files_end,ENTNAME)) /* Parsing the database file into `struct STRUCTURE' data structures. */ @@ -179,6 +181,7 @@ CONCAT(_nss_files_get,ENTNAME_r) (struct STRUCTURE *result, char *buffer, __nss_files_data_put (data); return status; } +libc_hidden_def (CONCAT (_nss_files_get,ENTNAME_r)) /* Macro for defining lookup functions for this file-based database. @@ -215,4 +218,5 @@ _nss_files_get##name##_r (proto, \ } \ \ return status; \ -} +} \ +libc_hidden_def (_nss_files_get##name##_r) diff --git a/nss/nss_files/files-alias.c b/nss/nss_files/files-alias.c index 75d91e0..8c6e176 100644 --- a/nss/nss_files/files-alias.c +++ b/nss/nss_files/files-alias.c @@ -31,8 +31,6 @@ #include "nsswitch.h" #include <nss_files.h> -NSS_DECLARE_MODULE_FUNCTIONS (files) - /* Maintenance of the stream open on the database file. For getXXent operations the stream needs to be held open across calls, the other @@ -63,12 +61,14 @@ _nss_files_setaliasent (void) { return __nss_files_data_setent (nss_file_aliasent, "/etc/aliases"); } +libc_hidden_def (_nss_files_setaliasent) enum nss_status _nss_files_endaliasent (void) { return __nss_files_data_endent (nss_file_aliasent); } +libc_hidden_def (_nss_files_endaliasent) /* Parsing the database file into `struct aliasent' data structures. */ static enum nss_status @@ -354,7 +354,7 @@ _nss_files_getaliasent_r (struct aliasent *result, char *buffer, size_t buflen, __nss_files_data_put (data); return status; } - +libc_hidden_def (_nss_files_getaliasent_r) enum nss_status _nss_files_getaliasbyname_r (const char *name, struct aliasent *result, @@ -387,3 +387,4 @@ _nss_files_getaliasbyname_r (const char *name, struct aliasent *result, return status; } +libc_hidden_def (_nss_files_getaliasbyname_r) diff --git a/nss/nss_files/files-ethers.c b/nss/nss_files/files-ethers.c index 2fe7f81..7c2c2b9 100644 --- a/nss/nss_files/files-ethers.c +++ b/nss/nss_files/files-ethers.c @@ -20,8 +20,6 @@ #include <netinet/if_ether.h> #include <nss.h> -NSS_DECLARE_MODULE_FUNCTIONS (files) - struct etherent_data {}; #define ENTNAME etherent diff --git a/nss/nss_files/files-grp.c b/nss/nss_files/files-grp.c index 49be38e..a716d94 100644 --- a/nss/nss_files/files-grp.c +++ b/nss/nss_files/files-grp.c @@ -19,8 +19,6 @@ #include <grp.h> #include <nss.h> -NSS_DECLARE_MODULE_FUNCTIONS (files) - #define STRUCTURE group #define ENTNAME grent #define DATABASE "group" diff --git a/nss/nss_files/files-hosts.c b/nss/nss_files/files-hosts.c index 894b85d..d54d91d 100644 --- a/nss/nss_files/files-hosts.c +++ b/nss/nss_files/files-hosts.c @@ -26,8 +26,6 @@ #include <alloc_buffer.h> #include <nss.h> -NSS_DECLARE_MODULE_FUNCTIONS (files) - /* Get implementation for some internal functions. */ #include "../resolv/res_hconf.h" @@ -358,6 +356,7 @@ _nss_files_gethostbyname3_r (const char *name, int af, struct hostent *result, return status; } +libc_hidden_def (_nss_files_gethostbyname3_r) enum nss_status _nss_files_gethostbyname_r (const char *name, struct hostent *result, @@ -367,6 +366,7 @@ _nss_files_gethostbyname_r (const char *name, struct hostent *result, return _nss_files_gethostbyname3_r (name, AF_INET, result, buffer, buflen, errnop, herrnop, NULL, NULL); } +libc_hidden_def (_nss_files_gethostbyname_r) enum nss_status _nss_files_gethostbyname2_r (const char *name, int af, struct hostent *result, @@ -376,6 +376,7 @@ _nss_files_gethostbyname2_r (const char *name, int af, struct hostent *result, return _nss_files_gethostbyname3_r (name, af, result, buffer, buflen, errnop, herrnop, NULL, NULL); } +libc_hidden_def (_nss_files_gethostbyname2_r) enum nss_status _nss_files_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, @@ -491,3 +492,4 @@ _nss_files_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, return status; } +libc_hidden_def (_nss_files_gethostbyname4_r) diff --git a/nss/nss_files/files-init.c b/nss/nss_files/files-init.c index 717c9fd..18ed288 100644 --- a/nss/nss_files/files-init.c +++ b/nss/nss_files/files-init.c @@ -21,8 +21,7 @@ #include <string.h> #include <nscd/nscd.h> #include <nss.h> - -NSS_DECLARE_MODULE_FUNCTIONS (files) +#include <nss_files.h> static void register_file (void (*cb) (size_t, struct traced_file *), @@ -49,5 +48,6 @@ _nss_files_init (void (*cb) (size_t, struct traced_file *)) register_file (cb, servdb, "/etc/services", 0); register_file (cb, netgrdb, "/etc/netgroup", 0); } +libc_hidden_def (_nss_files_init) #endif diff --git a/nss/nss_files/files-initgroups.c b/nss/nss_files/files-initgroups.c index 6fcea40..b44211e 100644 --- a/nss/nss_files/files-initgroups.c +++ b/nss/nss_files/files-initgroups.c @@ -28,8 +28,6 @@ #include <nss.h> #include <nss_files.h> -NSS_DECLARE_MODULE_FUNCTIONS (files) - enum nss_status _nss_files_initgroups_dyn (const char *user, gid_t group, long int *start, long int *size, gid_t **groupsp, long int limit, @@ -129,3 +127,4 @@ _nss_files_initgroups_dyn (const char *user, gid_t group, long int *start, return status == NSS_STATUS_SUCCESS && !any ? NSS_STATUS_NOTFOUND : status; } +libc_hidden_def (_nss_files_initgroups_dyn) diff --git a/nss/nss_files/files-netgrp.c b/nss/nss_files/files-netgrp.c index be9c72a..75bfbd9 100644 --- a/nss/nss_files/files-netgrp.c +++ b/nss/nss_files/files-netgrp.c @@ -28,8 +28,6 @@ #include "netgroup.h" #include <nss_files.h> -NSS_DECLARE_MODULE_FUNCTIONS (files) - #define DATAFILE "/etc/netgroup" libc_hidden_proto (_nss_files_endnetgrent) @@ -152,7 +150,7 @@ _nss_files_setnetgrent (const char *group, struct __netgrent *result) return status; } - +libc_hidden_def (_nss_files_setnetgrent) enum nss_status _nss_files_endnetgrent (struct __netgrent *result) @@ -293,3 +291,4 @@ _nss_files_getnetgrent_r (struct __netgrent *result, char *buffer, return status; } +libc_hidden_def (_nss_files_getnetgrent_r) diff --git a/nss/nss_files/files-network.c b/nss/nss_files/files-network.c index 75c9f8a..217ed78 100644 --- a/nss/nss_files/files-network.c +++ b/nss/nss_files/files-network.c @@ -21,7 +21,6 @@ #include <netdb.h> #include <stdint.h> #include <nss.h> -#include <nss_files.h> #define ENTNAME netent #define DATABASE "networks" diff --git a/nss/nss_files/files-proto.c b/nss/nss_files/files-proto.c index 98d082c..1307269 100644 --- a/nss/nss_files/files-proto.c +++ b/nss/nss_files/files-proto.c @@ -19,8 +19,6 @@ #include <netdb.h> #include <nss.h> -NSS_DECLARE_MODULE_FUNCTIONS (files) - #define ENTNAME protoent #define DATABASE "protocols" diff --git a/nss/nss_files/files-pwd.c b/nss/nss_files/files-pwd.c index b04165d..5c74c6d 100644 --- a/nss/nss_files/files-pwd.c +++ b/nss/nss_files/files-pwd.c @@ -19,8 +19,6 @@ #include <pwd.h> #include <nss.h> -NSS_DECLARE_MODULE_FUNCTIONS (files) - #define STRUCTURE passwd #define ENTNAME pwent #define DATABASE "passwd" diff --git a/nss/nss_files/files-rpc.c b/nss/nss_files/files-rpc.c index eeb2725..3dea8f1 100644 --- a/nss/nss_files/files-rpc.c +++ b/nss/nss_files/files-rpc.c @@ -19,8 +19,6 @@ #include <rpc/netdb.h> #include <nss.h> -NSS_DECLARE_MODULE_FUNCTIONS (files) - #define ENTNAME rpcent #define DATABASE "rpc" diff --git a/nss/nss_files/files-service.c b/nss/nss_files/files-service.c index f4f0985..a8d83e0 100644 --- a/nss/nss_files/files-service.c +++ b/nss/nss_files/files-service.c @@ -20,8 +20,6 @@ #include <netdb.h> #include <nss.h> -NSS_DECLARE_MODULE_FUNCTIONS (files) - #define ENTNAME servent #define DATABASE "services" diff --git a/nss/nss_files/files-sgrp.c b/nss/nss_files/files-sgrp.c index 6b1c9ea..213a408 100644 --- a/nss/nss_files/files-sgrp.c +++ b/nss/nss_files/files-sgrp.c @@ -19,8 +19,6 @@ #include <gshadow.h> #include <nss.h> -NSS_DECLARE_MODULE_FUNCTIONS (files) - #define STRUCTURE sgrp #define ENTNAME sgent #define DATABASE "gshadow" diff --git a/nss/nss_files/files-spwd.c b/nss/nss_files/files-spwd.c index 976deaf..d031257 100644 --- a/nss/nss_files/files-spwd.c +++ b/nss/nss_files/files-spwd.c @@ -19,8 +19,6 @@ #include <shadow.h> #include <nss.h> -NSS_DECLARE_MODULE_FUNCTIONS (files) - #define STRUCTURE spwd #define ENTNAME spent #define DATABASE "shadow" diff --git a/nss/nss_files_functions.c b/nss/nss_files_functions.c new file mode 100644 index 0000000..85720b4 --- /dev/null +++ b/nss/nss_files_functions.c @@ -0,0 +1,43 @@ +/* Direct access for nss_files functions for NSS module loading. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <https://www.gnu.org/licenses/>. */ + +#include <nss_module.h> +#include <nss_files.h> + +void +__nss_files_functions (nss_module_functions_untyped pointers) +{ + void **fptr = pointers; + + /* Functions which are not implemented. */ +#define _nss_files_getcanonname_r NULL +#define _nss_files_gethostbyaddr2_r NULL +#define _nss_files_getpublickey NULL +#define _nss_files_getsecretkey NULL +#define _nss_files_netname2user NULL + +#undef DEFINE_NSS_FUNCTION +#define DEFINE_NSS_FUNCTION(x) *fptr++ = _nss_files_##x; +#include "function.def" + +#ifdef PTR_MANGLE + void **end = fptr; + for (fptr = pointers; fptr != end; ++fptr) + PTR_MANGLE (*fptr); +#endif +} diff --git a/nss/nss_module.c b/nss/nss_module.c index 60c070c..7b42c58 100644 --- a/nss/nss_module.c +++ b/nss/nss_module.c @@ -30,6 +30,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <nss_files.h> /* Suffix after .so of NSS service modules. This is a bit of magic, but we assume LIBNSS_FILES_SO looks like "libnss_files.so.2" and we @@ -110,10 +111,45 @@ static const function_name nss_function_name_array[] = #include "function.def" }; +static bool +module_load_nss_files (struct nss_module *module) +{ + if (is_nscd) + { + void (*cb) (size_t, struct traced_file *) = nscd_init_cb; +# ifdef PTR_DEMANGLE + PTR_DEMANGLE (cb); +# endif + _nss_files_init (cb); + } + + /* Initialize the function pointers, following the double-checked + locking idiom. */ + __libc_lock_lock (nss_module_list_lock); + switch ((enum nss_module_state) atomic_load_acquire (&module->state)) + { + case nss_module_uninitialized: + case nss_module_failed: + __nss_files_functions (module->functions.untyped); + module->handle = NULL; + /* Synchronizes with unlocked __nss_module_load atomic_load_acquire. */ + atomic_store_release (&module->state, nss_module_loaded); + break; + case nss_module_loaded: + /* Nothing to clean up. */ + break; + } + __libc_lock_unlock (nss_module_list_lock); + return true; +} + /* Internal implementation of __nss_module_load. */ static bool module_load (struct nss_module *module) { + if (strcmp (module->name, "files") == 0) + return module_load_nss_files (module); + void *handle; { char *shlib_name; @@ -360,7 +396,7 @@ __nss_module_freeres (void) struct nss_module *current = nss_module_list; while (current != NULL) { - if (current->state == nss_module_loaded) + if (current->state == nss_module_loaded && current->handle != NULL) __libc_dlclose (current->handle); struct nss_module *next = current->next; diff --git a/nss/nss_module.h b/nss/nss_module.h index 05c4791..c1a1d90 100644 --- a/nss/nss_module.h +++ b/nss/nss_module.h @@ -38,6 +38,10 @@ struct nss_module_functions typedef void *nss_module_functions_untyped[sizeof (struct nss_module_functions) / sizeof (void *)]; +/* Locate the nss_files functions, as if by dlopen/dlsym. */ +void __nss_files_functions (nss_module_functions_untyped pointers) + attribute_hidden; + /* Initialization state of a NSS module. */ enum nss_module_state { |