1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-29 11:41:21 +03:00

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>
This commit is contained in:
Florian Weimer
2021-07-07 18:33:52 +02:00
parent 6212bb67f4
commit f9c8b11ed7
20 changed files with 114 additions and 32 deletions

View File

@ -19,6 +19,7 @@
#ifndef _NSS_FILES_H #ifndef _NSS_FILES_H
#define _NSS_FILES_H #define _NSS_FILES_H
#include <nss.h>
#include <stdio.h> #include <stdio.h>
#if IS_IN (libc) #if IS_IN (libc)
#include <libc-lock.h> #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_sgent)
libc_hidden_proto (_nss_files_parse_spent) 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 /* Generic implementation of fget*ent_r. Reads lines from FP until
EOF or a successful parse into *RESULT using PARSER. Returns 0 on EOF or a successful parse into *RESULT using PARSER. Returns 0 on
success, ENOENT on EOF, ERANGE on too-small buffer. */ success, ENOENT on EOF, ERANGE on too-small buffer. */

View File

@ -31,7 +31,8 @@ routines = nsswitch getnssent getnssent_r digits_dots \
compat-lookup nss_hash nss_files_fopen \ compat-lookup nss_hash nss_files_fopen \
nss_readline nss_parse_line_result \ nss_readline nss_parse_line_result \
nss_fgetent_r nss_module nss_action \ 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. # These are the databases that go through nss dispatch.
# Caution: if you add a database here, you must add its real name # Caution: if you add a database here, you must add its real name

View File

@ -91,12 +91,14 @@ CONCAT(_nss_files_set,ENTNAME) (int stayopen)
{ {
return __nss_files_data_setent (CONCAT (nss_file_, ENTNAME), DATAFILE); return __nss_files_data_setent (CONCAT (nss_file_, ENTNAME), DATAFILE);
} }
libc_hidden_def (CONCAT (_nss_files_set,ENTNAME))
enum nss_status enum nss_status
CONCAT(_nss_files_end,ENTNAME) (void) CONCAT(_nss_files_end,ENTNAME) (void)
{ {
return __nss_files_data_endent (CONCAT (nss_file_, ENTNAME)); 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. */ /* 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); __nss_files_data_put (data);
return status; return status;
} }
libc_hidden_def (CONCAT (_nss_files_get,ENTNAME_r))
/* Macro for defining lookup functions for this file-based database. /* Macro for defining lookup functions for this file-based database.
@ -215,4 +218,5 @@ _nss_files_get##name##_r (proto, \
} \ } \
\ \
return status; \ return status; \
} } \
libc_hidden_def (_nss_files_get##name##_r)

View File

@ -31,8 +31,6 @@
#include "nsswitch.h" #include "nsswitch.h"
#include <nss_files.h> #include <nss_files.h>
NSS_DECLARE_MODULE_FUNCTIONS (files)
/* Maintenance of the stream open on the database file. For getXXent /* Maintenance of the stream open on the database file. For getXXent
operations the stream needs to be held open across calls, the other 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"); return __nss_files_data_setent (nss_file_aliasent, "/etc/aliases");
} }
libc_hidden_def (_nss_files_setaliasent)
enum nss_status enum nss_status
_nss_files_endaliasent (void) _nss_files_endaliasent (void)
{ {
return __nss_files_data_endent (nss_file_aliasent); return __nss_files_data_endent (nss_file_aliasent);
} }
libc_hidden_def (_nss_files_endaliasent)
/* Parsing the database file into `struct aliasent' data structures. */ /* Parsing the database file into `struct aliasent' data structures. */
static enum nss_status 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); __nss_files_data_put (data);
return status; return status;
} }
libc_hidden_def (_nss_files_getaliasent_r)
enum nss_status enum nss_status
_nss_files_getaliasbyname_r (const char *name, struct aliasent *result, _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; return status;
} }
libc_hidden_def (_nss_files_getaliasbyname_r)

View File

