diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2010-06-14 21:17:05 +0000 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2010-06-14 21:17:05 +0000 |
commit | 9b65ad7e014d3198ab0995572fc2f7adf9b35a0f (patch) | |
tree | 503583403c003b9dc52e9a830e0f9d6cc5a95ba9 | |
parent | 2c40043c434b883a0bfce7d777a028ae0da6d25f (diff) |
implement a global symbol inside the NSS module to allow applications to disable NSS lookups over LDAP and use it in nslcd to avoid deadlocks
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-pam-ldapd@1141 ef36b2f9-881f-0410-afb5-c4e39611909c
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | nslcd/nslcd.c | 46 | ||||
-rw-r--r-- | nss/Makefile.am | 4 | ||||
-rw-r--r-- | nss/common.c | 22 | ||||
-rw-r--r-- | nss/common.h | 10 | ||||
-rw-r--r-- | nss/exports.linux | 3 | ||||
-rw-r--r-- | nss/netgroup.c | 2 | ||||
-rw-r--r-- | nss/prototypes.h | 6 | ||||
-rw-r--r-- | tests/Makefile.am | 4 |
9 files changed, 85 insertions, 14 deletions
diff --git a/configure.ac b/configure.ac index 166210f..f2bda9b 100644 --- a/configure.ac +++ b/configure.ac @@ -323,6 +323,7 @@ then # checks for availability of system libraries for nslcd AC_SEARCH_LIBS(gethostbyname,nsl socket) AC_SEARCH_LIBS(socket,socket) + AC_SEARCH_LIBS(dlopen,dl) # check for availability of functions AC_CHECK_FUNCS(setgroups) @@ -330,6 +331,7 @@ then AC_CHECK_FUNCS(getpeerucred) AC_CHECK_FUNCS(__nss_configure_lookup) AC_CHECK_FUNCS(getenv putenv clearenv) + AC_CHECK_FUNCS(dlopen dlsym dlerror) # replace getopt_long() function if it is not on the system AC_REPLACE_FUNCS(getopt_long) diff --git a/nslcd/nslcd.c b/nslcd/nslcd.c index 3aa1e7f..c6fcfaa 100644 --- a/nslcd/nslcd.c +++ b/nslcd/nslcd.c @@ -55,6 +55,7 @@ #ifndef HAVE_DAEMON #include "compat/daemon.h" #endif /* not HAVE_DAEMON */ +#include <dlfcn.h> #include "nslcd.h" #include "log.h" @@ -565,6 +566,41 @@ static void *worker(void UNUSED(*arg)) return NULL; } +/* function to disable lookups through the nss_ldap module to avoid lookup + loops */ +static void disable_nss_ldap(void) +{ + void *handle; + char *error; + int *enable_flag; + /* try to load the NSS module */ + handle=dlopen("libnss_ldap.so.2",RTLD_LAZY); + if (handle==NULL) + { + log_log(LOG_WARNING,"Warning: LDAP NSS module not loaded: %s",dlerror()); + return; + } + /* clear any existing errors */ + dlerror(); + /* try to look up the flag */ + enable_flag=(int *)dlsym(handle,"_nss_ldap_enablelookups"); + error=dlerror(); + if (error!=NULL) + { + log_log(LOG_WARNING,"Warning: %s (probably older NSS module loaded)",error); + /* fall back to changing the way host lookup is done */ +#ifdef HAVE___NSS_CONFIGURE_LOOKUP + if (__nss_configure_lookup("hosts","files dns")) + log_log(LOG_ERR,"unable to override hosts lookup method: %s",strerror(errno)); +#endif /* HAVE___NSS_CONFIGURE_LOOKUP */ + return; + } + /* disable nss_ldap */ + *enable_flag=0; + /* we don't do dlclose() because we want the symbol change to be + persistent */ +} + /* the main program... */ int main(int argc,char *argv[]) { @@ -585,14 +621,8 @@ int main(int argc,char *argv[]) /* this is a bit ugly */ environ=sane_environment; #endif /* not HAVE_CLEARENV */ - /* disable ldap lookups of host names to avoid lookup loop - and fall back to files dns (a sensible default) */ - /* TODO: parse /etc/nsswitch ourselves and just remove ldap from the list */ -#ifdef HAVE___NSS_CONFIGURE_LOOKUP - if (__nss_configure_lookup("hosts","files dns")) - log_log(LOG_ERR,"unable to override hosts lookup method: %s",strerror(errno)); -#endif /* HAVE___NSS_CONFIGURE_LOOKUP */ - /* FIXME: have some other mechanism for systems that don't have this */ + /* disable the nss_ldap module for this process */ + disable_nss_ldap(); /* set LDAP log level */ if (myldap_set_debuglevel(nslcd_debugging)!=LDAP_SUCCESS) exit(EXIT_FAILURE); diff --git a/nss/Makefile.am b/nss/Makefile.am index 72d53f3..89d9a4e 100644 --- a/nss/Makefile.am +++ b/nss/Makefile.am @@ -2,7 +2,7 @@ # # Copyright (C) 2006 Luke Howard # Copyright (C) 2006 West Consulting -# Copyright (C) 2006, 2007, 2009 Arthur de Jong +# Copyright (C) 2006, 2007, 2009, 2010 Arthur de Jong # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,7 @@ AM_CFLAGS = -fPIC NSS_VERS = 2 NSS_LDAP_NSS_VERSIONED = libnss_ldap.so.$(NSS_VERS) -nss_ldap_so_SOURCES = common.h prototypes.h \ +nss_ldap_so_SOURCES = common.c common.h prototypes.h \ ../nslcd.h ../common/nslcd-prot.h \ ../compat/attrs.h \ aliases.c ethers.c group.c hosts.c netgroup.c \ diff --git a/nss/common.c b/nss/common.c new file mode 100644 index 0000000..20a3136 --- /dev/null +++ b/nss/common.c @@ -0,0 +1,22 @@ +/* + common.c - common definitions + + Copyright (C) 2010 Arthur de Jong + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301 USA +*/ + +int _nss_ldap_enablelookups=1; diff --git a/nss/common.h b/nss/common.h index bf7d67d..bf03e9b 100644 --- a/nss/common.h +++ b/nss/common.h @@ -2,7 +2,7 @@ common.h - common functions for NSS lookups Copyright (C) 2006 West Consulting - Copyright (C) 2006, 2007, 2008, 2009 Arthur de Jong + Copyright (C) 2006, 2007, 2008, 2009, 2010 Arthur de Jong This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -83,6 +83,8 @@ TFILE *fp; \ int32_t tmpint32; \ enum nss_status retv; \ + if (!_nss_ldap_enablelookups) \ + return NSS_STATUS_UNAVAIL; \ /* check that we have a valid buffer */ \ if ((buffer==NULL)||(buflen<=0)) \ { \ @@ -117,6 +119,8 @@ /* This macro generates a simple setent() function body. This closes any open streams so that NSS_GETENT() can open a new file. */ #define NSS_SETENT(fp) \ + if (!_nss_ldap_enablelookups) \ + return NSS_STATUS_UNAVAIL; \ if (fp!=NULL) \ { \ (void)tio_close(fp); \ @@ -130,6 +134,8 @@ #define NSS_GETENT(fp,action,readfn) \ int32_t tmpint32; \ enum nss_status retv; \ + if (!_nss_ldap_enablelookups) \ + return NSS_STATUS_UNAVAIL; \ /* check that we have a valid buffer */ \ if ((buffer==NULL)||(buflen<=0)) \ { \ @@ -174,6 +180,8 @@ /* This macro generates a endent() function body. This just closes the stream. */ #define NSS_ENDENT(fp) \ + if (!_nss_ldap_enablelookups) \ + return NSS_STATUS_UNAVAIL; \ if (fp!=NULL) \ { \ (void)tio_close(fp); \ diff --git a/nss/exports.linux b/nss/exports.linux index 62c0313..0ed5ea2 100644 --- a/nss/exports.linux +++ b/nss/exports.linux @@ -3,6 +3,9 @@ EXPORTED { # published NSS service functions global: + # flag to enable or disable lookups + _nss_ldap_enablelookups; + # aliases - mail aliases _nss_ldap_getaliasbyname_r; _nss_ldap_setaliasent; diff --git a/nss/netgroup.c b/nss/netgroup.c index d052c84..93fc923 100644 --- a/nss/netgroup.c +++ b/nss/netgroup.c @@ -96,6 +96,8 @@ enum nss_status _nss_ldap_setnetgrent(const char *group,struct __netgrent UNUSED int32_t tmpint32; int errnocp; int *errnop; + if (!_nss_ldap_enablelookups) + return NSS_STATUS_UNAVAIL; errnop=&errnocp; /* check parameter */ if ((group==NULL)||(group[0]=='\0')) diff --git a/nss/prototypes.h b/nss/prototypes.h index 7b82c27..c611883 100644 --- a/nss/prototypes.h +++ b/nss/prototypes.h @@ -2,7 +2,7 @@ prototypes.h - all functions exported by the NSS library Copyright (C) 2006 West Consulting - Copyright (C) 2006, 2008 Arthur de Jong + Copyright (C) 2006, 2008, 2010 Arthur de Jong This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -97,6 +97,10 @@ struct __netgrent http://www.gnu.org/software/libc/manual/html_node/Name-Service-Switch.html */ +/* flag to gloabally disable lookups (all _nss_ldap_*() functions will return + NSS_STATUS_UNAVAIL */ +extern int _nss_ldap_enablelookups; + /* aliases - mail aliases */ enum nss_status _nss_ldap_getaliasbyname_r(const char *name,struct aliasent *result,char *buffer,size_t buflen,int *errnop); enum nss_status _nss_ldap_setaliasent(void); diff --git a/tests/Makefile.am b/tests/Makefile.am index a0be82c..65b49e3 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,7 +1,7 @@ # Makefile.am - use automake to generate Makefile.in # # Copyright (C) 2006 West Consulting -# Copyright (C) 2006, 2007, 2008, 2009 Arthur de Jong +# Copyright (C) 2006, 2007, 2008, 2009, 2010 Arthur de Jong # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -86,7 +86,7 @@ test_common_LDADD = ../nslcd/log.o ../nslcd/common.o ../nslcd/cfg.o \ ../common/libdict.a ../compat/libcompat.a common_SOURCES = ../common/nslcd-prot.c ../nslcd.h ../nss/prototypes.h \ - ../common/tio.c ../common/tio.h + ../common/tio.c ../common/tio.h ../nss/common.c test_aliases_SOURCES = test_aliases.c ../nss/aliases.c $(common_SOURCES) test_ethers_SOURCES = test_ethers.c ../nss/ethers.c $(common_SOURCES) |