aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2021-07-07 18:33:52 +0200
committerFlorian Weimer <fweimer@redhat.com>2021-07-07 18:33:52 +0200
commitf9c8b11ed7726b858cd7b7cea0d3d7c5233d78cf (patch)
tree7a7ebab1e97c4fb74bd7bdf2cee773557d83bdd8
parent6212bb67f4695962748a5981e1b9fea105af74f6 (diff)
downloadglibc-f9c8b11ed7726b858cd7b7cea0d3d7c5233d78cf.tar
glibc-f9c8b11ed7726b858cd7b7cea0d3d7c5233d78cf.tar.gz
glibc-f9c8b11ed7726b858cd7b7cea0d3d7c5233d78cf.tar.bz2
glibc-f9c8b11ed7726b858cd7b7cea0d3d7c5233d78cf.zip
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.h10
-rw-r--r--nss/Makefile3
-rw-r--r--nss/nss_files/files-XXX.c6
-rw-r--r--nss/nss_files/files-alias.c7
-rw-r--r--nss/nss_files/files-ethers.c2
-rw-r--r--nss/nss_files/files-grp.c2
-rw-r--r--nss/nss_files/files-hosts.c6
-rw-r--r--nss/nss_files/files-init.c4
-rw-r--r--nss/nss_files/files-initgroups.c3
-rw-r--r--nss/nss_files/files-netgrp.c5
-rw-r--r--nss/nss_files/files-network.c1
-rw-r--r--nss/nss_files/files-proto.c2
-rw-r--r--nss/nss_files/files-pwd.c2
-rw-r--r--nss/nss_files/files-rpc.c2
-rw-r--r--nss/nss_files/files-service.c2
-rw-r--r--nss/nss_files/files-sgrp.c2
-rw-r--r--nss/nss_files/files-spwd.c2
-rw-r--r--nss/nss_files_functions.c43
-rw-r--r--nss/nss_module.c38
-rw-r--r--nss/nss_module.h4
20 files changed, 114 insertions, 32 deletions
diff --git a/include/nss_files.h b/include/nss_files.h
index dd0081a0f1..6190cac6be 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 7259e83bb3..63a386af18 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 91553d7ca5..c158a891bd 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 75d91e0b0a..8c6e176ff6 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 2fe7f81e4b..7c2c2b9833 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 49be38e8b1..a716d948e2 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 894b85d501..d54d91d038 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 717c9fd334..18ed288d04 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 6fcea40b55..b44211e50b 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 be9c72accf..75bfbd9e44 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 75c9f8a57e..217ed78609 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 98d082c642..13072692c1 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 b04165ddde..5c74c6da9b 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 eeb2725d2c..3dea8f18f2 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 f4f0985377..a8d83e094e 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 6b1c9eac02..213a408e7b 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 976deaf918..d031257a20 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 0000000000..85720b4311
--- /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 60c070c851..7b42c585a4 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 05c4791d11..c1a1d90b60 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
{