@ -20,8 +20,6 @@
#include <netinet/if_ether.h> #include <netinet/if_ether.h>
#include <nss.h> #include <nss.h>
NSS_DECLARE_MODULE_FUNCTIONS (files)
struct etherent_data {}; struct etherent_data {};
#define ENTNAME etherent #define ENTNAME etherent

View File

@ -19,8 +19,6 @@
#include <grp.h> #include <grp.h>
#include <nss.h> #include <nss.h>
NSS_DECLARE_MODULE_FUNCTIONS (files)
#define STRUCTURE group #define STRUCTURE group
#define ENTNAME grent #define ENTNAME grent
#define DATABASE "group" #define DATABASE "group"

View File

@ -26,8 +26,6 @@
#include <alloc_buffer.h> #include <alloc_buffer.h>
#include <nss.h> #include <nss.h>
NSS_DECLARE_MODULE_FUNCTIONS (files)
/* Get implementation for some internal functions. */ /* Get implementation for some internal functions. */
#include "../resolv/res_hconf.h" #include "../resolv/res_hconf.h"
@ -358,6 +356,7 @@ _nss_files_gethostbyname3_r (const char *name, int af, struct hostent *result,
return status; return status;
} }
libc_hidden_def (_nss_files_gethostbyname3_r)
enum nss_status enum nss_status
_nss_files_gethostbyname_r (const char *name, struct hostent *result, _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, return _nss_files_gethostbyname3_r (name, AF_INET, result, buffer, buflen,
errnop, herrnop, NULL, NULL); errnop, herrnop, NULL, NULL);
} }
libc_hidden_def (_nss_files_gethostbyname_r)
enum nss_status enum nss_status
_nss_files_gethostbyname2_r (const char *name, int af, struct hostent *result, _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, return _nss_files_gethostbyname3_r (name, af, result, buffer, buflen,
errnop, herrnop, NULL, NULL); errnop, herrnop, NULL, NULL);
} }
libc_hidden_def (_nss_files_gethostbyname2_r)
enum nss_status enum nss_status
_nss_files_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, _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; return status;
} }
libc_hidden_def (_nss_files_gethostbyname4_r)

View File

@ -21,8 +21,7 @@
#include <string.h> #include <string.h>
#include <nscd/nscd.h> #include <nscd/nscd.h>
#include <nss.h> #include <nss.h>
#include <nss_files.h>
NSS_DECLARE_MODULE_FUNCTIONS (files)
static void static void
register_file (void (*cb) (size_t, struct traced_file *), 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, servdb, "/etc/services", 0);
register_file (cb, netgrdb, "/etc/netgroup", 0); register_file (cb, netgrdb, "/etc/netgroup", 0);
} }
libc_hidden_def (_nss_files_init)
#endif #endif

View File

@ -28,8 +28,6 @@
#include <nss.h> #include <nss.h>
#include <nss_files.h> #include <nss_files.h>
NSS_DECLARE_MODULE_FUNCTIONS (files)
enum nss_status enum nss_status
_nss_files_initgroups_dyn (const char *user, gid_t group, long int *start, _nss_files_initgroups_dyn (const char *user, gid_t group, long int *start,
long int *size, gid_t **groupsp, long int limit, 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; return status == NSS_STATUS_SUCCESS && !any ? NSS_STATUS_NOTFOUND : status;
} }
libc_hidden_def (_nss_files_initgroups_dyn)

View File

@ -28,8 +28,6 @@
#include "netgroup.h" #include "netgroup.h"
#include <nss_files.h> #include <nss_files.h>
NSS_DECLARE_MODULE_FUNCTIONS (files)
#define DATAFILE "/etc/netgroup" #define DATAFILE "/etc/netgroup"
libc_hidden_proto (_nss_files_endnetgrent) libc_hidden_proto (_nss_files_endnetgrent)
@ -152,7 +150,7 @@ _nss_files_setnetgrent (const char *group, struct __netgrent *result)
return status; return status;
} }
libc_hidden_def (_nss_files_setnetgrent)
enum nss_status enum nss_status
_nss_files_endnetgrent (struct __netgrent *result) _nss_files_endnetgrent (struct __netgrent *result)
@ -293,3 +291,4 @@ _nss_files_getnetgrent_r (struct __netgrent *result, char *buffer,
return status; return status;
} }
libc_hidden_def (_nss_files_getnetgrent_r)

