diff options
author | Luke Shumaker <lukeshu@sbcglobal.net> | 2014-10-04 16:13:03 -0400 |
---|---|---|
committer | Luke Shumaker <lukeshu@sbcglobal.net> | 2014-10-04 16:13:03 -0400 |
commit | c9618dfe442305531ee6cab9660333f4a697e094 (patch) | |
tree | 63da3cf1c107fdebd82987519b858f0d98c12d23 | |
parent | be4588009b7106859e1beae6038aaea8d7f85825 (diff) |
foo
-rw-r--r-- | compat/ether.c | 60 | ||||
-rw-r--r-- | compat/ether.h | 64 | ||||
-rw-r--r-- | compat/nss_compat.h | 159 | ||||
-rw-r--r-- | configure.ac | 701 | ||||
-rw-r--r-- | nslcd/alias.c | 139 | ||||
-rw-r--r-- | nslcd/attmap.c | 309 | ||||
-rw-r--r-- | nslcd/attmap.h | 99 | ||||
-rw-r--r-- | nslcd/cfg.c | 12 | ||||
-rw-r--r-- | nslcd/common.h | 47 | ||||
-rw-r--r-- | nslcd/db_config.c (renamed from nslcd/config.c) | 0 | ||||
-rw-r--r-- | nslcd/db_pam.c (renamed from nslcd/pam.c) | 0 | ||||
-rw-r--r-- | nslcd/db_passwd.c | 163 | ||||
-rw-r--r-- | nslcd/db_shadow.c (renamed from nslcd/shadow.c) | 79 | ||||
-rw-r--r-- | nslcd/ether.c | 188 | ||||
-rw-r--r-- | nslcd/group.c | 599 | ||||
-rw-r--r-- | nslcd/host.c | 191 | ||||
-rw-r--r-- | nslcd/myldap.c | 432 | ||||
-rw-r--r-- | nslcd/myldap.h | 6 | ||||
-rw-r--r-- | nslcd/netgroup.c | 257 | ||||
-rw-r--r-- | nslcd/network.c | 189 | ||||
-rw-r--r-- | nslcd/nslcd.c | 53 | ||||
-rw-r--r-- | nslcd/nsswitch.c | 2 | ||||
-rw-r--r-- | nslcd/passwd.c | 603 | ||||
-rw-r--r-- | nslcd/protocol.c | 197 | ||||
-rw-r--r-- | nslcd/rpc.c | 195 | ||||
-rw-r--r-- | nslcd/service.c | 246 | ||||
-rw-r--r-- | nslcd/usermod.c | 299 |
27 files changed, 228 insertions, 5061 deletions
diff --git a/compat/ether.c b/compat/ether.c deleted file mode 100644 index 7204b9d..0000000 --- a/compat/ether.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - ether.c - useful ethernet functions for systems lacking those - - Copyright (C) 2008, 2009, 2010, 2012 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 -*/ - -#include "config.h" - -#include <string.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <net/if.h> -#include <netinet/in.h> -#include <netinet/if_ether.h> -#ifdef HAVE_NETINET_ETHER_H -#include <netinet/ether.h> -#endif - -#include "ether.h" - -/* these functions are not really reentrant */ - -#ifndef HAVE_ETHER_NTOA_R -char *ether_ntoa_r(const struct ether_addr *addr, char *buf) -{ - char *tmp; - tmp = ether_ntoa(addr); - if (tmp == NULL) - return NULL; - strcpy(buf, tmp); - return buf; -} -#endif /* not HAVE_ETHER_NTOA_R */ - -#ifndef HAVE_ETHER_ATON_R -struct ether_addr *ether_aton_r(const char *asc, struct ether_addr *addr) -{ - struct ether_addr *tmp; - tmp = ether_aton(asc); - if (tmp == NULL) - return NULL; - memcpy(addr, tmp, sizeof(struct ether_addr)); - return addr; -} -#endif /* not HAVE_ETHER_ATON_R */ diff --git a/compat/ether.h b/compat/ether.h deleted file mode 100644 index 4528517..0000000 --- a/compat/ether.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - ether.h - ethernet definitions for systems lacking those - - Copyright (C) 2008, 2010, 2011, 2012 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 -*/ - -#ifndef COMPAT__ETHER_H -#define COMPAT__ETHER_H 1 - -#include <sys/types.h> -#include <sys/socket.h> -#include <net/if.h> -#include <netinet/in.h> -#include <netinet/if_ether.h> -#ifdef HAVE_NETINET_ETHER_H -#include <netinet/ether.h> -#endif - -#ifndef HAVE_STRUCT_ETHER_ADDR -struct ether_addr { - uint8_t ether_addr_octet[6]; -}; -#endif /* not HAVE_STRUCT_ETHER_ADDR */ - -#ifndef HAVE_ETHER_NTOA_R -char *ether_ntoa_r(const struct ether_addr *addr, char *buf); -#endif /* not HAVE_ETHER_NTOA_R */ - -#ifndef HAVE_ETHER_ATON_R -struct ether_addr *ether_aton_r(const char *asc, struct ether_addr *addr); -#endif /* not HAVE_ETHER_ATON_R */ - -#ifdef HAVE_ETHER_NTOA -#if !HAVE_DECL_ETHER_NTOA -/* we define ether_ntoa() here because on some platforms the function is - undefined */ -extern char *ether_ntoa(const struct ether_addr *e); -#endif /* not HAVE_DECL_ETHER_NTOA */ -#endif /* HAVE_ETHER_NTOA */ - -#ifdef HAVE_ETHER_ATON -#if !HAVE_DECL_ETHER_ATON -/* we define ether_aton() here because on some platforms the function is - undefined */ -extern struct ether_addr *ether_aton(const char *s); -#endif /* not HAVE_DECL_ETHER_ATON */ -#endif /* HAVE_ETHER_ATON */ - -#endif /* not COMPAT__ETHER_H */ diff --git a/compat/nss_compat.h b/compat/nss_compat.h deleted file mode 100644 index bdc7d92..0000000 --- a/compat/nss_compat.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - nss_compat.h - compatibility definitions for NSS functions - - Copyright (C) 2010, 2012 Arthur de Jong - Copyright (C) 2010 Symas Corporation - - 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 -*/ - -#ifndef COMPAT__NSS_H -#define COMPAT__NSS_H 1 - -#ifdef HAVE_NSS_H -#include <nss.h> -#endif /* HAVE_NSS_H */ -#ifdef HAVE_NSS_COMMON_H -#include <nss_common.h> -#endif /* HAVE_NSS_COMMON_H */ -#ifdef HAVE_ALIASES_H -#include <aliases.h> -#endif -#include <sys/socket.h> -#include <sys/types.h> -#include <grp.h> -#include <netdb.h> -#include <pwd.h> -#ifdef HAVE_SHADOW_H -#include <shadow.h> -#endif /* HAVE_SHADOW_H */ -#ifdef HAVE_RPC_RPCENT_H -#include <rpc/rpcent.h> -#endif /* HAVE_RPC_RPCENT_H */ -#ifdef HAVE_NSS_DBDEFS_H -#include <nss_dbdefs.h> -#endif /* HAVE_NSS_DBDEFS_H */ -#ifdef HAVE_NSSWITCH_H -#include <nsswitch.h> -#endif /* HAVE_NSSWITCH_H */ -#ifdef HAVE_IRS_NSS_H -#include "irs-nss.h" -#endif /* HAVE_IRS_NSS_H */ - -#include "compat/ether.h" - -/* define missing status codes */ -#ifndef HAVE_ENUM_NSS_STATUS -#ifndef NSS_STATUS_SUCCESS -#define NSS_STATUS_SUCCESS NSS_SUCCESS -#endif -#ifndef NSS_STATUS_NOTFOUND -#define NSS_STATUS_NOTFOUND NSS_NOTFOUND -#endif -#ifndef NSS_STATUS_UNAVAIL -#define NSS_STATUS_UNAVAIL NSS_UNAVAIL -#endif -#ifndef NSS_STATUS_TRYAGAIN -#define NSS_STATUS_TRYAGAIN NSS_TRYAGAIN -#endif -#ifndef NSS_STATUS_RETURN -#define NSS_STATUS_RETURN NSS_NOTFOUND -#endif -#endif /* not HAVE_ENUM_NSS_STATUS */ - -/* define nss_status_t */ -#ifdef HAVE_ENUM_NSS_STATUS -typedef enum nss_status nss_status_t; -#endif - -/* Define an aliasent if it was not found on the system. */ -#ifndef HAVE_STRUCT_ALIASENT -struct aliasent { - char *alias_name; - size_t alias_members_len; - char **alias_members; - int alias_local; -}; -#endif /* not HAVE_STRUCT_ALIASENT */ - -/* Define an rpcent if it was not found on the system */ -#ifndef HAVE_STRUCT_RPCENT -struct rpcent { - char *r_name; - char **r_aliases; - int r_number; -}; -#endif /* not HAVE_STRUCT_RPCENT */ - -/* We define struct etherent here because it does not seem to - be defined in any publicly available header file exposed - by glibc. This is taken from include/netinet/ether.h - of the glibc (2.3.6) source tarball. */ -#ifndef HAVE_STRUCT_ETHERENT -struct etherent { - const char *e_name; - struct ether_addr e_addr; -}; -#endif /* not HAVE_STRUCT_ETHERENT */ - -/* We also define struct __netgrent because its definition is - not publically available. This is taken from inet/netgroup.h - of the glibc (2.3.6) source tarball. - The first part of the struct is the only part that is modified - by our getnetgrent() function, all the other fields are not - touched at all. */ -struct __netgrent { - enum { triple_val, group_val } type; - union { - struct { - const char *host; - const char *user; - const char *domain; - } triple; - const char *group; - } val; - /* the following stuff is used by some NSS services - but not by ours (it's not completely clear how these - are shared between different services) or is used - by our caller */ - char *data; - size_t data_size; - union { - char *cursor; - unsigned long int position; - } insertedname; /* added name to union to avoid warning */ - int first; - struct name_list *known_groups; - struct name_list *needed_groups; - void *nip; /* changed from `service_user *nip' */ -}; - -/* Define struct spwd if it was not found on the system. */ -#ifndef HAVE_STRUCT_SPWD -struct spwd { - char *sp_namp; - char *sp_pwdp; - long sp_lstchg; - long sp_min; - long sp_max; - long sp_warn; - long sp_inact; - long sp_expire; - unsigned long sp_flag; -}; -#endif /* not HAVE_STRUCT_SPWD */ - -#endif /* not COMPAT__NSS_H */ diff --git a/configure.ac b/configure.ac index 0f80fbf..70ae448 100644 --- a/configure.ac +++ b/configure.ac @@ -24,6 +24,7 @@ AC_COPYRIGHT( [Copyright (C) 2006 Luke Howard Copyright (C) 2006 West Consulting Copyright (C) 2006-2014 Arthur de Jong +Copyright (C) 2014 Luke Shumaker This configure script is derived from configure.ac which is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser @@ -32,11 +33,11 @@ version 2.1 of the License, or (at your option) any later version. See the configure.ac file for more details.]) # initialize and set version and bugreport address -AC_INIT([nss-pam-ldapd], - [0.9.4], - [nss-pam-ldapd-users@lists.arthurdejong.org],, - [http://arthurdejong.org/nss-pam-ldapd/]) -RELEASE_MONTH="Jun 2014" +AC_INIT([parabola-nslcd], + [0.9.4.1], + [dev@lists.parabolagnulinux.org],, + [https://projects.parabola.nu/packages/parabola-nslcd.git/]) +RELEASE_MONTH="Sep 2014" AC_SUBST(RELEASE_MONTH) AC_CONFIG_SRCDIR([nslcd.h]) AC_CONFIG_MACRO_DIR([m4]) @@ -131,42 +132,6 @@ done # add --disable-maintainer-mode option AM_MAINTAINER_MODE([enable]) -# check whether the NSS module should be built -AC_MSG_CHECKING([whether to build the NSS module]) -AC_ARG_ENABLE(nss, - AS_HELP_STRING([--disable-nss], - [build the NSS module @<:@enabled@:>@]),, - [enable_nss="yes"]) -AC_MSG_RESULT($enable_nss) -AM_CONDITIONAL([ENABLE_NSS], [test "x$enable_nss" = "xyes"]) - -# check whether the PAM module should be built -AC_MSG_CHECKING([whether to build the PAM module]) -AC_ARG_ENABLE(pam, - AS_HELP_STRING([--disable-pam], - [build the PAM module @<:@enabled@:>@]),, - [enable_pam="yes"]) -AC_MSG_RESULT($enable_pam) -AM_CONDITIONAL([ENABLE_PAM], [test "x$enable_pam" = "xyes"]) - -# check whether command-line utilities should be built -AC_MSG_CHECKING([whether to build the command-line utilities]) -AC_ARG_ENABLE(utils, - AS_HELP_STRING([--disable-utils], - [build the the command-line utilities @<:@auto@:>@]),, - [enable_utils="auto"]) -if test "x$enable_utils" = "xauto" -then - if test "x$PYTHON" != "x:" && test "$HAVE_PYMOD_ARGPARSE" = "yes" - then - enable_utils="yes" - else - enable_utils="no" - fi -fi -AC_MSG_RESULT($enable_utils) -AM_CONDITIONAL([ENABLE_UTILS], [test "x$enable_utils" = "xyes"]) - # check whether the nslcd daemon should be built AC_MSG_CHECKING([whether to build the nslcd daemon]) AC_ARG_ENABLE(nslcd, @@ -176,37 +141,6 @@ AC_ARG_ENABLE(nslcd, AC_MSG_RESULT($enable_nslcd) AM_CONDITIONAL([ENABLE_NSLCD], [test "x$enable_nslcd" = "xyes"]) -# check whether the Python version of the nslcd daemon should be built -AC_MSG_CHECKING([whether to build the pynslcd daemon]) -AC_ARG_ENABLE(pynslcd, - AS_HELP_STRING([--enable-pynslcd], - [build the pynslcd daemon @<:@disabled@:>@]),, - [enable_pynslcd="no"]) -AC_MSG_RESULT($enable_pynslcd) -AM_CONDITIONAL([ENABLE_PYNSLCD], [test "x$enable_pynslcd" = "xyes"]) -if test "x$enable_pynslcd" = "xyes" -then - AC_MSG_WARN([the pynslcd daemon is experimental]) -fi - -# check whether SASL support should be enabled -AC_MSG_CHECKING([whether to enable SASL support]) -AC_ARG_ENABLE(sasl, - AS_HELP_STRING([--disable-sasl], - [disable SASL support @<:@enabled@:>@]), - [enable_sasl=$enableval], - [enable_sasl="yes"]) -AC_MSG_RESULT($enable_sasl) - -# check whether Kerberos support should be enabled -AC_MSG_CHECKING([whether to enable Kerberos support]) -AC_ARG_ENABLE(kerberos, - AS_HELP_STRING([--disable-kerberos], - [disable Kerberos support @<:@enabled@:>@]), - [enable_kerberos=$enableval], - [enable_kerberos="yes"]) -AC_MSG_RESULT($enable_kerberos) - # check whether configfile options should be checked AC_MSG_CHECKING([whether to check configfile options]) AC_ARG_ENABLE(configfile_checking, @@ -229,88 +163,6 @@ AC_ARG_WITH(ldap-conf-file, AC_DEFINE_UNQUOTED(NSLCD_CONF_PATH, "$NSLCD_CONF_PATH", [Path to nslcd configuration file.]) AC_SUBST(NSLCD_CONF_PATH) -# check the name of the file with a bindpw value -AC_ARG_WITH(bindpw-file, - AS_HELP_STRING([--with-bindpw-file=PATH], - [path to file with value for bindpw @<:@disabled@:>@]), - [ NSLCD_BINDPW_PATH="$with_bindpw_file" - AC_DEFINE_UNQUOTED(NSLCD_BINDPW_PATH, "$NSLCD_BINDPW_PATH", [Path to bindpw value.]) - AC_SUBST(NSLCD_BINDPW_PATH) - ]) - -# where should the pidfile be written -AC_ARG_WITH(nslcd-pidfile, - AS_HELP_STRING([--with-nslcd-pidfile=PATH], - [path to pidfile @<:@/var/run/nslcd/nslcd.pid@:>@]), - [ NSLCD_PIDFILE="$with_nslcd_pidfile" ], - [ NSLCD_PIDFILE="/var/run/nslcd/nslcd.pid" ]) -AC_DEFINE_UNQUOTED(NSLCD_PIDFILE, "$NSLCD_PIDFILE", [The location of the pidfile used for checking availability of the nslcd.]) -AC_SUBST(NSLCD_PIDFILE) - -# where is the socket used for communication -AC_ARG_WITH(nslcd-socket, - AS_HELP_STRING([--with-nslcd-socket=PATH], - [path to socket @<:@/var/run/nslcd/socket@:>@]), - [ NSLCD_SOCKET="$with_nslcd_socket" ], - [ NSLCD_SOCKET="/var/run/nslcd/socket" ]) -AC_DEFINE_UNQUOTED(NSLCD_SOCKET, "$NSLCD_SOCKET", [The location of the socket used for communicating.]) -AC_SUBST(NSLCD_SOCKET) - -# the directory PAM librabries are expected to be placed into -AC_MSG_CHECKING([location for PAM module]) -AC_ARG_WITH(pam-seclib-dir, - AS_HELP_STRING([--with-pam-seclib-dir=PAM_SECLIB_DIR], - [path to PAM security library @<:@auto@:>@]), - [ PAM_SECLIB_DIR="$with_pam_seclib_dir" ], - [ PAM_SECLIB_DIR="auto" ]) -if test "x$PAM_SECLIB_DIR" = "xauto" -then - case "$target_os" in - solaris*) PAM_SECLIB_DIR="/usr/lib/security" ;; - freebsd*|dragonfly*) PAM_SECLIB_DIR="/usr/lib" ;; - *) PAM_SECLIB_DIR="/lib/security" ;; - esac -fi -AC_MSG_RESULT($PAM_SECLIB_DIR) -AC_DEFINE_UNQUOTED(PAM_SECLIB_DIR, "$PAM_SECLIB_DIR", [path to PAM security library]) -AC_SUBST(PAM_SECLIB_DIR) - -# the SONAME to use for the NSS module -AC_MSG_CHECKING([name of NSS module]) -AC_ARG_WITH(nss-ldap-soname, - AS_HELP_STRING([--with-nss-ldap-soname=SONAME], - [name of NSS module @<:@auto@:>@]), - [ NSS_LDAP_SONAME="$with_nss_ldap_soname" ], - [ NSS_LDAP_SONAME="auto" ]) -if test "x$NSS_LDAP_SONAME" = "xauto" -then - case "$target_os" in - solaris*) NSS_LDAP_SONAME="nss_ldap.so.1" ;; - freebsd*|dragonfly*) NSS_LDAP_SONAME="nss_ldap.so.1" ;; - *) NSS_LDAP_SONAME="libnss_ldap.so.2" ;; - esac -fi -AC_MSG_RESULT($NSS_LDAP_SONAME) -AC_DEFINE_UNQUOTED(NSS_LDAP_SONAME, "$NSS_LDAP_SONAME", [The SONAME of the NSS library module.]) -AC_SUBST(NSS_LDAP_SONAME) - -# the SONAME to use for the PAM module -AC_MSG_CHECKING([name of PAM module]) -AC_ARG_WITH(pam-ldap-soname, - AS_HELP_STRING([--with-pam-ldap-soname=SONAME], - [name of PAM module @<:@auto@:>@]), - [ PAM_LDAP_SONAME="$with_pam_ldap_soname" ], - [ PAM_LDAP_SONAME="auto" ]) -if test "x$PAM_LDAP_SONAME" = "xauto" -then - case "$target_os" in - solaris*) PAM_LDAP_SONAME="pam_ldap.so.1" ;; - *) PAM_LDAP_SONAME="pam_ldap.so" ;; - esac -fi -AC_MSG_RESULT($PAM_LDAP_SONAME) -AC_SUBST(PAM_LDAP_SONAME) - # check which modules should be build AC_ARG_WITH(nss-maps, AS_HELP_STRING([--with-nss-maps=MAP LIST], @@ -320,7 +172,7 @@ AC_ARG_WITH(nss-maps, # checks for availability of header files AC_CHECK_HEADERS([ctype.h strings.h pthread.h pthread_np.h fcntl.h limits.h]) AC_CHECK_HEADERS([nss.h nss_common.h grp.h shadow.h aliases.h netdb.h rpc/rpcent.h]) -AC_CHECK_HEADERS([netinet/ether.h arpa/inet.h netinet/in.h]) +AC_CHECK_HEADERS([arpa/inet.h netinet/in.h]) AC_CHECK_HEADERS([nsswitch.h nss_dbdefs.h]) AC_CHECK_HEADERS([sys/socket.h sys/un.h sys/ucred.h ucred.h sys/param.h sys/time.h]) AC_CHECK_HEADERS([getopt.h syslog.h stddef.h]) @@ -403,247 +255,6 @@ then [Define to 1 if setnetgrent() returns void.]) fi -# NSS module-specific tests -if test "x$enable_nss" = "xyes" -then - # save CFLAGS and LIBS to restore later - nss_save_CFLAGS="$CFLAGS" - nss_save_LIBS="$LIBS" - - # check for a definition of struct aliasent - AC_CHECK_TYPES(struct aliasent,,, [ - #ifdef HAVE_ALIASES_H - #include <aliases.h> - #endif]) - - # check for a definition of struct etherent - AC_CHECK_TYPES(struct etherent,,, [ - #include <sys/socket.h> - #include <net/if.h> - #include <netinet/in.h> - #include <netinet/if_ether.h> - #ifdef HAVE_NETINET_ETHER_H - #include <netinet/ether.h> - #endif]) - - # check if struct passwd has a pw_class member - AC_CHECK_MEMBERS([struct passwd.pw_class],,, [ - #include <pwd.h>]) - - # check for a definition of struct rpcent - AC_CHECK_TYPES(struct rpcent,,, [ - #include <netdb.h> - #ifdef HAVE_RPC_RPCENT_H - #include <rpc/rpcent.h> - #endif]) - - # check for a definition of struct spwd - AC_CHECK_TYPES(struct spwd,,, [ - #ifdef HAVE_NSS_H - #include <nss.h> - #endif - #ifdef HAVE_NSS_COMMON_H - #include <nss_common.h> - #endif - #include <pwd.h> - #ifdef HAVE_SHADOW_H - #include <shadow.h> - #endif]) - - # check for a definition of enum nss_status and nss_backend_t - AC_CHECK_TYPES([enum nss_status, nss_backend_t],,, [ - #ifdef HAVE_NSS_H - #include <nss.h> - #endif - #ifdef HAVE_NSS_COMMON_H - #include <nss_common.h> - #endif - #ifdef HAVE_NSS_DBDEFS_H - #include <nss_dbdefs.h> - #endif - #ifdef HAVE_NSSWITCH_H - #include <nsswitch.h> - #endif - #ifdef HAVE_IRS_NSS_H - #include "irs-nss.h" - #endif]) - - # check if struct nss_XbyY_args has a returnlen attribute - AC_CHECK_MEMBERS([struct nss_XbyY_args.returnlen],,, [[ - #ifdef HAVE_NSS_H - #include <nss.h> - #endif - #ifdef HAVE_NSS_COMMON_H - #include <nss_common.h> - #endif - #ifdef HAVE_NSS_DBDEFS_H - #include <nss_dbdefs.h> - #endif - #ifdef HAVE_NSSWITCH_H - #include <nsswitch.h> - #endif - #ifdef HAVE_IRS_NSS_H - #include "irs-nss.h" - #endif]]) - - # check which NSS flavour to build - AC_MSG_CHECKING([which NSS flavour to build]) - AC_ARG_WITH(nss-flavour, - AS_HELP_STRING([--with-nss-flavour=auto|glibc|solaris|freebsd], - [the libc flavour to build our NSS module for @<:@auto@:>@]),, - with_nss_flavour=auto) - if test "x$with_nss_flavour" = "xauto" - then - # do the guessing game - case "$target_os" in - solaris*) with_nss_flavour=solaris ;; - freebsd*|dragonfly*) with_nss_flavour=freebsd ;; - *) with_nss_flavour=glibc ;; - esac - fi - AC_MSG_RESULT($with_nss_flavour) - case "$with_nss_flavour" in - glibc) AC_DEFINE(NSS_FLAVOUR_GLIBC, 1, [Whether to use the Glibc NSS interface flavour.]) ;; - solaris) AC_DEFINE(NSS_FLAVOUR_SOLARIS, 1, [Whether to use the Solaris NSS interface flavour.]) ;; - freebsd) AC_DEFINE(NSS_FLAVOUR_FREEBSD, 1, [Whether to use the FreeBSD NSS interface flavour.]) ;; - esac - - # check which module source files to use - AC_MSG_CHECKING([which NSS maps to build]) - if test "x$with_nss_maps" = "xall" - then - case "$with_nss_flavour" in - glibc) with_nss_maps="aliases,ethers,group,hosts,netgroup,networks,passwd,protocols,rpc,services,shadow" ;; - solaris) with_nss_maps="ethers,group,hosts,netgroup,networks,passwd,protocols,rpc,services,shadow" ;; - freebsd) with_nss_maps="group,hosts,passwd" ;; - esac - fi - AC_MSG_RESULT($with_nss_maps) - NSS_MODULE_OBJS="$(echo "$with_nss_maps " | sed 's/,/ /g;s/ */.$(OBJEXT) /g')" - AC_SUBST(NSS_MODULE_OBJS) - - # find out how to link the library - nss_ldap_so_LINK="\$(CCLD) \$(AM_CFLAGS) \$(CFLAGS) \$(nss_ldap_so_LDFLAGS) \$(LDFLAGS) -o \$@" - case "$target_os" in - solaris*) - if test "x$GCC" = xyes - then - nss_ldap_so_LINK="/usr/ccs/bin/ld -Bdirect -z nodelete -Bdynamic -M \$(srcdir)/exports.solaris -G -o \$@" - else - nss_ldap_so_LDFLAGS="-Wl,-Bdirect -Wl,-z,nodelete -Wl,-Bdynamic -Wl,-M,\$(srcdir)/exports.solaris -Wl,-G" - fi - ;; - *) - nss_ldap_so_LDFLAGS="-shared -Wl,-h,\$(NSS_LDAP_SONAME) -Wl,--version-script,\$(srcdir)/exports.$with_nss_flavour" - ;; - esac - AC_SUBST(nss_ldap_so_LDFLAGS) - AC_SUBST(nss_ldap_so_LINK) - - # restore CFLAGS and LIBS - CFLAGS="$nss_save_CFLAGS" - LIBS="$nss_save_LIBS" -fi - -# PAM module-specific tests -if test "x$enable_pam" = "xyes" -then - # save CFLAGS and LIBS to restore later - pam_save_CFLAGS="$CFLAGS" - pam_save_LIBS="$LIBS" - - # check for headers - AC_CHECK_HEADERS(security/pam_appl.h) - AC_CHECK_HEADERS(security/pam_modules.h,,, [ - #ifdef HAVE_SECURITY_PAM_APPL_H - #include <security/pam_appl.h> - #endif - ]) - AC_CHECK_HEADERS(pam/pam_modules.h) - AC_CHECK_HEADERS(security/pam_ext.h) - AC_CHECK_HEADERS(security/pam_modutil.h) - - # at least one of security/pam_modules.h or pam/pam_modules.h is required - if test "x$ac_cv_header_security_pam_modules_h" != "xyes" && \ - test "x$ac_cv_header_pam_pam_modules_h" != "xyes" - then - AC_MSG_ERROR(PAM header files are missing) - fi - - # find pam library - AC_SEARCH_LIBS(pam_get_data, pam,, AC_MSG_ERROR(no PAM library available)) - - # replace some PAM functions if they are unavailable - AC_REPLACE_FUNCS(pam_get_authtok pam_prompt) - AC_CHECK_FUNCS(pam_modutil_getpwnam pam_syslog) - - # find out how to link the library - pam_ldap_so_LINK="\$(CCLD) \$(AM_CFLAGS) \$(CFLAGS) \$(pam_ldap_so_LDFLAGS) \$(LDFLAGS) -o \$@" - case "$target_os" in - solaris*) - if test "x$GCC" = xyes - then - pam_ldap_so_LINK="/usr/ccs/bin/ld -Bdirect -z nodelete -Bdynamic -M \$(srcdir)/pam_ldap.map -G -o \$@" - else - pam_ldap_so_LDFLAGS="-shared -Wl,-Bdirect -Wl,-z,nodelete -Wl,-Bdynamic -Wl,-M,\$(srcdir)/pam_ldap.map -Wl,-G" - fi - ;; - *) - pam_ldap_so_LDFLAGS="-shared -Wl,--version-script,\$(srcdir)/pam_ldap.map" - ;; - esac - AC_SUBST(pam_ldap_so_LDFLAGS) - AC_SUBST(pam_ldap_so_LINK) - - # check argument type of pam_get_item() - AC_CACHE_CHECK( - [argument type of pam_get_item], - nss_pam_ldapd_cv_pam_get_item_arg3_type, - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[ - #ifdef HAVE_SECURITY_PAM_APPL_H - #include <security/pam_appl.h> - #endif - #ifndef HAVE_PAM_PAM_MODULES_H - #include <security/pam_modules.h> - #ifdef HAVE_SECURITY_PAM_EXT_H - #include <security/pam_ext.h> - #endif - #else - #include <pam/pam_modules.h> - #endif - #ifdef HAVE_SECURITY_PAM_MODUTIL_H - #include <security/pam_modutil.h> - #endif - extern int pam_get_item(const pam_handle_t *pamh, int item_type, const void **item); - ]], [])], - [nss_pam_ldapd_cv_pam_get_item_arg3_type="const void **"], - [nss_pam_ldapd_cv_pam_get_item_arg3_type="void **"]) ]) - PAM_ITEM_CONST="" - if test "$nss_pam_ldapd_cv_pam_get_item_arg3_type" = "const void **" - then - PAM_ITEM_CONST="const" - fi - AC_DEFINE_UNQUOTED(PAM_ITEM_CONST, [$PAM_ITEM_CONST], - [Define to empty if pam_get_item() doesn't take `const` parameter.]) - - # restore CFLAGS and LIBS - CFLAGS="$pam_save_CFLAGS" - LIBS="$pam_save_LIBS" -fi - -# utils-specific tests -if test "x$enable_utils" = "xyes" -then - # check Python interpreter - AM_PATH_PYTHON(2.5,, AC_MSG_ERROR([Python is required])) - AX_PYTHON_MODULE(argparse) - if test "x$HAVE_PYMOD_ARGPARSE" != "xyes" - then - AC_MSG_WARN(Required Python modules missing) - fi -fi - # nslcd daemon-specific tests if test "x$enable_nslcd" = "xyes" then @@ -651,24 +262,6 @@ then nslcd_save_CFLAGS="$CFLAGS" nslcd_save_LIBS="$LIBS" - # check header files - AC_CHECK_HEADERS(lber.h) - AC_CHECK_HEADERS(ldap.h,, test "x$enable_nslcd" = "xyes" && AC_MSG_ERROR([could not locate <ldap.h>]), [ - #if HAVE_LBER_H - #include <lber.h> - #endif - ]) - AC_CHECK_HEADERS(ldap_ssl.h) - AC_CHECK_HEADERS(gssldap.h) - if test "x$enable_sasl" = "xyes" - then - AC_CHECK_HEADERS(sasl.h sasl/sasl.h) - AC_CHECK_HEADERS(gsssasl.h) - fi - if test "x$enable_kerberos" = "xyes" - then - AC_CHECK_HEADERS(gssapi/gssapi.h gssapi/gssapi_generic.h gssapi/gssapi_krb5.h gssapi.h krb5.h) - fi AC_CHECK_HEADERS(regex.h) # checks for availability of system libraries for nslcd @@ -676,6 +269,9 @@ then AC_SEARCH_LIBS(hstrerror, resolv) AC_SEARCH_LIBS(dlopen, dl) + # check fo availability of sytemd socket activation + AC_SEARCH_LIBS(sd_listen_fds, systemd) + # check for availability of functions AC_CHECK_FUNCS(initgroups setgroups execvp execvpe) AC_CHECK_FUNCS(getpeereid) @@ -689,9 +285,6 @@ then AC_REPLACE_FUNCS(getopt_long) AC_REPLACE_FUNCS(strndup) - # replace ether_aton_r() and ether_ntoa_r() if they are not found - AC_CHECK_FUNCS(ether_aton_r ether_ntoa_r,, [AC_LIBOBJ(ether)]) - # check to see if struct sockaddr_storage is defined AC_CHECK_TYPE(struct sockaddr_storage,, AC_DEFINE(sockaddr_storage, sockaddr_in, [Define to `sockaddr_in' if not defined elsewhere.]), [ @@ -715,238 +308,6 @@ then CFLAGS="$pthread_save_CFLAGS" LIBS="$pthread_save_LIBS" - # also use deprecated LDAP functions - AC_DEFINE(LDAP_DEPRECATED, 1, Define to activate deprecated features in OpenLDAP) - # for compatibility on Solaris - AC_DEFINE(LDAP_REFERRALS, 1, Define to get some functions on Solaris) - - # search for an LDAP library (only OpenLDAP is tested) - AC_ARG_WITH(ldap-lib, - AS_HELP_STRING([--with-ldap-lib=TYPE], - [select ldap library (auto|netscape5|netscape4|netscape3|umich|openldap) @<:@auto@:>@])) - if test -z "$with_ldap_lib" - then - with_ldap_lib=auto - fi - if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = umich -o $with_ldap_lib = openldap \) - then - AC_SEARCH_LIBS(ldap_search_ext, [ldap_r ldap], found_ldap_lib=yes,, ) - fi - if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape5 \) - then - AC_CHECK_LIB(ldap50, main, LIBS="-lldap50 -lssldap50 -lssl3 -lnss3 -lnspr4 -lprldap50 -lplc4 -lplds4 $LIBS" found_ldap_lib=yes,, -lpthread) - fi - if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape4 \) - then - AC_CHECK_LIB(ldapssl41, main, LIBS="-lldapssl41 -lplc3 -lplds3 -lnspr3 $LIBS" found_ldap_lib=yes,, -lpthread) - if test -z "$found_ldap_lib" - then - AC_CHECK_LIB(ldapssl40, main, LIBS="-lldapssl40 $LIBS" found_ldap_lib=yes,, -lpthread) - fi - if test -z "$found_ldap_lib" - then - AC_CHECK_LIB(ldap41, main, LIBS="-lldap41 $LIBS" found_ldap_lib=yes,, ) - fi - if test -z "$found_ldap_lib" - then - AC_CHECK_LIB(ldap40, main, LIBS="-lldap40 $LIBS" found_ldap_lib=yes,, ) - fi - fi - if test -z "$found_ldap_lib" -a \( $with_ldap_lib = auto -o $with_ldap_lib = netscape3 \) - then - AC_CHECK_LIB(ldapssl30, main, LIBS="-lldapssl30 $LIBS" found_ldap_lib=yes,, -lpthread) - fi - AC_CHECK_FUNCS(ldap_search_ext,, AC_MSG_ERROR([could not locate a valid LDAP library])) - - # see if we need a BER library - AC_SEARCH_LIBS(ber_bvfree, lber) - - # check for extra SASL libraries - if test "$enable_sasl" = "yes" - then - AC_CHECK_TYPE(sasl_interact_t, - AC_DEFINE(HAVE_SASL_INTERACT_T, 1, [Define to 1 if you have a `sasl_interact_t' definition.]),, [ - #ifdef HAVE_SASL_SASL_H - #include <sasl/sasl.h> - #elif defined(HAVE_SASL_H) - #include <sasl.h> - #endif]) - AC_SEARCH_LIBS(ldap_sasl_interactive_bind_s, sasl2) - AC_CHECK_FUNCS(ldap_sasl_interactive_bind_s) - fi - - # check for extra Kerberos libraries - if test "$enable_kerberos" = "yes" - then - AC_SEARCH_LIBS(gss_krb5_ccache_name, gssapi gssapi_krb5) - AC_CHECK_FUNCS(gss_krb5_ccache_name) - - # save CFLAGS and LIBS to restore later - krb5_save_CFLAGS="$CFLAGS" - krb5_save_LIBS="$LIBS" - - # find library that contains krb5_is_thread_safe - AC_SEARCH_LIBS(krb5_sendauth, [krb5 'krb5 -lcrypto -ldes -lasn1 -lroken']) - AC_CHECK_FUNCS(krb5_is_thread_safe) - - # see if krb5 is thread safe - if test "x$ac_cv_func_krb5_is_thread_safe" == "xyes" - then - AC_CACHE_CHECK( - [krb5 thread safety], - nslcd_cv_krb5_is_thread_safe, - [AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[ - #include <krb5.h> - ]], [[ - if (!krb5_is_thread_safe()) - return 1; - ]])], - [nslcd_cv_krb5_is_thread_safe=yes], - [nslcd_cv_krb5_is_thread_safe=no], - [nslcd_cv_krb5_is_thread_safe=unknown])]) - if test "x$nslcd_cv_krb5_is_thread_safe" == "xno" - then - AC_MSG_WARN([krb5 is NOT thread safe]) - fi - fi - - # restore CFLAGS and LIBS because we don't directly use krb5 - CFLAGS="$krb5_save_CFLAGS" - LIBS="$krb5_save_LIBS" - - fi - - # check for ldap function availability - AC_CHECK_FUNCS(ber_bvfree ber_free ber_set_option ber_get_enum) - AC_CHECK_FUNCS(ldap_initialize ldap_start_tls_s) - AC_CHECK_FUNCS(ldap_get_option ldap_set_option ldap_set_rebind_proc) - AC_CHECK_FUNCS(ldap_simple_bind_s ldap_sasl_bind ldap_sasl_bind_s ldap_unbind) - AC_CHECK_FUNCS(ldap_search_ext ldap_modify_ext_s ldap_extended_operation_s) - AC_CHECK_FUNCS(ldap_explode_dn ldap_explode_rdn) - AC_CHECK_FUNCS(ldap_domain2hostlist ldap_domain2dn) - AC_CHECK_FUNCS(ldap_result ldap_parse_result ldap_msgfree ldap_memfree) - AC_CHECK_FUNCS(ldap_get_dn ldap_first_attribute ldap_next_attribute) - AC_CHECK_FUNCS(ldap_get_values ldap_value_free) - AC_CHECK_FUNCS(ldap_get_values_len ldap_count_values_len ldap_value_free_len) - AC_CHECK_FUNCS(ldap_err2string ldap_abandon) - AC_CHECK_FUNCS(ldap_control_create ldap_create_control ldap_control_find) - AC_CHECK_FUNCS(ldap_controls_free ldap_control_free ldap_get_entry_controls) - AC_CHECK_FUNCS(ldap_parse_passwordpolicy_control ldap_passwordpolicy_err2txt) - AC_CHECK_FUNCS(ldap_create_deref_control ldap_create_deref_control_value) - AC_CHECK_FUNCS(ldap_parse_deref_control ldap_derefresponse_free) - - # replace ldap_create_page_control() and ldap_parse_page_control() - AC_CHECK_FUNCS(ldap_create_page_control ldap_parse_page_control,, [AC_LIBOBJ(pagectrl)]) - AC_CHECK_DECLS(ldap_extended_operation_s,,, [ - #if HAVE_LBER_H - #include <lber.h> - #endif - #include <ldap.h>]) - - # replace other ldap functions - AC_REPLACE_FUNCS(ldap_passwd_s) - AC_REPLACE_FUNCS(ldap_initialize) - AC_REPLACE_FUNCS(ldap_parse_passwordpolicy_control) - AC_REPLACE_FUNCS(ldap_passwordpolicy_err2txt) - - # check the number of arguments that ldap_set_rebind_proc() uses - AC_CACHE_CHECK( - [number of arguments to ldap_set_rebind_proc], - nss_ldapd_cv_ldap_set_rebind_proc_args, - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[ - #include <lber.h> - #include <ldap.h> - ]], [[ - ldap_set_rebind_proc(0, 0, 0); - ]])], - [nss_ldapd_cv_ldap_set_rebind_proc_args=3], - [nss_ldapd_cv_ldap_set_rebind_proc_args=2]) ]) - AC_DEFINE_UNQUOTED(LDAP_SET_REBIND_PROC_ARGS, $nss_ldapd_cv_ldap_set_rebind_proc_args, - [Define to the number of arguments to ldap_set_rebindproc.]) - - # check the return type of ldap_set_rebind_proc() - AC_CACHE_CHECK( - [return type of ldap_set_rebind_proc], - nss_ldapd_cv_ldap_set_rebind_proc_type, - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[ - #include <lber.h> - #include <ldap.h> - ]], [[ - #if LDAP_SET_REBIND_PROC_ARGS == 3 - return ldap_set_rebind_proc(0, 0, 0); - #else - return ldap_set_rebind_proc(0, 0); - #endif - ]])], - [nss_ldapd_cv_ldap_set_rebind_proc_type=int], - [nss_ldapd_cv_ldap_set_rebind_proc_type=void]) ]) - if test "x$nss_ldapd_cv_ldap_set_rebind_proc_type" = "xvoid" - then - AC_DEFINE(LDAP_SET_REBIND_PROC_RETURNS_VOID, 1, - [Define to 1 if ldap_set_rebind_proc() returns void.]) - fi - - # check for broken implementations of ldap_create_deref_control() - if test "x$ac_cv_func_ldap_create_deref_control" = "xyes" - then - # this bug cannot be determined on compile time so we run a - # small test program - AC_CACHE_CHECK( - [ldap_create_deref_control() implementation], - nslcd_cv_ldap_create_deref_control_working, - [AC_RUN_IFELSE( - [AC_LANG_PROGRAM([[ - #include <stdio.h> - #include <lber.h> - #include <ldap.h> - ]], [[ - int rc; - LDAP *ld; - LDAPControl *ctrls[2] = {NULL, NULL}; - struct LDAPDerefSpec ds[2]; - char *attrs[2] = {"uid", NULL}; - ld = ldap_init("localhost", LDAP_PORT); - if (ld == NULL) - { - fprintf(stderr, "ldap_init() failed\n"); - return 2; - } - ds[0].derefAttr = "member"; - ds[0].attributes = attrs; - ds[1].derefAttr = NULL; - rc = ldap_create_deref_control(ld, ds, 0, &ctrls[0]); - if (rc != LDAP_SUCCESS) - { - fprintf(stderr, "ldap_create_deref_control() failed: %s\n", - ldap_err2string(rc)); - return 2; - } - if (ldap_control_find(LDAP_CONTROL_X_DEREF, ctrls, NULL) != NULL) - return 0; - if (ldap_control_find(LDAP_CONTROL_PAGEDRESULTS, ctrls, NULL) != NULL) - { - fprintf(stderr, "ldap_create_deref_control() created LDAP_CONTROL_PAGEDRESULTS control\n"); - return 3; - } - fprintf(stderr, "ldap_create_deref_control() created unknown control\n"); - return 2; - ]])], - [nslcd_cv_ldap_create_deref_control_working=ok], - [if test "$?" -eq 3; then nslcd_cv_ldap_create_deref_control_working=broken - else nslcd_cv_ldap_create_deref_control_working=unknown; fi], - [nslcd_cv_ldap_create_deref_control_working=cross])]) - if test "x$nslcd_cv_ldap_create_deref_control_working" != "xok" - then - AC_MSG_NOTICE([using replacement ldap_create_deref_control()]) - AC_LIBOBJ(derefctrl) - AC_DEFINE(REPLACE_LDAP_CREATE_DEREF_CONTROL, 1, - [Define to 1 if ldap_create_deref_control() is broken.]) - fi - fi - # save nslcd LIBS and CFLAGS and restore originals nslcd_CFLAGS="$CFLAGS" nslcd_LIBS="$LIBS" @@ -956,47 +317,7 @@ then AC_SUBST(nslcd_LIBS) fi -# pynslcd-specific tests -if test "x$enable_pynslcd" = "xyes" -then - # check Python interpreter - AM_PATH_PYTHON(2.5,, AC_MSG_ERROR([Python is required])) - AX_PYTHON_MODULE(daemon) - AX_PYTHON_MODULE(fcntl) - AX_PYTHON_MODULE(fnmatch) - AX_PYTHON_MODULE(ldap) - AX_PYTHON_MODULE(sqlite3) - # required by ldap.controls.ppolicy: - AX_PYTHON_MODULE(pyasn1) - AX_PYTHON_MODULE(pyasn1_modules) - if test "x$HAVE_PYMOD_DAEMON" != "xyes" || \ - test "x$HAVE_PYMOD_FCNTL" != "xyes" || \ - test "x$HAVE_PYMOD_FNMATCH" != "xyes" || \ - test "x$HAVE_PYMOD_LDAP" != "xyes" || \ - test "x$HAVE_PYMOD_SQLITE3" != "xyes" || \ - test "x$HAVE_PYMOD_PYASN1" != "xyes" || \ - test "x$HAVE_PYMOD_PYASN1_MODULES" != "xyes" - then - AC_MSG_WARN(Required Python modules missing) - fi - # optional modules - AX_PYTHON_MODULE(setproctitle) -fi - -AM_CONDITIONAL([NSS_FLAVOUR_GLIBC], [test "x${with_nss_flavour}" = xglibc]) -AM_CONDITIONAL([NSS_FLAVOUR_SOLARIS], [test "x${with_nss_flavour}" = xsolaris]) -AM_CONDITIONAL([NSS_FLAVOUR_FREEBSD], [test "x${with_nss_flavour}" = xfreebsd]) - # generate files -AC_CONFIG_FILES([Makefile compat/Makefile common/Makefile nss/Makefile - pam/Makefile utils/Makefile nslcd/Makefile pynslcd/Makefile +AC_CONFIG_FILES([Makefile compat/Makefile common/Makefile nslcd/Makefile man/Makefile tests/Makefile]) -AC_CONFIG_FILES([pynslcd/constants.py], [[ -( - echo '' - echo '# The following is automatically generated from nslcd.h.' - echo '# See that file for details.' - echo '' - sed -n 's| */\*.*\*/ *||;s/^.define *\(NSLCD_[A-Z_]*\) */\1 = /p' "$srcdir"/nslcd.h -) >> pynslcd/constants.py]]) AC_OUTPUT diff --git a/nslcd/alias.c b/nslcd/alias.c deleted file mode 100644 index 7d6b978..0000000 --- a/nslcd/alias.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - alias.c - alias entry lookup routines - Parts of this file were part of the nss_ldap library (as ldap-alias.c) - which has been forked into the nss-pam-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006-2014 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 -*/ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "common.h" -#include "log.h" -#include "myldap.h" -#include "cfg.h" -#include "attmap.h" - -/* Vendor-specific attributes and object classes. - * (Mainly from Sun.) - * ( 1.3.6.1.4.1.42.2.27.1.2.5 NAME 'nisMailAlias' SUP top STRUCTURAL - * DESC 'NIS mail alias' - * MUST cn - * MAY rfc822MailMember ) - */ - -/* the search base for searches */ -const char *alias_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; - -/* the search scope for searches */ -int alias_scope = LDAP_SCOPE_DEFAULT; - -/* the basic search filter for searches */ -const char *alias_filter = "(objectClass=nisMailAlias)"; - -/* the attributes to request with searches */ -const char *attmap_alias_cn = "cn"; -const char *attmap_alias_rfc822MailMember = "rfc822MailMember"; - -/* the attribute list to request with searches */ -static const char *alias_attrs[3]; - -/* create a search filter for searching an alias by name, - return -1 on errors */ -static int mkfilter_alias_byname(const char *name, - char *buffer, size_t buflen) -{ - char safename[BUFLEN_SAFENAME]; - /* escape attribute */ - if (myldap_escape(name, safename, sizeof(safename))) - { - log_log(LOG_ERR, "mkfilter_alias_byname(): safename buffer too small"); - return -1; - } - /* build filter */ - return mysnprintf(buffer, buflen, "(&%s(%s=%s))", - alias_filter, attmap_alias_cn, safename); -} - -void alias_init(void) -{ - int i; - /* set up search bases */ - if (alias_bases[0] == NULL) - for (i = 0; i < NSS_LDAP_CONFIG_MAX_BASES; i++) - alias_bases[i] = nslcd_cfg->bases[i]; - /* set up scope */ - if (alias_scope == LDAP_SCOPE_DEFAULT) - alias_scope = nslcd_cfg->scope; - /* set up attribute list */ - alias_attrs[0] = attmap_alias_cn; - alias_attrs[1] = attmap_alias_rfc822MailMember; - alias_attrs[2] = NULL; -} - -static int write_alias(TFILE *fp, MYLDAP_ENTRY *entry, const char *reqalias) -{ - int32_t tmpint32, tmp2int32, tmp3int32; - const char **names, **members; - int i; - /* get the name of the alias */ - names = myldap_get_values(entry, attmap_alias_cn); - if ((names == NULL) || (names[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_alias_cn); - return 0; - } - /* get the members of the alias */ - members = myldap_get_values(entry, attmap_alias_rfc822MailMember); - /* for each name, write an entry */ - for (i = 0; names[i] != NULL; i++) - { - if ((reqalias == NULL) || (strcasecmp(reqalias, names[i]) == 0)) - { - WRITE_INT32(fp, NSLCD_RESULT_BEGIN); - WRITE_STRING(fp, names[i]); - WRITE_STRINGLIST(fp, members); - } - } - return 0; -} - -NSLCD_HANDLE( - alias, byname, NSLCD_ACTION_ALIAS_BYNAME, - char name[BUFLEN_NAME]; - char filter[BUFLEN_FILTER]; - READ_STRING(fp, name); - log_setrequest("alias=\"%s\"", name);, - mkfilter_alias_byname(name, filter, sizeof(filter)), - write_alias(fp, entry, name) -) - -NSLCD_HANDLE( - alias, all, NSLCD_ACTION_ALIAS_ALL, - const char *filter; - log_setrequest("alias(all)");, - (filter = alias_filter, 0), - write_alias(fp, entry, NULL) -) diff --git a/nslcd/attmap.c b/nslcd/attmap.c deleted file mode 100644 index d024a59..0000000 --- a/nslcd/attmap.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - attmap.c - attribute mapping values and functions - This file is part of the nss-pam-ldapd library. - - Copyright (C) 2007-2014 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 -*/ - -#include "config.h" - -#include <stdlib.h> -#include <strings.h> - -#include "attmap.h" -#include "log.h" -#include "common/expr.h" - -/* these are the bases that are defined per database */ -extern const char *alias_bases[]; -extern const char *ether_bases[]; -extern const char *group_bases[]; -extern const char *host_bases[]; -extern const char *netgroup_bases[]; -extern const char *network_bases[]; -extern const char *passwd_bases[]; -extern const char *protocol_bases[]; -extern const char *rpc_bases[]; -extern const char *service_bases[]; -extern const char *shadow_bases[]; - -const char **base_get_var(enum ldap_map_selector map) -{ - switch (map) - { - case LM_ALIASES: return alias_bases; - case LM_ETHERS: return ether_bases; - case LM_GROUP: return group_bases; - case LM_HOSTS: return host_bases; - case LM_NETGROUP: return netgroup_bases; - case LM_NETWORKS: return network_bases; - case LM_PASSWD: return passwd_bases; - case LM_PROTOCOLS: return protocol_bases; - case LM_RPC: return rpc_bases; - case LM_SERVICES: return service_bases; - case LM_SHADOW: return shadow_bases; - case LM_NFSIDMAP: - case LM_NONE: - default: return NULL; - } -} - -/* these are the scopes that are defined per database */ -extern int alias_scope; -extern int ether_scope; -extern int group_scope; -extern int host_scope; -extern int netgroup_scope; -extern int network_scope; -extern int passwd_scope; -extern int protocol_scope; -extern int rpc_scope; -extern int service_scope; -extern int shadow_scope; - -int *scope_get_var(enum ldap_map_selector map) -{ - switch (map) - { - case LM_ALIASES: return &alias_scope; - case LM_ETHERS: return ðer_scope; - case LM_GROUP: return &group_scope; - case LM_HOSTS: return &host_scope; - case LM_NETGROUP: return &netgroup_scope; - case LM_NETWORKS: return &network_scope; - case LM_PASSWD: return &passwd_scope; - case LM_PROTOCOLS: return &protocol_scope; - case LM_RPC: return &rpc_scope; - case LM_SERVICES: return &service_scope; - case LM_SHADOW: return &shadow_scope; - case LM_NFSIDMAP: - case LM_NONE: - default: return NULL; - } -} - -/* these are the filters that are defined per database */ -extern const char *alias_filter; -extern const char *ether_filter; -extern const char *group_filter; -extern const char *host_filter; -extern const char *netgroup_filter; -extern const char *network_filter; -extern const char *passwd_filter; -extern const char *protocol_filter; -extern const char *rpc_filter; -extern const char *service_filter; -extern const char *shadow_filter; - -const char **filter_get_var(enum ldap_map_selector map) -{ - switch (map) - { - case LM_ALIASES: return &alias_filter; - case LM_ETHERS: return ðer_filter; - case LM_GROUP: return &group_filter; - case LM_HOSTS: return &host_filter; - case LM_NETGROUP: return &netgroup_filter; - case LM_NETWORKS: return &network_filter; - case LM_PASSWD: return &passwd_filter; - case LM_PROTOCOLS: return &protocol_filter; - case LM_RPC: return &rpc_filter; - case LM_SERVICES: return &service_filter; - case LM_SHADOW: return &shadow_filter; - case LM_NFSIDMAP: - case LM_NONE: - default: return NULL; - } -} - -const char **attmap_get_var(enum ldap_map_selector map, const char *name) -{ - if (map == LM_ALIASES) - { - if (strcasecmp(name, "cn") == 0) return &attmap_alias_cn; - if (strcasecmp(name, "rfc822MailMember") == 0) return &attmap_alias_rfc822MailMember; - } - else if (map == LM_ETHERS) - { - if (strcasecmp(name, "cn") == 0) return &attmap_ether_cn; - if (strcasecmp(name, "macAddress") == 0) return &attmap_ether_macAddress; - } - else if (map == LM_GROUP) - { - if (strcasecmp(name, "cn") == 0) return &attmap_group_cn; - if (strcasecmp(name, "userPassword") == 0) return &attmap_group_userPassword; - if (strcasecmp(name, "gidNumber") == 0) return &attmap_group_gidNumber; - if (strcasecmp(name, "memberUid") == 0) return &attmap_group_memberUid; - if (strcasecmp(name, "member") == 0) return &attmap_group_member; - } - else if (map == LM_HOSTS) - { - if (strcasecmp(name, "cn") == 0) return &attmap_host_cn; - if (strcasecmp(name, "ipHostNumber") == 0) return &attmap_host_ipHostNumber; - } - else if (map == LM_NETGROUP) - { - if (strcasecmp(name, "cn") == 0) return &attmap_netgroup_cn; - if (strcasecmp(name, "nisNetgroupTriple") == 0) return &attmap_netgroup_nisNetgroupTriple; - if (strcasecmp(name, "memberNisNetgroup") == 0) return &attmap_netgroup_memberNisNetgroup; - } - else if (map == LM_NETWORKS) - { - if (strcasecmp(name, "cn") == 0) return &attmap_network_cn; - if (strcasecmp(name, "ipNetworkNumber") == 0) return &attmap_network_ipNetworkNumber; - } - else if (map == LM_PASSWD) - { - if (strcasecmp(name, "uid") == 0) return &attmap_passwd_uid; - if (strcasecmp(name, "userPassword") == 0) return &attmap_passwd_userPassword; - if (strcasecmp(name, "uidNumber") == 0) return &attmap_passwd_uidNumber; - if (strcasecmp(name, "gidNumber") == 0) return &attmap_passwd_gidNumber; - if (strcasecmp(name, "gecos") == 0) return &attmap_passwd_gecos; - if (strcasecmp(name, "homeDirectory") == 0) return &attmap_passwd_homeDirectory; - if (strcasecmp(name, "loginShell") == 0) return &attmap_passwd_loginShell; - } - else if (map == LM_PROTOCOLS) - { - if (strcasecmp(name, "cn") == 0) return &attmap_protocol_cn; - if (strcasecmp(name, "ipProtocolNumber") == 0) return &attmap_protocol_ipProtocolNumber; - } - else if (map == LM_RPC) - { - if (strcasecmp(name, "cn") == 0) return &attmap_rpc_cn; - if (strcasecmp(name, "oncRpcNumber") == 0) return &attmap_rpc_oncRpcNumber; - } - else if (map == LM_SERVICES) - { - if (strcasecmp(name, "cn") == 0) return &attmap_service_cn; - if (strcasecmp(name, "ipServicePort") == 0) return &attmap_service_ipServicePort; - if (strcasecmp(name, "ipServiceProtocol") == 0) return &attmap_service_ipServiceProtocol; - } - else if (map == LM_SHADOW) - { - if (strcasecmp(name, "uid") == 0) return &attmap_shadow_uid; - if (strcasecmp(name, "userPassword") == 0) return &attmap_shadow_userPassword; - if (strcasecmp(name, "shadowLastChange") == 0) return &attmap_shadow_shadowLastChange; - if (strcasecmp(name, "shadowMin") == 0) return &attmap_shadow_shadowMin; - if (strcasecmp(name, "shadowMax") == 0) return &attmap_shadow_shadowMax; - if (strcasecmp(name, "shadowWarning") == 0) return &attmap_shadow_shadowWarning; - if (strcasecmp(name, "shadowInactive") == 0) return &attmap_shadow_shadowInactive; - if (strcasecmp(name, "shadowExpire") == 0) return &attmap_shadow_shadowExpire; - if (strcasecmp(name, "shadowFlag") == 0) return &attmap_shadow_shadowFlag; - } - return NULL; -} - -const char *attmap_set_mapping(const char **var, const char *value) -{ - /* check if we are setting an expression */ - if (value[0] == '"') - { - /* these attributes may contain an expression - (note that this needs to match the functionality in the specific - lookup module) */ - if ((var != &attmap_group_userPassword) && - (var != &attmap_group_member) && - (var != &attmap_passwd_userPassword) && - (var != &attmap_passwd_gidNumber) && - (var != &attmap_passwd_gecos) && - (var != &attmap_passwd_homeDirectory) && - (var != &attmap_passwd_loginShell) && - (var != &attmap_shadow_userPassword) && - (var != &attmap_shadow_shadowLastChange) && - (var != &attmap_shadow_shadowMin) && - (var != &attmap_shadow_shadowMax) && - (var != &attmap_shadow_shadowWarning) && - (var != &attmap_shadow_shadowInactive) && - (var != &attmap_shadow_shadowExpire) && - (var != &attmap_shadow_shadowFlag)) - return NULL; - /* the member attribute may only be set to an empty string */ - if ((var == &attmap_group_member) && (strcmp(value, "\"\"") != 0)) - return NULL; - } - /* check if the value will be changed */ - if ((*var == NULL) || (strcmp(*var, value) != 0)) - *var = strdup(value); - return *var; -} - -static const char *entry_expand(const char *name, void *expander_attr) -{ - MYLDAP_ENTRY *entry = (MYLDAP_ENTRY *)expander_attr; - const char **values; - if (strcasecmp(name, "dn") == 0) - return myldap_get_dn(entry); - values = myldap_get_values(entry, name); - if (values == NULL) - return ""; - /* TODO: handle userPassword attribute specially */ - if ((values[0] != NULL) && (values[1] != NULL)) - { - log_log(LOG_WARNING, "%s: %s: multiple values", - myldap_get_dn(entry), name); - } - return values[0]; -} - -const char *attmap_get_value(MYLDAP_ENTRY *entry, const char *attr, - char *buffer, size_t buflen) -{ - const char **values; - /* check and clear buffer */ - if ((buffer == NULL) || (buflen <= 0)) - return NULL; - buffer[0] = '\0'; - /* for simple values just return the attribute */ - if (attr[0] != '"') - { - values = myldap_get_values(entry, attr); - if ((values == NULL) || (values[0] == NULL)) - return NULL; - if (strlen(values[0]) >= buflen) - { - log_log(LOG_ERR, "attmap_get_value(): buffer too small (%d required)", - strlen(values[0])); - return NULL; - } - strncpy(buffer, values[0], buflen); - buffer[buflen - 1] = '\0'; - return buffer; - /* TODO: maybe warn when multiple values are found */ - } - /* we have an expression, try to parse */ - if ((attr[strlen(attr) - 1] != '"') || - (expr_parse(attr + 1, buffer, buflen, entry_expand, (void *)entry) == NULL)) - { - log_log(LOG_ERR, "attribute mapping %s is invalid", attr); - buffer[0] = '\0'; - return NULL; - } - /* strip trailing " */ - if (buffer[strlen(buffer) - 1] == '"') - buffer[strlen(buffer) - 1] = '\0'; - return buffer; -} - -SET *attmap_add_attributes(SET *set, const char *attr) -{ - if (attr[0] != '\"') - set_add(set, attr); - else - expr_vars(attr, set); - return set; -} diff --git a/nslcd/attmap.h b/nslcd/attmap.h deleted file mode 100644 index 81859ab..0000000 --- a/nslcd/attmap.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - attmap.h - attribute mapping variables - This file is part of the nss-pam-ldapd library. - - Copyright (C) 2007, 2008, 2009, 2010, 2012 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 -*/ - -#ifndef NSLCD__ATTMAP_H -#define NSLCD__ATTMAP_H 1 - -#include "cfg.h" -#include "myldap.h" -#include "common/set.h" - -/* these are the attribute names per database */ -extern const char *attmap_alias_cn; -extern const char *attmap_alias_rfc822MailMember; -extern const char *attmap_ether_cn; -extern const char *attmap_ether_macAddress; -extern const char *attmap_group_cn; -extern const char *attmap_group_userPassword; -extern const char *attmap_group_gidNumber; -extern const char *attmap_group_memberUid; -extern const char *attmap_group_member; -extern const char *attmap_host_cn; -extern const char *attmap_host_ipHostNumber; -extern const char *attmap_netgroup_cn; -extern const char *attmap_netgroup_nisNetgroupTriple; -extern const char *attmap_netgroup_memberNisNetgroup; -extern const char *attmap_network_cn; -extern const char *attmap_network_ipNetworkNumber; -extern const char *attmap_passwd_uid; -extern const char *attmap_passwd_userPassword; -extern const char *attmap_passwd_uidNumber; -extern const char *attmap_passwd_gidNumber; -extern const char *attmap_passwd_gecos; -extern const char *attmap_passwd_homeDirectory; -extern const char *attmap_passwd_loginShell; -extern const char *attmap_protocol_cn; -extern const char *attmap_protocol_ipProtocolNumber; -extern const char *attmap_rpc_cn; -extern const char *attmap_rpc_oncRpcNumber; -extern const char *attmap_service_cn; -extern const char *attmap_service_ipServicePort; -extern const char *attmap_service_ipServiceProtocol; -extern const char *attmap_shadow_uid; -extern const char *attmap_shadow_userPassword; -extern const char *attmap_shadow_shadowLastChange; -extern const char *attmap_shadow_shadowMin; -extern const char *attmap_shadow_shadowMax; -extern const char *attmap_shadow_shadowWarning; -extern const char *attmap_shadow_shadowInactive; -extern const char *attmap_shadow_shadowExpire; -extern const char *attmap_shadow_shadowFlag; - -/* return a reference to the map specific base variable */ -const char **base_get_var(enum ldap_map_selector map); - -/* return a reference to the map specific scope variable */ -int *scope_get_var(enum ldap_map_selector map); - -/* return a reference to the map specific filter variable */ -const char **filter_get_var(enum ldap_map_selector map); - -/* return a reference to the attribute mapping variable for the specified name - the name is the name after the attmap_... variables above with the - underscode replaced by a dot (e.g passwd.homeDirectory) */ -const char **attmap_get_var(enum ldap_map_selector map, const char *name); - -/* Set the attribute mapping of the variable to the value specified. - Returns the new value on success. */ -MUST_USE const char *attmap_set_mapping(const char **var, const char *value); - -/* Return a value for the attribute, handling the case where attr - is an expression. On error (e.g. problem parsing expression, attribute - value not found) it returns NULL and the buffer is made empty. */ -const char *attmap_get_value(MYLDAP_ENTRY *entry, const char *attr, - char *buffer, size_t buflen); - -/* Add the attributes from attr to the set. The attr argumenent - can either be an attribute or an attribute expression. */ -SET *attmap_add_attributes(SET *set, const char *attr); - -#endif /* not NSLCD__ATTMAP_H */ diff --git a/nslcd/cfg.c b/nslcd/cfg.c index 1d99962..7e172df 100644 --- a/nslcd/cfg.c +++ b/nslcd/cfg.c @@ -1864,16 +1864,4 @@ void cfg_init(const char *fname) } /* dump configuration */ cfg_dump(); - /* initialise all database modules */ - alias_init(); - ether_init(); - group_init(); - host_init(); - netgroup_init(); - network_init(); - passwd_init(); - protocol_init(); - rpc_init(); - service_init(); - shadow_init(); } diff --git a/nslcd/common.h b/nslcd/common.h index 5ca06c1..ce87b09 100644 --- a/nslcd/common.h +++ b/nslcd/common.h @@ -166,7 +166,6 @@ void invalidator_do(enum ldap_map_selector map); #define BUFLEN_PASSWORDHASH 256 /* passwords hashes */ #define BUFLEN_DN 512 /* distinguished names */ #define BUFLEN_SAFEDN 600 /* escapedd dn */ -#define BUFLEN_FILTER 4096 /* search filters */ #define BUFLEN_HOSTNAME (HOST_NAME_MAX + 1) /* host names (+ escaped) */ #define BUFLEN_MESSAGE 1024 /* message strings */ @@ -257,49 +256,35 @@ int nslcd_pam_pwmod(TFILE *fp, MYLDAP_SESSION *session, uid_t calleruid); int nslcd_usermod(TFILE *fp, MYLDAP_SESSION *session, uid_t calleruid); /* macros for generating service handling code */ -#define NSLCD_HANDLE(db, fn, action, readfn, mkfilter, writefn) \ +#define NSLCD_HANDLE(db, fn, action, fndecls, fnread, fncheck, fnsearch, fnwrite) \ int nslcd_##db##_##fn(TFILE *fp, MYLDAP_SESSION *session) \ - NSLCD_HANDLE_BODY(db, fn, action, readfn, mkfilter, writefn) -#define NSLCD_HANDLE_UID(db, fn, action, readfn, mkfilter, writefn) \ + NSLCD_HANDLE_BODY(db, fn, action, fndecls, fnread, fncheck, fnsearch, fnwrite) +#define NSLCD_HANDLE_UID(db, fn, action, fndecls, fnread, fncheck, fnsearch, fnwrite) \ int nslcd_##db##_##fn(TFILE *fp, MYLDAP_SESSION *session, uid_t calleruid) \ - NSLCD_HANDLE_BODY(db, fn, action, readfn, mkfilter, writefn) -#define NSLCD_HANDLE_BODY(db, fn, action, readfn, mkfilter, writefn) \ + NSLCD_HANDLE_BODY(db, fn, action, fndecls, fnread, fncheck, fnsearch, fnwrite) +#define NSLCD_HANDLE_BODY(db, fn, action, fndecls, fnread, fncheck, fnsearch, fnwrite) \ { \ /* define common variables */ \ int32_t tmpint32; \ - MYLDAP_SEARCH *search; \ - MYLDAP_ENTRY *entry; \ - const char *base; \ - int rc, i; \ + void *entry = NULL; \ + int rc = 1; \ + fndecls \ + MYLDAP_ENTRY *search(int *rcp) { fnsearch } \ /* read request parameters */ \ - readfn; \ + fnread \ + /* validate request parameters */ \ + fncheck \ /* write the response header */ \ WRITE_INT32(fp, NSLCD_VERSION); \ WRITE_INT32(fp, action); \ - /* prepare the search filter */ \ - if (mkfilter) \ + /* go over results */ \ + while ((entry = search(&rc)) != NULL) \ { \ - log_log(LOG_ERR, "nslcd_" __STRING(db) "_" __STRING(fn) \ - "(): filter buffer too small"); \ - return -1; \ - } \ - /* perform a search for each search base */ \ - for (i = 0; (base = db##_bases[i]) != NULL; i++) \ - { \ - /* do the LDAP search */ \ - search = myldap_search(session, base, db##_scope, filter, \ - db##_attrs, NULL); \ - if (search == NULL) \ + if ( ({ fnwrite }) ) \ return -1; \ - /* go over results */ \ - while ((entry = myldap_get_entry(search, &rc)) != NULL) \ - { \ - if (writefn) \ - return -1; \ - } \ } \ /* write the final result code */ \ - if (rc == LDAP_SUCCESS) \ + if (rc == 0) \ { \ WRITE_INT32(fp, NSLCD_RESULT_END); \ } \ diff --git a/nslcd/config.c b/nslcd/db_config.c index 75c9ec1..75c9ec1 100644 --- a/nslcd/config.c +++ b/nslcd/db_config.c diff --git a/nslcd/pam.c b/nslcd/db_pam.c index 0eff71b..0eff71b 100644 --- a/nslcd/pam.c +++ b/nslcd/db_pam.c diff --git a/nslcd/db_passwd.c b/nslcd/db_passwd.c new file mode 100644 index 0000000..12cdea8 --- /dev/null +++ b/nslcd/db_passwd.c @@ -0,0 +1,163 @@ +/* + passwd.c - password entry lookup routines + Parts of this file were part of the nss_ldap library (as ldap-pwd.c) + which has been forked into the nss-pam-ldapd library. + + Copyright (C) 1997-2005 Luke Howard + Copyright (C) 2006 West Consulting + Copyright (C) 2006-2014 Arthur de Jong + Copyright (C) 2014 Luke Shumaker + + 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 +*/ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <unistd.h> +#include <string.h> +#include <pthread.h> + +#include "common.h" +#include "log.h" +#include "myldap.h" +#include "cfg.h" +#include "attmap.h" +#include "common/dict.h" +#include "compat/strndup.h" + +#ifndef NSS_FLAVOUR_GLIBC +/* only check nsswitch.conf for glibc */ +#define check_nsswitch_reload() +#define shadow_uses_ldap() (1) +#endif /* NSS_FLAVOUR_GLIBC */ + +/* Note that the resulting password value should be one of: + <empty> - no password set, allow login without password + * - often used to prevent logins + x - "valid" encrypted password that does not match any valid password + often used to indicate that the password is defined elsewhere + other - encrypted password, usually in crypt(3) format */ + +static int write_passwd(TFILE *fp, struct passwd *entry, uid_t calleruid) +{ + const char *passwd; + /* if we are using shadow maps and this entry looks like it would return + shadow information, make the passwd entry indicate it */ + if (nsswitch_shadow_uses_ldap()) + { + passwd = "x"; + } + else + { + passwd = entry->pw_passwd; + if ((passwd == NULL) || (calleruid != 0)) + passwd = "!"; + } + if (entry->pw_uid >= nslcd_cfg->nss_min_uid) + { + WRITE_INT32(fp, NSLCD_RESULT_BEGIN); + WRITE_STRING(fp, entry->pw_name ); + WRITE_STRING(fp, passwd ); + WRITE_INT32( fp, entry->pw_uid ); + WRITE_INT32( fp, entry->pw_gid ); + WRITE_STRING(fp, entry->pw_gecos); + WRITE_STRING(fp, entry->pw_dir ); + WRITE_STRING(fp, entry->pw_shell); + } + return 0; +} + +NSLCD_HANDLE_UID( + passwd, byname, NSLCD_ACTION_PASSWD_BYNAME + ,/* decls */ + char name[BUFLEN_NAME]; + ,/* read */ + READ_STRING(fp, name); + log_setrequest("passwd=\"%s\"", name); + ,/* check */ + if (!isvalidname(name)) + { + log_log(LOG_WARNING, "request denied by validnames option"); + return -1; + } + nsswitch_check_reload();, + /* search */ + static size_t i = 0; + for (; i < session->cnt; i++) + { + if (strcmp(name, session->users[i].pw_name)==0) { + *rcp = 0; + i = session->cnt; + return &(session->users[i]); + } + } + return NULL; + /* write */ + write_passwd(fp, entry, calleruid) +) + +NSLCD_HANDLE_UID( + passwd, byuid, NSLCD_ACTION_PASSWD_BYUID + ,/* decls */ + uid_t uid; + ,/* read */ + READ_INT32(fp, uid); + log_setrequest("passwd=%lu", (unsigned long int)uid); + ,/* check */ + if (uid < nslcd_cfg->nss_min_uid) + { + /* return an empty result */ + WRITE_INT32(fp, NSLCD_VERSION); + WRITE_INT32(fp, NSLCD_ACTION_PASSWD_BYUID); + WRITE_INT32(fp, NSLCD_RESULT_END); + return 0; + } + nsswitch_check_reload(); + ,/* search */ + static size_t i = 0; + for (; i < session->cnt; i++) + { + if (uid == session->users[i].pw_uid) { + *rcp = 0; + i = session->cnt; + return &(session->users[i]); + } + } + return NULL; + ,/* write */ + write_passwd(fp, entry, calleruid) +) + +NSLCD_HANDLE_UID( + passwd, all, NSLCD_ACTION_PASSWD_ALL + ,/* decls */ + ,/* read */ + log_setrequest("passwd(all)"); + ,/* check */ + nsswitch_check_reload(); + ,/* search */ + static size_t i = 0; + for (; i < session->cnt; i++) + { + return &(session->users[i]); + } + return NULL; + ,/* write */ + write_passwd(fp, entry, calleruid); +) diff --git a/nslcd/shadow.c b/nslcd/db_shadow.c index 85ca4ef..7e24ea4 100644 --- a/nslcd/shadow.c +++ b/nslcd/db_shadow.c @@ -36,85 +36,6 @@ #include "cfg.h" #include "attmap.h" -/* ( nisSchema.2.1 NAME 'shadowAccount' SUP top AUXILIARY - * DESC 'Additional attributes for shadow passwords' - * MUST uid - * MAY ( userPassword $ shadowLastChange $ shadowMin - * shadowMax $ shadowWarning $ shadowInactive $ - * shadowExpire $ shadowFlag $ description ) ) - */ - -/* the search base for searches */ -const char *shadow_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; - -/* the search scope for searches */ -int shadow_scope = LDAP_SCOPE_DEFAULT; - -/* the basic search filter for searches */ -const char *shadow_filter = "(objectClass=shadowAccount)"; - -/* the attributes to request with searches */ -const char *attmap_shadow_uid = "uid"; -const char *attmap_shadow_userPassword = "\"*\""; -const char *attmap_shadow_shadowLastChange = "\"${shadowLastChange:--1}\""; -const char *attmap_shadow_shadowMin = "\"${shadowMin:--1}\""; -const char *attmap_shadow_shadowMax = "\"${shadowMax:--1}\""; -const char *attmap_shadow_shadowWarning = "\"${shadowWarning:--1}\""; -const char *attmap_shadow_shadowInactive = "\"${shadowInactive:--1}\""; -const char *attmap_shadow_shadowExpire = "\"${shadowExpire:--1}\""; -const char *attmap_shadow_shadowFlag = "\"${shadowFlag:-0}\""; - -/* default values for attributes */ -static const char *default_shadow_userPassword = "*"; /* unmatchable */ - -/* the attribute list to request with searches */ -static const char **shadow_attrs = NULL; - -static int mkfilter_shadow_byname(const char *name, char *buffer, size_t buflen) -{ - char safename[BUFLEN_SAFENAME]; - /* escape attribute */ - if (myldap_escape(name, safename, sizeof(safename))) - { - log_log(LOG_ERR, "mkfilter_shadow_byname(): safename buffer too small"); - return -1; - } - /* build filter */ - return mysnprintf(buffer, buflen, "(&%s(%s=%s))", - shadow_filter, attmap_shadow_uid, safename); -} - -void shadow_init(void) -{ - int i; - SET *set; - /* set up search bases */ - if (shadow_bases[0] == NULL) - for (i = 0; i < NSS_LDAP_CONFIG_MAX_BASES; i++) - shadow_bases[i] = nslcd_cfg->bases[i]; - /* set up scope */ - if (shadow_scope == LDAP_SCOPE_DEFAULT) - shadow_scope = nslcd_cfg->scope; - /* set up attribute list */ - set = set_new(); - attmap_add_attributes(set, attmap_shadow_uid); - attmap_add_attributes(set, attmap_shadow_userPassword); - attmap_add_attributes(set, attmap_shadow_shadowLastChange); - attmap_add_attributes(set, attmap_shadow_shadowMax); - attmap_add_attributes(set, attmap_shadow_shadowMin); - attmap_add_attributes(set, attmap_shadow_shadowWarning); - attmap_add_attributes(set, attmap_shadow_shadowInactive); - attmap_add_attributes(set, attmap_shadow_shadowExpire); - attmap_add_attributes(set, attmap_shadow_shadowFlag); - shadow_attrs = set_tolist(set); - if (shadow_attrs == NULL) - { - log_log(LOG_CRIT, "malloc() failed to allocate memory"); - exit(EXIT_FAILURE); - } - set_free(set); -} - static long to_date(const char *dn, const char *date, const char *attr) { char buffer[32]; diff --git a/nslcd/ether.c b/nslcd/ether.c deleted file mode 100644 index ff61dd2..0000000 --- a/nslcd/ether.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - ether.c - ethernet address entry lookup routines - Parts of this file were part of the nss_ldap library (as ldap-ethers.c) - which has been forked into the nss-pam-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006-2014 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 -*/ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#ifdef HAVE_STDINT_H -#include <stdint.h> -#endif /* HAVE_STDINT_H */ - -#include "common.h" -#include "log.h" -#include "myldap.h" -#include "cfg.h" -#include "attmap.h" -#include "compat/ether.h" - -/* ( nisSchema.2.11 NAME 'ieee802Device' SUP top AUXILIARY - * DESC 'A device with a MAC address; device SHOULD be - * used as a structural class' - * MAY macAddress ) - */ - -/* the search base for searches */ -const char *ether_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; - -/* the search scope for searches */ -int ether_scope = LDAP_SCOPE_DEFAULT; - -/* the basic search filter for searches */ -const char *ether_filter = "(objectClass=ieee802Device)"; - -/* the attributes to request with searches */ -const char *attmap_ether_cn = "cn"; -const char *attmap_ether_macAddress = "macAddress"; - -/* the attribute list to request with searches */ -static const char *ether_attrs[3]; - -/* create a search filter for searching an ethernet address - by name, return -1 on errors */ -static int mkfilter_ether_byname(const char *name, - char *buffer, size_t buflen) -{ - char safename[BUFLEN_HOSTNAME]; - /* escape attribute */ - if (myldap_escape(name, safename, sizeof(safename))) - { - log_log(LOG_ERR, "mkfilter_ether_byname(): safename buffer too small"); - return -1; - } - /* build filter */ - return mysnprintf(buffer, buflen, "(&%s(%s=%s))", - ether_filter, attmap_ether_cn, safename); -} - -static int mkfilter_ether_byether(const char *addrstr, - char *buffer, size_t buflen) -{ - /* Note: this only works if the address in LDAP has the preferred minimal - representation (e.g. 1:0:e:...) and not with extra leading zeros - (e.g. 01:00:0e:...) */ - /* there should be no characters that need escaping */ - return mysnprintf(buffer, buflen, "(&%s(%s=%s))", - ether_filter, attmap_ether_macAddress, addrstr); -} - -void ether_init(void) -{ - int i; - /* set up search bases */ - if (ether_bases[0] == NULL) - for (i = 0; i < NSS_LDAP_CONFIG_MAX_BASES; i++) - ether_bases[i] = nslcd_cfg->bases[i]; - /* set up scope */ - if (ether_scope == LDAP_SCOPE_DEFAULT) - ether_scope = nslcd_cfg->scope; - /* set up attribute list */ - ether_attrs[0] = attmap_ether_cn; - ether_attrs[1] = attmap_ether_macAddress; - ether_attrs[2] = NULL; -} - -/* TODO: check for errors in aton() */ -#define WRITE_ETHER(fp, addr) \ - ether_aton_r(addr, &tmpaddr); \ - WRITE(fp, &tmpaddr, sizeof(uint8_t[6])); - -static int write_ether(TFILE *fp, MYLDAP_ENTRY *entry, - const char *reqname, const char *reqether) -{ - int32_t tmpint32; - struct ether_addr tmpaddr; - const char *tmparr[2]; - const char **names, **ethers; - int i, j; - /* get the name of the ether entry */ - names = myldap_get_values(entry, attmap_ether_cn); - if ((names == NULL) || (names[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_ether_cn); - return 0; - } - /* get the addresses */ - if (reqether != NULL) - { - ethers = tmparr; - ethers[0] = reqether; - ethers[1] = NULL; - } - else - { - ethers = myldap_get_values(entry, attmap_ether_macAddress); - if ((ethers == NULL) || (ethers[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_ether_macAddress); - return 0; - } - /* TODO: move parsing of addresses up here */ - } - /* write entries for all names and addresses */ - for (i = 0; names[i] != NULL; i++) - if ((reqname == NULL) || (strcasecmp(reqname, names[i]) == 0)) - for (j = 0; ethers[j] != NULL; j++) - { - WRITE_INT32(fp, NSLCD_RESULT_BEGIN); - WRITE_STRING(fp, names[i]); - WRITE_ETHER(fp, ethers[j]); - } - return 0; -} - -NSLCD_HANDLE( - ether, byname, NSLCD_ACTION_ETHER_BYNAME, - char name[BUFLEN_HOSTNAME]; - char filter[BUFLEN_FILTER]; - READ_STRING(fp, name); - log_setrequest("ether=\"%s\"", name);, - mkfilter_ether_byname(name, filter, sizeof(filter)), - write_ether(fp, entry, name, NULL) -) - -NSLCD_HANDLE( - ether, byether, NSLCD_ACTION_ETHER_BYETHER, - struct ether_addr addr; - char addrstr[20]; - char filter[BUFLEN_FILTER]; - READ(fp, &addr, sizeof(uint8_t[6])); - if (ether_ntoa_r(&addr, addrstr) == NULL) - return -1; - log_setrequest("ether=%s", addrstr);, - mkfilter_ether_byether(addrstr, filter, sizeof(filter)), - write_ether(fp, entry, NULL, addrstr) -) - -NSLCD_HANDLE( - ether, all, NSLCD_ACTION_ETHER_ALL, - const char *filter; - log_setrequest("ether(all)");, - (filter = ether_filter, 0), - write_ether(fp, entry, NULL, NULL) -) diff --git a/nslcd/group.c b/nslcd/group.c deleted file mode 100644 index d7dfe42..0000000 --- a/nslcd/group.c +++ /dev/null @@ -1,599 +0,0 @@ -/* - group.c - group entry lookup routines - Parts of this file were part of the nss_ldap library (as ldap-grp.c) - which has been forked into the nss-pam-ldapd library. - - Copyright (C) 1997-2006 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006-2014 Arthur de Jong - Copyright (C) 2013 Steve Hill - - 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 -*/ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -/* for gid_t */ -#include <grp.h> - -#include "common/set.h" -#include "common.h" -#include "log.h" -#include "myldap.h" -#include "cfg.h" -#include "attmap.h" -#include "compat/strndup.h" - -/* ( nisSchema.2.2 NAME 'posixGroup' SUP top STRUCTURAL - * DESC 'Abstraction of a group of accounts' - * MUST ( cn $ gidNumber ) - * MAY ( userPassword $ memberUid $ description ) ) - * - * apart from the above a member attribute is also supported that - * may contains a DN of a user - * - * nested groups (groups that are member of a group) are currently - * not supported - */ - -/* the search base for searches */ -const char *group_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; - -/* the search scope for searches */ -int group_scope = LDAP_SCOPE_DEFAULT; - -/* the basic search filter for searches */ -const char *group_filter = "(objectClass=posixGroup)"; - -/* the attributes to request with searches */ -const char *attmap_group_cn = "cn"; -const char *attmap_group_userPassword = "\"*\""; -const char *attmap_group_gidNumber = "gidNumber"; -const char *attmap_group_memberUid = "memberUid"; -const char *attmap_group_member = "member"; - -/* special property for objectSid-based searches - (these are already LDAP-escaped strings) */ -static char *gidSid = NULL; - -/* BUILTIN SID definitions */ -static char *builtinSid = NULL; -const gid_t min_builtin_rid = 544; -const gid_t max_builtin_rid = 552; - -/* default values for attributes */ -static const char *default_group_userPassword = "*"; /* unmatchable */ - -/* the attribute list to request with searches */ -static const char **group_attrs = NULL; - -/* the attribute list for bymember searches (without member attributes) */ -static const char **group_bymember_attrs = NULL; - -/* create a search filter for searching a group entry - by name, return -1 on errors */ -static int mkfilter_group_byname(const char *name, - char *buffer, size_t buflen) -{ - char safename[BUFLEN_SAFENAME]; - /* escape attribute */ - if (myldap_escape(name, safename, sizeof(safename))) - { - log_log(LOG_ERR, "mkfilter_group_byname(): safename buffer too small"); - return -1; - } - /* build filter */ - return mysnprintf(buffer, buflen, "(&%s(%s=%s))", - group_filter, attmap_group_cn, safename); -} - -/* create a search filter for searching a group entry - by gid, return -1 on errors */ -static int mkfilter_group_bygid(gid_t gid, char *buffer, size_t buflen) -{ - /* if searching for a Windows domain SID */ - if (gidSid != NULL) - { - /* the given gid is a BUILTIN gid, the SID prefix is not the domain SID */ - if ((gid >= min_builtin_rid) && (gid <= max_builtin_rid)) - return mysnprintf(buffer, buflen, "(&%s(%s=%s\\%02x\\%02x\\%02x\\%02x))", - group_filter, attmap_group_gidNumber, builtinSid, - (int)(gid & 0xff), (int)((gid >> 8) & 0xff), - (int)((gid >> 16) & 0xff), (int)((gid >> 24) & 0xff)); - return mysnprintf(buffer, buflen, "(&%s(%s=%s\\%02x\\%02x\\%02x\\%02x))", - group_filter, attmap_group_gidNumber, gidSid, - (int)(gid & 0xff), (int)((gid >> 8) & 0xff), - (int)((gid >> 16) & 0xff), (int)((gid >> 24) & 0xff)); - } - else - { - return mysnprintf(buffer, buflen, "(&%s(%s=%d))", - group_filter, attmap_group_gidNumber, (int)gid); - } -} - -/* create a search filter for searching a group entry - by member uid, return -1 on errors */ -static int mkfilter_group_bymember(MYLDAP_SESSION *session, - const char *uid, - char *buffer, size_t buflen) -{ - char dn[BUFLEN_DN]; - char safeuid[BUFLEN_SAFENAME]; - char safedn[BUFLEN_SAFEDN]; - /* escape attribute */ - if (myldap_escape(uid, safeuid, sizeof(safeuid))) - { - log_log(LOG_ERR, "mkfilter_group_bymember(): safeuid buffer too small"); - return -1; - } - /* try to translate uid to DN */ - if ((strcasecmp(attmap_group_member, "\"\"") == 0) || - (uid2dn(session, uid, dn, sizeof(dn)) == NULL)) - return mysnprintf(buffer, buflen, "(&%s(%s=%s))", - group_filter, attmap_group_memberUid, safeuid); - /* escape DN */ - if (myldap_escape(dn, safedn, sizeof(safedn))) - { - log_log(LOG_ERR, "mkfilter_group_bymember(): safedn buffer too small"); - return -1; - } - /* also lookup using user DN */ - return mysnprintf(buffer, buflen, "(&%s(|(%s=%s)(%s=%s)))", - group_filter, - attmap_group_memberUid, safeuid, - attmap_group_member, safedn); -} - -static int mkfilter_group_bymemberdn(const char *dn, - char *buffer, size_t buflen) -{ - char safedn[BUFLEN_SAFEDN]; - /* escape DN */ - if (myldap_escape(dn, safedn, sizeof(safedn))) - { - log_log(LOG_ERR, "mkfilter_group_bymemberdn(): safedn buffer too small"); - return -1; - } - return mysnprintf(buffer, buflen, - "(&%s(%s=%s))", - group_filter, - attmap_group_member, safedn); -} - -void group_init(void) -{ - int i; - SET *set; - /* set up search bases */ - if (group_bases[0] == NULL) - for (i = 0; i < NSS_LDAP_CONFIG_MAX_BASES; i++) - group_bases[i] = nslcd_cfg->bases[i]; - /* set up scope */ - if (group_scope == LDAP_SCOPE_DEFAULT) - group_scope = nslcd_cfg->scope; - /* special case when gidNumber references objectSid */ - if (strncasecmp(attmap_group_gidNumber, "objectSid:", 10) == 0) - { - gidSid = sid2search(attmap_group_gidNumber + 10); - builtinSid = sid2search("S-1-5-32"); - attmap_group_gidNumber = strndup(attmap_group_gidNumber, 9); - } - /* set up attribute list */ - set = set_new(); - attmap_add_attributes(set, attmap_group_cn); - attmap_add_attributes(set, attmap_group_userPassword); - attmap_add_attributes(set, attmap_group_memberUid); - attmap_add_attributes(set, attmap_group_gidNumber); - attmap_add_attributes(set, attmap_group_member); - group_attrs = set_tolist(set); - if (group_attrs == NULL) - { - log_log(LOG_CRIT, "malloc() failed to allocate memory"); - exit(EXIT_FAILURE); - } - set_free(set); - /* set up bymember attribute list */ - set = set_new(); - attmap_add_attributes(set, attmap_group_cn); - attmap_add_attributes(set, attmap_group_userPassword); - attmap_add_attributes(set, attmap_group_gidNumber); - group_bymember_attrs = set_tolist(set); - if (group_bymember_attrs == NULL) - { - log_log(LOG_CRIT, "malloc() failed to allocate memory"); - exit(EXIT_FAILURE); - } - set_free(set); -} - -static int do_write_group(TFILE *fp, MYLDAP_ENTRY *entry, - const char **names, gid_t gids[], int numgids, - const char *passwd, const char **members, - const char *reqname) -{ - int32_t tmpint32, tmp2int32, tmp3int32; - int i, j; - /* write entries for all names and gids */ - for (i = 0; names[i] != NULL; i++) - { - if (!isvalidname(names[i])) - { - log_log(LOG_WARNING, "%s: %s: denied by validnames option", - myldap_get_dn(entry), attmap_group_cn); - } - else if ((reqname == NULL) || (STR_CMP(reqname, names[i]) == 0)) - { - for (j = 0; j < numgids; j++) - { - WRITE_INT32(fp, NSLCD_RESULT_BEGIN); - WRITE_STRING(fp, names[i]); - WRITE_STRING(fp, passwd); - WRITE_INT32(fp, gids[j]); - WRITE_STRINGLIST(fp, members); - } - } - } - return 0; -} - -static void getmembers(MYLDAP_ENTRY *entry, MYLDAP_SESSION *session, - SET *members, SET *seen, SET *subgroups) -{ - char buf[BUFLEN_NAME]; - int i; - const char **values; - const char ***derefs; - /* add the memberUid values */ - values = myldap_get_values(entry, attmap_group_memberUid); - if (values != NULL) - for (i = 0; values[i] != NULL; i++) - { - /* only add valid usernames */ - if (isvalidname(values[i])) - set_add(members, values[i]); - } - /* skip rest if attmap_group_member is blank */ - if (strcasecmp(attmap_group_member, "\"\"") == 0) - return; - /* add deref'd entries if we have them*/ - derefs = myldap_get_deref_values(entry, attmap_group_member, attmap_passwd_uid); - if (derefs != NULL) - { - /* add deref'd uid attributes */ - for (i = 0; derefs[0][i] != NULL; i++) - set_add(members, derefs[0][i]); - /* add non-deref'd attribute values as subgroups */ - for (i = 0; derefs[1][i] != NULL; i++) - { - if ((seen == NULL) || (!set_contains(seen, derefs[1][i]))) - { - if (seen != NULL) - set_add(seen, derefs[1][i]); - if (subgroups != NULL) - set_add(subgroups, derefs[1][i]); - } - } - return; /* no need to parse the member attribute ourselves */ - } - /* add the member values */ - values = myldap_get_values(entry, attmap_group_member); - if (values != NULL) - for (i = 0; values[i] != NULL; i++) - { - if ((seen == NULL) || (!set_contains(seen, values[i]))) - { - if (seen != NULL) - set_add(seen, values[i]); - /* transform the DN into a uid (dn2uid() already checks validity) */ - if (dn2uid(session, values[i], buf, sizeof(buf)) != NULL) - set_add(members, buf); - /* wasn't a UID - try handling it as a nested group */ - else if (subgroups != NULL) - set_add(subgroups, values[i]); - } - } -} - -/* the maximum number of gidNumber attributes per entry */ -#define MAXGIDS_PER_ENTRY 5 - -static int write_group(TFILE *fp, MYLDAP_ENTRY *entry, const char *reqname, - const gid_t *reqgid, int wantmembers, - MYLDAP_SESSION *session) -{ - const char **names, **gidvalues; - const char *passwd; - const char **members = NULL; - SET *set, *seen=NULL, *subgroups=NULL; - gid_t gids[MAXGIDS_PER_ENTRY]; - int numgids; - char *tmp; - char passbuffer[BUFLEN_PASSWORDHASH]; - MYLDAP_SEARCH *search; - MYLDAP_ENTRY *entry2; - int rc; - /* get group name (cn) */ - names = myldap_get_values(entry, attmap_group_cn); - if ((names == NULL) || (names[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_group_cn); - return 0; - } - /* get the group id(s) */ - if (reqgid != NULL) - { - gids[0] = *reqgid; - numgids = 1; - } - else - { - gidvalues = myldap_get_values_len(entry, attmap_group_gidNumber); - if ((gidvalues == NULL) || (gidvalues[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_group_gidNumber); - return 0; - } - for (numgids = 0; (numgids < MAXGIDS_PER_ENTRY) && (gidvalues[numgids] != NULL); numgids++) - { - if (gidSid != NULL) - gids[numgids] = (gid_t)binsid2id(gidvalues[numgids]); - else - { - errno = 0; - gids[numgids] = strtogid(gidvalues[numgids], &tmp, 10); - if ((*(gidvalues[numgids]) == '\0') || (*tmp != '\0')) - { - log_log(LOG_WARNING, "%s: %s: non-numeric", - myldap_get_dn(entry), attmap_group_gidNumber); - return 0; - } - else if ((errno != 0) || (strchr(gidvalues[numgids], '-') != NULL)) - { - log_log(LOG_WARNING, "%s: %s: out of range", - myldap_get_dn(entry), attmap_group_gidNumber); - return 0; - } - } - } - } - /* get group passwd (userPassword) (use only first entry) */ - passwd = get_userpassword(entry, attmap_group_userPassword, - passbuffer, sizeof(passbuffer)); - if (passwd == NULL) - passwd = default_group_userPassword; - /* get group members (memberUid&member) */ - if (wantmembers) - { - set = set_new(); - if (set != NULL) - { - if (nslcd_cfg->nss_nested_groups) - { - seen = set_new(); - subgroups = set_new(); - } - /* collect the members from this group */ - getmembers(entry, session, set, seen, subgroups); - /* add the members of any nested groups */ - if (subgroups != NULL) - { - while ((tmp = set_pop(subgroups)) != NULL) - { - search = myldap_search(session, tmp, LDAP_SCOPE_BASE, group_filter, group_attrs, NULL); - if (search != NULL) - while ((entry2 = myldap_get_entry(search, NULL)) != NULL) - getmembers(entry2, session, set, seen, subgroups); - free(tmp); - } - } - members = set_tolist(set); - set_free(set); - if (seen != NULL) - set_free(seen); - if (subgroups != NULL) - set_free(subgroups); - } - } - /* write entries (split to a separate function so we can ensure the call - to free() below in case a write fails) */ - rc = do_write_group(fp, entry, names, gids, numgids, passwd, members, - reqname); - /* free and return */ - if (members != NULL) - free(members); - return rc; -} - -NSLCD_HANDLE( - group, byname, NSLCD_ACTION_GROUP_BYNAME, - char name[BUFLEN_NAME]; - char filter[BUFLEN_FILTER]; - READ_STRING(fp, name); - log_setrequest("group=\"%s\"", name); - if (!isvalidname(name)) - { - log_log(LOG_WARNING, "request denied by validnames option"); - return -1; - }, - mkfilter_group_byname(name, filter, sizeof(filter)), - write_group(fp, entry, name, NULL, 1, session) -) - -NSLCD_HANDLE( - group, bygid, NSLCD_ACTION_GROUP_BYGID, - gid_t gid; - char filter[BUFLEN_FILTER]; - READ_INT32(fp, gid); - log_setrequest("group=%lu", (unsigned long int)gid);, - mkfilter_group_bygid(gid, filter, sizeof(filter)), - write_group(fp, entry, NULL, &gid, 1, session) -) - -int nslcd_group_bymember(TFILE *fp, MYLDAP_SESSION *session) -{ - /* define common variables */ - int32_t tmpint32; - MYLDAP_SEARCH *search; - MYLDAP_ENTRY *entry; - const char *dn; - const char *base; - int rc, i; - char name[BUFLEN_NAME]; - char filter[BUFLEN_FILTER]; - SET *seen=NULL, *tocheck=NULL; - /* read request parameters */ - READ_STRING(fp, name); - log_setrequest("group/member=\"%s\"", name); - /* validate request */ - if (!isvalidname(name)) - { - log_log(LOG_WARNING, "request denied by validnames option"); - return -1; - } - if ((nslcd_cfg->nss_initgroups_ignoreusers != NULL) && - set_contains(nslcd_cfg->nss_initgroups_ignoreusers, name)) - { - log_log(LOG_DEBUG, "ignored group member"); - /* just end the request, returning no results */ - WRITE_INT32(fp, NSLCD_VERSION); - WRITE_INT32(fp, NSLCD_ACTION_GROUP_BYMEMBER); - WRITE_INT32(fp, NSLCD_RESULT_END); - return 0; - } - /* write the response header */ - WRITE_INT32(fp, NSLCD_VERSION); - WRITE_INT32(fp, NSLCD_ACTION_GROUP_BYMEMBER); - /* prepare the search filter */ - if (mkfilter_group_bymember(session, name, filter, sizeof(filter))) - { - log_log(LOG_WARNING, "nslcd_group_bymember(): filter buffer too small"); - return -1; - } - if ((nslcd_cfg->nss_nested_groups) && (strcasecmp(attmap_group_member, "\"\"") != 0)) - { - seen = set_new(); - tocheck = set_new(); - if ((seen != NULL) && (tocheck == NULL)) - { - set_free(seen); - seen = NULL; - } - else if ((tocheck != NULL) && (seen == NULL)) - { - set_free(tocheck); - tocheck = NULL; - } - } - /* perform a search for each search base */ - for (i = 0; (base = group_bases[i]) != NULL; i++) - { - /* do the LDAP search */ - search = myldap_search(session, base, group_scope, filter, - group_bymember_attrs, NULL); - if (search == NULL) - { - if (seen != NULL) - { - set_free(seen); - set_free(tocheck); - } - return -1; - } - /* go over results */ - while ((entry = myldap_get_entry(search, &rc)) != NULL) - { - if ((seen == NULL) || (!set_contains(seen, dn = myldap_get_dn(entry)))) - { - if (seen != NULL) - { - set_add(seen, dn); - set_add(tocheck, dn); - } - if (write_group(fp, entry, NULL, NULL, 0, session)) - { - if (seen != NULL) - { - set_free(seen); - set_free(tocheck); - } - return -1; - } - } - } - } - /* write possible parent groups */ - if (tocheck != NULL) - { - while ((dn = set_pop(tocheck)) != NULL) - { - /* make filter for finding groups with our group as member */ - if (mkfilter_group_bymemberdn(dn, filter, sizeof(filter))) - { - log_log(LOG_WARNING, "nslcd_group_bymember(): filter buffer too small"); - free((void *)dn); - set_free(seen); - set_free(tocheck); - return -1; - } - free((void *)dn); - /* do the LDAP searches */ - for (i = 0; (base = group_bases[i]) != NULL; i++) - { - search = myldap_search(session, base, group_scope, filter, group_bymember_attrs, NULL); - if (search != NULL) - { - while ((entry = myldap_get_entry(search, NULL)) != NULL) - { - dn = myldap_get_dn(entry); - if (!set_contains(seen, dn)) - { - set_add(seen, dn); - set_add(tocheck, dn); - if (write_group(fp, entry, NULL, NULL, 0, session)) - { - set_free(seen); - set_free(tocheck); - return -1; - } - } - } - } - } - } - set_free(seen); - set_free(tocheck); - } - /* write the final result code */ - if (rc == LDAP_SUCCESS) - { - WRITE_INT32(fp, NSLCD_RESULT_END); - } - return 0; -} - -NSLCD_HANDLE( - group, all, NSLCD_ACTION_GROUP_ALL, - const char *filter; - log_setrequest("group(all)");, - (filter = group_filter, 0), - write_group(fp, entry, NULL, NULL, 1, session) -) diff --git a/nslcd/host.c b/nslcd/host.c deleted file mode 100644 index 7e5f6aa..0000000 --- a/nslcd/host.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - host.c - host name lookup routines - Parts of this file were part of the nss_ldap library (as ldap-hosts.c) - which has been forked into the nss-pam-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006-2014 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 -*/ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <arpa/inet.h> - -#include "common.h" -#include "log.h" -#include "myldap.h" -#include "cfg.h" -#include "attmap.h" - -/* ( nisSchema.2.6 NAME 'ipHost' SUP top AUXILIARY - * DESC 'Abstraction of a host, an IP device. The distinguished - * value of the cn attribute denotes the host's canonical - * name. Device SHOULD be used as a structural class' - * MUST ( cn $ ipHostNumber ) - * MAY ( l $ description $ manager ) ) - */ - -/* the search base for searches */ -const char *host_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; - -/* the search scope for searches */ -int host_scope = LDAP_SCOPE_DEFAULT; - -/* the basic search filter for searches */ -const char *host_filter = "(objectClass=ipHost)"; - -/* the attributes to request with searches */ -const char *attmap_host_cn = "cn"; -const char *attmap_host_ipHostNumber = "ipHostNumber"; - -/* the attribute list to request with searches */ -static const char *host_attrs[3]; - -/* create a search filter for searching a host entry - by name, return -1 on errors */ -static int mkfilter_host_byname(const char *name, char *buffer, size_t buflen) -{ - char safename[BUFLEN_HOSTNAME]; - /* escape attribute */ - if (myldap_escape(name, safename, sizeof(safename))) - { - log_log(LOG_ERR, "mkfilter_host_byname(): safename buffer too small"); - return -1; - } - /* build filter */ - return mysnprintf(buffer, buflen, "(&%s(%s=%s))", - host_filter, attmap_host_cn, safename); -} - -static int mkfilter_host_byaddr(const char *addrstr, - char *buffer, size_t buflen) -{ - char safeaddr[64]; - /* escape attribute */ - if (myldap_escape(addrstr, safeaddr, sizeof(safeaddr))) - { - log_log(LOG_ERR, "mkfilter_host_byaddr(): safeaddr buffer too small"); - return -1; - } - /* build filter */ - return mysnprintf(buffer, buflen, "(&%s(%s=%s))", - host_filter, attmap_host_ipHostNumber, safeaddr); -} - -void host_init(void) -{ - int i; - /* set up search bases */ - if (host_bases[0] == NULL) - for (i = 0; i < NSS_LDAP_CONFIG_MAX_BASES; i++) - host_bases[i] = nslcd_cfg->bases[i]; - /* set up scope */ - if (host_scope == LDAP_SCOPE_DEFAULT) - host_scope = nslcd_cfg->scope; - /* set up attribute list */ - host_attrs[0] = attmap_host_cn; - host_attrs[1] = attmap_host_ipHostNumber; - host_attrs[2] = NULL; -} - -/* write a single host entry to the stream */ -static int write_host(TFILE *fp, MYLDAP_ENTRY *entry) -{ - int32_t tmpint32, tmp2int32, tmp3int32; - int numaddr, i; - const char *hostname; - const char **hostnames; - const char **addresses; - /* get the most canonical name */ - hostname = myldap_get_rdn_value(entry, attmap_host_cn); - /* get the other names for the host */ - hostnames = myldap_get_values(entry, attmap_host_cn); - if ((hostnames == NULL) || (hostnames[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_host_cn); - return 0; - } - /* if the hostname is not yet found, get the first entry from hostnames */ - if (hostname == NULL) - hostname = hostnames[0]; - /* get the addresses */ - addresses = myldap_get_values(entry, attmap_host_ipHostNumber); - if ((addresses == NULL) || (addresses[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_host_ipHostNumber); - return 0; - } - /* write the entry */ - WRITE_INT32(fp, NSLCD_RESULT_BEGIN); - WRITE_STRING(fp, hostname); - WRITE_STRINGLIST_EXCEPT(fp, hostnames, hostname); - for (numaddr = 0; addresses[numaddr] != NULL; numaddr++) - /* noting */ ; - WRITE_INT32(fp, numaddr); - for (i = 0; i < numaddr; i++) - { - WRITE_ADDRESS(fp, entry, attmap_host_ipHostNumber, addresses[i]); - } - return 0; -} - -NSLCD_HANDLE( - host, byname, NSLCD_ACTION_HOST_BYNAME, - char name[BUFLEN_HOSTNAME]; - char filter[BUFLEN_FILTER]; - READ_STRING(fp, name); - log_setrequest("host=\"%s\"", name);, - mkfilter_host_byname(name, filter, sizeof(filter)), - write_host(fp, entry) -) - -NSLCD_HANDLE( - host, byaddr, NSLCD_ACTION_HOST_BYADDR, - int af; - char addr[64]; - int len = sizeof(addr); - char addrstr[64]; - char filter[BUFLEN_FILTER]; - READ_ADDRESS(fp, addr, len, af); - /* translate the address to a string */ - if (inet_ntop(af, addr, addrstr, sizeof(addrstr)) == NULL) - { - log_log(LOG_WARNING, "unable to convert address to string"); - return -1; - } - log_setrequest("host=%s", addrstr);, - mkfilter_host_byaddr(addrstr, filter, sizeof(filter)), - write_host(fp, entry) -) - - -NSLCD_HANDLE( - host, all, NSLCD_ACTION_HOST_ALL, - const char *filter; - log_setrequest("host(all)");, - (filter = host_filter, 0), - write_host(fp, entry) -) diff --git a/nslcd/myldap.c b/nslcd/myldap.c index cf16dd6..095e8e6 100644 --- a/nslcd/myldap.c +++ b/nslcd/myldap.c @@ -1226,440 +1226,20 @@ void myldap_session_close(MYLDAP_SESSION *session) free(session); } -/* mutex for updating the times in the uri */ -pthread_mutex_t uris_mutex = PTHREAD_MUTEX_INITIALIZER; -static int do_retry_search(MYLDAP_SEARCH *search) -{ - int sleeptime = 0; - int start_uri; - time_t endtime; - time_t nexttry; - time_t t; - int rc = LDAP_UNAVAILABLE; - struct myldap_uri *current_uri; - int dotry[NSS_LDAP_CONFIG_MAX_URIS]; - int do_invalidate = 0; - /* clear time stamps */ - for (start_uri = 0; start_uri < NSS_LDAP_CONFIG_MAX_URIS; start_uri++) - dotry[start_uri] = 1; - /* keep trying until we time out */ - endtime = time(NULL) + nslcd_cfg->reconnect_retrytime; - while (1) - { - nexttry = endtime; - /* try each configured URL once */ - pthread_mutex_lock(&uris_mutex); - start_uri = search->session->current_uri; - do - { - current_uri = &(nslcd_cfg->uris[search->session->current_uri]); - /* only try this URI if we should */ - if (!dotry[search->session->current_uri]) - { /* skip this URI */ } - else if ((current_uri->lastfail > (current_uri->firstfail + nslcd_cfg->reconnect_retrytime)) && - ((t = time(NULL)) < (current_uri->lastfail + nslcd_cfg->reconnect_retrytime))) - { - /* we are in a hard fail state and have retried not long ago */ - log_log(LOG_DEBUG, "not retrying server %s which failed just %d second(s) ago and has been failing for %d seconds", - current_uri->uri, (int)(t - current_uri->lastfail), - (int)(t - current_uri->firstfail)); - dotry[search->session->current_uri] = 0; - } - else - { - /* try to start the search */ - pthread_mutex_unlock(&uris_mutex); - rc = do_try_search(search); - if (rc == LDAP_SUCCESS) - { - pthread_mutex_lock(&uris_mutex); - /* check if we are coming back from an error */ - if ((current_uri->lastfail > 0) || (search->session->current_uri != start_uri)) - { - log_log(LOG_INFO, "connected to LDAP server %s", current_uri->uri); - do_invalidate = 1; - } - if (first_search) - { - do_invalidate = 1; - first_search = 0; - } - /* update ok time */ - current_uri->firstfail = 0; - current_uri->lastfail = 0; - pthread_mutex_unlock(&uris_mutex); - /* flag the search as valid */ - search->valid = 1; - /* signal external invalidation of configured caches */ - if (do_invalidate) - invalidator_do(LM_NONE); - return LDAP_SUCCESS; - } - /* close the current connection */ - do_close(search->session); - /* update time of failure and figure out when we should retry */ - pthread_mutex_lock(&uris_mutex); - t = time(NULL); - /* update timestaps unless we are doing an authentication search */ - if (search->session->binddn[0] == '\0') - { - if (current_uri->firstfail == 0) - current_uri->firstfail = t; - current_uri->lastfail = t; - } - /* if it is one of these, retrying this URI is not going to help */ - if ((rc == LDAP_INVALID_CREDENTIALS) || (rc == LDAP_INSUFFICIENT_ACCESS) || - (rc == LDAP_AUTH_METHOD_NOT_SUPPORTED)) - dotry[search->session->current_uri] = 0; - /* check when we should try this URI again */ - else if (t <= (current_uri->firstfail + nslcd_cfg->reconnect_retrytime)) - { - t += nslcd_cfg->reconnect_sleeptime; - if (t < nexttry) - nexttry = t; - } - } - /* try the next URI (with wrap-around) */ - search->session->current_uri++; - if (nslcd_cfg->uris[search->session->current_uri].uri == NULL) - search->session->current_uri = 0; - } - while (search->session->current_uri != start_uri); - pthread_mutex_unlock(&uris_mutex); - /* see if it is any use sleeping */ - if (nexttry >= endtime) - { - if (search->session->binddn[0] == '\0') - myldap_err(LOG_ERR, search->session->ld, rc, "no available LDAP server found"); - return rc; - } - /* sleep between tries */ - sleeptime = nexttry - time(NULL); - if (sleeptime > 0) - { - log_log(LOG_WARNING, "no available LDAP server found, sleeping %d seconds", - sleeptime); - (void)sleep(sleeptime); - } - } -} - -/* force quick retries of all failing LDAP servers */ -void myldap_immediate_reconnect(void) -{ - int i; - time_t t; - t = time(NULL) - nslcd_cfg->reconnect_retrytime; - pthread_mutex_lock(&uris_mutex); - for (i = 0; i < (NSS_LDAP_CONFIG_MAX_URIS + 1); i++) - { - /* only adjust failing connections that are in a hard fail state */ - if ((nslcd_cfg->uris[i].lastfail > t) && - (nslcd_cfg->uris[i].lastfail > (nslcd_cfg->uris[i].firstfail + nslcd_cfg->reconnect_retrytime))) - { - /* move lastfail back to ensure quick retry */ - log_log(LOG_DEBUG, "moving lastfail of %s %d second(s) back to force retry", - nslcd_cfg->uris[i].uri, (int)(nslcd_cfg->uris[i].lastfail - t)); - nslcd_cfg->uris[i].lastfail = t; - } - } - pthread_mutex_unlock(&uris_mutex); -} - -MYLDAP_SEARCH *myldap_search(MYLDAP_SESSION *session, - const char *base, int scope, const char *filter, - const char **attrs, int *rcp) +void myldap_search_close(MYLDAP_SEARCH *search) { - MYLDAP_SEARCH *search; - int i; - int rc; - /* check parameters */ - if ((session == NULL) || (base == NULL) || (filter == NULL) || (attrs == NULL)) - { - log_log(LOG_ERR, "myldap_search(): invalid parameter passed"); - errno = EINVAL; - if (rcp != NULL) - *rcp = LDAP_OPERATIONS_ERROR; - return NULL; - } - /* log the call */ - log_log(LOG_DEBUG, "myldap_search(base=\"%s\", filter=\"%s\")", - base, filter); - /* check if the idle time for the connection has expired */ - myldap_session_check(session); - /* allocate a new search entry */ - search = myldap_search_new(session, base, scope, filter, attrs); - /* find a place in the session where we can register our search */ - for (i = 0; (session->searches[i] != NULL) && (i < MAX_SEARCHES_IN_SESSION); i++) - /* nothing */ ; - if (i >= MAX_SEARCHES_IN_SESSION) - { - log_log(LOG_ERR, "myldap_search(): too many searches registered with session (max %d)", - MAX_SEARCHES_IN_SESSION); - myldap_search_close(search); - if (rcp != NULL) - *rcp = LDAP_OPERATIONS_ERROR; - return NULL; - } - /* register search with the session so we can free it later on */ - session->searches[i] = search; - /* do the search with retries to all configured servers */ - rc = do_retry_search(search); - if (rc != LDAP_SUCCESS) - { - myldap_search_close(search); - if (rcp != NULL) - *rcp = rc; - return NULL; - } - if (rcp != NULL) - *rcp = LDAP_SUCCESS; - return search; + search->close(search); } -void myldap_search_close(MYLDAP_SEARCH *search) -{ - int i; - if (search == NULL) - return; - /* free any messages */ - if (search->msg != NULL) - { - ldap_msgfree(search->msg); - search->msg = NULL; - } - /* abandon the search if there were more results to fetch */ - if ((search->session->ld != NULL) && (search->msgid != -1)) - { - ldap_abandon(search->session->ld, search->msgid); - search->msgid = -1; - } - /* find the reference to this search in the session */ - for (i = 0; i < MAX_SEARCHES_IN_SESSION; i++) - { - if (search->session->searches[i] == search) - search->session->searches[i] = NULL; - } - /* free any search entries */ - if (search->entry != NULL) - myldap_entry_free(search->entry); - /* clean up cookie */ - if (search->cookie != NULL) - ber_bvfree(search->cookie); - /* free read messages */ - if (search->msg != NULL) - ldap_msgfree(search->msg); - /* free the storage we allocated */ - free(search); +struct myldap_search { + MYLDAP_ENTRY *(*get_entry)(void *data, int *rcp); + void *data; } MYLDAP_ENTRY *myldap_get_entry(MYLDAP_SEARCH *search, int *rcp) { - int rc; - int parserc; - struct timeval tv, *tvp; - LDAPControl **resultcontrols; - ber_int_t count; - /* check parameters */ - if ((search == NULL) || (search->session == NULL) || (search->session->ld == NULL)) - { - log_log(LOG_ERR, "myldap_get_entry(): invalid search passed"); - errno = EINVAL; - if (rcp != NULL) - *rcp = LDAP_OPERATIONS_ERROR; - return NULL; - } - /* check if the connection wasn't closed in another search */ - if (!search->valid) - { - log_log(LOG_WARNING, "myldap_get_entry(): connection was closed"); - /* retry the search */ - if (search->may_retry_search) - { - log_log(LOG_DEBUG, "myldap_get_entry(): retry search"); - search->may_retry_search = 0; - if (do_retry_search(search) == LDAP_SUCCESS) - return myldap_get_entry(search, rcp); - } - myldap_search_close(search); - if (rcp != NULL) - *rcp = LDAP_SERVER_DOWN; - return NULL; - } - /* set up a timelimit value for operations */ - if (nslcd_cfg->timelimit == LDAP_NO_LIMIT) - tvp = NULL; - else - { - tv.tv_sec = nslcd_cfg->timelimit; - tv.tv_usec = 0; - tvp = &tv; - } - /* if we have an existing result entry, free it */ - if (search->entry != NULL) - { - myldap_entry_free(search->entry); - search->entry = NULL; - } - /* try to parse results until we have a final error or ok */ - while (1) - { - /* free the previous message if there was any */ - if (search->msg != NULL) - { - ldap_msgfree(search->msg); - search->msg = NULL; - } - /* get the next result */ - rc = ldap_result(search->session->ld, search->msgid, LDAP_MSG_ONE, tvp, - &(search->msg)); - /* handle result */ - switch (rc) - { - case LDAP_RES_SEARCH_ENTRY: - /* we have a normal search entry, update timestamp and return result */ - time(&(search->session->lastactivity)); - search->entry = myldap_entry_new(search); - if (rcp != NULL) - *rcp = LDAP_SUCCESS; - /* log the first couple of dns in the result (but not all, to - prevent swamping the log) */ - if (search->count < MAX_DEBUG_LOG_DNS) - log_log(LOG_DEBUG, "ldap_result(): %s", myldap_get_dn(search->entry)); - search->count++; - search->may_retry_search = 0; - return search->entry; - case LDAP_RES_SEARCH_RESULT: - /* we have a search result, parse it */ - resultcontrols = NULL; - if (search->cookie != NULL) - { - ber_bvfree(search->cookie); - search->cookie = NULL; - } - /* NB: this frees search->msg */ - parserc = ldap_parse_result(search->session->ld, search->msg, &rc, - NULL, NULL, NULL, &resultcontrols, 1); - search->msg = NULL; - /* check for errors during parsing */ - if ((parserc != LDAP_SUCCESS) && (parserc != LDAP_MORE_RESULTS_TO_RETURN)) - { - if (resultcontrols != NULL) - ldap_controls_free(resultcontrols); - myldap_err(LOG_ERR, search->session->ld, parserc, "ldap_parse_result() failed"); - myldap_search_close(search); - if (rcp != NULL) - *rcp = parserc; - return NULL; - } - /* check for errors in message */ - if ((rc != LDAP_SUCCESS) && (rc != LDAP_MORE_RESULTS_TO_RETURN)) - { - if (resultcontrols != NULL) - ldap_controls_free(resultcontrols); - myldap_err(LOG_ERR, search->session->ld, rc, "ldap_result() failed"); - /* close connection on connection problems */ - if ((rc == LDAP_UNAVAILABLE) || (rc == LDAP_SERVER_DOWN)) - do_close(search->session); - myldap_search_close(search); - if (rcp != NULL) - *rcp = rc; - return NULL; - } - /* handle result controls */ - if (resultcontrols != NULL) - { - /* see if there are any more pages to come */ - rc = ldap_parse_page_control(search->session->ld, resultcontrols, - &count, &(search->cookie)); - if (rc != LDAP_SUCCESS) - { - if (rc != LDAP_CONTROL_NOT_FOUND) - myldap_err(LOG_WARNING, search->session->ld, rc, "ldap_parse_page_control() failed"); - /* clear error flag */ - rc = LDAP_SUCCESS; - if (ldap_set_option(search->session->ld, LDAP_OPT_ERROR_NUMBER, - &rc) != LDAP_SUCCESS) - log_log(LOG_WARNING, "failed to clear the error flag"); - } - /* TODO: handle the above return code?? */ - ldap_controls_free(resultcontrols); - } - search->msgid = -1; - /* check if there are more pages to come */ - if ((search->cookie == NULL) || (search->cookie->bv_len == 0)) - { - if (search->count > MAX_DEBUG_LOG_DNS) - log_log(LOG_DEBUG, "ldap_result(): ... %d more results", - search->count - MAX_DEBUG_LOG_DNS); - log_log(LOG_DEBUG, "ldap_result(): end of results (%d total)", - search->count); - /* we are at the end of the search, no more results */ - myldap_search_close(search); - if (rcp != NULL) - *rcp = LDAP_SUCCESS; - return NULL; - } - /* try the next page */ - rc = do_try_search(search); - if (rc != LDAP_SUCCESS) - { - /* close connection on connection problems */ - if ((rc == LDAP_UNAVAILABLE) || (rc == LDAP_SERVER_DOWN)) - do_close(search->session); - myldap_search_close(search); - if (rcp != NULL) - *rcp = rc; - return NULL; - } - /* we continue with another pass */ - break; - case LDAP_RES_SEARCH_REFERENCE: - break; /* just ignore search references */ - default: - /* we have some error condition, find out which */ - switch (rc) - { - case -1: - /* try to get error code */ - if (ldap_get_option(search->session->ld, LDAP_OPT_ERROR_NUMBER, - &rc) != LDAP_SUCCESS) - rc = LDAP_UNAVAILABLE; - myldap_err(LOG_ERR, search->session->ld, rc, "ldap_result() failed"); - break; - case 0: - /* the timeout expired */ - log_log(LOG_ERR, "ldap_result() timed out"); - rc = LDAP_TIMELIMIT_EXCEEDED; - break; - default: - /* unknown code */ - log_log(LOG_WARNING, "ldap_result() returned unexpected result type"); - rc = LDAP_PROTOCOL_ERROR; - } - /* close connection on some connection problems */ - if ((rc == LDAP_UNAVAILABLE) || (rc == LDAP_SERVER_DOWN) || - (rc == LDAP_SUCCESS) || (rc == LDAP_TIMELIMIT_EXCEEDED) || - (rc == LDAP_OPERATIONS_ERROR) || (rc == LDAP_PROTOCOL_ERROR)) - { - do_close(search->session); - /* retry once if no data has been received yet */ - if (search->may_retry_search) - { - log_log(LOG_DEBUG, "myldap_get_entry(): retry search"); - search->may_retry_search = 0; - if (do_retry_search(search) == LDAP_SUCCESS) - return myldap_get_entry(search, rcp); - } - } - /* close search */ - myldap_search_close(search); - if (rcp != NULL) - *rcp = rc; - return NULL; - } - } + return search->get_entry(search->data, rcp); } /* Get the DN from the entry. This function only returns NULL (and sets diff --git a/nslcd/myldap.h b/nslcd/myldap.h index e54ae52..952c68f 100644 --- a/nslcd/myldap.h +++ b/nslcd/myldap.h @@ -57,11 +57,15 @@ typedef struct ldap_session MYLDAP_SESSION; not have any problems with an LDAP *ld per thread. http://www.openldap.org/lists/openldap-software/200606/msg00252.html */ +struct myldap_search { + MYLDAP_ENTRY *(*get_entry)(void *data, int *rcp); + void *data; +} /* A result set as returned by myldap_search(). */ typedef struct myldap_search MYLDAP_SEARCH; /* A single entry from the LDAP database as returned by myldap_get_entry(). */ -typedef struct myldap_entry MYLDAP_ENTRY; +#define MYLDAP_ENTRY void; /* Create a new session, this does not yet connect to the LDAP server. The connection to the server is made on-demand when a search is performed. This diff --git a/nslcd/netgroup.c b/nslcd/netgroup.c deleted file mode 100644 index 6dbf77a..0000000 --- a/nslcd/netgroup.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - netgroup.c - netgroup lookup routines - Parts of this file were part of the nss_ldap library (as ldap-netgrp.c) - which has been forked into the nss-pam-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006-2014 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 -*/ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/param.h> -#include <string.h> - -#include "common.h" -#include "log.h" -#include "myldap.h" -#include "cfg.h" -#include "attmap.h" - -/* ( nisSchema.2.8 NAME 'nisNetgroup' SUP top STRUCTURAL - * DESC 'Abstraction of a netgroup. May refer to other netgroups' - * MUST cn - * MAY ( nisNetgroupTriple $ memberNisNetgroup $ description ) ) - */ - -/* the search base for searches */ -const char *netgroup_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; - -/* the search scope for searches */ -int netgroup_scope = LDAP_SCOPE_DEFAULT; - -/* the basic search filter for searches */ -const char *netgroup_filter = "(objectClass=nisNetgroup)"; - -/* the attributes to request with searches */ -const char *attmap_netgroup_cn = "cn"; -const char *attmap_netgroup_nisNetgroupTriple = "nisNetgroupTriple"; -const char *attmap_netgroup_memberNisNetgroup = "memberNisNetgroup"; - -/* the attribute list to request with searches */ -static const char *netgroup_attrs[4]; - -static int mkfilter_netgroup_byname(const char *name, - char *buffer, size_t buflen) -{ - char safename[BUFLEN_SAFENAME]; - /* escape attribute */ - if (myldap_escape(name, safename, sizeof(safename))) - { - log_log(LOG_ERR, "mkfilter_netgroup_byname(): safename buffer too small"); - return -1; - } - /* build filter */ - return mysnprintf(buffer, buflen, "(&%s(%s=%s))", - netgroup_filter, attmap_netgroup_cn, safename); -} - -void netgroup_init(void) -{ - int i; - /* set up search bases */ - if (netgroup_bases[0] == NULL) - for (i = 0; i < NSS_LDAP_CONFIG_MAX_BASES; i++) - netgroup_bases[i] = nslcd_cfg->bases[i]; - /* set up scope */ - if (netgroup_scope == LDAP_SCOPE_DEFAULT) - netgroup_scope = nslcd_cfg->scope; - /* set up attribute list */ - netgroup_attrs[0] = attmap_netgroup_cn; - netgroup_attrs[1] = attmap_netgroup_nisNetgroupTriple; - netgroup_attrs[2] = attmap_netgroup_memberNisNetgroup; - netgroup_attrs[3] = NULL; -} - -static int write_string_stripspace_len(TFILE *fp, const char *str, int len) -{ - int32_t tmpint32; - int i, j; - DEBUG_PRINT("WRITE_STRING: var=" __STRING(str) " string=\"%s\"", str); - /* skip leading spaces */ - for (i = 0; (str[i] != '\0') && (isspace(str[i])); i++) - /* nothing */ ; - /* skip trailing spaces */ - for (j = len; (j > i) && (isspace(str[j - 1])); j--) - /* nothing */ ; - /* write length of string */ - WRITE_INT32(fp, j - i); - /* write string itself */ - if (j > i) - { - WRITE(fp, str + i, j - i); - } - /* we're done */ - return 0; -} - -#define WRITE_STRING_STRIPSPACE_LEN(fp, str, len) \ - if (write_string_stripspace_len(fp, str, len)) \ - return -1; - -#define WRITE_STRING_STRIPSPACE(fp, str) \ - WRITE_STRING_STRIPSPACE_LEN(fp, str, strlen(str)) - -static int write_netgroup_triple(TFILE *fp, MYLDAP_ENTRY *entry, - const char *triple) -{ - int32_t tmpint32; - int i; - int hostb, hoste, userb, usere, domainb, domaine; - /* skip leading spaces */ - for (i = 0; (triple[i] != '\0') && (isspace(triple[i])); i++) - /* nothing */ ; - /* we should have a bracket now */ - if (triple[i] != '(') - { - log_log(LOG_WARNING, "%s: %s: does not begin with '('", - myldap_get_dn(entry), attmap_netgroup_nisNetgroupTriple); - return 0; - } - i++; - hostb = i; - /* find comma (end of host string) */ - for (; (triple[i] != '\0') && (triple[i] != ','); i++) - /* nothing */ ; - hoste = i; - if (triple[i++] != ',') - { - log_log(LOG_WARNING, "%s: %s: missing ','", - myldap_get_dn(entry), attmap_netgroup_nisNetgroupTriple); - return 0; - } - userb = i; - /* find comma (end of user string) */ - for (; (triple[i] != '\0') && (triple[i] != ','); i++) - /* nothing */ ; - usere = i; - if (triple[i++] != ',') - { - log_log(LOG_WARNING, "%s: %s: missing ','", - myldap_get_dn(entry), attmap_netgroup_nisNetgroupTriple); - return 0; - } - domainb = i; - /* find closing bracket (end of domain string) */ - for (; (triple[i] != '\0') && (triple[i] != ')'); i++) - /* nothing */ ; - domaine=i; - if (triple[i++] != ')') - { - log_log(LOG_WARNING, "%s: %s: missing ')'", - myldap_get_dn(entry), attmap_netgroup_nisNetgroupTriple); - return 0; - } - /* skip trailing spaces */ - for (; (triple[i] != '\0') && (isspace(triple[i])); i++) - /* nothing */ ; - /* if anything is left in the string we have a problem */ - if (triple[i] != '\0') - { - log_log(LOG_WARNING, "%s: %s: contains trailing data", - myldap_get_dn(entry), attmap_netgroup_nisNetgroupTriple); - return 0; - } - /* write strings */ - WRITE_INT32(fp, NSLCD_NETGROUP_TYPE_TRIPLE); - WRITE_STRING_STRIPSPACE_LEN(fp, triple + hostb, hoste - hostb) - WRITE_STRING_STRIPSPACE_LEN(fp, triple + userb, usere - userb) - WRITE_STRING_STRIPSPACE_LEN(fp, triple + domainb, domaine - domainb) - /* we're done */ - return 0; -} - -static int write_netgroup(TFILE *fp, MYLDAP_ENTRY *entry, const char *reqname) -{ - int32_t tmpint32; - int i, j; - const char **names; - const char **triples; - const char **members; - /* get the netgroup name */ - names = myldap_get_values(entry, attmap_netgroup_cn); - if ((names == NULL) || (names[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_netgroup_cn); - return 0; - } - /* get the netgroup triples and member */ - triples = myldap_get_values(entry, attmap_netgroup_nisNetgroupTriple); - members = myldap_get_values(entry, attmap_netgroup_memberNisNetgroup); - /* write the entries */ - for (i = 0; names[i] != NULL; i++) - if ((reqname == NULL) || (STR_CMP(reqname, names[i]) == 0)) - { - /* write first part of result */ - WRITE_INT32(fp, NSLCD_RESULT_BEGIN); - WRITE_STRING(fp, names[i]); - /* write the netgroup triples */ - if (triples != NULL) - for (j = 0; triples[j] != NULL; j++) - if (write_netgroup_triple(fp, entry, triples[j])) - return -1; - /* write netgroup members */ - if (members != NULL) - for (j = 0; members[j] != NULL; j++) - { - /* write triple indicator */ - WRITE_INT32(fp, NSLCD_NETGROUP_TYPE_NETGROUP); - /* write netgroup name */ - WRITE_STRING_STRIPSPACE(fp, members[j]); - } - /* write end of result marker */ - WRITE_INT32(fp, NSLCD_NETGROUP_TYPE_END); - } - /* we're done */ - return 0; -} - -NSLCD_HANDLE( - netgroup, byname, NSLCD_ACTION_NETGROUP_BYNAME, - char name[BUFLEN_NAME]; - char filter[BUFLEN_FILTER]; - READ_STRING(fp, name); - log_setrequest("netgroup=\"%s\"", name);, - mkfilter_netgroup_byname(name, filter, sizeof(filter)), - write_netgroup(fp, entry, name) -) - -NSLCD_HANDLE( - netgroup, all, NSLCD_ACTION_NETGROUP_ALL, - const char *filter; - log_setrequest("netgroup(all)");, - (filter = netgroup_filter, 0), - write_netgroup(fp, entry, NULL) -) diff --git a/nslcd/network.c b/nslcd/network.c deleted file mode 100644 index 26f68ad..0000000 --- a/nslcd/network.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - network.c - network address entry lookup routines - Parts of this file were part of the nss_ldap library (as ldap-network.c) - which has been forked into the nss-pam-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006-2014 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 -*/ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <arpa/inet.h> - -#include "common.h" -#include "log.h" -#include "myldap.h" -#include "cfg.h" -#include "attmap.h" - -/* ( nisSchema.2.7 NAME 'ipNetwork' SUP top STRUCTURAL - * DESC 'Abstraction of a network. The distinguished value of - * MUST ( cn $ ipNetworkNumber ) - * MAY ( ipNetmaskNumber $ l $ description $ manager ) ) - */ - -/* the search base for searches */ -const char *network_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; - -/* the search scope for searches */ -int network_scope = LDAP_SCOPE_DEFAULT; - -/* the basic search filter for searches */ -const char *network_filter = "(objectClass=ipNetwork)"; - -/* the attributes used in searches */ -const char *attmap_network_cn = "cn"; -const char *attmap_network_ipNetworkNumber = "ipNetworkNumber"; - -/* the attribute list to request with searches */ -static const char *network_attrs[3]; - -/* create a search filter for searching a network entry - by name, return -1 on errors */ -static int mkfilter_network_byname(const char *name, - char *buffer, size_t buflen) -{ - char safename[BUFLEN_HOSTNAME]; - /* escape attribute */ - if (myldap_escape(name, safename, sizeof(safename))) - { - log_log(LOG_ERR, "mkfilter_network_byname(): safename buffer too small"); - return -1; - } - /* build filter */ - return mysnprintf(buffer, buflen, "(&%s(%s=%s))", - network_filter, attmap_network_cn, safename); -} - -static int mkfilter_network_byaddr(const char *addrstr, - char *buffer, size_t buflen) -{ - char safeaddr[64]; - /* escape attribute */ - if (myldap_escape(addrstr, safeaddr, sizeof(safeaddr))) - { - log_log(LOG_ERR, "mkfilter_network_byaddr(): safeaddr buffer too small"); - return -1; - } - /* build filter */ - return mysnprintf(buffer, buflen, "(&%s(%s=%s))", - network_filter, attmap_network_ipNetworkNumber, safeaddr); -} - -void network_init(void) -{ - int i; - /* set up search bases */ - if (network_bases[0] == NULL) - for (i = 0; i < NSS_LDAP_CONFIG_MAX_BASES; i++) - network_bases[i] = nslcd_cfg->bases[i]; - /* set up scope */ - if (network_scope == LDAP_SCOPE_DEFAULT) - network_scope = nslcd_cfg->scope; - /* set up attribute list */ - network_attrs[0] = attmap_network_cn; - network_attrs[1] = attmap_network_ipNetworkNumber; - network_attrs[2] = NULL; -} - -/* write a single network entry to the stream */ -static int write_network(TFILE *fp, MYLDAP_ENTRY *entry) -{ - int32_t tmpint32, tmp2int32, tmp3int32; - int numaddr, i; - const char *networkname; - const char **networknames; - const char **addresses; - /* get the most canonical name */ - networkname = myldap_get_rdn_value(entry, attmap_network_cn); - /* get the other names for the network */ - networknames = myldap_get_values(entry, attmap_network_cn); - if ((networknames == NULL) || (networknames[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_network_cn); - return 0; - } - /* if the networkname is not yet found, get the first entry from networknames */ - if (networkname == NULL) - networkname = networknames[0]; - /* get the addresses */ - addresses = myldap_get_values(entry, attmap_network_ipNetworkNumber); - if ((addresses == NULL) || (addresses[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_network_ipNetworkNumber); - return 0; - } - /* write the entry */ - WRITE_INT32(fp, NSLCD_RESULT_BEGIN); - WRITE_STRING(fp, networkname); - WRITE_STRINGLIST_EXCEPT(fp, networknames, networkname); - for (numaddr = 0; addresses[numaddr] != NULL; numaddr++) - /* noting */ ; - WRITE_INT32(fp, numaddr); - for (i = 0; i < numaddr; i++) - { - WRITE_ADDRESS(fp, entry, attmap_network_ipNetworkNumber, addresses[i]); - } - return 0; -} - -NSLCD_HANDLE( - network, byname, NSLCD_ACTION_NETWORK_BYNAME, - char name[BUFLEN_HOSTNAME]; - char filter[BUFLEN_FILTER]; - READ_STRING(fp, name); - log_setrequest("network=\"%s\"", name);, - mkfilter_network_byname(name, filter, sizeof(filter)), - write_network(fp, entry) -) - -NSLCD_HANDLE( - network, byaddr, NSLCD_ACTION_NETWORK_BYADDR, - int af; - char addr[64]; - int len = sizeof(addr); - char addrstr[64]; - char filter[BUFLEN_FILTER]; - READ_ADDRESS(fp, addr, len, af); - /* translate the address to a string */ - if (inet_ntop(af, addr, addrstr, sizeof(addrstr)) == NULL) - { - log_log(LOG_WARNING, "unable to convert address to string"); - return -1; - } - log_setrequest("network=%s", addrstr);, - mkfilter_network_byaddr(addrstr, filter, sizeof(filter)), - write_network(fp, entry) -) - -NSLCD_HANDLE( - network, all, NSLCD_ACTION_NETWORK_ALL, - const char *filter; - log_setrequest("network(all)");, - (filter = network_filter, 0), - write_network(fp, entry) -) diff --git a/nslcd/nslcd.c b/nslcd/nslcd.c index 8072b25..ddf5f24 100644 --- a/nslcd/nslcd.c +++ b/nslcd/nslcd.c @@ -3,6 +3,7 @@ Copyright (C) 2006 West Consulting Copyright (C) 2006-2014 Arthur de Jong + Copyright (C) 2014 Luke Shumaker This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -168,8 +169,8 @@ static void exithandler(void) if (nslcd_serversocket >= 0) { if (close(nslcd_serversocket)) - log_log(LOG_WARNING, "problem closing server socket (ignored): %s", - strerror(errno)); + log_log(LOG_WARNING, "problem closing server socket (ignored):%d: %s", + nslcd_serversocket, strerror(errno)); } /* log exit */ log_log(LOG_INFO, "version %s bailing out", VERSION); @@ -258,35 +259,35 @@ static void handleconnection(int sock, MYLDAP_SESSION *session) switch (action) { case NSLCD_ACTION_CONFIG_GET: (void)nslcd_config_get(fp, session); break; - case NSLCD_ACTION_ALIAS_BYNAME: (void)nslcd_alias_byname(fp, session); break; - case NSLCD_ACTION_ALIAS_ALL: (void)nslcd_alias_all(fp, session); break; - case NSLCD_ACTION_ETHER_BYNAME: (void)nslcd_ether_byname(fp, session); break; - case NSLCD_ACTION_ETHER_BYETHER: (void)nslcd_ether_byether(fp, session); break; - case NSLCD_ACTION_ETHER_ALL: (void)nslcd_ether_all(fp, session); break; + /* case NSLCD_ACTION_ALIAS_BYNAME: (void)nslcd_alias_byname(fp, session); break; */ + /* case NSLCD_ACTION_ALIAS_ALL: (void)nslcd_alias_all(fp, session); break; */ + /* case NSLCD_ACTION_ETHER_BYNAME: (void)nslcd_ether_byname(fp, session); break; */ + /* case NSLCD_ACTION_ETHER_BYETHER: (void)nslcd_ether_byether(fp, session); break; */ + /* case NSLCD_ACTION_ETHER_ALL: (void)nslcd_ether_all(fp, session); break; */ case NSLCD_ACTION_GROUP_BYNAME: (void)nslcd_group_byname(fp, session); break; case NSLCD_ACTION_GROUP_BYGID: (void)nslcd_group_bygid(fp, session); break; case NSLCD_ACTION_GROUP_BYMEMBER: (void)nslcd_group_bymember(fp, session); break; case NSLCD_ACTION_GROUP_ALL: (void)nslcd_group_all(fp, session); break; - case NSLCD_ACTION_HOST_BYNAME: (void)nslcd_host_byname(fp, session); break; - case NSLCD_ACTION_HOST_BYADDR: (void)nslcd_host_byaddr(fp, session); break; - case NSLCD_ACTION_HOST_ALL: (void)nslcd_host_all(fp, session); break; - case NSLCD_ACTION_NETGROUP_BYNAME: (void)nslcd_netgroup_byname(fp, session); break; - case NSLCD_ACTION_NETGROUP_ALL: (void)nslcd_netgroup_all(fp, session); break; - case NSLCD_ACTION_NETWORK_BYNAME: (void)nslcd_network_byname(fp, session); break; - case NSLCD_ACTION_NETWORK_BYADDR: (void)nslcd_network_byaddr(fp, session); break; - case NSLCD_ACTION_NETWORK_ALL: (void)nslcd_network_all(fp, session); break; + /* case NSLCD_ACTION_HOST_BYNAME: (void)nslcd_host_byname(fp, session); break; */ + /* case NSLCD_ACTION_HOST_BYADDR: (void)nslcd_host_byaddr(fp, session); break; */ + /* case NSLCD_ACTION_HOST_ALL: (void)nslcd_host_all(fp, session); break; */ + /* case NSLCD_ACTION_NETGROUP_BYNAME: (void)nslcd_netgroup_byname(fp, session); break; */ + /* case NSLCD_ACTION_NETGROUP_ALL: (void)nslcd_netgroup_all(fp, session); break; */ + /* case NSLCD_ACTION_NETWORK_BYNAME: (void)nslcd_network_byname(fp, session); break; */ + /* case NSLCD_ACTION_NETWORK_BYADDR: (void)nslcd_network_byaddr(fp, session); break; */ + /* case NSLCD_ACTION_NETWORK_ALL: (void)nslcd_network_all(fp, session); break; */ case NSLCD_ACTION_PASSWD_BYNAME: (void)nslcd_passwd_byname(fp, session, uid); break; case NSLCD_ACTION_PASSWD_BYUID: (void)nslcd_passwd_byuid(fp, session, uid); break; case NSLCD_ACTION_PASSWD_ALL: (void)nslcd_passwd_all(fp, session, uid); break; - case NSLCD_ACTION_PROTOCOL_BYNAME: (void)nslcd_protocol_byname(fp, session); break; - case NSLCD_ACTION_PROTOCOL_BYNUMBER:(void)nslcd_protocol_bynumber(fp, session); break; - case NSLCD_ACTION_PROTOCOL_ALL: (void)nslcd_protocol_all(fp, session); break; - case NSLCD_ACTION_RPC_BYNAME: (void)nslcd_rpc_byname(fp, session); break; - case NSLCD_ACTION_RPC_BYNUMBER: (void)nslcd_rpc_bynumber(fp, session); break; - case NSLCD_ACTION_RPC_ALL: (void)nslcd_rpc_all(fp, session); break; - case NSLCD_ACTION_SERVICE_BYNAME: (void)nslcd_service_byname(fp, session); break; - case NSLCD_ACTION_SERVICE_BYNUMBER: (void)nslcd_service_bynumber(fp, session); break; - case NSLCD_ACTION_SERVICE_ALL: (void)nslcd_service_all(fp, session); break; + /* case NSLCD_ACTION_PROTOCOL_BYNAME: (void)nslcd_protocol_byname(fp, session); break; */ + /* case NSLCD_ACTION_PROTOCOL_BYNUMBER:(void)nslcd_protocol_bynumber(fp, session); break; */ + /* case NSLCD_ACTION_PROTOCOL_ALL: (void)nslcd_protocol_all(fp, session); break; */ + /* case NSLCD_ACTION_RPC_BYNAME: (void)nslcd_rpc_byname(fp, session); break; */ + /* case NSLCD_ACTION_RPC_BYNUMBER: (void)nslcd_rpc_bynumber(fp, session); break; */ + /* case NSLCD_ACTION_RPC_ALL: (void)nslcd_rpc_all(fp, session); break; */ + /* case NSLCD_ACTION_SERVICE_BYNAME: (void)nslcd_service_byname(fp, session); break; */ + /* case NSLCD_ACTION_SERVICE_BYNUMBER: (void)nslcd_service_bynumber(fp, session); break; */ + /* case NSLCD_ACTION_SERVICE_ALL: (void)nslcd_service_all(fp, session); break; */ case NSLCD_ACTION_SHADOW_BYNAME: (void)nslcd_shadow_byname(fp, session, uid); break; case NSLCD_ACTION_SHADOW_ALL: (void)nslcd_shadow_all(fp, session, uid); break; case NSLCD_ACTION_PAM_AUTHC: (void)nslcd_pam_authc(fp, session, uid); break; @@ -471,9 +472,7 @@ int main(int argc, char *argv[]) /* 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); + /* read configuration file */ cfg_init(NSLCD_CONF_PATH); diff --git a/nslcd/nsswitch.c b/nslcd/nsswitch.c index ff9d9d5..2b94bc8 100644 --- a/nslcd/nsswitch.c +++ b/nslcd/nsswitch.c @@ -43,7 +43,7 @@ static time_t nsswitch_mtime = 0; /* the maximum line length supported of nsswitch.conf */ #define MAX_LINE_LENGTH 4096 -/* check whether /etc/nsswitch.conf should be related to update +/* check whether /etc/nsswitch.conf should be reloaded to update cached_shadow_uses_ldap */ void nsswitch_check_reload(void) { diff --git a/nslcd/passwd.c b/nslcd/passwd.c deleted file mode 100644 index 198fd45..0000000 --- a/nslcd/passwd.c +++ /dev/null @@ -1,603 +0,0 @@ -/* - passwd.c - password entry lookup routines - Parts of this file were part of the nss_ldap library (as ldap-pwd.c) - which has been forked into the nss-pam-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006-2014 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 -*/ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <sys/types.h> -#include <unistd.h> -#include <string.h> -#include <pthread.h> - -#include "common.h" -#include "log.h" -#include "myldap.h" -#include "cfg.h" -#include "attmap.h" -#include "common/dict.h" -#include "compat/strndup.h" - -/* ( nisSchema.2.0 NAME 'posixAccount' SUP top AUXILIARY - * DESC 'Abstraction of an account with POSIX attributes' - * MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory ) - * MAY ( userPassword $ loginShell $ gecos $ description ) ) - */ - -/* the search base for searches */ -const char *passwd_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; - -/* the search scope for searches */ -int passwd_scope = LDAP_SCOPE_DEFAULT; - -/* the basic search filter for searches */ -const char *passwd_filter = "(objectClass=posixAccount)"; - -/* the attributes used in searches */ -const char *attmap_passwd_uid = "uid"; -const char *attmap_passwd_userPassword = "\"*\""; -const char *attmap_passwd_uidNumber = "uidNumber"; -const char *attmap_passwd_gidNumber = "gidNumber"; -const char *attmap_passwd_gecos = "\"${gecos:-$cn}\""; -const char *attmap_passwd_homeDirectory = "homeDirectory"; -const char *attmap_passwd_loginShell = "loginShell"; - -/* special properties for objectSid-based searches - (these are already LDAP-escaped strings) */ -static char *uidSid = NULL; -static char *gidSid = NULL; - -/* default values for attributes */ -static const char *default_passwd_userPassword = "*"; /* unmatchable */ - -/* Note that the resulting password value should be one of: - <empty> - no password set, allow login without password - * - often used to prevent logins - x - "valid" encrypted password that does not match any valid password - often used to indicate that the password is defined elsewhere - other - encrypted password, usually in crypt(3) format */ - -/* the attribute list to request with searches */ -static const char **passwd_attrs = NULL; - -/* create a search filter for searching a passwd entry - by name, return -1 on errors */ -static int mkfilter_passwd_byname(const char *name, - char *buffer, size_t buflen) -{ - char safename[BUFLEN_SAFENAME]; - /* escape attribute */ - if (myldap_escape(name, safename, sizeof(safename))) - { - log_log(LOG_ERR, "mkfilter_passwd_byname(): safename buffer too small"); - return -1; - } - /* build filter */ - return mysnprintf(buffer, buflen, "(&%s(%s=%s))", - passwd_filter, attmap_passwd_uid, safename); -} - -/* create a search filter for searching a passwd entry - by uid, return -1 on errors */ -static int mkfilter_passwd_byuid(uid_t uid, char *buffer, size_t buflen) -{ - if (uidSid != NULL) - { - return mysnprintf(buffer, buflen, "(&%s(%s=%s\\%02x\\%02x\\%02x\\%02x))", - passwd_filter, attmap_passwd_uidNumber, uidSid, - (int)(uid & 0xff), (int)((uid >> 8) & 0xff), - (int)((uid >> 16) & 0xff), (int)((uid >> 24) & 0xff)); - } - else - { - return mysnprintf(buffer, buflen, "(&%s(%s=%d))", - passwd_filter, attmap_passwd_uidNumber, (int)uid); - } -} - -void passwd_init(void) -{ - int i; - SET *set; - /* set up search bases */ - if (passwd_bases[0] == NULL) - for (i = 0; i < NSS_LDAP_CONFIG_MAX_BASES; i++) - passwd_bases[i] = nslcd_cfg->bases[i]; - /* set up scope */ - if (passwd_scope == LDAP_SCOPE_DEFAULT) - passwd_scope = nslcd_cfg->scope; - /* special case when uidNumber or gidNumber reference objectSid */ - if (strncasecmp(attmap_passwd_uidNumber, "objectSid:", 10) == 0) - { - uidSid = sid2search(attmap_passwd_uidNumber + 10); - attmap_passwd_uidNumber = strndup(attmap_passwd_uidNumber, 9); - } - if (strncasecmp(attmap_passwd_gidNumber, "objectSid:", 10) == 0) - { - gidSid = sid2search(attmap_passwd_gidNumber + 10); - attmap_passwd_gidNumber = strndup(attmap_passwd_gidNumber, 9); - } - /* set up attribute list */ - set = set_new(); - attmap_add_attributes(set, "objectClass"); /* for testing shadowAccount */ - attmap_add_attributes(set, attmap_passwd_uid); - attmap_add_attributes(set, attmap_passwd_userPassword); - attmap_add_attributes(set, attmap_passwd_uidNumber); - attmap_add_attributes(set, attmap_passwd_gidNumber); - attmap_add_attributes(set, attmap_passwd_gecos); - attmap_add_attributes(set, attmap_passwd_homeDirectory); - attmap_add_attributes(set, attmap_passwd_loginShell); - passwd_attrs = set_tolist(set); - if (passwd_attrs == NULL) - { - log_log(LOG_CRIT, "malloc() failed to allocate memory"); - exit(EXIT_FAILURE); - } - set_free(set); -} - -/* the cache that is used in dn2uid() */ -static pthread_mutex_t dn2uid_cache_mutex = PTHREAD_MUTEX_INITIALIZER; -static DICT *dn2uid_cache = NULL; -struct dn2uid_cache_entry { - time_t timestamp; - char *uid; -}; - -/* checks whether the entry has a valid uidNumber attribute - (>= nss_min_uid) */ -static int entry_has_valid_uid(MYLDAP_ENTRY *entry) -{ - int i; - const char **values; - char *tmp; - uid_t uid; - /* if min_uid is not set any entry should do */ - if (nslcd_cfg->nss_min_uid == 0) - return 1; - /* get all uidNumber attributes */ - values = myldap_get_values_len(entry, attmap_passwd_uidNumber); - if ((values == NULL) || (values[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_passwd_uidNumber); - return 0; - } - /* check if there is a uidNumber attributes >= min_uid */ - for (i = 0; values[i] != NULL; i++) - { - if (uidSid != NULL) - uid = (uid_t)binsid2id(values[i]); - else - { - errno = 0; - uid = strtouid(values[i], &tmp, 10); - if ((*(values[i]) == '\0') || (*tmp != '\0')) - { - log_log(LOG_WARNING, "%s: %s: non-numeric", - myldap_get_dn(entry), attmap_passwd_uidNumber); - continue; - } - else if ((errno != 0) || (strchr(values[i], '-') != NULL)) - { - log_log(LOG_WARNING, "%s: %s: out of range", - myldap_get_dn(entry), attmap_passwd_uidNumber); - continue; - } - } - if (uid >= nslcd_cfg->nss_min_uid) - return 1; - } - /* nothing found */ - return 0; -} - -/* Perform an LDAP lookup to translate the DN into a uid. - This function either returns NULL or a strdup()ed string. */ -char *lookup_dn2uid(MYLDAP_SESSION *session, const char *dn, int *rcp, - char *buf, size_t buflen) -{ - MYLDAP_SEARCH *search; - MYLDAP_ENTRY *entry; - static const char *attrs[3]; - int rc = LDAP_SUCCESS; - const char **values; - char *uid = NULL; - if (rcp == NULL) - rcp = &rc; - /* we have to look up the entry */ - attrs[0] = attmap_passwd_uid; - attrs[1] = attmap_passwd_uidNumber; - attrs[2] = NULL; - search = myldap_search(session, dn, LDAP_SCOPE_BASE, passwd_filter, attrs, rcp); - if (search == NULL) - { - log_log(LOG_WARNING, "%s: lookup error: %s", dn, ldap_err2string(*rcp)); - return NULL; - } - entry = myldap_get_entry(search, rcp); - if (entry == NULL) - { - if (*rcp != LDAP_SUCCESS) - log_log(LOG_WARNING, "%s: lookup error: %s", dn, ldap_err2string(*rcp)); - return NULL; - } - /* check the uidNumber attribute if min_uid is set */ - if (entry_has_valid_uid(entry)) - { - /* get uid (just use first one) */ - values = myldap_get_values(entry, attmap_passwd_uid); - /* check the result for presence and validity */ - if ((values != NULL) && (values[0] != NULL) && - isvalidname(values[0]) && (strlen(values[0]) < buflen)) - { - strcpy(buf, values[0]); - uid = buf; - } - } - /* clean up and return */ - myldap_search_close(search); - return uid; -} - -/* Translate the DN into a user name. This function tries several aproaches - at getting the user name, including looking in the DN for a uid attribute, - looking in the cache and falling back to looking up a uid attribute in a - LDAP query. */ -char *dn2uid(MYLDAP_SESSION *session, const char *dn, char *buf, size_t buflen) -{ - struct dn2uid_cache_entry *cacheentry = NULL; - char *uid; - /* check for empty string */ - if ((dn == NULL) || (*dn == '\0')) - return NULL; - /* try to look up uid within DN string */ - if (myldap_cpy_rdn_value(dn, attmap_passwd_uid, buf, buflen) != NULL) - { - /* check if it is valid */ - if (!isvalidname(buf)) - return NULL; - return buf; - } - /* if we don't use the cache, just lookup and return */ - if ((nslcd_cfg->cache_dn2uid_positive == 0) && (nslcd_cfg->cache_dn2uid_negative == 0)) - return lookup_dn2uid(session, dn, NULL, buf, buflen); - /* see if we have a cached entry */ - pthread_mutex_lock(&dn2uid_cache_mutex); - if (dn2uid_cache == NULL) - dn2uid_cache = dict_new(); - if ((dn2uid_cache != NULL) && ((cacheentry = dict_get(dn2uid_cache, dn)) != NULL)) - { - if ((cacheentry->uid != NULL) && (strlen(cacheentry->uid) < buflen)) - { - /* if the cached entry is still valid, return that */ - if ((nslcd_cfg->cache_dn2uid_positive > 0) && - (time(NULL) < (cacheentry->timestamp + nslcd_cfg->cache_dn2uid_positive))) - { - strcpy(buf, cacheentry->uid); - pthread_mutex_unlock(&dn2uid_cache_mutex); - return buf; - } - } - else - { - if ((nslcd_cfg->cache_dn2uid_negative > 0) && - (time(NULL) < (cacheentry->timestamp + nslcd_cfg->cache_dn2uid_negative))) - /* if the cached entry is still valid, return that */ - { - pthread_mutex_unlock(&dn2uid_cache_mutex); - return NULL; - } - } - } - pthread_mutex_unlock(&dn2uid_cache_mutex); - /* look up the uid using an LDAP query */ - uid = lookup_dn2uid(session, dn, NULL, buf, buflen); - /* store the result in the cache */ - pthread_mutex_lock(&dn2uid_cache_mutex); - /* try to get the entry from the cache here again because it could have - changed in the meantime */ - cacheentry = dict_get(dn2uid_cache, dn); - if (cacheentry == NULL) - { - /* allocate a new entry in the cache */ - cacheentry = (struct dn2uid_cache_entry *)malloc(sizeof(struct dn2uid_cache_entry)); - if (cacheentry != NULL) - { - cacheentry->uid = NULL; - dict_put(dn2uid_cache, dn, cacheentry); - } - } - /* update the cache entry */ - if (cacheentry != NULL) - { - cacheentry->timestamp = time(NULL); - /* copy the uid if needed */ - if (cacheentry->uid == NULL) - cacheentry->uid = uid != NULL ? strdup(uid) : NULL; - else if ((uid == NULL) || (strcmp(cacheentry->uid, uid) != 0)) - { - free(cacheentry->uid); - cacheentry->uid = uid != NULL ? strdup(uid) : NULL; - } - } - pthread_mutex_unlock(&dn2uid_cache_mutex); - /* copy the result into the buffer */ - return uid; -} - -MYLDAP_ENTRY *uid2entry(MYLDAP_SESSION *session, const char *uid, int *rcp) -{ - MYLDAP_SEARCH *search = NULL; - MYLDAP_ENTRY *entry = NULL; - const char *base; - int i; - static const char *attrs[3]; - char filter[BUFLEN_FILTER]; - /* if it isn't a valid username, just bail out now */ - if (!isvalidname(uid)) - { - if (rcp != NULL) - *rcp = LDAP_INVALID_SYNTAX; - return NULL; - } - /* set up attributes (we don't need much) */ - attrs[0] = attmap_passwd_uid; - attrs[1] = attmap_passwd_uidNumber; - attrs[2] = NULL; - /* we have to look up the entry */ - mkfilter_passwd_byname(uid, filter, sizeof(filter)); - for (i = 0; (i < NSS_LDAP_CONFIG_MAX_BASES) && ((base = passwd_bases[i]) != NULL); i++) - { - search = myldap_search(session, base, passwd_scope, filter, attrs, rcp); - if (search == NULL) - { - if ((rcp != NULL) && (*rcp == LDAP_SUCCESS)) - *rcp = LDAP_NO_SUCH_OBJECT; - return NULL; - } - entry = myldap_get_entry(search, rcp); - if ((entry != NULL) && (entry_has_valid_uid(entry))) - return entry; - } - if ((rcp != NULL) && (*rcp == LDAP_SUCCESS)) - *rcp = LDAP_NO_SUCH_OBJECT; - return NULL; -} - -char *uid2dn(MYLDAP_SESSION *session, const char *uid, char *buf, size_t buflen) -{ - MYLDAP_ENTRY *entry; - /* look up the entry */ - entry = uid2entry(session, uid, NULL); - if (entry == NULL) - return NULL; - /* get DN */ - return myldap_cpy_dn(entry, buf, buflen); -} - -#ifndef NSS_FLAVOUR_GLIBC -/* only check nsswitch.conf for glibc */ -#define check_nsswitch_reload() -#define shadow_uses_ldap() (1) -#endif /* NSS_FLAVOUR_GLIBC */ - -/* the maximum number of uidNumber attributes per entry */ -#define MAXUIDS_PER_ENTRY 5 - -static int write_passwd(TFILE *fp, MYLDAP_ENTRY *entry, const char *requser, - const uid_t *requid, uid_t calleruid) -{ - int32_t tmpint32; - const char **tmpvalues; - char *tmp; - const char **usernames; - const char *passwd; - uid_t uids[MAXUIDS_PER_ENTRY]; - int numuids; - char gidbuf[32]; - gid_t gid; - char gecos[1024]; - char homedir[256]; - char shell[64]; - char passbuffer[BUFLEN_PASSWORDHASH]; - int i, j; - /* get the usernames for this entry */ - usernames = myldap_get_values(entry, attmap_passwd_uid); - if ((usernames == NULL) || (usernames[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_passwd_uid); - return 0; - } - /* if we are using shadow maps and this entry looks like it would return - shadow information, make the passwd entry indicate it */ - if (myldap_has_objectclass(entry, "shadowAccount") && nsswitch_shadow_uses_ldap()) - { - passwd = "x"; - } - else - { - passwd = get_userpassword(entry, attmap_passwd_userPassword, - passbuffer, sizeof(passbuffer)); - if ((passwd == NULL) || (calleruid != 0)) - passwd = default_passwd_userPassword; - } - /* get the uids for this entry */ - if (requid != NULL) - { - uids[0] = *requid; - numuids = 1; - } - else - { - tmpvalues = myldap_get_values_len(entry, attmap_passwd_uidNumber); - if ((tmpvalues == NULL) || (tmpvalues[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_passwd_uidNumber); - return 0; - } - for (numuids = 0; (numuids < MAXUIDS_PER_ENTRY) && (tmpvalues[numuids] != NULL); numuids++) - { - if (uidSid != NULL) - uids[numuids] = (uid_t)binsid2id(tmpvalues[numuids]); - else - { - errno = 0; - uids[numuids] = strtouid(tmpvalues[numuids], &tmp, 10); - if ((*(tmpvalues[numuids]) == '\0') || (*tmp != '\0')) - { - log_log(LOG_WARNING, "%s: %s: non-numeric", - myldap_get_dn(entry), attmap_passwd_uidNumber); - return 0; - } - else if ((errno != 0) || (strchr(tmpvalues[numuids], '-') != NULL)) - { - log_log(LOG_WARNING, "%s: %s: out of range", - myldap_get_dn(entry), attmap_passwd_uidNumber); - return 0; - } - } - } - } - /* get the gid for this entry */ - if (gidSid != NULL) - { - tmpvalues = myldap_get_values_len(entry, attmap_passwd_gidNumber); - if ((tmpvalues == NULL) || (tmpvalues[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_passwd_gidNumber); - return 0; - } - gid = (gid_t)binsid2id(tmpvalues[0]); - } - else - { - attmap_get_value(entry, attmap_passwd_gidNumber, gidbuf, sizeof(gidbuf)); - if (gidbuf[0] == '\0') - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_passwd_gidNumber); - return 0; - } - errno = 0; - gid = strtogid(gidbuf, &tmp, 10); - if ((gidbuf[0] == '\0') || (*tmp != '\0')) - { - log_log(LOG_WARNING, "%s: %s: non-numeric", - myldap_get_dn(entry), attmap_passwd_gidNumber); - return 0; - } - else if ((errno != 0) || (strchr(gidbuf, '-') != NULL)) - { - log_log(LOG_WARNING, "%s: %s: out of range", - myldap_get_dn(entry), attmap_passwd_gidNumber); - return 0; - } - } - /* get the gecos for this entry */ - attmap_get_value(entry, attmap_passwd_gecos, gecos, sizeof(gecos)); - /* get the home directory for this entry */ - attmap_get_value(entry, attmap_passwd_homeDirectory, homedir, sizeof(homedir)); - if (homedir[0] == '\0') - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_passwd_homeDirectory); - /* get the shell for this entry */ - attmap_get_value(entry, attmap_passwd_loginShell, shell, sizeof(shell)); - /* write the entries */ - for (i = 0; usernames[i] != NULL; i++) - if ((requser == NULL) || (STR_CMP(requser, usernames[i]) == 0)) - { - if (!isvalidname(usernames[i])) - { - log_log(LOG_WARNING, "%s: %s: denied by validnames option", - myldap_get_dn(entry), attmap_passwd_uid); - } - else - { - for (j = 0; j < numuids; j++) - { - if (uids[j] >= nslcd_cfg->nss_min_uid) - { - WRITE_INT32(fp, NSLCD_RESULT_BEGIN); - WRITE_STRING(fp, usernames[i]); - WRITE_STRING(fp, passwd); - WRITE_INT32(fp, uids[j]); - WRITE_INT32(fp, gid); - WRITE_STRING(fp, gecos); - WRITE_STRING(fp, homedir); - WRITE_STRING(fp, shell); - } - } - } - } - return 0; -} - -NSLCD_HANDLE_UID( - passwd, byname, NSLCD_ACTION_PASSWD_BYNAME, - char name[BUFLEN_NAME]; - char filter[BUFLEN_FILTER]; - READ_STRING(fp, name); - log_setrequest("passwd=\"%s\"", name); - if (!isvalidname(name)) - { - log_log(LOG_WARNING, "request denied by validnames option"); - return -1; - } - nsswitch_check_reload();, - mkfilter_passwd_byname(name, filter, sizeof(filter)), - write_passwd(fp, entry, name, NULL, calleruid) -) - -NSLCD_HANDLE_UID( - passwd, byuid, NSLCD_ACTION_PASSWD_BYUID, - uid_t uid; - char filter[BUFLEN_FILTER]; - READ_INT32(fp, uid); - log_setrequest("passwd=%lu", (unsigned long int)uid); - if (uid < nslcd_cfg->nss_min_uid) - { - /* return an empty result */ - WRITE_INT32(fp, NSLCD_VERSION); - WRITE_INT32(fp, NSLCD_ACTION_PASSWD_BYUID); - WRITE_INT32(fp, NSLCD_RESULT_END); - return 0; - } - nsswitch_check_reload();, - mkfilter_passwd_byuid(uid, filter, sizeof(filter)), - write_passwd(fp, entry, NULL, &uid, calleruid) -) - -NSLCD_HANDLE_UID( - passwd, all, NSLCD_ACTION_PASSWD_ALL, - const char *filter; - log_setrequest("passwd(all)"); - nsswitch_check_reload();, - (filter = passwd_filter, 0), - write_passwd(fp, entry, NULL, NULL, calleruid) -) diff --git a/nslcd/protocol.c b/nslcd/protocol.c deleted file mode 100644 index 0e2cc47..0000000 --- a/nslcd/protocol.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - protocol.c - protocol name and number lookup routines - Parts of this file were part of the nss_ldap library (as ldap-proto.c) - which has been forked into the nss-pam-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006-2014 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 -*/ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#ifdef HAVE_STDINT_H -#include <stdint.h> -#endif /* HAVE_STDINT_H */ - -#include "common.h" -#include "log.h" -#include "myldap.h" -#include "cfg.h" -#include "attmap.h" - -/* ( nisSchema.2.4 NAME 'ipProtocol' SUP top STRUCTURAL - * DESC 'Abstraction of an IP protocol. Maps a protocol number - * to one or more names. The distinguished value of the cn - * attribute denotes the protocol's canonical name' - * MUST ( cn $ ipProtocolNumber ) - * MAY description ) - */ - -/* the search base for searches */ -const char *protocol_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; - -/* the search scope for searches */ -int protocol_scope = LDAP_SCOPE_DEFAULT; - -/* the basic search filter for searches */ -const char *protocol_filter = "(objectClass=ipProtocol)"; - -/* the attributes used in searches */ -const char *attmap_protocol_cn = "cn"; -const char *attmap_protocol_ipProtocolNumber = "ipProtocolNumber"; - -/* the attribute list to request with searches */ -static const char *protocol_attrs[3]; - -static int mkfilter_protocol_byname(const char *name, - char *buffer, size_t buflen) -{ - char safename[BUFLEN_SAFENAME]; - /* escape attribute */ - if (myldap_escape(name, safename, sizeof(safename))) - { - log_log(LOG_ERR, "mkfilter_protocol_byname(): safename buffer too small"); - return -1; - } - /* build filter */ - return mysnprintf(buffer, buflen, "(&%s(%s=%s))", - protocol_filter, attmap_protocol_cn, safename); -} - -/* create a search filter for searching a protocol entry - by uid, return -1 on errors */ -static int mkfilter_protocol_bynumber(int protocol, - char *buffer, size_t buflen) -{ - return mysnprintf(buffer, buflen, "(&%s(%s=%d))", - protocol_filter, attmap_protocol_ipProtocolNumber, protocol); -} - -void protocol_init(void) -{ - int i; - /* set up search bases */ - if (protocol_bases[0] == NULL) - for (i = 0; i < NSS_LDAP_CONFIG_MAX_BASES; i++) - protocol_bases[i] = nslcd_cfg->bases[i]; - /* set up scope */ - if (protocol_scope == LDAP_SCOPE_DEFAULT) - protocol_scope = nslcd_cfg->scope; - /* set up attribute list */ - protocol_attrs[0] = attmap_protocol_cn; - protocol_attrs[1] = attmap_protocol_ipProtocolNumber; - protocol_attrs[2] = NULL; -} - -static int write_protocol(TFILE *fp, MYLDAP_ENTRY *entry, const char *reqname) -{ - int32_t tmpint32, tmp2int32, tmp3int32; - const char *name; - const char **aliases; - const char **protos; - char *tmp; - long proto; - int i; - /* get the most canonical name */ - name = myldap_get_rdn_value(entry, attmap_protocol_cn); - /* get the other names for the protocol */ - aliases = myldap_get_values(entry, attmap_protocol_cn); - if ((aliases == NULL) || (aliases[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_protocol_cn); - return 0; - } - /* if the protocol name is not yet found, get the first entry */ - if (name == NULL) - name = aliases[0]; - /* check case of returned protocol entry */ - if ((reqname != NULL) && (STR_CMP(reqname, name) != 0)) - { - for (i = 0; (aliases[i] != NULL) && (STR_CMP(reqname, aliases[i]) != 0); i++) - /* nothing */ ; - if (aliases[i] == NULL) - return 0; /* neither the name nor any of the aliases matched */ - } - /* get the protocol number */ - protos = myldap_get_values(entry, attmap_protocol_ipProtocolNumber); - if ((protos == NULL) || (protos[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_protocol_ipProtocolNumber); - return 0; - } - else if (protos[1] != NULL) - { - log_log(LOG_WARNING, "%s: %s: multiple values", - myldap_get_dn(entry), attmap_protocol_ipProtocolNumber); - } - errno = 0; - proto = strtol(protos[0], &tmp, 10); - if ((*(protos[0]) == '\0') || (*tmp != '\0')) - { - log_log(LOG_WARNING, "%s: %s: non-numeric", - myldap_get_dn(entry), attmap_protocol_ipProtocolNumber); - return 0; - } - else if ((errno != 0) || (proto < 0) || (proto > (long)UINT8_MAX)) - { - log_log(LOG_WARNING, "%s: %s: out of range", - myldap_get_dn(entry), attmap_protocol_ipProtocolNumber); - return 0; - } - /* write entry */ - WRITE_INT32(fp, NSLCD_RESULT_BEGIN); - WRITE_STRING(fp, name); - WRITE_STRINGLIST_EXCEPT(fp, aliases, name); - /* proto number is actually an 8-bit value but we write 32 bits anyway */ - WRITE_INT32(fp, proto); - return 0; -} - -NSLCD_HANDLE( - protocol, byname, NSLCD_ACTION_PROTOCOL_BYNAME, - char name[BUFLEN_NAME]; - char filter[BUFLEN_FILTER]; - READ_STRING(fp, name); - log_setrequest("protocol=\"%s\"", name);, - mkfilter_protocol_byname(name, filter, sizeof(filter)), - write_protocol(fp, entry, name) -) - -NSLCD_HANDLE( - protocol, bynumber, NSLCD_ACTION_PROTOCOL_BYNUMBER, - int protocol; - char filter[BUFLEN_FILTER]; - READ_INT32(fp, protocol); - log_setrequest("protocol=%lu", (unsigned long int)protocol);, - mkfilter_protocol_bynumber(protocol, filter, sizeof(filter)), - write_protocol(fp, entry, NULL) -) - -NSLCD_HANDLE( - protocol, all, NSLCD_ACTION_PROTOCOL_ALL, - const char *filter; - log_setrequest("protocol(all)");, - (filter = protocol_filter, 0), - write_protocol(fp, entry, NULL) -) diff --git a/nslcd/rpc.c b/nslcd/rpc.c deleted file mode 100644 index 4021978..0000000 --- a/nslcd/rpc.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - rpc.c - rpc name lookup routines - Parts of this file were part of the nss_ldap library (as ldap-rpc.c) which - has been forked into the nss-pam-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006-2014 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 -*/ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#ifdef HAVE_STDINT_H -#include <stdint.h> -#endif /* HAVE_STDINT_H */ - -#include "common.h" -#include "log.h" -#include "myldap.h" -#include "cfg.h" -#include "attmap.h" - -/* ( nisSchema.2.5 NAME 'oncRpc' SUP top STRUCTURAL - * DESC 'Abstraction of an Open Network Computing (ONC) - * [RFC1057] Remote Procedure Call (RPC) binding. - * This class maps an ONC RPC number to a name. - * The distinguished value of the cn attribute denotes - * the RPC service's canonical name' - * MUST ( cn $ oncRpcNumber ) - * MAY description ) - */ - -/* the search base for searches */ -const char *rpc_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; - -/* the search scope for searches */ -int rpc_scope = LDAP_SCOPE_DEFAULT; - -/* the basic search filter for searches */ -const char *rpc_filter = "(objectClass=oncRpc)"; - -/* the attributes to request with searches */ -const char *attmap_rpc_cn = "cn"; -const char *attmap_rpc_oncRpcNumber = "oncRpcNumber"; - -/* the attribute list to request with searches */ -static const char *rpc_attrs[3]; - -static int mkfilter_rpc_byname(const char *name, char *buffer, size_t buflen) -{ - char safename[BUFLEN_SAFENAME]; - /* escape attribute */ - if (myldap_escape(name, safename, sizeof(safename))) - { - log_log(LOG_ERR, "mkfilter_rpc_byname(): safename buffer too small"); - return -1; - } - /* build filter */ - return mysnprintf(buffer, buflen, "(&%s(%s=%s))", - rpc_filter, attmap_rpc_cn, safename); -} - -static int mkfilter_rpc_bynumber(int number, char *buffer, size_t buflen) -{ - return mysnprintf(buffer, buflen, "(&%s(%s=%d))", - rpc_filter, attmap_rpc_oncRpcNumber, number); -} - -void rpc_init(void) -{ - int i; - /* set up search bases */ - if (rpc_bases[0] == NULL) - for (i = 0; i < NSS_LDAP_CONFIG_MAX_BASES; i++) - rpc_bases[i] = nslcd_cfg->bases[i]; - /* set up scope */ - if (rpc_scope == LDAP_SCOPE_DEFAULT) - rpc_scope = nslcd_cfg->scope; - /* set up attribute list */ - rpc_attrs[0] = attmap_rpc_cn; - rpc_attrs[1] = attmap_rpc_oncRpcNumber; - rpc_attrs[2] = NULL; -} - -/* write a single rpc entry to the stream */ -static int write_rpc(TFILE *fp, MYLDAP_ENTRY *entry, const char *reqname) -{ - int32_t tmpint32, tmp2int32, tmp3int32; - const char *name; - const char **aliases; - const char **numbers; - char *tmp; - unsigned long number; - int i; - /* get the most canonical name */ - name = myldap_get_rdn_value(entry, attmap_rpc_cn); - /* get the other names for the rpc entries */ - aliases = myldap_get_values(entry, attmap_rpc_cn); - if ((aliases == NULL) || (aliases[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_rpc_cn); - return 0; - } - /* if the rpc name is not yet found, get the first entry */ - if (name == NULL) - name = aliases[0]; - /* check case of returned rpc entry */ - if ((reqname != NULL) && (STR_CMP(reqname, name) != 0)) - { - for (i = 0; (aliases[i] != NULL) && (STR_CMP(reqname, aliases[i]) != 0); i++) - /* nothing */ ; - if (aliases[i] == NULL) - return 0; /* neither the name nor any of the aliases matched */ - } - /* get the rpc number */ - numbers = myldap_get_values(entry, attmap_rpc_oncRpcNumber); - if ((numbers == NULL) || (numbers[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_rpc_oncRpcNumber); - return 0; - } - else if (numbers[1] != NULL) - { - log_log(LOG_WARNING, "%s: %s: multiple values", - myldap_get_dn(entry), attmap_rpc_oncRpcNumber); - } - errno = 0; - number = strtol(numbers[0], &tmp, 10); - if ((*(numbers[0]) == '\0') || (*tmp != '\0')) - { - log_log(LOG_WARNING, "%s: %s: non-numeric", - myldap_get_dn(entry), attmap_rpc_oncRpcNumber); - return 0; - } - else if ((errno != 0) || (number > UINT32_MAX)) - { - log_log(LOG_WARNING, "%s: %s: out of range", - myldap_get_dn(entry), attmap_rpc_oncRpcNumber); - return 0; - } - /* write the entry */ - WRITE_INT32(fp, NSLCD_RESULT_BEGIN); - WRITE_STRING(fp, name); - WRITE_STRINGLIST_EXCEPT(fp, aliases, name); - WRITE_INT32(fp, number); - return 0; -} - -NSLCD_HANDLE( - rpc, byname, NSLCD_ACTION_RPC_BYNAME, - char name[BUFLEN_NAME]; - char filter[BUFLEN_FILTER]; - READ_STRING(fp, name); - log_setrequest("rpc=\"%s\"", name);, - mkfilter_rpc_byname(name, filter, sizeof(filter)), - write_rpc(fp, entry, name) -) - -NSLCD_HANDLE( - rpc, bynumber, NSLCD_ACTION_RPC_BYNUMBER, - int number; - char filter[BUFLEN_FILTER]; - READ_INT32(fp, number); - log_setrequest("rpc=%lu", (unsigned long int)number);, - mkfilter_rpc_bynumber(number, filter, sizeof(filter)), - write_rpc(fp, entry, NULL) -) - -NSLCD_HANDLE( - rpc, all, NSLCD_ACTION_RPC_ALL, - const char *filter; - log_setrequest("rpc(all)");, - (filter = rpc_filter, 0), - write_rpc(fp, entry, NULL) -) diff --git a/nslcd/service.c b/nslcd/service.c deleted file mode 100644 index 1e5d615..0000000 --- a/nslcd/service.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - service.c - service entry lookup routines - Parts of this file were part of the nss_ldap library (as ldap-service.c) - which has been forked into the nss-pam-ldapd library. - - Copyright (C) 1997-2005 Luke Howard - Copyright (C) 2006 West Consulting - Copyright (C) 2006-2014 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 -*/ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#ifdef HAVE_STDINT_H -#include <stdint.h> -#endif /* HAVE_STDINT_H */ - -#include "common.h" -#include "log.h" -#include "myldap.h" -#include "cfg.h" -#include "attmap.h" - -/* ( nisSchema.2.3 NAME 'ipService' SUP top STRUCTURAL - * DESC 'Abstraction an Internet Protocol service. - * Maps an IP port and protocol (such as tcp or udp) - * to one or more names; the distinguished value of - * the cn attribute denotes the service's canonical - * name' - * MUST ( cn $ ipServicePort $ ipServiceProtocol ) - * MAY ( description ) ) - */ - -/* the search base for searches */ -const char *service_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL }; - -/* the search scope for searches */ -int service_scope = LDAP_SCOPE_DEFAULT; - -/* the basic search filter for searches */ -const char *service_filter = "(objectClass=ipService)"; - -/* the attributes to request with searches */ -const char *attmap_service_cn = "cn"; -const char *attmap_service_ipServicePort = "ipServicePort"; -const char *attmap_service_ipServiceProtocol = "ipServiceProtocol"; - -/* the attribute list to request with searches */ -static const char *service_attrs[4]; - -static int mkfilter_service_byname(const char *name, const char *protocol, - char *buffer, size_t buflen) -{ - char safename[BUFLEN_SAFENAME], safeprotocol[BUFLEN_SAFENAME]; - /* escape attributes */ - if (myldap_escape(name, safename, sizeof(safename))) - { - log_log(LOG_ERR, "mkfilter_service_byname(): safename buffer too small"); - return -1; - } - /* build filter */ - if (*protocol != '\0') - { - if (myldap_escape(protocol, safeprotocol, sizeof(safeprotocol))) - { - log_log(LOG_ERR, "mkfilter_service_byname(): safeprotocol buffer too small"); - return -1; - } - return mysnprintf(buffer, buflen, "(&%s(%s=%s)(%s=%s))", - service_filter, attmap_service_cn, safename, - attmap_service_ipServiceProtocol, safeprotocol); - } - else - return mysnprintf(buffer, buflen, "(&%s(%s=%s))", - service_filter, attmap_service_cn, safename); -} - -static int mkfilter_service_bynumber(int number, const char *protocol, - char *buffer, size_t buflen) -{ - char safeprotocol[BUFLEN_SAFENAME]; - if (*protocol != '\0') - { - if (myldap_escape(protocol, safeprotocol, sizeof(safeprotocol))) - { - log_log(LOG_ERR, "mkfilter_service_bynumber(): safeprotocol buffer too small"); - return -1; - } - return mysnprintf(buffer, buflen, "(&%s(%s=%d)(%s=%s))", - service_filter, attmap_service_ipServicePort, number, - attmap_service_ipServiceProtocol, safeprotocol); - } - else - return mysnprintf(buffer, buflen, "(&%s(%s=%d))", - service_filter, attmap_service_ipServicePort, number); -} - -void service_init(void) -{ - int i; - /* set up search bases */ - if (service_bases[0] == NULL) - for (i = 0; i < NSS_LDAP_CONFIG_MAX_BASES; i++) - service_bases[i] = nslcd_cfg->bases[i]; - /* set up scope */ - if (service_scope == LDAP_SCOPE_DEFAULT) - service_scope = nslcd_cfg->scope; - /* set up attribute list */ - service_attrs[0] = attmap_service_cn; - service_attrs[1] = attmap_service_ipServicePort; - service_attrs[2] = attmap_service_ipServiceProtocol; - service_attrs[3] = NULL; -} - -static int write_service(TFILE *fp, MYLDAP_ENTRY *entry, - const char *reqname, const char *reqprotocol) -{ - int32_t tmpint32, tmp2int32, tmp3int32; - const char *name; - const char **aliases; - const char **ports; - const char **protocols; - char *tmp; - long port; - int i; - /* get the most canonical name */ - name = myldap_get_rdn_value(entry, attmap_service_cn); - /* get the other names for the service entries */ - aliases = myldap_get_values(entry, attmap_service_cn); - if ((aliases == NULL) || (aliases[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_service_cn); - return 0; - } - /* if the service name is not yet found, get the first entry */ - if (name == NULL) - name = aliases[0]; - /* check case of returned services entry */ - if ((reqname != NULL) && (STR_CMP(reqname, name) != 0)) - { - for (i = 0; (aliases[i] != NULL) && (STR_CMP(reqname, aliases[i]) != 0); i++) - /* nothing */ ; - if (aliases[i] == NULL) - return 0; /* neither the name nor any of the aliases matched */ - } - /* get the service number */ - ports = myldap_get_values(entry, attmap_service_ipServicePort); - if ((ports == NULL) || (ports[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_service_ipServicePort); - return 0; - } - else if (ports[1] != NULL) - { - log_log(LOG_WARNING, "%s: %s: multiple values", - myldap_get_dn(entry), attmap_service_ipServicePort); - } - errno = 0; - port = strtol(ports[0], &tmp, 10); - if ((*(ports[0]) == '\0') || (*tmp != '\0')) - { - log_log(LOG_WARNING, "%s: %s: non-numeric value", - myldap_get_dn(entry), attmap_service_ipServicePort); - return 0; - } - else if ((errno != 0) || (port <= 0) || (port > (long)UINT16_MAX)) - { - log_log(LOG_WARNING, "%s: %s: out of range", - myldap_get_dn(entry), attmap_service_ipServicePort); - return 0; - } - /* get protocols */ - protocols = myldap_get_values(entry, attmap_service_ipServiceProtocol); - if ((protocols == NULL) || (protocols[0] == NULL)) - { - log_log(LOG_WARNING, "%s: %s: missing", - myldap_get_dn(entry), attmap_service_ipServiceProtocol); - return 0; - } - /* write the entries */ - for (i = 0; protocols[i] != NULL; i++) - if ((reqprotocol == NULL) || (*reqprotocol == '\0') || - (STR_CMP(reqprotocol, protocols[i]) == 0)) - { - WRITE_INT32(fp, NSLCD_RESULT_BEGIN); - WRITE_STRING(fp, name); - WRITE_STRINGLIST_EXCEPT(fp, aliases, name); - /* port number is actually a 16-bit value but we write 32 bits anyway */ - WRITE_INT32(fp, port); - WRITE_STRING(fp, protocols[i]); - } - return 0; -} - -NSLCD_HANDLE( - service, byname, NSLCD_ACTION_SERVICE_BYNAME, - char name[BUFLEN_NAME]; - char protocol[BUFLEN_NAME]; - char filter[BUFLEN_FILTER]; - READ_STRING(fp, name); - READ_STRING(fp, protocol); - log_setrequest("service=\"%s\"%s%s", name, - *protocol != '\0' ? "/" : "", protocol);, - mkfilter_service_byname(name, protocol, filter, sizeof(filter)), - write_service(fp, entry, name, protocol) -) - -NSLCD_HANDLE( - service, bynumber, NSLCD_ACTION_SERVICE_BYNUMBER, - int number; - char protocol[BUFLEN_NAME]; - char filter[BUFLEN_FILTER]; - READ_INT32(fp, number); - READ_STRING(fp, protocol); - log_setrequest("service=%lu%s%s", (unsigned long int)number, - *protocol != '\0' ? "/" : "", protocol);, - mkfilter_service_bynumber(number, protocol, filter, sizeof(filter)), - write_service(fp, entry, NULL, protocol) -) - -NSLCD_HANDLE( - service, all, NSLCD_ACTION_SERVICE_ALL, - const char *filter; - log_setrequest("service(all)");, - (filter = service_filter, 0), - write_service(fp, entry, NULL, NULL) -) diff --git a/nslcd/usermod.c b/nslcd/usermod.c deleted file mode 100644 index e0de4d4..0000000 --- a/nslcd/usermod.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - usermod.c - routines for changing user information such as full name, - login shell, etc - - Copyright (C) 2013-2014 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 -*/ - -#include "config.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#ifdef HAVE_STDINT_H -#include <stdint.h> -#endif /* HAVE_STDINT_H */ -#include <unistd.h> -#include <sys/stat.h> - -#include "common.h" -#include "log.h" -#include "myldap.h" -#include "cfg.h" -#include "attmap.h" -#include "compat/shell.h" - -/* ensure that both userdn and username are filled in from the entry, - returns an LDAP result code */ -static MYLDAP_ENTRY *validate_user(MYLDAP_SESSION *session, - char *username, int *rcp) -{ - int rc; - MYLDAP_ENTRY *entry = NULL; - /* check username for validity */ - if (!isvalidname(username)) - { - log_log(LOG_WARNING, "request denied by validnames option"); - *rcp = LDAP_NO_SUCH_OBJECT; - return NULL; - } - /* get the user entry based on the username */ - entry = uid2entry(session, username, &rc); - if (entry == NULL) - { - if (rc == LDAP_SUCCESS) - rc = LDAP_NO_SUCH_OBJECT; - log_log(LOG_DEBUG, "\"%s\": user not found: %s", username, ldap_err2string(rc)); - *rcp = rc; - return NULL; - } - return entry; -} - -static int is_valid_homedir(const char *homedir) -{ - struct stat sb; - /* should be absolute path */ - if (homedir[0] != '/') - return 0; - /* get directory status */ - if (stat(homedir, &sb)) - { - log_log(LOG_DEBUG, "cannot stat() %s: %s", homedir, strerror(errno)); - return 0; - } - /* check if a directory */ - if (!S_ISDIR(sb.st_mode)) - { - log_log(LOG_DEBUG, "%s: not a directory", homedir); - return 0; - } - /* FIXME: check ownership */ - return 1; -} - -static int is_valid_shell(const char *shell) -{ - int valid = 0; - char *l; - setusershell(); - while ((l = getusershell()) != NULL) - { - if (strcmp(l, shell) == 0) - { - valid = 1; - break; - } - } - endusershell(); - return valid; -} - -static MYLDAP_SESSION *get_session(const char *binddn, const char *userdn, - const char *password, int *rcp) -{ - MYLDAP_SESSION *session; - char buffer[BUFLEN_DN]; - /* set up a new connection */ - session = myldap_create_session(); - if (session == NULL) - { - *rcp = LDAP_UNAVAILABLE; - return NULL; - } - /* set up credentials for the session */ - if (myldap_set_credentials(session, binddn, password)) - return NULL; - /* perform search for own object (just to do any kind of search to set - up the connection with fail-over) */ - if ((lookup_dn2uid(session, userdn, rcp, buffer, sizeof(buffer)) == NULL) || - (*rcp != LDAP_SUCCESS)) - { - myldap_session_close(session); - return NULL; - } - return session; -} - -#define ADD_MOD(attribute, value) \ - if ((value != NULL) && (attribute[0] != '"')) \ - { \ - strvals[i * 2] = (char *)value; \ - strvals[i * 2 + 1] = NULL; \ - mods[i].mod_op = LDAP_MOD_REPLACE; \ - mods[i].mod_type = (char *)attribute; \ - mods[i].mod_values = strvals + (i * 2); \ - modsp[i] = mods + i; \ - i++; \ - } - -static int change(MYLDAP_SESSION *session, const char *userdn, - const char *homedir, const char *shell) -{ - #define NUMARGS 2 - char *strvals[(NUMARGS + 1) * 2]; - LDAPMod mods[(NUMARGS + 1)], *modsp[(NUMARGS + 1)]; - int i = 0; - /* build the list of modifications */ - ADD_MOD(attmap_passwd_homeDirectory, homedir); - ADD_MOD(attmap_passwd_loginShell, shell); - /* terminate the list of modifications */ - modsp[i] = NULL; - /* execute the update */ - return myldap_modify(session, userdn, modsp); -} - -int nslcd_usermod(TFILE *fp, MYLDAP_SESSION *session, uid_t calleruid) -{ - int32_t tmpint32; - int rc = LDAP_SUCCESS; - char username[BUFLEN_NAME]; - int asroot, isroot; - char password[BUFLEN_PASSWORD]; - int32_t param; - char buffer[4096]; - size_t buflen = sizeof(buffer); - size_t bufptr = 0; - const char *value = NULL; - const char *fullname = NULL, *roomnumber = NULL, *workphone = NULL; - const char *homephone = NULL, *other = NULL, *homedir = NULL; - const char *shell = NULL; - const char *binddn = NULL; /* the user performing the modification */ - MYLDAP_ENTRY *entry; - MYLDAP_SESSION *newsession; - char errmsg[BUFLEN_MESSAGE]; - /* read request parameters */ - READ_STRING(fp, username); - READ_INT32(fp, asroot); - READ_STRING(fp, password); - /* read the usermod parameters */ - while (1) - { - READ_INT32(fp, param); - if (param == NSLCD_USERMOD_END) - break; - READ_BUF_STRING(fp, value); - switch (param) - { - case NSLCD_USERMOD_FULLNAME: fullname = value; break; - case NSLCD_USERMOD_ROOMNUMBER: roomnumber = value; break; - case NSLCD_USERMOD_WORKPHONE: workphone = value; break; - case NSLCD_USERMOD_HOMEPHONE: homephone = value; break; - case NSLCD_USERMOD_OTHER: other = value; break; - case NSLCD_USERMOD_HOMEDIR: homedir = value; break; - case NSLCD_USERMOD_SHELL: shell = value; break; - default: /* other parameters are silently ignored */ break; - } - } - /* log call */ - log_setrequest("usermod=\"%s\"", username); - log_log(LOG_DEBUG, "nslcd_usermod(\"%s\",%s,\"%s\")", - username, asroot ? "asroot" : "asuser", *password ? "***" : ""); - if (fullname != NULL) - log_log(LOG_DEBUG, "nslcd_usermod(fullname=\"%s\")", fullname); - if (roomnumber != NULL) - log_log(LOG_DEBUG, "nslcd_usermod(roomnumber=\"%s\")", roomnumber); - if (workphone != NULL) - log_log(LOG_DEBUG, "nslcd_usermod(workphone=\"%s\")", workphone); - if (homephone != NULL) - log_log(LOG_DEBUG, "nslcd_usermod(homephone=\"%s\")", homephone); - if (other != NULL) - log_log(LOG_DEBUG, "nslcd_usermod(other=\"%s\")", other); - if (homedir != NULL) - log_log(LOG_DEBUG, "nslcd_usermod(homedir=\"%s\")", homedir); - if (shell != NULL) - log_log(LOG_DEBUG, "nslcd_usermod(shell=\"%s\")", shell); - /* write the response header */ - WRITE_INT32(fp, NSLCD_VERSION); - WRITE_INT32(fp, NSLCD_ACTION_USERMOD); - /* validate request */ - entry = validate_user(session, username, &rc); - if (entry == NULL) - { - /* for user not found we just say no result, otherwise break the protocol */ - if (rc == LDAP_NO_SUCH_OBJECT) - { - WRITE_INT32(fp, NSLCD_RESULT_END); - } - return -1; - } - /* check if it is a modification as root */ - isroot = (calleruid == 0) && asroot; - if (asroot) - { - if (nslcd_cfg->rootpwmoddn == NULL) - { - log_log(LOG_NOTICE, "rootpwmoddn not configured"); - /* we break the protocol */ - return -1; - } - binddn = nslcd_cfg->rootpwmoddn; - /* check if rootpwmodpw should be used */ - if ((*password == '\0') && isroot && (nslcd_cfg->rootpwmodpw != NULL)) - { - if (strlen(nslcd_cfg->rootpwmodpw) >= sizeof(password)) - { - log_log(LOG_ERR, "nslcd_pam_pwmod(): rootpwmodpw will not fit in password"); - return -1; - } - strcpy(password, nslcd_cfg->rootpwmodpw); - } - } - else - binddn = myldap_get_dn(entry); - WRITE_INT32(fp, NSLCD_RESULT_BEGIN); - /* home directory change requires either root or valid directory */ - if ((homedir != NULL) && (!isroot) && !is_valid_homedir(homedir)) - { - log_log(LOG_NOTICE, "invalid directory: %s", homedir); - WRITE_INT32(fp, NSLCD_USERMOD_HOMEDIR); - WRITE_STRING(fp, "invalid directory"); - homedir = NULL; - } - /* shell change requires either root or a valid shell */ - if ((shell != NULL) && (!isroot) && !is_valid_shell(shell)) - { - log_log(LOG_NOTICE, "invalid shell: %s", shell); - WRITE_INT32(fp, NSLCD_USERMOD_SHELL); - WRITE_STRING(fp, "invalid shell"); - shell = NULL; - } - /* perform requested changes */ - newsession = get_session(binddn, myldap_get_dn(entry), password, &rc); - if (newsession != NULL) - { - rc = change(newsession, myldap_get_dn(entry), homedir, shell); - myldap_session_close(newsession); - } - /* return response to caller */ - if (rc != LDAP_SUCCESS) - { - log_log(LOG_WARNING, "%s: modification failed: %s", - myldap_get_dn(entry), ldap_err2string(rc)); - mysnprintf(errmsg, sizeof(errmsg) - 1, "change failed: %s", ldap_err2string(rc)); - WRITE_INT32(fp, NSLCD_USERMOD_RESULT); - WRITE_STRING(fp, errmsg); - WRITE_INT32(fp, NSLCD_USERMOD_END); - WRITE_INT32(fp, NSLCD_RESULT_END); - return 0; - } - log_log(LOG_NOTICE, "changed information for %s", myldap_get_dn(entry)); - WRITE_INT32(fp, NSLCD_USERMOD_END); - WRITE_INT32(fp, NSLCD_RESULT_END); - return 0; -} |