Remove --enable-obsolete-nsl configure flag

this means that *always* libnsl is only built as shared library for
backward compatibility and the NSS modules libnss_nis and libnss_nisplus
are not built at all, libnsl's headers aren't installed.

This compatibility is kept only for architectures and ABIs that have
been added in or before version 2.28.

Replacement implementations based on TIRPC, which additionally support
IPv6, are available from <https://github.com/thkukuk/>.

This change does not affect libnss_compat which does not depended
on libnsl since 2.27 and thus can be used without NIS.

libnsl code depends on Sun RPC, e.g. on --enable-obsolete-rpc (installed
libnsl headers use installed Sun RPC headers), which will be removed in
the following commit.
This commit is contained in:
Petr Vorel 2020-07-08 13:06:55 +02:00 committed by Florian Weimer
parent acb527929d
commit ae7a94e5e3
71 changed files with 48 additions and 11162 deletions

View File

@ -227,15 +227,6 @@ if 'CFLAGS' is specified it must enable optimization. For example:
colon-separated list in a single environment variable
'GLIBC_TUNABLES'.
'--enable-obsolete-nsl'
By default, libnsl is only built as shared library for backward
compatibility and the NSS modules libnss_compat, libnss_nis and
libnss_nisplus are not built at all. Use this option to enable
libnsl with all depending NSS modules and header files. For
architectures and ABIs that have been added after version 2.28 of
the GNU C Library this option is not available, and the libnsl
compatibility library is not built.
'--disable-crypt'
Do not install the passphrase-hashing library 'libcrypt' or the
header file 'crypt.h'. 'unistd.h' will still declare the function

20
NEWS
View File

@ -80,6 +80,16 @@ Major new features:
Deprecated and removed features, and other changes affecting compatibility:
* Remove configure option --enable-obsolete-nsl. libnsl is only built
as shared library for backward compatibility and the NSS modules "nis"
and "nisplus" are not built at all and libnsl's headers aren't
installed. This compatibility is kept only for architectures and ABIs
that have been added in or before version 2.28. Replacement
implementations based on TI-RPC, which additionally support IPv6, are
available from <https://github.com/thkukuk/>. This change does not
affect the "compat" NSS module, which does not depended on libnsl
since 2.27 and thus can be used without NIS.
* The deprecated <sys/sysctl.h> header and the sysctl function have been
removed. To support old binaries, the sysctl function continues to
exist as a compatibility symbol (on those architectures which had it),
@ -115,11 +125,11 @@ Deprecated and removed features, and other changes affecting compatibility:
or contents might be overwritten on subsequent calls in the same thread or
if the thread is terminated. It makes strerror MT-safe.
* The "files", "nis" and "nisplus" NSS modules no longer supports the
"key" database (used for secure RPC). The contents of the
/etc/publickey file will be ignored, regardless of the settings in
/etc/nsswitch.conf. (This method of storing RPC keys only supported
the obsolete and insecure AUTH_DES flavor of secure RPC.)
* The "files" NSS module no longer supports the "key" database (used for
secure RPC). The contents of the /etc/publickey file will be ignored,
regardless of the settings in /etc/nsswitch.conf. (This method of
storing RPC keys only supported the obsolete and insecure AUTH_DES
flavor of secure RPC.)
Changes to build and runtime requirements:

View File

@ -167,10 +167,6 @@
to link against. */
#undef LINK_OBSOLETE_RPC
/* Define if obsolete libnsl code should be made available for user-level
code to link against. */
#undef LINK_OBSOLETE_NSL
/* Define if Systemtap <sys/sdt.h> probes should be defined. */
#undef USE_STAP_PROBE

View File

@ -97,7 +97,6 @@ build-static-nss = @static_nss@
cross-compiling = @cross_compiling@
force-install = @force_install@
link-obsolete-rpc = @link_obsolete_rpc@
build-obsolete-nsl = @build_obsolete_nsl@
build-crypt = @build_crypt@
build-nscd = @build_nscd@
use-nscd = @use_nscd@

20
configure vendored
View File