View File

@ -21,7 +21,6 @@
#include <netdb.h> #include <netdb.h>
#include <stdint.h> #include <stdint.h>
#include <nss.h> #include <nss.h>
#include <nss_files.h>
#define ENTNAME netent #define ENTNAME netent
#define DATABASE "networks" #define DATABASE "networks"

View File

@ -19,8 +19,6 @@
#include <netdb.h> #include <netdb.h>
#include <nss.h> #include <nss.h>
NSS_DECLARE_MODULE_FUNCTIONS (files)
#define ENTNAME protoent #define ENTNAME protoent
#define DATABASE "protocols" #define DATABASE "protocols"

View File

@ -19,8 +19,6 @@
#include <pwd.h> #include <pwd.h>
#include <nss.h> #include <nss.h>
NSS_DECLARE_MODULE_FUNCTIONS (files)
#define STRUCTURE passwd #define STRUCTURE passwd
#define ENTNAME pwent #define ENTNAME pwent
#define DATABASE "passwd" #define DATABASE "passwd"

View File

@ -19,8 +19,6 @@
#include <rpc/netdb.h> #include <rpc/netdb.h>
#include <nss.h> #include <nss.h>
NSS_DECLARE_MODULE_FUNCTIONS (files)
#define ENTNAME rpcent #define ENTNAME rpcent
#define DATABASE "rpc" #define DATABASE "rpc"

View File

@ -20,8 +20,6 @@
#include <netdb.h> #include <netdb.h>
#include <nss.h> #include <nss.h>
NSS_DECLARE_MODULE_FUNCTIONS (files)
#define ENTNAME servent #define ENTNAME servent
#define DATABASE "services" #define DATABASE "services"

View File

@ -19,8 +19,6 @@
#include <gshadow.h> #include <gshadow.h>
#include <nss.h> #include <nss.h>
NSS_DECLARE_MODULE_FUNCTIONS (files)
#define STRUCTURE sgrp #define STRUCTURE sgrp
#define ENTNAME sgent #define ENTNAME sgent
#define DATABASE "gshadow" #define DATABASE "gshadow"

View File

@ -19,8 +19,6 @@
#include <shadow.h> #include <shadow.h>
#include <nss.h> #include <nss.h>
NSS_DECLARE_MODULE_FUNCTIONS (files)
#define STRUCTURE spwd #define STRUCTURE spwd
#define ENTNAME spent #define ENTNAME spent
#define DATABASE "shadow" #define DATABASE "shadow"

43
nss/nss_files_functions.c Normal file
View File

@ -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
}

View File

@ -30,6 +30,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <nss_files.h>
/* Suffix after .so of NSS service modules. This is a bit of magic, /* 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 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" #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. */ /* Internal implementation of __nss_module_load. */
static bool static bool
module_load (struct nss_module *module) module_load (struct nss_module *module)
{ {
if (strcmp (module->name, "files") == 0)
return module_load_nss_files (module);
void *handle; void *handle;
{ {
char *shlib_name; char *shlib_name;
@ -360,7 +396,7 @@ __nss_module_freeres (void)
struct nss_module *current = nss_module_list; struct nss_module *current = nss_module_list;
while (current != NULL) while (current != NULL)
{ {
if (current->state == nss_module_loaded) if (current->state == nss_module_loaded && current->handle != NULL)
__libc_dlclose (current->handle); __libc_dlclose (current->handle);
struct nss_module *next = current->next; struct nss_module *next = current->next;

View File

@ -38,6 +38,10 @@ struct nss_module_functions
typedef void *nss_module_functions_untyped[sizeof (struct nss_module_functions) typedef void *nss_module_functions_untyped[sizeof (struct nss_module_functions)
/ sizeof (void *)]; / 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. */ /* Initialization state of a NSS module. */
enum nss_module_state enum nss_module_state
{ {