Update.
1998-01-31 Phil Blundell <philb@gnu.org> * configure.in: Add --without-cvs option to suppress automatic checkin of regenerated files. * config.make: Likewise. * Makefile: Respect with-cvs setting. * Makerules: Likewise. * configure.in: Allow the standalone ARM port to be configured. 1998-01-31 Thorsten Kukuk <kukuk@vt.uni-paderborn.de> * grp/getgrgid_r.c: Define USE_NSCD. * grp/getgrnam_r.c: Likewise. * pwd/getpwuid_r.c: Likewise. * pwd/getpwnam_r.c: Likewise. * sysdeps/unix/inet/Subdirs: Add nscd subdir. * nss/getXXbyYY_r.c: Try at first nscd. * nscd/Makefile: New, for the Name Switch Cache Daemon (nscd). * nscd/connections.c: New file. * nscd/dbg_log.c: New file. * nscd/dbg_log.h: New file. * nscd/grpcache.c: New file. * nscd/nscd.c: New file. * nscd/nscd.h: New file. * nscd/nscd_conf.c: New file. * nscd/nscd_stat.c: New file. * nscd/pwdcache.c: New file. * nscd/nscd_getgr_r.c: New, client code, linked into libc. * nscd/nscd_getpw_r.c: Likewise. * nscd/nscd_proto.h: New, prototypes for client functions. * nscd/nscd.conf: New, example for a configuration file. * nscd/nscd.init: New, example for a startup script. * nscd/getgrgid_r.c: Old grp/getgrgid_r version, used from nscd to avoid deadlocks. * nscd/getgrnam_r.c: Likewise. * nscd/getpwnam_r.c: Likewise. * nscd/getpwuid_r.c: Likewise. * nis/nis_cache.c: New file. * nis/nis_cache2.h: New file. * nis/nis_cache2_xdr.c: New file.
This commit is contained in:
parent
4eb36693e4
commit
d67281a7ea
51
ChangeLog
51
ChangeLog
@ -1,3 +1,48 @@
|
||||
1998-01-31 Phil Blundell <philb@gnu.org>
|
||||
|
||||
* configure.in: Add --without-cvs option to suppress automatic
|
||||
checkin of regenerated files.
|
||||
* config.make: Likewise.
|
||||
* Makefile: Respect with-cvs setting.
|
||||
* Makerules: Likewise.
|
||||
|
||||
* configure.in: Allow the standalone ARM port to be configured.
|
||||
|
||||
1998-01-31 Thorsten Kukuk <kukuk@vt.uni-paderborn.de>
|
||||
|
||||
* grp/getgrgid_r.c: Define USE_NSCD.
|
||||
* grp/getgrnam_r.c: Likewise.
|
||||
* pwd/getpwuid_r.c: Likewise.
|
||||
* pwd/getpwnam_r.c: Likewise.
|
||||
|
||||
* sysdeps/unix/inet/Subdirs: Add nscd subdir.
|
||||
|
||||
* nss/getXXbyYY_r.c: Try at first nscd.
|
||||
|
||||
* nscd/Makefile: New, for the Name Switch Cache Daemon (nscd).
|
||||
* nscd/connections.c: New file.
|
||||
* nscd/dbg_log.c: New file.
|
||||
* nscd/dbg_log.h: New file.
|
||||
* nscd/grpcache.c: New file.
|
||||
* nscd/nscd.c: New file.
|
||||
* nscd/nscd.h: New file.
|
||||
* nscd/nscd_conf.c: New file.
|
||||
* nscd/nscd_stat.c: New file.
|
||||
* nscd/pwdcache.c: New file.
|
||||
|
||||
* nscd/nscd_getgr_r.c: New, client code, linked into libc.
|
||||
* nscd/nscd_getpw_r.c: Likewise.
|
||||
* nscd/nscd_proto.h: New, prototypes for client functions.
|
||||
|
||||
* nscd/nscd.conf: New, example for a configuration file.
|
||||
* nscd/nscd.init: New, example for a startup script.
|
||||
|
||||
* nscd/getgrgid_r.c: Old grp/getgrgid_r version, used from nscd to
|
||||
avoid deadlocks.
|
||||
* nscd/getgrnam_r.c: Likewise.
|
||||
* nscd/getpwnam_r.c: Likewise.
|
||||
* nscd/getpwuid_r.c: Likewise.
|
||||
|
||||
1998-01-31 11:44 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* intl/Makefile: Use CVSOPTS in cvs invocation.
|
||||
@ -520,9 +565,9 @@
|
||||
|
||||
* nis/Makefile: Distribute nis_cache2.h, add nis cache functions
|
||||
to routines.
|
||||
* nis/nis_cache.c: New.
|
||||
* nis/nis_cache2.h: New.
|
||||
* nis/nis_cache2_xdr.c: New.
|
||||
* nis/nis_cache.c: New file.
|
||||
* nis/nis_cache2.h: New file.
|
||||
* nis/nis_cache2_xdr.c: New file.
|
||||
* nis/nis_call.c: Changes for cache2_info parameter.
|
||||
* nis/nis_checkpoint.c: Likewise.
|
||||
* nis/nis_intern.h: Likewise.
|
||||
|
158
configure
vendored
158
configure
vendored
@ -30,6 +30,8 @@ ac_help="$ac_help
|
||||
--with-binutils=PATH specify location of binutils (as and ld)"
|
||||
ac_help="$ac_help
|
||||
--with-elf if using the ELF object format"
|
||||
ac_help="$ac_help
|
||||
--without-cvs if CVS should not be used"
|
||||
ac_help="$ac_help
|
||||
--enable-libio build in GNU libio instead of GNU stdio"
|
||||
ac_help="$ac_help
|
||||
@ -618,6 +620,15 @@ else
|
||||
elf=no
|
||||
fi
|
||||
|
||||
# Check whether --with-cvs or --without-cvs was given.
|
||||
if test "${with_cvs+set}" = set; then
|
||||
withval="$with_cvs"
|
||||
with_cvs=$withval
|
||||
else
|
||||
with_cvs=yes
|
||||
fi
|
||||
|
||||
|
||||
|
||||
# Check whether --enable-libio or --disable-libio was given.
|
||||
if test "${enable_libio+set}" = set; then
|
||||
@ -762,7 +773,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
|
||||
fi
|
||||
|
||||
echo $ac_n "checking host system type""... $ac_c" 1>&6
|
||||
echo "configure:766: checking host system type" >&5
|
||||
echo "configure:777: checking host system type" >&5
|
||||
|
||||
host_alias=$host
|
||||
case "$host_alias" in
|
||||
@ -805,8 +816,8 @@ esac
|
||||
### platforms.
|
||||
###
|
||||
if test -z "$enable_hacker_mode"; then
|
||||
case "$host_os" in
|
||||
linux* | gnu*)
|
||||
case "$machine-$host_os" in
|
||||
*-linux* | *-gnu* | arm*-none*)
|
||||
;;
|
||||
*)
|
||||
echo "*** The GNU C library is currently not available for this platform."
|
||||
@ -881,7 +892,7 @@ fi
|
||||
# This can take a while to compute.
|
||||
sysdep_dir=$srcdir/sysdeps
|
||||
echo $ac_n "checking sysdep dirs""... $ac_c" 1>&6
|
||||
echo "configure:885: checking sysdep dirs" >&5
|
||||
echo "configure:896: checking sysdep dirs" >&5
|
||||
# Make sco3.2v4 become sco3.2.4 and sunos4.1.1_U1 become sunos4.1.1.U1.
|
||||
os="`echo $os | sed 's/\([0-9A-Z]\)[v_]\([0-9A-Z]\)/\1.\2/g'`"
|
||||
|
||||
@ -1082,7 +1093,7 @@ echo "$ac_t""sysdeps/generic" 1>&6
|
||||
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
|
||||
# ./install, which can be erroneously created by make from ./install.sh.
|
||||
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
|
||||
echo "configure:1086: checking for a BSD compatible install" >&5
|
||||
echo "configure:1097: checking for a BSD compatible install" >&5
|
||||
if test -z "$INSTALL"; then
|
||||
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
@ -1136,7 +1147,7 @@ if test "$INSTALL" = "${srcdir}/install-sh -c"; then
|
||||
INSTALL='\$(..)./install-sh -c'
|
||||
fi
|
||||
echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
|
||||
echo "configure:1140: checking whether ln -s works" >&5
|
||||
echo "configure:1151: checking whether ln -s works" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1161,7 +1172,7 @@ do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
set dummy $ac_prog; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1165: checking for $ac_word" >&5
|
||||
echo "configure:1176: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_MSGFMT'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1193,7 +1204,7 @@ test -n "$MSGFMT" || MSGFMT=":"
|
||||
# Extract the first word of "makeinfo", so it can be a program name with args.
|
||||
set dummy makeinfo; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1197: checking for $ac_word" >&5
|
||||
echo "configure:1208: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_MAKEINFO'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1233,7 +1244,7 @@ fi
|
||||
# Extract the first word of "gcc", so it can be a program name with args.
|
||||
set dummy gcc; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1237: checking for $ac_word" >&5
|
||||
echo "configure:1248: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1262,7 +1273,7 @@ if test -z "$CC"; then
|
||||
# Extract the first word of "cc", so it can be a program name with args.
|
||||
set dummy cc; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1266: checking for $ac_word" >&5
|
||||
echo "configure:1277: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1310,7 +1321,7 @@ fi
|
||||
fi
|
||||
|
||||
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
|
||||
echo "configure:1314: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
|
||||
echo "configure:1325: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
|
||||
|
||||
ac_ext=c
|
||||
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
|
||||
@ -1320,11 +1331,11 @@ ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS
|
||||
cross_compiling=$ac_cv_prog_cc_cross
|
||||
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1324 "configure"
|
||||
#line 1335 "configure"
|
||||
#include "confdefs.h"
|
||||
main(){return(0);}
|
||||
EOF
|
||||
if { (eval echo configure:1328: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
if { (eval echo configure:1339: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
ac_cv_prog_cc_works=yes
|
||||
# If we can't run a trivial program, we are probably using a cross compiler.
|
||||
if (./conftest; exit) 2>/dev/null; then
|
||||
@ -1347,13 +1358,13 @@ else
|
||||
cross_linkable=yes
|
||||
fi
|
||||
echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
|
||||
echo "configure:1351: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
|
||||
echo "configure:1362: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
|
||||
echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
|
||||
|
||||
cross_compiling=$ac_cv_prog_cc_cross
|
||||
|
||||
echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
|
||||
echo "configure:1357: checking whether we are using GNU C" >&5
|
||||
echo "configure:1368: checking whether we are using GNU C" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1362,7 +1373,7 @@ else
|
||||
yes;
|
||||
#endif
|
||||
EOF
|
||||
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1366: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
|
||||
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1377: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
|
||||
ac_cv_prog_gcc=yes
|
||||
else
|
||||
ac_cv_prog_gcc=no
|
||||
@ -1379,7 +1390,7 @@ if test $ac_cv_prog_gcc = yes; then
|
||||
yes;
|
||||
#endif
|
||||
EOF
|
||||
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1383: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
|
||||
if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1394: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
|
||||
if test -z "$CFLAGS"; then
|
||||
CFLAGS="-g -O2"
|
||||
fi
|
||||
@ -1391,7 +1402,7 @@ else
|
||||
fi
|
||||
|
||||
echo $ac_n "checking build system type""... $ac_c" 1>&6
|
||||
echo "configure:1395: checking build system type" >&5
|
||||
echo "configure:1406: checking build system type" >&5
|
||||
|
||||
build_alias=$build
|
||||
case "$build_alias" in
|
||||
@ -1414,7 +1425,7 @@ do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
set dummy $ac_prog; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1418: checking for $ac_word" >&5
|
||||
echo "configure:1429: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_BUILD_CC'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1445,7 +1456,7 @@ done
|
||||
fi
|
||||
|
||||
echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
|
||||
echo "configure:1449: checking how to run the C preprocessor" >&5
|
||||
echo "configure:1460: checking how to run the C preprocessor" >&5
|
||||
# On Suns, sometimes $CPP names a directory.
|
||||
if test -n "$CPP" && test -d "$CPP"; then
|
||||
CPP=
|
||||
@ -1460,13 +1471,13 @@ else
|
||||
# On the NeXT, cc -E runs the code through the compiler's parser,
|
||||
# not just through cpp.
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1464 "configure"
|
||||
#line 1475 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <assert.h>
|
||||
Syntax Error
|
||||
EOF
|
||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||
{ (eval echo configure:1470: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
{ (eval echo configure:1481: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
ac_err=`grep -v '^ *+' conftest.out`
|
||||
if test -z "$ac_err"; then
|
||||
:
|
||||
@ -1477,13 +1488,13 @@ else
|
||||
rm -rf conftest*
|
||||
CPP="${CC-cc} -E -traditional-cpp"
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1481 "configure"
|
||||
#line 1492 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <assert.h>
|
||||
Syntax Error
|
||||
EOF
|
||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||
{ (eval echo configure:1487: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
{ (eval echo configure:1498: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
ac_err=`grep -v '^ *+' conftest.out`
|
||||
if test -z "$ac_err"; then
|
||||
:
|
||||
@ -1516,7 +1527,7 @@ LD=`$CC -print-file-name=ld`
|
||||
|
||||
# Determine whether we are using GNU binutils.
|
||||
echo $ac_n "checking whether $AS is GNU as""... $ac_c" 1>&6
|
||||
echo "configure:1520: checking whether $AS is GNU as" >&5
|
||||
echo "configure:1531: checking whether $AS is GNU as" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_prog_as_gnu'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1534,7 +1545,7 @@ rm -f a.out
|
||||
gnu_as=$libc_cv_prog_as_gnu
|
||||
|
||||
echo $ac_n "checking whether $LD is GNU ld""... $ac_c" 1>&6
|
||||
echo "configure:1538: checking whether $LD is GNU ld" >&5
|
||||
echo "configure:1549: checking whether $LD is GNU ld" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_prog_ld_gnu'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1558,7 +1569,7 @@ fi
|
||||
# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
|
||||
set dummy ${ac_tool_prefix}ar; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1562: checking for $ac_word" >&5
|
||||
echo "configure:1573: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1589,7 +1600,7 @@ fi
|
||||
# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
|
||||
set dummy ${ac_tool_prefix}ranlib; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1593: checking for $ac_word" >&5
|
||||
echo "configure:1604: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1620,7 +1631,7 @@ if test -n "$ac_tool_prefix"; then
|
||||
# Extract the first word of "ranlib", so it can be a program name with args.
|
||||
set dummy ranlib; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1624: checking for $ac_word" >&5
|
||||
echo "configure:1635: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1655,7 +1666,7 @@ fi
|
||||
# Extract the first word of "bash", so it can be a program name with args.
|
||||
set dummy bash; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1659: checking for $ac_word" >&5
|
||||
echo "configure:1670: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_path_BASH'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1697,7 +1708,7 @@ if test "$BASH" = no; then
|
||||
# Extract the first word of "ksh", so it can be a program name with args.
|
||||
set dummy ksh; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1701: checking for $ac_word" >&5
|
||||
echo "configure:1712: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_path_KSH'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1743,7 +1754,7 @@ do
|
||||
# Extract the first word of "$ac_prog", so it can be a program name with args.
|
||||
set dummy $ac_prog; ac_word=$2
|
||||
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
|
||||
echo "configure:1747: checking for $ac_word" >&5
|
||||
echo "configure:1758: checking for $ac_word" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_path_PERL'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1778,7 +1789,7 @@ test -n "$PERL" || PERL="no"
|
||||
|
||||
|
||||
echo $ac_n "checking for signed size_t type""... $ac_c" 1>&6
|
||||
echo "configure:1782: checking for signed size_t type" >&5
|
||||
echo "configure:1793: checking for signed size_t type" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_signed_size_t'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1802,12 +1813,12 @@ EOF
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for libc-friendly stddef.h""... $ac_c" 1>&6
|
||||
echo "configure:1806: checking for libc-friendly stddef.h" >&5
|
||||
echo "configure:1817: checking for libc-friendly stddef.h" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_friendly_stddef'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1811 "configure"
|
||||
#line 1822 "configure"
|
||||
#include "confdefs.h"
|
||||
#define __need_size_t
|
||||
#define __need_wchar_t
|
||||
@ -1822,7 +1833,7 @@ size_t size; wchar_t wchar;
|
||||
if (&size == NULL || &wchar == NULL) abort ();
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:1826: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:1837: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
libc_cv_friendly_stddef=yes
|
||||
else
|
||||
@ -1841,7 +1852,7 @@ override stddef.h = # The installed <stddef.h> seems to be libc-friendly."
|
||||
fi
|
||||
|
||||
echo $ac_n "checking whether we need to use -P to assemble .S files""... $ac_c" 1>&6
|
||||
echo "configure:1845: checking whether we need to use -P to assemble .S files" >&5
|
||||
echo "configure:1856: checking whether we need to use -P to assemble .S files" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_need_minus_P'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1872,7 +1883,7 @@ if test $ac_cv_prog_gcc = yes; then
|
||||
# We must check this even if -pipe is not given here, because the user
|
||||
# might do `make CFLAGS=-pipe'.
|
||||
echo $ac_n "checking for gcc 2.7.x -pipe bug""... $ac_c" 1>&6
|
||||
echo "configure:1876: checking for gcc 2.7.x -pipe bug" >&5
|
||||
echo "configure:1887: checking for gcc 2.7.x -pipe bug" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_gcc_pipe_bug'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1901,7 +1912,7 @@ else
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for assembler global-symbol directive""... $ac_c" 1>&6
|
||||
echo "configure:1905: checking for assembler global-symbol directive" >&5
|
||||
echo "configure:1916: checking for assembler global-symbol directive" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_asm_global_directive'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1931,7 +1942,7 @@ EOF
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for .set assembler directive""... $ac_c" 1>&6
|
||||
echo "configure:1935: checking for .set assembler directive" >&5
|
||||
echo "configure:1946: checking for .set assembler directive" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_asm_set_directive'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1965,7 +1976,7 @@ EOF
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for .symver assembler directive""... $ac_c" 1>&6
|
||||
echo "configure:1969: checking for .symver assembler directive" >&5
|
||||
echo "configure:1980: checking for .symver assembler directive" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_asm_symver_directive'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -1984,7 +1995,7 @@ fi
|
||||
|
||||
echo "$ac_t""$libc_cv_asm_symver_directive" 1>&6
|
||||
echo $ac_n "checking for ld --version-script""... $ac_c" 1>&6
|
||||
echo "configure:1988: checking for ld --version-script" >&5
|
||||
echo "configure:1999: checking for ld --version-script" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_ld_version_script_option'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -2007,7 +2018,7 @@ EOF
|
||||
if { ac_try='${CC-cc} $CFLAGS -shared -o conftest.so conftest.o
|
||||
-nostartfiles -nostdlib
|
||||
-Wl,--version-script,conftest.map
|
||||
1>&5'; { (eval echo configure:2011: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
|
||||
1>&5'; { (eval echo configure:2022: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
|
||||
then
|
||||
libc_cv_ld_version_script_option=yes
|
||||
else
|
||||
@ -2045,7 +2056,7 @@ if test $VERSIONING = no; then
|
||||
fi
|
||||
if test $elf = yes; then
|
||||
echo $ac_n "checking for .previous assembler directive""... $ac_c" 1>&6
|
||||
echo "configure:2049: checking for .previous assembler directive" >&5
|
||||
echo "configure:2060: checking for .previous assembler directive" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_asm_previous_directive'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -2053,7 +2064,7 @@ else
|
||||
.section foo_section
|
||||
.previous
|
||||
EOF
|
||||
if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2057: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2068: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
libc_cv_asm_previous_directive=yes
|
||||
else
|
||||
libc_cv_asm_previous_directive=no
|
||||
@ -2069,7 +2080,7 @@ EOF
|
||||
|
||||
else
|
||||
echo $ac_n "checking for .popsection assembler directive""... $ac_c" 1>&6
|
||||
echo "configure:2073: checking for .popsection assembler directive" >&5
|
||||
echo "configure:2084: checking for .popsection assembler directive" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_asm_popsection_directive'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -2077,7 +2088,7 @@ else
|
||||
.pushsection foo_section
|
||||
.popsection
|
||||
EOF
|
||||
if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2081: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'; { (eval echo configure:2092: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
libc_cv_asm_popsection_directive=yes
|
||||
else
|
||||
libc_cv_asm_popsection_directive=no
|
||||
@ -2097,12 +2108,12 @@ fi
|
||||
|
||||
if test $elf != yes; then
|
||||
echo $ac_n "checking for .init and .fini sections""... $ac_c" 1>&6
|
||||
echo "configure:2101: checking for .init and .fini sections" >&5
|
||||
echo "configure:2112: checking for .init and .fini sections" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_have_initfini'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2106 "configure"
|
||||
#line 2117 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
int main() {
|
||||
@ -2111,7 +2122,7 @@ asm (".section .init");
|
||||
asm (".text");
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:2115: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:2126: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
rm -rf conftest*
|
||||
libc_cv_have_initfini=yes
|
||||
else
|
||||
@ -2139,19 +2150,19 @@ if test $elf = yes; then
|
||||
else
|
||||
if test $ac_cv_prog_cc_works = yes; then
|
||||
echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
|
||||
echo "configure:2143: checking for _ prefix on C symbol names" >&5
|
||||
echo "configure:2154: checking for _ prefix on C symbol names" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2148 "configure"
|
||||
#line 2159 "configure"
|
||||
#include "confdefs.h"
|
||||
asm ("_glibc_foobar:");
|
||||
int main() {
|
||||
glibc_foobar ();
|
||||
; return 0; }
|
||||
EOF
|
||||
if { (eval echo configure:2155: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
if { (eval echo configure:2166: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
|
||||
rm -rf conftest*
|
||||
libc_cv_asm_underscores=yes
|
||||
else
|
||||
@ -2166,17 +2177,17 @@ fi
|
||||
echo "$ac_t""$libc_cv_asm_underscores" 1>&6
|
||||
else
|
||||
echo $ac_n "checking for _ prefix on C symbol names""... $ac_c" 1>&6
|
||||
echo "configure:2170: checking for _ prefix on C symbol names" >&5
|
||||
echo "configure:2181: checking for _ prefix on C symbol names" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_asm_underscores'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 2175 "configure"
|
||||
#line 2186 "configure"
|
||||
#include "confdefs.h"
|
||||
void underscore_test(void) {
|
||||
return; }
|
||||
EOF
|
||||
if { (eval echo configure:2180: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if { (eval echo configure:2191: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
|
||||
if grep _underscore_test conftest* >/dev/null; then
|
||||
rm -f conftest*
|
||||
libc_cv_asm_underscores=yes
|
||||
@ -2209,7 +2220,7 @@ if test $elf = yes; then
|
||||
libc_cv_asm_weakext_directive=no
|
||||
else
|
||||
echo $ac_n "checking for assembler .weak directive""... $ac_c" 1>&6
|
||||
echo "configure:2213: checking for assembler .weak directive" >&5
|
||||
echo "configure:2224: checking for assembler .weak directive" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_asm_weak_directive'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -2232,7 +2243,7 @@ echo "$ac_t""$libc_cv_asm_weak_directive" 1>&6
|
||||
|
||||
if test $libc_cv_asm_weak_directive = no; then
|
||||
echo $ac_n "checking for assembler .weakext directive""... $ac_c" 1>&6
|
||||
echo "configure:2236: checking for assembler .weakext directive" >&5
|
||||
echo "configure:2247: checking for assembler .weakext directive" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_asm_weakext_directive'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -2269,7 +2280,7 @@ EOF
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for ld --no-whole-archive""... $ac_c" 1>&6
|
||||
echo "configure:2273: checking for ld --no-whole-archive" >&5
|
||||
echo "configure:2284: checking for ld --no-whole-archive" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_ld_no_whole_archive'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -2280,7 +2291,7 @@ __throw () {}
|
||||
EOF
|
||||
if { ac_try='${CC-cc} $CFLAGS
|
||||
-nostdlib -nostartfiles -Wl,--no-whole-archive
|
||||
-o conftest conftest.c 1>&5'; { (eval echo configure:2284: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
-o conftest conftest.c 1>&5'; { (eval echo configure:2295: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
libc_cv_ld_no_whole_archive=yes
|
||||
else
|
||||
libc_cv_ld_no_whole_archive=no
|
||||
@ -2291,7 +2302,7 @@ fi
|
||||
echo "$ac_t""$libc_cv_ld_no_whole_archive" 1>&6
|
||||
|
||||
echo $ac_n "checking for gcc -fno-exceptions""... $ac_c" 1>&6
|
||||
echo "configure:2295: checking for gcc -fno-exceptions" >&5
|
||||
echo "configure:2306: checking for gcc -fno-exceptions" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_gcc_no_exceptions'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -2302,7 +2313,7 @@ __throw () {}
|
||||
EOF
|
||||
if { ac_try='${CC-cc} $CFLAGS
|
||||
-nostdlib -nostartfiles -fno-exceptions
|
||||
-o conftest conftest.c 1>&5'; { (eval echo configure:2306: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
-o conftest conftest.c 1>&5'; { (eval echo configure:2317: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
libc_cv_gcc_no_exceptions=yes
|
||||
else
|
||||
libc_cv_gcc_no_exceptions=no
|
||||
@ -2314,14 +2325,14 @@ echo "$ac_t""$libc_cv_gcc_no_exceptions" 1>&6
|
||||
|
||||
if test "$base_machine" = alpha ; then
|
||||
echo $ac_n "checking for function ..ng prefix""... $ac_c" 1>&6
|
||||
echo "configure:2318: checking for function ..ng prefix" >&5
|
||||
echo "configure:2329: checking for function ..ng prefix" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_gcc_alpha_ng_prefix'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.c <<\EOF
|
||||
foo () { }
|
||||
EOF
|
||||
if { ac_try='${CC-cc} -S conftest.c -o - | fgrep "\$foo..ng" > /dev/null'; { (eval echo configure:2325: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
|
||||
if { ac_try='${CC-cc} -S conftest.c -o - | fgrep "\$foo..ng" > /dev/null'; { (eval echo configure:2336: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; };
|
||||
then
|
||||
libc_cv_gcc_alpha_ng_prefix=yes
|
||||
else
|
||||
@ -2345,12 +2356,12 @@ fi
|
||||
fi
|
||||
|
||||
echo $ac_n "checking for DWARF2 unwind info support""... $ac_c" 1>&6
|
||||
echo "configure:2349: checking for DWARF2 unwind info support" >&5
|
||||
echo "configure:2360: checking for DWARF2 unwind info support" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_gcc_dwarf2_unwind_info'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.c <<EOF
|
||||
#line 2354 "configure"
|
||||
#line 2365 "configure"
|
||||
static char __EH_FRAME_BEGIN__;
|
||||
_start ()
|
||||
{
|
||||
@ -2377,7 +2388,7 @@ __bzero () {}
|
||||
EOF
|
||||
if { ac_try='${CC-cc} $CFLAGS -DCHECK__register_frame_info
|
||||
-nostdlib -nostartfiles
|
||||
-o conftest conftest.c -lgcc >&5'; { (eval echo configure:2381: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
-o conftest conftest.c -lgcc >&5'; { (eval echo configure:2392: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
libc_cv_gcc_dwarf2_unwind_info=static
|
||||
else
|
||||
libc_cv_gcc_dwarf2_unwind_info=no
|
||||
@ -2385,7 +2396,7 @@ fi
|
||||
if test $libc_cv_gcc_dwarf2_unwind_info = no; then
|
||||
if { ac_try='${CC-cc} $CFLAGS -DCHECK__register_frame
|
||||
-nostdlib -nostartfiles
|
||||
-o conftest conftest.c -lgcc >&5'; { (eval echo configure:2389: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
-o conftest conftest.c -lgcc >&5'; { (eval echo configure:2400: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; }; then
|
||||
libc_cv_gcc_dwarf2_unwind_info=yes
|
||||
else
|
||||
libc_cv_gcc_dwarf2_unwind_info=no
|
||||
@ -2456,7 +2467,7 @@ if test "$uname" = "sysdeps/generic"; then
|
||||
fi
|
||||
|
||||
echo $ac_n "checking OS release for uname""... $ac_c" 1>&6
|
||||
echo "configure:2460: checking OS release for uname" >&5
|
||||
echo "configure:2471: checking OS release for uname" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_uname_release'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -2478,7 +2489,7 @@ echo "$ac_t""$libc_cv_uname_release" 1>&6
|
||||
uname_release="$libc_cv_uname_release"
|
||||
|
||||
echo $ac_n "checking OS version for uname""... $ac_c" 1>&6
|
||||
echo "configure:2482: checking OS version for uname" >&5
|
||||
echo "configure:2493: checking OS version for uname" >&5
|
||||
if eval "test \"`echo '$''{'libc_cv_uname_version'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -2500,7 +2511,7 @@ else
|
||||
fi
|
||||
|
||||
echo $ac_n "checking stdio selection""... $ac_c" 1>&6
|
||||
echo "configure:2504: checking stdio selection" >&5
|
||||
echo "configure:2515: checking stdio selection" >&5
|
||||
|
||||
case $stdio in
|
||||
libio) cat >> confdefs.h <<\EOF
|
||||
@ -2512,7 +2523,7 @@ esac
|
||||
echo "$ac_t""$stdio" 1>&6
|
||||
|
||||
echo $ac_n "checking ldap selection""... $ac_c" 1>&6
|
||||
echo "configure:2516: checking ldap selection" >&5
|
||||
echo "configure:2527: checking ldap selection" >&5
|
||||
|
||||
case $add_ons in
|
||||
*ldap*)
|
||||
@ -2574,7 +2585,7 @@ if test $static = no && test $shared = yes; then
|
||||
fi
|
||||
|
||||
echo $ac_n "checking whether -fPIC is default""... $ac_c" 1>&6
|
||||
echo "configure:2578: checking whether -fPIC is default" >&5
|
||||
echo "configure:2589: checking whether -fPIC is default" >&5
|
||||
if eval "test \"`echo '$''{'pic_default'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
@ -2756,6 +2767,7 @@ s%@includedir@%$includedir%g
|
||||
s%@oldincludedir@%$oldincludedir%g
|
||||
s%@infodir@%$infodir%g
|
||||
s%@mandir@%$mandir%g
|
||||
s%@with_cvs@%$with_cvs%g
|
||||
s%@subdirs@%$subdirs%g
|
||||
s%@host@%$host%g
|
||||
s%@host_alias@%$host_alias%g
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
@ -26,5 +26,6 @@
|
||||
#define ADD_PARAMS gid_t gid
|
||||
#define ADD_VARIABLES gid
|
||||
#define BUFLEN NSS_BUFLEN_GROUP
|
||||
#define USE_NSCD 1
|
||||
|
||||
#include "../nss/getXXbyYY_r.c"
|
||||
#include <nss/getXXbyYY_r.c>
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
@ -25,5 +25,6 @@
|
||||
#define DATABASE_NAME group
|
||||
#define ADD_PARAMS const char *name
|
||||
#define ADD_VARIABLES name
|
||||
#define USE_NSCD 1
|
||||
|
||||
#include "../nss/getXXbyYY_r.c"
|
||||
#include <nss/getXXbyYY_r.c>
|
||||
|
46
nscd/Makefile
Normal file
46
nscd/Makefile
Normal file
@ -0,0 +1,46 @@
|
||||
# Copyright (C) 1998 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 Library General Public License as
|
||||
# published by the Free Software Foundation; either version 2 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
|
||||
# Library General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
# write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
# Boston, MA 02111-1307, USA.
|
||||
|
||||
#
|
||||
# Sub-makefile for nscd portion of the library.
|
||||
#
|
||||
subdir := nscd
|
||||
|
||||
routines := nscd_getpw_r nscd_getgr_r
|
||||
|
||||
# We can later add the names of other thread packages here.
|
||||
ifeq (,$(findstring linuxthreads,$(add-ons)))
|
||||
|
||||
others := nscd
|
||||
install-sbin := nscd
|
||||
|
||||
endif
|
||||
|
||||
nscd-routines := nscd connections pwdcache getpwnam_r getpwuid_r grpcache\
|
||||
getgrnam_r getgrgid_r dbg_log nscd_conf nscd_stat
|
||||
extra-objs := $(nscd-routines:=.o)
|
||||
|
||||
distribute := nscd.h dbg_log.h
|
||||
|
||||
include ../Rules
|
||||
|
||||
ifeq ($(build-shared),yes)
|
||||
$(objpfx)nscd: $(nscd-routines:%=$(objpfx)%.o) $(objpfx)../linuxthreads/libpthread.so$(libpthread.so-version) $(objpfx)../nis/libnsl.so$(libnsl.so-version)
|
||||
else
|
||||
$(objpfx)nscd: $(nscd-routines:%=$(objpfx)%.o) $(objpfx)../linuxthreads/libpthread.a $(objpfx)../nis/libnsl.a
|
||||
endif
|
7
nscd/TODO
Normal file
7
nscd/TODO
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
* We should use readv/writev for group entries, too
|
||||
|
||||
* If we have reached the max. # of process, close accept socket.
|
||||
! THIS COULD CAUSE THE KERNEL TO HANG ! BE CAREFUL !
|
||||
|
||||
* Implement cache for hosts
|
529
nscd/connections.c
Normal file
529
nscd/connections.c
Normal file
@ -0,0 +1,529 @@
|
||||
/* Copyright (c) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <fcntl.h>
|
||||
#include <libintl.h>
|
||||
#include <locale.h>
|
||||
#include <pthread.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include "nscd.h"
|
||||
#include "dbg_log.h"
|
||||
|
||||
/* Socket 0 in the array is named and exported into the file namespace
|
||||
as a connection point for clients. */
|
||||
static int sock[MAX_NUM_CONNECTIONS];
|
||||
static int socks_active;
|
||||
static fd_set read_set;
|
||||
static pthread_mutex_t sock_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
|
||||
/* Cleanup. */
|
||||
void
|
||||
close_sockets (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (debug_flag)
|
||||
dbg_log (_("close_sockets called"));
|
||||
|
||||
pthread_mutex_lock (&sock_lock);
|
||||
|
||||
/* Close sockets. */
|
||||
for (i = 0; i < MAX_NUM_CONNECTIONS; ++i)
|
||||
if (sock[i] != 0)
|
||||
{
|
||||
if (close (sock[i]))
|
||||
dbg_log (_("socket [%d|%d] close: %s"), strerror (errno));
|
||||
|
||||
sock[i] = 0;
|
||||
--socks_active;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock (&sock_lock);
|
||||
}
|
||||
|
||||
void
|
||||
close_socket (int conn)
|
||||
{
|
||||
if (debug_flag > 2)
|
||||
dbg_log (_("close socket (%d|%d)"), conn, sock[conn]);
|
||||
|
||||
pthread_mutex_lock (&sock_lock);
|
||||
|
||||
close (sock[conn]);
|
||||
sock[conn] = 0;
|
||||
--socks_active;
|
||||
|
||||
pthread_mutex_unlock (&sock_lock);
|
||||
}
|
||||
|
||||
/* Local rountine, assigns a socket to a new connection request. */
|
||||
static void
|
||||
handle_new_connection (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (debug_flag > 2)
|
||||
dbg_log (_("handle_new_connection"));
|
||||
|
||||
pthread_mutex_lock (&sock_lock);
|
||||
|
||||
if (socks_active < MAX_NUM_CONNECTIONS)
|
||||
/* Find a free socket entry to use. */
|
||||
for (i = 1; i < MAX_NUM_CONNECTIONS; ++i)
|
||||
{
|
||||
if (sock[i] == 0)
|
||||
{
|
||||
if ((sock[i] = accept (sock[0], NULL, NULL)) < 0)
|
||||
{
|
||||
dbg_log (_("socket accept: %s"), strerror (errno));
|
||||
return;
|
||||
}
|
||||
++socks_active;
|
||||
FD_SET (sock[i], &read_set);
|
||||
if (debug_flag > 2)
|
||||
dbg_log (_("handle_new_connection used socket %d|%d"), i,
|
||||
sock[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int black_widow_sock;
|
||||
dbg_log (_("Supported number of simultainious connections exceeded"));
|
||||
dbg_log (_("Ignoring client connect request"));
|
||||
/* There has to be a better way to ignore a connection request,..
|
||||
when I get my hands on a sockets wiz I'll modify this. */
|
||||
black_widow_sock = accept (sock[0], NULL, NULL);
|
||||
close (black_widow_sock);
|
||||
}
|
||||
pthread_mutex_unlock (&sock_lock);
|
||||
}
|
||||
|
||||
/* Local routine, reads a request off a socket indicated by a selectset. */
|
||||
static int
|
||||
handle_new_request (fd_set read_selects, int **connp, request_header **reqp,
|
||||
char **key)
|
||||
{
|
||||
ssize_t nbytes;
|
||||
int i;
|
||||
|
||||
if (debug_flag)
|
||||
dbg_log ("handle_new_request");
|
||||
|
||||
/* Find the descriptor. */
|
||||
for (i = 1; i < MAX_NUM_CONNECTIONS; ++i)
|
||||
if (FD_ISSET(sock[i], &read_selects))
|
||||
break;
|
||||
|
||||
if (debug_flag > 2)
|
||||
dbg_log (_("handle_new_request uses socket %d"), i);
|
||||
|
||||
/* Read from it. */
|
||||
nbytes = read (sock[i], *reqp, sizeof (request_header));
|
||||
if (nbytes != sizeof (request_header))
|
||||
{
|
||||
/* Handle non-data read cases. */
|
||||
if (nbytes == 0)
|
||||
{
|
||||
/* Close socket down. */
|
||||
if (debug_flag > 2)
|
||||
dbg_log (_("Real close socket %d|%d"), i, sock[i]);
|
||||
|
||||
pthread_mutex_lock (&sock_lock);
|
||||
FD_CLR (sock[i], &read_set);
|
||||
close (sock[i]);
|
||||
sock[i] = 0;
|
||||
--socks_active;
|
||||
pthread_mutex_unlock (&sock_lock);
|
||||
}
|
||||
else
|
||||
if (nbytes < 0)
|
||||
{
|
||||
dbg_log (_("Read(%d|%d) error on get request: %s"),
|
||||
i, sock[i], strerror (errno));
|
||||
exit (1);
|
||||
}
|
||||
else
|
||||
dbg_log (_("Read, data < request buf size, ignoring data"));
|
||||
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*key = malloc ((*reqp)->key_len + 1);
|
||||
/* Read the key from it */
|
||||
nbytes = read (sock[i], *key, (*reqp)->key_len);
|
||||
if (nbytes != (*reqp)->key_len)
|
||||
{
|
||||
/* Handle non-data read cases. */
|
||||
if (nbytes == 0)
|
||||
{
|
||||
/* Close socket down. */
|
||||
if (debug_flag > 2)
|
||||
dbg_log (_("Real close socket %d|%d"), i, sock[i]);
|
||||
|
||||
pthread_mutex_lock (&sock_lock);
|
||||
FD_CLR (sock[i], &read_set);
|
||||
close (sock[i]);
|
||||
sock[i] = 0;
|
||||
--socks_active;
|
||||
pthread_mutex_unlock (&sock_lock);
|
||||
}
|
||||
else
|
||||
if (nbytes < 0)
|
||||
{
|
||||
perror (_("Read() error on get request"));
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
fputs (_("Read, data < request buf size, ignoring data"),
|
||||
stderr);
|
||||
|
||||
free (*key);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Ok, have a live one, A real data req buf has been obtained. */
|
||||
(*key)[(*reqp)->key_len] = '\0';
|
||||
**connp = i;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
get_request (int *conn, request_header *req, char **key)
|
||||
{
|
||||
int i, nr, done = 0;
|
||||
fd_set read_selects;
|
||||
|
||||
if (debug_flag)
|
||||
dbg_log ("get_request");
|
||||
|
||||
/* loop, processing new connection requests until a client buffer
|
||||
is read in on an existing connection. */
|
||||
while (!done)
|
||||
{
|
||||
/* Set up the socket descriptor mask for the select.
|
||||
copy read_set into the local copy. */
|
||||
|
||||
FD_ZERO (&read_selects);
|
||||
pthread_mutex_lock (&sock_lock);
|
||||
for (i = 0; i < MAX_NUM_CONNECTIONS; ++i)
|
||||
{
|
||||
if (FD_ISSET (sock[i], &read_set))
|
||||
FD_SET (sock[i], &read_selects);
|
||||
}
|
||||
pthread_mutex_unlock (&sock_lock);
|
||||
/* Poll active connections using select(). */
|
||||
nr = select (FD_SETSIZE, &read_selects, NULL, NULL, NULL);
|
||||
if (nr <= 0)
|
||||
{
|
||||
perror (_("Select new reads"));
|
||||
exit (1);
|
||||
}
|
||||
if (FD_ISSET (sock[0], &read_selects))
|
||||
/* Handle the case of a new connection request on the named socket. */
|
||||
handle_new_connection ();
|
||||
else
|
||||
{
|
||||
/* Read data from client specific descriptor. */
|
||||
if (handle_new_request (read_selects, &conn, &req, key) == 0)
|
||||
{
|
||||
FD_CLR (sock[*conn], &read_set);
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
} /* While not_done. */
|
||||
}
|
||||
|
||||
void
|
||||
init_sockets (void)
|
||||
{
|
||||
struct sockaddr_un sock_addr;
|
||||
|
||||
/* Initialize the connections db. */
|
||||
socks_active = 0;
|
||||
FD_ZERO (&read_set);
|
||||
|
||||
/* Create the socket. */
|
||||
sock[0] = socket (AF_UNIX, SOCK_STREAM, 0);
|
||||
if (sock[0] < 0)
|
||||
{
|
||||
perror (_("cannot create socket"));
|
||||
exit (1);
|
||||
}
|
||||
/* Bind a name to the socket. */
|
||||
sock_addr.sun_family = AF_UNIX;
|
||||
strcpy (sock_addr.sun_path, _PATH_NSCDSOCKET);
|
||||
if (bind (sock[0], (struct sockaddr *) &sock_addr, sizeof (sock_addr)) < 0)
|
||||
{
|
||||
dbg_log ("%s: %s", _PATH_NSCDSOCKET, strerror (errno));
|
||||
exit (1);
|
||||
}
|
||||
/* Set permissions for the socket. */
|
||||
chmod (_PATH_NSCDSOCKET, 0666);
|
||||
|
||||
/* Set the socket up to accept connections. */
|
||||
if (listen (sock[0], MAX_NUM_CONNECTIONS) < 0)
|
||||
{
|
||||
perror (_("cannot enable socket to accept connections"));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/* Add the socket to the server's set of active sockets. */
|
||||
FD_SET (sock[0], &read_set);
|
||||
++socks_active;
|
||||
}
|
||||
|
||||
void
|
||||
pw_send_answer (int conn, struct passwd *pwd)
|
||||
{
|
||||
pw_response_header resp;
|
||||
|
||||
resp.version = NSCD_VERSION;
|
||||
if (pwd != NULL)
|
||||
{
|
||||
resp.found = 1;
|
||||
resp.pw_name_len = strlen (pwd->pw_name);
|
||||
resp.pw_passwd_len = strlen (pwd->pw_passwd);
|
||||
resp.pw_uid = pwd->pw_uid;
|
||||
resp.pw_gid = pwd->pw_gid;
|
||||
resp.pw_gecos_len = strlen (pwd->pw_gecos);
|
||||
resp.pw_dir_len = strlen (pwd->pw_dir);
|
||||
resp.pw_shell_len = strlen (pwd->pw_shell);
|
||||
}
|
||||
else
|
||||
{
|
||||
resp.found = 0;
|
||||
resp.pw_name_len = 0;
|
||||
resp.pw_passwd_len = 0;
|
||||
resp.pw_uid = -1;
|
||||
resp.pw_gid = -1;
|
||||
resp.pw_gecos_len = 0;
|
||||
resp.pw_dir_len = 0;
|
||||
resp.pw_shell_len = 0;
|
||||
}
|
||||
if (sock[conn] == 0)
|
||||
{
|
||||
dbg_log (_("bad connection id on send response [%d|%d]"),
|
||||
conn, sock[conn]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send response header. */
|
||||
if (write (sock[conn], &resp, sizeof (pw_response_header)) !=
|
||||
sizeof (pw_response_header))
|
||||
{
|
||||
dbg_log (_("write incomplete on send response: %s"), strerror (errno));
|
||||
return;
|
||||
}
|
||||
|
||||
if (resp.found)
|
||||
{
|
||||
struct iovec vec[5];
|
||||
|
||||
/* Send pw_name. */
|
||||
vec[0].iov_base = pwd->pw_name;
|
||||
vec[0].iov_len = resp.pw_name_len;
|
||||
/* Send pw_passwd. */
|
||||
vec[1].iov_base = pwd->pw_passwd;
|
||||
vec[1].iov_len = resp.pw_passwd_len;
|
||||
/* Send pw_gecos. */
|
||||
vec[2].iov_base = pwd->pw_gecos;
|
||||
vec[2].iov_len = resp.pw_gecos_len;
|
||||
/* Send pw_dir. */
|
||||
vec[3].iov_base = pwd->pw_dir;
|
||||
vec[3].iov_len = resp.pw_dir_len;
|
||||
/* Send pw_shell. */
|
||||
vec[4].iov_base = pwd->pw_shell;
|
||||
vec[4].iov_len = resp.pw_shell_len;
|
||||
|
||||
if (writev (sock[conn], vec, 5) != (resp.pw_name_len + resp.pw_passwd_len
|
||||
+ resp.pw_gecos_len + resp.pw_dir_len
|
||||
+ resp.pw_shell_len))
|
||||
dbg_log (_("write incomplete on send passwd answer: %s"),
|
||||
strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
pw_send_disabled (int conn)
|
||||
{
|
||||
pw_response_header resp;
|
||||
|
||||
resp.version = NSCD_VERSION;
|
||||
resp.found = -1;
|
||||
resp.pw_name_len = 0;
|
||||
resp.pw_passwd_len = 0;
|
||||
resp.pw_uid = -1;
|
||||
resp.pw_gid = -1;
|
||||
resp.pw_gecos_len = 0;
|
||||
resp.pw_dir_len = 0;
|
||||
resp.pw_shell_len = 0;
|
||||
|
||||
if (sock[conn] == 0)
|
||||
{
|
||||
dbg_log ("bad connection id on send response [%d|%d]",
|
||||
conn, sock[conn]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send response header. */
|
||||
if (write (sock[conn], &resp, sizeof (pw_response_header))
|
||||
!= sizeof (pw_response_header))
|
||||
dbg_log (_("write incomplete on send response: %s"), strerror (errno));
|
||||
}
|
||||
|
||||
void
|
||||
gr_send_answer (int conn, struct group *grp)
|
||||
{
|
||||
gr_response_header resp;
|
||||
|
||||
resp.version = NSCD_VERSION;
|
||||
if (grp != NULL)
|
||||
{
|
||||
resp.found = 1;
|
||||
resp.gr_name_len = strlen (grp->gr_name);
|
||||
resp.gr_passwd_len = strlen (grp->gr_passwd);
|
||||
resp.gr_gid = grp->gr_gid;
|
||||
resp.gr_mem_len = 0;
|
||||
while (grp->gr_mem[resp.gr_mem_len])
|
||||
++resp.gr_mem_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
resp.found = 0;
|
||||
resp.gr_name_len = 0;
|
||||
resp.gr_passwd_len = 0;
|
||||
resp.gr_gid = -1;
|
||||
resp.gr_mem_len = 0;
|
||||
}
|
||||
if (sock[conn] == 0)
|
||||
{
|
||||
dbg_log (_("bad connection id on send response [%d|%d]"),
|
||||
conn, sock[conn]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send response header. */
|
||||
if (write (sock[conn], &resp, sizeof (gr_response_header))
|
||||
!= sizeof (gr_response_header))
|
||||
{
|
||||
dbg_log (_("write incomplete on send response: %s"), strerror (errno));
|
||||
return;
|
||||
}
|
||||
|
||||
if (resp.found)
|
||||
{
|
||||
unsigned int l = 0;
|
||||
|
||||
/* Send gr_name. */
|
||||
if (write (sock[conn], grp->gr_name, resp.gr_name_len)
|
||||
!= resp.gr_name_len)
|
||||
{
|
||||
dbg_log (_("write incomplete on send response: %s"),
|
||||
strerror (errno));
|
||||
return;
|
||||
}
|
||||
/* Send gr_passwd. */
|
||||
if (write (sock[conn], grp->gr_passwd, resp.gr_passwd_len)
|
||||
!= resp.gr_passwd_len)
|
||||
{
|
||||
dbg_log (_("write incomplete on send response: %s"),
|
||||
strerror (errno));
|
||||
return;
|
||||
}
|
||||
|
||||
while (grp->gr_mem[l])
|
||||
{
|
||||
size_t len = strlen (grp->gr_mem[l]);
|
||||
|
||||
if (write (sock[conn], &len, sizeof (len)) != sizeof (len))
|
||||
{
|
||||
dbg_log (_("write incomplete on send response: %s"),
|
||||
strerror (errno));
|
||||
return;
|
||||
}
|
||||
if (write (sock[conn], grp->gr_mem[l], len) != len)
|
||||
{
|
||||
dbg_log (_("write incomplete on send response: %s"),
|
||||
strerror (errno));
|
||||
return;
|
||||
}
|
||||
++l;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gr_send_disabled (int conn)
|
||||
{
|
||||
gr_response_header resp;
|
||||
|
||||
resp.version = NSCD_VERSION;
|
||||
resp.found = -1;
|
||||
resp.gr_name_len = 0;
|
||||
resp.gr_passwd_len = 0;
|
||||
resp.gr_gid = -1;
|
||||
resp.gr_mem_len = 0;
|
||||
|
||||
if (sock[conn] == 0)
|
||||
{
|
||||
dbg_log (_("bad connection id on send gr_disabled response [%d|%d]"),
|
||||
conn, sock[conn]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Send response header. */
|
||||
if (write (sock[conn], &resp, sizeof (gr_response_header))
|
||||
!= sizeof (gr_response_header))
|
||||
dbg_log (_("write incomplete on send gr_disabled response: %s"),
|
||||
strerror (errno));
|
||||
}
|
||||
|
||||
void
|
||||
stat_send (int conn, stat_response_header *resp)
|
||||
{
|
||||
if (sock[conn] == 0)
|
||||
{
|
||||
dbg_log (_("bad connection id on send stat response [%d|%d]"),
|
||||
conn, sock[conn]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* send response header. */
|
||||
if (write (sock[conn], resp, sizeof (stat_response_header))
|
||||
!= sizeof (stat_response_header))
|
||||
dbg_log (_("write incomplete on send stat response: %s"),
|
||||
strerror (errno));
|
||||
}
|
64
nscd/dbg_log.c
Normal file
64
nscd/dbg_log.c
Normal file
@ -0,0 +1,64 @@
|
||||
/* Copyright (c) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
#include "dbg_log.h"
|
||||
#include "nscd.h"
|
||||
|
||||
/* if in debug mode and we have a debug file, we write the messages to it,
|
||||
if in debug mode and no debug file, we write the messages to stderr,
|
||||
else to syslog. */
|
||||
|
||||
FILE *dbgout = NULL;
|
||||
int debug_flag = 0;
|
||||
|
||||
int
|
||||
set_logfile (const char *logfile)
|
||||
{
|
||||
dbgout = fopen (logfile, "a");
|
||||
return dbgout == NULL ? 0 : 1;
|
||||
}
|
||||
|
||||
void
|
||||
dbg_log (const char *fmt,...)
|
||||
{
|
||||
va_list ap;
|
||||
char msg[512], msg2[512];
|
||||
|
||||
va_start (ap, fmt);
|
||||
vsnprintf (msg2, sizeof (msg), fmt, ap);
|
||||
|
||||
if (debug_flag)
|
||||
{
|
||||
snprintf (msg, sizeof (msg), "%d: %s\n", getpid (), msg2);
|
||||
if (dbgout)
|
||||
fputs (msg, dbgout);
|
||||
else
|
||||
fputs (msg, stderr);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf (msg, sizeof (msg), "%d: %s", getpid (), msg2);
|
||||
syslog (LOG_NOTICE, msg);
|
||||
}
|
||||
va_end (ap);
|
||||
}
|
27
nscd/dbg_log.h
Normal file
27
nscd/dbg_log.h
Normal file
@ -0,0 +1,27 @@
|
||||
/* Copyright (c) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _DBG_LOG_H
|
||||
#define _DBG_LOG_H 1
|
||||
|
||||
extern int debug_flag;
|
||||
|
||||
extern void dbg_log (const char *, ...);
|
||||
|
||||
#endif
|
30
nscd/getgrgid_r.c
Normal file
30
nscd/getgrgid_r.c
Normal file
@ -0,0 +1,30 @@
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <grp.h>
|
||||
|
||||
|
||||
#define LOOKUP_TYPE struct group
|
||||
#define FUNCTION_NAME getgrgid
|
||||
#define DATABASE_NAME group
|
||||
#define ADD_PARAMS gid_t gid
|
||||
#define ADD_VARIABLES gid
|
||||
#define BUFLEN NSS_BUFLEN_GROUP
|
||||
|
||||
#include <nss/getXXbyYY_r.c>
|
29
nscd/getgrnam_r.c
Normal file
29
nscd/getgrnam_r.c
Normal file
@ -0,0 +1,29 @@
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <grp.h>
|
||||
|
||||
|
||||
#define LOOKUP_TYPE struct group
|
||||
#define FUNCTION_NAME getgrnam
|
||||
#define DATABASE_NAME group
|
||||
#define ADD_PARAMS const char *name
|
||||
#define ADD_VARIABLES name
|
||||
|
||||
#include <nss/getXXbyYY_r.c>
|
30
nscd/getpwnam_r.c
Normal file
30
nscd/getpwnam_r.c
Normal file
@ -0,0 +1,30 @@
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <pwd.h>
|
||||
|
||||
|
||||
#define LOOKUP_TYPE struct passwd
|
||||
#define FUNCTION_NAME getpwnam
|
||||
#define DATABASE_NAME passwd
|
||||
#define ADD_PARAMS const char *name
|
||||
#define ADD_VARIABLES name
|
||||
#define BUFLEN NSS_BUFLEN_PASSWD
|
||||
|
||||
#include <nss/getXXbyYY_r.c>
|
30
nscd/getpwuid_r.c
Normal file
30
nscd/getpwuid_r.c
Normal file
@ -0,0 +1,30 @@
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <pwd.h>
|
||||
|
||||
|
||||
#define LOOKUP_TYPE struct passwd
|
||||
#define FUNCTION_NAME getpwuid
|
||||
#define DATABASE_NAME passwd
|
||||
#define ADD_PARAMS uid_t uid
|
||||
#define ADD_VARIABLES uid
|
||||
#define BUFLEN NSS_BUFLEN_PASSWD
|
||||
|
||||
#include <nss/getXXbyYY_r.c>
|
589
nscd/grpcache.c
Normal file
589
nscd/grpcache.c
Normal file
@ -0,0 +1,589 @@
|
||||
/* Copyright (c) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <malloc.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
#include <rpcsvc/nis.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "dbg_log.h"
|
||||
#include "nscd.h"
|
||||
|
||||
static unsigned long modulo = 211;
|
||||
static unsigned long postimeout = 3600;
|
||||
static unsigned long negtimeout = 60;
|
||||
|
||||
static unsigned long poshit = 0;
|
||||
static unsigned long posmiss = 0;
|
||||
static unsigned long neghit = 0;
|
||||
static unsigned long negmiss = 0;
|
||||
|
||||
struct grphash
|
||||
{
|
||||
time_t create;
|
||||
struct grphash *next;
|
||||
struct group *grp;
|
||||
};
|
||||
typedef struct grphash grphash;
|
||||
|
||||
struct gidhash
|
||||
{
|
||||
struct gidhash *next;
|
||||
struct grphash *grptr;
|
||||
};
|
||||
typedef struct gidhash gidhash;
|
||||
|
||||
struct neghash
|
||||
{
|
||||
time_t create;
|
||||
struct neghash *next;
|
||||
char *key;
|
||||
};
|
||||
typedef struct neghash neghash;
|
||||
|
||||
static grphash *grptbl;
|
||||
static gidhash *gidtbl;
|
||||
static neghash *negtbl;
|
||||
|
||||
static pthread_rwlock_t grplock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
static pthread_rwlock_t neglock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
static void *grptable_update (void *);
|
||||
static void *negtable_update (void *);
|
||||
|
||||
void
|
||||
get_gr_stat (stat_response_header *stat)
|
||||
{
|
||||
stat->gr_poshit = poshit;
|
||||
stat->gr_posmiss = posmiss;
|
||||
stat->gr_neghit = neghit;
|
||||
stat->gr_negmiss = negmiss;
|
||||
stat->gr_size = modulo;
|
||||
stat->gr_posttl = postimeout;
|
||||
stat->gr_negttl = negtimeout;
|
||||
}
|
||||
|
||||
void
|
||||
set_grp_modulo (unsigned long mod)
|
||||
{
|
||||
modulo = mod;
|
||||
}
|
||||
|
||||
void
|
||||
set_pos_grp_ttl (unsigned long ttl)
|
||||
{
|
||||
postimeout = ttl;
|
||||
}
|
||||
|
||||
void
|
||||
set_neg_grp_ttl (unsigned long ttl)
|
||||
{
|
||||
negtimeout = ttl;
|
||||
}
|
||||
|
||||
int
|
||||
cache_grpinit ()
|
||||
{
|
||||
pthread_attr_t attr;
|
||||
pthread_t thread;
|
||||
|
||||
grptbl = calloc (1, modulo * sizeof (grphash));
|
||||
if (grptbl == NULL)
|
||||
return -1;
|
||||
calloc (1, modulo * sizeof (grphash));
|
||||
if (gidtbl == NULL)
|
||||
return -1;
|
||||
negtbl = calloc (1, modulo * sizeof (neghash));
|
||||
if (negtbl == NULL)
|
||||
return -1;
|
||||
|
||||
pthread_attr_init (&attr);
|
||||
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
|
||||
|
||||
pthread_create (&thread, NULL, grptable_update, &attr);
|
||||
pthread_create (&thread, NULL, negtable_update, &attr);
|
||||
|
||||
pthread_attr_destroy (&attr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct group *
|
||||
save_grp (struct group *src)
|
||||
{
|
||||
struct group *dest;
|
||||
unsigned long int l;
|
||||
|
||||
dest = calloc (1, sizeof (struct group));
|
||||
dest->gr_name = strdup (src->gr_name);
|
||||
dest->gr_passwd = strdup (src->gr_passwd);
|
||||
dest->gr_gid = src->gr_gid;
|
||||
|
||||
/* How many members does this group have? */
|
||||
l = 0;
|
||||
while (src->gr_mem[l])
|
||||
++l;
|
||||
|
||||
dest->gr_mem = calloc (1, sizeof (char *) * (l+1));
|
||||
l = 0;
|
||||
while (src->gr_mem[l])
|
||||
{
|
||||
dest->gr_mem[l] = strdup (src->gr_mem[l]);
|
||||
++l;
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
static void
|
||||
free_grp (struct group *src)
|
||||
{
|
||||
unsigned long int l;
|
||||
|
||||
free (src->gr_name);
|
||||
free (src->gr_passwd);
|
||||
|
||||
l = 0;
|
||||
while (src->gr_mem[l])
|
||||
{
|
||||
free (src->gr_mem[l]);
|
||||
++l;
|
||||
}
|
||||
free (src->gr_mem);
|
||||
free (src);
|
||||
}
|
||||
|
||||
static int
|
||||
add_cache (struct group *grp)
|
||||
{
|
||||
grphash *work;
|
||||
unsigned long int hash = __nis_hash (grp->gr_name,
|
||||
strlen (grp->gr_name)) % modulo;
|
||||
|
||||
work = &grptbl[hash];
|
||||
|
||||
if (grptbl[hash].grp == NULL)
|
||||
grptbl[hash].grp = save_grp (grp);
|
||||
else
|
||||
{
|
||||
while (work->next != NULL)
|
||||
work = work->next;
|
||||
|
||||
work->next = calloc (1, sizeof (grphash));
|
||||
work->next->grp = save_grp (grp);
|
||||
work = work->next;
|
||||
}
|
||||
|
||||
time (&work->create);
|
||||
gidtbl[grp->gr_gid % modulo].grptr = work;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct group *
|
||||
cache_search_name (const char *name)
|
||||
{
|
||||
grphash *work;
|
||||
unsigned long int hash = __nis_hash (name, strlen(name)) % modulo;
|
||||
|
||||
work = &grptbl[hash];
|
||||
|
||||
while (work->grp != NULL)
|
||||
{
|
||||
if (strcmp (work->grp->gr_name, name) == 0)
|
||||
return work->grp;
|
||||
if (work->next != NULL)
|
||||
work = work->next;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct group *
|
||||
cache_search_gid (gid_t gid)
|
||||
{
|
||||
gidhash *work;
|
||||
|
||||
work = &gidtbl[gid % modulo];
|
||||
|
||||
while (work->grptr != NULL)
|
||||
{
|
||||
if (work->grptr->grp->gr_gid == gid)
|
||||
return work->grptr->grp;
|
||||
if (work->next != NULL)
|
||||
work = work->next;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
add_negcache (char *key)
|
||||
{
|
||||
neghash *work;
|
||||
unsigned long int hash = __nis_hash (key, strlen (key)) % modulo;
|
||||
|
||||
work = &negtbl[hash];
|
||||
|
||||
if (negtbl[hash].key == NULL)
|
||||
negtbl[hash].key = strdup (key);
|
||||
else
|
||||
{
|
||||
while (work->next != NULL)
|
||||
work = work->next;
|
||||
|
||||
work->next = calloc (1, sizeof (neghash));
|
||||
work->next->key = strdup (key);
|
||||
work = work->next;
|
||||
}
|
||||
|
||||
time (&work->create);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
cache_search_neg (const char *key)
|
||||
{
|
||||
neghash *work;
|
||||
unsigned long int hash = __nis_hash (key, strlen (key)) % modulo;
|
||||
|
||||
work = &negtbl[hash];
|
||||
|
||||
while (work->key != NULL)
|
||||
{
|
||||
if (strcmp (work->key, key) == 0)
|
||||
return 1;
|
||||
if (work->next != NULL)
|
||||
work = work->next;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
cache_getgrnam (void *v_param)
|
||||
{
|
||||
param_t *param = (param_t *)v_param;
|
||||
struct group *grp, resultbuf;
|
||||
|
||||
pthread_rwlock_rdlock (&grplock);
|
||||
grp = cache_search_name (param->key);
|
||||
|
||||
/* I don't like it to hold the read only lock longer, but it is
|
||||
necessary to avoid to much malloc/free/strcpy. */
|
||||
|
||||
if (grp)
|
||||
{
|
||||
if (debug_flag)
|
||||
dbg_log (_("Found \"%s\" in cache !"), param->key);
|
||||
|
||||
++poshit;
|
||||
gr_send_answer (param->conn, grp);
|
||||
close_socket (param->conn);
|
||||
|
||||
pthread_rwlock_unlock (&grplock);
|
||||
}
|
||||
else
|
||||
{
|
||||
int buflen = 1024;
|
||||
char *buffer = calloc (1, buflen);
|
||||
int status;
|
||||
|
||||
if (debug_flag)
|
||||
dbg_log (_("Doesn't found \"%s\" in cache !"), param->key);
|
||||
|
||||
pthread_rwlock_unlock (&grplock);
|
||||
|
||||
pthread_rwlock_rdlock (&neglock);
|
||||
status = cache_search_neg (param->key);
|
||||
pthread_rwlock_unlock (&neglock);
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
while (buffer != NULL
|
||||
&& (getgrnam_r (param->key, &resultbuf, buffer, buflen, &grp)
|
||||
!= 0)
|
||||
&& errno == ERANGE)
|
||||
{
|
||||
errno = 0;
|
||||
buflen += 1024;
|
||||
buffer = realloc (buffer, buflen);
|
||||
}
|
||||
|
||||
if (buffer != NULL && grp != NULL)
|
||||
{
|
||||
struct group *tmp;
|
||||
|
||||
++poshit;
|
||||
pthread_rwlock_wrlock (&grplock);
|
||||
/* While we are waiting on the lock, somebody else could
|
||||
add this entry. */
|
||||
tmp = cache_search_name (param->key);
|
||||
if (tmp == NULL)
|
||||
add_cache (grp);
|
||||
pthread_rwlock_unlock (&grplock);
|
||||
}
|
||||
else
|
||||
{
|
||||
pthread_rwlock_wrlock (&neglock);
|
||||
add_negcache (param->key);
|
||||
++negmiss;
|
||||
pthread_rwlock_unlock (&neglock);
|
||||
}
|
||||
}
|
||||
else
|
||||
++neghit;
|
||||
|
||||
gr_send_answer (param->conn, grp);
|
||||
close_socket (param->conn);
|
||||
if (buffer != NULL)
|
||||
free (buffer);
|
||||
}
|
||||
free (param->key);
|
||||
free (param);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
cache_gr_disabled (void *v_param)
|
||||
{
|
||||
param_t *param = (param_t *)v_param;
|
||||
|
||||
gr_send_disabled (param->conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
cache_getgrgid (void *v_param)
|
||||
{
|
||||
param_t *param = (param_t *)v_param;
|
||||
struct group *grp, resultbuf;
|
||||
gid_t gid = strtol (param->key, NULL, 10);
|
||||
|
||||
pthread_rwlock_rdlock (&grplock);
|
||||
grp = cache_search_gid (gid);
|
||||
|
||||
/* I don't like it to hold the read only lock longer, but it is
|
||||
necessary to avoid to much malloc/free/strcpy. */
|
||||
|
||||
if (grp != NULL)
|
||||
{
|
||||
if (debug_flag)
|
||||
dbg_log (_("Found \"%d\" in cache !\n"), gid);
|
||||
|
||||
++poshit;
|
||||
gr_send_answer (param->conn, grp);
|
||||
close_socket (param->conn);
|
||||
|
||||
pthread_rwlock_unlock (&grplock);
|
||||
}
|
||||
else
|
||||
{
|
||||
int buflen = 1024;
|
||||
char *buffer = malloc (buflen);
|
||||
int status;
|
||||
|
||||
if (debug_flag)
|
||||
dbg_log (_("Doesn't found \"%d\" in cache !\n"), gid);
|
||||
|
||||
pthread_rwlock_unlock (&grplock);
|
||||
|
||||
pthread_rwlock_rdlock (&neglock);
|
||||
status = cache_search_neg (param->key);
|
||||
pthread_rwlock_unlock (&neglock);
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
while (buffer != NULL
|
||||
&& (getgrgid_r (gid, &resultbuf, buffer, buflen, &grp) != 0)
|
||||
&& errno == ERANGE)
|
||||
{
|
||||
errno = 0;
|
||||
buflen += 1024;
|
||||
buffer = realloc (buffer, buflen);
|
||||
}
|
||||
|
||||
if (buffer != NULL && grp != NULL)
|
||||
{
|
||||
struct group *tmp;
|
||||
|
||||
++posmiss;
|
||||
pthread_rwlock_wrlock (&grplock);
|
||||
/* While we are waiting on the lock, somebody else could
|
||||
add this entry. */
|
||||
tmp = cache_search_gid (gid);
|
||||
if (tmp == NULL)
|
||||
add_cache (grp);
|
||||
pthread_rwlock_unlock (&grplock);
|
||||
}
|
||||
else
|
||||
{
|
||||
++negmiss;
|
||||
pthread_rwlock_wrlock (&neglock);
|
||||
add_negcache (param->key);
|
||||
pthread_rwlock_unlock (&neglock);
|
||||
}
|
||||
}
|
||||
else
|
||||
++neghit;
|
||||
|
||||
gr_send_answer (param->conn, grp);
|
||||
close_socket (param->conn);
|
||||
if (buffer != NULL)
|
||||
free (buffer);
|
||||
}
|
||||
free (param->key);
|
||||
free (param);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
grptable_update (void *v)
|
||||
{
|
||||
time_t now;
|
||||
int i;
|
||||
|
||||
sleep (20);
|
||||
|
||||
while (!do_shutdown)
|
||||
{
|
||||
if (debug_flag > 2)
|
||||
dbg_log (_("(grptable_update) Wait for write lock!"));
|
||||
|
||||
pthread_rwlock_wrlock (&grplock);
|
||||
|
||||
if (debug_flag > 2)
|
||||
dbg_log (_("(grptable_update) Have write lock"));
|
||||
|
||||
time (&now);
|
||||
for (i = 0; i < modulo; ++i)
|
||||
{
|
||||
grphash *work = &grptbl[i];
|
||||
|
||||
while (work && work->grp)
|
||||
{
|
||||
if ((now - work->create) >= postimeout)
|
||||
{
|
||||
gidhash *uh = &gidtbl[work->grp->gr_gid % modulo];
|
||||
|
||||
if (debug_flag)
|
||||
dbg_log (_("Give \"%s\" free"), work->grp->gr_name);
|
||||
|
||||
while (uh && uh->grptr)
|
||||
{
|
||||
if (uh->grptr->grp->gr_gid == work->grp->gr_gid)
|
||||
{
|
||||
if (debug_flag > 3)
|
||||
dbg_log (_("Give gid for \"%s\" free"),
|
||||
work->grp->gr_name);
|
||||
if (uh->next != NULL)
|
||||
{
|
||||
gidhash *tmp = uh->next;
|
||||
uh->grptr = tmp->grptr;
|
||||
uh->next = tmp->next;
|
||||
free (tmp);
|
||||
}
|
||||
else
|
||||
uh->grptr = NULL;
|
||||
}
|
||||
uh = uh->next;
|
||||
}
|
||||
|
||||
free_grp (work->grp);
|
||||
if (work->next != NULL)
|
||||
{
|
||||
grphash *tmp = work->next;
|
||||
work->create = tmp->create;
|
||||
work->next = tmp->next;
|
||||
work->grp = tmp->grp;
|
||||
free (tmp);
|
||||
}
|
||||
else
|
||||
work->grp = NULL;
|
||||
}
|
||||
work = work->next;
|
||||
}
|
||||
}
|
||||
if (debug_flag > 2)
|
||||
dbg_log (_("(pwdtable_update) Release wait lock\n"));
|
||||
pthread_rwlock_unlock (&grplock);
|
||||
sleep (20);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
negtable_update (void *v)
|
||||
{
|
||||
time_t now;
|
||||
int i;
|
||||
|
||||
sleep (30);
|
||||
|
||||
while (!do_shutdown)
|
||||
{
|
||||
if (debug_flag > 2)
|
||||
dbg_log (_("(negtable_update) Wait for write lock!"));
|
||||
|
||||
pthread_rwlock_wrlock (&neglock);
|
||||
|
||||
if (debug_flag > 2)
|
||||
dbg_log (_("(negtable_update) Have write lock"));
|
||||
|
||||
time (&now);
|
||||
for (i = 0; i < modulo; ++i)
|
||||
{
|
||||
neghash *work = &negtbl[i];
|
||||
|
||||
while (work && work->key)
|
||||
{
|
||||
if ((now - work->create) >= negtimeout)
|
||||
{
|
||||
if (debug_flag)
|
||||
dbg_log (_("Give \"%s\" free"), work->key);
|
||||
|
||||
free (work->key);
|
||||
|
||||
if (work->next != NULL)
|
||||
{
|
||||
neghash *tmp = work->next;
|
||||
work->create = tmp->create;
|
||||
work->next = tmp->next;
|
||||
work->key = tmp->key;
|
||||
free (tmp);
|
||||
}
|
||||
else
|
||||
work->key = NULL;
|
||||
}
|
||||
work = work->next;
|
||||
}
|
||||
}
|
||||
if (debug_flag > 2)
|
||||
dbg_log (_("(negtable_update) Release wait lock"));
|
||||
pthread_rwlock_unlock (&neglock);
|
||||
sleep (10);
|
||||
}
|
||||
return NULL;
|
||||
}
|
423
nscd/nscd.c
Normal file
423
nscd/nscd.c
Normal file
@ -0,0 +1,423 @@
|
||||
/* Copyright (c) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* nscd - Name Service Cache Daemon. Caches passwd and group. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <libintl.h>
|
||||
#include <locale.h>
|
||||
#include <pthread.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include "dbg_log.h"
|
||||
#include "nscd.h"
|
||||
|
||||
/* Get libc version number. */
|
||||
#include <version.h>
|
||||
|
||||
#define PACKAGE _libc_intl_domainname
|
||||
|
||||
/* Structure used by main() thread to keep track of the number of
|
||||
active threads. Used to limit how many threads it will create
|
||||
and under a shutdown condition to wait till all in-progress
|
||||
requests have finished before "turning off the lights". */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int num_active;
|
||||
pthread_cond_t thread_exit_cv;
|
||||
pthread_mutex_t mutex;
|
||||
} thread_info_t;
|
||||
|
||||
thread_info_t thread_info;
|
||||
|
||||
int do_shutdown = 0;
|
||||
int disabled_passwd = 0;
|
||||
int disabled_group = 0;
|
||||
|
||||
static void termination_handler (int signum);
|
||||
static int check_pid (const char *file);
|
||||
static int write_pid (const char *file);
|
||||
static void usage (int status) __attribute__ ((noreturn));
|
||||
static void handle_requests (void);
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int go_background = 1;
|
||||
const char *conffile = _PATH_NSCDCONF;
|
||||
|
||||
/* Set locale via LC_ALL. */
|
||||
setlocale (LC_ALL, "");
|
||||
/* Set the text message domain. */
|
||||
textdomain (PACKAGE);
|
||||
|
||||
while (1)
|
||||
{
|
||||
int c;
|
||||
int option_index = 0;
|
||||
static struct option long_options[] = {
|
||||
{ "debug", no_argument, NULL, 'd' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ "shutdown", no_argument, NULL, 'K' },
|
||||
{NULL, 0, NULL, '\0'}
|
||||
};
|
||||
|
||||
c = getopt_long (argc, argv, "df:ghKV", long_options, &option_index);
|
||||
if (c == (-1))
|
||||
break;
|
||||
switch (c)
|
||||
{
|
||||
case 'd':
|
||||
debug_flag = 1;
|
||||
go_background = 0;
|
||||
break;
|
||||
case 'f':
|
||||
conffile = optarg;
|
||||
break;
|
||||
case 'h':
|
||||
usage (EXIT_SUCCESS);
|
||||
break;
|
||||
case 'K':
|
||||
if (getuid () != 0)
|
||||
{
|
||||
printf (_("Only root is allowed to use this option!\n\n"));
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
{
|
||||
int sock = __nscd_open_socket ();
|
||||
request_header req;
|
||||
ssize_t nbytes;
|
||||
|
||||
if (sock == -1)
|
||||
exit (EXIT_FAILURE);
|
||||
|
||||
req.version = NSCD_VERSION;
|
||||
req.type = SHUTDOWN;
|
||||
req.key_len = 0;
|
||||
nbytes = write (sock, &req, sizeof (request_header));
|
||||
close (sock);
|
||||
if (nbytes != req.key_len)
|
||||
exit (EXIT_FAILURE);
|
||||
else
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
case 'g':
|
||||
print_stat ();
|
||||
exit (EXIT_SUCCESS);
|
||||
case 'V':
|
||||
printf ("nscd (GNU %s) %s\n", PACKAGE, VERSION);
|
||||
printf (_("\
|
||||
Copyright (C) %s Free Software Foundation, Inc.\n\
|
||||
This is free software; see the source for copying conditions. There is NO\n\
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
|
||||
"), "1998");
|
||||
printf (_("Written by %s.\n"), "Thorsten Kukuk");
|
||||
exit (EXIT_SUCCESS);
|
||||
default:
|
||||
usage (EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
signal (SIGINT, termination_handler);
|
||||
signal (SIGQUIT, termination_handler);
|
||||
signal (SIGTERM, termination_handler);
|
||||
|
||||
/* Check if we are already running. */
|
||||
if (check_pid (_PATH_NSCDPID))
|
||||
{
|
||||
fputs (_("already running"), stderr);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Behave like a daemon. */
|
||||
if (go_background)
|
||||
{
|
||||
openlog ("nscd", LOG_CONS | LOG_ODELAY, LOG_DAEMON);
|
||||
|
||||
if (daemon (0, 0) < 0)
|
||||
{
|
||||
fprintf (stderr, _("connot auto-background: %s\n"),
|
||||
strerror (errno));
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
if (write_pid (_PATH_NSCDPID) < 0)
|
||||
dbg_log ("%s: %s", _PATH_NSCDPID, strerror (errno));
|
||||
|
||||
/* Ignore job control signals */
|
||||
signal (SIGTTOU, SIG_IGN);
|
||||
signal (SIGTTIN, SIG_IGN);
|
||||
signal (SIGTSTP, SIG_IGN);
|
||||
}
|
||||
/* Cleanup files created by a previous `bind' */
|
||||
unlink (_PATH_NSCDSOCKET);
|
||||
|
||||
nscd_parse_file (conffile);
|
||||
|
||||
/* Create first sockets */
|
||||
init_sockets ();
|
||||
/* Init databases */
|
||||
cache_pwdinit ();
|
||||
cache_grpinit ();
|
||||
/* Handle incoming requests */
|
||||
handle_requests ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create a socket connected to a name. */
|
||||
int
|
||||
__nscd_open_socket (void)
|
||||
{
|
||||
struct sockaddr_un addr;
|
||||
int sock;
|
||||
|
||||
sock = socket (PF_UNIX, SOCK_STREAM, 0);
|
||||
if (sock < 0)
|
||||
return -1;
|
||||
|
||||
addr.sun_family = AF_UNIX;
|
||||
strcpy (addr.sun_path, _PATH_NSCDSOCKET);
|
||||
if (connect (sock, (struct sockaddr *) &addr, sizeof (addr)) < 0)
|
||||
{
|
||||
close (sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
/* Cleanup. */
|
||||
static void
|
||||
termination_handler (int signum)
|
||||
{
|
||||
close_sockets ();
|
||||
|
||||
/* Clean up the files created by `bind'. */
|
||||
unlink (_PATH_NSCDSOCKET);
|
||||
|
||||
/* Clean up pid file. */
|
||||
unlink (_PATH_NSCDPID);
|
||||
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* Display usage information and exit. */
|
||||
static void
|
||||
usage (int status)
|
||||
{
|
||||
if (status != EXIT_SUCCESS)
|
||||
fprintf (stderr, _("Try `%s --help' for more information.\n"),
|
||||
program_invocation_name);
|
||||
else
|
||||
{
|
||||
printf (_("\
|
||||
Usage: %s [OPTION]...\n\
|
||||
-d, --debug do not fork and display messages on the current tty\n\
|
||||
-h, --help display this help and exit\n\
|
||||
-V, --version output version information and exit\n\
|
||||
-f configuration-file read configuration data from the specified file.\n\
|
||||
-K, --shutdown shut the server down.\n\
|
||||
-g Prints configuration and statistics to stdout.\n"),
|
||||
program_invocation_name);
|
||||
fputs (_("\
|
||||
Report bugs using the `glibcbug' script to <bugs@gnu.org>.\n"),
|
||||
stdout);
|
||||
}
|
||||
exit (status);
|
||||
}
|
||||
|
||||
/* Returns 1 if the process in pid file FILE is running, 0 if not. */
|
||||
static int
|
||||
check_pid (const char *file)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen (file, "r");
|
||||
if (fp)
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
fscanf (fp, "%d", &pid);
|
||||
fclose (fp);
|
||||
|
||||
if (kill (pid, 0) == 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Write the current process id to the file FILE.
|
||||
Returns 0 if successful, -1 if not. */
|
||||
static int
|
||||
write_pid (const char *file)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen (file, "w");
|
||||
if (fp == NULL)
|
||||
return -1;
|
||||
|
||||
fprintf (fp, "%d\n", getpid ());
|
||||
if (ferror (fp))
|
||||
return -1;
|
||||
|
||||
fclose (fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Type of the lookup function for netname2user. */
|
||||
typedef int (*pwbyname_function) (const char *name, struct passwd *pw,
|
||||
char *buffer, size_t buflen);
|
||||
|
||||
/* Hanlde incoming requests. */
|
||||
static
|
||||
void handle_requests (void)
|
||||
{
|
||||
request_header req;
|
||||
int conn; /* Handle on which connection (client) the request came from. */
|
||||
int done = 0;
|
||||
char *key;
|
||||
|
||||
while (!done)
|
||||
{
|
||||
key = NULL;
|
||||
get_request (&conn, &req, &key);
|
||||
if (debug_flag)
|
||||
dbg_log (_("handle_requests: request received (Version = %d)"),
|
||||
req.version);
|
||||
switch (req.type)
|
||||
{
|
||||
case GETPWBYNAME:
|
||||
{
|
||||
param_t *param = malloc (sizeof (param_t));
|
||||
pthread_t thread;
|
||||
|
||||
if (debug_flag)
|
||||
dbg_log ("\tGETPWBYNAME (%s)", key);
|
||||
param->key = key;
|
||||
param->conn = conn;
|
||||
if (disabled_passwd)
|
||||
pthread_create (&thread, NULL, cache_pw_disabled, (void *)param);
|
||||
else
|
||||
pthread_create (&thread, NULL, cache_getpwnam, (void *)param);
|
||||
pthread_detach (thread);
|
||||
}
|
||||
break;
|
||||
case GETPWBYUID:
|
||||
{
|
||||
param_t *param = malloc (sizeof (param_t));
|
||||
pthread_t thread;
|
||||
|
||||
if (debug_flag)
|
||||
dbg_log ("\tGETPWBYUID (%s)", key);
|
||||
param->key = key;
|
||||
param->conn = conn;
|
||||
if (disabled_passwd)
|
||||
pthread_create (&thread, NULL, cache_pw_disabled, (void *)param);
|
||||
else
|
||||
pthread_create (&thread, NULL, cache_getpwuid, (void *)param);
|
||||
pthread_detach (thread);
|
||||
}
|
||||
break;
|
||||
case GETGRBYNAME:
|
||||
{
|
||||
param_t *param = malloc (sizeof (param_t));
|
||||
pthread_t thread;
|
||||
|
||||
if (debug_flag)
|
||||
dbg_log ("\tGETGRBYNAME (%s)", key);
|
||||
param->key = key;
|
||||
param->conn = conn;
|
||||
if (disabled_group)
|
||||
pthread_create (&thread, NULL, cache_gr_disabled, (void *)param);
|
||||
else
|
||||
pthread_create (&thread, NULL, cache_getgrnam, (void *)param);
|
||||
pthread_detach (thread);
|
||||
}
|
||||
break;
|
||||
case GETGRBYGID:
|
||||
{
|
||||
param_t *param = malloc (sizeof (param_t));
|
||||
pthread_t thread;
|
||||
|
||||
if (debug_flag)
|
||||
dbg_log ("\tGETGRBYGID (%s)", key);
|
||||
param->key = key;
|
||||
param->conn = conn;
|
||||
if (disabled_group)
|
||||
pthread_create (&thread, NULL, cache_gr_disabled, (void *)param);
|
||||
else
|
||||
pthread_create (&thread, NULL, cache_getgrgid, (void *)param);
|
||||
pthread_detach (thread);
|
||||
}
|
||||
break;
|
||||
case GETHOSTBYNAME:
|
||||
/* Not yetimplemented. */
|
||||
close_socket (conn);
|
||||
break;
|
||||
case GETHOSTBYADDR:
|
||||
/* Not yet implemented. */
|
||||
close_socket (conn);
|
||||
break;
|
||||
case SHUTDOWN:
|
||||
do_shutdown = 1;
|
||||
close_socket (0);
|
||||
close_socket (conn);
|
||||
/* Clean up the files created by `bind'. */
|
||||
unlink (_PATH_NSCDSOCKET);
|
||||
/* Clean up pid file. */
|
||||
unlink (_PATH_NSCDPID);
|
||||
done = 1;
|
||||
break;
|
||||
case GETSTAT:
|
||||
{
|
||||
stat_response_header resp;
|
||||
|
||||
if (debug_flag)
|
||||
dbg_log ("\tGETSTAT");
|
||||
|
||||
get_pw_stat (&resp);
|
||||
get_gr_stat (&resp);
|
||||
resp.debug_level = debug_flag;
|
||||
resp.pw_enabled = !disabled_passwd;
|
||||
resp.gr_enabled = !disabled_group;
|
||||
|
||||
stat_send (conn, &resp);
|
||||
|
||||
close_socket (conn);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dbg_log (_("Unknown request (%d)"), req.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
30
nscd/nscd.conf
Normal file
30
nscd/nscd.conf
Normal file
@ -0,0 +1,30 @@
|
||||
#
|
||||
# /etc/nscd.conf
|
||||
#
|
||||
# An example Name Service Cache config file. This file is needed by nscd.
|
||||
#
|
||||
# Legal entries are:
|
||||
#
|
||||
# logfile <file>
|
||||
# enable-cache <service> <yes|no>
|
||||
# debug-level <level>
|
||||
# positive-time-to-live <service> <time in seconds>
|
||||
# negative-time-to-live <service> <time in seconds>
|
||||
# suggested-size <service> <prime number>
|
||||
#
|
||||
# Currently supported cache names (services): passwd, group
|
||||
#
|
||||
|
||||
|
||||
# logfile /var/adm/nscd.log
|
||||
# enable-cache hosts no
|
||||
|
||||
debug-level 0
|
||||
|
||||
positive-time-to-live passwd 600
|
||||
negative-time-to-live passwd 20
|
||||
suggested-size passwd 211
|
||||
|
||||
positive-time-to-live group 3600
|
||||
negative-time-to-live group 60
|
||||
suggested-size group 211
|
149
nscd/nscd.h
Normal file
149
nscd/nscd.h
Normal file
@ -0,0 +1,149 @@
|
||||
/* Copyright (c) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _NSCD_H
|
||||
#define _NSCD_H 1
|
||||
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
|
||||
/* Version number of the daemon interface */
|
||||
#define NSCD_VERSION 1
|
||||
|
||||
/* How many threads do we spawn maximal ? */
|
||||
#define MAX_NUM_CONNECTIONS 16
|
||||
|
||||
/* Services provided */
|
||||
typedef enum
|
||||
{
|
||||
GETPWBYNAME,
|
||||
GETPWBYUID,
|
||||
GETGRBYNAME,
|
||||
GETGRBYGID,
|
||||
GETHOSTBYNAME,
|
||||
GETHOSTBYADDR,
|
||||
SHUTDOWN, /* Shut the server down */
|
||||
GETSTAT /* Get the server statistic */
|
||||
} request_type;
|
||||
|
||||
/* Header common to all requests */
|
||||
typedef struct
|
||||
{
|
||||
/* Version number of the daemon interface */
|
||||
int version;
|
||||
/* Service requested */
|
||||
request_type type;
|
||||
/* key len */
|
||||
ssize_t key_len;
|
||||
} request_header;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int version;
|
||||
int found;
|
||||
ssize_t pw_name_len;
|
||||
ssize_t pw_passwd_len;
|
||||
uid_t pw_uid;
|
||||
gid_t pw_gid;
|
||||
ssize_t pw_gecos_len;
|
||||
ssize_t pw_dir_len;
|
||||
ssize_t pw_shell_len;
|
||||
} pw_response_header;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int version;
|
||||
int found;
|
||||
ssize_t gr_name_len;
|
||||
ssize_t gr_passwd_len;
|
||||
gid_t gr_gid;
|
||||
ssize_t gr_mem_len;
|
||||
} gr_response_header;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int debug_level;
|
||||
int pw_enabled;
|
||||
unsigned long pw_poshit;
|
||||
unsigned long pw_posmiss;
|
||||
unsigned long pw_neghit;
|
||||
unsigned long pw_negmiss;
|
||||
unsigned long pw_size;
|
||||
unsigned long pw_posttl;
|
||||
unsigned long pw_negttl;
|
||||
int gr_enabled;
|
||||
unsigned long gr_poshit;
|
||||
unsigned long gr_posmiss;
|
||||
unsigned long gr_neghit;
|
||||
unsigned long gr_negmiss;
|
||||
unsigned long gr_size;
|
||||
unsigned long gr_posttl;
|
||||
unsigned long gr_negttl;
|
||||
} stat_response_header;
|
||||
|
||||
#define _PATH_NSCDPID "/var/run/nscd.pid"
|
||||
#define _PATH_NSCDSOCKET "/var/run/.nscd_socket"
|
||||
#define _PATH_NSCDCONF "/etc/nscd.conf"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *key;
|
||||
int conn;
|
||||
} param_t;
|
||||
|
||||
extern int do_shutdown; /* 1 if we should quit the programm. */
|
||||
extern int disabled_passwd;
|
||||
extern int disabled_group;
|
||||
|
||||
extern int nscd_parse_file __P ((const char *fname));
|
||||
extern int set_logfile __P ((const char *logfile));
|
||||
extern void set_pos_pwd_ttl __P ((unsigned long));
|
||||
extern void set_neg_pwd_ttl __P ((unsigned long));
|
||||
extern void set_pos_grp_ttl __P ((unsigned long));
|
||||
extern void set_neg_grp_ttl __P ((unsigned long));
|
||||
extern void set_pwd_modulo __P ((unsigned long));
|
||||
extern void set_grp_modulo __P ((unsigned long));
|
||||
|
||||
extern void init_sockets __P ((void));
|
||||
extern void close_socket __P ((int conn));
|
||||
extern void close_sockets __P ((void));
|
||||
extern void get_request __P ((int *conn, request_header *req, char **key));
|
||||
extern void pw_send_answer __P ((int conn, struct passwd *pwd));
|
||||
extern void pw_send_disabled __P ((int conn));
|
||||
extern void gr_send_answer __P ((int conn, struct group *grp));
|
||||
extern void gr_send_disabled __P ((int conn));
|
||||
|
||||
extern int cache_pwdinit __P ((void));
|
||||
extern void *cache_getpwnam __P ((void *param));
|
||||
extern void *cache_getpwuid __P ((void *param));
|
||||
extern void *cache_pw_disabled __P ((void *param));
|
||||
|
||||
extern int cache_grpinit __P ((void));
|
||||
extern void *cache_getgrnam __P ((void *param));
|
||||
extern void *cache_getgrgid __P ((void *param));
|
||||
extern void *cache_gr_disabled __P ((void *param));
|
||||
|
||||
extern int __nscd_open_socket __P ((void));
|
||||
|
||||
extern void get_pw_stat __P ((stat_response_header *resp));
|
||||
extern void get_gr_stat __P ((stat_response_header *resp));
|
||||
extern void print_stat __P ((void));
|
||||
extern void stat_send __P ((int conn, stat_response_header *resp));
|
||||
|
||||
#endif
|
50
nscd/nscd.init
Normal file
50
nscd/nscd.init
Normal file
@ -0,0 +1,50 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# nscd: Starts the Name Switch Cache Daemon
|
||||
#
|
||||
# chkconfig: 345 52 25
|
||||
# description: This is a daemon which handles passwd and group lookups
|
||||
# for running programs and cache the results for the next
|
||||
# query. You should start this daemon only if you use
|
||||
# slow Services like NIS or NIS+
|
||||
|
||||
# Source function library.
|
||||
. /etc/rc.d/init.d/functions
|
||||
|
||||
# See how we were called.
|
||||
case "$1" in
|
||||
start)
|
||||
test -f /etc/nscd.conf -a -f /usr/sbin/nscd || exit 0
|
||||
secure=""
|
||||
# for table in passwd group
|
||||
# do
|
||||
# if egrep '^'$table':.*nisplus' /etc/nsswitch.conf >/dev/null
|
||||
# then
|
||||
# /usr/lib/nscd_nischeck $table ||
|
||||
# secure="$secure -S $table,yes"
|
||||
# fi
|
||||
# done
|
||||
echo -n "Starting Name Switch Cache Daemon: "
|
||||
daemon nscd $secure
|
||||
echo
|
||||
touch /var/lock/subsys/nscd
|
||||
;;
|
||||
stop)
|
||||
test -f /usr/sbin/nscd || exit 0
|
||||
echo -n "Stopping Name Switch Cache Daemon: "
|
||||
/usr/sbin/nscd -K
|
||||
rm -f /var/lock/subsys/nscd
|
||||
echo nscd
|
||||
;;
|
||||
status)
|
||||
status nscd
|
||||
;;
|
||||
restart)
|
||||
$0 stop
|
||||
$0 start
|
||||
;;
|
||||
*)
|
||||
echo "Usage: /etc/rc.d/init.d/nscd.init {start|stop|status|restart}"
|
||||
;;
|
||||
esac
|
||||
exit 0
|
148
nscd/nscd_conf.c
Normal file
148
nscd/nscd_conf.c
Normal file
@ -0,0 +1,148 @@
|
||||
/* Copyright (c) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "dbg_log.h"
|
||||
#include "nscd.h"
|
||||
|
||||
int
|
||||
nscd_parse_file (const char *fname)
|
||||
{
|
||||
FILE *fp;
|
||||
char *line, *cp, *entry, *arg1, *arg2;
|
||||
size_t len;
|
||||
|
||||
/* Open the configuration file. */
|
||||
fp = fopen (fname, "r");
|
||||
if (fp == NULL)
|
||||
return -1;
|
||||
|
||||
line = NULL;
|
||||
len = 0;
|
||||
|
||||
do
|
||||
{
|
||||
ssize_t n = getline (&line, &len, fp);
|
||||
if (n < 0)
|
||||
break;
|
||||
if (line[n - 1] == '\n')
|
||||
line[n - 1] = '\0';
|
||||
|
||||
/* Because the file format does not know any form of quoting we
|
||||
can search forward for the next '#' character and if found
|
||||
make it terminating the line. */
|
||||
cp = strchr (line, '#');
|
||||
if (cp != NULL)
|
||||
*cp = '\0';
|
||||
|
||||
/* If the line is blank it is ignored. */
|
||||
if (line[0] == '\0')
|
||||
continue;
|
||||
|
||||
entry = line;
|
||||
while (isspace (*entry) && *entry != '\0')
|
||||
++entry;
|
||||
cp = entry;
|
||||
while (!isspace (*cp) && *cp != '\0')
|
||||
++cp;
|
||||
arg1 = cp;
|
||||
++arg1;
|
||||
*cp = '\0';
|
||||
if (*cp = '\0' || strlen (entry) == 0)
|
||||
dbg_log (_("Parse error: %s"), line);
|
||||
while (isspace (*arg1) && *arg1 != '\0')
|
||||
++arg1;
|
||||
cp = arg1;
|
||||
while (!isspace (*cp) && *cp != '\0')
|
||||
++cp;
|
||||
arg2 = cp;
|
||||
++arg2;
|
||||
*cp = '\0';
|
||||
if (strlen (arg2) > 0)
|
||||
{
|
||||
while (isspace (*arg2) && *arg2 != '\0')
|
||||
++arg2;
|
||||
cp = arg2;
|
||||
while (!isspace (*cp) && *cp != '\0')
|
||||
++cp;
|
||||
*cp = '\0';
|
||||
}
|
||||
|
||||
if (strcmp (entry, "positive-time-to-live") == 0)
|
||||
{
|
||||
if (strcmp (arg1, "passwd") == 0)
|
||||
set_pos_pwd_ttl (atol (arg2));
|
||||
else if (strcmp (arg1, "group") == 0)
|
||||
set_pos_grp_ttl (atol (arg2));
|
||||
else
|
||||
dbg_log ("server %s is not supported\n", arg1);
|
||||
}
|
||||
else if (strcmp (entry, "negative-time-to-live") == 0)
|
||||
{
|
||||
if (strcmp (arg1, "passwd") == 0)
|
||||
set_neg_pwd_ttl (atol (arg2));
|
||||
else if (strcmp (arg1, "group") == 0)
|
||||
set_neg_grp_ttl (atol (arg2));
|
||||
else
|
||||
dbg_log (_("service %s is not supported"), arg1);
|
||||
}
|
||||
else if (strcmp (entry, "suggested-size") == 0)
|
||||
{
|
||||
if (strcmp (arg1, "passwd") == 0)
|
||||
set_pwd_modulo (atol (arg2));
|
||||
else if (strcmp (arg1, "group") == 0)
|
||||
set_grp_modulo (atol (arg2));
|
||||
else
|
||||
dbg_log (_("service %s is not supported"), arg1);
|
||||
}
|
||||
else if (strcmp (entry, "enable-cache") ==0)
|
||||
{
|
||||
if (strcmp (arg1, "passwd") == 0
|
||||
&& strcmp (arg2, "no") == 0)
|
||||
disabled_passwd = 1;
|
||||
}
|
||||
else if (strcmp (entry, "logfile") == 0)
|
||||
{
|
||||
if (!set_logfile (arg1))
|
||||
dbg_log (_("Could not create log file \"%s\""), arg1);
|
||||
}
|
||||
else if (strcmp (entry, "debug-level") == 0)
|
||||
{
|
||||
int level = atoi (arg1);
|
||||
if (level > 0)
|
||||
debug_flag = level;
|
||||
}
|
||||
else
|
||||
dbg_log (_("Unknown option: %s %s %s"), entry, arg1, arg2);
|
||||
}
|
||||
while (!feof (fp));
|
||||
|
||||
/* Free the buffer. */
|
||||
free (line);
|
||||
/* Close configuration file. */
|
||||
fclose (fp);
|
||||
|
||||
return 0;
|
||||
}
|
211
nscd/nscd_getgr_r.c
Normal file
211
nscd/nscd_getgr_r.c
Normal file
@ -0,0 +1,211 @@
|
||||
/* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <grp.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include "nscd.h"
|
||||
#include "nscd_proto.h"
|
||||
|
||||
static int __nscd_getgr_r (const char *key, request_type type,
|
||||
struct group *resultbuf, char *buffer,
|
||||
size_t buflen);
|
||||
|
||||
int
|
||||
__nscd_getgrnam_r (const char *name, struct group *resultbuf, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
if (name == NULL)
|
||||
return 1;
|
||||
|
||||
return __nscd_getgr_r (name, GETGRBYNAME, resultbuf, buffer, buflen);
|
||||
}
|
||||
|
||||
int
|
||||
__nscd_getgrgid_r (gid_t gid, struct group *resultbuf, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
char *p = buffer;
|
||||
char plen;
|
||||
|
||||
plen = snprintf (buffer, buflen, "%d", gid);
|
||||
if (plen == -1)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
}
|
||||
p = buffer + plen + 1;
|
||||
|
||||
return __nscd_getgr_r (buffer, GETGRBYGID, resultbuf, p, buflen - plen -1);
|
||||
}
|
||||
|
||||
/* Create a socket connected to a name. */
|
||||
static int
|
||||
nscd_open_socket (void)
|
||||
{
|
||||
struct sockaddr_un addr;
|
||||
int sock;
|
||||
|
||||
sock = socket (PF_UNIX, SOCK_STREAM, 0);
|
||||
if (sock < 0)
|
||||
return -1;
|
||||
|
||||
addr.sun_family = AF_UNIX;
|
||||
strcpy (addr.sun_path, _PATH_NSCDSOCKET);
|
||||
if (connect (sock, (struct sockaddr *) &addr, sizeof (addr)) < 0)
|
||||
{
|
||||
close (sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
static int
|
||||
__nscd_getgr_r (const char *key, request_type type, struct group *resultbuf,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
int sock = nscd_open_socket ();
|
||||
request_header req;
|
||||
gr_response_header gr_resp;
|
||||
ssize_t nbytes;
|
||||
|
||||
if (sock == -1)
|
||||
return 1;
|
||||
|
||||
req.version = NSCD_VERSION;
|
||||
req.type = type;
|
||||
req.key_len = strlen (key);
|
||||
nbytes = write (sock, &req, sizeof (request_header));
|
||||
if (nbytes != sizeof (request_header))
|
||||
{
|
||||
close (sock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
nbytes = write (sock, key, req.key_len);
|
||||
if (nbytes != req.key_len)
|
||||
{
|
||||
close (sock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
nbytes = read (sock, &gr_resp, sizeof (gr_response_header));
|
||||
if (nbytes != sizeof (gr_response_header))
|
||||
{
|
||||
close (sock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (gr_resp.found == -1)
|
||||
{
|
||||
close (sock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (gr_resp.found == 1)
|
||||
{
|
||||
size_t i;
|
||||
char *p = buffer;
|
||||
|
||||
if (buflen < gr_resp.gr_name_len + 1)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
close (sock);
|
||||
return -1;
|
||||
}
|
||||
resultbuf->gr_name = p;
|
||||
p += gr_resp.gr_name_len + 1;
|
||||
buflen -= (gr_resp.gr_name_len + 1);
|
||||
nbytes = read (sock, resultbuf->gr_name, gr_resp.gr_name_len);
|
||||
if (nbytes != gr_resp.gr_name_len)
|
||||
{
|
||||
close (sock);
|
||||
return 1;
|
||||
}
|
||||
resultbuf->gr_name[gr_resp.gr_name_len] = '\0';
|
||||
|
||||
if (buflen < gr_resp.gr_passwd_len + 1)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
close (sock);
|
||||
return -1;
|
||||
}
|
||||
resultbuf->gr_passwd = p;
|
||||
p += gr_resp.gr_passwd_len + 1;
|
||||
buflen -= (gr_resp.gr_passwd_len + 1);
|
||||
nbytes = read (sock, resultbuf->gr_passwd, gr_resp.gr_passwd_len);
|
||||
if (nbytes != gr_resp.gr_passwd_len)
|
||||
{
|
||||
close (sock);
|
||||
return 1;
|
||||
}
|
||||
resultbuf->gr_passwd[gr_resp.gr_passwd_len] = '\0';
|
||||
|
||||
resultbuf->gr_gid = gr_resp.gr_gid;
|
||||
|
||||
if (buflen < ((gr_resp.gr_mem_len + 1) * sizeof (char *)))
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
close (sock);
|
||||
return -1;
|
||||
}
|
||||
resultbuf->gr_mem = (char **)p;
|
||||
p += ((gr_resp.gr_mem_len + 1) * sizeof (char *));
|
||||
buflen -= ((gr_resp.gr_mem_len + 1) * sizeof (char *));
|
||||
|
||||
resultbuf->gr_mem[gr_resp.gr_mem_len] = NULL;
|
||||
|
||||
for (i = 0; i < gr_resp.gr_mem_len; ++i)
|
||||
{
|
||||
size_t len;
|
||||
nbytes = read (sock, &len, sizeof (len));
|
||||
if (nbytes != sizeof (len))
|
||||
{
|
||||
close (sock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (buflen < (len + 1))
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
close (sock);
|
||||
return -1;
|
||||
}
|
||||
resultbuf->gr_mem[i] = p;
|
||||
p += len + 1;
|
||||
buflen -= (len + 1);
|
||||
nbytes = read (sock, resultbuf->gr_mem[i], len);
|
||||
resultbuf->gr_mem[i][len] = '\0';
|
||||
if (nbytes != len)
|
||||
{
|
||||
close (sock);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
close (sock);
|
||||
return 0;
|
||||
}
|
198
nscd/nscd_getpw_r.c
Normal file
198
nscd/nscd_getpw_r.c
Normal file
@ -0,0 +1,198 @@
|
||||
/* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include "nscd.h"
|
||||
|
||||
static int __nscd_getpw_r (const char *key, request_type type,
|
||||
struct passwd *resultbuf, char *buffer,
|
||||
size_t buflen);
|
||||
|
||||
int
|
||||
__nscd_getpwnam_r (const char *name, struct passwd *resultbuf, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
if (name == NULL)
|
||||
return 1;
|
||||
|
||||
return __nscd_getpw_r (name, GETPWBYNAME, resultbuf, buffer, buflen);
|
||||
}
|
||||
|
||||
int
|
||||
__nscd_getpwuid_r (uid_t uid, struct passwd *resultbuf, char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
char *p = buffer;
|
||||
char plen;
|
||||
|
||||
plen = snprintf (buffer, buflen, "%d", uid);
|
||||
if (plen == -1)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
return -1;
|
||||
}
|
||||
p = buffer + plen + 1;
|
||||
|
||||
return __nscd_getpw_r (buffer, GETPWBYUID, resultbuf, p, buflen - plen -1);
|
||||
}
|
||||
|
||||
/* Create a socket connected to a name. */
|
||||
static int
|
||||
nscd_open_socket (void)
|
||||
{
|
||||
struct sockaddr_un addr;
|
||||
int sock;
|
||||
|
||||
sock = socket (PF_UNIX, SOCK_STREAM, 0);
|
||||
if (sock < 0)
|
||||
return -1;
|
||||
|
||||
addr.sun_family = AF_UNIX;
|
||||
strcpy (addr.sun_path, _PATH_NSCDSOCKET);
|
||||
if (connect (sock, (struct sockaddr *) &addr, sizeof (addr)) < 0)
|
||||
{
|
||||
close (sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
static int
|
||||
__nscd_getpw_r (const char *key, request_type type, struct passwd *resultbuf,
|
||||
char *buffer, size_t buflen)
|
||||
{
|
||||
int sock = nscd_open_socket ();
|
||||
request_header req;
|
||||
pw_response_header pw_resp;
|
||||
ssize_t nbytes;
|
||||
|
||||
if (sock == -1)
|
||||
return 1;
|
||||
|
||||
req.version = NSCD_VERSION;
|
||||
req.type = type;
|
||||
req.key_len = strlen (key);
|
||||
nbytes = write (sock, &req, sizeof (request_header));
|
||||
if (nbytes != sizeof (request_header))
|
||||
{
|
||||
close (sock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
nbytes = write (sock, key, req.key_len);
|
||||
if (nbytes != req.key_len)
|
||||
{
|
||||
close (sock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
nbytes = read (sock, &pw_resp, sizeof (pw_response_header));
|
||||
if (nbytes != sizeof (pw_response_header))
|
||||
{
|
||||
close (sock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pw_resp.found == -1)
|
||||
{
|
||||
close (sock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pw_resp.found == 1)
|
||||
{
|
||||
struct iovec vec[5];
|
||||
char *p = buffer;
|
||||
|
||||
if (buflen < pw_resp.pw_name_len + 1 + pw_resp.pw_passwd_len + 1
|
||||
+ pw_resp.pw_gecos_len + 1 + pw_resp.pw_dir_len + 1
|
||||
+ pw_resp.pw_shell_len + 1)
|
||||
{
|
||||
__set_errno (ERANGE);
|
||||
close (sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get pw_name */
|
||||
vec[0].iov_base = p;
|
||||
vec[0].iov_len = pw_resp.pw_name_len;
|
||||
p += pw_resp.pw_name_len + 1;
|
||||
buflen -= (pw_resp.pw_name_len + 1);
|
||||
/* get pw_passwd */
|
||||
vec[1].iov_base = p;
|
||||
vec[1].iov_len = pw_resp.pw_passwd_len;
|
||||
p += pw_resp.pw_passwd_len + 1;
|
||||
buflen -= (pw_resp.pw_passwd_len + 1);
|
||||
/* get pw_gecos */
|
||||
vec[2].iov_base = p;
|
||||
vec[2].iov_len = pw_resp.pw_gecos_len;
|
||||
p += pw_resp.pw_gecos_len + 1;
|
||||
buflen -= (pw_resp.pw_gecos_len + 1);
|
||||
/* get pw_dir */
|
||||
vec[3].iov_base = p;
|
||||
vec[3].iov_len = pw_resp.pw_dir_len;
|
||||
p += pw_resp.pw_dir_len + 1;
|
||||
buflen -= (pw_resp.pw_dir_len + 1);
|
||||
/* get pw_pshell */
|
||||
vec[4].iov_base = p;
|
||||
vec[4].iov_len = pw_resp.pw_dir_len;
|
||||
p += pw_resp.pw_dir_len + 1;
|
||||
buflen -= (pw_resp.pw_dir_len + 1);
|
||||
|
||||
nbytes = readv (sock, vec, 5);
|
||||
if (nbytes != pw_resp.pw_name_len + 1 + pw_resp.pw_passwd_len + 1 +
|
||||
pw_resp.pw_gecos_len + 1 + pw_resp.pw_dir_len + 1 +
|
||||
pw_resp.pw_shell_len + 1)
|
||||
{
|
||||
close (sock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
resultbuf->pw_name = vec[0].iov_base;
|
||||
resultbuf->pw_name[pw_resp.pw_name_len] = '\0';
|
||||
resultbuf->pw_passwd = vec[1].iov_base;
|
||||
resultbuf->pw_passwd[pw_resp.pw_passwd_len] = '\0';
|
||||
resultbuf->pw_uid = pw_resp.pw_uid;
|
||||
resultbuf->pw_gid = pw_resp.pw_gid;
|
||||
resultbuf->pw_gecos = vec[2].iov_base;
|
||||
resultbuf->pw_gecos[pw_resp.pw_gecos_len] = '\0';
|
||||
resultbuf->pw_dir = vec[3].iov_base;
|
||||
resultbuf->pw_dir[pw_resp.pw_dir_len] = '\0';
|
||||
resultbuf->pw_shell = vec[4].iov_base;
|
||||
resultbuf->pw_shell[pw_resp.pw_shell_len] = '\0';
|
||||
|
||||
close (sock);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
close (sock);
|
||||
return -1;
|
||||
}
|
||||
}
|
35
nscd/nscd_proto.h
Normal file
35
nscd/nscd_proto.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@uni-paderborn.de>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _NSCD_PROTO_H
|
||||
#define _NSCD_PROTO_H 1
|
||||
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
|
||||
extern int __nscd_getpwnam_r __P ((const char *name, struct passwd *resultbuf,
|
||||
char *buffer, size_t buflen));
|
||||
extern int __nscd_getpwuid_r __P ((uid_t uid, struct passwd *resultbuf,
|
||||
char *buffer, size_t buflen));
|
||||
extern int __nscd_getgrnam_r __P ((const char *name, struct group *resultbuf,
|
||||
char *buffer, size_t buflen));
|
||||
extern int __nscd_getgrgid_r __P ((uid_t uid, struct group *resultbuf,
|
||||
char *buffer, size_t buflen));
|
||||
|
||||
#endif /* _NSCD_PROTO_H */
|
87
nscd/nscd_stat.c
Normal file
87
nscd/nscd_stat.c
Normal file
@ -0,0 +1,87 @@
|
||||
/* Copyright (c) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include "nscd.h"
|
||||
|
||||
void
|
||||
print_stat (void)
|
||||
{
|
||||
int sock = __nscd_open_socket ();
|
||||
request_header req;
|
||||
stat_response_header resp;
|
||||
ssize_t nbytes;
|
||||
|
||||
if (sock == -1)
|
||||
{
|
||||
fputs (_("nscd not running!\n"), stdout);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
req.version = NSCD_VERSION;
|
||||
req.type = GETSTAT;
|
||||
req.key_len = 0;
|
||||
nbytes = write (sock, &req, sizeof (request_header));
|
||||
if (nbytes != sizeof (request_header))
|
||||
{
|
||||
perror (_("write incomplete"));
|
||||
close (sock);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
nbytes = read (sock, &resp, sizeof (stat_response_header));
|
||||
if (nbytes != sizeof (stat_response_header))
|
||||
{
|
||||
perror (_("read incomplete"));
|
||||
close (sock);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
close (sock);
|
||||
|
||||
printf (_("nscd configuration:\n\n"));
|
||||
printf (_("%12d server debug level\n\n"), resp.debug_level);
|
||||
|
||||
printf (_("passwd cache:\n\n"));
|
||||
printf (_("%12s cache is enabled\n"), resp.pw_enabled ? _("Yes") : _("No"));
|
||||
printf (_("%12ld cache hits on positive entries\n"), resp.pw_poshit);
|
||||
printf (_("%12ld cache hits on negative entries\n"), resp.pw_neghit);
|
||||
printf (_("%12ld cache misses on positive entries\n"), resp.pw_posmiss);
|
||||
printf (_("%12ld cache misses on negative entries\n"), resp.pw_negmiss);
|
||||
printf (_("%12ld suggested size\n"), resp.pw_size);
|
||||
printf (_("%12ld seconds time to live for positive entries\n"),
|
||||
resp.pw_posttl);
|
||||
printf (_("%12ld seconds time to live for negative entries\n\n"),
|
||||
resp.pw_negttl);
|
||||
|
||||
printf (_("group cache:\n\n"));
|
||||
printf (_("%12s cache is enabled\n"), resp.gr_enabled ? _("Yes") : _("No"));
|
||||
printf (_("%12ld cache hits on positive entries\n"), resp.gr_poshit);
|
||||
printf (_("%12ld cache hits on negative entries\n"), resp.gr_neghit);
|
||||
printf (_("%12ld cache misses on positive entries\n"), resp.gr_posmiss);
|
||||
printf (_("%12ld cache misses on negative entries\n"), resp.gr_negmiss);
|
||||
printf (_("%12ld suggested size\n"), resp.gr_size);
|
||||
printf (_("%12ld seconds time to live for positive entries\n"),
|
||||
resp.gr_posttl);
|
||||
printf (_("%12ld seconds time to live for negative entries\n"),
|
||||
resp.gr_negttl);
|
||||
}
|
581
nscd/pwdcache.c
Normal file
581
nscd/pwdcache.c
Normal file
@ -0,0 +1,581 @@
|
||||
/* Copyright (c) 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1998.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 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
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <pthread.h>
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
#include <rpcsvc/nis.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "dbg_log.h"
|
||||
#include "nscd.h"
|
||||
|
||||
static unsigned long int modulo = 211;
|
||||
static unsigned long int postimeout = 600;
|
||||
static unsigned long int negtimeout = 20;
|
||||
|
||||
static unsigned long int poshit = 0;
|
||||
static unsigned long int posmiss = 0;
|
||||
static unsigned long int neghit = 0;
|
||||
static unsigned long int negmiss = 0;
|
||||
|
||||
struct pwdhash
|
||||
{
|
||||
time_t create;
|
||||
struct pwdhash *next;
|
||||
struct passwd *pwd;
|
||||
};
|
||||
typedef struct pwdhash pwdhash;
|
||||
|
||||
struct uidhash
|
||||
{
|
||||
struct uidhash *next;
|
||||
struct pwdhash *pwptr;
|
||||
};
|
||||
typedef struct uidhash uidhash;
|
||||
|
||||
struct neghash
|
||||
{
|
||||
time_t create;
|
||||
struct neghash *next;
|
||||
char *key;
|
||||
};
|
||||
typedef struct neghash neghash;
|
||||
|
||||
static pwdhash *pwdtbl;
|
||||
static uidhash *uidtbl;
|
||||
static neghash *negtbl;
|
||||
|
||||
static pthread_rwlock_t pwdlock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
static pthread_rwlock_t neglock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
static void *pwdtable_update (void *);
|
||||
static void *negtable_update (void *);
|
||||
|
||||
void
|
||||
get_pw_stat (stat_response_header *stat)
|
||||
{
|
||||
stat->pw_poshit = poshit;
|
||||
stat->pw_posmiss = posmiss;
|
||||
stat->pw_neghit = neghit;
|
||||
stat->pw_negmiss = negmiss;
|
||||
stat->pw_size = modulo;
|
||||
stat->pw_posttl = postimeout;
|
||||
stat->pw_negttl = negtimeout;
|
||||
}
|
||||
|
||||
void
|
||||
set_pwd_modulo (unsigned long int mod)
|
||||
{
|
||||
modulo = mod;
|
||||
}
|
||||
|
||||
void
|
||||
set_pos_pwd_ttl (unsigned long int ttl)
|
||||
{
|
||||
postimeout = ttl;
|
||||
}
|
||||
|
||||
void
|
||||
set_neg_pwd_ttl (unsigned long int ttl)
|
||||
{
|
||||
negtimeout = ttl;
|
||||
}
|
||||
|
||||
int
|
||||
cache_pwdinit ()
|
||||
{
|
||||
pthread_t thread;
|
||||
|
||||
pwdtbl = calloc (modulo, sizeof (pwdhash));
|
||||
if (pwdtbl == NULL)
|
||||
return -1;
|
||||
uidtbl = calloc (modulo, sizeof (pwdhash));
|
||||
if (uidtbl == NULL)
|
||||
return -1;
|
||||
negtbl = calloc (modulo, sizeof (neghash));
|
||||
if (negtbl == NULL)
|
||||
return -1;
|
||||
|
||||
pthread_create (&thread, NULL, pwdtable_update, (void *)NULL);
|
||||
pthread_detach (thread);
|
||||
pthread_create (&thread, NULL, negtable_update, (void *)NULL);
|
||||
pthread_detach (thread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
save_pwd (struct passwd *src)
|
||||
{
|
||||
struct passwd *dest;
|
||||
|
||||
dest = calloc (1, sizeof (struct passwd));
|
||||
dest->pw_name = strdup (src->pw_name);
|
||||
dest->pw_passwd = strdup (src->pw_passwd);
|
||||
dest->pw_uid = src->pw_uid;
|
||||
dest->pw_gid = src->pw_gid;
|
||||
dest->pw_gecos = strdup (src->pw_gecos);
|
||||
dest->pw_dir = strdup (src->pw_dir);
|
||||
dest->pw_shell = strdup (src->pw_shell);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
static void
|
||||
free_pwd (struct passwd *src)
|
||||
{
|
||||
free (src->pw_name);
|
||||
free (src->pw_passwd);
|
||||
free (src->pw_gecos);
|
||||
free (src->pw_dir);
|
||||
free (src->pw_shell);
|
||||
free (src);
|
||||
}
|
||||
|
||||
static int
|
||||
add_cache (struct passwd *pwd)
|
||||
{
|
||||
pwdhash *work;
|
||||
unsigned long int hash = __nis_hash (pwd->pw_name,
|
||||
strlen (pwd->pw_name)) % modulo;
|
||||
|
||||
if (debug_flag)
|
||||
dbg_log (_("add_cache (%s)"), pwd->pw_name);
|
||||
|
||||
work = &pwdtbl[hash];
|
||||
|
||||
if (pwdtbl[hash].pwd == NULL)
|
||||
pwdtbl[hash].pwd = save_pwd (pwd);
|
||||
else
|
||||
{
|
||||
while (work->next != NULL)
|
||||
work = work->next;
|
||||
|
||||
work->next = calloc (1, sizeof (pwdhash));
|
||||
work->next->pwd = save_pwd (pwd);
|
||||
work = work->next;
|
||||
}
|
||||
/* Set a pointer from the pwuid hash table to the pwname hash table */
|
||||
time (&work->create);
|
||||
uidtbl[pwd->pw_uid % modulo].pwptr = work;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
cache_search_name (const char *name)
|
||||
{
|
||||
pwdhash *work;
|
||||
unsigned long int hash = __nis_hash (name, strlen (name)) % modulo;
|
||||
|
||||
work = &pwdtbl[hash];
|
||||
|
||||
while (work->pwd != NULL)
|
||||
{
|
||||
if (strcmp (work->pwd->pw_name, name) == 0)
|
||||
return work->pwd;
|
||||
if (work->next != NULL)
|
||||
work = work->next;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct passwd *
|
||||
cache_search_uid (uid_t uid)
|
||||
{
|
||||
uidhash *work;
|
||||
|
||||
work = &uidtbl[uid % modulo];
|
||||
|
||||
while (work->pwptr != NULL)
|
||||
{
|
||||
if (work->pwptr->pwd->pw_uid == uid)
|
||||
return work->pwptr->pwd;
|
||||
if (work->next != NULL)
|
||||
work = work->next;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
add_negcache (char *key)
|
||||
{
|
||||
neghash *work;
|
||||
unsigned long int hash = __nis_hash (key, strlen (key)) % modulo;
|
||||
|
||||
if (debug_flag)
|
||||
dbg_log (_("add_netgache (%s|%ld)"), key, hash);
|
||||
|
||||
work = &negtbl[hash];
|
||||
|
||||
if (negtbl[hash].key == NULL)
|
||||
{
|
||||
negtbl[hash].key = strdup (key);
|
||||
negtbl[hash].next = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (work->next != NULL)
|
||||
work = work->next;
|
||||
|
||||
work->next = calloc (1, sizeof (neghash));
|
||||
work->next->key = strdup (key);
|
||||
work = work->next;
|
||||
}
|
||||
/* Set a pointer from the pwuid hash table to the pwname hash table */
|
||||
time (&work->create);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
cache_search_neg (const char *key)
|
||||
{
|
||||
neghash *work;
|
||||
unsigned long int hash = __nis_hash (key, strlen (key)) % modulo;
|
||||
|
||||
work = &negtbl[hash];
|
||||
|
||||
if (debug_flag)
|
||||
dbg_log (_("cache_search_neg (%s|%ld)"), key, hash);
|
||||
|
||||
while (work->key != NULL)
|
||||
{
|
||||
if (strcmp (work->key, key) == 0)
|
||||
return 1;
|
||||
if (work->next != NULL)
|
||||
work = work->next;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
cache_getpwnam (void *v_param)
|
||||
{
|
||||
param_t *param = (param_t *)v_param;
|
||||
struct passwd *pwd, resultbuf;
|
||||
|
||||
pthread_rwlock_rdlock (&pwdlock);
|
||||
pwd = cache_search_name (param->key);
|
||||
|
||||
/* I don't like it to hold the read only lock longer, but it is
|
||||
necessary to avoid to much malloc/free/strcpy. */
|
||||
|
||||
if (pwd != NULL)
|
||||
{
|
||||
if (debug_flag)
|
||||
dbg_log (_("Found \"%s\" in cache !"), param->key);
|
||||
|
||||
++poshit;
|
||||
pw_send_answer (param->conn, pwd);
|
||||
close_socket (param->conn);
|
||||
|
||||
pthread_rwlock_unlock (&pwdlock);
|
||||
pwd = &resultbuf;
|
||||
}
|
||||
else
|
||||
{
|
||||
int status;
|
||||
int buflen = 1024;
|
||||
char *buffer = malloc (buflen);
|
||||
|
||||
if (debug_flag)
|
||||
dbg_log (_("Doesn't found \"%s\" in cache !"), param->key);
|
||||
|
||||
pthread_rwlock_unlock (&pwdlock);
|
||||
|
||||
pthread_rwlock_rdlock (&neglock);
|
||||
status = cache_search_neg (param->key);
|
||||
pthread_rwlock_unlock (&neglock);
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
while (buffer != NULL
|
||||
&& (getpwnam_r (param->key, &resultbuf, buffer, buflen, &pwd)
|
||||
!= 0)
|
||||
&& errno == ERANGE)
|
||||
{
|
||||
errno = 0;
|
||||
buflen += 1024;
|
||||
buffer = realloc (buffer, buflen);
|
||||
}
|
||||
|
||||
if (buffer != NULL && pwd != NULL)
|
||||
{
|
||||
struct passwd *tmp;
|
||||
|
||||
++posmiss;
|
||||
pthread_rwlock_wrlock (&pwdlock);
|
||||
/* While we are waiting on the lock, somebody else could
|
||||
add this entry. */
|
||||
tmp = cache_search_name (param->key);
|
||||
if (tmp == NULL)
|
||||
add_cache (pwd);
|
||||
pthread_rwlock_unlock (&pwdlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
++negmiss;
|
||||
pthread_rwlock_wrlock (&neglock);
|
||||
add_negcache (param->key);
|
||||
pthread_rwlock_unlock (&neglock);
|
||||
}
|
||||
}
|
||||
else
|
||||
++neghit;
|
||||
pw_send_answer (param->conn, pwd);
|
||||
close_socket (param->conn);
|
||||
if (buffer != NULL)
|
||||
free (buffer);
|
||||
}
|
||||
free (param->key);
|
||||
free (param);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
cache_pw_disabled (void *v_param)
|
||||
{
|
||||
param_t *param = (param_t *)v_param;
|
||||
|
||||
pw_send_disabled (param->conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
cache_getpwuid (void *v_param)
|
||||
{
|
||||
param_t *param = (param_t *)v_param;
|
||||
struct passwd *pwd, resultbuf;
|
||||
uid_t uid = strtol (param->key, NULL, 10);
|
||||
|
||||
pthread_rwlock_rdlock (&pwdlock);
|
||||
pwd = cache_search_uid (uid);
|
||||
|
||||
/* I don't like it to hold the read only lock longer, but it is
|
||||
necessary to avoid to much malloc/free/strcpy. */
|
||||
|
||||
if (pwd != NULL)
|
||||
{
|
||||
if (debug_flag)
|
||||
dbg_log (_("Found \"%d\" in cache !"), uid);
|
||||
|
||||
++poshit;
|
||||
pw_send_answer (param->conn, pwd);
|
||||
close_socket (param->conn);
|
||||
|
||||
pthread_rwlock_unlock (&pwdlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
int buflen = 1024;
|
||||
char *buffer = malloc (buflen);
|
||||
int status;
|
||||
|
||||
if (debug_flag)
|
||||
dbg_log (_("Doesn't found \"%d\" in cache !"), uid);
|
||||
|
||||
pthread_rwlock_unlock (&pwdlock);
|
||||
|
||||
pthread_rwlock_rdlock (&neglock);
|
||||
status = cache_search_neg (param->key);
|
||||
pthread_rwlock_unlock (&neglock);
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
while (buffer != NULL
|
||||
&& (getpwuid_r (uid, &resultbuf, buffer, buflen, &pwd) != 0)
|
||||
&& errno == ERANGE)
|
||||
{
|
||||
errno = 0;
|
||||
buflen += 1024;
|
||||
buffer = realloc (buffer, buflen);
|
||||
}
|
||||
|
||||
if (buffer != NULL && pwd != NULL)
|
||||
{
|
||||
struct passwd *tmp;
|
||||
|
||||
++posmiss;
|
||||
pthread_rwlock_wrlock (&pwdlock);
|
||||
/* While we are waiting on the lock, somebody else could
|
||||
add this entry. */
|
||||
tmp = cache_search_uid (uid);
|
||||
if (tmp == NULL)
|
||||
add_cache (pwd);
|
||||
pthread_rwlock_unlock (&pwdlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
++negmiss;
|
||||
pthread_rwlock_wrlock (&neglock);
|
||||
add_negcache (param->key);
|
||||
pthread_rwlock_unlock (&neglock);
|
||||
}
|
||||
}
|
||||
else
|
||||
++neghit;
|
||||
|
||||
pw_send_answer (param->conn, pwd);
|
||||
close_socket (param->conn);
|
||||
if (buffer != NULL)
|
||||
free (buffer);
|
||||
}
|
||||
free (param->key);
|
||||
free (param);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
pwdtable_update (void *v)
|
||||
{
|
||||
time_t now;
|
||||
int i;
|
||||
|
||||
sleep (20);
|
||||
|
||||
while (!do_shutdown)
|
||||
{
|
||||
if (debug_flag > 2)
|
||||
dbg_log (_("(pwdtable_update) Wait for write lock!"));
|
||||
|
||||
pthread_rwlock_wrlock (&pwdlock);
|
||||
|
||||
if (debug_flag > 2)
|
||||
dbg_log (_("(pwdtable_update) Have write lock"));
|
||||
|
||||
time (&now);
|
||||
for (i = 0; i < modulo; ++i)
|
||||
{
|
||||
pwdhash *work = &pwdtbl[i];
|
||||
|
||||
while (work && work->pwd)
|
||||
{
|
||||
if ((now - work->create) >= postimeout)
|
||||
{
|
||||
uidhash *uh = &uidtbl[work->pwd->pw_uid % modulo];
|
||||
|
||||
if (debug_flag)
|
||||
dbg_log (_("Give \"%s\" free"), work->pwd->pw_name);
|
||||
|
||||
while (uh != NULL && uh->pwptr)
|
||||
{
|
||||
if (uh->pwptr->pwd->pw_uid == work->pwd->pw_uid)
|
||||
{
|
||||
if (debug_flag)
|
||||
dbg_log (_("Give uid for \"%s\" free"),
|
||||
work->pwd->pw_name);
|
||||
if (uh->next != NULL)
|
||||
{
|
||||
uidhash *tmp = uh->next;
|
||||
uh->pwptr = tmp->pwptr;
|
||||
uh->next = tmp->next;
|
||||
free (tmp);
|
||||
}
|
||||
else
|
||||
uh->pwptr = NULL;
|
||||
}
|
||||
uh = uh->next;
|
||||
}
|
||||
|
||||
free_pwd (work->pwd);
|
||||
if (work->next != NULL)
|
||||
{
|
||||
pwdhash *tmp = work->next;
|
||||
work->create = tmp->create;
|
||||
work->next = tmp->next;
|
||||
work->pwd = tmp->pwd;
|
||||
free (tmp);
|
||||
}
|
||||
else
|
||||
work->pwd = NULL;
|
||||
}
|
||||
work = work->next;
|
||||
}
|
||||
}
|
||||
if (debug_flag > 2)
|
||||
dbg_log (_("(pwdtable_update) Release wait lock"));
|
||||
pthread_rwlock_unlock (&pwdlock);
|
||||
sleep (20);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *
|
||||
negtable_update (void *v)
|
||||
{
|
||||
time_t now;
|
||||
int i;
|
||||
|
||||
sleep (30);
|
||||
|
||||
while (!do_shutdown)
|
||||
{
|
||||
if (debug_flag > 2)
|
||||
dbg_log (_("(negtable_update) Wait for write lock!"));
|
||||
|
||||
pthread_rwlock_wrlock (&neglock);
|
||||
|
||||
if (debug_flag)
|
||||
dbg_log (_("(negtable_update) Have write lock"));
|
||||
|
||||
time (&now);
|
||||
for (i = 0; i < modulo; ++i)
|
||||
{
|
||||
neghash *work = &negtbl[i];
|
||||
|
||||
while (work && work->key)
|
||||
{
|
||||
if ((now - work->create) >= negtimeout)
|
||||
{
|
||||
if (debug_flag)
|
||||
dbg_log (_("Give \"%s\" free"), work->key);
|
||||
|
||||
free (work->key);
|
||||
|
||||
if (work->next != NULL)
|
||||
{
|
||||
neghash *tmp = work->next;
|
||||
work->create = tmp->create;
|
||||
work->next = tmp->next;
|
||||
work->key = tmp->key;
|
||||
free (tmp);
|
||||
}
|
||||
else
|
||||
work->key = NULL;
|
||||
}
|
||||
work = work->next;
|
||||
}
|
||||
}
|
||||
if (debug_flag)
|
||||
dbg_log (_("(negtable_update) Release wait lock"));
|
||||
|
||||
pthread_rwlock_unlock (&neglock);
|
||||
sleep (10);
|
||||
}
|
||||
return NULL;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include "nsswitch.h"
|
||||
#include <nscd/nscd_proto.h>
|
||||
|
||||
/*******************************************************************\
|
||||
|* Here we assume several symbols to be defined: *|
|
||||
@ -51,6 +52,12 @@
|
||||
#define INTERNAL(name) INTERNAL1 (name)
|
||||
#define INTERNAL1(name) __##name
|
||||
|
||||
#ifdef USE_NSCD
|
||||
# define NSCD_NAME ADD_NSCD (REENTRANT_NAME)
|
||||
# define ADD_NSCD(name) ADD_NSCD1 (name)
|
||||
# define ADD_NSCD1(name) __nscd_##name
|
||||
#endif
|
||||
|
||||
#define FUNCTION_NAME_STRING STRINGIZE (FUNCTION_NAME)
|
||||
#define REENTRANT_NAME_STRING STRINGIZE (REENTRANT_NAME)
|
||||
#define DATABASE_NAME_STRING STRINGIZE (DATABASE_NAME)
|
||||
@ -93,6 +100,9 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
|
||||
lookup_function fct;
|
||||
int no_more;
|
||||
enum nss_status status = NSS_STATUS_UNAVAIL;
|
||||
#ifdef USE_NSCD
|
||||
int nscd_status;
|
||||
#endif
|
||||
|
||||
#ifdef HANDLE_DIGITS_DOTS
|
||||
# define resbuf (*resbuf)
|
||||
@ -100,6 +110,15 @@ INTERNAL (REENTRANT_NAME) (ADD_PARAMS, LOOKUP_TYPE *resbuf, char *buffer,
|
||||
# undef resbuf
|
||||
#endif
|
||||
|
||||
#ifdef USE_NSCD
|
||||
nscd_status = NSCD_NAME (ADD_VARIABLES, resbuf, buffer, buflen H_ERRNO_VAR);
|
||||
if (nscd_status < 1)
|
||||
{
|
||||
*result = nscd_status == 0 ? resbuf : NULL;
|
||||
return nscd_status;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (startp == NULL)
|
||||
{
|
||||
no_more = DB_LOOKUP_FCT (&nip, REENTRANT_NAME_STRING, (void **) &fct);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
@ -26,5 +26,6 @@
|
||||
#define ADD_PARAMS const char *name
|
||||
#define ADD_VARIABLES name
|
||||
#define BUFLEN NSS_BUFLEN_PASSWD
|
||||
#define USE_NSCD 1
|
||||
|
||||
#include "../nss/getXXbyYY_r.c"
|
||||
#include <nss/getXXbyYY_r.c>
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
|
||||
|
||||
@ -26,5 +26,6 @@
|
||||
#define ADD_PARAMS uid_t uid
|
||||
#define ADD_VARIABLES uid
|
||||
#define BUFLEN NSS_BUFLEN_PASSWD
|
||||
#define USE_NSCD 1
|
||||
|
||||
#include "../nss/getXXbyYY_r.c"
|
||||
#include <nss/getXXbyYY_r.c>
|
||||
|
@ -3,4 +3,5 @@ resolv
|
||||
hesiod
|
||||
sunrpc
|
||||
nis
|
||||
nscd
|
||||
streams
|
||||
|
Loading…
x
Reference in New Issue
Block a user