@ -673,7 +673,6 @@ base_machine
have_tunables
build_pt_chown
build_nscd
build_obsolete_nsl
link_obsolete_rpc
libc_cv_static_nss_crypt
libc_cv_nss_crypt
@ -786,7 +785,6 @@ enable_experimental_malloc
enable_crypt
enable_nss_crypt
enable_obsolete_rpc
enable_obsolete_nsl
enable_systemtap
enable_build_nscd
enable_nscd
@ -1459,8 +1457,6 @@ Optional Features:
--enable-nss-crypt enable libcrypt to use nss
--enable-obsolete-rpc build and install the obsolete RPC code for
link-time usage
--enable-obsolete-nsl build and install the obsolete libnsl library and
depending NSS modules
--enable-systemtap enable systemtap static probe points [default=no]
--disable-build-nscd disable building and installing the nscd daemon
--disable-nscd library functions will not contact the nscd daemon
@ -3654,20 +3650,6 @@ if test "$link_obsolete_rpc" = yes; then
fi
# Check whether --enable-obsolete-nsl was given.
if test "${enable_obsolete_nsl+set}" = set; then :
enableval=$enable_obsolete_nsl; build_obsolete_nsl=$enableval
else
build_obsolete_nsl=no
fi
if test "$build_obsolete_nsl" = yes; then
$as_echo "#define LINK_OBSOLETE_NSL 1" >>confdefs.h
fi
# Check whether --enable-systemtap was given.
if test "${enable_systemtap+set}" = set; then :
enableval=$enable_systemtap; systemtap=$enableval
@ -3785,7 +3767,7 @@ main ()
{
#ifndef __CET__
#error no CET compiler support
# error no CET compiler support
#endif
;
return 0;

View File

@ -387,17 +387,6 @@ if test "$link_obsolete_rpc" = yes; then
AC_DEFINE(LINK_OBSOLETE_RPC)
fi
AC_ARG_ENABLE([obsolete-nsl],
AC_HELP_STRING([--enable-obsolete-nsl],
[build and install the obsolete libnsl library and depending NSS modules]),
[build_obsolete_nsl=$enableval],
[build_obsolete_nsl=no])
AC_SUBST(build_obsolete_nsl)
if test "$build_obsolete_nsl" = yes; then
AC_DEFINE(LINK_OBSOLETE_NSL)
fi
AC_ARG_ENABLE([systemtap],
[AS_HELP_STRING([--enable-systemtap],
[enable systemtap static probe points @<:@default=no@:>@])],

View File

@ -31,12 +31,6 @@
#include "../nscd/nscd-client.h"
#include "../nscd/nscd_proto.h"
#ifdef LINK_OBSOLETE_NSL
# define DEFAULT_CONFIG "compat [NOTFOUND=return] files"
#else
# define DEFAULT_CONFIG "files"
#endif
/* Type of the lookup function. */
typedef enum nss_status (*initgroups_dyn_function) (const char *, gid_t,
long int *, long int *,
@ -83,7 +77,7 @@ internal_getgrouplist (const char *user, gid_t group, long int *size,
&__nss_initgroups_database) < 0)
{
if (__nss_group_database == NULL)
no_more = __nss_database_lookup2 ("group", NULL, DEFAULT_CONFIG,
no_more = __nss_database_lookup2 ("group", NULL, "files",
&__nss_group_database);
__nss_initgroups_database = __nss_group_database;

View File

@ -33,8 +33,6 @@ extern enum nss_status _nss_ ## service ## _getaliasbyname_r \
DECLARE_NSS_PROTOTYPES (files)
DECLARE_NSS_PROTOTYPES (nis)
DECLARE_NSS_PROTOTYPES (nisplus)
#undef DECLARE_NSS_PROTOTYPES
# endif /* !_ISOMAC */

View File

@ -39,10 +39,11 @@ extern char **__libc_argv attribute_hidden;
__libgcc_s_init because unwinding is already in progress, so libgcc_s.so
has already been loaded if its unwinder is used (Bug 22636).
2. It allows us to provide robust fallback code at dlopen time for
incorrectly configured systems that mix old libnss_* modules with newly
installed libraries e.g. old libnss_nis.so.2 with new libnsl.so.1. Using
RTLD_LAZY here causes a failure at the time the symbol is called and at
that point it is much harder to safely return an error (Bug 22766).
incorrectly configured systems that mix old libnss_* modules
with newly installed libraries e.g. old libnss_dns.so.2 with new
libresolv.so.2. Using RTLD_LAZY here causes a failure at the
time the symbol is called and at that point it is much harder to
safely return an error (Bug 22766).
The use of RTLD_NOW also impacts gconv module loading, backtracing
(where the unwinder form libgcc_s.so is used), and IDNA functions

View File

@ -56,8 +56,6 @@ extern enum nss_status _nss_ ## service ##_initgroups_dyn \
DECLARE_NSS_PROTOTYPES (compat)
DECLARE_NSS_PROTOTYPES (files)
DECLARE_NSS_PROTOTYPES (hesiod)
DECLARE_NSS_PROTOTYPES (nis)
DECLARE_NSS_PROTOTYPES (nisplus)
#undef DECLARE_NSS_PROTOTYPES
#endif

View File

@ -833,13 +833,7 @@ for linking")
# define libnsl_hidden_proto(name, attrs...) hidden_proto (name, ##attrs)
# define libnsl_hidden_tls_proto(name, attrs...) \
hidden_tls_proto (name, ##attrs)
# ifdef LINK_OBSOLETE_NSL
/* libnsl_hidden_nolink should only get used in libnsl code. */
# define libnsl_hidden_nolink_def(name, version) libnsl_hidden_def (name)
# else
# define libnsl_hidden_nolink_def(name, version) hidden_nolink (name, libnsl, version)
# endif
# define libnsl_hidden_def(name) hidden_def (name)
# define libnsl_hidden_nolink_def(name, version) hidden_nolink (name, libnsl, version)
# define libnsl_hidden_weak(name) hidden_weak (name)
# define libnsl_hidden_ver(local, name) hidden_ver (local, name)
# define libnsl_hidden_data_def(name) hidden_data_def (name)
@ -849,7 +843,6 @@ for linking")
#else
# define libnsl_hidden_proto(name, attrs...)
# define libnsl_hidden_tls_proto(name, attrs...)
# define libnsl_hidden_def(name)
# define libnsl_hidden_weak(name)
# define libnsl_hidden_ver(local, name)
# define libnsl_hidden_data_def(name)
@ -858,52 +851,6 @@ for linking")
# define libnsl_hidden_data_ver(local, name)
#endif
#if IS_IN (libnss_nis)
# define libnss_nis_hidden_proto(name, attrs...) hidden_proto (name, ##attrs)
# define libnss_nis_hidden_tls_proto(name, attrs...) \
hidden_tls_proto (name, ##attrs)
# define libnss_nis_hidden_def(name) hidden_def (name)
# define libnss_nis_hidden_weak(name) hidden_weak (name)
# define libnss_nis_hidden_ver(local, name) hidden_ver (local, name)
# define libnss_nis_hidden_data_def(name) hidden_data_def (name)
# define libnss_nis_hidden_tls_def(name) hidden_tls_def (name)
# define libnss_nis_hidden_data_weak(name) hidden_data_weak (name)
# define libnss_nis_hidden_data_ver(local, name) hidden_data_ver (local, name)
#else
# define libnss_nis_hidden_proto(name, attrs...)
# define libnss_nis_hidden_tls_proto(name, attrs...)
# define libnss_nis_hidden_def(name)
# define libnss_nis_hidden_weak(name)
# define libnss_nis_hidden_ver(local, name)
# define libnss_nis_hidden_data_def(name)
# define libnss_nis_hidden_tls_def(name)
# define libnss_nis_hidden_data_weak(name)
# define libnss_nis_hidden_data_ver(local, name)
#endif
#if IS_IN (libnss_nisplus)
# define libnss_nisplus_hidden_proto(name, attrs...) hidden_proto (name, ##attrs)
# define libnss_nisplus_hidden_tls_proto(name, attrs...) \
hidden_tls_proto (name, ##attrs)
# define libnss_nisplus_hidden_def(name) hidden_def (name)
# define libnss_nisplus_hidden_weak(name) hidden_weak (name)
# define libnss_nisplus_hidden_ver(local, name) hidden_ver (local, name)
# define libnss_nisplus_hidden_data_def(name) hidden_data_def (name)
# define libnss_nisplus_hidden_tls_def(name) hidden_tls_def (name)
# define libnss_nisplus_hidden_data_weak(name) hidden_data_weak (name)
# define libnss_nisplus_hidden_data_ver(local, name) hidden_data_ver (local, name)
#else
# define libnss_nisplus_hidden_proto(name, attrs...)
# define libnss_nisplus_hidden_tls_proto(name, attrs...)
# define libnss_nisplus_hidden_def(name)
# define libnss_nisplus_hidden_weak(name)
# define libnss_nisplus_hidden_ver(local, name)
# define libnss_nisplus_hidden_data_def(name)
# define libnss_nisplus_hidden_tls_def(name)
# define libnss_nisplus_hidden_data_weak(name)
# define libnss_nisplus_hidden_data_ver(local, name)
#endif
#define libc_hidden_builtin_proto(name, attrs...) libc_hidden_proto (name, ##attrs)
#define libc_hidden_builtin_def(name) libc_hidden_def (name)
#define libc_hidden_builtin_weak(name) libc_hidden_weak (name)

View File

@ -286,15 +286,9 @@ DECLARE_NSS_PROTOTYPES (compat)
DECLARE_NSS_PROTOTYPES (dns)
DECLARE_NSS_PROTOTYPES (files)
DECLARE_NSS_PROTOTYPES (hesiod)
DECLARE_NSS_PROTOTYPES (nis)
DECLARE_NSS_PROTOTYPES (nisplus)
#undef DECLARE_NSS_PROTOTYPES
libnss_nis_hidden_proto (_nss_nis_endhostent)
libnss_nis_hidden_proto (_nss_nis_endnetent)
libnss_nis_hidden_proto (_nss_nis_endspent)
#endif
#endif /* !_NETDB_H */

View File

@ -36,8 +36,6 @@ extern enum nss_status _nss_ ## service ## _getntohost_r \
char *buffer, size_t buflen, int *errnop);
DECLARE_NSS_PROTOTYPES (files)
DECLARE_NSS_PROTOTYPES (nis)
DECLARE_NSS_PROTOTYPES (nisplus)
#undef DECLARE_NSS_PROTOTYPES

View File

@ -48,8 +48,6 @@ extern enum nss_status _nss_ ## service ##_getpwent_r \
DECLARE_NSS_PROTOTYPES (compat)
DECLARE_NSS_PROTOTYPES (files)
DECLARE_NSS_PROTOTYPES (hesiod)
DECLARE_NSS_PROTOTYPES (nis)
DECLARE_NSS_PROTOTYPES (nisplus)
#undef DECLARE_NSS_PROTOTYPES
#endif

View File

@ -13,17 +13,6 @@ libc_hidden_proto (key_gendes)
struct key_netstarg;
extern int key_setnet (struct key_netstarg *arg);
#define DECLARE_NSS_PROTOTYPES(service) \
extern enum nss_status _nss_ ##service ## _netname2user \
(char netname[MAXNETNAMELEN + 1], uid_t *uidp, \
gid_t *gidp, int *gidlenp, gid_t *gidlist, \
int *errnop);
DECLARE_NSS_PROTOTYPES (nis)
DECLARE_NSS_PROTOTYPES (nisplus)
#undef DECLARE_NSS_PROTOTYPES
libc_hidden_proto (key_encryptsession_pk)
libc_hidden_proto (key_decryptsession_pk)

View File

@ -17,19 +17,6 @@ extern enum auth_stat _svcauth_des (struct svc_req *rqst,
struct rpc_msg *msg);
#define DECLARE_NSS_PROTOTYPES(service) \
extern enum nss_status _nss_ ## service ## _getpublickey \
(const char *netname, char *pkey, int *errnop); \
extern enum nss_status _nss_ ## service ## _getsecretkey \
(const char *netname, char *skey, char *passwd, \
int *errnop);
DECLARE_NSS_PROTOTYPES (files)
DECLARE_NSS_PROTOTYPES (nis)
DECLARE_NSS_PROTOTYPES (nisplus)
#undef DECLARE_NSS_PROTOTYPES
libc_hidden_proto (authdes_getucred)
libc_hidden_proto (xdr_authdes_cred)
libc_hidden_proto (xdr_authdes_verf)

View File

@ -45,8 +45,6 @@ extern enum nss_status _nss_ ## service ## _getrpcbynumber_r \
DECLARE_NSS_PROTOTYPES (files)
DECLARE_NSS_PROTOTYPES (nis)
DECLARE_NSS_PROTOTYPES (nisplus)
#undef DECLARE_NSS_PROTOTYPES

View File

@ -1 +0,0 @@
#include <nis/rpcsvc/yp_prot.h>

View File

@ -44,8 +44,6 @@ extern enum nss_status _nss_ ## service ## _getspnam_r \
DECLARE_NSS_PROTOTYPES (compat)
DECLARE_NSS_PROTOTYPES (files)
DECLARE_NSS_PROTOTYPES (hesiod)
DECLARE_NSS_PROTOTYPES (nis)
DECLARE_NSS_PROTOTYPES (nisplus)
#undef DECLARE_NSS_PROTOTYPES

View File

@ -257,16 +257,6 @@ This frontend allows users to specify tunables as a colon-separated list in a
single environment variable @env{GLIBC_TUNABLES}.
@end table
@item --enable-obsolete-nsl
By default, libnsl is only built as shared library for backward
compatibility and the NSS modules libnss_compat, libnss_nis and
libnss_nisplus are not built at all.
Use this option to enable libnsl with all depending NSS modules and
header files.
For architectures and ABIs that have been added after version 2.28 of
@theglibc{} this option is not available, and the libnsl compatibility
library is not built.
@item --disable-crypt
Do not install the passphrase-hashing library @file{libcrypt} or the
header file @file{crypt.h}. @file{unistd.h} will still declare the

View File

@ -328,17 +328,12 @@ For the @code{hosts} and @code{networks} databases the default value is
the DNS service not to be available but if it is available the answer it
returns is definitive.
The @code{passwd}, @code{group}, and @code{shadow} databases are
The @code{passwd}, @code{group}, and @code{shadow} databases was
traditionally handled in a special way. The appropriate files in the
@file{/etc} directory are read but if an entry with a name starting
with a @code{+} character is found NIS is used. This kind of lookup
remains possible if @theglibc{} was configured with the
@code{--enable-obsolete-nsl} option and the special lookup service
@code{compat} is used. If @theglibc{} was configured with the
@code{--enable-obsolete-nsl} option the default value for the three
databases above is @code{compat [NOTFOUND=return] files}. If the
@code{--enable-obsolete-nsl} option was not used the default value
for the services is @code{files}.
@file{/etc} directory were read but if an entry with a name starting
with a @code{+} character was found NIS was used. This kind of lookup
was removed and now the default value for the services is @code{files}.
libnss_compat no longer depends on libnsl and can be used without NIS.
For all other databases the default value is @code{files} unless
@theglibc{} was configured with @code{--enable-obsolete-rpc} option, in

View File

@ -3,14 +3,14 @@
# Name Service Switch configuration file.
#
passwd: db files nis
passwd: db files
shadow: files
group: db files nis
group: db files
hosts: files nisplus nis dns
networks: nisplus [NOTFOUND=return] files
hosts: files dns
networks: files
ethers: nisplus [NOTFOUND=return] db files
protocols: nisplus [NOTFOUND=return] db files
rpc: nisplus [NOTFOUND=return] db files
services: nisplus [NOTFOUND=return] db files
ethers: db files
protocols: db files
rpc: db files
services: db files

View File

@ -22,40 +22,13 @@ subdir := nis
include ../Makeconfig
ifndef have-GLIBC_2.28
ifeq ($(build-obsolete-nsl),yes)
$(error --enabe-obsolete-nsl is not available)
endif
else
ifeq ($(build-obsolete-nsl),yes)
headers := $(wildcard rpcsvc/*.[hx])
# These are the databases available for the nis (and perhaps later nisplus)
# service. This must be a superset of the services in nss.
databases = proto service hosts network grp pwd rpc ethers \
spwd netgrp alias
# Specify rules for the nss_* modules.
services := nis nisplus
endif
ifdef have-GLIBC_2.28
extra-libs = libnsl
ifeq ($(build-obsolete-nsl),yes)
extra-libs += $(services:%=libnss_%)
endif
# These libraries will be built in the `others' pass rather than
# the `lib' pass, because they depend on libc.so being built already.
extra-libs-others = $(extra-libs)
ifeq ($(build-obsolete-nsl),yes)
# The sources are found in the appropriate subdir.
subdir-dirs = $(services:%=nss_%)
vpath %.c $(subdir-dirs)
endif
libnsl-routines = yp_xdr ypclnt ypupdate_xdr \
nis_subr nis_local_names nis_free nis_file \
nis_print nis_error nis_call nis_lookup\
@ -68,17 +41,6 @@ libnsl-routines = yp_xdr ypclnt ypupdate_xdr \
nis_findserv nis_callback nis_clone_dir nis_clone_obj\
nis_clone_res
ifeq ($(build-obsolete-nsl),yes)
libnsl-routines += nss-default
libnss_nis-routines := $(addprefix nis-,$(databases)) nis-initgroups \
nss-nis
libnss_nis-inhibit-o = $(filter-out .os,$(object-suffixes))
libnss_nisplus-routines := $(addprefix nisplus-,$(databases)) nisplus-parser \
nss-nisplus nisplus-initgroups
libnss_nisplus-inhibit-o = $(filter-out .os,$(object-suffixes))
else # not $(build-obsolete-nsl)
# Pretend that libnsl.so is a linker script, so that the symbolic link
# is not installed.
install-lib-ldscripts = libnsl.so
@ -86,31 +48,18 @@ $(inst_libdir)/libnsl.so:
# Build only shared libnsl.
libnsl-inhibit-o = $(filter-out .os,$(object-suffixes))
endif # not $(build-obsolete-nsl)
endif # have-GLIBC_2.28
include ../Rules
ifeq ($(build-obsolete-nsl),yes)
$(objpfx)libnss_nis.so: $(objpfx)libnsl.so$(libnsl.so-version) \
$(common-objpfx)nss/libnss_files.so
$(objpfx)libnss_nisplus.so: $(objpfx)libnsl.so$(libnsl.so-version)
endif
libnsl-libc = $(common-objpfx)linkobj/libc.so
# Target-specific variable setting to link objects using deprecated
# RPC interfaces with the version of libc.so that makes them available
# for new links:
$(services:%=$(objpfx)libnss_%.so) $(objpfx)libnsl.so: \
libc-for-link = $(libnsl-libc)
$(objpfx)libnsl.so: libc-for-link = $(libnsl-libc)
ifeq ($(build-shared),yes)
$(others:%=$(objpfx)%): $(objpfx)libnsl.so$(libnsl.so-version)
else
ifeq ($(build-obsolete-nsl),yes)
$(others:%=$(objpfx)%): $(objpfx)libnsl.a
endif
endif

View File

@ -58,63 +58,7 @@ libnsl {
xdr_ypall;
}
GLIBC_PRIVATE {
_nsl_default_nss; __prepare_niscall; __follow_path; __do_niscall3;
__prepare_niscall; __follow_path; __do_niscall3;
__create_ib_request; _xdr_ib_request; _xdr_nis_result;
}
}
libnss_nis {
GLIBC_PRIVATE {
_nss_nis_endaliasent; _nss_nis_endetherent; _nss_nis_endgrent;
_nss_nis_endhostent; _nss_nis_endnetent; _nss_nis_endnetgrent;
_nss_nis_endprotoent; _nss_nis_endpwent; _nss_nis_endrpcent;
_nss_nis_endservent; _nss_nis_endspent; _nss_nis_getaliasbyname_r;
_nss_nis_getaliasent_r; _nss_nis_getetherent_r; _nss_nis_getgrent_r;
_nss_nis_getgrgid_r; _nss_nis_getgrnam_r; _nss_nis_gethostbyaddr_r;
_nss_nis_gethostbyname2_r; _nss_nis_gethostbyname_r; _nss_nis_gethostent_r;
_nss_nis_gethostton_r; _nss_nis_getnetbyaddr_r; _nss_nis_getnetbyname_r;
_nss_nis_getnetent_r; _nss_nis_getnetgrent_r; _nss_nis_getntohost_r;
_nss_nis_getprotobyname_r; _nss_nis_getprotobynumber_r;
_nss_nis_getprotoent_r; _nss_nis_getpublickey; _nss_nis_getpwent_r;
_nss_nis_getpwnam_r; _nss_nis_getpwuid_r; _nss_nis_getrpcbyname_r;
_nss_nis_getrpcbynumber_r; _nss_nis_getrpcent_r; _nss_nis_getsecretkey;
_nss_nis_getservbyname_r; _nss_nis_getservbyport_r; _nss_nis_getservent_r;
_nss_nis_getspent_r; _nss_nis_getspnam_r;
_nss_nis_netname2user; _nss_nis_setaliasent; _nss_nis_setetherent;
_nss_nis_setgrent; _nss_nis_sethostent; _nss_nis_setnetent;
_nss_nis_setnetgrent; _nss_nis_setprotoent; _nss_nis_setpwent;
_nss_nis_setrpcent; _nss_nis_setservent; _nss_nis_setspent;
_nss_nis_initgroups_dyn; _nss_nis_gethostbyname4_r;
}
}
libnss_nisplus {
GLIBC_PRIVATE {
_nss_nisplus_endaliasent; _nss_nisplus_endetherent; _nss_nisplus_endgrent;
_nss_nisplus_endhostent; _nss_nisplus_endnetent; _nss_nisplus_endnetgrent;
_nss_nisplus_endprotoent; _nss_nisplus_endpwent; _nss_nisplus_endrpcent;
_nss_nisplus_endservent; _nss_nisplus_endspent;
_nss_nisplus_getaliasbyname_r; _nss_nisplus_getaliasent_r;
_nss_nisplus_getetherent_r; _nss_nisplus_getgrent_r;
_nss_nisplus_getgrgid_r; _nss_nisplus_getgrnam_r;
_nss_nisplus_gethostbyaddr_r; _nss_nisplus_gethostbyname2_r;
_nss_nisplus_gethostbyname_r; _nss_nisplus_gethostent_r;
_nss_nisplus_gethostton_r; _nss_nisplus_getnetbyaddr_r;
_nss_nisplus_getnetbyname_r; _nss_nisplus_getnetent_r;
_nss_nisplus_getnetgrent_r; _nss_nisplus_getntohost_r;
_nss_nisplus_getprotobyname_r; _nss_nisplus_getprotobynumber_r;
_nss_nisplus_getprotoent_r; _nss_nisplus_getpublickey;
_nss_nisplus_getpwent_r; _nss_nisplus_getpwnam_r; _nss_nisplus_getpwuid_r;
_nss_nisplus_getrpcbyname_r; _nss_nisplus_getrpcbynumber_r;
_nss_nisplus_getrpcent_r; _nss_nisplus_getsecretkey;
_nss_nisplus_getservbyname_r; _nss_nisplus_getservbynumber_r;
_nss_nisplus_getservent_r; _nss_nisplus_getspent_r;
_nss_nisplus_getspnam_r; _nss_nisplus_netname2user;
_nss_nisplus_setaliasent;
_nss_nisplus_setetherent; _nss_nisplus_setgrent; _nss_nisplus_sethostent;
_nss_nisplus_setnetent; _nss_nisplus_setnetgrent; _nss_nisplus_setprotoent;
_nss_nisplus_setpwent; _nss_nisplus_setrpcent; _nss_nisplus_setservent;
_nss_nisplus_setspent; _nss_nisplus_initgroups_dyn;
_nss_nisplus_gethostbyname4_r;
}
}

View File

@ -23,9 +23,6 @@
#define NSS_FLAG_ADJUNCT_AS_SHADOW 8
/* Get current set of default flags. */
extern int _nsl_default_nss (void);
/* Set up everything for a call to __do_niscall3. */
extern nis_error __prepare_niscall (const_nis_name name, directory_obj **dirp,
dir_binding *bptrp, unsigned int flags);

View File

@ -1,35 +0,0 @@
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
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/>. */
#ifndef __NISPLUS_PARSER_H
#define __NISPLUS_PARSER_H 1
#include <pwd.h>
#include <grp.h>
#include <shadow.h>
extern int _nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
char *buffer, size_t buflen, int *errnop);
extern int _nss_nisplus_parse_grent (nis_result *result, struct group *gr,
char *buffer, size_t buflen, int *errnop);
extern int _nss_nisplus_parse_spent (nis_result *result, struct spwd *sp,
char *buffer, size_t buflen, int *errnop);
#endif

View File

@ -1,127 +0,0 @@
/* Copyright (C) 1996-2020 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 <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <stdlib.h>
#include <string.h>
#include <libc-lock.h>
#include <libnsl.h>
/* Path of the file. */
static const char default_nss[] = "/etc/default/nss";
/* Flags once read from the file. */
static int default_nss_flags;
/* Code to make sure we call 'init' once. */
__libc_once_define (static, once);
/* Table of the recognized variables. */
static const struct
{
char name[23];
unsigned int len;
int flag;
} vars[] =
{
#define STRNLEN(s) s, sizeof (s) - 1
{ STRNLEN ("NETID_AUTHORITATIVE"), NSS_FLAG_NETID_AUTHORITATIVE },
{ STRNLEN ("SERVICES_AUTHORITATIVE"), NSS_FLAG_SERVICES_AUTHORITATIVE },
{ STRNLEN ("SETENT_BATCH_READ"), NSS_FLAG_SETENT_BATCH_READ },
{ STRNLEN ("ADJUNCT_AS_SHADOW"), NSS_FLAG_ADJUNCT_AS_SHADOW },
};
#define nvars (sizeof (vars) / sizeof (vars[0]))
static void
init (void)
{
int saved_errno = errno;
FILE *fp = fopen (default_nss, "rce");
if (fp != NULL)
{
char *line = NULL;
size_t linelen = 0;
__fsetlocking (fp, FSETLOCKING_BYCALLER);
while (!feof_unlocked (fp))
{
ssize_t n = getline (&line, &linelen, fp);
if (n <= 0)
break;
/* Recognize only
<THE-VARIABLE> = TRUE
with arbitrary white spaces. */
char *cp = line;
while (isspace (*cp))
++cp;
/* Recognize comment lines. */
if (*cp == '#')
continue;
int idx;
for (idx = 0; idx < nvars; ++idx)
if (strncmp (cp, vars[idx].name, vars[idx].len) == 0)
break;
if (idx == nvars)
continue;
cp += vars[idx].len;
while (isspace (*cp))
++cp;
if (*cp++ != '=')
continue;
while (isspace (*cp))
++cp;
if (strncmp (cp, "TRUE", 4) != 0)
continue;
cp += 4;
while (isspace (*cp))
++cp;
if (*cp == '\0')
default_nss_flags |= vars[idx].flag;
}
free (line);
fclose (fp);
}
__set_errno (saved_errno);
}
int
_nsl_default_nss (void)
{
/* If we have not yet read the file yet do it now. */
__libc_once (once, init);
return default_nss_flags;
}

View File

@ -1,44 +0,0 @@
/* Copyright (C) 1996-2020 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-nis.h"
#include "nsswitch.h"
/* Convert YP error number to NSS error number. */
const enum nss_status __yperr2nss_tab[] =
{
[YPERR_SUCCESS] = NSS_STATUS_SUCCESS,
[YPERR_BADARGS] = NSS_STATUS_UNAVAIL,
[YPERR_RPC] = NSS_STATUS_UNAVAIL,
[YPERR_DOMAIN] = NSS_STATUS_UNAVAIL,
[YPERR_MAP] = NSS_STATUS_UNAVAIL,
[YPERR_KEY] = NSS_STATUS_NOTFOUND,
[YPERR_YPERR] = NSS_STATUS_UNAVAIL,
[YPERR_RESRC] = NSS_STATUS_TRYAGAIN,
[YPERR_NOMORE] = NSS_STATUS_NOTFOUND,
[YPERR_PMAP] = NSS_STATUS_UNAVAIL,
[YPERR_YPBIND] = NSS_STATUS_UNAVAIL,
[YPERR_YPSERV] = NSS_STATUS_UNAVAIL,
[YPERR_NODOM] = NSS_STATUS_UNAVAIL,
[YPERR_BADDB] = NSS_STATUS_UNAVAIL,
[YPERR_VERS] = NSS_STATUS_UNAVAIL,
[YPERR_ACCESS] = NSS_STATUS_UNAVAIL,
[YPERR_BUSY] = NSS_STATUS_TRYAGAIN
};
const unsigned int __yperr2nss_count = (sizeof (__yperr2nss_tab)
/ sizeof (__yperr2nss_tab[0]));

View File

@ -1,59 +0,0 @@
/* Copyright (C) 1996-2020 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/>. */
#ifndef _NIS_NSS_NIS_H
#define _NIS_NSS_NIS_H 1
#include <rpcsvc/ypclnt.h>
#include "nsswitch.h"
NSS_DECLARE_MODULE_FUNCTIONS (nis)
/* Convert YP error number to NSS error number. */
extern const enum nss_status __yperr2nss_tab[] attribute_hidden;
extern const unsigned int __yperr2nss_count attribute_hidden;
static inline enum nss_status
yperr2nss (int errval)
{
if ((unsigned int) errval >= __yperr2nss_count)
return NSS_STATUS_UNAVAIL;
return __yperr2nss_tab[(unsigned int) errval];
}
struct response_t
{
struct response_t *next;
size_t size;
char mem[0];
};
typedef struct intern_t
{
struct response_t *start;
struct response_t *next;
size_t offset;
} intern_t;
extern int _nis_saveit (int instatus, char *inkey, int inkeylen, char *inval,
int invallen, char *indata) attribute_hidden;
#endif /* nis/nss-nis.h */

View File

@ -1,78 +0,0 @@
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1997.
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 <rpcsvc/nis.h>
#include "nss-nisplus.h"
#include "nsswitch.h"
/* Convert NIS+ error number to NSS error number. */
const enum nss_status __niserr2nss_tab[] =
{
[NIS_SUCCESS] = NSS_STATUS_SUCCESS,
[NIS_S_SUCCESS] = NSS_STATUS_SUCCESS,
[NIS_NOTFOUND] = NSS_STATUS_NOTFOUND,
[NIS_S_NOTFOUND] = NSS_STATUS_NOTFOUND,
[NIS_CACHEEXPIRED] = NSS_STATUS_UNAVAIL,
[NIS_NAMEUNREACHABLE] = NSS_STATUS_UNAVAIL,
[NIS_UNKNOWNOBJ] = NSS_STATUS_NOTFOUND,
[NIS_TRYAGAIN] = NSS_STATUS_TRYAGAIN,
[NIS_SYSTEMERROR] = NSS_STATUS_UNAVAIL,
[NIS_CHAINBROKEN] = NSS_STATUS_UNAVAIL,
[NIS_PERMISSION] = NSS_STATUS_UNAVAIL,
[NIS_NOTOWNER] = NSS_STATUS_UNAVAIL,
[NIS_NOT_ME] = NSS_STATUS_UNAVAIL,
[NIS_NOMEMORY] = NSS_STATUS_TRYAGAIN,
[NIS_NAMEEXISTS] = NSS_STATUS_UNAVAIL,
[NIS_NOTMASTER] = NSS_STATUS_UNAVAIL,
[NIS_INVALIDOBJ] = NSS_STATUS_UNAVAIL,
[NIS_BADNAME] = NSS_STATUS_UNAVAIL,
[NIS_NOCALLBACK] = NSS_STATUS_UNAVAIL,
[NIS_CBRESULTS] = NSS_STATUS_UNAVAIL,
[NIS_NOSUCHNAME] = NSS_STATUS_NOTFOUND,
[NIS_NOTUNIQUE] = NSS_STATUS_UNAVAIL,
[NIS_IBMODERROR] = NSS_STATUS_UNAVAIL,
[NIS_NOSUCHTABLE] = NSS_STATUS_UNAVAIL,
[NIS_TYPEMISMATCH] = NSS_STATUS_UNAVAIL,
[NIS_LINKNAMEERROR] = NSS_STATUS_UNAVAIL,
[NIS_PARTIAL] = NSS_STATUS_NOTFOUND,
[NIS_TOOMANYATTRS] = NSS_STATUS_UNAVAIL,
[NIS_RPCERROR] = NSS_STATUS_UNAVAIL,
[NIS_BADATTRIBUTE] = NSS_STATUS_UNAVAIL,
[NIS_NOTSEARCHABLE] = NSS_STATUS_UNAVAIL,
[NIS_CBERROR] = NSS_STATUS_UNAVAIL,
[NIS_FOREIGNNS] = NSS_STATUS_UNAVAIL,
[NIS_BADOBJECT] = NSS_STATUS_UNAVAIL,
[NIS_NOTSAMEOBJ] = NSS_STATUS_UNAVAIL,
[NIS_MODFAIL] = NSS_STATUS_UNAVAIL,
[NIS_BADREQUEST] = NSS_STATUS_UNAVAIL,
[NIS_NOTEMPTY] = NSS_STATUS_UNAVAIL,
[NIS_COLDSTART_ERR] = NSS_STATUS_UNAVAIL,
[NIS_RESYNC] = NSS_STATUS_UNAVAIL,
[NIS_FAIL] = NSS_STATUS_UNAVAIL,
[NIS_UNAVAIL] = NSS_STATUS_UNAVAIL,
[NIS_RES2BIG] = NSS_STATUS_UNAVAIL,
[NIS_SRVAUTH] = NSS_STATUS_UNAVAIL,
[NIS_CLNTAUTH] = NSS_STATUS_UNAVAIL,
[NIS_NOFILESPACE] = NSS_STATUS_UNAVAIL,
[NIS_NOPROC] = NSS_STATUS_UNAVAIL,
[NIS_DUMPLATER] = NSS_STATUS_UNAVAIL
};
const unsigned int __niserr2nss_count = (sizeof (__niserr2nss_tab)
/ sizeof (__niserr2nss_tab[0]));

View File

@ -1,41 +0,0 @@
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1997.
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/>. */
#ifndef _NIS_NSS_NISPLUS_H
#define _NIS_NSS_NISPLUS_H 1
#include <rpcsvc/nis.h>
#include "nsswitch.h"
NSS_DECLARE_MODULE_FUNCTIONS (nisplus)
/* Convert NIS+ error number to NSS error number. */
extern const enum nss_status __niserr2nss_tab[] attribute_hidden;
extern const unsigned int __niserr2nss_count attribute_hidden;
static enum nss_status
__attribute__ ((unused))
niserr2nss (int errval)
{
if ((unsigned int) errval >= __niserr2nss_count)
return NSS_STATUS_UNAVAIL;
return __niserr2nss_tab[(unsigned int) errval];
}
#endif /* nis/nss-nisplus.h */

View File

@ -1,281 +0,0 @@
/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
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.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <aliases.h>
#include <libc-lock.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
#include "nss-nis.h"
__libc_lock_define_initialized (static, lock)
static bool_t new_start = 1;
static char *oldkey;
static int oldkeylen;
static int
_nss_nis_parse_aliasent (const char *key, char *alias, struct aliasent *result,
char *buffer, size_t buflen, int *errnop)
{
char *first_unused = buffer + strlen (alias) + 1;
size_t room_left =
buflen - (buflen % __alignof__ (char *)) - strlen (alias) - 2;
char *line;
char *cp;
result->alias_members_len = 0;
*first_unused = '\0';
first_unused++;
strcpy (first_unused, key);
if (first_unused[room_left - 1] != '\0')
{
/* The line is too long for our buffer. */
no_more_room:
*errnop = ERANGE;
return -1;
}
result->alias_name = first_unused;
/* Terminate the line for any case. */
cp = strpbrk (alias, "#\n");
if (cp != NULL)
*cp = '\0';
first_unused += strlen (result->alias_name) + 1;
/* Adjust the pointer so it is aligned for
storing pointers. */
first_unused += __alignof__ (char *) - 1;
first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *));
result->alias_members = (char **) first_unused;
line = alias;
while (*line != '\0')
{
/* Skip leading blanks. */
while (isspace (*line))
line++;
if (*line == '\0')
break;
if (room_left < sizeof (char *))
goto no_more_room;
room_left -= sizeof (char *);
result->alias_members[result->alias_members_len] = line;
while (*line != '\0' && *line != ',')
line++;
if (line != result->alias_members[result->alias_members_len])
{
*line = '\0';
line++;
result->alias_members_len++;
}
}
return result->alias_members_len == 0 ? 0 : 1;
}
enum nss_status
_nss_nis_setaliasent (void)
{
__libc_lock_lock (lock);
new_start = 1;
if (oldkey != NULL)
{
free (oldkey);
oldkey = NULL;
oldkeylen = 0;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
/* The 'endaliasent' function is identical. */
strong_alias (_nss_nis_setaliasent, _nss_nis_endaliasent)
static enum nss_status
internal_nis_getaliasent_r (struct aliasent *alias, char *buffer,
size_t buflen, int *errnop)
{
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
alias->alias_local = 0;
/* Get the next entry until we found a correct one. */
int parse_res;
do
{
char *result;
int len;
char *outkey;
int keylen;
int yperr;
if (new_start)
yperr = yp_first (domain, "mail.aliases", &outkey, &keylen, &result,
&len);
else
yperr = yp_next (domain, "mail.aliases", oldkey, oldkeylen, &outkey,
&keylen, &result, &len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
*errnop = errno;
return retval;
}
if (__glibc_unlikely ((size_t) (len + 1) > buflen))
{
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (buffer, result, len);
buffer[len] = '\0';
while (isspace (*p))
++p;
free (result);
parse_res = _nss_nis_parse_aliasent (outkey, p, alias, buffer,
buflen, errnop);
if (__glibc_unlikely (parse_res == -1))
{
free (outkey);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
free (oldkey);
oldkey = outkey;
oldkeylen = keylen;
new_start = 0;
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nis_getaliasent_r (struct aliasent *alias, char *buffer, size_t buflen,
int *errnop)
{
enum nss_status status;
__libc_lock_lock (lock);
status = internal_nis_getaliasent_r (alias, buffer, buflen, errnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nis_getaliasbyname_r (const char *name, struct aliasent *alias,
char *buffer, size_t buflen, int *errnop)
{
if (name == NULL)
{
*errnop = EINVAL;
return NSS_STATUS_UNAVAIL;
}
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
size_t namlen = strlen (name);
char *name2;
int use_alloca = __libc_use_alloca (namlen + 1);
if (use_alloca)
name2 = __alloca (namlen + 1);
else
{
name2 = malloc (namlen + 1);
if (name2 == NULL)
{
*errnop = ENOMEM;
return NSS_STATUS_TRYAGAIN;
}
}
/* Convert name to lowercase. */
size_t i;
for (i = 0; i < namlen; ++i)
name2[i] = _tolower (name[i]);
name2[i] = '\0';
char *result;
int len;
int yperr = yp_match (domain, "mail.aliases", name2, namlen, &result, &len);
if (!use_alloca)
free (name2);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
*errnop = errno;
return retval;
}
if (__glibc_unlikely ((size_t) (len + 1) > buflen))
{
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (buffer, result, len);
buffer[len] = '\0';
while (isspace (*p))
++p;
free (result);
alias->alias_local = 0;
int parse_res = _nss_nis_parse_aliasent (name, p, alias, buffer, buflen,
errnop);
if (__glibc_unlikely (parse_res < 1))
{
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
return NSS_STATUS_SUCCESS;
}

View File

@ -1,292 +0,0 @@
/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
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.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <libc-lock.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
#include <netinet/ether.h>
#include <netinet/if_ether.h>
#include "nss-nis.h"
/* Protect global state against multiple changers */
__libc_lock_define_initialized (static, lock)
/* Get the declaration of the parser function. */
#define ENTNAME etherent
#define STRUCTURE etherent
#define EXTERN_PARSER
#include <nss/nss_files/files-parse.c>
struct response
{
struct response *next;
char val[0];
};
static struct response *start;
static struct response *next;
static int
saveit (int instatus, char *inkey, int inkeylen, char *inval,
int invallen, char *indata)
{
if (instatus != YP_TRUE)
return 1;
if (inkey && inkeylen > 0 && inval && invallen > 0)
{
struct response *newp = malloc (sizeof (struct response) + invallen + 1);
if (newp == NULL)
return 1; /* We have no error code for out of memory */
if (start == NULL)
start = newp;
else
next->next = newp;
next = newp;
newp->next = NULL;
*((char *) mempcpy (newp->val, inval, invallen)) = '\0';
}
return 0;
}
static void
internal_nis_endetherent (void)
{
while (start != NULL)
{
next = start;
start = start->next;
free (next);
}
}
enum nss_status
_nss_nis_endetherent (void)
{
__libc_lock_lock (lock);
internal_nis_endetherent ();
next = NULL;
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nis_setetherent (void)
{
char *domainname;
struct ypall_callback ypcb;
enum nss_status status;
yp_get_default_domain (&domainname);
internal_nis_endetherent ();
ypcb.foreach = saveit;
ypcb.data = NULL;
status = yperr2nss (yp_all (domainname, "ethers.byname", &ypcb));
next = start;
return status;
}
enum nss_status
_nss_nis_setetherent (int stayopen)
{
enum nss_status result;
__libc_lock_lock (lock);
result = internal_nis_setetherent ();
__libc_lock_unlock (lock);
return result;
}
static enum nss_status
internal_nis_getetherent_r (struct etherent *eth, char *buffer, size_t buflen,
int *errnop)
{
struct parser_data *data = (void *) buffer;
int parse_res;
if (start == NULL)
internal_nis_setetherent ();
/* Get the next entry until we found a correct one. */
do
{
char *p;
if (next == NULL)
return NSS_STATUS_NOTFOUND;
p = strncpy (buffer, next->val, buflen);
while (isspace (*p))
++p;
parse_res = _nss_files_parse_etherent (p, eth, data, buflen, errnop);
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
next = next->next;
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nis_getetherent_r (struct etherent *result, char *buffer, size_t buflen,
int *errnop)
{
int status;
__libc_lock_lock (lock);
status = internal_nis_getetherent_r (result, buffer, buflen, errnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nis_gethostton_r (const char *name, struct etherent *eth,
char *buffer, size_t buflen, int *errnop)
{
if (name == NULL)
{
*errnop = EINVAL;
return NSS_STATUS_UNAVAIL;
}
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
char *result;
int len;
int yperr = yp_match (domain, "ethers.byname", name, strlen (name), &result,
&len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
*errnop = errno;
return retval;
}
if (__glibc_unlikely ((size_t) (len + 1) > buflen))
{
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (buffer, result, len);
buffer[len] = '\0';
while (isspace (*p))
++p;
free (result);
int parse_res = _nss_files_parse_etherent (p, eth, (void *) buffer, buflen,
errnop);
if (__glibc_unlikely (parse_res < 1))
{
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nis_getntohost_r (const struct ether_addr *addr, struct etherent *eth,
char *buffer, size_t buflen, int *errnop)
{
if (addr == NULL)
{
*errnop = EINVAL;
return NSS_STATUS_UNAVAIL;
}
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
char buf[33];
int nlen = snprintf (buf, sizeof (buf), "%x:%x:%x:%x:%x:%x",
(int) addr->ether_addr_octet[0],
(int) addr->ether_addr_octet[1],
(int) addr->ether_addr_octet[2],
(int) addr->ether_addr_octet[3],
(int) addr->ether_addr_octet[4],
(int) addr->ether_addr_octet[5]);
char *result;
int len;
int yperr = yp_match (domain, "ethers.byaddr", buf, nlen, &result, &len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
*errnop = errno;
return retval;
}
if (__glibc_unlikely ((size_t) (len + 1) > buflen))
{
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (buffer, result, len);
buffer[len] = '\0';
while (isspace (*p))
++p;
free (result);
int parse_res = _nss_files_parse_etherent (p, eth, (void *) buffer, buflen,
errnop);
if (__glibc_unlikely (parse_res < 1))
{
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
return NSS_STATUS_SUCCESS;
}

View File

@ -1,359 +0,0 @@
/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
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 <ctype.h>
#include <errno.h>
#include <grp.h>
#include <nss.h>
#include <string.h>
#include <libc-lock.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
#include "nss-nis.h"
#include <libnsl.h>
/* Get the declaration of the parser function. */
#define ENTNAME grent
#define STRUCTURE group
#define EXTERN_PARSER
#include <nss/nss_files/files-parse.c>
/* Protect global state against multiple changers */
__libc_lock_define_initialized (static, lock)
static bool_t new_start = 1;
static char *oldkey;
static int oldkeylen;
static intern_t intern;
static void
internal_nis_endgrent (void)
{
new_start = 1;
if (oldkey != NULL)
{
free (oldkey);
oldkey = NULL;
oldkeylen = 0;
}
struct response_t *curr = intern.start;
while (curr != NULL)
{
struct response_t *last = curr;
curr = curr->next;
free (last);
}
intern.next = intern.start = NULL;
}
enum nss_status
_nss_nis_endgrent (void)
{
__libc_lock_lock (lock);
internal_nis_endgrent ();
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
enum nss_status
internal_nis_setgrent (void)
{
/* We have to read all the data now. */
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
struct ypall_callback ypcb;
ypcb.foreach = _nis_saveit;
ypcb.data = (char *) &intern;
enum nss_status status = yperr2nss (yp_all (domain, "group.byname", &ypcb));
/* Mark the last buffer as full. */
if (intern.next != NULL)
intern.next->size = intern.offset;
intern.next = intern.start;
intern.offset = 0;
return status;
}
enum nss_status
_nss_nis_setgrent (int stayopen)
{
enum nss_status result = NSS_STATUS_SUCCESS;
__libc_lock_lock (lock);
internal_nis_endgrent ();
if (_nsl_default_nss () & NSS_FLAG_SETENT_BATCH_READ)
result = internal_nis_setgrent ();
__libc_lock_unlock (lock);
return result;
}
static enum nss_status
internal_nis_getgrent_r (struct group *grp, char *buffer, size_t buflen,
int *errnop)
{
/* If we read the entire database at setpwent time we just iterate
over the data we have in memory. */
bool batch_read = intern.start != NULL;
char *domain = NULL;
if (!batch_read && __builtin_expect (yp_get_default_domain (&domain), 0))
return NSS_STATUS_UNAVAIL;
/* Get the next entry until we found a correct one. */
int parse_res;
do
{
char *result;
char *outkey;
int len;
int keylen;
if (batch_read)
{
struct response_t *bucket;
handle_batch_read:
bucket = intern.next;
if (__glibc_unlikely (intern.offset >= bucket->size))
{
if (bucket->next == NULL)
return NSS_STATUS_NOTFOUND;
/* We look at all the content in the current bucket. Go on
to the next. */
bucket = intern.next = bucket->next;
intern.offset = 0;
}
for (result = &bucket->mem[intern.offset]; isspace (*result);
++result)
++intern.offset;
len = strlen (result);
}
else
{
int yperr;
if (new_start)
{
/* Maybe we should read the database in one piece. */
if ((_nsl_default_nss () & NSS_FLAG_SETENT_BATCH_READ)
&& internal_nis_setgrent () == NSS_STATUS_SUCCESS
&& intern.start != NULL)
{
batch_read = true;
goto handle_batch_read;
}
yperr = yp_first (domain, "group.byname", &outkey, &keylen,
&result, &len);
}
else
yperr = yp_next (domain, "group.byname", oldkey, oldkeylen,
&outkey, &keylen, &result, &len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
*errnop = errno;
return retval;
}
}
if (__glibc_unlikely ((size_t) (len + 1) > buflen))
{
if (!batch_read)
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (buffer, result, len);
buffer[len] = '\0';
while (isspace (*p))
++p;
if (!batch_read)
free (result);
parse_res = _nss_files_parse_grent (p, grp, (void *) buffer, buflen,
errnop);
if (__glibc_unlikely (parse_res == -1))
{
if (!batch_read)
free (outkey);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
if (batch_read)
intern.offset += len + 1;
else
{
free (oldkey);
oldkey = outkey;
oldkeylen = keylen;
new_start = 0;
}
}
while (parse_res < 1);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nis_getgrent_r (struct group *result, char *buffer, size_t buflen,
int *errnop)
{
int status;
__libc_lock_lock (lock);
status = internal_nis_getgrent_r (result, buffer, buflen, errnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nis_getgrnam_r (const char *name, struct group *grp,
char *buffer, size_t buflen, int *errnop)
{
if (name == NULL)
{
*errnop = EINVAL;
return NSS_STATUS_UNAVAIL;
}
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
char *result;
int len;
int yperr = yp_match (domain, "group.byname", name, strlen (name), &result,
&len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
*errnop = errno;
return retval;
}
if (__glibc_unlikely ((size_t) (len + 1) > buflen))
{
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (buffer, result, len);
buffer[len] = '\0';
while (isspace (*p))
++p;
free (result);
int parse_res = _nss_files_parse_grent (p, grp, (void *) buffer, buflen,
errnop);
if (__builtin_expect (parse_res < 1, 0))
{
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nis_getgrgid_r (gid_t gid, struct group *grp,
char *buffer, size_t buflen, int *errnop)
{
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
char buf[32];
int nlen = sprintf (buf, "%lu", (unsigned long int) gid);
char *result;
int len;
int yperr = yp_match (domain, "group.bygid", buf, nlen, &result, &len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
*errnop = errno;
return retval;
}
if (__glibc_unlikely ((size_t) (len + 1) > buflen))
{
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (buffer, result, len);
buffer[len] = '\0';
while (isspace (*p))
++p;
free (result);
int parse_res = _nss_files_parse_grent (p, grp, (void *) buffer, buflen,
errnop);
if (__glibc_unlikely (parse_res < 1))
{
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
return NSS_STATUS_SUCCESS;
}

View File

@ -1,535 +0,0 @@
/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
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 <assert.h>
#include <nss.h>
#include <ctype.h>
#include <netdb.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <libc-lock.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
#include "nss-nis.h"
#define ENTNAME hostent
#define DATABASE "hosts"
#define NEED_H_ERRNO
#define EXTRA_ARGS , af
#define EXTRA_ARGS_DECL , int af
#define ENTDATA hostent_data
struct hostent_data
{
unsigned char host_addr[16]; /* IPv4 or IPv6 address. */
char *h_addr_ptrs[2]; /* Points to that and null terminator. */
};
#define TRAILING_LIST_MEMBER h_aliases
#define TRAILING_LIST_SEPARATOR_P isspace
#include <nss/nss_files/files-parse.c>
LINE_PARSER
("#",
{
char *addr;
STRING_FIELD (addr, isspace, 1);
assert (af == AF_INET || af == AF_INET6 || af == AF_UNSPEC);
/* Parse address. */
if (af != AF_INET6 && inet_pton (AF_INET, addr, entdata->host_addr) > 0)
{
result->h_addrtype = AF_INET;
result->h_length = INADDRSZ;
}
else if (af != AF_INET
&& inet_pton (AF_INET6, addr, entdata->host_addr) > 0)
{
result->h_addrtype = AF_INET6;
result->h_length = IN6ADDRSZ;
}
else
/* Illegal address: ignore line. */
return 0;
/* Store a pointer to the address in the expected form. */
entdata->h_addr_ptrs[0] = (char *) entdata->host_addr;
entdata->h_addr_ptrs[1] = NULL;
result->h_addr_list = entdata->h_addr_ptrs;
STRING_FIELD (result->h_name, isspace, 1);
})
__libc_lock_define_initialized (static, lock)
static bool_t new_start = 1;
static char *oldkey = NULL;
static int oldkeylen = 0;
enum nss_status
_nss_nis_sethostent (int stayopen)
{
return _nss_nis_endhostent ();
}
enum nss_status
_nss_nis_endhostent (void)
{
__libc_lock_lock (lock);
new_start = 1;
if (oldkey != NULL)
{
free (oldkey);
oldkey = NULL;
oldkeylen = 0;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
libnss_nis_hidden_def (_nss_nis_endhostent)
/* The calling function always need to get a lock first. */
static enum nss_status
internal_nis_gethostent_r (struct hostent *host, char *buffer,
size_t buflen, int *errnop, int *h_errnop,
int af)
{
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct parser_data);
buffer += pad;
struct parser_data *data = (void *) buffer;
if (__glibc_unlikely (buflen < sizeof *data + 1 + pad))
{
*errnop = ERANGE;
*h_errnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
buflen -= pad;
/* Get the next entry until we found a correct one. */
const size_t linebuflen = buffer + buflen - data->linebuffer;
int parse_res;
do
{
char *result;
int len;
char *outkey;
int keylen;
int yperr;
if (new_start)
yperr = yp_first (domain, "hosts.byname", &outkey, &keylen, &result,
&len);
else
yperr = yp_next (domain, "hosts.byname", oldkey, oldkeylen, &outkey,
&keylen, &result, &len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
switch (retval)
{
case NSS_STATUS_TRYAGAIN:
*errnop = errno;
*h_errnop = TRY_AGAIN;
break;
case NSS_STATUS_NOTFOUND:
*h_errnop = HOST_NOT_FOUND;
break;
default:
*h_errnop = NO_RECOVERY;
break;
}
return retval;
}
if (__glibc_unlikely ((size_t) (len + 1) > linebuflen))
{
free (result);
*h_errnop = NETDB_INTERNAL;
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (data->linebuffer, result, len);
data->linebuffer[len] = '\0';
while (isspace (*p))
++p;
free (result);
parse_res = parse_line (p, host, data, buflen, errnop, af);
if (__glibc_unlikely (parse_res == -1))
{
free (outkey);
*h_errnop = NETDB_INTERNAL;
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
free (oldkey);
oldkey = outkey;
oldkeylen = keylen;
new_start = 0;
}
while (!parse_res);
*h_errnop = NETDB_SUCCESS;
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nis_gethostent_r (struct hostent *host, char *buffer, size_t buflen,
int *errnop, int *h_errnop)
{
enum nss_status status;
__libc_lock_lock (lock);
status = internal_nis_gethostent_r (host, buffer, buflen, errnop, h_errnop,
AF_INET);
__libc_lock_unlock (lock);
return status;
}
static enum nss_status
internal_gethostbyname2_r (const char *name, int af, struct hostent *host,
char *buffer, size_t buflen, int *errnop,
int *h_errnop)
{
uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct parser_data);
buffer += pad;
struct parser_data *data = (void *) buffer;
if (name == NULL)
{
*errnop = EINVAL;
return NSS_STATUS_UNAVAIL;
}
char *domain;
if (yp_get_default_domain (&domain))
return NSS_STATUS_UNAVAIL;
if (buflen < sizeof *data + 1 + pad)
{
*h_errnop = NETDB_INTERNAL;
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
buflen -= pad;
/* Convert name to lowercase. */
size_t namlen = strlen (name);
/* Limit name length to the maximum size of an RPC packet. */
if (namlen > UDPMSGSIZE)
{
*errnop = ERANGE;
return NSS_STATUS_UNAVAIL;
}
char name2[namlen + 1];
size_t i;
for (i = 0; i < namlen; ++i)
name2[i] = tolower (name[i]);
name2[i] = '\0';
char *result;
int len;
int yperr = yp_match (domain, "hosts.byname", name2, namlen, &result, &len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
{
*h_errnop = TRY_AGAIN;
*errnop = errno;
}
if (retval == NSS_STATUS_NOTFOUND)
*h_errnop = HOST_NOT_FOUND;
return retval;
}
const size_t linebuflen = buffer + buflen - data->linebuffer;
if (__glibc_unlikely ((size_t) (len + 1) > linebuflen))
{
free (result);
*h_errnop = NETDB_INTERNAL;
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (data->linebuffer, result, len);
data->linebuffer[len] = '\0';
while (isspace (*p))
++p;
free (result);
int parse_res = parse_line (p, host, data, buflen, errnop, af);
if (__glibc_unlikely (parse_res < 1 || host->h_addrtype != af))
{
if (parse_res == -1)
{
*h_errnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
else
{
*h_errnop = HOST_NOT_FOUND;
return NSS_STATUS_NOTFOUND;
}
}
*h_errnop = NETDB_SUCCESS;
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nis_gethostbyname2_r (const char *name, int af, struct hostent *host,
char *buffer, size_t buflen, int *errnop,
int *h_errnop)
{
if (af != AF_INET && af != AF_INET6)
{
*h_errnop = HOST_NOT_FOUND;
return NSS_STATUS_NOTFOUND;
}
return internal_gethostbyname2_r (name, af, host, buffer, buflen, errnop,
h_errnop);
}
enum nss_status
_nss_nis_gethostbyname_r (const char *name, struct hostent *host, char *buffer,
size_t buflen, int *errnop, int *h_errnop)
{
return internal_gethostbyname2_r (name, AF_INET, host, buffer, buflen,
errnop, h_errnop);
}
enum nss_status
_nss_nis_gethostbyaddr_r (const void *addr, socklen_t addrlen, int af,
struct hostent *host, char *buffer, size_t buflen,
int *errnop, int *h_errnop)
{
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct parser_data);
buffer += pad;
struct parser_data *data = (void *) buffer;
if (__glibc_unlikely (buflen < sizeof *data + 1 + pad))
{
*errnop = ERANGE;
*h_errnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
buflen -= pad;
char *buf = inet_ntoa (*(const struct in_addr *) addr);
char *result;
int len;
int yperr = yp_match (domain, "hosts.byaddr", buf, strlen (buf), &result,
&len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
{
*h_errnop = TRY_AGAIN;
*errnop = errno;
}
else if (retval == NSS_STATUS_NOTFOUND)
*h_errnop = HOST_NOT_FOUND;
return retval;
}
const size_t linebuflen = buffer + buflen - data->linebuffer;
if (__glibc_unlikely ((size_t) (len + 1) > linebuflen))
{
free (result);
*errnop = ERANGE;
*h_errnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (data->linebuffer, result, len);
data->linebuffer[len] = '\0';
while (isspace (*p))
++p;
free (result);
int parse_res = parse_line (p, host, data, buflen, errnop, af);
if (__glibc_unlikely (parse_res < 1))
{
if (parse_res == -1)
{
*h_errnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
else
{
*h_errnop = HOST_NOT_FOUND;
return NSS_STATUS_NOTFOUND;
}
}
*h_errnop = NETDB_SUCCESS;
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nis_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
char *buffer, size_t buflen, int *errnop,
int *herrnop, int32_t *ttlp)
{
char *domain;
if (yp_get_default_domain (&domain))
{
*herrnop = NO_DATA;
return NSS_STATUS_UNAVAIL;
}
/* Convert name to lowercase. */
size_t namlen = strlen (name);
/* Limit name length to the maximum size of an RPC packet. */
if (namlen > UDPMSGSIZE)
{
*errnop = ERANGE;
return NSS_STATUS_UNAVAIL;
}
char name2[namlen + 1];
size_t i;
for (i = 0; i < namlen; ++i)
name2[i] = tolower (name[i]);
name2[i] = '\0';
char *result;
int len;
int yperr = yp_match (domain, "hosts.byname", name2, namlen, &result, &len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
{
*herrnop = TRY_AGAIN;
*errnop = errno;
}
if (retval == NSS_STATUS_NOTFOUND)
*herrnop = HOST_NOT_FOUND;
return retval;
}
if (*pat == NULL)
{
uintptr_t pad = (-(uintptr_t) buffer
% __alignof__ (struct gaih_addrtuple));
buffer += pad;
buflen = buflen > pad ? buflen - pad : 0;
if (__glibc_unlikely (buflen < sizeof (struct gaih_addrtuple)))
{
erange:
free (result);
*errnop = ERANGE;
*herrnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
*pat = (struct gaih_addrtuple *) buffer;
buffer += sizeof (struct gaih_addrtuple);
buflen -= sizeof (struct gaih_addrtuple);
}
uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct parser_data);
buffer += pad;
struct parser_data *data = (void *) buffer;
if (__glibc_unlikely (buflen < sizeof *data + 1 + pad))
goto erange;
buflen -= pad;
struct hostent host;
int parse_res = parse_line (result, &host, data, buflen, errnop, AF_UNSPEC);
if (__glibc_unlikely (parse_res < 1))
{
if (parse_res == -1)
{
*herrnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
else
{
*herrnop = HOST_NOT_FOUND;
return NSS_STATUS_NOTFOUND;
}
}
(*pat)->next = NULL;
(*pat)->family = host.h_addrtype;
memcpy ((*pat)->addr, host.h_addr_list[0], host.h_length);
(*pat)->scopeid = 0;
assert (host.h_addr_list[1] == NULL);
/* Undo the alignment for parser_data. */
buffer -= pad;
buflen += pad;
size_t h_name_len = strlen (host.h_name) + 1;
if (h_name_len >= buflen)
goto erange;
(*pat)->name = memcpy (buffer, host.h_name, h_name_len);
free (result);
return NSS_STATUS_SUCCESS;
}

View File

@ -1,343 +0,0 @@
/* Copyright (C) 1998-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
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 <ctype.h>
#include <errno.h>
#include <grp.h>
#include <nss.h>
#include <pwd.h>
#include <string.h>
#include <unistd.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
#include <sys/param.h>
#include <scratch_buffer.h>
#include "nss-nis.h"
#include <libnsl.h>
/* Get the declaration of the parser function. */
#define ENTNAME grent
#define STRUCTURE group
#define EXTERN_PARSER
#include <nss/nss_files/files-parse.c>
static enum nss_status
internal_setgrent (char *domainname, intern_t *intern)
{
struct ypall_callback ypcb;
enum nss_status status;
ypcb.foreach = _nis_saveit;
ypcb.data = (char *) intern;
status = yperr2nss (yp_all (domainname, "group.byname", &ypcb));
/* Mark the last buffer as full. */
if (intern->next != NULL)
intern->next->size = intern->offset;
intern->next = intern->start;
intern->offset = 0;
return status;
}
static enum nss_status
internal_getgrent_r (struct group *grp, char *buffer, size_t buflen,
int *errnop, intern_t *intern)
{
if (intern->start == NULL)
return NSS_STATUS_NOTFOUND;
/* Get the next entry until we found a correct one. */
int parse_res;
do
{
struct response_t *bucket = intern->next;
if (__glibc_unlikely (intern->offset >= bucket->size))
{
if (bucket->next == NULL)
return NSS_STATUS_NOTFOUND;
/* We look at all the content in the current bucket. Go on
to the next. */
bucket = intern->next = bucket->next;
intern->offset = 0;
}
char *p;
for (p = &bucket->mem[intern->offset]; isspace (*p); ++p)
++intern->offset;
size_t len = strlen (p) + 1;
if (__glibc_unlikely (len > buflen))
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
/* We unfortunately have to copy the data in the user-provided
buffer because that buffer might be around for a very long
time and the servent structure must remain valid. If we would
rely on the BUCKET memory the next 'setservent' or 'endservent'
call would destroy it.
The important thing is that it is a single NUL-terminated
string. This is what the parsing routine expects. */
p = memcpy (buffer, &bucket->mem[intern->offset], len);
parse_res = _nss_files_parse_grent (p, grp, (void *) buffer, buflen,
errnop);
if (__glibc_unlikely (parse_res == -1))
return NSS_STATUS_TRYAGAIN;
intern->offset += len;
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
static int
get_uid (const char *user, uid_t *uidp)
{
struct scratch_buffer tmpbuf;
scratch_buffer_init (&tmpbuf);
while (1)
{
struct passwd result;
struct passwd *resp;
int r = getpwnam_r (user, &result, tmpbuf.data, tmpbuf.length, &resp);
if (r == 0 && resp != NULL)
{
*uidp = resp->pw_uid;
scratch_buffer_free (&tmpbuf);
return 0;
}
if (r != ERANGE)
break;
if (!scratch_buffer_grow (&tmpbuf))
return 1;
}
scratch_buffer_free (&tmpbuf);
return 1;
}
static enum nss_status
initgroups_netid (uid_t uid, gid_t group, long int *start, long int *size,
gid_t **groupsp, long int limit, int *errnop,
const char *domainname)
{
/* Limit domainname length to the maximum size of an RPC packet. */
if (strlen (domainname) > UDPMSGSIZE)
{
*errnop = ERANGE;
return NSS_STATUS_UNAVAIL;
}
/* Prepare the key. The form is "unix.UID@DOMAIN" with the UID and
DOMAIN field filled in appropriately. */
char key[sizeof ("unix.@") + sizeof (uid_t) * 3 + strlen (domainname)];
ssize_t keylen = snprintf (key, sizeof (key), "unix.%lu@%s",
(unsigned long int) uid, domainname);
char *result;
int reslen;
int yperr = yp_match (domainname, "netid.byname", key, keylen, &result,
&reslen);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
return yperr2nss (yperr);
/* Parse the result: following the colon is a comma separated list of
group IDs. */
char *cp = strchr (result, ':');
if (cp == NULL)
{
errout:
free (result);
return NSS_STATUS_NOTFOUND;
}
/* Skip the colon. */
++cp;
gid_t *groups = *groupsp;
while (*cp != '\0')
{
char *endp;
unsigned long int gid = strtoul (cp, &endp, 0);
if (cp == endp)
goto errout;
if (*endp == ',')
++endp;
else if (*endp != '\0')
goto errout;
cp = endp;
if (gid == group)
/* We do not need this group again. */
continue;
/* Insert this group. */
if (*start == *size)
{
/* Need a bigger buffer. */
long int newsize;
if (limit > 0 && *size == limit)
/* We reached the maximum. */
break;
if (limit <= 0)
newsize = 2 * *size;
else
newsize = MIN (limit, 2 * *size);
gid_t *newgroups = realloc (groups, newsize * sizeof (*groups));
if (newgroups == NULL)
goto errout;
*groupsp = groups = newgroups;
*size = newsize;
}
groups[*start] = gid;
*start += 1;
}
free (result);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nis_initgroups_dyn (const char *user, gid_t group, long int *start,
long int *size, gid_t **groupsp, long int limit,
int *errnop)
{
/* We always need the domain name. */
char *domainname;
if (yp_get_default_domain (&domainname))
return NSS_STATUS_UNAVAIL;
/* Check whether we are supposed to use the netid.byname map. */
if (_nsl_default_nss () & NSS_FLAG_NETID_AUTHORITATIVE)
{
/* We need the user ID. */
uid_t uid;
if (get_uid (user, &uid) == 0
&& initgroups_netid (uid, group, start, size, groupsp, limit,
errnop, domainname) == NSS_STATUS_SUCCESS)
return NSS_STATUS_SUCCESS;
}
struct group grpbuf, *g;
enum nss_status status;
intern_t intern = { NULL, NULL, 0 };
gid_t *groups = *groupsp;
status = internal_setgrent (domainname, &intern);
if (status != NSS_STATUS_SUCCESS)
return status;
struct scratch_buffer tmpbuf;
scratch_buffer_init (&tmpbuf);
while (1)
{
while ((status =
internal_getgrent_r (&grpbuf, tmpbuf.data, tmpbuf.length, errnop,
&intern)) == NSS_STATUS_TRYAGAIN
&& *errnop == ERANGE)
if (!scratch_buffer_grow (&tmpbuf))
{
status = NSS_STATUS_TRYAGAIN;
goto done;
}
if (status != NSS_STATUS_SUCCESS)
{
if (status == NSS_STATUS_NOTFOUND)
status = NSS_STATUS_SUCCESS;
goto done;
}
g = &grpbuf;
if (g->gr_gid != group)
{
char **m;
for (m = g->gr_mem; *m != NULL; ++m)
if (strcmp (*m, user) == 0)
{
/* Matches user. Insert this group. */
if (*start == *size)
{
/* Need a bigger buffer. */
gid_t *newgroups;
long int newsize;
if (limit > 0 && *size == limit)
/* We reached the maximum. */
goto done;
if (limit <= 0)
newsize = 2 * *size;
else
newsize = MIN (limit, 2 * *size);
newgroups = realloc (groups, newsize * sizeof (*groups));
if (newgroups == NULL)
{
status = NSS_STATUS_TRYAGAIN;
*errnop = errno;
goto done;
}
*groupsp = groups = newgroups;
*size = newsize;
}
groups[*start] = g->gr_gid;
*start += 1;
break;
}
}
}
done:
while (intern.start != NULL)
{
intern.next = intern.start;
intern.start = intern.start->next;
free (intern.next);
}
scratch_buffer_free (&tmpbuf);
return status;
}

View File

@ -1,98 +0,0 @@
/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
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 <assert.h>
#include <ctype.h>
#include <errno.h>
#include <malloc.h>
#include <netdb.h>
#include <nss.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netgroup.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
#include "nss-nis.h"
extern enum nss_status
_nss_netgroup_parseline (char **cursor, struct __netgrent *netgrp,
char *buffer, size_t buflen, int *errnop);
static void
internal_nis_endnetgrent (struct __netgrent *netgrp)
{
free (netgrp->data);
netgrp->data = NULL;
netgrp->data_size = 0;
netgrp->cursor = NULL;
}
enum nss_status
_nss_nis_setnetgrent (const char *group, struct __netgrent *netgrp)
{
int len;
enum nss_status status;
status = NSS_STATUS_SUCCESS;
if (__glibc_unlikely (group == NULL || group[0] == '\0'))
return NSS_STATUS_UNAVAIL;
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
status = yperr2nss (yp_match (domain, "netgroup", group, strlen (group),
&netgrp->data, &len));
if (__glibc_likely (status == NSS_STATUS_SUCCESS))
{
/* Our implementation of yp_match already allocates a buffer
which is one byte larger than the value in LEN specifies
and the last byte is filled with NUL. So we can simply
use that buffer. */
assert (len >= 0);
assert (netgrp->data[len] == '\0');
netgrp->data_size = len;
netgrp->cursor = netgrp->data;
}
return status;
}
enum nss_status
_nss_nis_endnetgrent (struct __netgrent *netgrp)
{
internal_nis_endnetgrent (netgrp);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nis_getnetgrent_r (struct __netgrent *result, char *buffer, size_t buflen,
int *errnop)
{
return _nss_netgroup_parseline (&result->cursor, result, buffer, buflen,
errnop);
}

View File

@ -1,314 +0,0 @@
/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
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.h>
#include <netdb.h>
#include <ctype.h>
#include <errno.h>
#include <stdint.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <libc-lock.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
#include "nss-nis.h"
/* Get the declaration of the parser function. */
#define ENTNAME netent
#define EXTERN_PARSER
#include <nss/nss_files/files-parse.c>
__libc_lock_define_initialized (static, lock)
static bool_t new_start = 1;
static char *oldkey;
static int oldkeylen;
enum nss_status
_nss_nis_setnetent (int stayopen)
{
return _nss_nis_endnetent ();
}
enum nss_status
_nss_nis_endnetent (void)
{
__libc_lock_lock (lock);
new_start = 1;
if (oldkey != NULL)
{
free (oldkey);
oldkey = NULL;
oldkeylen = 0;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
libnss_nis_hidden_def (_nss_nis_endnetent)
static enum nss_status
internal_nis_getnetent_r (struct netent *net, char *buffer, size_t buflen,
int *errnop, int *herrnop)
{
struct parser_data *data = (void *) buffer;
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
/* Get the next entry until we found a correct one. */
int parse_res;
do
{
char *result;
char *outkey;
int len;
int keylen;
int yperr;
if (new_start)
yperr = yp_first (domain, "networks.byname", &outkey, &keylen, &result,
&len);
else
yperr = yp_next (domain, "networks.byname", oldkey, oldkeylen, &outkey,
&keylen, &result, &len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
{
*herrnop = NETDB_INTERNAL;
*errnop = errno;
}
return retval;
}
if (__glibc_unlikely ((size_t) (len + 1) > buflen))
{
free (result);
*errnop = ERANGE;
*herrnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (buffer, result, len);
buffer[len] = '\0';
while (isspace (*p))
++p;
free (result);
parse_res = _nss_files_parse_netent (p, net, data, buflen, errnop);
if (__glibc_unlikely (parse_res == -1))
{
free (outkey);
*herrnop = NETDB_INTERNAL;
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
free (oldkey);
oldkey = outkey;
oldkeylen = keylen;
new_start = 0;
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nis_getnetent_r (struct netent *net, char *buffer, size_t buflen,
int *errnop, int *herrnop)
{
enum nss_status status;
__libc_lock_lock (lock);
status = internal_nis_getnetent_r (net, buffer, buflen, errnop, herrnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nis_getnetbyname_r (const char *name, struct netent *net, char *buffer,
size_t buflen, int *errnop, int *herrnop)
{
if (name == NULL)
{
*errnop = EINVAL;
*herrnop = NETDB_INTERNAL;
return NSS_STATUS_UNAVAIL;
}
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
struct parser_data *data = (void *) buffer;
if (buflen < sizeof *data + 1)
{
*herrnop = NETDB_INTERNAL;
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
/* Convert name to lowercase. */
size_t namlen = strlen (name);
/* Limit name length to the maximum size of an RPC packet. */
if (namlen > UDPMSGSIZE)
{
*errnop = ERANGE;
return NSS_STATUS_UNAVAIL;
}
char name2[namlen + 1];
size_t i;
for (i = 0; i < namlen; ++i)
name2[i] = _tolower (name[i]);
name2[i] = '\0';
char *result;
int len;
int yperr = yp_match (domain, "networks.byname", name2, namlen, &result,
&len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
{
*errnop = errno;
*herrnop = NETDB_INTERNAL;
}
return retval;
}
if (__glibc_unlikely ((size_t) (len + 1) > buflen))
{
free (result);
*errnop = ERANGE;
*herrnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (buffer, result, len);
buffer[len] = '\0';
while (isspace (*p))
++p;
free (result);
int parse_res = _nss_files_parse_netent (p, net, data, buflen, errnop);
if (__glibc_unlikely (parse_res < 1))
{
*herrnop = NETDB_INTERNAL;
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
else
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nis_getnetbyaddr_r (uint32_t addr, int type, struct netent *net,
char *buffer, size_t buflen, int *errnop,
int *herrnop)
{
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
struct in_addr in = { .s_addr = htonl (addr) };
char *buf = inet_ntoa (in);
size_t blen = strlen (buf);
while (1)
{
char *result;
int len;
int yperr = yp_match (domain, "networks.byaddr", buf, blen, &result,
&len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_NOTFOUND)
{
if (buf[blen - 2] == '.' && buf[blen - 1] == '0')
{
/* Try again, but with trailing dot(s)
removed (one by one) */
buf[blen - 2] = '\0';
blen -= 2;
continue;
}
else
return NSS_STATUS_NOTFOUND;
}
else
{
if (retval == NSS_STATUS_TRYAGAIN)
*errnop = errno;
return retval;
}
}
if (__glibc_unlikely ((size_t) (len + 1) > buflen))
{
free (result);
*errnop = ERANGE;
*herrnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (buffer, result, len);
buffer[len] = '\0';
while (isspace (*p))
++p;
free (result);
int parse_res = _nss_files_parse_netent (p, net, (void *) buffer,
buflen, errnop);
if (__glibc_unlikely (parse_res < 1))
{
*herrnop = NETDB_INTERNAL;
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
else
return NSS_STATUS_SUCCESS;
}
}

View File

@ -1,278 +0,0 @@
/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
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.h>
#include <netdb.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <libc-lock.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
#include "nss-nis.h"
/* Get the declaration of the parser function. */
#define ENTNAME protoent
#define EXTERN_PARSER
#include <nss/nss_files/files-parse.c>
__libc_lock_define_initialized (static, lock)
struct response
{
struct response *next;
char val[0];
};
static struct response *start;
static struct response *next;
static int
saveit (int instatus, char *inkey, int inkeylen, char *inval,
int invallen, char *indata)
{
if (instatus != YP_TRUE)
return 1;
if (inkey && inkeylen > 0 && inval && invallen > 0)
{
struct response *newp = malloc (sizeof (struct response) + invallen + 1);
if (newp == NULL)
return 1; /* We have no error code for out of memory */
if (start == NULL)
start = newp;
else
next->next = newp;
next = newp;
newp->next = NULL;
*((char *) mempcpy (newp->val, inval, invallen)) = '\0';
}
return 0;
}
static void
internal_nis_endprotoent (void)
{
while (start != NULL)
{
next = start;
start = start->next;
free (next);
}
}
static enum nss_status
internal_nis_setprotoent (void)
{
char *domainname;
struct ypall_callback ypcb;
enum nss_status status;
yp_get_default_domain (&domainname);
internal_nis_endprotoent ();
ypcb.foreach = saveit;
ypcb.data = NULL;
status = yperr2nss (yp_all (domainname, "protocols.bynumber", &ypcb));
next = start;
return status;
}
enum nss_status
_nss_nis_setprotoent (int stayopen)
{
enum nss_status status;
__libc_lock_lock (lock);
status = internal_nis_setprotoent ();
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nis_endprotoent (void)
{
__libc_lock_lock (lock);
internal_nis_endprotoent ();
next = NULL;
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nis_getprotoent_r (struct protoent *proto,
char *buffer, size_t buflen, int *errnop)
{
struct parser_data *data = (void *) buffer;
int parse_res;
if (start == NULL)
internal_nis_setprotoent ();
/* Get the next entry until we found a correct one. */
do
{
char *p;
if (next == NULL)
return NSS_STATUS_NOTFOUND;
p = strncpy (buffer, next->val, buflen);
while (isspace (*p))
++p;
parse_res = _nss_files_parse_protoent (p, proto, data, buflen, errnop);
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
next = next->next;
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nis_getprotoent_r (struct protoent *proto, char *buffer, size_t buflen,
int *errnop)
{
enum nss_status status;
__libc_lock_lock (lock);
status = internal_nis_getprotoent_r (proto, buffer, buflen, errnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nis_getprotobyname_r (const char *name, struct protoent *proto,
char *buffer, size_t buflen, int *errnop)
{
if (name == NULL)
{
*errnop = EINVAL;
return NSS_STATUS_UNAVAIL;
}
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
char *result;
int len;
int yperr = yp_match (domain, "protocols.byname", name, strlen (name),
&result, &len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
*errnop = errno;
return retval;
}
if (__glibc_unlikely ((size_t) (len + 1) > buflen))
{
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (buffer, result, len);
buffer[len] = '\0';
while (isspace (*p))
++p;
free (result);
int parse_res = _nss_files_parse_protoent (p, proto, (void *) buffer, buflen,
errnop);
if (__glibc_unlikely (parse_res < 1))
{
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nis_getprotobynumber_r (int number, struct protoent *proto,
char *buffer, size_t buflen, int *errnop)
{
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
char buf[32];
int nlen = snprintf (buf, sizeof (buf), "%d", number);
char *result;
int len;
int yperr = yp_match (domain, "protocols.bynumber", buf, nlen, &result,
&len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
*errnop = errno;
return retval;
}
if (__glibc_unlikely ((size_t) (len + 1) > buflen))
{
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (buffer, result, len);
buffer[len] = '\0';
while (isspace (*p))
++p;
free (result);
int parse_res = _nss_files_parse_protoent (p, proto, (void *) buffer, buflen,
errnop);
if (__glibc_unlikely (parse_res < 1))
{
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
return NSS_STATUS_SUCCESS;
}

View File

@ -1,581 +0,0 @@
/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
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 <assert.h>
#include <ctype.h>
#include <errno.h>
#include <nss.h>
#include <pwd.h>
#include <string.h>
#include <libc-lock.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
#include "nss-nis.h"
#include <libnsl.h>
/* Get the declaration of the parser function. */
#define ENTNAME pwent
#define STRUCTURE passwd
#define EXTERN_PARSER
#include <nss/nss_files/files-parse.c>
/* Protect global state against multiple changers */
__libc_lock_define_initialized (static, lock)
static bool new_start = true;
static char *oldkey;
static int oldkeylen;
static intern_t intern;
int
_nis_saveit (int instatus, char *inkey, int inkeylen, char *inval,
int invallen, char *indata)
{
intern_t *intern = (intern_t *) indata;
if (instatus != YP_TRUE)
return 1;
if (inkey && inkeylen > 0 && inval && invallen > 0)
{
struct response_t *bucket = intern->next;
if (__glibc_unlikely (bucket == NULL))
{
#define MINSIZE 4096 - 4 * sizeof (void *)
const size_t minsize = MAX (MINSIZE, 2 * (invallen + 1));
bucket = malloc (sizeof (struct response_t) + minsize);
if (bucket == NULL)
/* We have no error code for out of memory. */
return 1;
bucket->next = NULL;
bucket->size = minsize;
intern->start = intern->next = bucket;
intern->offset = 0;
}
else if (__builtin_expect (invallen + 1 > bucket->size - intern->offset,
0))
{
/* We need a new (larger) buffer. */
const size_t newsize = 2 * MAX (bucket->size, invallen + 1);
struct response_t *newp = malloc (sizeof (struct response_t)
+ newsize);
if (newp == NULL)
/* We have no error code for out of memory. */
return 1;
/* Mark the old bucket as full. */
bucket->size = intern->offset;
newp->next = NULL;
newp->size = newsize;
bucket = intern->next = bucket->next = newp;
intern->offset = 0;
}
char *p = mempcpy (&bucket->mem[intern->offset], inval, invallen);
if (__glibc_unlikely (p[-1] != '\0'))
{
*p = '\0';
++invallen;
}
intern->offset += invallen;
}
return 0;
}
static void
internal_nis_endpwent (void)
{
new_start = true;
free (oldkey);
oldkey = NULL;
oldkeylen = 0;
struct response_t *curr = intern.start;
while (curr != NULL)
{
struct response_t *last = curr;
curr = curr->next;
free (last);
}
intern.next = intern.start = NULL;
}
enum nss_status
_nss_nis_endpwent (void)
{
__libc_lock_lock (lock);
internal_nis_endpwent ();
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
enum nss_status
internal_nis_setpwent (void)
{
/* We have to read all the data now. */
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
struct ypall_callback ypcb;
ypcb.foreach = _nis_saveit;
ypcb.data = (char *) &intern;
enum nss_status status = yperr2nss (yp_all (domain, "passwd.byname", &ypcb));
/* Mark the last buffer as full. */
if (intern.next != NULL)
intern.next->size = intern.offset;
intern.next = intern.start;
intern.offset = 0;
return status;
}
enum nss_status
_nss_nis_setpwent (int stayopen)
{
enum nss_status result = NSS_STATUS_SUCCESS;
__libc_lock_lock (lock);
internal_nis_endpwent ();
if (_nsl_default_nss () & NSS_FLAG_SETENT_BATCH_READ)
result = internal_nis_setpwent ();
__libc_lock_unlock (lock);
return result;
}
static enum nss_status
internal_nis_getpwent_r (struct passwd *pwd, char *buffer, size_t buflen,
int *errnop)
{
/* If we read the entire database at setpwent time we just iterate
over the data we have in memory. */
bool batch_read = intern.start != NULL;
char *domain = NULL;
if (!batch_read && __builtin_expect (yp_get_default_domain (&domain), 0))
return NSS_STATUS_UNAVAIL;
/* Get the next entry until we found a correct one. */
int parse_res;
do
{
char *result;
char *outkey;
int len;
int keylen;
if (batch_read)
{
struct response_t *bucket;
handle_batch_read:
bucket = intern.next;
if (__glibc_unlikely (intern.offset >= bucket->size))
{
if (bucket->next == NULL)
return NSS_STATUS_NOTFOUND;
/* We look at all the content in the current bucket. Go on
to the next. */
bucket = intern.next = bucket->next;
intern.offset = 0;
}
for (result = &bucket->mem[intern.offset]; isspace (*result);
++result)
++intern.offset;
len = strlen (result);
}
else
{
int yperr;
if (new_start)
{
/* Maybe we should read the database in one piece. */
if ((_nsl_default_nss () & NSS_FLAG_SETENT_BATCH_READ)
&& internal_nis_setpwent () == NSS_STATUS_SUCCESS
&& intern.start != NULL)
{
batch_read = true;
goto handle_batch_read;
}
yperr = yp_first (domain, "passwd.byname", &outkey, &keylen,
&result, &len);
}
else
yperr = yp_next (domain, "passwd.byname", oldkey, oldkeylen,
&outkey, &keylen, &result, &len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
*errnop = errno;
return retval;
}
}
/* Check for adjunct style secret passwords. They can be
recognized by a password starting with "##". We do not use
it if the passwd.adjunct.byname table is supposed to be used
as a shadow.byname replacement. */
char *p = strchr (result, ':');
size_t namelen;
char *result2;
int len2;
if ((_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW) == 0
&& p != NULL /* This better should be true in all cases. */
&& p[1] == '#' && p[2] == '#'
&& (namelen = p - result,
yp_match (domain, "passwd.adjunct.byname", result, namelen,
&result2, &len2)) == YPERR_SUCCESS)
{
/* We found a passwd.adjunct.byname entry. Merge encrypted
password therein into original result. */
char *encrypted = strchr (result2, ':');
char *endp;
size_t restlen;
if (encrypted == NULL
|| (endp = strchr (++encrypted, ':')) == NULL
|| (p = strchr (p + 1, ':')) == NULL)
{
/* Invalid format of the entry. This never should happen
unless the data from which the NIS table is generated is
wrong. We simply ignore it. */
free (result2);
goto non_adjunct;
}
restlen = len - (p - result);
if (__builtin_expect ((size_t) (namelen + (endp - encrypted)
+ restlen + 2) > buflen, 0))
{
free (result2);
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
mempcpy (mempcpy (mempcpy (mempcpy (buffer, result, namelen),
":", 1),
encrypted, endp - encrypted),
p, restlen + 1);
p = buffer;
free (result2);
}
else
{
non_adjunct:
if (__glibc_unlikely ((size_t) (len + 1) > buflen))
{
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
p = buffer;
*((char *) mempcpy (buffer, result, len)) = '\0';
}
while (isspace (*p))
++p;
if (!batch_read)
free (result);
parse_res = _nss_files_parse_pwent (p, pwd, (void *) buffer, buflen,
errnop);
if (__glibc_unlikely (parse_res == -1))
{
if (!batch_read)
free (outkey);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
if (batch_read)
intern.offset += len + 1;
else
{
free (oldkey);
oldkey = outkey;
oldkeylen = keylen;
new_start = false;
}
}
while (parse_res < 1);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nis_getpwent_r (struct passwd *result, char *buffer, size_t buflen,
int *errnop)
{
int status;
__libc_lock_lock (lock);
status = internal_nis_getpwent_r (result, buffer, buflen, errnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nis_getpwnam_r (const char *name, struct passwd *pwd,
char *buffer, size_t buflen, int *errnop)
{
if (name == NULL)
{
*errnop = EINVAL;
return NSS_STATUS_UNAVAIL;
}
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
size_t namelen = strlen (name);
char *result;
int len;
int yperr = yp_match (domain, "passwd.byname", name, namelen, &result, &len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
*errnop = errno;
return retval;
}
/* Check for adjunct style secret passwords. They can be recognized
by a password starting with "##". We do not use it if the
passwd.adjunct.byname table is supposed to be used as a shadow.byname
replacement. */
char *result2;
int len2;
char *p = strchr (result, ':');
if ((_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW) == 0
&& p != NULL /* This better should be true in all cases. */
&& p[1] == '#' && p[2] == '#'
&& yp_match (domain, "passwd.adjunct.byname", name, namelen,
&result2, &len2) == YPERR_SUCCESS)
{
/* We found a passwd.adjunct.byname entry. Merge encrypted password
therein into original result. */
char *encrypted = strchr (result2, ':');
char *endp;
if (encrypted == NULL
|| (endp = strchr (++encrypted, ':')) == NULL
|| (p = strchr (p + 1, ':')) == NULL)
{
/* Invalid format of the entry. This never should happen
unless the data from which the NIS table is generated is
wrong. We simply ignore it. */
free (result2);
goto non_adjunct;
}
size_t restlen = len - (p - result);
if (__builtin_expect ((size_t) (namelen + (endp - encrypted)
+ restlen + 2) > buflen, 0))
{
free (result2);
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
__mempcpy (__mempcpy (__mempcpy (__mempcpy (buffer, name, namelen),
":", 1),
encrypted, endp - encrypted),
p, restlen + 1);
p = buffer;
free (result2);
}
else
{
non_adjunct:
if (__glibc_unlikely ((size_t) (len + 1) > buflen))
{
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
p = strncpy (buffer, result, len);
buffer[len] = '\0';
}
while (isspace (*p))
++p;
free (result);
int parse_res = _nss_files_parse_pwent (p, pwd, (void *) buffer, buflen,
errnop);
if (__glibc_unlikely (parse_res < 1))
{
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
else
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nis_getpwuid_r (uid_t uid, struct passwd *pwd,
char *buffer, size_t buflen, int *errnop)
{
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
char buf[32];
int nlen = snprintf (buf, sizeof (buf), "%lu", (unsigned long int) uid);
char *result;
int len;
int yperr = yp_match (domain, "passwd.byuid", buf, nlen, &result, &len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
*errnop = errno;
return retval;
}
/* Check for adjunct style secret passwords. They can be recognized
by a password starting with "##". We do not use it if the
passwd.adjunct.byname table is supposed to be used as a shadow.byname
replacement. */
char *result2;
int len2;
size_t namelen;
char *p = strchr (result, ':');
if ((_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW) == 0
&& p != NULL /* This better should be true in all cases. */
&& p[1] == '#' && p[2] == '#'
&& (namelen = p - result,
yp_match (domain, "passwd.adjunct.byname", result, namelen,
&result2, &len2)) == YPERR_SUCCESS)
{
/* We found a passwd.adjunct.byname entry. Merge encrypted password
therein into original result. */
char *encrypted = strchr (result2, ':');
char *endp;
size_t restlen;
if (encrypted == NULL
|| (endp = strchr (++encrypted, ':')) == NULL
|| (p = strchr (p + 1, ':')) == NULL)
{
/* Invalid format of the entry. This never should happen
unless the data from which the NIS table is generated is
wrong. We simply ignore it. */
free (result2);
goto non_adjunct;
}
restlen = len - (p - result);
if (__builtin_expect ((size_t) (namelen + (endp - encrypted)
+ restlen + 2) > buflen, 0))
{
free (result2);
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
__mempcpy (__mempcpy (__mempcpy (__mempcpy (buffer, result, namelen),
":", 1),
encrypted, endp - encrypted),
p, restlen + 1);
p = buffer;
free (result2);
}
else
{
non_adjunct:
if (__glibc_unlikely ((size_t) (len + 1) > buflen))
{
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
p = strncpy (buffer, result, len);
buffer[len] = '\0';
}
while (isspace (*p))
++p;
free (result);
int parse_res = _nss_files_parse_pwent (p, pwd, (void *) buffer, buflen,
errnop);
if (__glibc_unlikely (parse_res < 1))
{
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
else
return NSS_STATUS_SUCCESS;
}

View File

@ -1,279 +0,0 @@
/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
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.h>
#include <netdb.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <libc-lock.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
#include "nss-nis.h"
/* Get the declaration of the parser function. */
#define ENTNAME rpcent
#define EXTERN_PARSER
#include <nss/nss_files/files-parse.c>
__libc_lock_define_initialized (static, lock)
static intern_t intern;
static void
internal_nis_endrpcent (intern_t *intern)
{
struct response_t *curr = intern->next;
while (curr != NULL)
{
struct response_t *last = curr;
curr = curr->next;
free (last);
}
intern->next = intern->start = NULL;
}
static enum nss_status
internal_nis_setrpcent (intern_t *intern)
{
char *domainname;
struct ypall_callback ypcb;
enum nss_status status;
if (yp_get_default_domain (&domainname))
return NSS_STATUS_UNAVAIL;
internal_nis_endrpcent (intern);
ypcb.foreach = _nis_saveit;
ypcb.data = (char *) intern;
status = yperr2nss (yp_all (domainname, "rpc.bynumber", &ypcb));
/* Mark the last buffer as full. */
if (intern->next != NULL)
intern->next->size = intern->offset;
intern->next = intern->start;
intern->offset = 0;
return status;
}
enum nss_status
_nss_nis_setrpcent (int stayopen)
{
enum nss_status status;
__libc_lock_lock (lock);
status = internal_nis_setrpcent (&intern);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nis_endrpcent (void)
{
__libc_lock_lock (lock);
internal_nis_endrpcent (&intern);
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen,
int *errnop, intern_t *intern)
{
struct parser_data *pdata = (void *) buffer;
int parse_res;
char *p;
if (intern->start == NULL)
internal_nis_setrpcent (intern);
if (intern->next == NULL)
/* Not one entry in the map. */
return NSS_STATUS_NOTFOUND;
/* Get the next entry until we found a correct one. */
do
{
struct response_t *bucket = intern->next;
if (__glibc_unlikely (intern->offset >= bucket->size))
{
if (bucket->next == NULL)
return NSS_STATUS_NOTFOUND;
/* We look at all the content in the current bucket. Go on
to the next. */
bucket = intern->next = bucket->next;
intern->offset = 0;
}
for (p = &bucket->mem[intern->offset]; isspace (*p); ++p)
++intern->offset;
size_t len = strlen (p) + 1;
if (__glibc_unlikely (len > buflen))
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
/* We unfortunately have to copy the data in the user-provided
buffer because that buffer might be around for a very long
time and the servent structure must remain valid. If we would
rely on the BUCKET memory the next 'setservent' or 'endservent'
call would destroy it.
The important thing is that it is a single NUL-terminated
string. This is what the parsing routine expects. */
p = memcpy (buffer, &bucket->mem[intern->offset], len);
parse_res = _nss_files_parse_rpcent (p, rpc, pdata, buflen, errnop);
if (__glibc_unlikely (parse_res == -1))
return NSS_STATUS_TRYAGAIN;
intern->offset += len;
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen,
int *errnop)
{
enum nss_status status;
__libc_lock_lock (lock);
status = internal_nis_getrpcent_r (rpc, buffer, buflen, errnop, &intern);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nis_getrpcbyname_r (const char *name, struct rpcent *rpc,
char *buffer, size_t buflen, int *errnop)
{
if (name == NULL)
{
*errnop = EINVAL;
return NSS_STATUS_UNAVAIL;
}
intern_t data = { NULL, NULL, 0 };
enum nss_status status = internal_nis_setrpcent (&data);
if (__glibc_unlikely (status != NSS_STATUS_SUCCESS))
return status;
int found = 0;
while (!found
&& ((status = internal_nis_getrpcent_r (rpc, buffer, buflen, errnop,
&data)) == NSS_STATUS_SUCCESS))
{
if (strcmp (rpc->r_name, name) == 0)
found = 1;
else
{
int i = 0;
while (rpc->r_aliases[i] != NULL)
{
if (strcmp (rpc->r_aliases[i], name) == 0)
{
found = 1;
break;
}
else
++i;
}
}
}
internal_nis_endrpcent (&data);
if (__glibc_unlikely (!found && status == NSS_STATUS_SUCCESS))
return NSS_STATUS_NOTFOUND;
return status;
}
enum nss_status
_nss_nis_getrpcbynumber_r (int number, struct rpcent *rpc,
char *buffer, size_t buflen, int *errnop)
{
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
char buf[32];
int nlen = snprintf (buf, sizeof (buf), "%d", number);
char *result;
int len;
int yperr = yp_match (domain, "rpc.bynumber", buf, nlen, &result, &len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
*errnop = errno;
return retval;
}
if (__glibc_unlikely ((size_t) (len + 1) > buflen))
{
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (buffer, result, len);
buffer[len] = '\0';
while (isspace (*p))
++p;
free (result);
int parse_res = _nss_files_parse_rpcent (p, rpc, (void *) buffer, buflen,
errnop);
if (__glibc_unlikely (parse_res < 1))
{
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
else
return NSS_STATUS_SUCCESS;
}

View File

@ -1,438 +0,0 @@
/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
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.h>
#include <netdb.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <libc-lock.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
#include "nss-nis.h"
#include <libnsl.h>
/* Get the declaration of the parser function. */
#define ENTNAME servent
#define EXTERN_PARSER
#include <nss/nss_files/files-parse.c>
__libc_lock_define_initialized (static, lock)
static intern_t intern;
struct search_t
{
const char *name;
const char *proto;
int port;
enum nss_status status;
struct servent *serv;
char *buffer;
size_t buflen;
int *errnop;
};
static int
dosearch (int instatus, char *inkey, int inkeylen, char *inval,
int invallen, char *indata)
{
struct search_t *req = (struct search_t *) indata;
if (__glibc_unlikely (instatus != YP_TRUE))
return 1;
if (inkey && inkeylen > 0 && inval && invallen > 0)
{
if (__glibc_unlikely ((size_t) (invallen + 1) > req->buflen))
{
*req->errnop = ERANGE;
req->status = NSS_STATUS_TRYAGAIN;
return 1;
}
char *p = strncpy (req->buffer, inval, invallen);
req->buffer[invallen] = '\0';
while (isspace (*p))
++p;
int parse_res = _nss_files_parse_servent (p, req->serv,
(void *) req->buffer,
req->buflen, req->errnop);
if (parse_res == -1)
{
req->status = NSS_STATUS_TRYAGAIN;
return 1;
}
if (!parse_res)
return 0;
if (req->proto != NULL && strcmp (req->serv->s_proto, req->proto) != 0)
return 0;
if (req->port != -1 && req->serv->s_port != req->port)
return 0;
if (req->name != NULL && strcmp (req->serv->s_name, req->name) != 0)
{
char **cp;
for (cp = req->serv->s_aliases; *cp; cp++)
if (strcmp (req->name, *cp) == 0)
break;
if (*cp == NULL)
return 0;
}
req->status = NSS_STATUS_SUCCESS;
return 1;
}
return 0;
}
static void
internal_nis_endservent (void)
{
struct response_t *curr = intern.next;
while (curr != NULL)
{
struct response_t *last = curr;
curr = curr->next;
free (last);
}
intern.next = intern.start = NULL;
}
enum nss_status
_nss_nis_endservent (void)
{
__libc_lock_lock (lock);
internal_nis_endservent ();
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nis_setservent (void)
{
char *domainname;
struct ypall_callback ypcb;
enum nss_status status;
if (yp_get_default_domain (&domainname))
return NSS_STATUS_UNAVAIL;
internal_nis_endservent ();
ypcb.foreach = _nis_saveit;
ypcb.data = (char *) &intern;
status = yperr2nss (yp_all (domainname, "services.byname", &ypcb));
/* Mark the last buffer as full. */
if (intern.next != NULL)
intern.next->size = intern.offset;
intern.next = intern.start;
intern.offset = 0;
return status;
}
enum nss_status
_nss_nis_setservent (int stayopen)
{
enum nss_status status;
__libc_lock_lock (lock);
status = internal_nis_setservent ();
__libc_lock_unlock (lock);
return status;
}
static enum nss_status
internal_nis_getservent_r (struct servent *serv, char *buffer,
size_t buflen, int *errnop)
{
struct parser_data *pdata = (void *) buffer;
int parse_res;
char *p;
if (intern.start == NULL)
internal_nis_setservent ();
if (intern.next == NULL)
/* Not one entry in the map. */
return NSS_STATUS_NOTFOUND;
/* Get the next entry until we found a correct one. */
do
{
struct response_t *bucket = intern.next;
if (__glibc_unlikely (intern.offset >= bucket->size))
{
if (bucket->next == NULL)
return NSS_STATUS_NOTFOUND;
/* We look at all the content in the current bucket. Go on
to the next. */
bucket = intern.next = bucket->next;
intern.offset = 0;
}
for (p = &bucket->mem[intern.offset]; isspace (*p); ++p)
++intern.offset;
size_t len = strlen (p) + 1;
if (__glibc_unlikely (len > buflen))
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
/* We unfortunately have to copy the data in the user-provided
buffer because that buffer might be around for a very long
time and the servent structure must remain valid. If we would
rely on the BUCKET memory the next 'setservent' or 'endservent'
call would destroy it.
The important thing is that it is a single NUL-terminated
string. This is what the parsing routine expects. */
p = memcpy (buffer, &bucket->mem[intern.offset], len);
parse_res = _nss_files_parse_servent (p, serv, pdata, buflen, errnop);
if (__glibc_unlikely (parse_res == -1))
return NSS_STATUS_TRYAGAIN;
intern.offset += len;
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nis_getservent_r (struct servent *serv, char *buffer, size_t buflen,
int *errnop)
{
enum nss_status status;
__libc_lock_lock (lock);
status = internal_nis_getservent_r (serv, buffer, buflen, errnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nis_getservbyname_r (const char *name, const char *protocol,
struct servent *serv, char *buffer, size_t buflen,
int *errnop)
{
if (name == NULL)
{
*errnop = EINVAL;
return NSS_STATUS_UNAVAIL;
}
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
/* If the protocol is given, we could try if our NIS server knows
about services.byservicename map. If yes, we only need one query. */
size_t keylen = strlen (name) + (protocol ? 1 + strlen (protocol) : 0);
/* Limit key length to the maximum size of an RPC packet. */
if (keylen > UDPMSGSIZE)
{
*errnop = ERANGE;
return NSS_STATUS_UNAVAIL;
}
char key[keylen + 1];
/* key is: "name/proto" */
char *cp = stpcpy (key, name);
if (protocol != NULL)
{
*cp++ = '/';
strcpy (cp, protocol);
}
char *result;
int int_len;
int status = yp_match (domain, "services.byservicename", key,
keylen, &result, &int_len);
size_t len = int_len;
/* If we found the key, it's ok and parse the result. If not,
fall through and parse the complete table. */
if (__glibc_likely (status == YPERR_SUCCESS))
{
if (__glibc_unlikely ((size_t) (len + 1) > buflen))
{
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (buffer, result, len);
buffer[len] = '\0';
while (isspace (*p))
++p;
free (result);
int parse_res = _nss_files_parse_servent (p, serv, (void *) buffer,
buflen, errnop);
if (__glibc_unlikely (parse_res < 0))
{
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
else
return NSS_STATUS_SUCCESS;
}
/* Check if it is safe to rely on services.byservicename. */
if (_nsl_default_nss () & NSS_FLAG_SERVICES_AUTHORITATIVE)
return yperr2nss (status);
struct ypall_callback ypcb;
struct search_t req;
ypcb.foreach = dosearch;
ypcb.data = (char *) &req;
req.name = name;
req.proto = protocol;
req.port = -1;
req.serv = serv;
req.buffer = buffer;
req.buflen = buflen;
req.errnop = errnop;
req.status = NSS_STATUS_NOTFOUND;
status = yp_all (domain, "services.byname", &ypcb);
if (__glibc_unlikely (status != YPERR_SUCCESS))
return yperr2nss (status);
return req.status;
}
enum nss_status
_nss_nis_getservbyport_r (int port, const char *protocol,
struct servent *serv, char *buffer,
size_t buflen, int *errnop)
{
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
/* If the protocol is given, we only need one query.
Otherwise try first port/tcp, then port/udp and then fallback
to sequential scanning of services.byname. */
const char *proto = protocol != NULL ? protocol : "tcp";
/* Limit protocol name length to the maximum size of an RPC packet. */
if (strlen (proto) > UDPMSGSIZE)
{
*errnop = ERANGE;
return NSS_STATUS_UNAVAIL;
}
do
{
/* key is: "port/proto" */
char key[sizeof (int) * 3 + strlen (proto) + 2];
size_t keylen = snprintf (key, sizeof (key), "%d/%s", ntohs (port),
proto);
char *result;
int int_len;
int status = yp_match (domain, "services.byname", key, keylen, &result,
&int_len);
size_t len = int_len;
/* If we found the key, it's ok and parse the result. If not,
fall through and parse the complete table. */
if (__glibc_likely (status == YPERR_SUCCESS))
{
if (__glibc_unlikely ((size_t) (len + 1) > buflen))
{
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (buffer, result, len);
buffer[len] = '\0';
while (isspace (*p))
++p;
free (result);
int parse_res = _nss_files_parse_servent (p, serv, (void *) buffer,
buflen, errnop);
if (__glibc_unlikely (parse_res < 0))
{
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
return NSS_STATUS_SUCCESS;
}
}
while (protocol == NULL && (proto[0] == 't' ? (proto = "udp") : NULL));
if (port == -1)
return NSS_STATUS_NOTFOUND;
struct ypall_callback ypcb;
struct search_t req;
ypcb.foreach = dosearch;
ypcb.data = (char *) &req;
req.name = NULL;
req.proto = protocol;
req.port = port;
req.serv = serv;
req.buffer = buffer;
req.buflen = buflen;
req.errnop = errnop;
req.status = NSS_STATUS_NOTFOUND;
int status = yp_all (domain, "services.byname", &ypcb);
if (__glibc_unlikely (status != YPERR_SUCCESS))
return yperr2nss (status);
return req.status;
}

View File

@ -1,235 +0,0 @@
/* Copyright (C) 1996-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
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.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <shadow.h>
#include <libc-lock.h>
#include <rpcsvc/yp.h>
#include <rpcsvc/ypclnt.h>
#include <netdb.h>
#include "nss-nis.h"
#include <libnsl.h>
/* Get the declaration of the parser function. */
#define ENTNAME spent
#define STRUCTURE spwd
#define EXTERN_PARSER
#include <nss/nss_files/files-parse.c>
/* Protect global state against multiple changers */
__libc_lock_define_initialized (static, lock)
static bool new_start = true;
static bool ent_adjunct_used;
static char *oldkey;
static int oldkeylen;
enum nss_status
_nss_nis_setspent (int stayopen)
{
return _nss_nis_endspent ();
}
enum nss_status
_nss_nis_endspent (void)
{
__libc_lock_lock (lock);
new_start = true;
ent_adjunct_used = false;
free (oldkey);
oldkey = NULL;
oldkeylen = 0;
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
libnss_nis_hidden_def (_nss_nis_endspent)
static enum nss_status
internal_nis_getspent_r (struct spwd *sp, char *buffer, size_t buflen,
int *errnop)
{
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
/* Get the next entry until we found a correct one. */
int parse_res;
do
{
char *result;
char *outkey;
int len;
int keylen;
int yperr;
if (new_start)
{
yperr = yp_first (domain, "shadow.byname", &outkey, &keylen, &result,
&len);
if (__builtin_expect (yperr == YPERR_MAP, 0)
&& (_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW))
{
free (result);
yperr = yp_first (domain, "passwd.adjunct.byname", &outkey,
&keylen, &result, &len);
ent_adjunct_used = true;
}
}
else
yperr = yp_next (domain, (ent_adjunct_used
? "passwd.adjunct.byname" : "shadow.byname"),
oldkey, oldkeylen, &outkey, &keylen, &result, &len);
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
*errnop = errno;
return retval;
}
if (__builtin_expect ((size_t) (len + (ent_adjunct_used ? 3 : 1))
> buflen, 0))
{
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (buffer, result, len);
if (ent_adjunct_used)
/* This is an ugly trick. The format of passwd.adjunct.byname almost
matches the shadow.byname format except that the last two fields
are missing. Synthesize them by marking them empty. */
strcpy (&buffer[len], "::");
else
buffer[len] = '\0';
while (isspace (*p))
++p;
free (result);
parse_res = _nss_files_parse_spent (p, sp, (void *) buffer, buflen,
errnop);
if (__builtin_expect (parse_res == -1, 0))
{
free (outkey);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
free (oldkey);
oldkey = outkey;
oldkeylen = keylen;
new_start = false;
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nis_getspent_r (struct spwd *result, char *buffer, size_t buflen,
int *errnop)
{
int status;
__libc_lock_lock (lock);
status = internal_nis_getspent_r (result, buffer, buflen, errnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nis_getspnam_r (const char *name, struct spwd *sp,
char *buffer, size_t buflen, int *errnop)
{
if (name == NULL)
{
*errnop = EINVAL;
return NSS_STATUS_UNAVAIL;
}
const size_t name_len = strlen (name);
char *domain;
if (__glibc_unlikely (yp_get_default_domain (&domain)))
return NSS_STATUS_UNAVAIL;
bool adjunct_used = false;
char *result;
int len;
int yperr = yp_match (domain, "shadow.byname", name, name_len, &result,
&len);
if (__builtin_expect (yperr == YPERR_MAP, 0)
&& (_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW))
{
free (result);
yperr = yp_match (domain, "passwd.adjunct.byname", name, name_len,
&result, &len);
adjunct_used = true;
}
if (__glibc_unlikely (yperr != YPERR_SUCCESS))
{
enum nss_status retval = yperr2nss (yperr);
if (retval == NSS_STATUS_TRYAGAIN)
*errnop = errno;
return retval;
}
if (__glibc_unlikely ((size_t) (len + (adjunct_used ? 3 : 1)) > buflen))
{
free (result);
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
char *p = strncpy (buffer, result, len);
if (__builtin_expect (adjunct_used, false))
/* This is an ugly trick. The format of passwd.adjunct.byname almost
matches the shadow.byname format except that the last two fields
are missing. Synthesize them by marking them empty. */
strcpy (&buffer[len], "::");
else
buffer[len] = '\0';
while (isspace (*p))
++p;
free (result);
int parse_res = _nss_files_parse_spent (p, sp, (void *) buffer, buflen,
errnop);
if (__glibc_unlikely (parse_res < 1))
{
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
return NSS_STATUS_SUCCESS;
}

View File

@ -1,337 +0,0 @@
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
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 <atomic.h>
#include <nss.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <aliases.h>
#include <libc-lock.h>
#include <rpcsvc/nis.h>
#include "nss-nisplus.h"
__libc_lock_define_initialized (static, lock)
static nis_result *result;
static u_long next_entry;
static nis_name tablename_val;
static size_t tablename_len;
#define NISENTRYVAL(idx, col, res) \
(NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
#define NISENTRYLEN(idx, col, res) \
(NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
static enum nss_status
_nss_create_tablename (int *errnop)
{
if (tablename_val == NULL)
{
const char *local_dir = nis_local_directory ();
size_t local_dir_len = strlen (local_dir);
static const char prefix[] = "mail_aliases.org_dir.";
char *p = malloc (sizeof (prefix) + local_dir_len);
if (p == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1);
tablename_len = sizeof (prefix) - 1 + local_dir_len;
atomic_write_barrier ();
tablename_val = p;
}
return NSS_STATUS_SUCCESS;
}
static int
_nss_nisplus_parse_aliasent (nis_result *result, unsigned long entry,
struct aliasent *alias, char *buffer,
size_t buflen, int *errnop)
{
if (result == NULL)
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
|| __type_of (&NIS_RES_OBJECT (result)[entry]) != NIS_ENTRY_OBJ
|| strcmp (NIS_RES_OBJECT (result)[entry].EN_data.en_type,
"mail_aliases") != 0
|| NIS_RES_OBJECT (result)[entry].EN_data.en_cols.en_cols_len < 2)
return 0;
if (NISENTRYLEN (entry, 1, result) >= buflen)
{
/* The line is too long for our buffer. */
no_more_room:
*errnop = ERANGE;
return -1;
}
char *cp = __stpncpy (buffer, NISENTRYVAL (entry, 1, result),
NISENTRYLEN (entry, 1, result));
*cp = '\0';
char *first_unused = cp + 1;
size_t room_left = buflen - (first_unused - buffer);
alias->alias_local = 0;
alias->alias_members_len = 0;
if (NISENTRYLEN (entry, 0, result) >= room_left)
goto no_more_room;
cp = __stpncpy (first_unused, NISENTRYVAL (entry, 0, result),
NISENTRYLEN (entry, 0, result));
*cp = '\0';
alias->alias_name = first_unused;
/* Terminate the line for any case. */
cp = strpbrk (alias->alias_name, "#\n");
if (cp != NULL)
*cp = '\0';
size_t len = strlen (alias->alias_name) + 1;
first_unused += len;
room_left -= len;
/* Adjust the pointer so it is aligned for
storing pointers. */
size_t adjust = ((__alignof__ (char *)
- (first_unused - (char *) 0) % __alignof__ (char *))
% __alignof__ (char *));
if (room_left < adjust)
goto no_more_room;
first_unused += adjust;
room_left -= adjust;
alias->alias_members = (char **) first_unused;
char *line = buffer;
while (*line != '\0')
{
/* Skip leading blanks. */
while (isspace (*line))
++line;
if (*line == '\0')
break;
if (room_left < sizeof (char *))
goto no_more_room;
room_left -= sizeof (char *);
alias->alias_members[alias->alias_members_len] = line;
while (*line != '\0' && *line != ',')
++line;
if (line != alias->alias_members[alias->alias_members_len])
{
*line++ = '\0';
++alias->alias_members_len;
}
else if (*line == ',')
++line;
}
return alias->alias_members_len == 0 ? 0 : 1;
}
static enum nss_status
internal_setaliasent (void)
{
enum nss_status status;
int err;
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
if (_nss_create_tablename (&err) != NSS_STATUS_SUCCESS)
return NSS_STATUS_UNAVAIL;
next_entry = 0;
result = nis_list (tablename_val, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (result == NULL)
{
status = NSS_STATUS_TRYAGAIN;
__set_errno (ENOMEM);
}
else
{
status = niserr2nss (result->status);
if (status != NSS_STATUS_SUCCESS)
{
nis_freeresult (result);
result = NULL;
}
}
return status;
}
enum nss_status
_nss_nisplus_setaliasent (void)
{
enum nss_status status;
__libc_lock_lock (lock);
status = internal_setaliasent ();
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_endaliasent (void)
{
__libc_lock_lock (lock);
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
next_entry = 0;
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_getaliasent_r (struct aliasent *alias,
char *buffer, size_t buflen, int *errnop)
{
int parse_res;
if (result == NULL)
{
enum nss_status status;
status = internal_setaliasent ();
if (result == NULL || status != NSS_STATUS_SUCCESS)
return status;
}
/* Get the next entry until we found a correct one. */
do
{
if (next_entry >= result->objects.objects_len)
return NSS_STATUS_NOTFOUND;
parse_res = _nss_nisplus_parse_aliasent (result, next_entry, alias,
buffer, buflen, errnop);
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
++next_entry;
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getaliasent_r (struct aliasent *result, char *buffer,
size_t buflen, int *errnop)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_getaliasent_r (result, buffer, buflen, errnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_getaliasbyname_r (const char *name, struct aliasent *alias,
char *buffer, size_t buflen, int *errnop)
{
int parse_res;
if (tablename_val == NULL)
{
__libc_lock_lock (lock);
enum nss_status status = _nss_create_tablename (errnop);
__libc_lock_unlock (lock);
if (status != NSS_STATUS_SUCCESS)
return status;
}
if (name == NULL)
{
*errnop = EINVAL;
return NSS_STATUS_UNAVAIL;
}
char buf[strlen (name) + 9 + tablename_len];
int olderr = errno;
snprintf (buf, sizeof (buf), "[name=%s],%s", name, tablename_val);
nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (result == NULL)
{
*errnop = ENOMEM;
return NSS_STATUS_TRYAGAIN;
}
if (__glibc_unlikely (niserr2nss (result->status) != NSS_STATUS_SUCCESS))
{
enum nss_status status = niserr2nss (result->status);
nis_freeresult (result);
return status;
}
parse_res = _nss_nisplus_parse_aliasent (result, 0, alias,
buffer, buflen, errnop);
/* We do not need the lookup result anymore. */
nis_freeresult (result);
if (__glibc_unlikely (parse_res < 1))
{
__set_errno (olderr);
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
else
return NSS_STATUS_NOTFOUND;
}
return NSS_STATUS_SUCCESS;
}

View File

@ -1,356 +0,0 @@
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
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 <atomic.h>
#include <ctype.h>
#include <errno.h>
#include <inttypes.h>
#include <netdb.h>
#include <nss.h>
#include <string.h>
#include <netinet/ether.h>
#include <netinet/if_ether.h>
#include <rpcsvc/nis.h>
#include <libc-lock.h>
#include "nss-nisplus.h"
__libc_lock_define_initialized (static, lock)
static nis_result *result;
static nis_name tablename_val;
static u_long tablename_len;
#define NISENTRYVAL(idx, col, res) \
(NIS_RES_OBJECT (res)[idx].zo_data.objdata_u.en_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
#define NISENTRYLEN(idx, col, res) \
(NIS_RES_OBJECT (res)[idx].zo_data.objdata_u.en_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
static int
_nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
char *buffer, size_t buflen, int *errnop)
{
char *p = buffer;
size_t room_left = buflen;
if (result == NULL)
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
|| NIS_RES_NUMOBJ (result) != 1
|| __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
|| strcmp (NIS_RES_OBJECT (result)->EN_data.en_type,
"ethers_tbl") != 0
|| NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 2)
return 0;
/* Generate the ether entry format and use the normal parser */
if (NISENTRYLEN (0, 0, result) + 1 > room_left)
{
*errnop = ERANGE;
return -1;
}
char *cp = __stpncpy (p, NISENTRYVAL (0, 0, result),
NISENTRYLEN (0, 0, result));
*cp = '\0';
room_left -= NISENTRYLEN (0, 0, result) + 1;
ether->e_name = p;
struct ether_addr *ea = ether_aton (NISENTRYVAL (0, 1, result));
if (ea == NULL)
{
*errnop = EINVAL;
return -2;
}
ether->e_addr = *ea;
return 1;
}
static enum nss_status
_nss_create_tablename (int *errnop)
{
if (tablename_val == NULL)
{
const char *local_dir = nis_local_directory ();
size_t local_dir_len = strlen (local_dir);
static const char prefix[] = "ethers.org_dir.";
char *p = malloc (sizeof (prefix) + local_dir_len);
if (p == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1);
tablename_len = sizeof (prefix) - 1 + local_dir_len;
atomic_write_barrier ();
tablename_val = p;
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_setetherent (int stayopen)
{
enum nss_status status;
int err;
status = NSS_STATUS_SUCCESS;
__libc_lock_lock (lock);
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
if (_nss_create_tablename (&err) != NSS_STATUS_SUCCESS)
status = NSS_STATUS_UNAVAIL;
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_endetherent (void)
{
__libc_lock_lock (lock);
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_getetherent_r (struct etherent *ether, char *buffer,
size_t buflen, int *errnop)
{
if (tablename_val == NULL)
{
enum nss_status status = _nss_create_tablename (errnop);
if (status != NSS_STATUS_SUCCESS)
return status;
}
/* Get the next entry until we found a correct one. */
int parse_res;
do
{
nis_result *saved_result;
if (result == NULL)
{
saved_result = NULL;
result = nis_first_entry (tablename_val);
if (result == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
return niserr2nss (result->status);
}
else
{
saved_result = result;
result = nis_next_entry (tablename_val, &result->cookie);
if (result == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
nis_freeresult (saved_result);
return niserr2nss (result->status);
}
}
parse_res = _nss_nisplus_parse_etherent (result, ether, buffer,
buflen, errnop);
if (parse_res == -1)
{
nis_freeresult (result);
result = saved_result;
return NSS_STATUS_TRYAGAIN;
}
if (saved_result != NULL)
nis_freeresult (saved_result);
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getetherent_r (struct etherent *result, char *buffer,
size_t buflen, int *errnop)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_getetherent_r (result, buffer, buflen, errnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_gethostton_r (const char *name, struct etherent *eth,
char *buffer, size_t buflen, int *errnop)
{
if (tablename_val == NULL)
{
enum nss_status status = _nss_create_tablename (errnop);
if (status != NSS_STATUS_SUCCESS)
return status;
}
if (name == NULL)
{
*errnop = EINVAL;
return NSS_STATUS_UNAVAIL;
}
char buf[strlen (name) + 9 + tablename_len];
int olderr = errno;
snprintf (buf, sizeof (buf), "[name=%s],%s", name, tablename_val);
nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM,
NULL, NULL);
if (result == NULL)
{
*errnop = ENOMEM;
return NSS_STATUS_TRYAGAIN;
}
if (__glibc_unlikely (niserr2nss (result->status) != NSS_STATUS_SUCCESS))
{
enum nss_status status = niserr2nss (result->status);
nis_freeresult (result);
return status;
}
int parse_res = _nss_nisplus_parse_etherent (result, eth, buffer,
buflen, errnop);
/* We do not need the lookup result anymore. */
nis_freeresult (result);
if (__glibc_unlikely (parse_res < 1))
{
__set_errno (olderr);
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
return NSS_STATUS_NOTFOUND;
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getntohost_r (const struct ether_addr *addr, struct etherent *eth,
char *buffer, size_t buflen, int *errnop)
{
if (tablename_val == NULL)
{
__libc_lock_lock (lock);
enum nss_status status = _nss_create_tablename (errnop);
__libc_lock_unlock (lock);
if (status != NSS_STATUS_SUCCESS)
return status;
}
if (addr == NULL)
{
*errnop = EINVAL;
return NSS_STATUS_UNAVAIL;
}
char buf[26 + tablename_len];
snprintf (buf, sizeof (buf),
"[addr=%" PRIx8 ":%" PRIx8 ":%" PRIx8 ":%" PRIx8 ":%" PRIx8
":%" PRIx8 "],%s",
addr->ether_addr_octet[0], addr->ether_addr_octet[1],
addr->ether_addr_octet[2], addr->ether_addr_octet[3],
addr->ether_addr_octet[4], addr->ether_addr_octet[5],
tablename_val);
nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM,
NULL, NULL);
if (result == NULL)
{
*errnop = ENOMEM;
return NSS_STATUS_TRYAGAIN;
}
if (__glibc_unlikely (niserr2nss (result->status) != NSS_STATUS_SUCCESS))
{
enum nss_status status = niserr2nss (result->status);
nis_freeresult (result);
return status;
}
int parse_res = _nss_nisplus_parse_etherent (result, eth, buffer,
buflen, errnop);
/* We do not need the lookup result anymore. */
nis_freeresult (result);
if (__glibc_unlikely (parse_res < 1))
{
if (parse_res == -1)
return NSS_STATUS_TRYAGAIN;
return NSS_STATUS_NOTFOUND;
}
return NSS_STATUS_SUCCESS;
}

View File

@ -1,401 +0,0 @@
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
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 <atomic.h>
#include <nss.h>
#include <grp.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <libc-lock.h>
#include <rpcsvc/nis.h>
#include "nss-nisplus.h"
#include "nisplus-parser.h"
#include <libnsl.h>
#include <nis_intern.h>
#include <nis_xdr.h>
__libc_lock_define_initialized (static, lock);
/* Connection information. */
static ib_request *ibreq;
static directory_obj *dir;
static dir_binding bptr;
static char *tablepath;
static char *tableptr;
/* Cursor. */
static netobj cursor;
nis_name grp_tablename_val attribute_hidden;
size_t grp_tablename_len attribute_hidden;
enum nss_status
_nss_grp_create_tablename (int *errnop)
{
if (grp_tablename_val == NULL)
{
const char *local_dir = nis_local_directory ();
size_t local_dir_len = strlen (local_dir);
static const char prefix[] = "group.org_dir.";
char *p = malloc (sizeof (prefix) + local_dir_len);
if (p == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1);
grp_tablename_len = sizeof (prefix) - 1 + local_dir_len;
atomic_write_barrier ();
if (atomic_compare_and_exchange_bool_acq (&grp_tablename_val, p, NULL))
{
/* Another thread already installed the value. */
free (p);
grp_tablename_len = strlen (grp_tablename_val);
}
}
return NSS_STATUS_SUCCESS;
}
static void
internal_endgrent (void)
{
__nisbind_destroy (&bptr);
memset (&bptr, '\0', sizeof (bptr));
nis_free_directory (dir);
dir = NULL;
nis_free_request (ibreq);
ibreq = NULL;
xdr_free ((xdrproc_t) xdr_netobj, (char *) &cursor);
memset (&cursor, '\0', sizeof (cursor));
free (tablepath);
tableptr = tablepath = NULL;
}
static enum nss_status
internal_setgrent (int *errnop)
{
enum nss_status status = NSS_STATUS_SUCCESS;
if (grp_tablename_val == NULL)
status = _nss_grp_create_tablename (errnop);
if (status == NSS_STATUS_SUCCESS)
{
ibreq = __create_ib_request (grp_tablename_val, 0);
if (ibreq == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
nis_error retcode = __prepare_niscall (grp_tablename_val, &dir, &bptr, 0);
if (retcode != NIS_SUCCESS)
{
nis_free_request (ibreq);
ibreq = NULL;
status = niserr2nss (retcode);
}
}
return status;
}
enum nss_status
_nss_nisplus_setgrent (int stayopen)
{
enum nss_status status;
__libc_lock_lock (lock);
internal_endgrent ();
// XXX We need to be able to set errno. Pass in new parameter.
int err;
status = internal_setgrent (&err);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_endgrent (void)
{
__libc_lock_lock (lock);
internal_endgrent ();
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_getgrent_r (struct group *gr, char *buffer, size_t buflen,
int *errnop)
{
int parse_res = -1;
enum nss_status retval = NSS_STATUS_SUCCESS;
/* Get the next entry until we found a correct one. */
do
{
nis_error status;
nis_result result;
memset (&result, '\0', sizeof (result));
if (cursor.n_bytes == NULL)
{
if (ibreq == NULL)
{
retval = internal_setgrent (errnop);
if (retval != NSS_STATUS_SUCCESS)
return retval;
}
status = __do_niscall3 (&bptr, NIS_IBFIRST,
(xdrproc_t) _xdr_ib_request,
(caddr_t) ibreq,
(xdrproc_t) _xdr_nis_result,
(caddr_t) &result,
0, NULL);
}
else
{
ibreq->ibr_cookie.n_bytes = cursor.n_bytes;
ibreq->ibr_cookie.n_len = cursor.n_len;
status = __do_niscall3 (&bptr, NIS_IBNEXT,
(xdrproc_t) _xdr_ib_request,
(caddr_t) ibreq,
(xdrproc_t) _xdr_nis_result,
(caddr_t) &result,
0, NULL);
ibreq->ibr_cookie.n_bytes = NULL;
ibreq->ibr_cookie.n_len = 0;
}
if (status != NIS_SUCCESS)
return niserr2nss (status);
if (NIS_RES_STATUS (&result) == NIS_NOTFOUND)
{
/* No more entries on this server. This means we have to go
to the next server on the path. */
status = __follow_path (&tablepath, &tableptr, ibreq, &bptr);
if (status != NIS_SUCCESS)
return niserr2nss (status);
directory_obj *newdir = NULL;
dir_binding newbptr;
status = __prepare_niscall (ibreq->ibr_name, &newdir, &newbptr, 0);
if (status != NIS_SUCCESS)
return niserr2nss (status);
nis_free_directory (dir);
dir = newdir;
__nisbind_destroy (&bptr);
bptr = newbptr;
xdr_free ((xdrproc_t) xdr_netobj, (char *) &result.cookie);
result.cookie.n_bytes = NULL;
result.cookie.n_len = 0;
parse_res = 0;
goto next;
}
else if (NIS_RES_STATUS (&result) != NIS_SUCCESS)
return niserr2nss (NIS_RES_STATUS (&result));
parse_res = _nss_nisplus_parse_grent (&result, gr,
buffer, buflen, errnop);
if (__glibc_unlikely (parse_res == -1))
{
*errnop = ERANGE;
retval = NSS_STATUS_TRYAGAIN;
goto freeres;
}
next:
/* Free the old cursor. */
xdr_free ((xdrproc_t) xdr_netobj, (char *) &cursor);
/* Remember the new one. */
cursor.n_bytes = result.cookie.n_bytes;
cursor.n_len = result.cookie.n_len;
/* Free the result structure. NB: we do not remove the cookie. */
result.cookie.n_bytes = NULL;
result.cookie.n_len = 0;
freeres:
xdr_free ((xdrproc_t) _xdr_nis_result, (char *) &result);
memset (&result, '\0', sizeof (result));
}
while (!parse_res);
return retval;
}
enum nss_status
_nss_nisplus_getgrent_r (struct group *result, char *buffer, size_t buflen,
int *errnop)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_getgrent_r (result, buffer, buflen, errnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_getgrnam_r (const char *name, struct group *gr,
char *buffer, size_t buflen, int *errnop)
{
int parse_res;
if (grp_tablename_val == NULL)
{
enum nss_status status = _nss_grp_create_tablename (errnop);
if (status != NSS_STATUS_SUCCESS)
return status;
}
if (name == NULL)
{
*errnop = EINVAL;
return NSS_STATUS_NOTFOUND;
}
nis_result *result;
char buf[strlen (name) + 9 + grp_tablename_len];
int olderr = errno;
snprintf (buf, sizeof (buf), "[name=%s],%s", name, grp_tablename_val);
result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
if (result == NULL)
{
*errnop = ENOMEM;
return NSS_STATUS_TRYAGAIN;
}
if (__glibc_unlikely (niserr2nss (result->status) != NSS_STATUS_SUCCESS))
{
enum nss_status status = niserr2nss (result->status);
nis_freeresult (result);
return status;
}
parse_res = _nss_nisplus_parse_grent (result, gr, buffer, buflen, errnop);
nis_freeresult (result);
if (__glibc_unlikely (parse_res < 1))
{
if (parse_res == -1)
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
else
{
__set_errno (olderr);
return NSS_STATUS_NOTFOUND;
}
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getgrgid_r (const gid_t gid, struct group *gr,
char *buffer, size_t buflen, int *errnop)
{
if (grp_tablename_val == NULL)
{
enum nss_status status = _nss_grp_create_tablename (errnop);
if (status != NSS_STATUS_SUCCESS)
return status;
}
int parse_res;
nis_result *result;
char buf[8 + 3 * sizeof (unsigned long int) + grp_tablename_len];
int olderr = errno;
snprintf (buf, sizeof (buf), "[gid=%lu],%s",
(unsigned long int) gid, grp_tablename_val);
result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (result == NULL)
{
*errnop = ENOMEM;
return NSS_STATUS_TRYAGAIN;
}
if (__glibc_unlikely (niserr2nss (result->status) != NSS_STATUS_SUCCESS))
{
enum nss_status status = niserr2nss (result->status);
__set_errno (olderr);
nis_freeresult (result);
return status;
}
parse_res = _nss_nisplus_parse_grent (result, gr, buffer, buflen, errnop);
nis_freeresult (result);
if (__glibc_unlikely (parse_res < 1))
{
__set_errno (olderr);
if (parse_res == -1)
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
else
return NSS_STATUS_NOTFOUND;
}
return NSS_STATUS_SUCCESS;
}

View File

@ -1,584 +0,0 @@
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
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 <assert.h>
#include <atomic.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <nss.h>
#include <string.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <rpcsvc/nis.h>
#include <libc-lock.h>
#include "nss-nisplus.h"
__libc_lock_define_initialized (static, lock)
static nis_result *result;
static nis_name tablename_val;
static u_long tablename_len;
#define NISENTRYVAL(idx, col, res) \
(NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
#define NISENTRYLEN(idx, col, res) \
(NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
static int
_nss_nisplus_parse_hostent (nis_result *result, int af, struct hostent *host,
char *buffer, size_t buflen, int *errnop)
{
unsigned int i;
char *first_unused = buffer;
size_t room_left = buflen;
if (result == NULL)
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
|| __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
|| strcmp (NIS_RES_OBJECT (result)[0].EN_data.en_type, "hosts_tbl") != 0
|| NIS_RES_OBJECT (result)[0].EN_data.en_cols.en_cols_len < 4)
return 0;
char *data = first_unused;
if (room_left < (af != AF_INET ? IN6ADDRSZ : INADDRSZ))
{
no_more_room:
*errnop = ERANGE;
return -1;
}
/* Parse address. */
if (af != AF_INET6
&& inet_pton (AF_INET, NISENTRYVAL (0, 2, result), data) > 0)
{
host->h_addrtype = AF_INET;
host->h_length = INADDRSZ;
}
else if (af != AF_INET
&& inet_pton (AF_INET6, NISENTRYVAL (0, 2, result), data) > 0)
{
host->h_addrtype = AF_INET6;
host->h_length = IN6ADDRSZ;
}
else
/* Illegal address: ignore line. */
return 0;
first_unused += host->h_length;
room_left -= host->h_length;
if (NISENTRYLEN (0, 0, result) + 1 > room_left)
goto no_more_room;
host->h_name = first_unused;
first_unused = __stpncpy (first_unused, NISENTRYVAL (0, 0, result),
NISENTRYLEN (0, 0, result));
*first_unused++ = '\0';
room_left -= NISENTRYLEN (0, 0, result) + 1;
char *line = first_unused;
/* When this is a call to gethostbyname4_r we do not need the aliases. */
if (af != AF_UNSPEC)
{
/* XXX Rewrite at some point to allocate the array first and then
copy the strings. It is wasteful to first concatenate the strings
to just split them again later. */
for (i = 0; i < NIS_RES_NUMOBJ (result); ++i)
{
if (strcmp (NISENTRYVAL (i, 1, result), host->h_name) != 0)
{
if (NISENTRYLEN (i, 1, result) + 2 > room_left)
goto no_more_room;
*first_unused++ = ' ';
first_unused = __stpncpy (first_unused,
NISENTRYVAL (i, 1, result),
NISENTRYLEN (i, 1, result));
*first_unused = '\0';
room_left -= NISENTRYLEN (i, 1, result) + 1;
}
}
*first_unused++ = '\0';
}
/* Adjust the pointer so it is aligned for
storing pointers. */
size_t adjust = ((__alignof__ (char *)
- (first_unused - (char *) 0) % __alignof__ (char *))
% __alignof__ (char *));
if (room_left < adjust + 3 * sizeof (char *))
goto no_more_room;
first_unused += adjust;
room_left -= adjust;
host->h_addr_list = (char **) first_unused;
room_left -= 3 * sizeof (char *);
host->h_addr_list[0] = data;
host->h_addr_list[1] = NULL;
host->h_aliases = &host->h_addr_list[2];
/* When this is a call to gethostbyname4_r we do not need the aliases. */
if (af != AF_UNSPEC)
{
i = 0;
while (*line != '\0')
{
/* Skip leading blanks. */
while (isspace (*line))
++line;
if (*line == '\0')
break;
if (room_left < sizeof (char *))
goto no_more_room;
room_left -= sizeof (char *);
host->h_aliases[i++] = line;
while (*line != '\0' && *line != ' ')
++line;
if (*line == ' ')
*line++ = '\0';
}
host->h_aliases[i] = NULL;
}
return 1;
}
static enum nss_status
_nss_create_tablename (int *errnop)
{
if (tablename_val == NULL)
{
const char *local_dir = nis_local_directory ();
size_t local_dir_len = strlen (local_dir);
static const char prefix[] = "hosts.org_dir.";
char *p = malloc (sizeof (prefix) + local_dir_len);
if (p == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1);
tablename_len = sizeof (prefix) - 1 + local_dir_len;
atomic_write_barrier ();
tablename_val = p;
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_sethostent (int stayopen)
{
enum nss_status status = NSS_STATUS_SUCCESS;
int err;
__libc_lock_lock (lock);
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
if (tablename_val == NULL)
status = _nss_create_tablename (&err);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_endhostent (void)
{
__libc_lock_lock (lock);
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_gethostent_r (struct hostent *host, char *buffer,
size_t buflen, int *errnop, int *herrnop)
{
int parse_res;
/* Get the next entry until we found a correct one. */
do
{
nis_result *saved_res;
if (result == NULL)
{
saved_res = NULL;
if (tablename_val == NULL)
{
enum nss_status status = _nss_create_tablename (errnop);
if (status != NSS_STATUS_SUCCESS)
return status;
}
result = nis_first_entry (tablename_val);
if (result == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
enum nss_status retval = niserr2nss (result->status);
if (retval == NSS_STATUS_TRYAGAIN)
{
*herrnop = NETDB_INTERNAL;
*errnop = errno;
}
return retval;
}
}
else
{
saved_res = result;
result = nis_next_entry (tablename_val, &result->cookie);
if (result == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
enum nss_status retval= niserr2nss (result->status);
nis_freeresult (result);
result = saved_res;
if (retval == NSS_STATUS_TRYAGAIN)
{
*herrnop = NETDB_INTERNAL;
*errnop = errno;
}
return retval;
}
}
parse_res = _nss_nisplus_parse_hostent (result, AF_INET, host, buffer,
buflen, errnop);
if (parse_res == -1)
{
nis_freeresult (result);
result = saved_res;
*herrnop = NETDB_INTERNAL;
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
if (saved_res != NULL)
nis_freeresult (saved_res);
} while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_gethostent_r (struct hostent *result, char *buffer,
size_t buflen, int *errnop, int *herrnop)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_gethostent_r (result, buffer, buflen, errnop,
herrnop);
__libc_lock_unlock (lock);
return status;
}
static enum nss_status
get_tablename (int *herrnop)
{
__libc_lock_lock (lock);
enum nss_status status = _nss_create_tablename (herrnop);
__libc_lock_unlock (lock);
if (status != NSS_STATUS_SUCCESS)
*herrnop = NETDB_INTERNAL;
return status;
}
static enum nss_status
internal_gethostbyname2_r (const char *name, int af, struct hostent *host,
char *buffer, size_t buflen, int *errnop,
int *herrnop)
{
if (tablename_val == NULL)
{
enum nss_status status = get_tablename (herrnop);
if (status != NSS_STATUS_SUCCESS)
return status;
}
if (name == NULL)
{
*errnop = EINVAL;
*herrnop = NETDB_INTERNAL;
return NSS_STATUS_NOTFOUND;
}
char buf[strlen (name) + 10 + tablename_len];
int olderr = errno;
/* Search at first in the alias list, and use the correct name
for the next search. */
snprintf (buf, sizeof (buf), "[name=%s],%s", name, tablename_val);
nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (result != NULL)
{
/* If we did not find it, try it as original name. But if the
database is correct, we should find it in the first case, too. */
char *bufptr = buf;
size_t buflen = sizeof (buf);
if ((result->status == NIS_SUCCESS || result->status == NIS_S_SUCCESS)
&& __type_of (result->objects.objects_val) == NIS_ENTRY_OBJ
&& strcmp (result->objects.objects_val->EN_data.en_type,
"hosts_tbl") == 0
&& result->objects.objects_val->EN_data.en_cols.en_cols_len >= 3)
{
/* We need to allocate a new buffer since there is no
guarantee the returned alias name has a length limit. */
name = NISENTRYVAL(0, 0, result);
size_t buflen = strlen (name) + 10 + tablename_len;
bufptr = alloca (buflen);
}
snprintf (bufptr, buflen, "[cname=%s],%s", name, tablename_val);
nis_freeresult (result);
result = nis_list (bufptr, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
}
if (result == NULL)
{
*errnop = ENOMEM;
*herrnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
int retval = niserr2nss (result->status);
if (__glibc_unlikely (retval != NSS_STATUS_SUCCESS))
{
if (retval == NSS_STATUS_TRYAGAIN)
{
*errnop = errno;
*herrnop = TRY_AGAIN;
}
else
{
__set_errno (olderr);
*herrnop = NETDB_INTERNAL;
}
nis_freeresult (result);
return retval;
}
int parse_res = _nss_nisplus_parse_hostent (result, af, host, buffer,
buflen, errnop);
nis_freeresult (result);
if (parse_res > 0)
return NSS_STATUS_SUCCESS;
*herrnop = NETDB_INTERNAL;
if (parse_res == -1)
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
__set_errno (olderr);
return NSS_STATUS_NOTFOUND;
}
enum nss_status
_nss_nisplus_gethostbyname2_r (const char *name, int af, struct hostent *host,
char *buffer, size_t buflen, int *errnop,
int *herrnop)
{
if (af != AF_INET && af != AF_INET6)
{
*herrnop = HOST_NOT_FOUND;
return NSS_STATUS_NOTFOUND;
}
return internal_gethostbyname2_r (name, af, host, buffer, buflen, errnop,
herrnop);
}
enum nss_status
_nss_nisplus_gethostbyname_r (const char *name, struct hostent *host,
char *buffer, size_t buflen, int *errnop,
int *h_errnop)
{
return internal_gethostbyname2_r (name, AF_INET, host, buffer,
buflen, errnop, h_errnop);
}
enum nss_status
_nss_nisplus_gethostbyaddr_r (const void *addr, socklen_t addrlen, int af,
struct hostent *host, char *buffer,
size_t buflen, int *errnop, int *herrnop)
{
if (tablename_val == NULL)
{
enum nss_status status = get_tablename (herrnop);
if (status != NSS_STATUS_SUCCESS)
return status;
}
if (addr == NULL)
return NSS_STATUS_NOTFOUND;
char buf[24 + tablename_len];
int retval, parse_res;
int olderr = errno;
snprintf (buf, sizeof (buf), "[addr=%s],%s",
inet_ntoa (*(const struct in_addr *) addr), tablename_val);
nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (result == NULL)
{
__set_errno (ENOMEM);
return NSS_STATUS_TRYAGAIN;
}
retval = niserr2nss (result->status);
if (__glibc_unlikely (retval != NSS_STATUS_SUCCESS))
{
if (retval == NSS_STATUS_TRYAGAIN)
{
*errnop = errno;
*herrnop = NETDB_INTERNAL;
}
else
__set_errno (olderr);
nis_freeresult (result);
return retval;
}
parse_res = _nss_nisplus_parse_hostent (result, af, host,
buffer, buflen, errnop);
nis_freeresult (result);
if (parse_res > 0)
return NSS_STATUS_SUCCESS;
*herrnop = NETDB_INTERNAL;
if (parse_res == -1)
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
__set_errno (olderr);
return NSS_STATUS_NOTFOUND;
}
enum nss_status
_nss_nisplus_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
char *buffer, size_t buflen, int *errnop,
int *herrnop, int32_t *ttlp)
{
struct hostent host;
enum nss_status status = internal_gethostbyname2_r (name, AF_UNSPEC, &host,
buffer, buflen,
errnop, herrnop);
if (__glibc_likely (status == NSS_STATUS_SUCCESS))
{
if (*pat == NULL)
{
uintptr_t pad = (-(uintptr_t) buffer
% __alignof__ (struct gaih_addrtuple));
buffer += pad;
buflen = buflen > pad ? buflen - pad : 0;
if (__glibc_unlikely (buflen < sizeof (struct gaih_addrtuple)))
{
free (result);
*errnop = ERANGE;
*herrnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
}
(*pat)->next = NULL;
(*pat)->name = host.h_name;
(*pat)->family = host.h_addrtype;
memcpy ((*pat)->addr, host.h_addr_list[0], host.h_length);
(*pat)->scopeid = 0;
assert (host.h_addr_list[1] == NULL);
}
return status;
}

View File

@ -1,148 +0,0 @@
/* Copyright (C) 1997-2020 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 <atomic.h>
#include <nss.h>
#include <grp.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <libc-lock.h>
#include <rpcsvc/nis.h>
#include "nss-nisplus.h"
#include "nisplus-parser.h"
#include <libnsl.h>
#include <nis_intern.h>
#include <nis_xdr.h>
#define NISOBJVAL(col, obj) \
((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
#define NISOBJLEN(col, obj) \
((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
extern nis_name grp_tablename_val attribute_hidden;
extern size_t grp_tablename_len attribute_hidden;
extern enum nss_status _nss_grp_create_tablename (int *errnop);
enum nss_status
_nss_nisplus_initgroups_dyn (const char *user, gid_t group, long int *start,
long int *size, gid_t **groupsp, long int limit,
int *errnop)
{
if (grp_tablename_val == NULL)
{
enum nss_status status = _nss_grp_create_tablename (errnop);
if (status != NSS_STATUS_SUCCESS)
return status;
}
nis_result *result;
char buf[strlen (user) + 12 + grp_tablename_len];
snprintf (buf, sizeof (buf), "[members=%s],%s", user, grp_tablename_val);
result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH | ALL_RESULTS, NULL, NULL);
if (result == NULL)
{
*errnop = ENOMEM;
return NSS_STATUS_TRYAGAIN;
}
if (__glibc_unlikely (niserr2nss (result->status) != NSS_STATUS_SUCCESS))
{
enum nss_status status = niserr2nss (result->status);
nis_freeresult (result);
return status;
}
if (NIS_RES_NUMOBJ (result) == 0)
{
errout:
nis_freeresult (result);
return NSS_STATUS_NOTFOUND;
}
gid_t *groups = *groupsp;
nis_object *obj = NIS_RES_OBJECT (result);
for (unsigned int cnt = 0; cnt < NIS_RES_NUMOBJ (result); ++cnt, ++obj)
{
if (__type_of (obj) != NIS_ENTRY_OBJ
|| strcmp (obj->EN_data.en_type, "group_tbl") != 0
|| obj->EN_data.en_cols.en_cols_len < 4)
continue;
char *numstr = NISOBJVAL (2, obj);
size_t len = NISOBJLEN (2, obj);
if (len == 0 || numstr[0] == '\0')
continue;
gid_t gid;
char *endp;
if (__glibc_unlikely (numstr[len - 1] != '\0'))
{
char numstrbuf[len + 1];
memcpy (numstrbuf, numstr, len);
numstrbuf[len] = '\0';
gid = strtoul (numstrbuf, &endp, 10);
if (*endp)
continue;
}
else
{
gid = strtoul (numstr, &endp, 10);
if (*endp)
continue;
}
if (gid == group)
continue;
/* Insert this group. */
if (*start == *size)
{
/* Need a bigger buffer. */
long int newsize;
if (limit > 0 && *size == limit)
/* We reached the maximum. */
break;
if (limit <= 0)
newsize = 2 * *size;
else
newsize = MIN (limit, 2 * *size);
gid_t *newgroups = realloc (groups, newsize * sizeof (*groups));
if (newgroups == NULL)
goto errout;
*groupsp = groups = newgroups;
*size = newsize;
}
groups[*start] = gid;
*start += 1;
}
nis_freeresult (result);
return NSS_STATUS_SUCCESS;
}

View File

@ -1,191 +0,0 @@
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
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.h>
#include <errno.h>
#include <ctype.h>
#include <netdb.h>
#include <string.h>
#include <netgroup.h>
#include <rpcsvc/nis.h>
#include "nss-nisplus.h"
#define NISENTRYVAL(idx, col, res) \
(NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
#define NISENTRYLEN(idx, col, res) \
(NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
enum nss_status
_nss_nisplus_getnetgrent_r (struct __netgrent *result, char *buffer,
size_t buflen, int *errnop)
{
enum nss_status status;
/* Some sanity checks. */
if (result->data == NULL || result->data_size == 0)
return NSS_STATUS_NOTFOUND;
if (result->position == result->data_size)
return result->first ? NSS_STATUS_NOTFOUND : NSS_STATUS_RETURN;
unsigned int entrylen
= NISENTRYLEN (result->position, 1, (nis_result *) result->data);
if (entrylen > 0)
{
/* We have a list of other netgroups. */
result->type = group_val;
if (entrylen >= buflen)
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
strncpy (buffer, NISENTRYVAL (result->position, 1,
(nis_result *) result->data),
entrylen);
buffer[entrylen] = '\0';
result->val.group = buffer;
++result->position;
result->first = 0;
return NSS_STATUS_SUCCESS;
}
/* Before we can copy the entry to the private buffer we have to make
sure it is big enough. */
unsigned int hostlen
= NISENTRYLEN (result->position, 2, (nis_result *) result->data);
unsigned int userlen
= NISENTRYLEN (result->position, 3, (nis_result *) result->data);
unsigned int domainlen
= NISENTRYLEN (result->position, 4, (nis_result *) result->data);
if (hostlen + userlen + domainlen + 6 > buflen)
{
*errnop = ERANGE;
status = NSS_STATUS_TRYAGAIN;
}
else
{
char *cp = buffer;
result->type = triple_val;
if (hostlen == 0
|| NISENTRYVAL (result->position, 2,
(nis_result *) result->data)[0] == '\0')
result->val.triple.host = NULL;
else
{
result->val.triple.host = cp;
cp = __stpncpy (cp, NISENTRYVAL (result->position, 2,
(nis_result *) result->data),
hostlen);
*cp++ = '\0';
}
if (userlen == 0
|| NISENTRYVAL (result->position, 3,
(nis_result *) result->data)[0] == '\0')
result->val.triple.user = NULL;
else
{
result->val.triple.user = cp;
cp = __stpncpy (cp, NISENTRYVAL (result->position, 3,
(nis_result *) result->data),
userlen);
*cp++ = '\0';
}
if (domainlen == 0
|| NISENTRYVAL (result->position, 4,
(nis_result *) result->data)[0] == '\0')
result->val.triple.domain = NULL;
else
{
result->val.triple.domain = cp;
cp = __stpncpy (cp, NISENTRYVAL (result->position, 4,
(nis_result *) result->data),
domainlen);
*cp = '\0';
}
status = NSS_STATUS_SUCCESS;
/* Remember where we stopped reading. */
++result->position;
result->first = 0;
}
return status;
}
static void
internal_endnetgrent (struct __netgrent *netgrp)
{
nis_freeresult ((nis_result *) netgrp->data);
netgrp->data = NULL;
netgrp->data_size = 0;
netgrp->position = 0;
}
enum nss_status
_nss_nisplus_setnetgrent (const char *group, struct __netgrent *netgrp)
{
char buf[strlen (group) + 25];
if (group == NULL || group[0] == '\0')
return NSS_STATUS_UNAVAIL;
enum nss_status status = NSS_STATUS_SUCCESS;
snprintf (buf, sizeof (buf), "[name=%s],netgroup.org_dir", group);
netgrp->data = (char *) nis_list (buf, EXPAND_NAME, NULL, NULL);
if (netgrp->data == NULL)
{
__set_errno (ENOMEM);
status = NSS_STATUS_TRYAGAIN;
}
else if (niserr2nss (((nis_result *) netgrp->data)->status)
!= NSS_STATUS_SUCCESS)
{
status = niserr2nss (((nis_result *) netgrp->data)->status);
internal_endnetgrent (netgrp);
}
else
{
netgrp->data_size = ((nis_result *) netgrp->data)->objects.objects_len;
netgrp->position = 0;
netgrp->first = 1;
}
return status;
}
enum nss_status
_nss_nisplus_endnetgrent (struct __netgrent *netgrp)
{
internal_endnetgrent (netgrp);
return NSS_STATUS_SUCCESS;
}

View File

@ -1,494 +0,0 @@
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
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 <atomic.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <nss.h>
#include <stdint.h>
#include <string.h>
#include <arpa/inet.h>
#include <rpcsvc/nis.h>
#include <libc-lock.h>
#include "nss-nisplus.h"
__libc_lock_define_initialized (static, lock)
static nis_result *result;
static nis_name tablename_val;
static u_long tablename_len;
#define NISENTRYVAL(idx, col, res) \
(NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
#define NISENTRYLEN(idx, col, res) \
(NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
static int
_nss_nisplus_parse_netent (nis_result *result, struct netent *network,
char *buffer, size_t buflen, int *errnop)
{
char *first_unused = buffer;
size_t room_left = buflen;
if (result == NULL)
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
|| __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
|| strcmp (NIS_RES_OBJECT (result)[0].EN_data.en_type,
"networks_tbl") != 0
|| NIS_RES_OBJECT (result)[0].EN_data.en_cols.en_cols_len < 3)
return 0;
if (NISENTRYLEN (0, 0, result) >= room_left)
{
/* The line is too long for our buffer. */
no_more_room:
*errnop = ERANGE;
return -1;
}
strncpy (first_unused, NISENTRYVAL (0, 0, result),
NISENTRYLEN (0, 0, result));
first_unused[NISENTRYLEN (0, 0, result)] = '\0';
network->n_name = first_unused;
size_t len = strlen (first_unused) + 1;
room_left -= len;
first_unused += len;
network->n_addrtype = 0;
network->n_net = inet_network (NISENTRYVAL (0, 2, result));
/* XXX Rewrite at some point to allocate the array first and then
copy the strings. It wasteful to first concatenate the strings
to just split them again later. */
char *line = first_unused;
for (unsigned int i = 0; i < NIS_RES_NUMOBJ (result); ++i)
{
if (strcmp (NISENTRYVAL (i, 1, result), network->n_name) != 0)
{
if (NISENTRYLEN (i, 1, result) + 2 > room_left)
goto no_more_room;
*first_unused++ = ' ';
first_unused = __stpncpy (first_unused, NISENTRYVAL (i, 1, result),
NISENTRYLEN (i, 1, result));
room_left -= (NISENTRYLEN (i, 1, result) + 1);
}
}
*first_unused++ = '\0';
/* Adjust the pointer so it is aligned for
storing pointers. */
size_t adjust = ((__alignof__ (char *)
- (first_unused - (char *) 0) % __alignof__ (char *))
% __alignof__ (char *));
if (room_left < adjust + sizeof (char *))
goto no_more_room;
first_unused += adjust;
room_left -= adjust;
network->n_aliases = (char **) first_unused;
/* For the terminating NULL pointer. */
room_left -= sizeof (char *);
unsigned int i = 0;
while (*line != '\0')
{
/* Skip leading blanks. */
while (isspace (*line))
++line;
if (*line == '\0')
break;
if (room_left < sizeof (char *))
goto no_more_room;
room_left -= sizeof (char *);
network->n_aliases[i++] = line;
while (*line != '\0' && *line != ' ')
++line;
if (*line == ' ')
*line++ = '\0';
}
network->n_aliases[i] = NULL;
return 1;
}
static enum nss_status
_nss_create_tablename (int *errnop)
{
if (tablename_val == NULL)
{
const char *local_dir = nis_local_directory ();
size_t local_dir_len = strlen (local_dir);
static const char prefix[] = "networks.org_dir.";
char *p = malloc (sizeof (prefix) + local_dir_len);
if (p == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1);
tablename_len = sizeof (prefix) - 1 + local_dir_len;
atomic_write_barrier ();
tablename_val = p;
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_setnetent (int stayopen)
{
enum nss_status status = NSS_STATUS_SUCCESS;
__libc_lock_lock (lock);
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
if (tablename_val == NULL)
{
int err;
status = _nss_create_tablename (&err);
}
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_endnetent (void)
{
__libc_lock_lock (lock);
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_getnetent_r (struct netent *network, char *buffer,
size_t buflen, int *errnop, int *herrnop)
{
int parse_res;
/* Get the next entry until we found a correct one. */
do
{
nis_result *saved_res;
if (result == NULL)
{
saved_res = NULL;
if (tablename_val == NULL)
{
enum nss_status status = _nss_create_tablename (errnop);
if (status != NSS_STATUS_SUCCESS)
return status;
}
result = nis_first_entry (tablename_val);
if (result == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
int retval = niserr2nss (result->status);
nis_freeresult (result);
result = NULL;
if (retval == NSS_STATUS_TRYAGAIN)
{
*herrnop = NETDB_INTERNAL;
*errnop = errno;
return retval;
}
else
return retval;
}
}
else
{
saved_res = result;
result = nis_next_entry (tablename_val, &result->cookie);
if (result == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
int retval = niserr2nss (result->status);
nis_freeresult (result);
result = saved_res;
if (retval == NSS_STATUS_TRYAGAIN)
{
*herrnop = NETDB_INTERNAL;
*errnop = errno;
}
return retval;
}
}
parse_res = _nss_nisplus_parse_netent (result, network, buffer,
buflen, errnop);
if (parse_res == -1)
{
*herrnop = NETDB_INTERNAL;
return NSS_STATUS_TRYAGAIN;
}
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getnetent_r (struct netent *result, char *buffer,
size_t buflen, int *errnop, int *herrnop)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_getnetent_r (result, buffer, buflen, errnop,
herrnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_getnetbyname_r (const char *name, struct netent *network,
char *buffer, size_t buflen, int *errnop,
int *herrnop)
{
int parse_res, retval;
if (tablename_val == NULL)
{
__libc_lock_lock (lock);
enum nss_status status = _nss_create_tablename (errnop);
__libc_lock_unlock (lock);
if (status != NSS_STATUS_SUCCESS)
return status;
}
if (name == NULL)
{
*errnop = EINVAL;
*herrnop = NETDB_INTERNAL;
return NSS_STATUS_UNAVAIL;
}
nis_result *result;
char buf[strlen (name) + 10 + tablename_len];
int olderr = errno;
/* Search at first in the alias list, and use the correct name
for the next search */
snprintf (buf, sizeof (buf), "[name=%s],%s", name, tablename_val);
result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH | USE_DGRAM, NULL, NULL);
if (result != NULL)
{
char *bufptr = buf;
/* If we do not find it, try it as original name. But if the
database is correct, we should find it in the first case, too */
if ((result->status != NIS_SUCCESS
&& result->status != NIS_S_SUCCESS)
|| __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ
|| strcmp (result->objects.objects_val[0].EN_data.en_type,
"networks_tbl") != 0
|| (result->objects.objects_val[0].EN_data.en_cols.en_cols_len
< 3))
snprintf (buf, sizeof (buf), "[cname=%s],%s", name, tablename_val);
else
{
/* We need to allocate a new buffer since there is no
guarantee the returned name has a length limit. */
const char *entryval = NISENTRYVAL (0, 0, result);
size_t buflen = strlen (entryval) + 10 + tablename_len;
bufptr = alloca (buflen);
snprintf (bufptr, buflen, "[cname=%s],%s",
entryval, tablename_val);
}
nis_freeresult (result);
result = nis_list (bufptr, FOLLOW_LINKS | FOLLOW_PATH | USE_DGRAM,
NULL, NULL);
}
if (result == NULL)
{
__set_errno (ENOMEM);
return NSS_STATUS_TRYAGAIN;
}
retval = niserr2nss (result->status);
if (__glibc_unlikely (retval != NSS_STATUS_SUCCESS))
{
if (retval == NSS_STATUS_TRYAGAIN)
{
*errnop = errno;
*herrnop = NETDB_INTERNAL;
}
else
__set_errno (olderr);
nis_freeresult (result);
return retval;
}
parse_res = _nss_nisplus_parse_netent (result, network, buffer, buflen,
errnop);
nis_freeresult (result);
if (parse_res > 0)
return NSS_STATUS_SUCCESS;
*herrnop = NETDB_INTERNAL;
if (parse_res == -1)
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
__set_errno (olderr);
return NSS_STATUS_NOTFOUND;
}
/* XXX type is ignored, SUN's NIS+ table doesn't support it */
enum nss_status
_nss_nisplus_getnetbyaddr_r (uint32_t addr, const int type,
struct netent *network, char *buffer,
size_t buflen, int *errnop, int *herrnop)
{
if (tablename_val == NULL)
{
__libc_lock_lock (lock);
enum nss_status status = _nss_create_tablename (errnop);
__libc_lock_unlock (lock);
if (status != NSS_STATUS_SUCCESS)
return status;
}
{
char buf[27 + tablename_len];
char buf2[18];
int olderr = errno;
struct in_addr in = { .s_addr = htonl (addr) };
strcpy (buf2, inet_ntoa (in));
size_t b2len = strlen (buf2);
while (1)
{
snprintf (buf, sizeof (buf), "[addr=%s],%s", buf2, tablename_val);
nis_result *result = nis_list (buf, EXPAND_NAME | USE_DGRAM,
NULL, NULL);
if (result == NULL)
{
__set_errno (ENOMEM);
return NSS_STATUS_TRYAGAIN;
}
enum nss_status retval = niserr2nss (result->status);
if (__glibc_unlikely (retval != NSS_STATUS_SUCCESS))
{
if (b2len > 2 && buf2[b2len - 2] == '.' && buf2[b2len - 1] == '0')
{
/* Try again, but with trailing dot(s)
removed (one by one) */
buf2[b2len - 2] = '\0';
b2len -= 2;
nis_freeresult (result);
continue;
}
if (retval == NSS_STATUS_TRYAGAIN)
{
*errnop = errno;
*herrnop = NETDB_INTERNAL;
}
else
__set_errno (olderr);
nis_freeresult (result);
return retval;
}
int parse_res = _nss_nisplus_parse_netent (result, network, buffer,
buflen, errnop);
nis_freeresult (result);
if (parse_res > 0)
return NSS_STATUS_SUCCESS;
*herrnop = NETDB_INTERNAL;
if (parse_res == -1)
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
else
{
__set_errno (olderr);
return NSS_STATUS_NOTFOUND;
}
}
}
}

View File

@ -1,375 +0,0 @@
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
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 <pwd.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <rpcsvc/nis.h>
#include "nisplus-parser.h"
#define NISENTRYVAL(idx, col, res) \
(NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
#define NISENTRYLEN(idx, col, res) \
(NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
#define NISOBJVAL(col, obj) \
((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
#define NISOBJLEN(col, obj) \
((obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
int
_nss_nisplus_parse_pwent (nis_result *result, struct passwd *pw,
char *buffer, size_t buflen, int *errnop)
{
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
|| NIS_RES_NUMOBJ (result) != 1
|| __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
|| strcmp (NIS_RES_OBJECT (result)->EN_data.en_type, "passwd_tbl") != 0
|| NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 7)
return 0;
nis_object *obj = NIS_RES_OBJECT (result);
char *first_unused = buffer;
size_t room_left = buflen;
size_t len;
if (NISOBJLEN (0, obj) >= room_left)
{
/* The line is too long for our buffer. */
no_more_room:
*errnop = ERANGE;
return -1;
}
strncpy (first_unused, NISOBJVAL (0, obj), NISOBJLEN (0, obj));
first_unused[NISOBJLEN (0, obj)] = '\0';
len = strlen (first_unused);
if (len == 0) /* No name ? Should never happen, database is corrupt */
return 0;
pw->pw_name = first_unused;
room_left -= len + 1;
first_unused += len + 1;
if (NISOBJLEN (1, obj) >= room_left)
goto no_more_room;
strncpy (first_unused, NISOBJVAL (1, obj), NISOBJLEN (1, obj));
first_unused[NISOBJLEN (1, obj)] = '\0';
pw->pw_passwd = first_unused;
len = strlen (first_unused);
room_left -= len + 1;
first_unused += len + 1;
char *numstr = NISOBJVAL (2, obj);
len = NISOBJLEN (2, obj);
if (len == 0 || numstr[len - 1] != '\0')
{
if (len >= room_left)
goto no_more_room;
strncpy (first_unused, numstr, len);
first_unused[len] = '\0';
numstr = first_unused;
}
if (numstr[0] == '\0')
/* If we don't have a uid, it's an invalid shadow entry. */
return 0;
pw->pw_uid = strtoul (numstr, NULL, 10);
numstr = NISOBJVAL (3, obj);
len = NISOBJLEN (3, obj);
if (len == 0 || numstr[len - 1] != '\0')
{
if (len >= room_left)
goto no_more_room;
strncpy (first_unused, numstr, len);
first_unused[len] = '\0';
numstr = first_unused;
}
if (numstr[0] == '\0')
/* If we don't have a gid, it's an invalid shadow entry. */
return 0;
pw->pw_gid = strtoul (numstr, NULL, 10);
if (NISOBJLEN(4, obj) >= room_left)
goto no_more_room;
strncpy (first_unused, NISOBJVAL (4, obj), NISOBJLEN (4, obj));
first_unused[NISOBJLEN (4, obj)] = '\0';
pw->pw_gecos = first_unused;
len = strlen (first_unused);
room_left -= len + 1;
first_unused += len + 1;
if (NISOBJLEN (5, obj) >= room_left)
goto no_more_room;
strncpy (first_unused, NISOBJVAL (5, obj), NISOBJLEN (5, obj));
first_unused[NISOBJLEN (5, obj)] = '\0';
pw->pw_dir = first_unused;
len = strlen (first_unused);
room_left -= len + 1;
first_unused += len + 1;
if (NISOBJLEN (6, obj) >= room_left)
goto no_more_room;
strncpy (first_unused, NISOBJVAL (6, obj), NISOBJLEN (6, obj));
first_unused[NISOBJLEN (6, obj)] = '\0';
pw->pw_shell = first_unused;
len = strlen (first_unused);
room_left -= len + 1;
first_unused += len + 1;
return 1;
}
int
_nss_nisplus_parse_grent (nis_result *result, struct group *gr,
char *buffer, size_t buflen, int *errnop)
{
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
|| __type_of(NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
|| strcmp (NIS_RES_OBJECT (result)[0].EN_data.en_type, "group_tbl") != 0
|| NIS_RES_OBJECT (result)[0].EN_data.en_cols.en_cols_len < 4)
return 0;
nis_object *obj = NIS_RES_OBJECT (result);
char *first_unused = buffer;
size_t room_left = buflen;
char *line;
int count;
size_t len;
if (NISOBJLEN (0, obj) >= room_left)
{
/* The line is too long for our buffer. */
no_more_room:
*errnop = ERANGE;
return -1;
}
strncpy (first_unused, NISOBJVAL (0, obj), NISOBJLEN (0, obj));
first_unused[NISOBJLEN (0, obj)] = '\0';
len = strlen (first_unused);
if (len == 0) /* group table is corrupt */
return 0;
gr->gr_name = first_unused;
room_left -= len + 1;
first_unused += len + 1;
if (NISOBJLEN (1, obj) >= room_left)
goto no_more_room;
strncpy (first_unused, NISOBJVAL (1, obj), NISOBJLEN (1, obj));
first_unused[NISOBJLEN (1, obj)] = '\0';
gr->gr_passwd = first_unused;
len = strlen (first_unused);
room_left -= len + 1;
first_unused += len + 1;
char *numstr = NISOBJVAL (2, obj);
len = NISOBJLEN (2, obj);
if (len == 0 || numstr[len - 1] != '\0')
{
if (len >= room_left)
goto no_more_room;
strncpy (first_unused, numstr, len);
first_unused[len] = '\0';
numstr = first_unused;
}
if (numstr[0] == '\0')
/* We should always have a gid. */
return 0;
gr->gr_gid = strtoul (numstr, NULL, 10);
if (NISOBJLEN (3, obj) >= room_left)
goto no_more_room;
strncpy (first_unused, NISOBJVAL (3, obj), NISOBJLEN (3, obj));
first_unused[NISOBJLEN (3, obj)] = '\0';
line = first_unused;
len = strlen (line);
room_left -= len + 1;
first_unused += len + 1;
/* Adjust the pointer so it is aligned for
storing pointers. */
size_t adjust = ((__alignof__ (char *)
- (first_unused - (char *) 0) % __alignof__ (char *))
% __alignof__ (char *));
if (room_left < adjust)
goto no_more_room;
first_unused += adjust;
room_left -= adjust;
gr->gr_mem = (char **) first_unused;
count = 0;
while (*line != '\0')
{
/* Skip leading blanks. */
while (isspace (*line))
++line;
if (*line == '\0')
break;
if (room_left < sizeof (char *))
goto no_more_room;
room_left -= sizeof (char *);
gr->gr_mem[count++] = line;
while (*line != '\0' && *line != ',' && !isspace (*line))
++line;
if (*line == ',' || isspace (*line))
{
int is = isspace (*line);
*line++ = '\0';
if (is)
while (*line != '\0' && (*line == ',' || isspace (*line)))
++line;
}
}
if (room_left < sizeof (char *))
goto no_more_room;
room_left -= sizeof (char *);
gr->gr_mem[count] = NULL;
return 1;
}
int
_nss_nisplus_parse_spent (nis_result *result, struct spwd *sp,
char *buffer, size_t buflen, int *errnop)
{
char *first_unused = buffer;
size_t room_left = buflen;
size_t len;
if (result == NULL)
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
|| NIS_RES_NUMOBJ (result) != 1
|| __type_of(NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
|| strcmp (NIS_RES_OBJECT (result)->EN_data.en_type, "passwd_tbl") != 0
|| NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 8)
return 0;
if (NISENTRYLEN (0, 0, result) >= room_left)
{
/* The line is too long for our buffer. */
no_more_room:
*errnop = ERANGE;
return -1;
}
strncpy (first_unused, NISENTRYVAL (0, 0, result),
NISENTRYLEN (0, 0, result));
first_unused[NISENTRYLEN (0, 0, result)] = '\0';
len = strlen (first_unused);
if (len == 0)
return 0;
sp->sp_namp = first_unused;
room_left -= len + 1;
first_unused += len + 1;
if (NISENTRYLEN (0, 1, result) >= room_left)
goto no_more_room;
strncpy (first_unused, NISENTRYVAL (0, 1, result),
NISENTRYLEN (0, 1, result));
first_unused[NISENTRYLEN (0, 1, result)] = '\0';
sp->sp_pwdp = first_unused;
len = strlen (first_unused);
room_left -= len + 1;
first_unused += len + 1;
sp->sp_lstchg = sp->sp_min = sp->sp_max = sp->sp_warn = sp->sp_inact =
sp->sp_expire = -1;
sp->sp_flag = ~0ul;
if (NISENTRYLEN (0, 7, result) > 0)
{
char *line = NISENTRYVAL (0, 7, result);
char *cp = strchr (line, ':');
if (cp == NULL)
return 1;
*cp++ = '\0';
if (*line)
sp->sp_lstchg = atol (line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 1;
*cp++ = '\0';
if (*line)
sp->sp_min = atol (line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 1;
*cp++ = '\0';
if (*line)
sp->sp_max = atol (line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 1;
*cp++ = '\0';
if (*line)
sp->sp_warn = atol (line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 1;
*cp++ = '\0';
if (*line)
sp->sp_inact = atol (line);
line = cp;
cp = strchr (line, ':');
if (cp == NULL)
return 1;
*cp++ = '\0';
if (*line)
sp->sp_expire = atol (line);
line = cp;
if (line == NULL)
return 1;
if (*line)
sp->sp_flag = atol (line);
}
return 1;
}

View File

@ -1,441 +0,0 @@
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
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 <atomic.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <nss.h>
#include <string.h>
#include <rpcsvc/nis.h>
#include <libc-lock.h>
#include "nss-nisplus.h"
__libc_lock_define_initialized (static, lock)
static nis_result *result;
static nis_name tablename_val;
static u_long tablename_len;
#define NISENTRYVAL(idx, col, res) \
(NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
#define NISENTRYLEN(idx, col, res) \
(NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
static int
_nss_nisplus_parse_protoent (nis_result *result, struct protoent *proto,
char *buffer, size_t buflen, int *errnop)
{
char *first_unused = buffer;
size_t room_left = buflen;
unsigned int i;
if (result == NULL)
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
|| __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
|| strcmp (NIS_RES_OBJECT (result)->EN_data.en_type,
"protocols_tbl") != 0
|| NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 3)
return 0;
/* Generate the protocols entry format and use the normal parser */
if (NISENTRYLEN (0, 0, result) + 1 > room_left)
{
no_more_room:
*errnop = ERANGE;
return -1;
}
strncpy (first_unused, NISENTRYVAL (0, 0, result),
NISENTRYLEN (0, 0, result));
first_unused[NISENTRYLEN (0, 0, result)] = '\0';
proto->p_name = first_unused;
size_t len = strlen (first_unused) + 1;
room_left -= len;
first_unused += len;
proto->p_proto = atoi (NISENTRYVAL (0, 2, result));
/* XXX Rewrite at some point to allocate the array first and then
copy the strings. It wasteful to first concatenate the strings
to just split them again later. */
char *line = first_unused;
for (i = 0; i < NIS_RES_NUMOBJ (result); ++i)
{
if (strcmp (NISENTRYVAL (i, 1, result), proto->p_name) != 0)
{
if (NISENTRYLEN (i, 1, result) + 2 > room_left)
goto no_more_room;
*first_unused++ = ' ';
first_unused = __stpncpy (first_unused, NISENTRYVAL (i, 1, result),
NISENTRYLEN (i, 1, result));
room_left -= NISENTRYLEN (i, 1, result) + 1;
}
}
*first_unused++ = '\0';
/* Adjust the pointer so it is aligned for
storing pointers. */
size_t adjust = ((__alignof__ (char *)
- (first_unused - (char *) 0) % __alignof__ (char *))
% __alignof__ (char *));
if (room_left < adjust + sizeof (char *))
goto no_more_room;
first_unused += adjust;
room_left -= adjust;
proto->p_aliases = (char **) first_unused;
/* For the terminating NULL pointer. */
room_left -= sizeof (char *);
i = 0;
while (*line != '\0')
{
/* Skip leading blanks. */
while (isspace (*line))
line++;
if (*line == '\0')
break;
if (room_left < sizeof (char *))
goto no_more_room;
room_left -= sizeof (char *);
proto->p_aliases[i++] = line;
while (*line != '\0' && *line != ' ')
++line;
if (*line == ' ')
*line++ = '\0';
}
proto->p_aliases[i] = NULL;
return 1;
}
static enum nss_status
_nss_create_tablename (int *errnop)
{
if (tablename_val == NULL)
{
const char *local_dir = nis_local_directory ();
size_t local_dir_len = strlen (local_dir);
static const char prefix[] = "protocols.org_dir.";
char *p = malloc (sizeof (prefix) + local_dir_len);
if (p == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1);
tablename_len = sizeof (prefix) - 1 + local_dir_len;
atomic_write_barrier ();
tablename_val = p;
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_setprotoent (int stayopen)
{
enum nss_status status = NSS_STATUS_SUCCESS;
__libc_lock_lock (lock);
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
if (tablename_val == NULL)
{
int err;
status = _nss_create_tablename (&err);
}
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_endprotoent (void)
{
__libc_lock_lock (lock);
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_getprotoent_r (struct protoent *proto, char *buffer,
size_t buflen, int *errnop)
{
int parse_res;
/* Get the next entry until we found a correct one. */
do
{
nis_result *saved_res;
if (result == NULL)
{
saved_res = NULL;
if (tablename_val == NULL)
{
enum nss_status status = _nss_create_tablename (errnop);
if (status != NSS_STATUS_SUCCESS)
return status;
}
result = nis_first_entry (tablename_val);
if (result == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
return niserr2nss (result->status);
}
else
{
saved_res = result;
result = nis_next_entry (tablename_val, &result->cookie);
if (result == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
nis_freeresult (saved_res);
return niserr2nss (result->status);
}
}
parse_res = _nss_nisplus_parse_protoent (result, proto, buffer,
buflen, errnop);
if (parse_res == -1)
{
nis_freeresult (result);
result = saved_res;
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
else
{
if (saved_res)
nis_freeresult (saved_res);
}
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getprotoent_r (struct protoent *result, char *buffer,
size_t buflen, int *errnop)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_getprotoent_r (result, buffer, buflen, errnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_getprotobyname_r (const char *name, struct protoent *proto,
char *buffer, size_t buflen, int *errnop)
{
int parse_res;
if (tablename_val == NULL)
{
__libc_lock_lock (lock);
enum nss_status status = _nss_create_tablename (errnop);
__libc_lock_unlock (lock);
if (status != NSS_STATUS_SUCCESS)
return status;
}
if (name == NULL)
return NSS_STATUS_NOTFOUND;
char buf[strlen (name) + 10 + tablename_len];
int olderr = errno;
/* Search at first in the alias list, and use the correct name
for the next search */
snprintf (buf, sizeof (buf), "[name=%s],%s", name, tablename_val);
nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
if (result != NULL)
{
char *bufptr = buf;
/* If we did not find it, try it as original name. But if the
database is correct, we should find it in the first case, too */
if ((result->status != NIS_SUCCESS
&& result->status != NIS_S_SUCCESS)
|| __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ
|| strcmp (result->objects.objects_val->EN_data.en_type,
"protocols_tbl") != 0
|| result->objects.objects_val->EN_data.en_cols.en_cols_len < 3)
snprintf (buf, sizeof (buf), "[cname=%s],%s", name, tablename_val);
else
{
/* We need to allocate a new buffer since there is no
guarantee the returned name has a length limit. */
const char *entryval = NISENTRYVAL (0, 0, result);
size_t buflen = strlen (entryval) + 10 + tablename_len;
bufptr = alloca (buflen);
snprintf (bufptr, buflen, "[cname=%s],%s",
entryval, tablename_val);
}
nis_freeresult (result);
result = nis_list (bufptr, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
}
if (result == NULL)
{
__set_errno (ENOMEM);
return NSS_STATUS_TRYAGAIN;
}
if (__glibc_unlikely (niserr2nss (result->status) != NSS_STATUS_SUCCESS))
{
enum nss_status status = niserr2nss (result->status);
__set_errno (olderr);
nis_freeresult (result);
return status;
}
parse_res = _nss_nisplus_parse_protoent (result, proto, buffer, buflen,
errnop);
nis_freeresult (result);
if (parse_res < 1)
{
if (parse_res == -1)
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
else
{
__set_errno (olderr);
return NSS_STATUS_NOTFOUND;
}
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getprotobynumber_r (const int number, struct protoent *proto,
char *buffer, size_t buflen, int *errnop)
{
if (tablename_val == NULL)
{
__libc_lock_lock (lock);
enum nss_status status = _nss_create_tablename (errnop);
__libc_lock_unlock (lock);
if (status != NSS_STATUS_SUCCESS)
return status;
}
char buf[12 + 3 * sizeof (number) + tablename_len];
int olderr = errno;
snprintf (buf, sizeof (buf), "[number=%d],%s", number, tablename_val);
nis_result *result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH, NULL, NULL);
if (result == NULL)
{
__set_errno (ENOMEM);
return NSS_STATUS_TRYAGAIN;
}
if (__glibc_unlikely (niserr2nss (result->status) != NSS_STATUS_SUCCESS))
{
enum nss_status status = niserr2nss (result->status);
__set_errno (olderr);
nis_freeresult (result);
return status;
}
int parse_res = _nss_nisplus_parse_protoent (result, proto, buffer, buflen,
errnop);
nis_freeresult (result);
if (parse_res < 1)
{
if (parse_res == -1)
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
else
{
__set_errno (olderr);
return NSS_STATUS_NOTFOUND;
}
}
return NSS_STATUS_SUCCESS;
}

View File

@ -1,408 +0,0 @@
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
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 <atomic.h>
#include <nss.h>
#include <errno.h>
#include <pwd.h>
#include <string.h>
#include <libc-lock.h>
#include <rpcsvc/nis.h>
#include "nss-nisplus.h"
#include "nisplus-parser.h"
#include <libnsl.h>
#include <nis_intern.h>
#include <nis_xdr.h>
__libc_lock_define_initialized (static, lock)
/* Connection information. */
static ib_request *ibreq;
static directory_obj *dir;
static dir_binding bptr;
static char *tablepath;
static char *tableptr;
/* Cursor. */
static netobj cursor;
nis_name pwd_tablename_val attribute_hidden;
size_t pwd_tablename_len attribute_hidden;
enum nss_status
_nss_pwd_create_tablename (int *errnop)
{
if (pwd_tablename_val == NULL)
{
const char *local_dir = nis_local_directory ();
size_t local_dir_len = strlen (local_dir);
static const char prefix[] = "passwd.org_dir.";
char *p = malloc (sizeof (prefix) + local_dir_len);
if (p == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1);
pwd_tablename_len = sizeof (prefix) - 1 + local_dir_len;
atomic_write_barrier ();
if (atomic_compare_and_exchange_bool_acq (&pwd_tablename_val, p, NULL))
{
/* Another thread already installed the value. */
free (p);
pwd_tablename_len = strlen (pwd_tablename_val);
}
}
return NSS_STATUS_SUCCESS;
}
static void
internal_nisplus_endpwent (void)
{
__nisbind_destroy (&bptr);
memset (&bptr, '\0', sizeof (bptr));
nis_free_directory (dir);
dir = NULL;
nis_free_request (ibreq);
ibreq = NULL;
xdr_free ((xdrproc_t) xdr_netobj, (char *) &cursor);
memset (&cursor, '\0', sizeof (cursor));
free (tablepath);
tableptr = tablepath = NULL;
}
static enum nss_status
internal_nisplus_setpwent (int *errnop)
{
enum nss_status status = NSS_STATUS_SUCCESS;
if (pwd_tablename_val == NULL)
status = _nss_pwd_create_tablename (errnop);
if (status == NSS_STATUS_SUCCESS)
{
ibreq = __create_ib_request (pwd_tablename_val, 0);
if (ibreq == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
nis_error retcode = __prepare_niscall (pwd_tablename_val, &dir,
&bptr, 0);
if (retcode != NIS_SUCCESS)
{
nis_free_request (ibreq);
ibreq = NULL;
status = niserr2nss (retcode);
}
}
return status;
}
enum nss_status
_nss_nisplus_setpwent (int stayopen)
{
enum nss_status status;
__libc_lock_lock (lock);
internal_nisplus_endpwent ();
// XXX We need to be able to set errno. Pass in new parameter.
int err;
status = internal_nisplus_setpwent (&err);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_endpwent (void)
{
__libc_lock_lock (lock);
internal_nisplus_endpwent ();
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_getpwent_r (struct passwd *pw, char *buffer, size_t buflen,
int *errnop)
{
int parse_res = -1;
enum nss_status retval = NSS_STATUS_SUCCESS;
/* Get the next entry until we found a correct one. */
do
{
nis_error status;
nis_result result;
memset (&result, '\0', sizeof (result));
if (cursor.n_bytes == NULL)
{
if (ibreq == NULL)
{
retval = internal_nisplus_setpwent (errnop);
if (retval != NSS_STATUS_SUCCESS)
return retval;
}
status = __do_niscall3 (&bptr, NIS_IBFIRST,
(xdrproc_t) _xdr_ib_request,
(caddr_t) ibreq,
(xdrproc_t) _xdr_nis_result,
(caddr_t) &result,
0, NULL);
}
else
{
ibreq->ibr_cookie.n_bytes = cursor.n_bytes;
ibreq->ibr_cookie.n_len = cursor.n_len;
status = __do_niscall3 (&bptr, NIS_IBNEXT,
(xdrproc_t) _xdr_ib_request,
(caddr_t) ibreq,
(xdrproc_t) _xdr_nis_result,
(caddr_t) &result,
0, NULL);
ibreq->ibr_cookie.n_bytes = NULL;
ibreq->ibr_cookie.n_len = 0;
}
if (status != NIS_SUCCESS)
return niserr2nss (status);
if (NIS_RES_STATUS (&result) == NIS_NOTFOUND)
{
/* No more entries on this server. This means we have to go
to the next server on the path. */
status = __follow_path (&tablepath, &tableptr, ibreq, &bptr);
if (status != NIS_SUCCESS)
return niserr2nss (status);
directory_obj *newdir = NULL;
dir_binding newbptr;
status = __prepare_niscall (ibreq->ibr_name, &newdir, &newbptr, 0);
if (status != NIS_SUCCESS)
return niserr2nss (status);
nis_free_directory (dir);
dir = newdir;
__nisbind_destroy (&bptr);
bptr = newbptr;
xdr_free ((xdrproc_t) xdr_netobj, (char *) &result.cookie);
result.cookie.n_bytes = NULL;
result.cookie.n_len = 0;
parse_res = 0;
goto next;
}
else if (NIS_RES_STATUS (&result) != NIS_SUCCESS)
return niserr2nss (NIS_RES_STATUS (&result));
parse_res = _nss_nisplus_parse_pwent (&result, pw, buffer,
buflen, errnop);
if (__glibc_unlikely (parse_res == -1))
{
*errnop = ERANGE;
retval = NSS_STATUS_TRYAGAIN;
goto freeres;
}
next:
/* Free the old cursor. */
xdr_free ((xdrproc_t) xdr_netobj, (char *) &cursor);
/* Remember the new one. */
cursor.n_bytes = result.cookie.n_bytes;
cursor.n_len = result.cookie.n_len;
/* Free the result structure. NB: we do not remove the cookie. */
result.cookie.n_bytes = NULL;
result.cookie.n_len = 0;
freeres:
xdr_free ((xdrproc_t) _xdr_nis_result, (char *) &result);
memset (&result, '\0', sizeof (result));
}
while (!parse_res);
return retval;
}
enum nss_status
_nss_nisplus_getpwent_r (struct passwd *result, char *buffer, size_t buflen,
int *errnop)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_getpwent_r (result, buffer, buflen, errnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_getpwnam_r (const char *name, struct passwd *pw,
char *buffer, size_t buflen, int *errnop)
{
int parse_res;
if (pwd_tablename_val == NULL)
{
enum nss_status status = _nss_pwd_create_tablename (errnop);
if (status != NSS_STATUS_SUCCESS)
return status;
}
if (name == NULL)
{
*errnop = EINVAL;
return NSS_STATUS_UNAVAIL;
}
nis_result *result;
char buf[strlen (name) + 9 + pwd_tablename_len];
int olderr = errno;
snprintf (buf, sizeof (buf), "[name=%s],%s", name, pwd_tablename_val);
result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM, NULL, NULL);
if (result == NULL)
{
*errnop = ENOMEM;
return NSS_STATUS_TRYAGAIN;
}
if (__glibc_unlikely (niserr2nss (result->status) != NSS_STATUS_SUCCESS))
{
enum nss_status status = niserr2nss (result->status);
__set_errno (olderr);
nis_freeresult (result);
return status;
}
parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen, errnop);
nis_freeresult (result);
if (__glibc_unlikely (parse_res < 1))
{
if (parse_res == -1)
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
else
{
__set_errno (olderr);
return NSS_STATUS_NOTFOUND;
}
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getpwuid_r (const uid_t uid, struct passwd *pw,
char *buffer, size_t buflen, int *errnop)
{
if (pwd_tablename_val == NULL)
{
enum nss_status status = _nss_pwd_create_tablename (errnop);
if (status != NSS_STATUS_SUCCESS)
return status;
}
int parse_res;
nis_result *result;
char buf[8 + 3 * sizeof (unsigned long int) + pwd_tablename_len];
int olderr = errno;
snprintf (buf, sizeof (buf), "[uid=%lu],%s",
(unsigned long int) uid, pwd_tablename_val);
result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM, NULL, NULL);
if (result == NULL)
{
*errnop = ENOMEM;
return NSS_STATUS_TRYAGAIN;
}
if (__glibc_unlikely (niserr2nss (result->status) != NSS_STATUS_SUCCESS))
{
enum nss_status status = niserr2nss (result->status);
__set_errno (olderr);
nis_freeresult (result);
return status;
}
parse_res = _nss_nisplus_parse_pwent (result, pw, buffer, buflen, errnop);
nis_freeresult (result);
if (__glibc_unlikely (parse_res < 1))
{
if (parse_res == -1)
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
else
{
__set_errno (olderr);
return NSS_STATUS_NOTFOUND;
}
}
return NSS_STATUS_SUCCESS;
}

View File

@ -1,444 +0,0 @@
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
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 <atomic.h>
#include <ctype.h>
#include <errno.h>
#include <nss.h>
#include <string.h>
#include <rpc/netdb.h>
#include <rpcsvc/nis.h>
#include <libc-lock.h>
#include "nss-nisplus.h"
__libc_lock_define_initialized (static, lock)
static nis_result *result;
static nis_name tablename_val;
static u_long tablename_len;
#define NISENTRYVAL(idx, col, res) \
(NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
#define NISENTRYLEN(idx, col, res) \
(NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
static int
_nss_nisplus_parse_rpcent (nis_result *result, struct rpcent *rpc,
char *buffer, size_t buflen, int *errnop)
{
char *first_unused = buffer;
size_t room_left = buflen;
unsigned int i;
char *line;
if (result == NULL)
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
|| __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
|| strcmp (NIS_RES_OBJECT (result)[0].EN_data.en_type, "rpc_tbl") != 0
|| NIS_RES_OBJECT (result)[0].EN_data.en_cols.en_cols_len < 3)
return 0;
if (NISENTRYLEN (0, 0, result) >= room_left)
{
no_more_room:
*errnop = ERANGE;
return -1;
}
strncpy (first_unused, NISENTRYVAL (0, 0, result),
NISENTRYLEN (0, 0, result));
first_unused[NISENTRYLEN (0, 0, result)] = '\0';
rpc->r_name = first_unused;
size_t len = strlen (first_unused) + 1;
room_left -= len;
first_unused += len;
rpc->r_number = atoi (NISENTRYVAL (0, 2, result));
/* XXX Rewrite at some point to allocate the array first and then
copy the strings. It wasteful to first concatenate the strings
to just split them again later. */
line = first_unused;
for (i = 0; i < NIS_RES_NUMOBJ (result); ++i)
{
if (strcmp (NISENTRYVAL (i, 1, result), rpc->r_name) != 0)
{
if (NISENTRYLEN (i, 1, result) + 2 > room_left)
goto no_more_room;
*first_unused++ = ' ';
first_unused = __stpncpy (first_unused, NISENTRYVAL (i, 1, result),
NISENTRYLEN (i, 1, result));
room_left -= NISENTRYLEN (i, 1, result) + 1;
}
}
*first_unused++ = '\0';
/* Adjust the pointer so it is aligned for
storing pointers. */
size_t adjust = ((__alignof__ (char *)
- (first_unused - (char *) 0) % __alignof__ (char *))
% __alignof__ (char *));
if (room_left < adjust + sizeof (char *))
goto no_more_room;
first_unused += adjust;
room_left -= adjust;
rpc->r_aliases = (char **) first_unused;
/* For the terminating NULL pointer. */
room_left -= sizeof (char *);
i = 0;
while (*line != '\0')
{
/* Skip leading blanks. */
while (isspace (*line))
++line;
if (*line == '\0')
break;
if (room_left < sizeof (char *))
goto no_more_room;
room_left -= sizeof (char *);
rpc->r_aliases[i++] = line;
while (*line != '\0' && *line != ' ')
++line;
if (*line == ' ')
*line++ = '\0';
}
rpc->r_aliases[i] = NULL;
return 1;
}
static enum nss_status
_nss_create_tablename (int *errnop)
{
if (tablename_val == NULL)
{
const char *local_dir = nis_local_directory ();
size_t local_dir_len = strlen (local_dir);
static const char prefix[] = "rpc.org_dir.";
char *p = malloc (sizeof (prefix) + local_dir_len);
if (p == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1);
tablename_len = sizeof (prefix) - 1 + local_dir_len;
atomic_write_barrier ();
tablename_val = p;
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_setrpcent (int stayopen)
{
enum nss_status status = NSS_STATUS_SUCCESS;
__libc_lock_lock (lock);
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
if (tablename_val == NULL)
{
int err;
status = _nss_create_tablename (&err);
}
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_endrpcent (void)
{
__libc_lock_lock (lock);
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_getrpcent_r (struct rpcent *rpc, char *buffer,
size_t buflen, int *errnop)
{
int parse_res;
/* Get the next entry until we found a correct one. */
do
{
nis_result *saved_res;
if (result == NULL)
{
saved_res = NULL;
if (tablename_val == NULL)
{
enum nss_status status = _nss_create_tablename (errnop);
if (status != NSS_STATUS_SUCCESS)
return status;
}
result = nis_first_entry (tablename_val);
if (result == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
return niserr2nss (result->status);
}
else
{
saved_res = result;
result = nis_next_entry (tablename_val, &result->cookie);
if (result == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
nis_freeresult (saved_res);
return niserr2nss (result->status);
}
}
parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer,
buflen, errnop);
if (parse_res == -1)
{
nis_freeresult (result);
result = saved_res;
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
else
{
if (saved_res)
nis_freeresult (saved_res);
}
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getrpcent_r (struct rpcent *result, char *buffer,
size_t buflen, int *errnop)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_getrpcent_r (result, buffer, buflen, errnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_getrpcbyname_r (const char *name, struct rpcent *rpc,
char *buffer, size_t buflen, int *errnop)
{
int parse_res;
if (tablename_val == NULL)
{
__libc_lock_lock (lock);
enum nss_status status = _nss_create_tablename (errnop);
__libc_lock_unlock (lock);
if (status != NSS_STATUS_SUCCESS)
return status;
}
if (name == NULL)
return NSS_STATUS_NOTFOUND;
char buf[strlen (name) + 10 + tablename_len];
int olderr = errno;
/* Search at first in the alias list, and use the correct name
for the next search */
snprintf (buf, sizeof (buf), "[name=%s],%s", name, tablename_val);
nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM,
NULL, NULL);
if (result != NULL)
{
char *bufptr = buf;
/* If we did not find it, try it as original name. But if the
database is correct, we should find it in the first case, too */
if ((result->status != NIS_SUCCESS
&& result->status != NIS_S_SUCCESS)
|| __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ
|| strcmp (result->objects.objects_val->EN_data.en_type,
"rpc_tbl") != 0
|| result->objects.objects_val->EN_data.en_cols.en_cols_len < 3)
snprintf (buf, sizeof (buf), "[cname=%s],%s", name, tablename_val);
else
{
/* We need to allocate a new buffer since there is no
guarantee the returned name has a length limit. */
const char *entryval = NISENTRYVAL (0, 0, result);
size_t buflen = strlen (entryval) + 10 + tablename_len;
bufptr = alloca (buflen);
snprintf (bufptr, buflen, "[cname=%s],%s",
entryval, tablename_val);
}
nis_freeresult (result);
result = nis_list (bufptr, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM,
NULL, NULL);
}
if (result == NULL)
{
*errnop = ENOMEM;
return NSS_STATUS_TRYAGAIN;
}
if (__glibc_unlikely (niserr2nss (result->status) != NSS_STATUS_SUCCESS))
{
enum nss_status status = niserr2nss (result->status);
__set_errno (olderr);
nis_freeresult (result);
return status;
}
parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer, buflen,
errnop);
nis_freeresult (result);
if (parse_res < 1)
{
if (parse_res == -1)
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
__set_errno (olderr);
return NSS_STATUS_NOTFOUND;
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getrpcbynumber_r (const int number, struct rpcent *rpc,
char *buffer, size_t buflen, int *errnop)
{
if (tablename_val == NULL)
{
__libc_lock_lock (lock);
enum nss_status status = _nss_create_tablename (errnop);
__libc_lock_unlock (lock);
if (status != NSS_STATUS_SUCCESS)
return status;
}
char buf[12 + 3 * sizeof (number) + tablename_len];
int olderr = errno;
snprintf (buf, sizeof (buf), "[number=%d],%s", number, tablename_val);
nis_result *result = nis_list (buf, FOLLOW_LINKS | FOLLOW_PATH | USE_DGRAM,
NULL, NULL);
if (result == NULL)
{
*errnop = ENOMEM;
return NSS_STATUS_TRYAGAIN;
}
if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0))
{
enum nss_status status = niserr2nss (result->status);
__set_errno (olderr);
nis_freeresult (result);
return status;
}
int parse_res = _nss_nisplus_parse_rpcent (result, rpc, buffer, buflen,
errnop);
nis_freeresult (result);
if (parse_res < 1)
{
if (parse_res == -1)
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
else
{
__set_errno (olderr);
return NSS_STATUS_NOTFOUND;
}
}
return NSS_STATUS_SUCCESS;
}

View File

@ -1,461 +0,0 @@
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
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 <atomic.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <nss.h>
#include <string.h>
#include <rpcsvc/nis.h>
#include <libc-lock.h>
#include "nss-nisplus.h"
__libc_lock_define_initialized (static, lock);
static nis_result *result;
static nis_name tablename_val;
static u_long tablename_len;
#define NISENTRYVAL(idx, col, res) \
(NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
#define NISENTRYLEN(idx, col, res) \
(NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
static int
_nss_nisplus_parse_servent (nis_result *result, struct servent *serv,
char *buffer, size_t buflen, int *errnop)
{
char *first_unused = buffer;
size_t room_left = buflen;
if (result == NULL)
return 0;
if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
|| __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
|| strcmp (NIS_RES_OBJECT (result)->EN_data.en_type, "services_tbl") != 0
|| NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 4)
return 0;
if (NISENTRYLEN (0, 0, result) >= room_left)
{
no_more_room:
*errnop = ERANGE;
return -1;
}
strncpy (first_unused, NISENTRYVAL (0, 0, result),
NISENTRYLEN (0, 0, result));
first_unused[NISENTRYLEN (0, 0, result)] = '\0';
serv->s_name = first_unused;
size_t len = strlen (first_unused) + 1;
room_left -= len;
first_unused += len;
if (NISENTRYLEN (0, 2, result) >= room_left)
goto no_more_room;
strncpy (first_unused, NISENTRYVAL (0, 2, result),
NISENTRYLEN (0, 2, result));
first_unused[NISENTRYLEN (0, 2, result)] = '\0';
serv->s_proto = first_unused;
len = strlen (first_unused) + 1;
room_left -= len;
first_unused += len;
serv->s_port = htons (atoi (NISENTRYVAL (0, 3, result)));
/* XXX Rewrite at some point to allocate the array first and then
copy the strings. It wasteful to first concatenate the strings
to just split them again later. */
char *line = first_unused;
for (unsigned int i = 0; i < NIS_RES_NUMOBJ (result); ++i)
{
if (strcmp (NISENTRYVAL (i, 1, result), serv->s_name) != 0)
{
if (NISENTRYLEN (i, 1, result) + 2 > room_left)
goto no_more_room;
*first_unused++ = ' ';
first_unused = __stpncpy (first_unused, NISENTRYVAL (i, 1, result),
NISENTRYLEN (i, 1, result));
room_left -= NISENTRYLEN (i, 1, result) + 1;
}
}
*first_unused++ = '\0';
/* Adjust the pointer so it is aligned for
storing pointers. */
size_t adjust = ((__alignof__ (char *)
- (first_unused - (char *) 0) % __alignof__ (char *))
% __alignof__ (char *));
if (room_left < adjust + sizeof (char *))
goto no_more_room;
first_unused += adjust;
room_left -= adjust;
serv->s_aliases = (char **) first_unused;
/* For the terminating NULL pointer. */
room_left -= (sizeof (char *));
unsigned int i = 0;
while (*line != '\0')
{
/* Skip leading blanks. */
while (isspace (*line))
++line;
if (*line == '\0')
break;
if (room_left < sizeof (char *))
goto no_more_room;
room_left -= sizeof (char *);
serv->s_aliases[i++] = line;
while (*line != '\0' && *line != ' ')
++line;
if (*line == ' ')
*line++ = '\0';
}
serv->s_aliases[i] = NULL;
return 1;
}
static enum nss_status
_nss_create_tablename (int *errnop)
{
if (tablename_val == NULL)
{
const char *local_dir = nis_local_directory ();
size_t local_dir_len = strlen (local_dir);
static const char prefix[] = "services.org_dir.";
char *p = malloc (sizeof (prefix) + local_dir_len);
if (p == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1);
tablename_len = sizeof (prefix) - 1 + local_dir_len;
atomic_write_barrier ();
tablename_val = p;
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_setservent (int stayopen)
{
enum nss_status status = NSS_STATUS_SUCCESS;
int err;
__libc_lock_lock (lock);
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
if (tablename_val == NULL)
status = _nss_create_tablename (&err);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_endservent (void)
{
__libc_lock_lock (lock);
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_getservent_r (struct servent *serv, char *buffer,
size_t buflen, int *errnop)
{
int parse_res;
/* Get the next entry until we found a correct one. */
do
{
nis_result *saved_res;
if (result == NULL)
{
saved_res = NULL;
if (tablename_val == NULL)
{
enum nss_status status = _nss_create_tablename (errnop);
if (status != NSS_STATUS_SUCCESS)
return status;
}
result = nis_first_entry (tablename_val);
if (result == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
return niserr2nss (result->status);
}
else
{
saved_res = result;
result = nis_next_entry (tablename_val, &result->cookie);
if (result == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
nis_freeresult (saved_res);
return niserr2nss (result->status);
}
}
parse_res = _nss_nisplus_parse_servent (result, serv, buffer,
buflen, errnop);
if (__glibc_unlikely (parse_res == -1))
{
nis_freeresult (result);
result = saved_res;
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
else
{
if (saved_res)
nis_freeresult (saved_res);
}
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getservent_r (struct servent *result, char *buffer,
size_t buflen, int *errnop)
{
__libc_lock_lock (lock);
int status = internal_nisplus_getservent_r (result, buffer, buflen, errnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_getservbyname_r (const char *name, const char *protocol,
struct servent *serv,
char *buffer, size_t buflen, int *errnop)
{
if (tablename_val == NULL)
{
__libc_lock_lock (lock);
enum nss_status status = _nss_create_tablename (errnop);
__libc_lock_unlock (lock);
if (status != NSS_STATUS_SUCCESS)
return status;
}
if (name == NULL || protocol == NULL)
{
*errnop = EINVAL;
return NSS_STATUS_NOTFOUND;
}
size_t protocol_len = strlen (protocol);
char buf[strlen (name) + protocol_len + 17 + tablename_len];
int olderr = errno;
/* Search at first in the alias list, and use the correct name
for the next search */
snprintf (buf, sizeof (buf), "[name=%s,proto=%s],%s", name, protocol,
tablename_val);
nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM,
NULL, NULL);
if (result != NULL)
{
char *bufptr = buf;
/* If we did not find it, try it as original name. But if the
database is correct, we should find it in the first case, too */
if ((result->status != NIS_SUCCESS
&& result->status != NIS_S_SUCCESS)
|| __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
|| strcmp (NIS_RES_OBJECT (result)->EN_data.en_type,
"services_tbl") != 0
|| NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 4)
snprintf (buf, sizeof (buf), "[cname=%s,proto=%s],%s", name, protocol,
tablename_val);
else
{
/* We need to allocate a new buffer since there is no
guarantee the returned name has a length limit. */
const char *entryval = NISENTRYVAL(0, 0, result);
size_t buflen = (strlen (entryval) + protocol_len + 17
+ tablename_len);
bufptr = alloca (buflen);
snprintf (bufptr, buflen, "[cname=%s,proto=%s],%s",
entryval, protocol, tablename_val);
}
nis_freeresult (result);
result = nis_list (bufptr, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM,
NULL, NULL);
}
if (result == NULL)
{
*errnop = ENOMEM;
return NSS_STATUS_TRYAGAIN;
}
if (__glibc_unlikely (niserr2nss (result->status) != NSS_STATUS_SUCCESS))
{
enum nss_status status = niserr2nss (result->status);
__set_errno (olderr);
nis_freeresult (result);
return status;
}
int parse_res = _nss_nisplus_parse_servent (result, serv, buffer, buflen,
errnop);
nis_freeresult (result);
if (__glibc_unlikely (parse_res < 1))
{
if (parse_res == -1)
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
else
{
__set_errno (olderr);
return NSS_STATUS_NOTFOUND;
}
}
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getservbyport_r (const int number, const char *protocol,
struct servent *serv,
char *buffer, size_t buflen, int *errnop)
{
if (tablename_val == NULL)
{
__libc_lock_lock (lock);
enum nss_status status = _nss_create_tablename (errnop);
__libc_lock_unlock (lock);
if (status != NSS_STATUS_SUCCESS)
return status;
}
if (protocol == NULL)
{
*errnop = EINVAL;
return NSS_STATUS_NOTFOUND;
}
char buf[17 + 3 * sizeof (int) + strlen (protocol) + tablename_len];
int olderr = errno;
snprintf (buf, sizeof (buf), "[port=%d,proto=%s],%s",
number, protocol, tablename_val);
nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM,
NULL, NULL);
if (result == NULL)
{
*errnop = ENOMEM;
return NSS_STATUS_TRYAGAIN;
}
if (__glibc_unlikely (niserr2nss (result->status) != NSS_STATUS_SUCCESS))
{
enum nss_status status = niserr2nss (result->status);
__set_errno (olderr);
nis_freeresult (result);
return status;
}
int parse_res = _nss_nisplus_parse_servent (result, serv, buffer, buflen,
errnop);
nis_freeresult (result);
if (__glibc_unlikely (parse_res < 1))
{
if (parse_res == -1)
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
else
{
__set_errno (olderr);
return NSS_STATUS_NOTFOUND;
}
}
return NSS_STATUS_SUCCESS;
}

View File

@ -1,220 +0,0 @@
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
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.h>
#include <errno.h>
#include <shadow.h>
#include <string.h>
#include <libc-lock.h>
#include <rpcsvc/nis.h>
#include "nss-nisplus.h"
#include "nisplus-parser.h"
__libc_lock_define_initialized (static, lock)
static nis_result *result;
/* Defined in nisplus-pwd.c. */
extern nis_name pwd_tablename_val attribute_hidden;
extern size_t pwd_tablename_len attribute_hidden;
extern enum nss_status _nss_pwd_create_tablename (int *errnop);
enum nss_status
_nss_nisplus_setspent (int stayopen)
{
enum nss_status status = NSS_STATUS_SUCCESS;
int err;
__libc_lock_lock (lock);
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
if (pwd_tablename_val == NULL)
status = _nss_pwd_create_tablename (&err);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_endspent (void)
{
__libc_lock_lock (lock);
if (result != NULL)
{
nis_freeresult (result);
result = NULL;
}
__libc_lock_unlock (lock);
return NSS_STATUS_SUCCESS;
}
static enum nss_status
internal_nisplus_getspent_r (struct spwd *sp, char *buffer, size_t buflen,
int *errnop)
{
int parse_res;
/* Get the next entry until we found a correct one. */
do
{
nis_result *saved_res;
if (result == NULL)
{
saved_res = NULL;
if (pwd_tablename_val == NULL)
{
enum nss_status status = _nss_pwd_create_tablename (errnop);
if (status != NSS_STATUS_SUCCESS)
return status;
}
result = nis_first_entry (pwd_tablename_val);
if (result == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
return niserr2nss (result->status);
}
else
{
saved_res = result;
result = nis_next_entry (pwd_tablename_val, &result->cookie);
if (result == NULL)
{
*errnop = errno;
return NSS_STATUS_TRYAGAIN;
}
if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
{
nis_freeresult (saved_res);
return niserr2nss (result->status);
}
}
parse_res = _nss_nisplus_parse_spent (result, sp, buffer,
buflen, errnop);
if (__glibc_unlikely (parse_res == -1))
{
nis_freeresult (result);
result = saved_res;
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
if (saved_res != NULL)
nis_freeresult (saved_res);
}
while (!parse_res);
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_nisplus_getspent_r (struct spwd *result, char *buffer, size_t buflen,
int *errnop)
{
int status;
__libc_lock_lock (lock);
status = internal_nisplus_getspent_r (result, buffer, buflen, errnop);
__libc_lock_unlock (lock);
return status;
}
enum nss_status
_nss_nisplus_getspnam_r (const char *name, struct spwd *sp,
char *buffer, size_t buflen, int *errnop)
{
int parse_res;
if (pwd_tablename_val == NULL)
{
enum nss_status status = _nss_pwd_create_tablename (errnop);
if (status != NSS_STATUS_SUCCESS)
return status;
}
if (name == NULL)
{
*errnop = EINVAL;
return NSS_STATUS_NOTFOUND;
}
nis_result *result;
char buf[strlen (name) + 9 + pwd_tablename_len];
int olderr = errno;
snprintf (buf, sizeof (buf), "[name=%s],%s", name, pwd_tablename_val);
result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM, NULL, NULL);
if (result == NULL)
{
*errnop = ENOMEM;
return NSS_STATUS_TRYAGAIN;
}
if (__glibc_unlikely (niserr2nss (result->status) != NSS_STATUS_SUCCESS))
{
enum nss_status status = niserr2nss (result->status);
__set_errno (olderr);
nis_freeresult (result);
return status;
}
parse_res = _nss_nisplus_parse_spent (result, sp, buffer, buflen, errnop);
nis_freeresult (result);
if (__glibc_unlikely (parse_res < 1))
{
if (parse_res == -1)
{
*errnop = ERANGE;
return NSS_STATUS_TRYAGAIN;
}
else
{
__set_errno (olderr);
return NSS_STATUS_NOTFOUND;
}
}
return NSS_STATUS_SUCCESS;
}

View File

@ -1,474 +0,0 @@
%/*
% * Copyright (c) 2010, Oracle America, Inc.
% *
% * Redistribution and use in source and binary forms, with or without
% * modification, are permitted provided that the following conditions are
% * met:
% *
% * * Redistributions of source code must retain the above copyright
% * notice, this list of conditions and the following disclaimer.
% * * Redistributions in binary form must reproduce the above
% * copyright notice, this list of conditions and the following
% * disclaimer in the documentation and/or other materials
% * provided with the distribution.
% * * Neither the name of the "Oracle America, Inc." nor the names of its
% * contributors may be used to endorse or promote products derived
% * from this software without specific prior written permission.
% *
% * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
% * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
% * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
% * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
% * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
% * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
% * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
% * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
% * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
% * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
% * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
% */
#ifdef RPC_HDR
%/*
% * nis.h
% *
% * This file is the main include file for NIS clients. It contains
% * both the client library function defines and the various data
% * structures used by the NIS service. It includes the file nis_tags.h
% * which defines the tag values. This allows the tags to change without
% * having to change the nis.x file.
% *
% * NOTE : DO NOT EDIT THIS FILE! It is automatically generated when
% * rpcgen is run on the nis.x file. Note that there is a
% * simple sed script to remove some unneeded lines. (See the
% * Makefile target nis.h)
% *
% */
%#include <rpcsvc/nis_tags.h>
#endif
/* This gets stuffed into the source files. */
#if RPC_HDR
%#include <rpc/xdr.h>
#endif
/* Include the RPC Language description of NIS objects */
#include "nis_object.x"
/* Errors that can be returned by the service */
enum nis_error {
NIS_SUCCESS = 0, /* A-ok, let's rock n roll */
NIS_S_SUCCESS = 1, /* Name found (maybe) */
NIS_NOTFOUND = 2, /* Name definitely not found */
NIS_S_NOTFOUND = 3, /* Name maybe not found */
NIS_CACHEEXPIRED = 4, /* Name exists but cache out of date */
NIS_NAMEUNREACHABLE = 5, /* Can't get there from here */
NIS_UNKNOWNOBJ = 6, /* Object type is bogus */
NIS_TRYAGAIN = 7, /* I'm busy, call back */
NIS_SYSTEMERROR = 8, /* Generic system error */
NIS_CHAINBROKEN = 9, /* First/Next warning */
NIS_PERMISSION = 10, /* Not enough permission to access */
NIS_NOTOWNER = 11, /* You don't own it, sorry */
NIS_NOT_ME = 12, /* I don't serve this name */
NIS_NOMEMORY = 13, /* Outta VM! Help! */
NIS_NAMEEXISTS = 14, /* Can't create over another name */
NIS_NOTMASTER = 15, /* I'm justa secondaray, don't ask me */
NIS_INVALIDOBJ = 16, /* Object is broken somehow */
NIS_BADNAME = 17, /* Unparsable name */
NIS_NOCALLBACK = 18, /* Couldn't talk to call back proc */
NIS_CBRESULTS = 19, /* Results being called back to you */
NIS_NOSUCHNAME = 20, /* Name unknown */
NIS_NOTUNIQUE = 21, /* Value is not uniques (entry) */
NIS_IBMODERROR = 22, /* Inf. Base. Modify error. */
NIS_NOSUCHTABLE = 23, /* Name for table was wrong */
NIS_TYPEMISMATCH = 24, /* Entry and table type mismatch */
NIS_LINKNAMEERROR = 25, /* Link points to bogus name */
NIS_PARTIAL = 26, /* Partial success, found table */
NIS_TOOMANYATTRS = 27, /* Too many attributes */
NIS_RPCERROR = 28, /* RPC error encountered */
NIS_BADATTRIBUTE = 29, /* Bad or invalid attribute */
NIS_NOTSEARCHABLE = 30, /* Non-searchable object searched */
NIS_CBERROR = 31, /* Error during callback (svc crash) */
NIS_FOREIGNNS = 32, /* Foreign Namespace */
NIS_BADOBJECT = 33, /* Malformed object structure */
NIS_NOTSAMEOBJ = 34, /* Object swapped during deletion */
NIS_MODFAIL = 35, /* Failure during a Modify. */
NIS_BADREQUEST = 36, /* Illegal query for table */
NIS_NOTEMPTY = 37, /* Attempt to remove a non-empty tbl */
NIS_COLDSTART_ERR = 38, /* Error accesing the cold start file */
NIS_RESYNC = 39, /* Transaction log too far out of date */
NIS_FAIL = 40, /* NIS operation failed. */
NIS_UNAVAIL = 41, /* NIS+ service is unavailable (client) */
NIS_RES2BIG = 42, /* NIS+ result too big for datagram */
NIS_SRVAUTH = 43, /* NIS+ server wasn't authenticated. */
NIS_CLNTAUTH = 44, /* NIS+ Client wasn't authenticated. */
NIS_NOFILESPACE = 45, /* NIS+ server ran out of disk space */
NIS_NOPROC = 46, /* NIS+ server couldn't create new proc */
NIS_DUMPLATER = 47 /* NIS+ server already has dump child */
};
/*
* Structure definitions for the parameters and results of the actual
* NIS RPC calls.
*
* This is the standard result (in the protocol) of most of the nis
* requests.
*/
struct nis_result {
nis_error status; /* Status of the response */
nis_object objects<>; /* objects found */
netobj cookie; /* Cookie Data */
uint32_t zticks; /* server ticks */
uint32_t dticks; /* DBM ticks. */
uint32_t aticks; /* Cache (accel) ticks */
uint32_t cticks; /* Client ticks */
};
/*
* A Name Service request
* This request is used to access the name space, ns_name is the name
* of the object within the namespace and the object is it's value, for
* add/modify, a copy of the original for remove.
*/
struct ns_request {
nis_name ns_name; /* Name in the NIS name space */
nis_object ns_object<1>; /* Optional Object (add/remove) */
};
/*
* An information base request
* This request includes the NIS name of the table we wish to search, the
* search criteria in the form of attribute/value pairs and an optional
* callback program number. If the callback program number is provided
* the server will send back objects one at a time, otherwise it will
* return them all in the response.
*/
struct ib_request {
nis_name ibr_name; /* The name of the Table */
nis_attr ibr_srch<>; /* The search critereia */
uint32_t ibr_flags; /* Optional flags */
nis_object ibr_obj<1>; /* optional object (add/modify) */
nis_server ibr_cbhost<1>; /* Optional callback info */
u_int ibr_bufsize; /* Optional first/next bufsize */
netobj ibr_cookie; /* The first/next cookie */
};
/*
* This argument to the PING call notifies the replicas that something in
* a directory has changed and this is it's timestamp. The replica will use
* the timestamp to determine if its resync operation was successful.
*/
struct ping_args {
nis_name dir; /* Directory that had the change */
uint32_t stamp; /* timestamp of the transaction */
};
/*
* These are the type of entries that are stored in the transaction log,
* note that modifications will appear as two entries, for names, they have
* a "OLD" entry followed by a "NEW" entry. For entries in tables, there
* is a remove followed by an add. It is done this way so that we can read
* the log backwards to back out transactions and forwards to propogate
* updated.
*/
enum log_entry_t {
LOG_NOP = 0,
ADD_NAME = 1, /* Name Added to name space */
REM_NAME = 2, /* Name removed from name space */
MOD_NAME_OLD = 3, /* Name was modified in the name space */
MOD_NAME_NEW = 4, /* Name was modified in the name space */
ADD_IBASE = 5, /* Entry added to information base */
REM_IBASE = 6, /* Entry removed from information base */
MOD_IBASE = 7, /* Entry was modified in information base */
UPD_STAMP = 8 /* Update timestamp (used as fenceposts) */
};
/*
* This result is returned from the name service when it is requested to
* dump logged entries from its transaction log. Information base updates
* will have the name of the information base in the le_name field and
* a canonical set of attribute/value pairs to fully specify the entry's
* 'name'.
*/
struct log_entry {
uint32_t le_time; /* Time in seconds */
log_entry_t le_type; /* Type of log entry */
nis_name le_princp; /* Principal making the change */
nis_name le_name; /* Name of table/dir involved */
nis_attr le_attrs<>; /* List of AV pairs. */
nis_object le_object; /* Actual object value */
};
struct log_result {
nis_error lr_status; /* The status itself */
netobj lr_cookie; /* Used by the dump callback */
log_entry lr_entries<>; /* zero or more entries */
};
struct cp_result {
nis_error cp_status; /* Status of the checkpoint */
uint32_t cp_zticks; /* Service 'ticks' */
uint32_t cp_dticks; /* Database 'ticks' */
};
/*
* This structure defines a generic NIS tag list. The taglist contains
* zero or tags, each of which is a type and a value. (u_int).
* These are used to report statistics (see tag definitions below)
* and to set or reset state variables.
*/
struct nis_tag {
uint32_t tag_type; /* Statistic tag (may vary) */
string tag_val<>; /* Statistic value may also vary */
};
struct nis_taglist {
nis_tag tags<>; /* List of tags */
};
struct dump_args {
nis_name da_dir; /* Directory to dump */
uint32_t da_time; /* From this timestamp */
nis_server da_cbhost<1>; /* Callback to use. */
};
struct fd_args {
nis_name dir_name; /* The directory we're looking for */
nis_name requester; /* Host principal name for signature */
};
struct fd_result {
nis_error status; /* Status returned by function */
nis_name source; /* Source of this answer */
opaque dir_data<>; /* Directory Data (XDR'ed) */
opaque signature<>; /* Signature of the source */
};
%/*
% * Structures used for server binding.
% */
struct nis_bound_endpoint {
endpoint ep;
int generation;
int rank;
uint32_t flags;
int hostnum;
int epnum;
nis_name uaddr;
endpoint cbep;
};
typedef struct nis_bound_endpoint nis_bound_endpoint;
struct nis_bound_directory {
int generation;
int min_rank; /* minimum rank of bound endpoints */
int optimal_rank; /* best possible rank of all endpoints */
directory_obj dobj;
nis_bound_endpoint BEP<>;
};
typedef struct nis_bound_directory nis_bound_directory;
%#define bep_len BEP.BEP_len
%#define bep_val BEP.BEP_val
struct nis_active_endpoint {
endpoint ep;
nis_name hostname;
int rank;
int uaddr_generation;
nis_name uaddr;
int cbep_generation;
endpoint cbep;
};
typedef struct nis_active_endpoint nis_active_endpoint;
%/* defines for nis_bound_endpoint.flags */
%#define NIS_BOUND 0x1
%#define NIS_TRANSIENT_ERRORS 0x2
program NIS_PROG {
/* RPC Language description of the NIS+ protocol */
version NIS_VERSION {
/* The name service functions */
nis_result NIS_LOOKUP(ns_request) = 1;
nis_result NIS_ADD(ns_request) = 2;
nis_result NIS_MODIFY(ns_request) = 3;
nis_result NIS_REMOVE(ns_request) = 4;
/* The information base functions */
nis_result NIS_IBLIST(ib_request) = 5;
nis_result NIS_IBADD(ib_request) = 6;
nis_result NIS_IBMODIFY(ib_request) = 7;
nis_result NIS_IBREMOVE(ib_request) = 8;
nis_result NIS_IBFIRST(ib_request) = 9;
nis_result NIS_IBNEXT(ib_request) = 10;
/* NIS Administrative functions */
fd_result NIS_FINDDIRECTORY(fd_args) = 12;
/* If fetch and optionally reset statistics */
nis_taglist NIS_STATUS(nis_taglist) = 14;
/* Dump changes to directory since time in da_time */
log_result NIS_DUMPLOG(dump_args) = 15;
/* Dump contents of directory named */
log_result NIS_DUMP(dump_args) = 16;
/* Check status of callback thread */
bool NIS_CALLBACK(netobj) = 17;
/* Return last update time for named dir */
uint32_t NIS_CPTIME(nis_name) = 18;
/* Checkpoint directory or table named */
cp_result NIS_CHECKPOINT(nis_name) = 19;
/* Send 'status changed' ping to replicates */
void NIS_PING(ping_args) = 20;
/* Modify server behaviour (such as debugging) */
nis_taglist NIS_SERVSTATE(nis_taglist) = 21;
/* Create a Directory */
nis_error NIS_MKDIR(nis_name) = 22;
/* Remove a Directory */
nis_error NIS_RMDIR(nis_name) = 23;
/* Update public keys of a directory object */
nis_error NIS_UPDKEYS(nis_name) = 24;
} = 3;
} = 100300;
/*
* Included below are the defines that become part of nis.h,
* they are technically not part of the protocol, but do define
* key aspects of the implementation and are therefore useful
* in building a conforming server or client.
*/
#if RPC_HDR
%/*
% * Generic "hash" datastructures, used by all types of hashed data.
% */
%struct nis_hash_data {
% nis_name name; /* NIS name of hashed item */
% int keychain; /* It's hash key (for pop) */
% struct nis_hash_data *next; /* Hash collision pointer */
% struct nis_hash_data *prv_item; /* A serial, doubly linked list */
% struct nis_hash_data *nxt_item; /* of items in the hash table */
%};
%typedef struct nis_hash_data NIS_HASH_ITEM;
%
%struct nis_hash_table {
% NIS_HASH_ITEM *keys[64]; /* A hash table of items */
% NIS_HASH_ITEM *first; /* The first "item" in serial list */
%};
%typedef struct nis_hash_table NIS_HASH_TABLE;
%
%/* Structure for storing dynamically allocated static data */
%struct nis_sdata {
% void *buf; /* Memory allocation pointer */
% u_int size; /* Buffer size */
%};
%
%/* Generic client creating flags */
%#define ZMH_VC 1
%#define ZMH_DG 2
%#define ZMH_AUTH 4
%
%/* Testing Access rights for objects */
%
%#define NIS_READ_ACC 1
%#define NIS_MODIFY_ACC 2
%#define NIS_CREATE_ACC 4
%#define NIS_DESTROY_ACC 8
%/* Test macros. a == access rights, m == desired rights. */
%#define NIS_WORLD(a, m) (((a) & (m)) != 0)
%#define NIS_GROUP(a, m) (((a) & ((m) << 8)) != 0)
%#define NIS_OWNER(a, m) (((a) & ((m) << 16)) != 0)
%#define NIS_NOBODY(a, m) (((a) & ((m) << 24)) != 0)
%/*
% * EOL Alert - The following non-prefixed test macros are
% * here for backward compatability, and will be not be present
% * in future releases - use the NIS_*() macros above.
% */
%#define WORLD(a, m) (((a) & (m)) != 0)
%#define GROUP(a, m) (((a) & ((m) << 8)) != 0)
%#define OWNER(a, m) (((a) & ((m) << 16)) != 0)
%#define NOBODY(a, m) (((a) & ((m) << 24)) != 0)
%
%#define OATYPE(d, n) (((d)->do_armask.do_armask_val+n)->oa_otype)
%#define OARIGHTS(d, n) (((d)->do_armask.do_armask_val+n)->oa_rights)
%#define WORLD_DEFAULT (NIS_READ_ACC)
%#define GROUP_DEFAULT (NIS_READ_ACC << 8)
%#define OWNER_DEFAULT ((NIS_READ_ACC +\
NIS_MODIFY_ACC +\
NIS_CREATE_ACC +\
NIS_DESTROY_ACC) << 16)
%#define DEFAULT_RIGHTS (WORLD_DEFAULT | GROUP_DEFAULT | OWNER_DEFAULT)
%
%/* Result manipulation defines ... */
%#define NIS_RES_NUMOBJ(x) ((x)->objects.objects_len)
%#define NIS_RES_OBJECT(x) ((x)->objects.objects_val)
%#define NIS_RES_COOKIE(x) ((x)->cookie)
%#define NIS_RES_STATUS(x) ((x)->status)
%
%/* These defines make getting at the variant part of the object easier. */
%#define TA_data zo_data.objdata_u.ta_data
%#define EN_data zo_data.objdata_u.en_data
%#define DI_data zo_data.objdata_u.di_data
%#define LI_data zo_data.objdata_u.li_data
%#define GR_data zo_data.objdata_u.gr_data
%
%#define __type_of(o) ((o)->zo_data.zo_type)
%
%/* Declarations for the internal subroutines in nislib.c */
%enum name_pos {SAME_NAME, HIGHER_NAME, LOWER_NAME, NOT_SEQUENTIAL, BAD_NAME};
%typedef enum name_pos name_pos;
%
%/*
% * Defines for getting at column data in entry objects. Because RPCGEN
% * generates some rather wordy structures, we create some defines that
% * collapse the needed keystrokes to access a particular value using
% * these definitions they take an nis_object *, and an int and return
% * a u_char * for Value, and an int for length.
% */
%#define ENTRY_VAL(obj, col) \
% (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val
%#define ENTRY_LEN(obj, col) \
% (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len
%
%
%
%#ifdef __cplusplus
%}
%#endif
%
%/* Prototypes, and extern declarations for the NIS library functions. */
%#include <rpcsvc/nislib.h>
%#endif /* __NIS_RPCGEN_H */
%/* EDIT_START */
%
%/*
% * nis_3.h
% *
% * This file contains definitions that are only of interest to the actual
% * service daemon and client stubs. Normal users of NIS will not include
% * this file.
% *
% * NOTE : This include file is automatically created by a combination
% * of rpcgen and sed. DO NOT EDIT IT, change the nis.x file instead
% * and then remake this file.
% */
%#ifndef __nis_3_h
%#define __nis_3_h
%#ifdef __cplusplus
%extern "C" {
%#endif
#endif

View File

@ -1,63 +0,0 @@
%/*
% * Copyright (c) 2010, Oracle America, Inc.
% *
% * Redistribution and use in source and binary forms, with or without
% * modification, are permitted provided that the following conditions are
% * met:
% *
% * * Redistributions of source code must retain the above copyright
% * notice, this list of conditions and the following disclaimer.
% * * Redistributions in binary form must reproduce the above
% * copyright notice, this list of conditions and the following
% * disclaimer in the documentation and/or other materials
% * provided with the distribution.
% * * Neither the name of the "Oracle America, Inc." nor the names of its
% * contributors may be used to endorse or promote products derived
% * from this software without specific prior written permission.
% *
% * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
% * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
% * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
% * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
% * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
% * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
% * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
% * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
% * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
% * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
% * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
% */
/*
* nis_callback.x
*/
%#pragma ident "@(#)nis_callback.x 1.7 94/05/03"
/*
* "@(#)zns_cback.x 1.2 90/09/10"
*
* RPCL description of the Callback Service.
*/
#ifdef RPC_HDR
%#include <rpcsvc/nis.h>
#endif
#ifdef RPC_XDR
%#include "nis_clnt.h"
#endif
typedef nis_object *obj_p;
struct cback_data {
obj_p entries<>; /* List of objects */
};
program CB_PROG {
version CB_VERS {
bool CBPROC_RECEIVE(cback_data) = 1;
void CBPROC_FINISH(void) = 2;
void CBPROC_ERROR(nis_error) = 3;
} = 1;
} = 100302;

View File

@ -1,328 +0,0 @@
/*
* nis_object.x
*
* Copyright (c) 2010, Oracle America, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
* * Neither the name of the "Oracle America, Inc." nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
%#pragma ident "@(#)nis_object.x 1.12 97/11/19"
#if RPC_HDR
%
%#ifndef __nis_object_h
%#define __nis_object_h
%
#endif
/*
* This file defines the format for a NIS object in RPC language.
* It is included by the main .x file and the database access protocol
* file. It is common because both of them need to deal with the same
* type of object. Generating the actual code though is a bit messy because
* the nis.x file and the nis_dba.x file will generate xdr routines to
* encode/decode objects when only one set is needed. Such is life when
* one is using rpcgen.
*
* Note, the protocol doesn't specify any limits on such things as
* maximum name length, number of attributes, etc. These are enforced
* by the database backend. When you hit them you will no. Also see
* the db_getlimits() function for fetching the limit values.
*
*/
/* Some manifest constants, chosen to maximize flexibility without
* plugging the wire full of data.
*/
const NIS_MAXSTRINGLEN = 255;
const NIS_MAXNAMELEN = 1024;
const NIS_MAXATTRNAME = 32;
const NIS_MAXATTRVAL = 2048;
const NIS_MAXCOLUMNS = 64;
const NIS_MAXATTR = 16;
const NIS_MAXPATH = 1024;
const NIS_MAXREPLICAS = 128;
const NIS_MAXLINKS = 16;
const NIS_PK_NONE = 0; /* no public key (unix/sys auth) */
const NIS_PK_DH = 1; /* Public key is Diffie-Hellman type */
const NIS_PK_RSA = 2; /* Public key if RSA type */
const NIS_PK_KERB = 3; /* Use kerberos style authentication */
const NIS_PK_DHEXT = 4; /* Extended Diffie-Hellman for RPC-GSS */
/*
* The fundamental name type of NIS. The name may consist of two parts,
* the first being the fully qualified name, and the second being an
* optional set of attribute/value pairs.
*/
struct nis_attr {
string zattr_ndx<>; /* name of the index */
opaque zattr_val<>; /* Value for the attribute. */
};
typedef string nis_name<>; /* The NIS name itself. */
/* NIS object types are defined by the following enumeration. The numbers
* they use are based on the following scheme :
* 0 - 1023 are reserved for Sun,
* 1024 - 2047 are defined to be private to a particular tree.
* 2048 - 4095 are defined to be user defined.
* 4096 - ... are reserved for future use.
*
* EOL Alert - The non-prefixed names are present for backward
* compatability only, and will not exist in future releases. Use
* the NIS_* names for future compatability.
*/
enum zotypes {
BOGUS_OBJ = 0, /* Uninitialized object structure */
NO_OBJ = 1, /* NULL object (no data) */
DIRECTORY_OBJ = 2, /* Directory object describing domain */
GROUP_OBJ = 3, /* Group object (a list of names) */
TABLE_OBJ = 4, /* Table object (a database schema) */
ENTRY_OBJ = 5, /* Entry object (a database record) */
LINK_OBJ = 6, /* A name link. */
PRIVATE_OBJ = 7, /* Private object (all opaque data) */
NIS_BOGUS_OBJ = 0, /* Uninitialized object structure */
NIS_NO_OBJ = 1, /* NULL object (no data) */
NIS_DIRECTORY_OBJ = 2, /* Directory object describing domain */
NIS_GROUP_OBJ = 3, /* Group object (a list of names) */
NIS_TABLE_OBJ = 4, /* Table object (a database schema) */
NIS_ENTRY_OBJ = 5, /* Entry object (a database record) */
NIS_LINK_OBJ = 6, /* A name link. */
NIS_PRIVATE_OBJ = 7 /* Private object (all opaque data) */
};
/*
* The types of Name services NIS knows about. They are enumerated
* here. The Binder code will use this type to determine if it has
* a set of library routines that will access the indicated name service.
*/
enum nstype {
UNKNOWN = 0,
NIS = 1, /* Nis Plus Service */
SUNYP = 2, /* Old NIS Service */
IVY = 3, /* Nis Plus Plus Service */
DNS = 4, /* Domain Name Service */
X500 = 5, /* ISO/CCCIT X.500 Service */
DNANS = 6, /* Digital DECNet Name Service */
XCHS = 7, /* Xerox ClearingHouse Service */
CDS= 8
};
/*
* DIRECTORY - The name service object. These objects identify other name
* servers that are serving some portion of the name space. Each has a
* type associated with it. The resolver library will note whether or not
* is has the needed routines to access that type of service.
* The oarmask structure defines an access rights mask on a per object
* type basis for the name spaces. The only bits currently used are
* create and destroy. By enabling or disabling these access rights for
* a specific object type for a one of the accessor entities (owner,
* group, world) the administrator can control what types of objects
* may be freely added to the name space and which require the
* administrator's approval.
*/
struct oar_mask {
uint32_t oa_rights; /* Access rights mask */
zotypes oa_otype; /* Object type */
};
struct endpoint {
string uaddr<>;
string family<>; /* Transport family (INET, OSI, etc) */
string proto<>; /* Protocol (TCP, UDP, CLNP, etc) */
};
/*
* Note: pkey is a netobj which is limited to 1024 bytes which limits the
* keysize to 8192 bits. This is consider to be a reasonable limit for
* the expected lifetime of this service.
*/
struct nis_server {
nis_name name; /* Principal name of the server */
endpoint ep<>; /* Universal addr(s) for server */
uint32_t key_type; /* Public key type */
netobj pkey; /* server's public key */
};
struct directory_obj {
nis_name do_name; /* Name of the directory being served */
nstype do_type; /* one of NIS, DNS, IVY, YP, or X.500 */
nis_server do_servers<>; /* <0> == Primary name server */
uint32_t do_ttl; /* Time To Live (for caches) */
oar_mask do_armask<>; /* Create/Destroy rights by object type */
};
/*
* ENTRY - This is one row of data from an information base.
* The type value is used by the client library to convert the entry to
* it's internal structure representation. The Table name is a back pointer
* to the table where the entry is stored. This allows the client library
* to determine where to send a request if the client wishes to change this
* entry but got to it through a LINK rather than directly.
* If the entry is a "standalone" entry then this field is void.
*/
const EN_BINARY = 1; /* Indicates value is binary data */
const EN_CRYPT = 2; /* Indicates the value is encrypted */
const EN_XDR = 4; /* Indicates the value is XDR encoded */
const EN_MODIFIED = 8; /* Indicates entry is modified. */
const EN_ASN1 = 64; /* Means contents use ASN.1 encoding */
struct entry_col {
uint32_t ec_flags; /* Flags for this value */
opaque ec_value<>; /* It's textual value */
};
struct entry_obj {
string en_type<>; /* Type of entry such as "passwd" */
entry_col en_cols<>; /* Value for the entry */
};
/*
* GROUP - The group object contains a list of NIS principal names. Groups
* are used to authorize principals. Each object has a set of access rights
* for members of its group. Principal names in groups are in the form
* name.directory and recursive groups are expressed as @groupname.directory
*/
struct group_obj {
uint32_t gr_flags; /* Flags controlling group */
nis_name gr_members<>; /* List of names in group */
};
/*
* LINK - This is the LINK object. It is quite similar to a symbolic link
* in the UNIX filesystem. The attributes in the main object structure are
* relative to the LINK data and not what it points to (like the file system)
* "modify" privleges here indicate the right to modify what the link points
* at and not to modify that actual object pointed to by the link.
*/
struct link_obj {
zotypes li_rtype; /* Real type of the object */
nis_attr li_attrs<>; /* Attribute/Values for tables */
nis_name li_name; /* The object's real NIS name */
};
/*
* TABLE - This is the table object. It implements a simple
* data base that applications and use for configuration or
* administration purposes. The role of the table is to group together
* a set of related entries. Tables are the simple database component
* of NIS. Like many databases, tables are logically divided into columns
* and rows. The columns are labeled with indexes and each ENTRY makes
* up a row. Rows may be addressed within the table by selecting one
* or more indexes, and values for those indexes. Each row which has
* a value for the given index that matches the desired value is returned.
* Within the definition of each column there is a flags variable, this
* variable contains flags which determine whether or not the column is
* searchable, contains binary data, and access rights for the entry objects
* column value.
*/
const TA_BINARY = 1; /* Means table data is binary */
const TA_CRYPT = 2; /* Means value should be encrypted */
const TA_XDR = 4; /* Means value is XDR encoded */
const TA_SEARCHABLE = 8; /* Means this column is searchable */
const TA_CASE = 16; /* Means this column is Case Sensitive */
const TA_MODIFIED = 32; /* Means this columns attrs are modified*/
const TA_ASN1 = 64; /* Means contents use ASN.1 encoding */
struct table_col {
string tc_name<64>; /* Column Name */
uint32_t tc_flags; /* control flags */
uint32_t tc_rights; /* Access rights mask */
};
struct table_obj {
string ta_type<64>; /* Table type such as "passwd" */
int ta_maxcol; /* Total number of columns */
u_char ta_sep; /* Separator character */
table_col ta_cols<>; /* The number of table indexes */
string ta_path<>; /* A search path for this table */
};
/*
* This union joins together all of the currently known objects.
*/
union objdata switch (zotypes zo_type) {
case NIS_DIRECTORY_OBJ :
struct directory_obj di_data;
case NIS_GROUP_OBJ :
struct group_obj gr_data;
case NIS_TABLE_OBJ :
struct table_obj ta_data;
case NIS_ENTRY_OBJ:
struct entry_obj en_data;
case NIS_LINK_OBJ :
struct link_obj li_data;
case NIS_PRIVATE_OBJ :
opaque po_data<>;
case NIS_NO_OBJ :
void;
case NIS_BOGUS_OBJ :
void;
default :
void;
};
/*
* This is the basic NIS object data type. It consists of a generic part
* which all objects contain, and a specialized part which varies depending
* on the type of the object. All of the specialized sections have been
* described above. You might have wondered why they all start with an
* integer size, followed by the useful data. The answer is, when the
* server doesn't recognize the type returned it treats it as opaque data.
* And the definition for opaque data is {int size; char *data;}. In this
* way, servers and utility routines that do not understand a given type
* may still pass it around. One has to be careful in setting
* this variable accurately, it must take into account such things as
* XDR padding of structures etc. The best way to set it is to note one's
* position in the XDR encoding stream, encode the structure, look at the
* new position and calculate the size.
*/
struct nis_oid {
uint32_t ctime; /* Time of objects creation */
uint32_t mtime; /* Time of objects modification */
};
struct nis_object {
nis_oid zo_oid; /* object identity verifier. */
nis_name zo_name; /* The NIS name for this object */
nis_name zo_owner; /* NIS name of object owner. */
nis_name zo_group; /* NIS name of access group. */
nis_name zo_domain; /* The administrator for the object */
uint32_t zo_access; /* Access rights (owner, group, world) */
uint32_t zo_ttl; /* Object's time to live in seconds. */
objdata zo_data; /* Data structure for this type */
};
#if RPC_HDR
%
%#endif /* if __nis_object_h */
%
#endif

View File

@ -1,311 +0,0 @@
/* @(#)yp.x 2.1 88/08/01 4.0 RPCSRC */
/*
* Copyright (c) 2010, Oracle America, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
* * Neither the name of the "Oracle America, Inc." nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Protocol description file for the Yellow Pages Service
*/
const YPMAXRECORD = 1024;
const YPMAXDOMAIN = 64;
const YPMAXMAP = 64;
const YPMAXPEER = 64;
enum ypstat {
YP_TRUE = 1,
YP_NOMORE = 2,
YP_FALSE = 0,
YP_NOMAP = -1,
YP_NODOM = -2,
YP_NOKEY = -3,
YP_BADOP = -4,
YP_BADDB = -5,
YP_YPERR = -6,
YP_BADARGS = -7,
YP_VERS = -8
};
enum ypxfrstat {
YPXFR_SUCC = 1,
YPXFR_AGE = 2,
YPXFR_NOMAP = -1,
YPXFR_NODOM = -2,
YPXFR_RSRC = -3,
YPXFR_RPC = -4,
YPXFR_MADDR = -5,
YPXFR_YPERR = -6,
YPXFR_BADARGS = -7,
YPXFR_DBM = -8,
YPXFR_FILE = -9,
YPXFR_SKEW = -10,
YPXFR_CLEAR = -11,
YPXFR_FORCE = -12,
YPXFR_XFRERR = -13,
YPXFR_REFUSED = -14
};
typedef string domainname<YPMAXDOMAIN>;
typedef string mapname<YPMAXMAP>;
typedef string peername<YPMAXPEER>;
typedef opaque keydat<YPMAXRECORD>;
typedef opaque valdat<YPMAXRECORD>;
struct ypmap_parms {
domainname domain;
mapname map;
unsigned int ordernum;
peername peer;
};
struct ypreq_key {
domainname domain;
mapname map;
keydat key;
};
struct ypreq_nokey {
domainname domain;
mapname map;
};
struct ypreq_xfr {
ypmap_parms map_parms;
unsigned int transid;
unsigned int prog;
unsigned int port;
};
struct ypresp_val {
ypstat stat;
valdat val;
};
struct ypresp_key_val {
ypstat stat;
#ifdef STUPID_SUN_BUG
/* This is the form as distributed by Sun. But even the Sun NIS
servers expect the values in the other order. So their
implementation somehow must change the order internally. We
don't want to follow this bad example since the user should be
able to use rpcgen on this file. */
keydat key;
valdat val;
#else
valdat val;
keydat key;
#endif
};
struct ypresp_master {
ypstat stat;
peername peer;
};
struct ypresp_order {
ypstat stat;
unsigned int ordernum;
};
union ypresp_all switch (bool more) {
case TRUE:
ypresp_key_val val;
case FALSE:
void;
};
struct ypresp_xfr {
unsigned int transid;
ypxfrstat xfrstat;
};
struct ypmaplist {
mapname map;
ypmaplist *next;
};
struct ypresp_maplist {
ypstat stat;
ypmaplist *maps;
};
enum yppush_status {
YPPUSH_SUCC = 1, /* Success */
YPPUSH_AGE = 2, /* Master's version not newer */
YPPUSH_NOMAP = -1, /* Can't find server for map */
YPPUSH_NODOM = -2, /* Domain not supported */
YPPUSH_RSRC = -3, /* Local resource alloc failure */
YPPUSH_RPC = -4, /* RPC failure talking to server */
YPPUSH_MADDR = -5, /* Can't get master address */
YPPUSH_YPERR = -6, /* YP server/map db error */
YPPUSH_BADARGS = -7, /* Request arguments bad */
YPPUSH_DBM = -8, /* Local dbm operation failed */
YPPUSH_FILE = -9, /* Local file I/O operation failed */
YPPUSH_SKEW = -10, /* Map version skew during transfer */
YPPUSH_CLEAR = -11, /* Can't send "Clear" req to local ypserv */
YPPUSH_FORCE = -12, /* No local order number in map use -f flag. */
YPPUSH_XFRERR = -13, /* ypxfr error */
YPPUSH_REFUSED = -14 /* Transfer request refused by ypserv */
};
struct yppushresp_xfr {
unsigned transid;
yppush_status status;
};
/*
* Response structure and overall result status codes. Success and failure
* represent two separate response message types.
*/
enum ypbind_resptype {
YPBIND_SUCC_VAL = 1,
YPBIND_FAIL_VAL = 2
};
struct ypbind_binding {
opaque ypbind_binding_addr[4]; /* In network order */
opaque ypbind_binding_port[2]; /* In network order */
};
union ypbind_resp switch (ypbind_resptype ypbind_status) {
case YPBIND_FAIL_VAL:
unsigned ypbind_error;
case YPBIND_SUCC_VAL:
ypbind_binding ypbind_bindinfo;
};
/* Detailed failure reason codes for response field ypbind_error*/
const YPBIND_ERR_ERR = 1; /* Internal error */
const YPBIND_ERR_NOSERV = 2; /* No bound server for passed domain */
const YPBIND_ERR_RESC = 3; /* System resource allocation failure */
/*
* Request data structure for ypbind "Set domain" procedure.
*/
struct ypbind_setdom {
domainname ypsetdom_domain;
ypbind_binding ypsetdom_binding;
unsigned ypsetdom_vers;
};
/*
* YP access protocol
*/
program YPPROG {
version YPVERS {
void
YPPROC_NULL(void) = 0;
bool
YPPROC_DOMAIN(domainname) = 1;
bool
YPPROC_DOMAIN_NONACK(domainname) = 2;
ypresp_val
YPPROC_MATCH(ypreq_key) = 3;
ypresp_key_val
YPPROC_FIRST(ypreq_key) = 4;
ypresp_key_val
YPPROC_NEXT(ypreq_key) = 5;
ypresp_xfr
YPPROC_XFR(ypreq_xfr) = 6;
void
YPPROC_CLEAR(void) = 7;
ypresp_all
YPPROC_ALL(ypreq_nokey) = 8;
ypresp_master
YPPROC_MASTER(ypreq_nokey) = 9;
ypresp_order
YPPROC_ORDER(ypreq_nokey) = 10;
ypresp_maplist
YPPROC_MAPLIST(domainname) = 11;
} = 2;
} = 100004;
/*
* YPPUSHPROC_XFRRESP is the callback routine for result of YPPROC_XFR
*/
program YPPUSH_XFRRESPPROG {
version YPPUSH_XFRRESPVERS {
void
YPPUSHPROC_NULL(void) = 0;
#ifdef STUPID_SUN_BUG
/* This is the form as distributed by Sun. But even
the Sun NIS servers expect the values in the other
order. So their implementation somehow must change
the order internally. We don't want to follow this
bad example since the user should be able to use
rpcgen on this file. */
yppushresp_xfr
YPPUSHPROC_XFRRESP(void) = 1;
#else
void
YPPUSHPROC_XFRRESP(yppushresp_xfr) = 1;
#endif
} = 1;
} = 0x40000000; /* transient: could be anything up to 0x5fffffff */
/*
* YP binding protocol
*/
program YPBINDPROG {
version YPBINDVERS {
void
YPBINDPROC_NULL(void) = 0;
ypbind_resp
YPBINDPROC_DOMAIN(domainname) = 1;
void
YPBINDPROC_SETDOM(ypbind_setdom) = 2;
} = 2;
} = 100007;

View File

@ -1,366 +0,0 @@
/*
* This file contains symbols and structures defining the rpc protocol
* between the NIS clients and the NIS servers. The servers
* are the NIS database servers, and the NIS binders.
*/
#ifndef _RPCSVC_YP_PROT_H
#define _RPCSVC_YP_PROT_H
#include <features.h>
#include <rpc/rpc.h>
#include <rpcsvc/ypclnt.h>
__BEGIN_DECLS
/*
* The following procedures are supported by the protocol:
*
* YPPROC_NULL() returns () takes nothing, returns nothing. This indicates
* that the NIS server is alive.
*
* YPPROC_DOMAIN (char *) returns (bool_t) TRUE. Indicates that the
* responding NIS server does serve the named domain; FALSE indicates no
* support.
*
* YPPROC_DOMAIN_NONACK (char *) returns (TRUE) if the NIS server does serve
* the named domain, otherwise does not return. Used in the broadcast case.
*
* YPPROC_MATCH (struct ypreq_key) returns (struct ypresp_val). Returns the
* right-hand value for a passed left-hand key, within a named map and
* domain.
*
* YPPROC_FIRST (struct ypreq_nokey) returns (struct ypresp_key_val).
* Returns the first key-value pair from a named domain and map.
*
* YPPROC_NEXT (struct ypreq_key) returns (struct ypresp_key_val). Returns
* the key-value pair following a passed key-value pair within a named
* domain and map.
*
* YPPROC_XFR (struct ypreq_xfr) returns nothing. Indicates to a server that
* a map should be updated.
*
* YPPROC_CLEAR takes nothing, returns nothing. Instructs a NIS server to
* close the current map, so that old versions of the disk file don't get
* held open.
*
* YPPROC_ALL (struct ypreq_nokey), returns
* union switch (bool_t more) {
* TRUE: (struct ypresp_key_val);
* FALSE: (struct) {};
* }
*
* YPPROC_MASTER (struct ypreq_nokey), returns (ypresp_master)
*
* YPPROC_ORDER (struct ypreq_nokey), returns (ypresp_order)
*
* YPPROC_MAPLIST (char *), returns (struct ypmaplist *)
*/
/* Program and version symbols, magic numbers */
#define YPPROG 100004
#define YPVERS 2
#define YPVERS_ORIG 1
#define YPMAXRECORD 1024
#define YPMAXDOMAIN 64 /* XXX orig. yp_prot.h defines 256 */
#define YPMAXMAP 64
#define YPMAXPEER 64 /* XXX orig. yp_prot.h defines 256 */
/* byte size of a large NIS packet */
#define YPMSGSZ 1600
typedef struct {
u_int keydat_len;
char *keydat_val;
} keydat_t;
typedef struct {
u_int valdat_len;
char *valdat_val;
} valdat_t;
struct ypmap_parms {
char *domain; /* Null string means not available */
char *map; /* Null string means not available */
unsigned int ordernum; /* 0 means not available */
char *owner; /* Null string means not available */
};
/*
* Request parameter structures
*/
struct ypreq_key {
const char *domain;
const char *map;
keydat_t keydat;
};
struct ypreq_nokey {
char *domain;
char *map;
};
struct ypreq_xfr {
struct ypmap_parms map_parms;
u_int transid;
u_int proto;
u_int port;
};
#define ypxfr_domain map_parms.domain
#define ypxfr_map map_parms.map
#define ypxfr_ordernum map_parms.ordernum
#define ypxfr_owner map_parms.owner
/* Return status values */
enum ypstat {
YP_TRUE = 1, /* General purpose success code */
#define YP_TRUE YP_TRUE
YP_NOMORE = 2, /* No more entries in map */
#define YP_NOMORE YP_NOMORE
YP_FALSE = 0, /* General purpose failure code */
#define YP_FALSE YP_FALSE
YP_NOMAP = -1, /* No such map in domain */
#define YP_NOMAP YP_NOMAP
YP_NODOM = -2, /* Domain not supported */
#define YP_NODOM YP_NODOM
YP_NOKEY = -3, /* No such key in map */
#define YP_NOKEY YP_NOKEY
YP_BADOP = -4, /* Invalid operation */
#define YP_BADOP YP_BADOP
YP_BADDB = -5, /* Server data base is bad */
#define YP_BADDB YP_BADDB
YP_YPERR = -6, /* NIS server error */
#define YP_YPERR YP_YPERR
YP_BADARGS = -7, /* Request arguments bad */
#define YP_BADARGS YP_BADARGS
YP_VERS = -8, /* NIS server version mismatch - server can't supply
requested service. */
#define YP_VERS YP_VERS
};
/*
* Response parameter structures
*/
typedef enum ypstat ypstat;
struct ypresp_val {
ypstat status;
valdat_t valdat;
};
struct ypresp_key_val {
ypstat status;
#ifdef STUPID_SUN_BUG
/* This is the form as distributed by Sun. But even the Sun NIS
servers expect the values in the other order. So their
implementation somehow must change the order internally. We
don't want to follow this bad example since the user should be
able to use rpcgen on this file. */
keydat_t keydat;
valdat_t valdat;
#else
valdat_t valdat;
keydat_t keydat;
#endif
};
struct ypresp_master {
ypstat status;
char *master;
};
struct ypresp_order {
ypstat status;
u_int ordernum;
};
struct ypmaplist {
char *map;
#define ypml_name map
struct ypmaplist *next;
#define ypml_next next
};
struct ypresp_maplist {
ypstat status;
struct ypmaplist *list;
};
/*
* Procedure symbols. YPPROC_NULL, YPPROC_DOMAIN, and YPPROC_DOMAIN_NONACK
* must keep the same values (0, 1, and 2) that they had in the first version
* of the protocol.
*/
#define YPPROC_NULL 0
#define YPPROC_DOMAIN 1
#define YPPROC_DOMAIN_NONACK 2
#define YPPROC_MATCH 3
#define YPPROC_FIRST 4
#define YPPROC_NEXT 5
#define YPPROC_XFR 6
#define YPPROC_CLEAR 7
#define YPPROC_ALL 8
#define YPPROC_MASTER 9
#define YPPROC_ORDER 10
#define YPPROC_MAPLIST 11
#define YPPROC_NEWXFR 12
/*
* Protocol between clients and NIS binder servers
*/
/*
* The following procedures are supported by the protocol:
*
* YPBINDPROC_NULL() returns ()
* takes nothing, returns nothing
*
* YPBINDPROC_DOMAIN takes (char *) returns (struct ypbind_resp)
*
* YPBINDPROC_SETDOM takes (struct ypbind_setdom) returns nothing
*/
/* Program and version symbols, magic numbers */
#define YPBINDPROG 100007
#define YPBINDVERS 2
#define YPBINDVERS_ORIG 1
/* Procedure symbols */
#define YPBINDPROC_NULL 0
#define YPBINDPROC_DOMAIN 1
#define YPBINDPROC_SETDOM 2
/*
* Response structure and overall result status codes. Success and failure
* represent two separate response message types.
*/
enum ypbind_resptype {YPBIND_SUCC_VAL = 1, YPBIND_FAIL_VAL = 2};
struct ypbind_binding {
struct in_addr ypbind_binding_addr; /* In network order */
unsigned short int ypbind_binding_port; /* In network order */
};
struct ypbind_resp {
enum ypbind_resptype ypbind_status;
union {
u_int ypbind_error;
struct ypbind_binding ypbind_bindinfo;
} ypbind_respbody;
};
/* Detailed failure reason codes for response field ypbind_error*/
#define YPBIND_ERR_ERR 1 /* Internal error */
#define YPBIND_ERR_NOSERV 2 /* No bound server for passed domain */
#define YPBIND_ERR_RESC 3 /* System resource allocation failure */
/*
* Request data structure for ypbind "Set domain" procedure.
*/
struct ypbind_setdom {
char *ypsetdom_domain;
struct ypbind_binding ypsetdom_binding;
u_int ypsetdom_vers;
};
#define ypsetdom_addr ypsetdom_binding.ypbind_binding_addr
#define ypsetdom_port ypsetdom_binding.ypbind_binding_port
/*
* Protocol between clients (ypxfr, only) and yppush
* yppush speaks a protocol in the transient range, which
* is supplied to ypxfr as a command-line parameter when it
* is activated by ypserv.
*/
#define YPPUSHVERS 1
#define YPPUSHVERS_ORIG 1
/* Procedure symbols */
#define YPPUSHPROC_NULL 0
#define YPPUSHPROC_XFRRESP 1
/* Status values for yppushresp_xfr.status */
enum yppush_status {
YPPUSH_SUCC = 1, /* Success */
#define YPPUSH_SUCC YPPUSH_SUCC
YPPUSH_AGE = 2, /* Master's version not newer */
#define YPPUSH_AGE YPPUSH_AGE
YPPUSH_NOMAP = -1, /* Can't find server for map */
#define YPPUSH_NOMAP YPPUSH_NOMAP
YPPUSH_NODOM = -2, /* Domain not supported */
#define YPPUSH_NODOM YPPUSH_NODOM
YPPUSH_RSRC = -3, /* Local resouce alloc failure */
#define YPPUSH_RSRC YPPUSH_RSRC
YPPUSH_RPC = -4, /* RPC failure talking to server */
#define YPPUSH_RPC YPPUSH_RPC
YPPUSH_MADDR = -5, /* Can't get master address */
#define YPPUSH_MADDR YPPUSH_MADDR
YPPUSH_YPERR = -6, /* NIS server/map db error */
#define YPPUSH_YPERR YPPUSH_YPERR
YPPUSH_BADARGS = -7, /* Request arguments bad */
#define YPPUSH_BADARGS YPPUSH_BADARGS
YPPUSH_DBM = -8, /* Local dbm operation failed */
#define YPPUSH_DBM YPPUSH_DBM
YPPUSH_FILE = -9, /* Local file I/O operation failed */
#define YPPUSH_FILE YPPUSH_FILE
YPPUSH_SKEW = -10, /* Map version skew during transfer */
#define YPPUSH_SKEW YPPUSH_SKEW
YPPUSH_CLEAR = -11, /* Can't send "Clear" req to local ypserv */
#define YPPUSH_CLEAR YPPUSH_CLEAR
YPPUSH_FORCE = -12, /* No local order number in map - use -f flag*/
#define YPPUSH_FORCE YPPUSH_FORCE
YPPUSH_XFRERR = -13, /* ypxfr error */
#define YPPUSH_XFRERR YPPUSH_XFRERR
YPPUSH_REFUSED = -14, /* Transfer request refused by ypserv */
#define YPPUSH_REFUSED YPPUSH_REFUSED
YPPUSH_NOALIAS = -15 /* Alias not found for map or domain */
#define YPPUSH_NOALIAS YPPUSH_NOALIAS
};
typedef enum yppush_status yppush_status;
struct yppushresp_xfr {
u_int transid;
yppush_status status;
};
struct ypresp_all {
bool_t more;
union {
struct ypresp_key_val val;
} ypresp_all_u;
};
extern bool_t xdr_ypreq_key (XDR *__xdrs, struct ypreq_key * __objp);
extern bool_t xdr_ypreq_nokey (XDR *__xdrs, struct ypreq_nokey * __objp);
extern bool_t xdr_ypreq_xfr (XDR *__xdrs, struct ypreq_xfr * __objp);
extern bool_t xdr_ypresp_val (XDR *__xdrs, struct ypresp_val * __objp);
extern bool_t xdr_ypresp_key_val (XDR *__xdrs, struct ypresp_key_val * __objp);
extern bool_t xdr_ypbind_resp (XDR *__xdrs, struct ypbind_resp * __objp);
extern bool_t xdr_ypbind_setdom (XDR *__xdrs, struct ypbind_setdom * __objp);
extern bool_t xdr_ypmap_parms (XDR *__xdrs, struct ypmap_parms * __objp);
extern bool_t xdr_yppushresp_xfr (XDR *__xdrs, struct yppushresp_xfr * __objp);
extern bool_t xdr_ypresp_order (XDR *__xdrs, struct ypresp_order * __objp);
extern bool_t xdr_ypresp_master (XDR *__xdrs, struct ypresp_master * __objp);
extern bool_t xdr_ypall (XDR *__xdrs, struct ypall_callback * __objp);
extern bool_t xdr_ypresp_maplist (XDR *__xdrs, struct ypresp_maplist * __objp);
extern bool_t xdr_ypbind_binding (XDR *__xdrs, struct ypbind_binding * __objp);
extern bool_t xdr_ypbind_resptype (XDR *__xdrs, enum ypbind_resptype * __objp);
extern bool_t xdr_ypstat (XDR *__xdrs, enum ypbind_resptype * __objp);
extern bool_t xdr_ypresp_all (XDR *__xdrs, struct ypresp_all * __objp);
extern bool_t xdr_domainname (XDR *__xdrs, char ** __objp);
__END_DECLS
#endif /* _RPCSVC_YP_PROT_H */

View File

@ -32,12 +32,6 @@
#include "../nss/nsswitch.h"
#ifdef LINK_OBSOLETE_NSL
# define DEFAULT_CONFIG "compat [NOTFOUND=return] files"
#else
# define DEFAULT_CONFIG "files"
#endif
/* Type of the lookup function. */
typedef enum nss_status (*initgroups_dyn_function) (const char *, gid_t,
long int *, long int *,
@ -88,7 +82,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
int no_more;
if (group_database == NULL)
no_more = __nss_database_lookup2 ("group", NULL, DEFAULT_CONFIG,
no_more = __nss_database_lookup2 ("group", NULL, "files",
&group_database);
else
no_more = 0;

View File

@ -19,10 +19,6 @@
#include <config.h>
#define DATABASE_NAME group
#ifdef LINK_OBSOLETE_NSL
# define DEFAULT_CONFIG "compat [NOTFOUND=return] files"
#else
# define DEFAULT_CONFIG "files"
#endif
#define DEFAULT_CONFIG "files"
#include "XXX-lookup.c"

View File

@ -42,14 +42,6 @@
#include <sysdep.h>
#include <config.h>
#ifdef LINK_OBSOLETE_NSL
# define DEFAULT_CONFIG "compat [NOTFOUND=return] files"
# define DEFAULT_DEFCONFIG "nis [NOTFOUND=return] files"
#else
# define DEFAULT_CONFIG "files"
# define DEFAULT_DEFCONFIG "files"
#endif
/* Prototypes for the local functions. */
static name_database *nss_parse_file (const char *fname);
static name_database_entry *nss_getline (char *line);
@ -161,7 +153,7 @@ __nss_database_lookup2 (const char *database, const char *alternate_name,
or null to use the most common default. */
if (*ni == NULL)
{
*ni = nss_parse_service_list (defconfig ?: DEFAULT_DEFCONFIG);
*ni = nss_parse_service_list (defconfig ?: "files");
if (*ni != NULL)
{
/* Record the memory we've just allocated in defconfig_entries list,
@ -845,8 +837,8 @@ __nss_disable_nscd (void (*cb) (size_t, struct traced_file *))
is_nscd = true;
/* Find all the relevant modules so that the init functions are called. */
nss_load_all_libraries ("passwd", DEFAULT_CONFIG);
nss_load_all_libraries ("group", DEFAULT_CONFIG);
nss_load_all_libraries ("passwd", "files");
nss_load_all_libraries ("group", "files");
nss_load_all_libraries ("hosts", "dns [!UNAVAIL=return] files");
nss_load_all_libraries ("services", NULL);

View File

@ -15,8 +15,6 @@
# dns Use DNS (Domain Name Service)
# files Use the local files in /etc
# hesiod Use Hesiod (DNS) for user lookups
# nis Use NIS (NIS version 2), also called YP
# nisplus Use NIS+ (NIS version 3)
#
# See `info libc 'NSS Basics'` for more information.
#

View File

@ -19,10 +19,6 @@
#include <config.h>
#define DATABASE_NAME passwd
#ifdef LINK_OBSOLETE_NSL
# define DEFAULT_CONFIG "compat [NOTFOUND=return] files"
#else
# define DEFAULT_CONFIG "files"
#endif
#define DEFAULT_CONFIG "files"
#include "XXX-lookup.c"

View File

@ -20,10 +20,6 @@
#define DATABASE_NAME shadow
#define ALTERNATE_NAME passwd
#ifdef LINK_OBSOLETE_NSL
# define DEFAULT_CONFIG "compat [NOTFOUND=return] files"
#else
# define DEFAULT_CONFIG "files"
#endif
#define DEFAULT_CONFIG "files"
#include "XXX-lookup.c"

View File

@ -396,8 +396,7 @@ class Context(object):
extra_glibcs=[{'variant': 'disable-multi-arch',
'cfg': ['--disable-multi-arch']},
{'variant': 'enable-obsolete',
'cfg': ['--enable-obsolete-rpc',
'--enable-obsolete-nsl']},
'cfg': ['--enable-obsolete-rpc']},
{'variant': 'static-pie',
'cfg': ['--enable-static-pie']},
{'variant': 'x32-static-pie',
@ -414,8 +413,7 @@ class Context(object):
{'variant': 'enable-obsolete',
'arch': 'i686',
'ccopts': '-m32 -march=i686',
'cfg': ['--enable-obsolete-rpc',
'--enable-obsolete-nsl']},
'cfg': ['--enable-obsolete-rpc']},
{'arch': 'i486',
'ccopts': '-m32 -march=i486'},
{'arch': 'i586',

View File

@ -43,8 +43,6 @@ libresolv=2
libnss_files=2
libnss_dns=2
libnss_compat=2
libnss_nis=2
libnss_nisplus=2
libnss_ldap=2
libnss_hesiod=2
libnss_db=2

View File

@ -56,8 +56,6 @@ else ifeq (dlfcn,$(subdir))
LDLIBS-dl.so += $(objdir)/mach/libmachuser.so
else ifeq (nis,$(subdir))
LDLIBS-nsl.so += $(objdir)/mach/libmachuser.so
LDLIBS-nss_nis.so += $(objdir)/mach/libmachuser.so
LDLIBS-nss_nisplus.so += $(objdir)/mach/libmachuser.so
LDLIBS-nss_compat.so += $(objdir)/mach/libmachuser.so
else ifeq (nss,$(subdir))
LDLIBS-nss.so += $(objdir)/mach/libmachuser.so

View File

@ -15,8 +15,6 @@ libresolv=2 GLIBC_2.0 GLIBC_2.2
libnss_files=2 GLIBC_2.0 GLIBC_2.2
libnss_dns=2 GLIBC_2.0 GLIBC_2.2
libnss_compat=2 GLIBC_2.0 GLIBC_2.2
libnss_nis=2 GLIBC_2.0 GLIBC_2.2
libnss_nisplus=2 GLIBC_2.0 GLIBC_2.2
libnss_ldap=2 GLIBC_2.0 GLIBC_2.2
libnss_hesiod=2 GLIBC_2.0 GLIBC_2.2